Update the address and phone number of the FSF
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
CommitLineData
2469cfa2
NC
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
18af0b39 3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2469cfa2
NC
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
2469cfa2
NC
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <limits.h>
27
28#define PUSH_1X_WORKAROUND
29#include "as.h"
30#include "subsegs.h"
31#include "opcode/msp430.h"
32#include "safe-ctype.h"
33
f5c7edf4
AM
34/* GCC uses the some condition codes which we'll
35 implement as new polymorph instructions.
36
37 COND EXPL SHORT JUMP LONG JUMP
38 ===============================================
39 eq == jeq jne +4; br lab
40 ne != jne jeq +4; br lab
41
42 ltn honours no-overflow flag
43 ltn < jn jn +2; jmp +4; br lab
44
45 lt < jl jge +4; br lab
46 ltu < jlo lhs +4; br lab
47 le <= see below
48 leu <= see below
49
50 gt > see below
51 gtu > see below
52 ge >= jge jl +4; br lab
53 geu >= jhs jlo +4; br lab
54 ===============================================
55
56 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
57 beq,bne,blt,bltn,bltu,bge,bgeu
58 'u' means unsigned compares
59
60 Also, we add 'jump' instruction:
61 jump UNCOND -> jmp br lab
62
63 They will have fmt == 4, and insn_opnumb == number of instruction. */
64
65struct rcodes_s
66{
67 char * name;
68 int index; /* Corresponding insn_opnumb. */
69 int sop; /* Opcode if jump length is short. */
70 long lpos; /* Label position. */
71 long lop0; /* Opcode 1 _word_ (16 bits). */
72 long lop1; /* Opcode second word. */
73 long lop2; /* Opcode third word. */
74};
75
76#define MSP430_RLC(n,i,sop,o1) \
77 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
78
79static struct rcodes_s msp430_rcodes[] =
80{
81 MSP430_RLC (beq, 0, 0x2400, 0x2000),
82 MSP430_RLC (bne, 1, 0x2000, 0x2400),
83 MSP430_RLC (blt, 2, 0x3800, 0x3400),
84 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
85 MSP430_RLC (bge, 4, 0x3400, 0x3800),
86 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
87 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
88 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
89 {0,0,0,0,0,0,0}
90};
91#undef MSP430_RLC
92
93
94/* More difficult than above and they have format 5.
95
96 COND EXPL SHORT LONG
97 =================================================================
98 gt > jeq +2; jge label jeq +6; jl +4; br label
99 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
100 leu <= jeq label; jlo label jeq +2; jhs +4; br label
101 le <= jeq label; jl label jeq +2; jge +4; br label
102 ================================================================= */
103
104struct hcodes_s
105{
106 char * name;
107 int index; /* Corresponding insn_opnumb. */
108 int tlab; /* Number of labels in short mode. */
109 int op0; /* Opcode for first word of short jump. */
110 int op1; /* Opcode for second word of short jump. */
111 int lop0; /* Opcodes for long jump mode. */
112 int lop1;
113 int lop2;
114};
115
116static struct hcodes_s msp430_hcodes[] =
117{
118 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
119 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
120 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
121 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
122 {0,0,0,0,0,0,0,0}
123};
124
2469cfa2
NC
125const char comment_chars[] = ";";
126const char line_comment_chars[] = "#";
127const char line_separator_chars[] = "";
128const char EXP_CHARS[] = "eE";
129const char FLT_CHARS[] = "dD";
130
131/* Handle long expressions. */
132extern LITTLENUM_TYPE generic_bignum[];
133
134static struct hash_control *msp430_hash;
135
b18c562e
NC
136/* Relaxations. */
137#define STATE_UNCOND_BRANCH 1 /* jump */
138#define STATE_NOOV_BRANCH 3 /* bltn */
139#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
140#define STATE_EMUL_BRANCH 4
141
142#define CNRL 2
143#define CUBL 4
144#define CNOL 8
145#define CSBL 6
146#define CEBL 4
147
148/* Length. */
149#define STATE_BITS10 1 /* wild guess. short jump */
150#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
151#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
152
153#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
154#define RELAX_STATE(s) ((s) & 3)
155#define RELAX_LEN(s) ((s) >> 2)
156#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
157
158relax_typeS md_relax_table[] =
159{
160 /* Unused. */
161 {1, 1, 0, 0},
162 {1, 1, 0, 0},
163 {1, 1, 0, 0},
164 {1, 1, 0, 0},
165
166 /* Unconditional jump. */
167 {1, 1, 8, 5},
168 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
169 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
170 {1, 1, CUBL, 0}, /* state undef */
171
172 /* Simple branches. */
173 {0, 0, 8, 9},
174 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
175 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
176 {1, 1, CSBL, 0},
177
178 /* blt no overflow branch. */
179 {1, 1, 8, 13},
180 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
181 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
182 {1, 1, CNOL, 0},
183
184 /* Emulated branches. */
185 {1, 1, 8, 17},
186 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
187 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
188 {1, 1, CNOL, 0}
189};
190
2469cfa2 191
8cd5b113 192#define MAX_OP_LEN 256
2469cfa2
NC
193
194struct mcu_type_s
195{
b18c562e 196 char * name;
2469cfa2
NC
197 int isa;
198 int mach;
199};
200
201#define MSP430_ISA_11 11
3b260895 202#define MSP430_ISA_110 110
2469cfa2
NC
203#define MSP430_ISA_12 12
204#define MSP430_ISA_13 13
205#define MSP430_ISA_14 14
3b260895
NC
206#define MSP430_ISA_15 15
207#define MSP430_ISA_16 16
2469cfa2
NC
208#define MSP430_ISA_31 31
209#define MSP430_ISA_32 32
210#define MSP430_ISA_33 33
3b260895
NC
211#define MSP430_ISA_41 41
212#define MSP430_ISA_42 42
2469cfa2
NC
213#define MSP430_ISA_43 43
214#define MSP430_ISA_44 44
2469cfa2
NC
215
216#define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
217#define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
218
219static struct mcu_type_s mcu_types[] =
220{
b18c562e
NC
221 {"msp1", MSP430_ISA_11, bfd_mach_msp11},
222 {"msp2", MSP430_ISA_14, bfd_mach_msp14},
223 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
224 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
225 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
226 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
227 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
228 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
229 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
230
231 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
232 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
233 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
234 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
235
236 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
237 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
238 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
239 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
240 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
241 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
242 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
243
244 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
245 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
246 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
247 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
248 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
249 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
c05e9f04
NC
250 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
251 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
252 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
3b260895 253
b18c562e
NC
254 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
255 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
256 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
257 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
258 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
259 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
260 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
261 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
262 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
263
264 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
265 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
266 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
267 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
3b260895
NC
268
269 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
270 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
271 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
c05e9f04 272
3b260895
NC
273 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
274 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
275 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
276
c05e9f04
NC
277 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
278 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
279 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
280
b18c562e
NC
281 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
282 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
283 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
284 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
285 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
286 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
2469cfa2
NC
287
288 {NULL, 0, 0}
289};
290
291
292static struct mcu_type_s default_mcu =
293 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
294
b18c562e
NC
295static struct mcu_type_s * msp430_mcu = & default_mcu;
296
297/* Profiling capability:
298 It is a performance hit to use gcc's profiling approach for this tiny target.
299 Even more -- jtag hardware facility does not perform any profiling functions.
300 However we've got gdb's built-in simulator where we can do anything.
301 Therefore my suggestion is:
302
303 We define new section ".profiler" which holds all profiling information.
304 We define new pseudo operation .profiler which will instruct assembler to
305 add new profile entry to the object file. Profile should take place at the
306 present address.
307
308 Pseudo-op format:
309
310 .profiler flags,function_to_profile [, cycle_corrector, extra]
311
312 where 'flags' is a combination of the following chars:
313 s - function Start
314 x - function eXit
315 i - function is in Init section
316 f - function is in Fini section
317 l - Library call
318 c - libC standard call
319 d - stack value Demand (saved at run-time in simulator)
320 I - Interrupt service routine
321 P - Prologue start
322 p - Prologue end
323 E - Epilogue start
324 e - Epilogue end
325 j - long Jump/ sjlj unwind
326 a - an Arbitrary code fragment
327 t - exTra parameter saved (constant value like frame size)
328 '""' optional: "sil" == sil
329
330 function_to_profile - function's address
331 cycle_corrector - a value which should be added to the cycle
332 counter, zero if omitted
333 extra - some extra parameter, zero if omitted.
334
335 For example:
336 ------------------------------
337 .global fxx
338 .type fxx,@function
339 fxx:
340 .LFrameOffset_fxx=0x08
341 .profiler "scdP", fxx ; function entry.
342 ; we also demand stack value to be displayed
343 push r11
344 push r10
345 push r9
346 push r8
347 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
348 ; (this is a prologue end)
349 ; note, that spare var filled with the farme size
350 mov r15,r8
351 ....
352 .profiler cdE,fxx ; check stack
353 pop r8
354 pop r9
355 pop r10
356 pop r11
357 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
358 ret ; cause 'ret' insn takes 3 cycles
359 -------------------------------
360
361 This profiling approach does not produce any overhead and
362 absolutely harmless.
363 So, even profiled code can be uploaded to the MCU. */
364#define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
365#define MSP430_PROFILER_FLAG_EXIT 2 /* x */
366#define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
367#define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
368#define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
369#define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
370#define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
371#define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
372#define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
373#define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
374#define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
375#define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
376#define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
377#define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
378#define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
379#define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
2469cfa2 380
b18c562e
NC
381static int
382pow2value (int y)
2469cfa2 383{
b18c562e
NC
384 int n = 0;
385 unsigned int x;
2469cfa2 386
b18c562e 387 x = y;
2469cfa2 388
b18c562e
NC
389 if (!x)
390 return 1;
2469cfa2 391
b18c562e
NC
392 for (; x; x = x >> 1)
393 if (x & 1)
394 n++;
395
396 return n == 1;
397}
398
399/* Parse ordinary expression. */
400
401static char *
402parse_exp (char * s, expressionS * op)
2469cfa2 403{
b18c562e
NC
404 input_line_pointer = s;
405 expression (op);
406 if (op->X_op == O_absent)
407 as_bad (_("missing operand"));
408 return input_line_pointer;
409}
2469cfa2 410
b18c562e
NC
411
412/* Delete spaces from s: X ( r 1 2) => X(r12). */
2469cfa2
NC
413
414static void
b18c562e 415del_spaces (char * s)
2469cfa2 416{
b18c562e
NC
417 while (*s)
418 {
419 if (ISSPACE (*s))
420 {
421 char *m = s + 1;
2469cfa2 422
b18c562e
NC
423 while (ISSPACE (*m) && *m)
424 m++;
425 memmove (s, m, strlen (m) + 1);
426 }
427 else
428 s++;
429 }
430}
2469cfa2 431
b18c562e
NC
432static inline char *
433skip_space (char * s)
434{
435 while (ISSPACE (*s))
436 ++s;
437 return s;
438}
2469cfa2 439
b18c562e
NC
440/* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
441
442static char *
443extract_operand (char * from, char * to, int limit)
444{
445 int size = 0;
446
447 /* Drop leading whitespace. */
448 from = skip_space (from);
449
450 while (size < limit && *from)
451 {
452 *(to + size) = *from;
453 if (*from == ',' || *from == ';' || *from == '\n')
454 break;
455 from++;
456 size++;
457 }
458
459 *(to + size) = 0;
460 del_spaces (to);
461
462 from++;
463
464 return from;
2469cfa2
NC
465}
466
b18c562e
NC
467static void
468msp430_profiler (int dummy ATTRIBUTE_UNUSED)
2469cfa2 469{
b18c562e
NC
470 char buffer[1024];
471 char f[32];
472 char * str = buffer;
473 char * flags = f;
474 int p_flags = 0;
475 char * halt;
476 int ops = 0;
477 int left;
478 char * s;
479 segT seg;
480 int subseg;
481 char * end = 0;
482 expressionS exp;
483 expressionS exp1;
484
485 s = input_line_pointer;
486 end = input_line_pointer;
487
488 while (*end && *end != '\n')
489 end++;
490
491 while (*s && *s != '\n')
492 {
493 if (*s == ',')
494 ops++;
495 s++;
496 }
2469cfa2 497
b18c562e
NC
498 left = 3 - ops;
499
500 if (ops < 1)
501 {
502 as_bad (_(".profiler pseudo requires at least two operands."));
503 input_line_pointer = end;
504 return;
505 }
506
507 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
508
509 while (*flags)
510 {
511 switch (*flags)
512 {
513 case '"':
514 break;
515 case 'a':
516 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
517 break;
518 case 'j':
519 p_flags |= MSP430_PROFILER_FLAG_JUMP;
520 break;
521 case 'P':
522 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
523 break;
524 case 'p':
525 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
526 break;
527 case 'E':
528 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
529 break;
530 case 'e':
531 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
532 break;
533 case 's':
534 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
535 break;
536 case 'x':
537 p_flags |= MSP430_PROFILER_FLAG_EXIT;
538 break;
539 case 'i':
540 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
541 break;
542 case 'f':
543 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
544 break;
545 case 'l':
546 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
547 break;
548 case 'c':
549 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
550 break;
551 case 'd':
552 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
553 break;
554 case 'I':
555 p_flags |= MSP430_PROFILER_FLAG_ISR;
556 break;
557 case 't':
558 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
559 break;
560 default:
561 as_warn (_("unknown profiling flag - ignored."));
562 break;
563 }
564 flags++;
565 }
566
567 if (p_flags
568 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
569 | MSP430_PROFILER_FLAG_EXIT))
570 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
571 | MSP430_PROFILER_FLAG_PROLEND
572 | MSP430_PROFILER_FLAG_EPISTART
573 | MSP430_PROFILER_FLAG_EPIEND))
574 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
575 | MSP430_PROFILER_FLAG_FINISECT))))
576 {
577 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
578 input_line_pointer = end;
579 return;
580 }
581
582 /* Generate temp symbol which denotes current location. */
583 if (now_seg == absolute_section) /* Paranoja ? */
584 {
585 exp1.X_op = O_constant;
586 exp1.X_add_number = abs_section_offset;
587 as_warn (_("profiling in absolute section? Hm..."));
588 }
589 else
590 {
591 exp1.X_op = O_symbol;
592 exp1.X_add_symbol = symbol_temp_new_now ();
593 exp1.X_add_number = 0;
594 }
595
596 /* Generate a symbol which holds flags value. */
597 exp.X_op = O_constant;
598 exp.X_add_number = p_flags;
599
600 /* Save current section. */
601 seg = now_seg;
602 subseg = now_subseg;
603
604 /* Now go to .profiler section. */
605 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
606
607 /* Save flags. */
608 emit_expr (& exp, 2);
609
610 /* Save label value. */
611 emit_expr (& exp1, 2);
612
613 while (ops--)
614 {
615 /* Now get profiling info. */
616 halt = extract_operand (input_line_pointer, str, 1024);
617 /* Process like ".word xxx" directive. */
618 parse_exp (str, & exp);
619 emit_expr (& exp, 2);
620 input_line_pointer = halt;
621 }
622
623 /* Fill the rest with zeros. */
624 exp.X_op = O_constant;
625 exp.X_add_number = 0;
626 while (left--)
627 emit_expr (& exp, 2);
628
629 /* Return to current section. */
630 subseg_set (seg, subseg);
2469cfa2
NC
631}
632
633static char *
b18c562e 634extract_word (char * from, char * to, int limit)
2469cfa2
NC
635{
636 char *op_start;
637 char *op_end;
638 int size = 0;
639
640 /* Drop leading whitespace. */
641 from = skip_space (from);
642 *to = 0;
643
644 /* Find the op code end. */
645 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
646 {
647 to[size++] = *op_end++;
648 if (size + 1 >= limit)
649 break;
650 }
651
652 to[size] = 0;
653 return op_end;
654}
655
b18c562e
NC
656#define OPTION_MMCU 'm'
657
2469cfa2 658static void
b18c562e 659msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
2469cfa2
NC
660{
661 char *str = (char *) alloca (32); /* 32 for good measure. */
662
663 input_line_pointer = extract_word (input_line_pointer, str, 32);
664
665 md_parse_option (OPTION_MMCU, str);
666 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
667}
668
b18c562e
NC
669static void
670show_mcu_list (FILE * stream)
671{
672 int i;
673
674 fprintf (stream, _("Known MCU names:\n"));
675
676 for (i = 0; mcu_types[i].name; i++)
677 fprintf (stream, _("\t %s\n"), mcu_types[i].name);
678
679 fprintf (stream, "\n");
680}
681
2469cfa2 682int
b18c562e 683md_parse_option (int c, char * arg)
2469cfa2
NC
684{
685 int i;
686
687 switch (c)
688 {
689 case OPTION_MMCU:
690 for (i = 0; mcu_types[i].name; ++i)
691 if (strcmp (mcu_types[i].name, arg) == 0)
692 break;
693
694 if (!mcu_types[i].name)
695 {
696 show_mcu_list (stderr);
697 as_fatal (_("unknown MCU: %s\n"), arg);
698 }
699
700 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
701 msp430_mcu = &mcu_types[i];
702 else
703 as_fatal (_("redefinition of mcu type %s' to %s'"),
704 msp430_mcu->name, mcu_types[i].name);
705 return 1;
706 }
707
708 return 0;
709}
710
2469cfa2 711
b18c562e 712const pseudo_typeS md_pseudo_table[] =
2469cfa2 713{
b18c562e
NC
714 {"arch", msp430_set_arch, 0},
715 {"profiler", msp430_profiler, 0},
716 {NULL, NULL, 0}
717};
2469cfa2 718
b18c562e 719const char *md_shortopts = "m:";
2469cfa2 720
b18c562e 721struct option md_longopts[] =
2469cfa2 722{
b18c562e
NC
723 {"mmcu", required_argument, NULL, OPTION_MMCU},
724 {NULL, no_argument, NULL, 0}
725};
2469cfa2 726
b18c562e 727size_t md_longopts_size = sizeof (md_longopts);
2469cfa2 728
b18c562e
NC
729void
730md_show_usage (FILE * stream)
2469cfa2 731{
b18c562e
NC
732 fprintf (stream,
733 _("MSP430 options:\n"
734 " -mmcu=[msp430-name] select microcontroller type\n"
735 " msp430x110 msp430x112\n"
736 " msp430x1101 msp430x1111\n"
737 " msp430x1121 msp430x1122 msp430x1132\n"
738 " msp430x122 msp430x123\n"
739 " msp430x1222 msp430x1232\n"
740 " msp430x133 msp430x135\n"
741 " msp430x1331 msp430x1351\n"
742 " msp430x147 msp430x148 msp430x149\n"
743 " msp430x155 msp430x156 msp430x157\n"
744 " msp430x167 msp430x168 msp430x169\n"
745 " msp430x1610 msp430x1611 msp430x1612\n"
746 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
747 " msp430x323 msp430x325\n"
748 " msp430x336 msp430x337\n"
749 " msp430x412 msp430x413 msp430x415 msp430x417\n"
750 " msp430xE423 msp430xE425 msp430E427\n"
751 " msp430xW423 msp430xW425 msp430W427\n"
752 " msp430xG437 msp430xG438 msp430G439\n"
753 " msp430x435 msp430x436 msp430x437\n"
754 " msp430x447 msp430x448 msp430x449\n"));
2469cfa2 755
b18c562e
NC
756 show_mcu_list (stream);
757}
2469cfa2 758
b18c562e
NC
759symbolS *
760md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
761{
762 return 0;
2469cfa2
NC
763}
764
765static char *
b18c562e 766extract_cmd (char * from, char * to, int limit)
2469cfa2
NC
767{
768 int size = 0;
769
770 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
771 {
772 *(to + size) = *from;
773 from++;
774 size++;
775 }
776
777 *(to + size) = 0;
778
779 return from;
780}
781
782/* Turn a string in input_line_pointer into a floating point constant
783 of type TYPE, and store the appropriate bytes in *LITP. The number
784 of LITTLENUMS emitted is stored in *SIZEP. An error message is
785 returned, or NULL on OK. */
786
787char *
b18c562e 788md_atof (int type, char * litP, int * sizeP)
2469cfa2
NC
789{
790 int prec;
791 LITTLENUM_TYPE words[4];
792 LITTLENUM_TYPE *wordP;
793 char *t;
794
795 switch (type)
796 {
797 case 'f':
798 prec = 2;
799 break;
800 case 'd':
801 prec = 4;
802 break;
803 default:
804 *sizeP = 0;
805 return _("bad call to md_atof");
806 }
807
808 t = atof_ieee (input_line_pointer, type, words);
809 if (t)
810 input_line_pointer = t;
811
812 *sizeP = prec * sizeof (LITTLENUM_TYPE);
813
814 /* This loop outputs the LITTLENUMs in REVERSE order. */
815 for (wordP = words + prec - 1; prec--;)
816 {
817 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
818 litP += sizeof (LITTLENUM_TYPE);
819 }
820
821 return NULL;
822}
823
824void
b18c562e 825md_begin (void)
2469cfa2 826{
b18c562e 827 struct msp430_opcode_s * opcode;
2469cfa2
NC
828 msp430_hash = hash_new ();
829
830 for (opcode = msp430_opcodes; opcode->name; opcode++)
831 hash_insert (msp430_hash, opcode->name, (char *) opcode);
832
833 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
834}
835
b18c562e
NC
836static int
837check_reg (char * t)
2469cfa2 838{
b18c562e 839 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
2469cfa2 840
b18c562e
NC
841 if (strlen (t) > 2 && *(t + 2) != '+')
842 return 1;
2469cfa2 843
b18c562e 844 while (*t)
2469cfa2 845 {
b18c562e
NC
846 if ((*t < '0' || *t > '9') && *t != '+')
847 break;
848 t++;
2469cfa2
NC
849 }
850
b18c562e
NC
851 if (*t)
852 return 1;
2469cfa2 853
b18c562e 854 return 0;
2469cfa2
NC
855}
856
2469cfa2 857
b18c562e
NC
858static int
859msp430_srcoperand (struct msp430_operand_s * op,
860 char * l, int bin, int * imm_op)
2469cfa2 861{
b18c562e 862 char *__tl = l;
2469cfa2 863
b18c562e
NC
864 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
865 if (*l == '#')
2469cfa2 866 {
b18c562e
NC
867 char *h = l;
868 int vshift = -1;
869 int rval = 0;
2469cfa2 870
b18c562e
NC
871 /* Check if there is:
872 llo(x) - least significant 16 bits, x &= 0xffff
873 lhi(x) - x = (x >> 16) & 0xffff,
874 hlo(x) - x = (x >> 32) & 0xffff,
875 hhi(x) - x = (x >> 48) & 0xffff
876 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 877
b18c562e 878 *imm_op = 1;
2469cfa2 879
b18c562e
NC
880 if (strncasecmp (h, "#llo(", 5) == 0)
881 {
882 vshift = 0;
883 rval = 3;
884 }
885 else if (strncasecmp (h, "#lhi(", 5) == 0)
886 {
887 vshift = 1;
888 rval = 3;
889 }
890 else if (strncasecmp (h, "#hlo(", 5) == 0)
891 {
892 vshift = 2;
893 rval = 3;
894 }
895 else if (strncasecmp (h, "#hhi(", 5) == 0)
896 {
897 vshift = 3;
898 rval = 3;
899 }
900 else if (strncasecmp (h, "#lo(", 4) == 0)
901 {
902 vshift = 0;
903 rval = 2;
904 }
905 else if (strncasecmp (h, "#hi(", 4) == 0)
906 {
907 vshift = 1;
908 rval = 2;
909 }
2469cfa2 910
b18c562e
NC
911 op->reg = 0; /* Reg PC. */
912 op->am = 3;
913 op->ol = 1; /* Immediate will follow an instruction. */
914 __tl = h + 1 + rval;
915 op->mode = OP_EXP;
2469cfa2 916
b18c562e
NC
917 parse_exp (__tl, &(op->exp));
918 if (op->exp.X_op == O_constant)
2469cfa2 919 {
b18c562e 920 int x = op->exp.X_add_number;
2469cfa2 921
b18c562e 922 if (vshift == 0)
2469cfa2 923 {
b18c562e
NC
924 x = x & 0xffff;
925 op->exp.X_add_number = x;
926 }
927 else if (vshift == 1)
928 {
929 x = (x >> 16) & 0xffff;
930 op->exp.X_add_number = x;
931 }
932 else if (vshift > 1)
933 {
934 if (x < 0)
935 op->exp.X_add_number = -1;
2469cfa2 936 else
b18c562e
NC
937 op->exp.X_add_number = 0; /* Nothing left. */
938 x = op->exp.X_add_number;
2469cfa2 939 }
2469cfa2 940
b18c562e
NC
941 if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
942 {
943 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
944 return 1;
945 }
2469cfa2 946
b18c562e
NC
947 /* Now check constants. */
948 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 949
b18c562e 950 x = (short) x; /* Extend sign. */
2469cfa2 951
b18c562e 952 if (x == 0)
2469cfa2 953 {
b18c562e
NC
954 op->reg = 3;
955 op->am = 0;
956 op->ol = 0;
957 op->mode = OP_REG;
958 }
959 else if (x == 1)
960 {
961 op->reg = 3;
962 op->am = 1;
963 op->ol = 0;
964 op->mode = OP_REG;
965 }
966 else if (x == 2)
967 {
968 op->reg = 3;
969 op->am = 2;
970 op->ol = 0;
971 op->mode = OP_REG;
972 }
973 else if (x == -1)
974 {
975 op->reg = 3;
976 op->am = 3;
977 op->ol = 0;
978 op->mode = OP_REG;
979 }
980 else if (x == 4)
981 {
982#ifdef PUSH_1X_WORKAROUND
983 if (bin == 0x1200)
984 {
985 /* Remove warning as confusing.
986 as_warn(_("Hardware push bug workaround")); */
987 }
988 else
989#endif
990 {
991 op->reg = 2;
992 op->am = 2;
993 op->ol = 0;
994 op->mode = OP_REG;
995 }
996 }
997 else if (x == 8)
998 {
999#ifdef PUSH_1X_WORKAROUND
1000 if (bin == 0x1200)
1001 {
1002 /* Remove warning as confusing.
1003 as_warn(_("Hardware push bug workaround")); */
1004 }
1005 else
1006#endif
1007 {
1008 op->reg = 2;
1009 op->am = 3;
1010 op->ol = 0;
1011 op->mode = OP_REG;
1012 }
2469cfa2 1013 }
2469cfa2 1014 }
b18c562e
NC
1015 else if (op->exp.X_op == O_symbol)
1016 {
1017 op->mode = OP_EXP;
1018 }
1019 else if (op->exp.X_op == O_big)
1020 {
1021 short x;
1022 if (vshift != -1)
1023 {
1024 op->exp.X_op = O_constant;
1025 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1026 x = op->exp.X_add_number;
1027 }
1028 else
1029 {
1030 as_bad (_
1031 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1032 l);
1033 return 1;
1034 }
2469cfa2 1035
b18c562e
NC
1036 if (x == 0)
1037 {
1038 op->reg = 3;
1039 op->am = 0;
1040 op->ol = 0;
1041 op->mode = OP_REG;
1042 }
1043 else if (x == 1)
1044 {
1045 op->reg = 3;
1046 op->am = 1;
1047 op->ol = 0;
1048 op->mode = OP_REG;
1049 }
1050 else if (x == 2)
1051 {
1052 op->reg = 3;
1053 op->am = 2;
1054 op->ol = 0;
1055 op->mode = OP_REG;
1056 }
1057 else if (x == -1)
1058 {
1059 op->reg = 3;
1060 op->am = 3;
1061 op->ol = 0;
1062 op->mode = OP_REG;
1063 }
1064 else if (x == 4)
1065 {
1066 op->reg = 2;
1067 op->am = 2;
1068 op->ol = 0;
1069 op->mode = OP_REG;
1070 }
1071 else if (x == 8)
1072 {
1073 op->reg = 2;
1074 op->am = 3;
1075 op->ol = 0;
1076 op->mode = OP_REG;
1077 }
1078 }
1079 /* Redudant (yet) check. */
1080 else if (op->exp.X_op == O_register)
1081 as_bad
1082 (_("Registers cannot be used within immediate expression [%s]"), l);
1083 else
1084 as_bad (_("unknown operand %s"), l);
2469cfa2 1085
b18c562e
NC
1086 return 0;
1087 }
2469cfa2 1088
b18c562e
NC
1089 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1090 if (*l == '&')
1091 {
1092 char *h = l;
2469cfa2 1093
b18c562e
NC
1094 op->reg = 2; /* reg 2 in absolute addr mode. */
1095 op->am = 1; /* mode As == 01 bin. */
1096 op->ol = 1; /* Immediate value followed by instruction. */
1097 __tl = h + 1;
1098 parse_exp (__tl, &(op->exp));
1099 op->mode = OP_EXP;
1100 if (op->exp.X_op == O_constant)
2469cfa2 1101 {
b18c562e 1102 int x = op->exp.X_add_number;
2469cfa2 1103
b18c562e
NC
1104 if (x > 65535 || x < -32768)
1105 {
1106 as_bad (_("value out of range: %d"), x);
1107 return 1;
1108 }
2469cfa2 1109 }
b18c562e
NC
1110 else if (op->exp.X_op == O_symbol)
1111 ;
1112 else
2469cfa2 1113 {
b18c562e
NC
1114 /* Redudant (yet) check. */
1115 if (op->exp.X_op == O_register)
1116 as_bad
1117 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 1118 else
b18c562e
NC
1119 as_bad (_("unknown expression in operand %s"), l);
1120 return 1;
2469cfa2 1121 }
b18c562e
NC
1122 return 0;
1123 }
2469cfa2 1124
b18c562e
NC
1125 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1126 if (*l == '@')
1127 {
1128 char *t = l;
1129 char *m = strchr (l, '+');
1130
1131 if (t != l)
2469cfa2 1132 {
b18c562e
NC
1133 as_bad (_("unknown addressing mode %s"), l);
1134 return 1;
2469cfa2
NC
1135 }
1136
b18c562e
NC
1137 t++;
1138 if (*t != 'r' && *t != 'R')
1139 {
1140 as_bad (_("unknown addressing mode %s"), l);
1141 return 1;
1142 }
2469cfa2 1143
b18c562e 1144 t++; /* Points to the reg value. */
2469cfa2 1145
b18c562e 1146 if (check_reg (t))
2469cfa2 1147 {
b18c562e
NC
1148 as_bad (_("Bad register name r%s"), t);
1149 return 1;
2469cfa2 1150 }
2469cfa2 1151
b18c562e
NC
1152 op->mode = OP_REG;
1153 op->am = m ? 3 : 2;
1154 op->ol = 0;
1155 if (m)
1156 *m = 0; /* strip '+' */
1157 op->reg = atoi (t);
1158 if (op->reg < 0 || op->reg > 15)
2469cfa2 1159 {
b18c562e
NC
1160 as_bad (_("MSP430 does not have %d registers"), op->reg);
1161 return 1;
1162 }
2469cfa2 1163
b18c562e
NC
1164 return 0;
1165 }
2469cfa2 1166
b18c562e
NC
1167 /* Check if register indexed X(Rn). */
1168 do
1169 {
1170 char *h = strrchr (l, '(');
1171 char *m = strrchr (l, ')');
1172 char *t;
2469cfa2 1173
b18c562e 1174 *imm_op = 1;
2469cfa2 1175
b18c562e
NC
1176 if (!h)
1177 break;
1178 if (!m)
1179 {
1180 as_bad (_("')' required"));
1181 return 1;
1182 }
2469cfa2 1183
b18c562e
NC
1184 t = h;
1185 op->am = 1;
1186 op->ol = 1;
1187 /* Extract a register. */
1188 t++; /* Advance pointer. */
2469cfa2 1189
b18c562e
NC
1190 if (*t != 'r' && *t != 'R')
1191 {
1192 as_bad (_
1193 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1194 l);
1195 return 1;
1196 }
1197 t++;
2469cfa2 1198
b18c562e
NC
1199 op->reg = *t - '0';
1200 if (op->reg > 9 || op->reg < 0)
1201 {
1202 as_bad (_("unknown operator (r%s substituded as a register name"),
1203 t);
1204 return 1;
1205 }
1206 t++;
1207 if (*t != ')')
1208 {
1209 op->reg = op->reg * 10;
1210 op->reg += *t - '0';
2469cfa2 1211
b18c562e 1212 if (op->reg > 15)
2469cfa2 1213 {
b18c562e
NC
1214 as_bad (_("unknown operator %s"), l);
1215 return 1;
2469cfa2 1216 }
b18c562e 1217 if (op->reg == 2)
2469cfa2 1218 {
b18c562e
NC
1219 as_bad (_("r2 should not be used in indexed addressing mode"));
1220 return 1;
1221 }
2469cfa2 1222
b18c562e
NC
1223 if (*(t + 1) != ')')
1224 {
1225 as_bad (_("unknown operator %s"), l);
1226 return 1;
2469cfa2 1227 }
b18c562e
NC
1228 }
1229
1230 /* Extract constant. */
1231 __tl = l;
1232 *h = 0;
1233 op->mode = OP_EXP;
1234 parse_exp (__tl, &(op->exp));
1235 if (op->exp.X_op == O_constant)
1236 {
1237 int x = op->exp.X_add_number;
1238
1239 if (x > 65535 || x < -32768)
2469cfa2 1240 {
b18c562e
NC
1241 as_bad (_("value out of range: %d"), x);
1242 return 1;
2469cfa2 1243 }
b18c562e
NC
1244
1245 if (x == 0)
2469cfa2 1246 {
b18c562e
NC
1247 op->mode = OP_REG;
1248 op->am = 2;
1249 op->ol = 0;
1250 return 0;
2469cfa2
NC
1251 }
1252 }
b18c562e
NC
1253 else if (op->exp.X_op == O_symbol)
1254 ;
2469cfa2
NC
1255 else
1256 {
b18c562e
NC
1257 /* Redudant (yet) check. */
1258 if (op->exp.X_op == O_register)
1259 as_bad
1260 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1261 else
1262 as_bad (_("unknown expression in operand %s"), l);
1263 return 1;
2469cfa2 1264 }
2469cfa2 1265
b18c562e 1266 return 0;
2469cfa2 1267 }
b18c562e 1268 while (0);
2469cfa2 1269
b18c562e
NC
1270 /* Register mode 'mov r1,r2'. */
1271 do
1272 {
1273 char *t = l;
1274
1275 /* Operand should be a register. */
1276 if (*t == 'r' || *t == 'R')
1277 {
1278 int x = atoi (t + 1);
1279
1280 if (check_reg (t + 1))
1281 break;
1282
1283 if (x < 0 || x > 15)
1284 break; /* Symbolic mode. */
1285
1286 op->mode = OP_REG;
1287 op->am = 0;
1288 op->ol = 0;
1289 op->reg = x;
1290 return 0;
1291 }
1292 }
1293 while (0);
1294
1295 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1296 do
1297 {
b18c562e
NC
1298 op->mode = OP_EXP;
1299 op->reg = 0; /* PC relative... be careful. */
1300 op->am = 1;
1301 op->ol = 1;
1302 __tl = l;
1303 parse_exp (__tl, &(op->exp));
1304 return 0;
1305 }
1306 while (0);
1307
1308 /* Unreachable. */
1309 as_bad (_("unknown addressing mode for operand %s"), l);
1310 return 1;
2469cfa2
NC
1311}
1312
b18c562e 1313
2469cfa2 1314static int
b18c562e 1315msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
2469cfa2
NC
1316{
1317 int dummy;
b18c562e
NC
1318 int ret = msp430_srcoperand (op, l, bin, & dummy);
1319
2469cfa2
NC
1320 if (ret)
1321 return ret;
1322
1323 if (op->am == 2)
1324 {
1325 char *__tl = "0";
1326
1327 op->mode = OP_EXP;
1328 op->am = 1;
1329 op->ol = 1;
1330 parse_exp (__tl, &(op->exp));
b18c562e 1331
2469cfa2
NC
1332 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1333 {
1334 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1335 op->reg, op->reg);
1336 return 1;
1337 }
1338 return 0;
1339 }
1340
1341 if (op->am > 1)
1342 {
1343 as_bad (_
1344 ("this addressing mode is not applicable for destination operand"));
1345 return 1;
1346 }
1347 return 0;
1348}
1349
1350
b18c562e
NC
1351/* Parse instruction operands.
1352 Return binary opcode. */
1353
1354static unsigned int
1355msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 1356{
b18c562e
NC
1357 int bin = opcode->bin_opcode; /* Opcode mask. */
1358 int __is;
1359 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1360 char *frag;
1361 int where;
1362 struct msp430_operand_s op1, op2;
1363 int res = 0;
1364 static short ZEROS = 0;
1365 int byte_op, imm_op;
2469cfa2 1366
b18c562e
NC
1367 /* Opcode is the one from opcodes table
1368 line contains something like
1369 [.w] @r2+, 5(R1)
1370 or
1371 .b @r2+, 5(R1). */
2469cfa2 1372
b18c562e
NC
1373 /* Check if byte or word operation. */
1374 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
2469cfa2 1375 {
b18c562e
NC
1376 bin |= BYTE_OPERATION;
1377 byte_op = 1;
2469cfa2 1378 }
b18c562e
NC
1379 else
1380 byte_op = 0;
2469cfa2 1381
b18c562e
NC
1382 /* skip .[bwBW]. */
1383 while (! ISSPACE (*line) && *line)
1384 line++;
2469cfa2 1385
b18c562e 1386 if (opcode->insn_opnumb && (!*line || *line == '\n'))
2469cfa2 1387 {
b18c562e
NC
1388 as_bad (_("instruction %s requires %d operand(s)"),
1389 opcode->name, opcode->insn_opnumb);
1390 return 0;
1391 }
2469cfa2 1392
b18c562e
NC
1393 memset (l1, 0, sizeof (l1));
1394 memset (l2, 0, sizeof (l2));
1395 memset (&op1, 0, sizeof (op1));
1396 memset (&op2, 0, sizeof (op2));
2469cfa2 1397
b18c562e 1398 imm_op = 0;
2469cfa2 1399
b18c562e
NC
1400 switch (opcode->fmt)
1401 {
1402 case 0: /* Emulated. */
1403 switch (opcode->insn_opnumb)
2469cfa2 1404 {
b18c562e
NC
1405 case 0:
1406 /* Set/clear bits instructions. */
1407 __is = 2;
1408 frag = frag_more (__is);
1409 bfd_putl16 ((bfd_vma) bin, frag);
1410 break;
1411 case 1:
1412 /* Something which works with destination operand. */
1413 line = extract_operand (line, l1, sizeof (l1));
1414 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1415 if (res)
1416 break;
2469cfa2 1417
b18c562e
NC
1418 bin |= (op1.reg | (op1.am << 7));
1419 __is = 1 + op1.ol;
1420 frag = frag_more (2 * __is);
1421 where = frag - frag_now->fr_literal;
1422 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 1423
b18c562e 1424 if (op1.mode == OP_EXP)
2469cfa2 1425 {
b18c562e
NC
1426 where += 2;
1427 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1428
1429 if (op1.reg)
1430 fix_new_exp (frag_now, where, 2,
1431 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2469cfa2 1432 else
b18c562e
NC
1433 fix_new_exp (frag_now, where, 2,
1434 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1435 }
b18c562e 1436 break;
2469cfa2 1437
b18c562e
NC
1438 case 2:
1439 {
1440 /* Shift instruction. */
1441 line = extract_operand (line, l1, sizeof (l1));
1442 strncpy (l2, l1, sizeof (l2));
1443 l2[sizeof (l2) - 1] = '\0';
1444 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1445 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2469cfa2 1446
b18c562e
NC
1447 if (res)
1448 break; /* An error occurred. All warnings were done before. */
2469cfa2 1449
b18c562e 1450 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2469cfa2 1451
b18c562e
NC
1452 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1453 frag = frag_more (2 * __is);
1454 where = frag - frag_now->fr_literal;
1455 bfd_putl16 ((bfd_vma) bin, frag);
1456
1457 if (op1.mode == OP_EXP)
1458 {
1459 where += 2; /* Advance 'where' as we do not know _where_. */
1460 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1461
1462 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1463 fix_new_exp (frag_now, where, 2,
1464 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1465 else
1466 fix_new_exp (frag_now, where, 2,
1467 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1468 }
1469
1470 if (op2.mode == OP_EXP)
1471 {
1472 imm_op = 0;
1473 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1474
1475 if (op2.reg) /* Not PC relative. */
1476 fix_new_exp (frag_now, where + 2, 2,
1477 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1478 else
1479 fix_new_exp (frag_now, where + 2, 2,
1480 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1481 }
1482 break;
1483 }
1484 case 3:
1485 /* Branch instruction => mov dst, r0. */
1486 line = extract_operand (line, l1, sizeof (l1));
1487
1488 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1489 if (res)
1490 break;
1491
1492 byte_op = 0;
1493 imm_op = 0;
1494
1495 bin |= ((op1.reg << 8) | (op1.am << 4));
1496 __is = 1 + op1.ol;
1497 frag = frag_more (2 * __is);
1498 where = frag - frag_now->fr_literal;
1499 bfd_putl16 ((bfd_vma) bin, frag);
1500
1501 if (op1.mode == OP_EXP)
2469cfa2 1502 {
b18c562e
NC
1503 where += 2;
1504 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1505
1506 if (op1.reg || (op1.reg == 0 && op1.am == 3))
1507 fix_new_exp (frag_now, where, 2,
1508 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2469cfa2 1509 else
b18c562e
NC
1510 fix_new_exp (frag_now, where, 2,
1511 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1512 }
b18c562e 1513 break;
2469cfa2 1514 }
b18c562e 1515 break;
2469cfa2 1516
b18c562e
NC
1517 case 1: /* Format 1, double operand. */
1518 line = extract_operand (line, l1, sizeof (l1));
1519 line = extract_operand (line, l2, sizeof (l2));
1520 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1521 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2469cfa2 1522
b18c562e
NC
1523 if (res)
1524 break; /* Error occurred. All warnings were done before. */
2469cfa2 1525
b18c562e
NC
1526 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1527
1528 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1529 frag = frag_more (2 * __is);
1530 where = frag - frag_now->fr_literal;
1531 bfd_putl16 ((bfd_vma) bin, frag);
1532
1533 if (op1.mode == OP_EXP)
2469cfa2 1534 {
b18c562e
NC
1535 where += 2; /* Advance where as we do not know _where_. */
1536 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1537
1538 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1539 fix_new_exp (frag_now, where, 2,
1540 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1541 else
1542 fix_new_exp (frag_now, where, 2,
1543 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1544 }
b18c562e
NC
1545
1546 if (op2.mode == OP_EXP)
2469cfa2 1547 {
b18c562e
NC
1548 imm_op = 0;
1549 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1550
1551 if (op2.reg) /* Not PC relative. */
1552 fix_new_exp (frag_now, where + 2, 2,
1553 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1554 else
1555 fix_new_exp (frag_now, where + 2, 2,
1556 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1557 }
b18c562e
NC
1558 break;
1559
1560 case 2: /* Single-operand mostly instr. */
1561 if (opcode->insn_opnumb == 0)
2469cfa2 1562 {
b18c562e
NC
1563 /* reti instruction. */
1564 frag = frag_more (2);
1565 bfd_putl16 ((bfd_vma) bin, frag);
1566 break;
2469cfa2 1567 }
2469cfa2 1568
b18c562e
NC
1569 line = extract_operand (line, l1, sizeof (l1));
1570 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1571 if (res)
1572 break; /* Error in operand. */
2469cfa2 1573
b18c562e
NC
1574 bin |= op1.reg | (op1.am << 4);
1575 __is = 1 + op1.ol;
1576 frag = frag_more (2 * __is);
1577 where = frag - frag_now->fr_literal;
1578 bfd_putl16 ((bfd_vma) bin, frag);
1579
1580 if (op1.mode == OP_EXP)
2469cfa2 1581 {
b18c562e
NC
1582 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1583
1584 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1585 fix_new_exp (frag_now, where + 2, 2,
1586 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1587 else
1588 fix_new_exp (frag_now, where + 2, 2,
1589 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1590 }
b18c562e 1591 break;
2469cfa2 1592
b18c562e
NC
1593 case 3: /* Conditional jumps instructions. */
1594 line = extract_operand (line, l1, sizeof (l1));
1595 /* l1 is a label. */
1596 if (l1[0])
2469cfa2 1597 {
b18c562e
NC
1598 char *m = l1;
1599 expressionS exp;
2469cfa2 1600
b18c562e
NC
1601 if (*m == '$')
1602 m++;
2469cfa2 1603
b18c562e
NC
1604 parse_exp (m, &exp);
1605 frag = frag_more (2); /* Instr size is 1 word. */
2469cfa2 1606
b18c562e 1607 /* In order to handle something like:
2469cfa2 1608
b18c562e
NC
1609 and #0x8000, r5
1610 tst r5
1611 jz 4 ; skip next 4 bytes
1612 inv r5
1613 inc r5
1614 nop ; will jump here if r5 positive or zero
2469cfa2 1615
b18c562e 1616 jCOND -n ;assumes jump n bytes backward:
2469cfa2 1617
b18c562e
NC
1618 mov r5,r6
1619 jmp -2
2469cfa2 1620
b18c562e
NC
1621 is equal to:
1622 lab:
1623 mov r5,r6
1624 jmp lab
1625
1626 jCOND $n ; jump from PC in either direction. */
2469cfa2 1627
b18c562e
NC
1628 if (exp.X_op == O_constant)
1629 {
1630 int x = exp.X_add_number;
2469cfa2 1631
b18c562e
NC
1632 if (x & 1)
1633 {
1634 as_warn (_("Even number required. Rounded to %d"), x + 1);
1635 x++;
1636 }
2469cfa2 1637
b18c562e
NC
1638 if ((*l1 == '$' && x > 0) || x < 0)
1639 x -= 2;
2469cfa2 1640
b18c562e
NC
1641 x >>= 1;
1642
1643 if (x > 512 || x < -511)
1644 {
1645 as_bad (_("Wrong displacement %d"), x << 1);
1646 break;
1647 }
1648
1649 bin |= x & 0x3ff;
1650 bfd_putl16 ((bfd_vma) bin, frag);
1651 }
1652 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 1653 {
b18c562e
NC
1654 where = frag - frag_now->fr_literal;
1655 fix_new_exp (frag_now, where, 2,
1656 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1657
1658 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 1659 }
b18c562e 1660 else if (*l1 == '$')
2469cfa2 1661 {
b18c562e
NC
1662 as_bad (_("instruction requires label sans '$'"));
1663 break;
2469cfa2 1664 }
b18c562e 1665 else
2469cfa2 1666 {
b18c562e
NC
1667 as_bad (_
1668 ("instruction requires label or value in range -511:512"));
1669 break;
2469cfa2
NC
1670 }
1671 }
b18c562e
NC
1672 else
1673 {
1674 as_bad (_("instruction requires label"));
1675 break;
1676 }
1677 break;
2469cfa2 1678
b18c562e
NC
1679 case 4: /* Extended jumps. */
1680 line = extract_operand (line, l1, sizeof (l1));
1681 if (l1[0])
2469cfa2 1682 {
b18c562e
NC
1683 char *m = l1;
1684 expressionS exp;
2469cfa2 1685
b18c562e
NC
1686 /* Ignore absolute addressing. make it PC relative anyway. */
1687 if (*m == '#' || *m == '$')
1688 m++;
2469cfa2 1689
b18c562e
NC
1690 parse_exp (m, & exp);
1691 if (exp.X_op == O_symbol)
2469cfa2 1692 {
b18c562e
NC
1693 /* Relaxation required. */
1694 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1695
1696 frag = frag_more (8);
1697 bfd_putl16 ((bfd_vma) rc.sop, frag);
1698 frag = frag_variant (rs_machine_dependent, 8, 2,
1699 ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
1700 exp.X_add_symbol,
1701 0, /* Offset is zero if jump dist less than 1K. */
1702 (char *) frag);
1703 break;
2469cfa2
NC
1704 }
1705 }
b18c562e
NC
1706
1707 as_bad (_("instruction requires label"));
1708 break;
1709
1710 case 5: /* Emulated extended branches. */
1711 line = extract_operand (line, l1, sizeof (l1));
1712 if (l1[0])
2469cfa2 1713 {
b18c562e
NC
1714 char * m = l1;
1715 expressionS exp;
1716
1717 /* Ignore absolute addressing. make it PC relative anyway. */
1718 if (*m == '#' || *m == '$')
1719 m++;
1720
1721 parse_exp (m, & exp);
1722 if (exp.X_op == O_symbol)
1723 {
1724 /* Relaxation required. */
1725 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1726
1727 frag = frag_more (8);
1728 bfd_putl16 ((bfd_vma) hc.op0, frag);
1729 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1730 frag = frag_variant (rs_machine_dependent, 8, 2,
1731 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
1732 exp.X_add_symbol,
1733 0, /* Offset is zero if jump dist less than 1K. */
1734 (char *) frag);
1735 break;
1736 }
2469cfa2
NC
1737 }
1738
b18c562e
NC
1739 as_bad (_("instruction requires label"));
1740 break;
2469cfa2 1741
b18c562e
NC
1742 default:
1743 as_bad (_("Ilegal instruction or not implmented opcode."));
1744 }
2469cfa2 1745
b18c562e
NC
1746 input_line_pointer = line;
1747 return 0;
1748}
2469cfa2 1749
b18c562e
NC
1750void
1751md_assemble (char * str)
1752{
1753 struct msp430_opcode_s * opcode;
1754 char cmd[32];
1755 unsigned int i = 0;
2469cfa2 1756
b18c562e
NC
1757 str = skip_space (str); /* Skip leading spaces. */
1758 str = extract_cmd (str, cmd, sizeof (cmd));
2469cfa2 1759
b18c562e
NC
1760 while (cmd[i] && i < sizeof (cmd))
1761 {
1762 char a = TOLOWER (cmd[i]);
1763 cmd[i] = a;
1764 i++;
2469cfa2 1765 }
2469cfa2 1766
b18c562e 1767 if (!cmd[0])
2469cfa2 1768 {
b18c562e
NC
1769 as_bad (_("can't find opcode "));
1770 return;
1771 }
2469cfa2 1772
b18c562e 1773 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 1774
b18c562e
NC
1775 if (opcode == NULL)
1776 {
1777 as_bad (_("unknown opcode `%s'"), cmd);
1778 return;
2469cfa2 1779 }
2469cfa2 1780
b18c562e
NC
1781 {
1782 char *__t = input_line_pointer;
2469cfa2 1783
b18c562e
NC
1784 msp430_operands (opcode, str);
1785 input_line_pointer = __t;
1786 }
1787}
2469cfa2
NC
1788
1789/* GAS will call this function for each section at the end of the assembly,
1790 to permit the CPU backend to adjust the alignment of a section. */
1791
1792valueT
b18c562e 1793md_section_align (asection * seg, valueT addr)
2469cfa2
NC
1794{
1795 int align = bfd_get_section_alignment (stdoutput, seg);
1796
1797 return ((addr + (1 << align) - 1) & (-1 << align));
1798}
1799
1800/* If you define this macro, it should return the offset between the
1801 address of a PC relative fixup and the position from which the PC
1802 relative adjustment should be made. On many processors, the base
1803 of a PC relative instruction is the next instruction, so this
1804 macro would return the length of an instruction. */
1805
1806long
b18c562e 1807md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
1808{
1809 if (fixp->fx_addsy != (symbolS *) NULL
1810 && (!S_IS_DEFINED (fixp->fx_addsy)
1811 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1812 return 0;
1813
1814 return fixp->fx_frag->fr_address + fixp->fx_where;
1815}
1816
1817/* GAS will call this for each fixup. It should store the correct
1818 value in the object file. */
1819
1820void
b18c562e 1821md_apply_fix3 (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 1822{
b18c562e 1823 unsigned char * where;
2469cfa2
NC
1824 unsigned long insn;
1825 long value;
1826
1827 if (fixp->fx_addsy == (symbolS *) NULL)
1828 {
1829 value = *valuep;
1830 fixp->fx_done = 1;
1831 }
1832 else if (fixp->fx_pcrel)
1833 {
1834 segT s = S_GET_SEGMENT (fixp->fx_addsy);
1835
1836 if (fixp->fx_addsy && (s == seg || s == absolute_section))
1837 {
18af0b39
NC
1838 /* FIXME: We can appear here only in case if we perform a pc
1839 relative jump to the label which is i) global, ii) locally
1840 defined or this is a jump to an absolute symbol.
1841 If this is an absolute symbol -- everything is OK.
1842 If this is a global label, we've got a symbol value defined
1843 twice:
1844 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1845 from this section start
1846 2. *valuep will contain the real offset from jump insn to the
1847 label
1848 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1849 will be incorrect. Therefore remove s_get_value. */
1850 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
1851 fixp->fx_done = 1;
1852 }
1853 else
1854 value = *valuep;
1855 }
1856 else
1857 {
1858 value = fixp->fx_offset;
1859
1860 if (fixp->fx_subsy != (symbolS *) NULL)
1861 {
1862 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1863 {
1864 value -= S_GET_VALUE (fixp->fx_subsy);
1865 fixp->fx_done = 1;
1866 }
1867 else
1868 {
1869 /* We don't actually support subtracting a symbol. */
1870 as_bad_where (fixp->fx_file, fixp->fx_line,
1871 _("expression too complex"));
1872 }
1873 }
1874 }
1875
1876 switch (fixp->fx_r_type)
1877 {
1878 default:
1879 fixp->fx_no_overflow = 1;
1880 break;
1881 case BFD_RELOC_MSP430_10_PCREL:
1882 break;
1883 }
1884
1885 if (fixp->fx_done)
1886 {
1887 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 1888 value, and stuff the instruction back again. */
2469cfa2 1889
2132e3a3 1890 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
1891
1892 insn = bfd_getl16 (where);
1893
1894 switch (fixp->fx_r_type)
1895 {
1896 case BFD_RELOC_MSP430_10_PCREL:
1897 if (value & 1)
1898 as_bad_where (fixp->fx_file, fixp->fx_line,
1899 _("odd address operand: %ld"), value);
1900
1901 /* Jumps are in words. */
1902 value >>= 1;
1903 --value; /* Correct PC. */
1904
1905 if (value < -512 || value > 511)
1906 as_bad_where (fixp->fx_file, fixp->fx_line,
1907 _("operand out of range: %ld"), value);
1908
1909 value &= 0x3ff; /* get rid of extended sign */
1910 bfd_putl16 ((bfd_vma) (value | insn), where);
1911 break;
1912
b18c562e 1913 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
1914 case BFD_RELOC_MSP430_16_PCREL:
1915 if (value & 1)
1916 as_bad_where (fixp->fx_file, fixp->fx_line,
1917 _("odd address operand: %ld"), value);
1918
1919 /* Nothing to be corrected here. */
1920 if (value < -32768 || value > 65536)
1921 as_bad_where (fixp->fx_file, fixp->fx_line,
1922 _("operand out of range: %ld"), value);
1923
1924 value &= 0xffff; /* Get rid of extended sign. */
1925 bfd_putl16 ((bfd_vma) value, where);
1926 break;
1927
1928 case BFD_RELOC_MSP430_16_PCREL_BYTE:
1929 /* Nothing to be corrected here. */
1930 if (value < -32768 || value > 65536)
1931 as_bad_where (fixp->fx_file, fixp->fx_line,
1932 _("operand out of range: %ld"), value);
1933
1934 value &= 0xffff; /* Get rid of extended sign. */
1935 bfd_putl16 ((bfd_vma) value, where);
1936 break;
1937
1938 case BFD_RELOC_32:
1939 bfd_putl16 ((bfd_vma) value, where);
1940 break;
1941
1942 case BFD_RELOC_MSP430_16:
1943 case BFD_RELOC_16:
1944 case BFD_RELOC_MSP430_16_BYTE:
1945 value &= 0xffff;
1946 bfd_putl16 ((bfd_vma) value, where);
1947 break;
1948
1949 default:
1950 as_fatal (_("line %d: unknown relocation type: 0x%x"),
1951 fixp->fx_line, fixp->fx_r_type);
1952 break;
1953 }
1954 }
1955 else
1956 {
1957 fixp->fx_addnumber = value;
1958 }
2469cfa2
NC
1959}
1960
1961/* A `BFD_ASSEMBLER' GAS will call this to generate a reloc. GAS
1962 will pass the resulting reloc to `bfd_install_relocation'. This
1963 currently works poorly, as `bfd_install_relocation' often does the
1964 wrong thing, and instances of `tc_gen_reloc' have been written to
1965 work around the problems, which in turns makes it difficult to fix
1966 `bfd_install_relocation'. */
1967
1968/* If while processing a fixup, a reloc really needs to be created
1969 then it is done here. */
1970
1971arelent *
b18c562e 1972tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 1973{
b18c562e 1974 arelent * reloc;
2469cfa2 1975
b18c562e 1976 reloc = xmalloc (sizeof (arelent));
2469cfa2 1977
b18c562e 1978 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2469cfa2
NC
1979 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1980
1981 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1982 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1983 if (reloc->howto == (reloc_howto_type *) NULL)
1984 {
1985 as_bad_where (fixp->fx_file, fixp->fx_line,
1986 _("reloc %d not supported by object file format"),
1987 (int) fixp->fx_r_type);
1988 return NULL;
1989 }
1990
1991 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1992 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1993 reloc->address = fixp->fx_offset;
1994
1995 reloc->addend = fixp->fx_offset;
1996
1997 return reloc;
1998}
1999
b18c562e
NC
2000int
2001md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
2002 asection * segment_type ATTRIBUTE_UNUSED)
2003{
2004 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
2005 {
2006 /* This is a jump -> pcrel mode. Nothing to do much here.
2007 Return value == 2. */
2008 fragP->fr_subtype =
2009 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
2010 }
2011 else if (fragP->fr_symbol)
2012 {
2013 /* Its got a segment, but its not ours. Even if fr_symbol is in
2014 an absolute segment, we dont know a displacement until we link
2015 object files. So it will always be long. This also applies to
2016 labels in a subsegment of current. Liker may relax it to short
2017 jump later. Return value == 8. */
2018 fragP->fr_subtype =
2019 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
2020 }
2021 else
2022 {
2023 /* We know the abs value. may be it is a jump to fixed address.
2024 Impossible in our case, cause all constants already handeled. */
2025 fragP->fr_subtype =
2026 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
2027 }
2469cfa2 2028
b18c562e
NC
2029 return md_relax_table[fragP->fr_subtype].rlx_length;
2030}
2031
2032void
2033md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
2034 asection * sec ATTRIBUTE_UNUSED,
2035 fragS * fragP)
2469cfa2 2036{
b18c562e
NC
2037 char * where = 0;
2038 int rela = -1;
2039 int i;
2040 struct rcodes_s * cc = NULL;
2041 struct hcodes_s * hc = NULL;
2042
2043 switch (fragP->fr_subtype)
2044 {
2045 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
2046 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
2047 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
2048 /* We do not have to convert anything here.
2049 Just apply a fix. */
2050 rela = BFD_RELOC_MSP430_10_PCREL;
2051 break;
2052
2053 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
2054 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
2055 /* Convert uncond branch jmp lab -> br lab. */
2056 cc = & msp430_rcodes[7];
2057 where = fragP->fr_literal + fragP->fr_fix;
2058 bfd_putl16 (cc->lop0, where);
2059 rela = BFD_RELOC_MSP430_RL_PCREL;
2060 fragP->fr_fix += 2;
2061 break;
2062
2063 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
2064 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
2065 {
2066 /* Other simple branches. */
2067 int insn = bfd_getl16 (fragP->fr_opcode);
2068
2069 insn &= 0xffff;
2070 /* Find actual instruction. */
2071 for (i = 0; i < 7 && !cc; i++)
2072 if (msp430_rcodes[i].sop == insn)
2073 cc = & msp430_rcodes[i];
2074 if (!cc || !cc->name)
2075 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2076 __FUNCTION__, (long) insn);
2077 where = fragP->fr_literal + fragP->fr_fix;
2078 bfd_putl16 (cc->lop0, where);
2079 bfd_putl16 (cc->lop1, where + 2);
2080 rela = BFD_RELOC_MSP430_RL_PCREL;
2081 fragP->fr_fix += 4;
2082 }
2083 break;
2084
2085 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
2086 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2087 cc = & msp430_rcodes[6];
2088 where = fragP->fr_literal + fragP->fr_fix;
2089 bfd_putl16 (cc->lop0, where);
2090 bfd_putl16 (cc->lop1, where + 2);
2091 bfd_putl16 (cc->lop2, where + 4);
2092 rela = BFD_RELOC_MSP430_RL_PCREL;
2093 fragP->fr_fix += 6;
2094 break;
2095
2096 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2097 {
2098 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2099
2100 insn &= 0xffff;
2101 for (i = 0; i < 4 && !hc; i++)
2102 if (msp430_hcodes[i].op1 == insn)
2103 hc = &msp430_hcodes[i];
2104 if (!hc || !hc->name)
2105 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2106 __FUNCTION__, (long) insn);
2107 rela = BFD_RELOC_MSP430_10_PCREL;
2108 /* Apply a fix for a first label if necessary.
2109 another fix will be applied to the next word of insn anyway. */
2110 if (hc->tlab == 2)
2111 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2112 fragP->fr_offset, TRUE, rela);
2113 fragP->fr_fix += 2;
2114 }
2115
2116 break;
2117
2118 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2119 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2120 {
2121 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2122
2123 insn &= 0xffff;
2124 for (i = 0; i < 4 && !hc; i++)
2125 if (msp430_hcodes[i].op1 == insn)
2126 hc = & msp430_hcodes[i];
2127 if (!hc || !hc->name)
2128 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2129 __FUNCTION__, (long) insn);
2130 rela = BFD_RELOC_MSP430_RL_PCREL;
2131 where = fragP->fr_literal + fragP->fr_fix;
2132 bfd_putl16 (hc->lop0, where);
2133 bfd_putl16 (hc->lop1, where + 2);
2134 bfd_putl16 (hc->lop2, where + 4);
2135 fragP->fr_fix += 6;
2136 }
2137 break;
2138
2139 default:
2140 as_fatal (_("internal inconsistency problem in %s: %lx"),
2141 __FUNCTION__, (long) fragP->fr_subtype);
2142 break;
2143 }
2144
2145 /* Now apply fix. */
2146 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2147 fragP->fr_offset, TRUE, rela);
2148 /* Just fixed 2 bytes. */
2149 fragP->fr_fix += 2;
2469cfa2
NC
2150}
2151
b18c562e
NC
2152/* Relax fragment. Mostly stolen from hc11 and mcore
2153 which arches I think I know. */
2469cfa2 2154
b18c562e
NC
2155long
2156msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2157 long stretch ATTRIBUTE_UNUSED)
2469cfa2 2158{
b18c562e
NC
2159 long growth;
2160 offsetT aim = 0;
2161 symbolS *symbolP;
2162 const relax_typeS *this_type;
2163 const relax_typeS *start_type;
2164 relax_substateT next_state;
2165 relax_substateT this_state;
2166 const relax_typeS *table = md_relax_table;
2167
2168 /* Nothing to be done if the frag has already max size. */
2169 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2170 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2171 return 0;
2172
2173 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2174 {
2175 symbolP = fragP->fr_symbol;
2176 if (symbol_resolved_p (symbolP))
2177 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2178 __FUNCTION__);
2179 /* We know the offset. calculate a distance. */
2180 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2181 }
2182
2183 this_state = fragP->fr_subtype;
2184 start_type = this_type = table + this_state;
2185
2186 if (aim < 0)
2187 {
2188 /* Look backwards. */
2189 for (next_state = this_type->rlx_more; next_state;)
2190 if (aim >= this_type->rlx_backward)
2191 next_state = 0;
2192 else
2193 {
2194 /* Grow to next state. */
2195 this_state = next_state;
2196 this_type = table + this_state;
2197 next_state = this_type->rlx_more;
2198 }
2199 }
2200 else
2201 {
2202 /* Look forwards. */
2203 for (next_state = this_type->rlx_more; next_state;)
2204 if (aim <= this_type->rlx_forward)
2205 next_state = 0;
2206 else
2207 {
2208 /* Grow to next state. */
2209 this_state = next_state;
2210 this_type = table + this_state;
2211 next_state = this_type->rlx_more;
2212 }
2213 }
2214
2215 growth = this_type->rlx_length - start_type->rlx_length;
2216 if (growth != 0)
2217 fragP->fr_subtype = this_state;
2218 return growth;
2469cfa2 2219}
This page took 0.237364 seconds and 4 git commands to generate.