[PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav...
[binutils-gdb.git] / gas / config / tc-msp430.c
blob5821b1c81108de78fcf6930f2d04d350fad7aa88
1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2019 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
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 3, or (at your option)
11 any later version.
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.
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
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include "as.h"
24 #include <limits.h>
25 #include "subsegs.h"
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
34 following code:
36 jump .l1
37 nop
38 jump subroutine ; external symbol
39 .l1:
40 nop
41 ret
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
45 2: nop
46 4: br subroutine
47 .l1:
48 8: nop
49 10: ret
51 If the 'subroutine' is within +-1024 bytes range then linker
52 will produce:
53 0: jmp .text +0x08
54 2: nop
55 4: jmp subroutine
56 .l1:
57 6: nop
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax;
70 int msp430_enable_polys;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
85 le <= see below
86 leu <= see below
88 gt > see below
89 gtu > see below
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
103 struct rcodes_s
105 const char * name;
106 int index; /* Corresponding insn_opnumb. */
107 int sop; /* Opcode if jump length is short. */
108 long lpos; /* Label position. */
109 long lop0; /* Opcode 1 _word_ (16 bits). */
110 long lop1; /* Opcode second word. */
111 long lop2; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes[] =
119 MSP430_RLC (beq, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
127 {0,0,0,0,0,0,0}
130 #undef MSP430_RLC
131 #define MSP430_RLC(n,i,sop,o1) \
132 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
134 static struct rcodes_s msp430x_rcodes[] =
136 MSP430_RLC (beq, 0, 0x2400, 0x2000),
137 MSP430_RLC (bne, 1, 0x2000, 0x2400),
138 MSP430_RLC (blt, 2, 0x3800, 0x3400),
139 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
140 MSP430_RLC (bge, 4, 0x3400, 0x3800),
141 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
142 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
143 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
144 {0,0,0,0,0,0,0}
146 #undef MSP430_RLC
148 /* More difficult than above and they have format 5.
150 COND EXPL SHORT LONG
151 =================================================================
152 gt > jeq +2; jge label jeq +6; jl +4; br label
153 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
154 leu <= jeq label; jlo label jeq +2; jhs +4; br label
155 le <= jeq label; jl label jeq +2; jge +4; br label
156 ================================================================= */
158 struct hcodes_s
160 const char * name;
161 int index; /* Corresponding insn_opnumb. */
162 int tlab; /* Number of labels in short mode. */
163 int op0; /* Opcode for first word of short jump. */
164 int op1; /* Opcode for second word of short jump. */
165 int lop0; /* Opcodes for long jump mode. */
166 int lop1;
167 int lop2;
170 static struct hcodes_s msp430_hcodes[] =
172 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
173 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
174 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
175 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
176 {0,0,0,0,0,0,0,0}
179 static struct hcodes_s msp430x_hcodes[] =
181 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
182 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
183 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
184 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
185 {0,0,0,0,0,0,0,0}
188 const char comment_chars[] = ";";
189 const char line_comment_chars[] = "#";
190 const char line_separator_chars[] = "{";
191 const char EXP_CHARS[] = "eE";
192 const char FLT_CHARS[] = "dD";
194 /* Handle long expressions. */
195 extern LITTLENUM_TYPE generic_bignum[];
197 static struct hash_control *msp430_hash;
199 /* Relaxations. */
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
205 #define CNRL 2
206 #define CUBL 4
207 #define CNOL 8
208 #define CSBL 6
209 #define CEBL 4
211 /* Length. */
212 #define STATE_BITS10 1 /* Wild guess. short jump. */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */
214 #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table[] =
223 /* Unused. */
224 {1, 1, 0, 0},
225 {1, 1, 0, 0},
226 {1, 1, 0, 0},
227 {1, 1, 0, 0},
229 /* Unconditional jump. */
230 {1, 1, 8, 5},
231 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
232 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
233 {1, 1, CUBL, 0}, /* state undef */
235 /* Simple branches. */
236 {0, 0, 8, 9},
237 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
238 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
239 {1, 1, CSBL, 0},
241 /* blt no overflow branch. */
242 {1, 1, 8, 13},
243 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
244 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
245 {1, 1, CNOL, 0},
247 /* Emulated branches. */
248 {1, 1, 8, 17},
249 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
250 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
251 {1, 1, CNOL, 0}
255 #define MAX_OP_LEN 4096
257 typedef enum msp_isa
259 MSP_ISA_430,
260 MSP_ISA_430X,
261 MSP_ISA_430Xv2
262 } msp_isa;
264 static enum msp_isa selected_isa = MSP_ISA_430Xv2;
266 static inline bfd_boolean
267 target_is_430x (void)
269 return selected_isa >= MSP_ISA_430X;
272 static inline bfd_boolean
273 target_is_430xv2 (void)
275 return selected_isa == MSP_ISA_430Xv2;
278 /* Generate an absolute 16-bit relocation.
279 For the 430X we generate a relocation without linker range checking
280 if the value is being used in an extended (ie 20-bit) instruction,
281 otherwise if have a shifted expression we use a HI reloc.
282 For the 430 we generate a relocation without assembler range checking
283 if we are handling an immediate value or a byte-width instruction. */
285 #undef CHECK_RELOC_MSP430
286 #define CHECK_RELOC_MSP430(OP) \
287 (target_is_430x () \
288 ? (extended_op \
289 ? BFD_RELOC_16 \
290 : ((OP).vshift == 1) \
291 ? BFD_RELOC_MSP430_ABS_HI16 \
292 : BFD_RELOC_MSP430X_ABS16) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
302 (target_is_430x () \
303 ? BFD_RELOC_MSP430X_PCR16 \
304 : (imm_op || byte_op) \
305 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
307 /* Profiling capability:
308 It is a performance hit to use gcc's profiling approach for this tiny target.
309 Even more -- jtag hardware facility does not perform any profiling functions.
310 However we've got gdb's built-in simulator where we can do anything.
311 Therefore my suggestion is:
313 We define new section ".profiler" which holds all profiling information.
314 We define new pseudo operation .profiler which will instruct assembler to
315 add new profile entry to the object file. Profile should take place at the
316 present address.
318 Pseudo-op format:
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
323 s - function Start
324 x - function eXit
325 i - function is in Init section
326 f - function is in Fini section
327 l - Library call
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
331 P - Prologue start
332 p - Prologue end
333 E - Epilogue start
334 e - Epilogue end
335 j - long Jump/ sjlj unwind
336 a - an Arbitrary code fragment
337 t - exTra parameter saved (constant value like frame size)
338 '""' optional: "sil" == sil
340 function_to_profile - function's address
341 cycle_corrector - a value which should be added to the cycle
342 counter, zero if omitted
343 extra - some extra parameter, zero if omitted.
345 For example:
346 ------------------------------
347 .global fxx
348 .type fxx,@function
349 fxx:
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
353 push r11
354 push r10
355 push r9
356 push r8
357 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
358 ; (this is a prologue end)
359 ; note, that spare var filled with the frame size
360 mov r15,r8
361 ....
362 .profiler cdE,fxx ; check stack
363 pop r8
364 pop r9
365 pop r10
366 pop r11
367 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
368 ret ; cause 'ret' insn takes 3 cycles
369 -------------------------------
371 This profiling approach does not produce any overhead and
372 absolutely harmless.
373 So, even profiled code can be uploaded to the MCU. */
374 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
375 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
376 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
377 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
378 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
379 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
380 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
381 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
382 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
383 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
384 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
385 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
386 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
387 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
388 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
389 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
391 static int
392 pow2value (int y)
394 int n = 0;
395 unsigned int x;
397 x = y;
399 if (!x)
400 return 1;
402 for (; x; x = x >> 1)
403 if (x & 1)
404 n++;
406 return n == 1;
409 /* Parse ordinary expression. */
411 static char *
412 parse_exp (char * s, expressionS * op)
414 input_line_pointer = s;
415 expression (op);
416 if (op->X_op == O_absent)
417 as_bad (_("missing operand"));
419 /* Our caller is likely to check that the entire expression was parsed.
420 If we have found a hex constant with an 'h' suffix, ilp will be left
421 pointing at the 'h', so skip it here. */
422 if (input_line_pointer != NULL
423 && op->X_op == O_constant
424 && (*input_line_pointer == 'h' || *input_line_pointer == 'H'))
425 ++ input_line_pointer;
426 return input_line_pointer;
430 /* Delete spaces from s: X ( r 1 2) => X(r12). */
432 static void
433 del_spaces (char * s)
435 while (*s)
437 if (ISSPACE (*s))
439 char *m = s + 1;
441 while (ISSPACE (*m) && *m)
442 m++;
443 memmove (s, m, strlen (m) + 1);
445 else
446 s++;
450 static inline char *
451 skip_space (char * s)
453 while (ISSPACE (*s))
454 ++s;
455 return s;
458 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
460 static char *
461 extract_operand (char * from, char * to, int limit)
463 int size = 0;
465 /* Drop leading whitespace. */
466 from = skip_space (from);
468 while (size < limit && *from)
470 *(to + size) = *from;
471 if (*from == ',' || *from == ';' || *from == '\n')
472 break;
473 from++;
474 size++;
477 *(to + size) = 0;
478 del_spaces (to);
480 from++;
482 return from;
485 static void
486 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
488 char buffer[1024];
489 char f[32];
490 char * str = buffer;
491 char * flags = f;
492 int p_flags = 0;
493 char * halt;
494 int ops = 0;
495 int left;
496 char * s;
497 segT seg;
498 int subseg;
499 char * end = 0;
500 expressionS exp;
501 expressionS exp1;
503 s = input_line_pointer;
504 end = input_line_pointer;
506 while (*end && *end != '\n')
507 end++;
509 while (*s && *s != '\n')
511 if (*s == ',')
512 ops++;
513 s++;
516 left = 3 - ops;
518 if (ops < 1)
520 as_bad (_(".profiler pseudo requires at least two operands."));
521 input_line_pointer = end;
522 return;
525 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
527 while (*flags)
529 switch (*flags)
531 case '"':
532 break;
533 case 'a':
534 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
535 break;
536 case 'j':
537 p_flags |= MSP430_PROFILER_FLAG_JUMP;
538 break;
539 case 'P':
540 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
541 break;
542 case 'p':
543 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
544 break;
545 case 'E':
546 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
547 break;
548 case 'e':
549 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
550 break;
551 case 's':
552 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
553 break;
554 case 'x':
555 p_flags |= MSP430_PROFILER_FLAG_EXIT;
556 break;
557 case 'i':
558 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
559 break;
560 case 'f':
561 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
562 break;
563 case 'l':
564 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
565 break;
566 case 'c':
567 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
568 break;
569 case 'd':
570 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
571 break;
572 case 'I':
573 p_flags |= MSP430_PROFILER_FLAG_ISR;
574 break;
575 case 't':
576 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
577 break;
578 default:
579 as_warn (_("unknown profiling flag - ignored."));
580 break;
582 flags++;
585 if (p_flags
586 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
587 | MSP430_PROFILER_FLAG_EXIT))
588 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
589 | MSP430_PROFILER_FLAG_PROLEND
590 | MSP430_PROFILER_FLAG_EPISTART
591 | MSP430_PROFILER_FLAG_EPIEND))
592 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
593 | MSP430_PROFILER_FLAG_FINISECT))))
595 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
596 input_line_pointer = end;
597 return;
600 /* Generate temp symbol which denotes current location. */
601 if (now_seg == absolute_section) /* Paranoia ? */
603 exp1.X_op = O_constant;
604 exp1.X_add_number = abs_section_offset;
605 as_warn (_("profiling in absolute section?"));
607 else
609 exp1.X_op = O_symbol;
610 exp1.X_add_symbol = symbol_temp_new_now ();
611 exp1.X_add_number = 0;
614 /* Generate a symbol which holds flags value. */
615 exp.X_op = O_constant;
616 exp.X_add_number = p_flags;
618 /* Save current section. */
619 seg = now_seg;
620 subseg = now_subseg;
622 /* Now go to .profiler section. */
623 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0, 0);
625 /* Save flags. */
626 emit_expr (& exp, 2);
628 /* Save label value. */
629 emit_expr (& exp1, 2);
631 while (ops--)
633 /* Now get profiling info. */
634 halt = extract_operand (input_line_pointer, str, 1024);
635 /* Process like ".word xxx" directive. */
636 (void) parse_exp (str, & exp);
637 emit_expr (& exp, 2);
638 input_line_pointer = halt;
641 /* Fill the rest with zeros. */
642 exp.X_op = O_constant;
643 exp.X_add_number = 0;
644 while (left--)
645 emit_expr (& exp, 2);
647 /* Return to current section. */
648 subseg_set (seg, subseg);
651 static char *
652 extract_word (char * from, char * to, int limit)
654 char *op_end;
655 int size = 0;
657 /* Drop leading whitespace. */
658 from = skip_space (from);
659 *to = 0;
661 /* Find the op code end. */
662 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
664 to[size++] = *op_end++;
665 if (size + 1 >= limit)
666 break;
669 to[size] = 0;
670 return op_end;
673 #define OPTION_MMCU 'm'
674 #define OPTION_RELAX 'Q'
675 #define OPTION_POLYMORPHS 'P'
676 #define OPTION_LARGE 'l'
677 static bfd_boolean large_model = FALSE;
678 #define OPTION_NO_INTR_NOPS 'N'
679 #define OPTION_INTR_NOPS 'n'
680 static bfd_boolean gen_interrupt_nops = FALSE;
681 #define OPTION_WARN_INTR_NOPS 'y'
682 #define OPTION_NO_WARN_INTR_NOPS 'Y'
683 static bfd_boolean warn_interrupt_nops = TRUE;
684 #define OPTION_UNKNOWN_INTR_NOPS 'u'
685 #define OPTION_NO_UNKNOWN_INTR_NOPS 'U'
686 static bfd_boolean do_unknown_interrupt_nops = TRUE;
687 #define OPTION_MCPU 'c'
688 #define OPTION_MOVE_DATA 'd'
689 static bfd_boolean move_data = FALSE;
690 #define OPTION_DATA_REGION 'r'
691 static bfd_boolean upper_data_region_in_use = FALSE;
693 enum
695 OPTION_SILICON_ERRATA = OPTION_MD_BASE,
696 OPTION_SILICON_ERRATA_WARN,
699 static unsigned int silicon_errata_fix = 0;
700 static unsigned int silicon_errata_warn = 0;
701 #define SILICON_ERRATA_CPU4 (1 << 0)
702 #define SILICON_ERRATA_CPU8 (1 << 1)
703 #define SILICON_ERRATA_CPU11 (1 << 2)
704 #define SILICON_ERRATA_CPU12 (1 << 3)
705 #define SILICON_ERRATA_CPU13 (1 << 4)
706 #define SILICON_ERRATA_CPU19 (1 << 5)
708 static void
709 msp430_set_arch (int option)
711 char str[32]; /* 32 for good measure. */
713 input_line_pointer = extract_word (input_line_pointer, str, 32);
715 md_parse_option (option, str);
716 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
717 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
720 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
721 Keep these two structures in sync.
722 The data in this structure has been extracted from version 1.194 of the
723 devices.csv file released by TI in September 2016. */
725 struct msp430_mcu_data
727 const char * name;
728 unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
729 unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
731 msp430_mcu_data [] =
733 { "cc430f5123",2,8 },
734 { "cc430f5125",2,8 },
735 { "cc430f5133",2,8 },
736 { "cc430f5135",2,8 },
737 { "cc430f5137",2,8 },
738 { "cc430f5143",2,8 },
739 { "cc430f5145",2,8 },
740 { "cc430f5147",2,8 },
741 { "cc430f6125",2,8 },
742 { "cc430f6126",2,8 },
743 { "cc430f6127",2,8 },
744 { "cc430f6135",2,8 },
745 { "cc430f6137",2,8 },
746 { "cc430f6143",2,8 },
747 { "cc430f6145",2,8 },
748 { "cc430f6147",2,8 },
749 { "msp430afe221",0,2 },
750 { "msp430afe222",0,2 },
751 { "msp430afe223",0,2 },
752 { "msp430afe231",0,2 },
753 { "msp430afe232",0,2 },
754 { "msp430afe233",0,2 },
755 { "msp430afe251",0,2 },
756 { "msp430afe252",0,2 },
757 { "msp430afe253",0,2 },
758 { "msp430bt5190",2,8 },
759 { "msp430c091",0,0 },
760 { "msp430c092",0,0 },
761 { "msp430c111",0,0 },
762 { "msp430c1111",0,0 },
763 { "msp430c112",0,0 },
764 { "msp430c1121",0,0 },
765 { "msp430c1331",0,0 },
766 { "msp430c1351",0,0 },
767 { "msp430c311s",0,0 },
768 { "msp430c312",0,0 },
769 { "msp430c313",0,0 },
770 { "msp430c314",0,0 },
771 { "msp430c315",0,0 },
772 { "msp430c323",0,0 },
773 { "msp430c325",0,0 },
774 { "msp430c336",0,1 },
775 { "msp430c337",0,1 },
776 { "msp430c412",0,0 },
777 { "msp430c413",0,0 },
778 { "msp430cg4616",1,1 },
779 { "msp430cg4617",1,1 },
780 { "msp430cg4618",1,1 },
781 { "msp430cg4619",1,1 },
782 { "msp430e112",0,0 },
783 { "msp430e313",0,0 },
784 { "msp430e315",0,0 },
785 { "msp430e325",0,0 },
786 { "msp430e337",0,1 },
787 { "msp430f110",0,0 },
788 { "msp430f1101",0,0 },
789 { "msp430f1101a",0,0 },
790 { "msp430f1111",0,0 },
791 { "msp430f1111a",0,0 },
792 { "msp430f112",0,0 },
793 { "msp430f1121",0,0 },
794 { "msp430f1121a",0,0 },
795 { "msp430f1122",0,0 },
796 { "msp430f1132",0,0 },
797 { "msp430f122",0,0 },
798 { "msp430f1222",0,0 },
799 { "msp430f123",0,0 },
800 { "msp430f1232",0,0 },
801 { "msp430f133",0,0 },
802 { "msp430f135",0,0 },
803 { "msp430f147",0,1 },
804 { "msp430f1471",0,1 },
805 { "msp430f148",0,1 },
806 { "msp430f1481",0,1 },
807 { "msp430f149",0,1 },
808 { "msp430f1491",0,1 },
809 { "msp430f155",0,0 },
810 { "msp430f156",0,0 },
811 { "msp430f157",0,0 },
812 { "msp430f1610",0,1 },
813 { "msp430f1611",0,1 },
814 { "msp430f1612",0,1 },
815 { "msp430f167",0,1 },
816 { "msp430f168",0,1 },
817 { "msp430f169",0,1 },
818 { "msp430f2001",0,0 },
819 { "msp430f2002",0,0 },
820 { "msp430f2003",0,0 },
821 { "msp430f2011",0,0 },
822 { "msp430f2012",0,0 },
823 { "msp430f2013",0,0 },
824 { "msp430f2101",0,0 },
825 { "msp430f2111",0,0 },
826 { "msp430f2112",0,0 },
827 { "msp430f2121",0,0 },
828 { "msp430f2122",0,0 },
829 { "msp430f2131",0,0 },
830 { "msp430f2132",0,0 },
831 { "msp430f2232",0,0 },
832 { "msp430f2234",0,0 },
833 { "msp430f2252",0,0 },
834 { "msp430f2254",0,0 },
835 { "msp430f2272",0,0 },
836 { "msp430f2274",0,0 },
837 { "msp430f233",0,2 },
838 { "msp430f2330",0,2 },
839 { "msp430f235",0,2 },
840 { "msp430f2350",0,2 },
841 { "msp430f2370",0,2 },
842 { "msp430f2410",0,2 },
843 { "msp430f2416",1,2 },
844 { "msp430f2417",1,2 },
845 { "msp430f2418",1,2 },
846 { "msp430f2419",1,2 },
847 { "msp430f247",0,2 },
848 { "msp430f2471",0,2 },
849 { "msp430f248",0,2 },
850 { "msp430f2481",0,2 },
851 { "msp430f249",0,2 },
852 { "msp430f2491",0,2 },
853 { "msp430f2616",1,2 },
854 { "msp430f2617",1,2 },
855 { "msp430f2618",1,2 },
856 { "msp430f2619",1,2 },
857 { "msp430f412",0,0 },
858 { "msp430f413",0,0 },
859 { "msp430f4132",0,0 },
860 { "msp430f415",0,0 },
861 { "msp430f4152",0,0 },
862 { "msp430f417",0,0 },
863 { "msp430f423",0,1 },
864 { "msp430f423a",0,1 },
865 { "msp430f425",0,1 },
866 { "msp430f4250",0,0 },
867 { "msp430f425a",0,1 },
868 { "msp430f4260",0,0 },
869 { "msp430f427",0,1 },
870 { "msp430f4270",0,0 },
871 { "msp430f427a",0,1 },
872 { "msp430f435",0,0 },
873 { "msp430f4351",0,0 },
874 { "msp430f436",0,0 },
875 { "msp430f4361",0,0 },
876 { "msp430f437",0,0 },
877 { "msp430f4371",0,0 },
878 { "msp430f438",0,0 },
879 { "msp430f439",0,0 },
880 { "msp430f447",0,1 },
881 { "msp430f448",0,1 },
882 { "msp430f4481",0,1 },
883 { "msp430f449",0,1 },
884 { "msp430f4491",0,1 },
885 { "msp430f4616",1,1 },
886 { "msp430f46161",1,1 },
887 { "msp430f4617",1,1 },
888 { "msp430f46171",1,1 },
889 { "msp430f4618",1,1 },
890 { "msp430f46181",1,1 },
891 { "msp430f4619",1,1 },
892 { "msp430f46191",1,1 },
893 { "msp430f47126",1,4 },
894 { "msp430f47127",1,4 },
895 { "msp430f47163",1,4 },
896 { "msp430f47166",1,4 },
897 { "msp430f47167",1,4 },
898 { "msp430f47173",1,4 },
899 { "msp430f47176",1,4 },
900 { "msp430f47177",1,4 },
901 { "msp430f47183",1,4 },
902 { "msp430f47186",1,4 },
903 { "msp430f47187",1,4 },
904 { "msp430f47193",1,4 },
905 { "msp430f47196",1,4 },
906 { "msp430f47197",1,4 },
907 { "msp430f477",0,0 },
908 { "msp430f478",0,0 },
909 { "msp430f4783",0,4 },
910 { "msp430f4784",0,4 },
911 { "msp430f479",0,0 },
912 { "msp430f4793",0,4 },
913 { "msp430f4794",0,4 },
914 { "msp430f5131",2,8 },
915 { "msp430f5132",2,8 },
916 { "msp430f5151",2,8 },
917 { "msp430f5152",2,8 },
918 { "msp430f5171",2,8 },
919 { "msp430f5172",2,8 },
920 { "msp430f5212",2,8 },
921 { "msp430f5213",2,8 },
922 { "msp430f5214",2,8 },
923 { "msp430f5217",2,8 },
924 { "msp430f5218",2,8 },
925 { "msp430f5219",2,8 },
926 { "msp430f5222",2,8 },
927 { "msp430f5223",2,8 },
928 { "msp430f5224",2,8 },
929 { "msp430f5227",2,8 },
930 { "msp430f5228",2,8 },
931 { "msp430f5229",2,8 },
932 { "msp430f5232",2,8 },
933 { "msp430f5234",2,8 },
934 { "msp430f5237",2,8 },
935 { "msp430f5239",2,8 },
936 { "msp430f5242",2,8 },
937 { "msp430f5244",2,8 },
938 { "msp430f5247",2,8 },
939 { "msp430f5249",2,8 },
940 { "msp430f5252",2,8 },
941 { "msp430f5253",2,8 },
942 { "msp430f5254",2,8 },
943 { "msp430f5255",2,8 },
944 { "msp430f5256",2,8 },
945 { "msp430f5257",2,8 },
946 { "msp430f5258",2,8 },
947 { "msp430f5259",2,8 },
948 { "msp430f5304",2,8 },
949 { "msp430f5308",2,8 },
950 { "msp430f5309",2,8 },
951 { "msp430f5310",2,8 },
952 { "msp430f5324",2,8 },
953 { "msp430f5325",2,8 },
954 { "msp430f5326",2,8 },
955 { "msp430f5327",2,8 },
956 { "msp430f5328",2,8 },
957 { "msp430f5329",2,8 },
958 { "msp430f5333",2,8 },
959 { "msp430f5335",2,8 },
960 { "msp430f5336",2,8 },
961 { "msp430f5338",2,8 },
962 { "msp430f5340",2,8 },
963 { "msp430f5341",2,8 },
964 { "msp430f5342",2,8 },
965 { "msp430f5358",2,8 },
966 { "msp430f5359",2,8 },
967 { "msp430f5418",2,8 },
968 { "msp430f5418a",2,8 },
969 { "msp430f5419",2,8 },
970 { "msp430f5419a",2,8 },
971 { "msp430f5435",2,8 },
972 { "msp430f5435a",2,8 },
973 { "msp430f5436",2,8 },
974 { "msp430f5436a",2,8 },
975 { "msp430f5437",2,8 },
976 { "msp430f5437a",2,8 },
977 { "msp430f5438",2,8 },
978 { "msp430f5438a",2,8 },
979 { "msp430f5500",2,8 },
980 { "msp430f5501",2,8 },
981 { "msp430f5502",2,8 },
982 { "msp430f5503",2,8 },
983 { "msp430f5504",2,8 },
984 { "msp430f5505",2,8 },
985 { "msp430f5506",2,8 },
986 { "msp430f5507",2,8 },
987 { "msp430f5508",2,8 },
988 { "msp430f5509",2,8 },
989 { "msp430f5510",2,8 },
990 { "msp430f5513",2,8 },
991 { "msp430f5514",2,8 },
992 { "msp430f5515",2,8 },
993 { "msp430f5517",2,8 },
994 { "msp430f5519",2,8 },
995 { "msp430f5521",2,8 },
996 { "msp430f5522",2,8 },
997 { "msp430f5524",2,8 },
998 { "msp430f5525",2,8 },
999 { "msp430f5526",2,8 },
1000 { "msp430f5527",2,8 },
1001 { "msp430f5528",2,8 },
1002 { "msp430f5529",2,8 },
1003 { "msp430f5630",2,8 },
1004 { "msp430f5631",2,8 },
1005 { "msp430f5632",2,8 },
1006 { "msp430f5633",2,8 },
1007 { "msp430f5634",2,8 },
1008 { "msp430f5635",2,8 },
1009 { "msp430f5636",2,8 },
1010 { "msp430f5637",2,8 },
1011 { "msp430f5638",2,8 },
1012 { "msp430f5658",2,8 },
1013 { "msp430f5659",2,8 },
1014 { "msp430f5xx_6xxgeneric",2,8 },
1015 { "msp430f6433",2,8 },
1016 { "msp430f6435",2,8 },
1017 { "msp430f6436",2,8 },
1018 { "msp430f6438",2,8 },
1019 { "msp430f6458",2,8 },
1020 { "msp430f6459",2,8 },
1021 { "msp430f6630",2,8 },
1022 { "msp430f6631",2,8 },
1023 { "msp430f6632",2,8 },
1024 { "msp430f6633",2,8 },
1025 { "msp430f6634",2,8 },
1026 { "msp430f6635",2,8 },
1027 { "msp430f6636",2,8 },
1028 { "msp430f6637",2,8 },
1029 { "msp430f6638",2,8 },
1030 { "msp430f6658",2,8 },
1031 { "msp430f6659",2,8 },
1032 { "msp430f6720",2,8 },
1033 { "msp430f6720a",2,8 },
1034 { "msp430f6721",2,8 },
1035 { "msp430f6721a",2,8 },
1036 { "msp430f6723",2,8 },
1037 { "msp430f6723a",2,8 },
1038 { "msp430f6724",2,8 },
1039 { "msp430f6724a",2,8 },
1040 { "msp430f6725",2,8 },
1041 { "msp430f6725a",2,8 },
1042 { "msp430f6726",2,8 },
1043 { "msp430f6726a",2,8 },
1044 { "msp430f6730",2,8 },
1045 { "msp430f6730a",2,8 },
1046 { "msp430f6731",2,8 },
1047 { "msp430f6731a",2,8 },
1048 { "msp430f6733",2,8 },
1049 { "msp430f6733a",2,8 },
1050 { "msp430f6734",2,8 },
1051 { "msp430f6734a",2,8 },
1052 { "msp430f6735",2,8 },
1053 { "msp430f6735a",2,8 },
1054 { "msp430f6736",2,8 },
1055 { "msp430f6736a",2,8 },
1056 { "msp430f6745",2,8 },
1057 { "msp430f67451",2,8 },
1058 { "msp430f67451a",2,8 },
1059 { "msp430f6745a",2,8 },
1060 { "msp430f6746",2,8 },
1061 { "msp430f67461",2,8 },
1062 { "msp430f67461a",2,8 },
1063 { "msp430f6746a",2,8 },
1064 { "msp430f6747",2,8 },
1065 { "msp430f67471",2,8 },
1066 { "msp430f67471a",2,8 },
1067 { "msp430f6747a",2,8 },
1068 { "msp430f6748",2,8 },
1069 { "msp430f67481",2,8 },
1070 { "msp430f67481a",2,8 },
1071 { "msp430f6748a",2,8 },
1072 { "msp430f6749",2,8 },
1073 { "msp430f67491",2,8 },
1074 { "msp430f67491a",2,8 },
1075 { "msp430f6749a",2,8 },
1076 { "msp430f67621",2,8 },
1077 { "msp430f67621a",2,8 },
1078 { "msp430f67641",2,8 },
1079 { "msp430f67641a",2,8 },
1080 { "msp430f6765",2,8 },
1081 { "msp430f67651",2,8 },
1082 { "msp430f67651a",2,8 },
1083 { "msp430f6765a",2,8 },
1084 { "msp430f6766",2,8 },
1085 { "msp430f67661",2,8 },
1086 { "msp430f67661a",2,8 },
1087 { "msp430f6766a",2,8 },
1088 { "msp430f6767",2,8 },
1089 { "msp430f67671",2,8 },
1090 { "msp430f67671a",2,8 },
1091 { "msp430f6767a",2,8 },
1092 { "msp430f6768",2,8 },
1093 { "msp430f67681",2,8 },
1094 { "msp430f67681a",2,8 },
1095 { "msp430f6768a",2,8 },
1096 { "msp430f6769",2,8 },
1097 { "msp430f67691",2,8 },
1098 { "msp430f67691a",2,8 },
1099 { "msp430f6769a",2,8 },
1100 { "msp430f6775",2,8 },
1101 { "msp430f67751",2,8 },
1102 { "msp430f67751a",2,8 },
1103 { "msp430f6775a",2,8 },
1104 { "msp430f6776",2,8 },
1105 { "msp430f67761",2,8 },
1106 { "msp430f67761a",2,8 },
1107 { "msp430f6776a",2,8 },
1108 { "msp430f6777",2,8 },
1109 { "msp430f67771",2,8 },
1110 { "msp430f67771a",2,8 },
1111 { "msp430f6777a",2,8 },
1112 { "msp430f6778",2,8 },
1113 { "msp430f67781",2,8 },
1114 { "msp430f67781a",2,8 },
1115 { "msp430f6778a",2,8 },
1116 { "msp430f6779",2,8 },
1117 { "msp430f67791",2,8 },
1118 { "msp430f67791a",2,8 },
1119 { "msp430f6779a",2,8 },
1120 { "msp430fe423",0,0 },
1121 { "msp430fe4232",0,0 },
1122 { "msp430fe423a",0,0 },
1123 { "msp430fe4242",0,0 },
1124 { "msp430fe425",0,0 },
1125 { "msp430fe4252",0,0 },
1126 { "msp430fe425a",0,0 },
1127 { "msp430fe427",0,0 },
1128 { "msp430fe4272",0,0 },
1129 { "msp430fe427a",0,0 },
1130 { "msp430fg4250",0,0 },
1131 { "msp430fg4260",0,0 },
1132 { "msp430fg4270",0,0 },
1133 { "msp430fg437",0,0 },
1134 { "msp430fg438",0,0 },
1135 { "msp430fg439",0,0 },
1136 { "msp430fg4616",1,1 },
1137 { "msp430fg4617",1,1 },
1138 { "msp430fg4618",1,1 },
1139 { "msp430fg4619",1,1 },
1140 { "msp430fg477",0,0 },
1141 { "msp430fg478",0,0 },
1142 { "msp430fg479",0,0 },
1143 { "msp430fg6425",2,8 },
1144 { "msp430fg6426",2,8 },
1145 { "msp430fg6625",2,8 },
1146 { "msp430fg6626",2,8 },
1147 { "msp430fr2032",2,0 },
1148 { "msp430fr2033",2,0 },
1149 { "msp430fr2110",2,0 },
1150 { "msp430fr2111",2,0 },
1151 { "msp430fr2310",2,0 },
1152 { "msp430fr2311",2,0 },
1153 { "msp430fr2433",2,8 },
1154 { "msp430fr2532",2,8 },
1155 { "msp430fr2533",2,8 },
1156 { "msp430fr2632",2,8 },
1157 { "msp430fr2633",2,8 },
1158 { "msp430fr2xx_4xxgeneric",2,8 },
1159 { "msp430fr4131",2,0 },
1160 { "msp430fr4132",2,0 },
1161 { "msp430fr4133",2,0 },
1162 { "msp430fr5720",2,8 },
1163 { "msp430fr5721",2,8 },
1164 { "msp430fr5722",2,8 },
1165 { "msp430fr5723",2,8 },
1166 { "msp430fr5724",2,8 },
1167 { "msp430fr5725",2,8 },
1168 { "msp430fr5726",2,8 },
1169 { "msp430fr5727",2,8 },
1170 { "msp430fr5728",2,8 },
1171 { "msp430fr5729",2,8 },
1172 { "msp430fr5730",2,8 },
1173 { "msp430fr5731",2,8 },
1174 { "msp430fr5732",2,8 },
1175 { "msp430fr5733",2,8 },
1176 { "msp430fr5734",2,8 },
1177 { "msp430fr5735",2,8 },
1178 { "msp430fr5736",2,8 },
1179 { "msp430fr5737",2,8 },
1180 { "msp430fr5738",2,8 },
1181 { "msp430fr5739",2,8 },
1182 { "msp430fr57xxgeneric",2,8 },
1183 { "msp430fr5847",2,8 },
1184 { "msp430fr58471",2,8 },
1185 { "msp430fr5848",2,8 },
1186 { "msp430fr5849",2,8 },
1187 { "msp430fr5857",2,8 },
1188 { "msp430fr5858",2,8 },
1189 { "msp430fr5859",2,8 },
1190 { "msp430fr5867",2,8 },
1191 { "msp430fr58671",2,8 },
1192 { "msp430fr5868",2,8 },
1193 { "msp430fr5869",2,8 },
1194 { "msp430fr5870",2,8 },
1195 { "msp430fr5872",2,8 },
1196 { "msp430fr58721",2,8 },
1197 { "msp430fr5887",2,8 },
1198 { "msp430fr5888",2,8 },
1199 { "msp430fr5889",2,8 },
1200 { "msp430fr58891",2,8 },
1201 { "msp430fr5922",2,8 },
1202 { "msp430fr59221",2,8 },
1203 { "msp430fr5947",2,8 },
1204 { "msp430fr59471",2,8 },
1205 { "msp430fr5948",2,8 },
1206 { "msp430fr5949",2,8 },
1207 { "msp430fr5957",2,8 },
1208 { "msp430fr5958",2,8 },
1209 { "msp430fr5959",2,8 },
1210 { "msp430fr5962",2,8 },
1211 { "msp430fr5964",2,8 },
1212 { "msp430fr5967",2,8 },
1213 { "msp430fr5968",2,8 },
1214 { "msp430fr5969",2,8 },
1215 { "msp430fr59691",2,8 },
1216 { "msp430fr5970",2,8 },
1217 { "msp430fr5972",2,8 },
1218 { "msp430fr59721",2,8 },
1219 { "msp430fr5986",2,8 },
1220 { "msp430fr5987",2,8 },
1221 { "msp430fr5988",2,8 },
1222 { "msp430fr5989",2,8 },
1223 { "msp430fr59891",2,8 },
1224 { "msp430fr5992",2,8 },
1225 { "msp430fr5994",2,8 },
1226 { "msp430fr59941",2,8 },
1227 { "msp430fr5xx_6xxgeneric",2,8 },
1228 { "msp430fr6820",2,8 },
1229 { "msp430fr6822",2,8 },
1230 { "msp430fr68221",2,8 },
1231 { "msp430fr6870",2,8 },
1232 { "msp430fr6872",2,8 },
1233 { "msp430fr68721",2,8 },
1234 { "msp430fr6877",2,8 },
1235 { "msp430fr6879",2,8 },
1236 { "msp430fr68791",2,8 },
1237 { "msp430fr6887",2,8 },
1238 { "msp430fr6888",2,8 },
1239 { "msp430fr6889",2,8 },
1240 { "msp430fr68891",2,8 },
1241 { "msp430fr6920",2,8 },
1242 { "msp430fr6922",2,8 },
1243 { "msp430fr69221",2,8 },
1244 { "msp430fr6927",2,8 },
1245 { "msp430fr69271",2,8 },
1246 { "msp430fr6928",2,8 },
1247 { "msp430fr6970",2,8 },
1248 { "msp430fr6972",2,8 },
1249 { "msp430fr69721",2,8 },
1250 { "msp430fr6977",2,8 },
1251 { "msp430fr6979",2,8 },
1252 { "msp430fr69791",2,8 },
1253 { "msp430fr6987",2,8 },
1254 { "msp430fr6988",2,8 },
1255 { "msp430fr6989",2,8 },
1256 { "msp430fr69891",2,8 },
1257 { "msp430fw423",0,0 },
1258 { "msp430fw425",0,0 },
1259 { "msp430fw427",0,0 },
1260 { "msp430fw428",0,0 },
1261 { "msp430fw429",0,0 },
1262 { "msp430g2001",0,0 },
1263 { "msp430g2101",0,0 },
1264 { "msp430g2102",0,0 },
1265 { "msp430g2111",0,0 },
1266 { "msp430g2112",0,0 },
1267 { "msp430g2113",0,0 },
1268 { "msp430g2121",0,0 },
1269 { "msp430g2131",0,0 },
1270 { "msp430g2132",0,0 },
1271 { "msp430g2152",0,0 },
1272 { "msp430g2153",0,0 },
1273 { "msp430g2201",0,0 },
1274 { "msp430g2202",0,0 },
1275 { "msp430g2203",0,0 },
1276 { "msp430g2210",0,0 },
1277 { "msp430g2211",0,0 },
1278 { "msp430g2212",0,0 },
1279 { "msp430g2213",0,0 },
1280 { "msp430g2221",0,0 },
1281 { "msp430g2230",0,0 },
1282 { "msp430g2231",0,0 },
1283 { "msp430g2232",0,0 },
1284 { "msp430g2233",0,0 },
1285 { "msp430g2252",0,0 },
1286 { "msp430g2253",0,0 },
1287 { "msp430g2302",0,0 },
1288 { "msp430g2303",0,0 },
1289 { "msp430g2312",0,0 },
1290 { "msp430g2313",0,0 },
1291 { "msp430g2332",0,0 },
1292 { "msp430g2333",0,0 },
1293 { "msp430g2352",0,0 },
1294 { "msp430g2353",0,0 },
1295 { "msp430g2402",0,0 },
1296 { "msp430g2403",0,0 },
1297 { "msp430g2412",0,0 },
1298 { "msp430g2413",0,0 },
1299 { "msp430g2432",0,0 },
1300 { "msp430g2433",0,0 },
1301 { "msp430g2444",0,0 },
1302 { "msp430g2452",0,0 },
1303 { "msp430g2453",0,0 },
1304 { "msp430g2513",0,0 },
1305 { "msp430g2533",0,0 },
1306 { "msp430g2544",0,0 },
1307 { "msp430g2553",0,0 },
1308 { "msp430g2744",0,0 },
1309 { "msp430g2755",0,0 },
1310 { "msp430g2855",0,0 },
1311 { "msp430g2955",0,0 },
1312 { "msp430i2020",0,2 },
1313 { "msp430i2021",0,2 },
1314 { "msp430i2030",0,2 },
1315 { "msp430i2031",0,2 },
1316 { "msp430i2040",0,2 },
1317 { "msp430i2041",0,2 },
1318 { "msp430i2xxgeneric",0,2 },
1319 { "msp430l092",0,0 },
1320 { "msp430p112",0,0 },
1321 { "msp430p313",0,0 },
1322 { "msp430p315",0,0 },
1323 { "msp430p315s",0,0 },
1324 { "msp430p325",0,0 },
1325 { "msp430p337",0,1 },
1326 { "msp430sl5438a",2,8 },
1327 { "msp430tch5e",0,0 },
1328 { "msp430xgeneric",2,8 },
1329 { "rf430f5144",2,8 },
1330 { "rf430f5155",2,8 },
1331 { "rf430f5175",2,8 },
1332 { "rf430frl152h",0,0 },
1333 { "rf430frl152h_rom",0,0 },
1334 { "rf430frl153h",0,0 },
1335 { "rf430frl153h_rom",0,0 },
1336 { "rf430frl154h",0,0 },
1337 { "rf430frl154h_rom",0,0 }
1341 md_parse_option (int c, const char * arg)
1343 switch (c)
1345 case OPTION_SILICON_ERRATA:
1346 case OPTION_SILICON_ERRATA_WARN:
1348 signed int i;
1349 const struct
1351 const char * name;
1352 unsigned int length;
1353 unsigned int bitfield;
1354 } erratas[] =
1356 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4 },
1357 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8 },
1358 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11 },
1359 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12 },
1360 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13 },
1361 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19 },
1366 for (i = ARRAY_SIZE (erratas); i--;)
1367 if (strncasecmp (arg, erratas[i].name, erratas[i].length) == 0)
1369 if (c == OPTION_SILICON_ERRATA)
1370 silicon_errata_fix |= erratas[i].bitfield;
1371 else
1372 silicon_errata_warn |= erratas[i].bitfield;
1373 arg += erratas[i].length;
1374 break;
1376 if (i < 0)
1378 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg);
1379 break;
1381 if (*arg == 0)
1382 break;
1383 if (*arg != ',')
1384 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg);
1385 else
1386 arg ++;
1388 while (*arg != 0);
1390 return 1;
1392 case OPTION_MMCU:
1393 if (arg == NULL)
1394 as_fatal (_("MCU option requires a name\n"));
1396 if (strcasecmp ("msp430", arg) == 0)
1397 selected_isa = MSP_ISA_430;
1398 else if (strcasecmp ("msp430xv2", arg) == 0)
1399 selected_isa = MSP_ISA_430Xv2;
1400 else if (strcasecmp ("msp430x", arg) == 0)
1401 selected_isa = MSP_ISA_430X;
1402 else
1404 int i;
1406 for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
1407 if (strcasecmp (msp430_mcu_data[i].name, arg) == 0)
1409 switch (msp430_mcu_data[i].revision)
1411 case 0: selected_isa = MSP_ISA_430; break;
1412 case 1: selected_isa = MSP_ISA_430X; break;
1413 case 2: selected_isa = MSP_ISA_430Xv2; break;
1415 break;
1418 /* It is not an error if we do not match the MCU name. */
1419 return 1;
1421 case OPTION_MCPU:
1422 if (strcmp (arg, "430") == 0
1423 || strcasecmp (arg, "msp430") == 0)
1424 selected_isa = MSP_ISA_430;
1425 else if (strcasecmp (arg, "430x") == 0
1426 || strcasecmp (arg, "msp430x") == 0)
1427 selected_isa = MSP_ISA_430X;
1428 else if (strcasecmp (arg, "430xv2") == 0
1429 || strcasecmp (arg, "msp430xv2") == 0)
1430 selected_isa = MSP_ISA_430Xv2;
1431 else
1432 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1433 return 1;
1435 case OPTION_RELAX:
1436 msp430_enable_relax = 1;
1437 return 1;
1439 case OPTION_POLYMORPHS:
1440 msp430_enable_polys = 1;
1441 return 1;
1443 case OPTION_LARGE:
1444 large_model = TRUE;
1445 return 1;
1447 case OPTION_NO_INTR_NOPS:
1448 gen_interrupt_nops = FALSE;
1449 return 1;
1450 case OPTION_INTR_NOPS:
1451 gen_interrupt_nops = TRUE;
1452 return 1;
1454 case OPTION_WARN_INTR_NOPS:
1455 warn_interrupt_nops = TRUE;
1456 return 1;
1457 case OPTION_NO_WARN_INTR_NOPS:
1458 warn_interrupt_nops = FALSE;
1459 return 1;
1461 case OPTION_UNKNOWN_INTR_NOPS:
1462 do_unknown_interrupt_nops = TRUE;
1463 return 1;
1464 case OPTION_NO_UNKNOWN_INTR_NOPS:
1465 do_unknown_interrupt_nops = FALSE;
1466 return 1;
1468 case OPTION_MOVE_DATA:
1469 move_data = TRUE;
1470 return 1;
1472 case OPTION_DATA_REGION:
1473 if (strcmp (arg, "upper") == 0
1474 || strcmp (arg, "either") == 0)
1475 upper_data_region_in_use = TRUE;
1476 return 1;
1479 return 0;
1482 /* The intention here is to have the mere presence of these sections
1483 cause the object to have a reference to a well-known symbol. This
1484 reference pulls in the bits of the runtime (crt0) that initialize
1485 these sections. Thus, for example, the startup code to call
1486 memset() to initialize .bss will only be linked in when there is a
1487 non-empty .bss section. Otherwise, the call would exist but have a
1488 zero length parameter, which is a waste of memory and cycles.
1490 The code which initializes these sections should have a global
1491 label for these symbols, and should be marked with KEEP() in the
1492 linker script. */
1494 static void
1495 msp430_make_init_symbols (const char * name)
1497 if (strncmp (name, ".bss", 4) == 0
1498 || strncmp (name, ".lower.bss", 10) == 0
1499 || strncmp (name, ".either.bss", 11) == 0
1500 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1501 (void) symbol_find_or_make ("__crt0_init_bss");
1503 if (strncmp (name, ".data", 5) == 0
1504 || strncmp (name, ".lower.data", 11) == 0
1505 || strncmp (name, ".either.data", 12) == 0
1506 || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
1507 (void) symbol_find_or_make ("__crt0_movedata");
1508 /* Note - data assigned to the .either.data section may end up being
1509 placed in the .upper.data section if the .lower.data section is
1510 full. Hence the need to define the crt0 symbol.
1511 The linker may create upper or either data sections, even when none exist
1512 at the moment, so use the value of the data-region flag to determine if
1513 the symbol is needed. */
1514 if (strncmp (name, ".either.data", 12) == 0
1515 || strncmp (name, ".upper.data", 11) == 0
1516 || upper_data_region_in_use)
1517 (void) symbol_find_or_make ("__crt0_move_highdata");
1519 /* See note about .either.data above. */
1520 if (strncmp (name, ".upper.bss", 10) == 0
1521 || strncmp (name, ".either.bss", 11) == 0
1522 || upper_data_region_in_use)
1523 (void) symbol_find_or_make ("__crt0_init_highbss");
1525 /* The following symbols are for the crt0 functions that run through
1526 the different .*_array sections and call the functions placed there.
1527 - init_array stores global static C++ constructors to run before main.
1528 - preinit_array is not expected to ever be used for MSP430.
1529 GCC only places initialization functions for runtime "sanitizers"
1530 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1531 - fini_array stores global static C++ destructors to run after calling
1532 exit() or returning from main.
1533 __crt0_run_array is required to actually call the functions in the above
1534 arrays. */
1535 if (strncmp (name, ".init_array", 11) == 0)
1537 (void) symbol_find_or_make ("__crt0_run_init_array");
1538 (void) symbol_find_or_make ("__crt0_run_array");
1540 else if (strncmp (name, ".preinit_array", 14) == 0)
1542 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1543 (void) symbol_find_or_make ("__crt0_run_array");
1545 else if (strncmp (name, ".fini_array", 11) == 0)
1547 (void) symbol_find_or_make ("__crt0_run_fini_array");
1548 (void) symbol_find_or_make ("__crt0_run_array");
1552 static void
1553 msp430_section (int arg)
1555 char * saved_ilp = input_line_pointer;
1556 const char * name = obj_elf_section_name ();
1558 msp430_make_init_symbols (name);
1560 input_line_pointer = saved_ilp;
1561 obj_elf_section (arg);
1564 void
1565 msp430_frob_section (asection *sec)
1567 const char *name = sec->name;
1569 if (sec->size == 0)
1570 return;
1572 msp430_make_init_symbols (name);
1575 static void
1576 msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
1578 symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
1580 if (symbolP)
1581 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
1582 (void) symbol_find_or_make ("__crt0_init_bss");
1585 static void
1586 msp430_comm (int needs_align)
1588 s_comm_internal (needs_align, elf_common_parse);
1589 (void) symbol_find_or_make ("__crt0_init_bss");
1592 static void
1593 msp430_refsym (int arg ATTRIBUTE_UNUSED)
1595 char sym_name[1024];
1596 input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
1598 (void) symbol_find_or_make (sym_name);
1601 const pseudo_typeS md_pseudo_table[] =
1603 {"arch", msp430_set_arch, OPTION_MMCU},
1604 {"cpu", msp430_set_arch, OPTION_MCPU},
1605 {"profiler", msp430_profiler, 0},
1606 {"section", msp430_section, 0},
1607 {"section.s", msp430_section, 0},
1608 {"sect", msp430_section, 0},
1609 {"sect.s", msp430_section, 0},
1610 {"pushsection", msp430_section, 1},
1611 {"refsym", msp430_refsym, 0},
1612 {"comm", msp430_comm, 0},
1613 {"lcomm", msp430_lcomm, 0},
1614 {NULL, NULL, 0}
1617 const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1619 struct option md_longopts[] =
1621 {"msilicon-errata", required_argument, NULL, OPTION_SILICON_ERRATA},
1622 {"msilicon-errata-warn", required_argument, NULL, OPTION_SILICON_ERRATA_WARN},
1623 {"mmcu", required_argument, NULL, OPTION_MMCU},
1624 {"mcpu", required_argument, NULL, OPTION_MCPU},
1625 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1626 {"mQ", no_argument, NULL, OPTION_RELAX},
1627 {"ml", no_argument, NULL, OPTION_LARGE},
1628 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1629 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1630 {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
1631 {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
1632 {"mu", no_argument, NULL, OPTION_UNKNOWN_INTR_NOPS},
1633 {"mU", no_argument, NULL, OPTION_NO_UNKNOWN_INTR_NOPS},
1634 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1635 {"mdata-region", required_argument, NULL, OPTION_DATA_REGION},
1636 {NULL, no_argument, NULL, 0}
1639 size_t md_longopts_size = sizeof (md_longopts);
1641 void
1642 md_show_usage (FILE * stream)
1644 fprintf (stream,
1645 _("MSP430 options:\n"
1646 " -mmcu=<msp430-name> - select microcontroller type\n"
1647 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1648 fprintf (stream,
1649 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1650 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1651 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1652 fprintf (stream,
1653 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1654 " -mP - enable polymorph instructions\n"));
1655 fprintf (stream,
1656 _(" -ml - enable large code model\n"));
1657 fprintf (stream,
1658 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1659 fprintf (stream,
1660 _(" -mn - insert a NOP after changing interrupts\n"));
1661 fprintf (stream,
1662 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1663 fprintf (stream,
1664 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1665 fprintf (stream,
1666 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1667 " known how the state is changed, do not warn/insert NOPs\n"));
1668 fprintf (stream,
1669 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1670 " known how the state is changed, warn/insert NOPs (default)\n"
1671 " -mn and/or -my are required for this to have any effect\n"));
1672 fprintf (stream,
1673 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1674 fprintf (stream,
1675 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1676 " placed in.\n"));
1679 symbolS *
1680 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1682 return NULL;
1685 static char *
1686 extract_cmd (char * from, char * to, int limit)
1688 int size = 0;
1690 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1692 *(to + size) = *from;
1693 from++;
1694 size++;
1697 *(to + size) = 0;
1699 return from;
1702 const char *
1703 md_atof (int type, char * litP, int * sizeP)
1705 return ieee_md_atof (type, litP, sizeP, FALSE);
1708 void
1709 md_begin (void)
1711 struct msp430_opcode_s * opcode;
1712 msp430_hash = hash_new ();
1714 for (opcode = msp430_opcodes; opcode->name; opcode++)
1715 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1717 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1718 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1720 /* Set linkrelax here to avoid fixups in most sections. */
1721 linkrelax = 1;
1724 static inline bfd_boolean
1725 is_regname_end (char c)
1727 return (c == 0 || ! ISALNUM (c));
1730 /* Returns the register number equivalent to the string T.
1731 Returns -1 if there is no such register.
1732 Skips a leading 'r' or 'R' character if there is one.
1733 Handles the register aliases PC and SP. */
1735 static signed int
1736 check_reg (char * t)
1738 char * endt;
1739 signed long int val;
1741 if (t == NULL || t[0] == 0)
1742 return -1;
1744 if (*t == 'r' || *t == 'R')
1745 ++t;
1747 if (strncasecmp (t, "pc", 2) == 0 && is_regname_end (t[2]))
1748 return 0;
1750 if (strncasecmp (t, "sp", 2) == 0 && is_regname_end (t[2]))
1751 return 1;
1753 if (strncasecmp (t, "sr", 2) == 0 && is_regname_end (t[2]))
1754 return 2;
1756 if (*t == '0' && is_regname_end (t[1]))
1757 return 0;
1759 val = strtol (t, & endt, 0);
1761 if (val < 1 || val > 15)
1762 return -1;
1764 if (is_regname_end (*endt))
1765 return val;
1767 return -1;
1770 static int
1771 msp430_srcoperand (struct msp430_operand_s * op,
1772 char * l,
1773 int bin,
1774 bfd_boolean * imm_op,
1775 bfd_boolean allow_20bit_values,
1776 bfd_boolean constants_allowed)
1778 char * end;
1779 char *__tl = l;
1781 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1782 if (*l == '#')
1784 char *h = l;
1785 int vshift = -1;
1786 int rval = 0;
1788 /* Check if there is:
1789 llo(x) - least significant 16 bits, x &= 0xffff
1790 lhi(x) - x = (x >> 16) & 0xffff,
1791 hlo(x) - x = (x >> 32) & 0xffff,
1792 hhi(x) - x = (x >> 48) & 0xffff
1793 The value _MUST_ be constant expression: #hlo(1231231231). */
1795 *imm_op = TRUE;
1797 if (strncasecmp (h, "#llo(", 5) == 0)
1799 vshift = 0;
1800 rval = 3;
1802 else if (strncasecmp (h, "#lhi(", 5) == 0)
1804 vshift = 1;
1805 rval = 3;
1807 else if (strncasecmp (h, "#hlo(", 5) == 0)
1809 vshift = 2;
1810 rval = 3;
1812 else if (strncasecmp (h, "#hhi(", 5) == 0)
1814 vshift = 3;
1815 rval = 3;
1817 else if (strncasecmp (h, "#lo(", 4) == 0)
1819 vshift = 0;
1820 rval = 2;
1822 else if (strncasecmp (h, "#hi(", 4) == 0)
1824 vshift = 1;
1825 rval = 2;
1828 op->reg = 0; /* Reg PC. */
1829 op->am = 3;
1830 op->ol = 1; /* Immediate will follow an instruction. */
1831 __tl = h + 1 + rval;
1832 op->mode = OP_EXP;
1833 op->vshift = vshift;
1835 end = parse_exp (__tl, &(op->exp));
1836 if (end != NULL && *end != 0 && *end != ')' )
1838 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end, l);
1839 return 1;
1841 if (op->exp.X_op == O_constant)
1843 int x = op->exp.X_add_number;
1845 if (vshift == 0)
1847 x = x & 0xffff;
1848 op->exp.X_add_number = x;
1850 else if (vshift == 1)
1852 x = (x >> 16) & 0xffff;
1853 op->exp.X_add_number = x;
1854 op->vshift = 0;
1856 else if (vshift > 1)
1858 if (x < 0)
1859 op->exp.X_add_number = -1;
1860 else
1861 op->exp.X_add_number = 0; /* Nothing left. */
1862 x = op->exp.X_add_number;
1863 op->vshift = 0;
1866 if (allow_20bit_values)
1868 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
1870 as_bad (_("value 0x%x out of extended range."), x);
1871 return 1;
1874 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1876 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1877 return 1;
1880 /* Now check constants. */
1881 /* Substitute register mode with a constant generator if applicable. */
1883 if (!allow_20bit_values)
1884 x = (short) x; /* Extend sign. */
1886 if (! constants_allowed)
1888 else if (x == 0)
1890 op->reg = 3;
1891 op->am = 0;
1892 op->ol = 0;
1893 op->mode = OP_REG;
1895 else if (x == 1)
1897 op->reg = 3;
1898 op->am = 1;
1899 op->ol = 0;
1900 op->mode = OP_REG;
1902 else if (x == 2)
1904 op->reg = 3;
1905 op->am = 2;
1906 op->ol = 0;
1907 op->mode = OP_REG;
1909 else if (x == -1)
1911 op->reg = 3;
1912 op->am = 3;
1913 op->ol = 0;
1914 op->mode = OP_REG;
1916 else if (x == 4)
1918 if (bin == 0x1200 && ! target_is_430x ())
1920 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1921 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1922 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1923 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1925 else
1927 op->reg = 2;
1928 op->am = 2;
1929 op->ol = 0;
1930 op->mode = OP_REG;
1933 else if (x == 8)
1935 if (bin == 0x1200 && ! target_is_430x ())
1937 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1938 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1939 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1941 else
1943 op->reg = 2;
1944 op->am = 3;
1945 op->ol = 0;
1946 op->mode = OP_REG;
1950 else if (op->exp.X_op == O_symbol)
1952 if (vshift > 1)
1953 as_bad (_("error: unsupported #foo() directive used on symbol"));
1954 op->mode = OP_EXP;
1956 else if (op->exp.X_op == O_big)
1958 short x;
1960 if (vshift != -1)
1962 op->exp.X_op = O_constant;
1963 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1964 x = op->exp.X_add_number;
1965 op->vshift = 0;
1967 else
1969 as_bad (_
1970 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
1972 return 1;
1975 if (x == 0)
1977 op->reg = 3;
1978 op->am = 0;
1979 op->ol = 0;
1980 op->mode = OP_REG;
1982 else if (x == 1)
1984 op->reg = 3;
1985 op->am = 1;
1986 op->ol = 0;
1987 op->mode = OP_REG;
1989 else if (x == 2)
1991 op->reg = 3;
1992 op->am = 2;
1993 op->ol = 0;
1994 op->mode = OP_REG;
1996 else if (x == -1)
1998 op->reg = 3;
1999 op->am = 3;
2000 op->ol = 0;
2001 op->mode = OP_REG;
2003 else if (x == 4)
2005 op->reg = 2;
2006 op->am = 2;
2007 op->ol = 0;
2008 op->mode = OP_REG;
2010 else if (x == 8)
2012 op->reg = 2;
2013 op->am = 3;
2014 op->ol = 0;
2015 op->mode = OP_REG;
2018 /* Redundant (yet) check. */
2019 else if (op->exp.X_op == O_register)
2020 as_bad
2021 (_("Registers cannot be used within immediate expression [%s]"), l);
2022 else
2023 as_bad (_("unknown operand %s"), l);
2025 return 0;
2028 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2029 if (*l == '&')
2031 char *h = l;
2033 op->reg = 2; /* Reg 2 in absolute addr mode. */
2034 op->am = 1; /* Mode As == 01 bin. */
2035 op->ol = 1; /* Immediate value followed by instruction. */
2036 __tl = h + 1;
2037 end = parse_exp (__tl, &(op->exp));
2038 if (end != NULL && *end != 0)
2040 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end, l);
2041 return 1;
2043 op->mode = OP_EXP;
2044 op->vshift = 0;
2045 if (op->exp.X_op == O_constant)
2047 int x = op->exp.X_add_number;
2049 if (allow_20bit_values)
2051 if (x > 0xfffff || x < -(0x7ffff))
2053 as_bad (_("value 0x%x out of extended range."), x);
2054 return 1;
2057 else if (x > 65535 || x < -32768)
2059 as_bad (_("value out of range: 0x%x"), x);
2060 return 1;
2063 else if (op->exp.X_op == O_symbol)
2065 else
2067 /* Redundant (yet) check. */
2068 if (op->exp.X_op == O_register)
2069 as_bad
2070 (_("Registers cannot be used within absolute expression [%s]"), l);
2071 else
2072 as_bad (_("unknown expression in operand %s"), l);
2073 return 1;
2075 return 0;
2078 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2079 if (*l == '@')
2081 char *t = l;
2082 char *m = strchr (l, '+');
2084 if (t != l)
2086 as_bad (_("unknown addressing mode %s"), l);
2087 return 1;
2090 t++;
2092 if ((op->reg = check_reg (t)) == -1)
2094 as_bad (_("Bad register name %s"), t);
2095 return 1;
2098 op->mode = OP_REG;
2099 op->am = m ? 3 : 2;
2100 op->ol = 0;
2102 /* PC cannot be used in indirect addressing. */
2103 if (target_is_430xv2 () && op->reg == 0)
2105 as_bad (_("cannot use indirect addressing with the PC"));
2106 return 1;
2109 return 0;
2112 /* Check if register indexed X(Rn). */
2115 char *h = strrchr (l, '(');
2116 char *m = strrchr (l, ')');
2117 char *t;
2119 *imm_op = TRUE;
2121 if (!h)
2122 break;
2123 if (!m)
2125 as_bad (_("')' required"));
2126 return 1;
2129 t = h;
2130 op->am = 1;
2131 op->ol = 1;
2133 /* Extract a register. */
2134 if ((op->reg = check_reg (t + 1)) == -1)
2136 as_bad (_
2137 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2139 return 1;
2142 if (op->reg == 2)
2144 as_bad (_("r2 should not be used in indexed addressing mode"));
2145 return 1;
2148 /* Extract constant. */
2149 __tl = l;
2150 *h = 0;
2151 op->mode = OP_EXP;
2152 op->vshift = 0;
2153 end = parse_exp (__tl, &(op->exp));
2154 if (end != NULL && *end != 0)
2156 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
2157 return 1;
2159 if (op->exp.X_op == O_constant)
2161 int x = op->exp.X_add_number;
2163 if (allow_20bit_values)
2165 if (x > 0xfffff || x < - (0x7ffff))
2167 as_bad (_("value 0x%x out of extended range."), x);
2168 return 1;
2171 else if (x > 65535 || x < -32768)
2173 as_bad (_("value out of range: 0x%x"), x);
2174 return 1;
2177 if (x == 0)
2179 op->mode = OP_REG;
2180 op->am = 2;
2181 op->ol = 0;
2182 return 0;
2185 if (op->reg == 1 && (x & 1))
2187 if (silicon_errata_fix & SILICON_ERRATA_CPU8)
2188 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2189 else if (silicon_errata_warn & SILICON_ERRATA_CPU8)
2190 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2193 else if (op->exp.X_op == O_symbol)
2195 else
2197 /* Redundant (yet) check. */
2198 if (op->exp.X_op == O_register)
2199 as_bad
2200 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
2201 else
2202 as_bad (_("unknown expression in operand %s"), l);
2203 return 1;
2206 return 0;
2208 while (0);
2210 /* Possibly register mode 'mov r1,r2'. */
2211 if ((op->reg = check_reg (l)) != -1)
2213 op->mode = OP_REG;
2214 op->am = 0;
2215 op->ol = 0;
2216 return 0;
2219 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2220 op->mode = OP_EXP;
2221 op->reg = 0; /* PC relative... be careful. */
2222 /* An expression starting with a minus sign is a constant, not an address. */
2223 op->am = (*l == '-' ? 3 : 1);
2224 op->ol = 1;
2225 op->vshift = 0;
2226 __tl = l;
2227 end = parse_exp (__tl, &(op->exp));
2228 if (end != NULL && * end != 0)
2230 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
2231 return 1;
2233 return 0;
2237 static int
2238 msp430_dstoperand (struct msp430_operand_s * op,
2239 char * l,
2240 int bin,
2241 bfd_boolean allow_20bit_values,
2242 bfd_boolean constants_allowed)
2244 int dummy;
2245 int ret = msp430_srcoperand (op, l, bin, & dummy,
2246 allow_20bit_values,
2247 constants_allowed);
2249 if (ret)
2250 return ret;
2252 if (op->am == 2)
2254 char *__tl = (char *) "0";
2256 op->mode = OP_EXP;
2257 op->am = 1;
2258 op->ol = 1;
2259 op->vshift = 0;
2260 (void) parse_exp (__tl, &(op->exp));
2262 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
2264 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2265 op->reg, op->reg);
2266 return 1;
2268 return 0;
2271 if (op->am > 1)
2273 as_bad (_
2274 ("this addressing mode is not applicable for destination operand"));
2275 return 1;
2277 return 0;
2280 /* Attempt to encode a MOVA instruction with the given operands.
2281 Returns the length of the encoded instruction if successful
2282 or 0 upon failure. If the encoding fails, an error message
2283 will be returned if a pointer is provided. */
2285 static int
2286 try_encode_mova (bfd_boolean imm_op,
2287 int bin,
2288 struct msp430_operand_s * op1,
2289 struct msp430_operand_s * op2,
2290 const char ** error_message_return)
2292 short ZEROS = 0;
2293 char *frag;
2294 int where;
2296 /* Only a restricted subset of the normal MSP430 addressing modes
2297 are supported here, so check for the ones that are allowed. */
2298 if (imm_op)
2300 if (op1->mode == OP_EXP)
2302 if (op2->mode != OP_REG)
2304 if (error_message_return != NULL)
2305 * error_message_return = _("expected register as second argument of %s");
2306 return 0;
2309 if (op1->am == 3)
2311 /* MOVA #imm20, Rdst. */
2312 bin |= 0x80 | op2->reg;
2313 frag = frag_more (4);
2314 where = frag - frag_now->fr_literal;
2315 if (op1->exp.X_op == O_constant)
2317 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2318 bfd_putl16 ((bfd_vma) bin, frag);
2319 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2321 else
2323 bfd_putl16 ((bfd_vma) bin, frag);
2324 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2325 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2326 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2329 return 4;
2331 else if (op1->am == 1)
2333 /* MOVA z16(Rsrc), Rdst. */
2334 bin |= 0x30 | (op1->reg << 8) | op2->reg;
2335 frag = frag_more (4);
2336 where = frag - frag_now->fr_literal;
2337 bfd_putl16 ((bfd_vma) bin, frag);
2338 if (op1->exp.X_op == O_constant)
2340 if (op1->exp.X_add_number > 0xffff
2341 || op1->exp.X_add_number < -(0x7fff))
2343 if (error_message_return != NULL)
2344 * error_message_return = _("index value too big for %s");
2345 return 0;
2347 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2349 else
2351 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2352 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
2353 op1->reg == 0 ?
2354 BFD_RELOC_MSP430X_PCR16 :
2355 BFD_RELOC_MSP430X_ABS16);
2357 return 4;
2360 if (error_message_return != NULL)
2361 * error_message_return = _("unexpected addressing mode for %s");
2362 return 0;
2364 else if (op1->am == 0)
2366 /* MOVA Rsrc, ... */
2367 if (op2->mode == OP_REG)
2369 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
2370 frag = frag_more (2);
2371 where = frag - frag_now->fr_literal;
2372 bfd_putl16 ((bfd_vma) bin, frag);
2373 return 2;
2375 else if (op2->am == 1)
2377 if (op2->reg == 2)
2379 /* MOVA Rsrc, &abs20. */
2380 bin |= 0x60 | (op1->reg << 8);
2381 frag = frag_more (4);
2382 where = frag - frag_now->fr_literal;
2383 if (op2->exp.X_op == O_constant)
2385 bin |= (op2->exp.X_add_number >> 16) & 0xf;
2386 bfd_putl16 ((bfd_vma) bin, frag);
2387 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2389 else
2391 bfd_putl16 ((bfd_vma) bin, frag);
2392 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2393 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
2394 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2396 return 4;
2399 /* MOVA Rsrc, z16(Rdst). */
2400 bin |= 0x70 | (op1->reg << 8) | op2->reg;
2401 frag = frag_more (4);
2402 where = frag - frag_now->fr_literal;
2403 bfd_putl16 ((bfd_vma) bin, frag);
2404 if (op2->exp.X_op == O_constant)
2406 if (op2->exp.X_add_number > 0xffff
2407 || op2->exp.X_add_number < -(0x7fff))
2409 if (error_message_return != NULL)
2410 * error_message_return = _("index value too big for %s");
2411 return 0;
2413 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2415 else
2417 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2418 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2419 op2->reg == 0 ?
2420 BFD_RELOC_MSP430X_PCR16 :
2421 BFD_RELOC_MSP430X_ABS16);
2423 return 4;
2426 if (error_message_return != NULL)
2427 * error_message_return = _("unexpected addressing mode for %s");
2428 return 0;
2432 /* imm_op == FALSE. */
2434 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2436 /* MOVA &abs20, Rdst. */
2437 if (op2->mode != OP_REG)
2439 if (error_message_return != NULL)
2440 * error_message_return = _("expected register as second argument of %s");
2441 return 0;
2444 if (op2->reg == 2 || op2->reg == 3)
2446 if (error_message_return != NULL)
2447 * error_message_return = _("constant generator destination register found in %s");
2448 return 0;
2451 bin |= 0x20 | op2->reg;
2452 frag = frag_more (4);
2453 where = frag - frag_now->fr_literal;
2454 if (op1->exp.X_op == O_constant)
2456 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2457 bfd_putl16 ((bfd_vma) bin, frag);
2458 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2460 else
2462 bfd_putl16 ((bfd_vma) bin, frag);
2463 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2464 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2465 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2467 return 4;
2469 else if (op1->mode == OP_REG)
2471 if (op1->am == 3)
2473 /* MOVA @Rsrc+, Rdst. */
2474 if (op2->mode != OP_REG)
2476 if (error_message_return != NULL)
2477 * error_message_return = _("expected register as second argument of %s");
2478 return 0;
2481 if (op2->reg == 2 || op2->reg == 3)
2483 if (error_message_return != NULL)
2484 * error_message_return = _("constant generator destination register found in %s");
2485 return 0;
2488 if (op1->reg == 2 || op1->reg == 3)
2490 if (error_message_return != NULL)
2491 * error_message_return = _("constant generator source register found in %s");
2492 return 0;
2495 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2496 frag = frag_more (2);
2497 where = frag - frag_now->fr_literal;
2498 bfd_putl16 ((bfd_vma) bin, frag);
2499 return 2;
2501 else if (op1->am == 2)
2503 /* MOVA @Rsrc,Rdst */
2504 if (op2->mode != OP_REG)
2506 if (error_message_return != NULL)
2507 * error_message_return = _("expected register as second argument of %s");
2508 return 0;
2511 if (op2->reg == 2 || op2->reg == 3)
2513 if (error_message_return != NULL)
2514 * error_message_return = _("constant generator destination register found in %s");
2515 return 0;
2518 if (op1->reg == 2 || op1->reg == 3)
2520 if (error_message_return != NULL)
2521 * error_message_return = _("constant generator source register found in %s");
2522 return 0;
2525 bin |= (op1->reg << 8) | op2->reg;
2526 frag = frag_more (2);
2527 where = frag - frag_now->fr_literal;
2528 bfd_putl16 ((bfd_vma) bin, frag);
2529 return 2;
2533 if (error_message_return != NULL)
2534 * error_message_return = _("unexpected addressing mode for %s");
2536 return 0;
2539 #define NOP_CHECK_INTERRUPT (1 << 0)
2540 #define NOP_CHECK_CPU12 (1 << 1)
2541 #define NOP_CHECK_CPU19 (1 << 2)
2543 static signed int check_for_nop = 0;
2545 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2547 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2548 For MOV insns, more sophisticated processing is needed to determine if they
2549 result in enabling/disabling interrupts. */
2550 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2551 || ((strcmp (OPCODE, "bic") == 0) \
2552 && BIN == 0xc232) \
2553 || ((strcmp (OPCODE, "clr") == 0) \
2554 && BIN == 0x4302))
2556 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2557 || ((strcmp (OPCODE, "bis") == 0) \
2558 && BIN == 0xd232))
2560 const char * const INSERT_NOP_BEFORE_EINT = "NOP inserted here, before an interrupt enable instruction";
2561 const char * const INSERT_NOP_AFTER_DINT = "NOP inserted here, after an interrupt disable instruction";
2562 const char * const INSERT_NOP_AFTER_EINT = "NOP inserted here, after an interrupt enable instruction";
2563 const char * const INSERT_NOP_BEFORE_UNKNOWN = "NOP inserted here, before this interrupt state change";
2564 const char * const INSERT_NOP_AFTER_UNKNOWN ="NOP inserted here, after the instruction that changed interrupt state";
2565 const char * const INSERT_NOP_AT_EOF = "NOP inserted after the interrupt state change at the end of the file";
2567 const char * const WARN_NOP_BEFORE_EINT = "a NOP might be needed here, before an interrupt enable instruction";
2568 const char * const WARN_NOP_AFTER_DINT = "a NOP might be needed here, after an interrupt disable instruction";
2569 const char * const WARN_NOP_AFTER_EINT = "a NOP might be needed here, after an interrupt enable instruction";
2570 const char * const WARN_NOP_BEFORE_UNKNOWN = "a NOP might be needed here, before this interrupt state change";
2571 const char * const WARN_NOP_AFTER_UNKNOWN = "a NOP might also be needed here, after the instruction that changed interrupt state";
2572 const char * const WARN_NOP_AT_EOF = "a NOP might be needed after the interrupt state change at the end of the file";
2574 static void
2575 gen_nop (void)
2577 char *frag;
2578 frag = frag_more (2);
2579 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2580 dwarf2_emit_insn (2);
2583 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2585 static void
2586 warn_eint_nop (bfd_boolean prev_insn_is_nop, bfd_boolean prev_insn_is_dint)
2588 if (prev_insn_is_nop
2589 /* If the last insn was a DINT, we will have already warned that a NOP is
2590 required after it. */
2591 || prev_insn_is_dint
2592 /* 430 ISA does not require a NOP before EINT. */
2593 || (! target_is_430x ()))
2594 return;
2596 if (gen_interrupt_nops)
2598 gen_nop ();
2599 if (warn_interrupt_nops)
2600 as_warn (_(INSERT_NOP_BEFORE_EINT));
2602 else if (warn_interrupt_nops)
2603 as_warn (_(WARN_NOP_BEFORE_EINT));
2606 /* Use when unsure what effect the insn will have on the interrupt status,
2607 to insert/warn about adding a NOP before the current insn. */
2609 static void
2610 warn_unsure_interrupt (bfd_boolean prev_insn_is_nop,
2611 bfd_boolean prev_insn_is_dint)
2613 if (prev_insn_is_nop
2614 /* If the last insn was a DINT, we will have already warned that a NOP is
2615 required after it. */
2616 || prev_insn_is_dint
2617 /* 430 ISA does not require a NOP before EINT or DINT. */
2618 || (! target_is_430x ()))
2619 return;
2621 if (gen_interrupt_nops)
2623 gen_nop ();
2624 if (warn_interrupt_nops)
2625 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN));
2627 else if (warn_interrupt_nops)
2628 as_warn (_(WARN_NOP_BEFORE_UNKNOWN));
2631 /* Parse instruction operands.
2632 Return binary opcode. */
2634 static unsigned int
2635 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2637 int bin = opcode->bin_opcode; /* Opcode mask. */
2638 int insn_length = 0;
2639 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2640 char *frag;
2641 char *end;
2642 int where;
2643 struct msp430_operand_s op1, op2;
2644 int res = 0;
2645 static short ZEROS = 0;
2646 bfd_boolean byte_op, imm_op;
2647 int op_length = 0;
2648 int fmt;
2649 int extended = 0x1800;
2650 bfd_boolean extended_op = FALSE;
2651 bfd_boolean addr_op;
2652 const char * error_message;
2653 static signed int repeat_count = 0;
2654 static bfd_boolean prev_insn_is_nop = FALSE;
2655 static bfd_boolean prev_insn_is_dint = FALSE;
2656 static bfd_boolean prev_insn_is_eint = FALSE;
2657 /* We might decide before the end of the function that the current insn is
2658 equivalent to DINT/EINT. */
2659 bfd_boolean this_insn_is_dint = FALSE;
2660 bfd_boolean this_insn_is_eint = FALSE;
2661 bfd_boolean fix_emitted;
2663 /* Opcode is the one from opcodes table
2664 line contains something like
2665 [.w] @r2+, 5(R1)
2667 .b @r2+, 5(R1). */
2669 byte_op = FALSE;
2670 addr_op = FALSE;
2671 if (*line == '.')
2673 bfd_boolean check = FALSE;
2674 ++ line;
2676 switch (TOLOWER (* line))
2678 case 'b':
2679 /* Byte operation. */
2680 bin |= BYTE_OPERATION;
2681 byte_op = TRUE;
2682 check = TRUE;
2683 break;
2685 case 'a':
2686 /* "Address" ops work on 20-bit values. */
2687 addr_op = TRUE;
2688 bin |= BYTE_OPERATION;
2689 check = TRUE;
2690 break;
2692 case 'w':
2693 /* Word operation - this is the default. */
2694 check = TRUE;
2695 break;
2697 case 0:
2698 case ' ':
2699 case '\n':
2700 case '\r':
2701 as_warn (_("no size modifier after period, .w assumed"));
2702 break;
2704 default:
2705 as_bad (_("unrecognised instruction size modifier .%c"),
2706 * line);
2707 return 0;
2710 if (check)
2712 ++ line;
2717 if (*line && ! ISSPACE (*line))
2719 as_bad (_("junk found after instruction: %s.%s"),
2720 opcode->name, line);
2721 return 0;
2724 /* Catch the case where the programmer has used a ".a" size modifier on an
2725 instruction that does not support it. Look for an alternative extended
2726 instruction that has the same name without the period. Eg: "add.a"
2727 becomes "adda". Although this not an officially supported way of
2728 specifying instruction aliases other MSP430 assemblers allow it. So we
2729 support it for compatibility purposes. */
2730 if (addr_op && opcode->fmt >= 0)
2732 const char * old_name = opcode->name;
2733 char real_name[32];
2735 sprintf (real_name, "%sa", old_name);
2736 opcode = hash_find (msp430_hash, real_name);
2737 if (opcode == NULL)
2739 as_bad (_("instruction %s.a does not exist"), old_name);
2740 return 0;
2742 #if 0 /* Enable for debugging. */
2743 as_warn ("treating %s.a as %s", old_name, real_name);
2744 #endif
2745 addr_op = FALSE;
2746 bin = opcode->bin_opcode;
2749 if (opcode->fmt != -1
2750 && opcode->insn_opnumb
2751 && (!*line || *line == '\n'))
2753 as_bad (ngettext ("instruction %s requires %d operand",
2754 "instruction %s requires %d operands",
2755 opcode->insn_opnumb),
2756 opcode->name, opcode->insn_opnumb);
2757 return 0;
2760 memset (l1, 0, sizeof (l1));
2761 memset (l2, 0, sizeof (l2));
2762 memset (&op1, 0, sizeof (op1));
2763 memset (&op2, 0, sizeof (op2));
2765 imm_op = FALSE;
2767 if ((fmt = opcode->fmt) < 0)
2769 if (! target_is_430x ())
2771 as_bad (_("instruction %s requires MSP430X mcu"),
2772 opcode->name);
2773 return 0;
2776 fmt = (-fmt) - 1;
2777 extended_op = TRUE;
2780 if (repeat_count)
2782 /* If requested set the extended instruction repeat count. */
2783 if (extended_op)
2785 if (repeat_count > 0)
2786 extended |= (repeat_count - 1);
2787 else
2788 extended |= (1 << 7) | (- repeat_count);
2790 else
2791 as_bad (_("unable to repeat %s insn"), opcode->name);
2793 repeat_count = 0;
2796 /* The previous instruction set this flag if it wants to check if this insn
2797 is a NOP. */
2798 if (check_for_nop)
2800 if (! is_opcode ("nop"))
2804 switch (check_for_nop & - check_for_nop)
2806 case NOP_CHECK_INTERRUPT:
2807 /* NOP_CHECK_INTERRUPT rules:
2808 1. 430 and 430x ISA require a NOP after DINT.
2809 2. Only the 430x ISA requires NOP before EINT (this has
2810 been dealt with in the previous call to this function).
2811 3. Only the 430x ISA requires NOP after every EINT.
2812 CPU42 errata. */
2813 if (gen_interrupt_nops || warn_interrupt_nops)
2815 if (prev_insn_is_dint)
2817 if (gen_interrupt_nops)
2819 gen_nop ();
2820 if (warn_interrupt_nops)
2821 as_warn (_(INSERT_NOP_AFTER_DINT));
2823 else
2824 as_warn (_(WARN_NOP_AFTER_DINT));
2826 else if (prev_insn_is_eint)
2828 if (gen_interrupt_nops)
2830 gen_nop ();
2831 if (warn_interrupt_nops)
2832 as_warn (_(INSERT_NOP_AFTER_EINT));
2834 else
2835 as_warn (_(WARN_NOP_AFTER_EINT));
2837 /* If we get here it's because the last instruction was
2838 determined to either disable or enable interrupts, but
2839 we're not sure which.
2840 We have no information yet about what effect the
2841 current instruction has on interrupts, that has to be
2842 sorted out later.
2843 The last insn may have required a NOP after it, so we
2844 deal with that now. */
2845 else
2847 if (gen_interrupt_nops)
2849 gen_nop ();
2850 if (warn_interrupt_nops)
2851 as_warn (_(INSERT_NOP_AFTER_UNKNOWN));
2853 else
2854 /* warn_unsure_interrupt was called on the previous
2855 insn. */
2856 as_warn (_(WARN_NOP_AFTER_UNKNOWN));
2859 break;
2861 case NOP_CHECK_CPU12:
2862 if (silicon_errata_warn & SILICON_ERRATA_CPU12)
2863 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2865 if (silicon_errata_fix & SILICON_ERRATA_CPU12)
2866 gen_nop ();
2867 break;
2869 case NOP_CHECK_CPU19:
2870 if (silicon_errata_warn & SILICON_ERRATA_CPU19)
2871 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2873 if (silicon_errata_fix & SILICON_ERRATA_CPU19)
2874 gen_nop ();
2875 break;
2877 default:
2878 as_bad (_("internal error: unknown nop check state"));
2879 break;
2881 check_for_nop &= ~ (check_for_nop & - check_for_nop);
2883 while (check_for_nop);
2885 check_for_nop = 0;
2888 switch (fmt)
2890 case 0:
2891 /* Emulated. */
2892 switch (opcode->insn_opnumb)
2894 case 0:
2895 if (is_opcode ("eint"))
2896 warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint);
2898 /* Set/clear bits instructions. */
2899 if (extended_op)
2901 if (!addr_op)
2902 extended |= BYTE_OPERATION;
2904 /* Emit the extension word. */
2905 insn_length += 2;
2906 frag = frag_more (2);
2907 bfd_putl16 (extended, frag);
2910 insn_length += 2;
2911 frag = frag_more (2);
2912 bfd_putl16 ((bfd_vma) bin, frag);
2913 dwarf2_emit_insn (insn_length);
2914 break;
2916 case 1:
2917 /* Something which works with destination operand. */
2918 line = extract_operand (line, l1, sizeof (l1));
2919 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2920 if (res)
2921 break;
2923 bin |= (op1.reg | (op1.am << 7));
2925 /* If the PC is the destination... */
2926 if (op1.am == 0 && op1.reg == 0
2927 /* ... and the opcode alters the SR. */
2928 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2929 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2931 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
2932 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2933 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
2934 as_warn (_("CPU11: PC is destination of SR altering instruction"));
2937 /* If the status register is the destination... */
2938 if (op1.am == 0 && op1.reg == 2
2939 /* ... and the opcode alters the SR. */
2940 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2941 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2942 || is_opcode ("sbc") || is_opcode ("sxt")
2943 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2944 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2945 || is_opcode ("sbcx")
2948 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
2949 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2950 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
2951 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2954 /* Compute the entire instruction length, in bytes. */
2955 op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2956 insn_length += op_length;
2957 frag = frag_more (op_length);
2958 where = frag - frag_now->fr_literal;
2960 if (extended_op)
2962 if (!addr_op)
2963 extended |= BYTE_OPERATION;
2965 if (op1.ol != 0 && ((extended & 0xf) != 0))
2967 as_bad (_("repeat instruction used with non-register mode instruction"));
2968 extended &= ~ 0xf;
2971 if (op1.mode == OP_EXP)
2973 if (op1.exp.X_op == O_constant)
2974 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2976 else if (op1.reg || op1.am == 3) /* Not PC relative. */
2977 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2978 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2979 else
2980 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2981 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2984 /* Emit the extension word. */
2985 bfd_putl16 (extended, frag);
2986 frag += 2;
2987 where += 2;
2990 bfd_putl16 ((bfd_vma) bin, frag);
2991 frag += 2;
2992 where += 2;
2994 if (op1.mode == OP_EXP)
2996 if (op1.exp.X_op == O_constant)
2998 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3000 else
3002 bfd_putl16 ((bfd_vma) ZEROS, frag);
3004 if (!extended_op)
3006 if (op1.reg)
3007 fix_new_exp (frag_now, where, 2,
3008 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3009 else
3010 fix_new_exp (frag_now, where, 2,
3011 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3016 dwarf2_emit_insn (insn_length);
3017 break;
3019 case 2:
3020 /* Shift instruction. */
3021 line = extract_operand (line, l1, sizeof (l1));
3022 strncpy (l2, l1, sizeof (l2));
3023 l2[sizeof (l2) - 1] = '\0';
3024 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3025 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3027 if (res)
3028 break; /* An error occurred. All warnings were done before. */
3030 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
3031 frag = frag_more (insn_length);
3032 where = frag - frag_now->fr_literal;
3034 if (target_is_430xv2 ()
3035 && op1.mode == OP_REG
3036 && op1.reg == 0
3037 && (is_opcode ("rlax")
3038 || is_opcode ("rlcx")
3039 || is_opcode ("rla")
3040 || is_opcode ("rlc")))
3042 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3043 break;
3046 /* If the status register is the destination... */
3047 if (op1.am == 0 && op1.reg == 2
3048 /* ... and the opcode alters the SR. */
3049 && (is_opcode ("rla") || is_opcode ("rlc")
3050 || is_opcode ("rlax") || is_opcode ("rlcx")
3051 || is_opcode ("sxt") || is_opcode ("sxtx")
3052 || is_opcode ("swpb")
3055 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
3056 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3057 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
3058 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3061 if (extended_op)
3063 if (!addr_op)
3064 extended |= BYTE_OPERATION;
3066 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3068 as_bad (_("repeat instruction used with non-register mode instruction"));
3069 extended &= ~ 0xf;
3072 if (op1.mode == OP_EXP)
3074 if (op1.exp.X_op == O_constant)
3075 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3077 else if (op1.reg || op1.am == 3) /* Not PC relative. */
3078 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3079 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3080 else
3081 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3082 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3085 if (op2.mode == OP_EXP)
3087 if (op2.exp.X_op == O_constant)
3088 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3090 else if (op1.mode == OP_EXP)
3091 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3092 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3093 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3094 else
3095 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3096 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3097 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3100 /* Emit the extension word. */
3101 bfd_putl16 (extended, frag);
3102 frag += 2;
3103 where += 2;
3106 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3107 bfd_putl16 ((bfd_vma) bin, frag);
3108 frag += 2;
3109 where += 2;
3111 if (op1.mode == OP_EXP)
3113 if (op1.exp.X_op == O_constant)
3115 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3117 else
3119 bfd_putl16 ((bfd_vma) ZEROS, frag);
3121 if (!extended_op)
3123 if (op1.reg || op1.am == 3) /* Not PC relative. */
3124 fix_new_exp (frag_now, where, 2,
3125 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3126 else
3127 fix_new_exp (frag_now, where, 2,
3128 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3131 frag += 2;
3132 where += 2;
3135 if (op2.mode == OP_EXP)
3137 if (op2.exp.X_op == O_constant)
3139 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3141 else
3143 bfd_putl16 ((bfd_vma) ZEROS, frag);
3145 if (!extended_op)
3147 if (op2.reg) /* Not PC relative. */
3148 fix_new_exp (frag_now, where, 2,
3149 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
3150 else
3151 fix_new_exp (frag_now, where, 2,
3152 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3157 dwarf2_emit_insn (insn_length);
3158 break;
3160 case 3:
3161 /* Branch instruction => mov dst, r0. */
3162 if (extended_op)
3164 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3165 break;
3168 line = extract_operand (line, l1, sizeof (l1));
3169 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
3170 if (res)
3171 break;
3173 byte_op = FALSE;
3174 imm_op = FALSE;
3175 bin |= ((op1.reg << 8) | (op1.am << 4));
3176 op_length = 2 + 2 * op1.ol;
3177 frag = frag_more (op_length);
3178 where = frag - frag_now->fr_literal;
3179 bfd_putl16 ((bfd_vma) bin, frag);
3181 if (op1.mode == OP_EXP)
3183 if (op1.exp.X_op == O_constant)
3185 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
3187 else
3189 where += 2;
3191 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3193 if (op1.reg || op1.am == 3)
3194 fix_new_exp (frag_now, where, 2,
3195 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3196 else
3197 fix_new_exp (frag_now, where, 2,
3198 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3202 dwarf2_emit_insn (insn_length + op_length);
3203 break;
3205 case 4:
3206 /* CALLA instructions. */
3207 fix_emitted = FALSE;
3209 line = extract_operand (line, l1, sizeof (l1));
3210 imm_op = FALSE;
3212 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
3213 extended_op, FALSE);
3214 if (res)
3215 break;
3217 byte_op = FALSE;
3219 op_length = 2 + 2 * op1.ol;
3220 frag = frag_more (op_length);
3221 where = frag - frag_now->fr_literal;
3223 if (imm_op)
3225 if (op1.am == 3)
3227 bin |= 0xb0;
3229 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3230 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3231 fix_emitted = TRUE;
3233 else if (op1.am == 1)
3235 if (op1.reg == 0)
3237 bin |= 0x90;
3239 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3240 BFD_RELOC_MSP430X_PCR20_CALL);
3241 fix_emitted = TRUE;
3243 else
3244 bin |= 0x50 | op1.reg;
3246 else if (op1.am == 0)
3247 bin |= 0x40 | op1.reg;
3249 else if (op1.am == 1)
3251 bin |= 0x80;
3253 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3254 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3255 fix_emitted = TRUE;
3257 else if (op1.am == 2)
3258 bin |= 0x60 | op1.reg;
3259 else if (op1.am == 3)
3260 bin |= 0x70 | op1.reg;
3262 bfd_putl16 ((bfd_vma) bin, frag);
3264 if (op1.mode == OP_EXP)
3266 if (op1.ol != 1)
3268 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
3269 break;
3272 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3274 if (! fix_emitted)
3275 fix_new_exp (frag_now, where + 2, 2,
3276 &(op1.exp), FALSE, BFD_RELOC_16);
3279 dwarf2_emit_insn (insn_length + op_length);
3280 break;
3282 case 5:
3284 int n;
3285 int reg;
3287 /* [POP|PUSH]M[.A] #N, Rd */
3288 line = extract_operand (line, l1, sizeof (l1));
3289 line = extract_operand (line, l2, sizeof (l2));
3291 if (*l1 != '#')
3293 as_bad (_("expected #n as first argument of %s"), opcode->name);
3294 break;
3296 end = parse_exp (l1 + 1, &(op1.exp));
3297 if (end != NULL && *end != 0)
3299 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end, l1);
3300 break;
3302 if (op1.exp.X_op != O_constant)
3304 as_bad (_("expected constant expression as first argument of %s"),
3305 opcode->name);
3306 break;
3309 if ((reg = check_reg (l2)) == -1)
3311 as_bad (_("expected register as second argument of %s"),
3312 opcode->name);
3313 break;
3316 op_length = 2;
3317 frag = frag_more (op_length);
3318 where = frag - frag_now->fr_literal;
3319 bin = opcode->bin_opcode;
3320 if (! addr_op)
3321 bin |= 0x100;
3322 n = op1.exp.X_add_number;
3323 bin |= (n - 1) << 4;
3324 if (is_opcode ("pushm"))
3325 bin |= reg;
3326 else
3328 if (reg - n + 1 < 0)
3330 as_bad (_("Too many registers popped"));
3331 break;
3334 /* CPU21 errata: cannot use POPM to restore the SR register. */
3335 if (target_is_430xv2 ()
3336 && (reg - n + 1 < 3)
3337 && reg >= 2
3338 && is_opcode ("popm"))
3340 as_bad (_("Cannot use POPM to restore the SR register"));
3341 break;
3344 bin |= (reg - n + 1);
3347 bfd_putl16 ((bfd_vma) bin, frag);
3348 dwarf2_emit_insn (op_length);
3349 break;
3352 case 6:
3354 int n;
3355 int reg;
3357 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3358 if (extended & 0xff)
3360 as_bad (_("repeat count cannot be used with %s"), opcode->name);
3361 break;
3364 line = extract_operand (line, l1, sizeof (l1));
3365 line = extract_operand (line, l2, sizeof (l2));
3367 if (*l1 != '#')
3369 as_bad (_("expected #n as first argument of %s"), opcode->name);
3370 break;
3372 end = parse_exp (l1 + 1, &(op1.exp));
3373 if (end != NULL && *end != 0)
3375 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3376 break;
3378 if (op1.exp.X_op != O_constant)
3380 as_bad (_("expected constant expression as first argument of %s"),
3381 opcode->name);
3382 break;
3384 n = op1.exp.X_add_number;
3385 if (n > 4 || n < 1)
3387 as_bad (_("expected first argument of %s to be in the range 1-4"),
3388 opcode->name);
3389 break;
3392 if ((reg = check_reg (l2)) == -1)
3394 as_bad (_("expected register as second argument of %s"),
3395 opcode->name);
3396 break;
3399 if (target_is_430xv2 () && reg == 0)
3401 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3402 break;
3405 op_length = 2;
3406 frag = frag_more (op_length);
3407 where = frag - frag_now->fr_literal;
3409 bin = opcode->bin_opcode;
3410 if (! addr_op)
3411 bin |= 0x10;
3412 bin |= (n - 1) << 10;
3413 bin |= reg;
3415 bfd_putl16 ((bfd_vma) bin, frag);
3416 dwarf2_emit_insn (op_length);
3417 break;
3420 case 8:
3422 bfd_boolean need_reloc = FALSE;
3423 int n;
3424 int reg;
3426 /* ADDA, CMPA and SUBA address instructions. */
3427 if (extended & 0xff)
3429 as_bad (_("repeat count cannot be used with %s"), opcode->name);
3430 break;
3433 line = extract_operand (line, l1, sizeof (l1));
3434 line = extract_operand (line, l2, sizeof (l2));
3436 bin = opcode->bin_opcode;
3438 if (*l1 == '#')
3440 end = parse_exp (l1 + 1, &(op1.exp));
3441 if (end != NULL && *end != 0)
3443 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3444 break;
3447 if (op1.exp.X_op == O_constant)
3449 n = op1.exp.X_add_number;
3450 if (n > 0xfffff || n < - (0x7ffff))
3452 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3453 opcode->name);
3454 break;
3457 bin |= ((n >> 16) & 0xf) << 8;
3459 else
3461 n = 0;
3462 need_reloc = TRUE;
3465 op_length = 4;
3467 else
3469 if ((n = check_reg (l1)) == -1)
3471 as_bad (_("expected register name or constant as first argument of %s"),
3472 opcode->name);
3473 break;
3476 bin |= (n << 8) | (1 << 6);
3477 op_length = 2;
3480 if ((reg = check_reg (l2)) == -1)
3482 as_bad (_("expected register as second argument of %s"),
3483 opcode->name);
3484 break;
3487 frag = frag_more (op_length);
3488 where = frag - frag_now->fr_literal;
3489 bin |= reg;
3490 if (need_reloc)
3491 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3492 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
3494 bfd_putl16 ((bfd_vma) bin, frag);
3495 if (op_length == 4)
3496 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
3497 dwarf2_emit_insn (op_length);
3498 break;
3501 case 9: /* MOVA, BRA, RETA. */
3502 imm_op = FALSE;
3503 bin = opcode->bin_opcode;
3505 if (is_opcode ("reta"))
3507 /* The RETA instruction does not take any arguments.
3508 The implicit first argument is @SP+.
3509 The implicit second argument is PC. */
3510 op1.mode = OP_REG;
3511 op1.am = 3;
3512 op1.reg = 1;
3514 op2.mode = OP_REG;
3515 op2.reg = 0;
3517 else
3519 line = extract_operand (line, l1, sizeof (l1));
3520 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3521 &imm_op, extended_op, FALSE);
3523 if (is_opcode ("bra"))
3525 /* This is the BRA synthetic instruction.
3526 The second argument is always PC. */
3527 op2.mode = OP_REG;
3528 op2.reg = 0;
3530 else
3532 line = extract_operand (line, l2, sizeof (l2));
3533 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
3534 extended_op, TRUE);
3537 if (res)
3538 break; /* Error occurred. All warnings were done before. */
3541 /* Only a restricted subset of the normal MSP430 addressing modes
3542 are supported here, so check for the ones that are allowed. */
3543 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
3544 & error_message)) == 0)
3546 as_bad (error_message, opcode->name);
3547 break;
3549 dwarf2_emit_insn (op_length);
3550 break;
3552 case 10: /* RPT */
3553 line = extract_operand (line, l1, sizeof l1);
3554 /* The RPT instruction only accepted immediates and registers. */
3555 if (*l1 == '#')
3557 end = parse_exp (l1 + 1, &(op1.exp));
3558 if (end != NULL && *end != 0)
3560 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3561 break;
3563 if (op1.exp.X_op != O_constant)
3565 as_bad (_("expected constant value as argument to RPT"));
3566 break;
3568 if (op1.exp.X_add_number < 1
3569 || op1.exp.X_add_number > (1 << 4))
3571 as_bad (_("expected constant in the range 2..16"));
3572 break;
3575 /* We silently accept and ignore a repeat count of 1. */
3576 if (op1.exp.X_add_number > 1)
3577 repeat_count = op1.exp.X_add_number;
3579 else
3581 int reg;
3583 if ((reg = check_reg (l1)) != -1)
3585 if (reg == 0)
3586 as_warn (_("PC used as an argument to RPT"));
3587 else
3588 repeat_count = - reg;
3590 else
3592 as_bad (_("expected constant or register name as argument to RPT insn"));
3593 break;
3596 break;
3598 default:
3599 as_bad (_("Illegal emulated instruction"));
3600 break;
3602 break;
3604 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3605 From f5 ref man 6.3.3:
3606 The 16-bit Status Register (SR, also called R2), used as a source or
3607 destination register, can only be used in register mode addressed
3608 with word instructions. */
3610 case 1: /* Format 1, double operand. */
3611 line = extract_operand (line, l1, sizeof (l1));
3612 line = extract_operand (line, l2, sizeof (l2));
3613 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3614 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3616 if (res)
3617 break; /* Error occurred. All warnings were done before. */
3619 if (extended_op
3620 && is_opcode ("movx")
3621 && addr_op
3622 && msp430_enable_relax)
3624 /* This is the MOVX.A instruction. See if we can convert
3625 it into the MOVA instruction instead. This saves 2 bytes. */
3626 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3627 NULL)) != 0)
3629 dwarf2_emit_insn (op_length);
3630 break;
3634 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3636 /* If the PC is the destination... */
3637 if (op2.am == 0 && op2.reg == 0
3638 /* ... and the opcode alters the SR. */
3639 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3640 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3642 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
3643 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3644 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
3645 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3648 /* If the status register is the destination... */
3649 if (op2.am == 0 && op2.reg == 2
3650 /* ... and the opcode alters the SR. */
3651 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3652 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3653 || is_opcode ("xor")
3654 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3655 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3656 || is_opcode ("xorx")
3659 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
3660 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3661 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
3662 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3665 /* Chain these checks for SR manipulations so we can warn if they are not
3666 caught. */
3667 if (((is_opcode ("bis") && bin == 0xd032)
3668 || (is_opcode ("mov") && bin == 0x4032)
3669 || (is_opcode ("xor") && bin == 0xe032))
3670 && op1.mode == OP_EXP
3671 && op1.exp.X_op == O_constant
3672 && (op1.exp.X_add_number & 0x10) == 0x10)
3673 check_for_nop |= NOP_CHECK_CPU19;
3674 else if ((is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
3676 /* Any MOV with the SR as the destination either enables or disables
3677 interrupts. */
3678 if (op1.mode == OP_EXP
3679 && op1.exp.X_op == O_constant)
3681 if ((op1.exp.X_add_number & 0x8) == 0x8)
3683 /* The GIE bit is being set. */
3684 warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint);
3685 this_insn_is_eint = TRUE;
3687 else
3688 /* The GIE bit is being cleared. */
3689 this_insn_is_dint = TRUE;
3691 /* If an immediate value which is covered by the constant generator
3692 is the src, then op1 will have been changed to either R2 or R3 by
3693 this point.
3694 The only constants covered by CG1 and CG2, which have bit 3 set
3695 and therefore would enable interrupts when writing to the SR, are
3696 R2 with addresing mode 0b11 and R3 with 0b11.
3697 The addressing mode is in bits 5:4 of the binary opcode. */
3698 else if (op1.mode == OP_REG
3699 && (op1.reg == 2 || op1.reg == 3)
3700 && (bin & 0x30) == 0x30)
3702 warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint);
3703 this_insn_is_eint = TRUE;
3705 /* Any other use of the constant generator with destination R2, will
3706 disable interrupts. */
3707 else if (op1.mode == OP_REG
3708 && (op1.reg == 2 || op1.reg == 3))
3709 this_insn_is_dint = TRUE;
3710 else if (do_unknown_interrupt_nops)
3712 /* FIXME: Couldn't work out whether the insn is enabling or
3713 disabling interrupts, so for safety need to treat it as both
3714 a DINT and EINT. */
3715 warn_unsure_interrupt (prev_insn_is_nop, prev_insn_is_dint);
3716 check_for_nop |= NOP_CHECK_INTERRUPT;
3719 else if (is_eint (opcode->name, bin))
3720 warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint);
3721 else if ((bin & 0x32) == 0x32)
3723 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3724 * an interrupt state change if a write happens. */
3725 /* FIXME: How strict to be here? */
3729 /* Compute the entire length of the instruction in bytes. */
3730 op_length = (extended_op ? 2 : 0) /* The extension word. */
3731 + 2 /* The opcode */
3732 + (2 * op1.ol) /* The first operand. */
3733 + (2 * op2.ol); /* The second operand. */
3735 insn_length += op_length;
3736 frag = frag_more (op_length);
3737 where = frag - frag_now->fr_literal;
3739 if (extended_op)
3741 if (!addr_op)
3742 extended |= BYTE_OPERATION;
3744 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3746 as_bad (_("repeat instruction used with non-register mode instruction"));
3747 extended &= ~ 0xf;
3750 /* If necessary, emit a reloc to update the extension word. */
3751 if (op1.mode == OP_EXP)
3753 if (op1.exp.X_op == O_constant)
3754 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3756 else if (op1.reg || op1.am == 3) /* Not PC relative. */
3757 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3758 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3759 else
3760 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3761 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3764 if (op2.mode == OP_EXP)
3766 if (op2.exp.X_op == O_constant)
3767 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3769 else if (op1.mode == OP_EXP)
3770 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3771 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3772 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3774 else
3775 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3776 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3777 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3780 /* Emit the extension word. */
3781 bfd_putl16 (extended, frag);
3782 where += 2;
3783 frag += 2;
3786 bfd_putl16 ((bfd_vma) bin, frag);
3787 where += 2;
3788 frag += 2;
3790 if (op1.mode == OP_EXP)
3792 if (op1.exp.X_op == O_constant)
3794 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3796 else
3798 bfd_putl16 ((bfd_vma) ZEROS, frag);
3800 if (!extended_op)
3802 if (op1.reg || op1.am == 3) /* Not PC relative. */
3803 fix_new_exp (frag_now, where, 2,
3804 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3805 else
3806 fix_new_exp (frag_now, where, 2,
3807 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3811 where += 2;
3812 frag += 2;
3815 if (op2.mode == OP_EXP)
3817 if (op2.exp.X_op == O_constant)
3819 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3821 else
3823 bfd_putl16 ((bfd_vma) ZEROS, frag);
3825 if (!extended_op)
3827 if (op2.reg) /* Not PC relative. */
3828 fix_new_exp (frag_now, where, 2,
3829 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
3830 else
3831 fix_new_exp (frag_now, where, 2,
3832 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3837 dwarf2_emit_insn (insn_length);
3839 /* If the PC is the destination... */
3840 if (op2.am == 0 && op2.reg == 0
3841 /* ... but the opcode does not alter the destination. */
3842 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3843 check_for_nop |= NOP_CHECK_CPU12;
3844 break;
3846 case 2: /* Single-operand mostly instr. */
3847 if (opcode->insn_opnumb == 0)
3849 /* reti instruction. */
3850 insn_length += 2;
3851 frag = frag_more (2);
3852 bfd_putl16 ((bfd_vma) bin, frag);
3853 dwarf2_emit_insn (insn_length);
3854 break;
3857 line = extract_operand (line, l1, sizeof (l1));
3858 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3859 &imm_op, extended_op, TRUE);
3860 if (res)
3861 break; /* Error in operand. */
3863 if (target_is_430xv2 ()
3864 && op1.mode == OP_REG
3865 && op1.reg == 0
3866 && (is_opcode ("rrax")
3867 || is_opcode ("rrcx")
3868 || is_opcode ("rra")
3869 || is_opcode ("rrc")))
3871 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3872 break;
3875 /* If the status register is the destination... */
3876 if (op1.am == 0 && op1.reg == 2
3877 /* ... and the opcode alters the SR. */
3878 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3880 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
3881 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3882 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
3883 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3886 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3887 frag = frag_more (insn_length);
3888 where = frag - frag_now->fr_literal;
3890 if (extended_op)
3892 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3894 /* These two instructions use a special
3895 encoding of the A/L and B/W bits. */
3896 bin &= ~ BYTE_OPERATION;
3898 if (byte_op)
3900 as_bad (_("%s instruction does not accept a .b suffix"),
3901 opcode->name);
3902 break;
3904 else if (! addr_op)
3905 extended |= BYTE_OPERATION;
3907 else if (! addr_op)
3908 extended |= BYTE_OPERATION;
3910 if (is_opcode ("rrux"))
3911 extended |= IGNORE_CARRY_BIT;
3913 if (op1.ol != 0 && ((extended & 0xf) != 0))
3915 as_bad (_("repeat instruction used with non-register mode instruction"));
3916 extended &= ~ 0xf;
3919 if (op1.mode == OP_EXP)
3921 if (op1.exp.X_op == O_constant)
3922 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3924 else if (op1.reg || op1.am == 3) /* Not PC relative. */
3925 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3926 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3927 else
3928 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3929 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3932 /* Emit the extension word. */
3933 bfd_putl16 (extended, frag);
3934 frag += 2;
3935 where += 2;
3938 bin |= op1.reg | (op1.am << 4);
3939 bfd_putl16 ((bfd_vma) bin, frag);
3940 frag += 2;
3941 where += 2;
3943 if (op1.mode == OP_EXP)
3945 if (op1.exp.X_op == O_constant)
3947 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3949 else
3951 bfd_putl16 ((bfd_vma) ZEROS, frag);
3953 if (!extended_op)
3955 if (op1.reg || op1.am == 3) /* Not PC relative. */
3956 fix_new_exp (frag_now, where, 2,
3957 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3958 else
3959 fix_new_exp (frag_now, where, 2,
3960 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3965 dwarf2_emit_insn (insn_length);
3966 break;
3968 case 3: /* Conditional jumps instructions. */
3969 line = extract_operand (line, l1, sizeof (l1));
3970 /* l1 is a label. */
3971 if (l1[0])
3973 char *m = l1;
3974 expressionS exp;
3976 if (*m == '$')
3977 m++;
3979 end = parse_exp (m, &exp);
3980 if (end != NULL && *end != 0)
3982 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3983 break;
3986 /* In order to handle something like:
3988 and #0x8000, r5
3989 tst r5
3990 jz 4 ; skip next 4 bytes
3991 inv r5
3992 inc r5
3993 nop ; will jump here if r5 positive or zero
3995 jCOND -n ;assumes jump n bytes backward:
3997 mov r5,r6
3998 jmp -2
4000 is equal to:
4001 lab:
4002 mov r5,r6
4003 jmp lab
4005 jCOND $n ; jump from PC in either direction. */
4007 if (exp.X_op == O_constant)
4009 int x = exp.X_add_number;
4011 if (x & 1)
4013 as_warn (_("Even number required. Rounded to %d"), x + 1);
4014 x++;
4017 if ((*l1 == '$' && x > 0) || x < 0)
4018 x -= 2;
4020 x >>= 1;
4022 if (x > 512 || x < -511)
4024 as_bad (_("Wrong displacement %d"), x << 1);
4025 break;
4028 insn_length += 2;
4029 frag = frag_more (2); /* Instr size is 1 word. */
4031 bin |= x & 0x3ff;
4032 bfd_putl16 ((bfd_vma) bin, frag);
4034 else if (exp.X_op == O_symbol && *l1 != '$')
4036 insn_length += 2;
4037 frag = frag_more (2); /* Instr size is 1 word. */
4038 where = frag - frag_now->fr_literal;
4039 fix_new_exp (frag_now, where, 2,
4040 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
4042 bfd_putl16 ((bfd_vma) bin, frag);
4044 else if (*l1 == '$')
4046 as_bad (_("instruction requires label sans '$'"));
4048 else
4049 as_bad (_
4050 ("instruction requires label or value in range -511:512"));
4051 dwarf2_emit_insn (insn_length);
4052 break;
4054 else
4056 as_bad (_("instruction requires label"));
4057 break;
4059 break;
4061 case 4: /* Extended jumps. */
4062 if (!msp430_enable_polys)
4064 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4065 break;
4068 line = extract_operand (line, l1, sizeof (l1));
4069 if (l1[0])
4071 char *m = l1;
4072 expressionS exp;
4074 /* Ignore absolute addressing. make it PC relative anyway. */
4075 if (*m == '#' || *m == '$')
4076 m++;
4078 end = parse_exp (m, & exp);
4079 if (end != NULL && *end != 0)
4081 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
4082 break;
4084 if (exp.X_op == O_symbol)
4086 /* Relaxation required. */
4087 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
4089 if (target_is_430x ())
4090 rc = msp430x_rcodes[opcode->insn_opnumb];
4092 /* The parameter to dwarf2_emit_insn is actually the offset to
4093 the start of the insn from the fix piece of instruction that
4094 was emitted. Since next fragments may have variable size we
4095 tie debug info to the beginning of the instruction. */
4096 insn_length += 8;
4097 frag = frag_more (8);
4098 dwarf2_emit_insn (0);
4099 bfd_putl16 ((bfd_vma) rc.sop, frag);
4100 frag = frag_variant (rs_machine_dependent, 8, 2,
4101 /* Wild guess. */
4102 ENCODE_RELAX (rc.lpos, STATE_BITS10),
4103 exp.X_add_symbol,
4104 0, /* Offset is zero if jump dist less than 1K. */
4105 (char *) frag);
4106 break;
4110 as_bad (_("instruction requires label"));
4111 break;
4113 case 5: /* Emulated extended branches. */
4114 if (!msp430_enable_polys)
4116 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4117 break;
4119 line = extract_operand (line, l1, sizeof (l1));
4120 if (l1[0])
4122 char * m = l1;
4123 expressionS exp;
4125 /* Ignore absolute addressing. make it PC relative anyway. */
4126 if (*m == '#' || *m == '$')
4127 m++;
4129 end = parse_exp (m, & exp);
4130 if (end != NULL && *end != 0)
4132 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
4133 break;
4135 if (exp.X_op == O_symbol)
4137 /* Relaxation required. */
4138 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
4140 if (target_is_430x ())
4141 hc = msp430x_hcodes[opcode->insn_opnumb];
4143 insn_length += 8;
4144 frag = frag_more (8);
4145 dwarf2_emit_insn (0);
4146 bfd_putl16 ((bfd_vma) hc.op0, frag);
4147 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
4149 frag = frag_variant (rs_machine_dependent, 8, 2,
4150 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
4151 exp.X_add_symbol,
4152 0, /* Offset is zero if jump dist less than 1K. */
4153 (char *) frag);
4154 break;
4158 as_bad (_("instruction requires label"));
4159 break;
4161 default:
4162 as_bad (_("Illegal instruction or not implemented opcode."));
4165 if (is_opcode ("nop"))
4167 prev_insn_is_nop = TRUE;
4168 prev_insn_is_dint = FALSE;
4169 prev_insn_is_eint = FALSE;
4171 else if (this_insn_is_dint || is_dint (opcode->name, bin))
4173 prev_insn_is_dint = TRUE;
4174 prev_insn_is_eint = FALSE;
4175 prev_insn_is_nop = FALSE;
4176 check_for_nop |= NOP_CHECK_INTERRUPT;
4178 /* NOP is not needed after EINT for 430 ISA. */
4179 else if (target_is_430x () && (this_insn_is_eint || is_eint (opcode->name, bin)))
4181 prev_insn_is_eint = TRUE;
4182 prev_insn_is_nop = FALSE;
4183 prev_insn_is_dint = FALSE;
4184 check_for_nop |= NOP_CHECK_INTERRUPT;
4186 else
4188 prev_insn_is_nop = FALSE;
4189 prev_insn_is_dint = FALSE;
4190 prev_insn_is_eint = FALSE;
4193 input_line_pointer = line;
4194 return 0;
4197 void
4198 md_assemble (char * str)
4200 struct msp430_opcode_s * opcode;
4201 char cmd[32];
4202 unsigned int i = 0;
4204 str = skip_space (str); /* Skip leading spaces. */
4205 str = extract_cmd (str, cmd, sizeof (cmd) - 1);
4207 while (cmd[i])
4209 char a = TOLOWER (cmd[i]);
4210 cmd[i] = a;
4211 i++;
4214 if (!cmd[0])
4216 as_bad (_("can't find opcode"));
4217 return;
4220 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
4222 if (opcode == NULL)
4224 as_bad (_("unknown opcode `%s'"), cmd);
4225 return;
4229 char *__t = input_line_pointer;
4231 msp430_operands (opcode, str);
4232 input_line_pointer = __t;
4236 /* GAS will call this function for each section at the end of the assembly,
4237 to permit the CPU backend to adjust the alignment of a section. */
4239 valueT
4240 md_section_align (asection * seg, valueT addr)
4242 int align = bfd_get_section_alignment (stdoutput, seg);
4244 return ((addr + (1 << align) - 1) & -(1 << align));
4247 /* If you define this macro, it should return the offset between the
4248 address of a PC relative fixup and the position from which the PC
4249 relative adjustment should be made. On many processors, the base
4250 of a PC relative instruction is the next instruction, so this
4251 macro would return the length of an instruction. */
4253 long
4254 md_pcrel_from_section (fixS * fixp, segT sec)
4256 if (fixp->fx_addsy != (symbolS *) NULL
4257 && (!S_IS_DEFINED (fixp->fx_addsy)
4258 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
4259 return 0;
4261 return fixp->fx_frag->fr_address + fixp->fx_where;
4264 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4265 Now it handles the situation when relocations
4266 have to be passed to linker. */
4268 msp430_force_relocation_local (fixS *fixp)
4270 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
4271 return 1;
4272 if (fixp->fx_pcrel)
4273 return 1;
4274 if (msp430_enable_polys
4275 && !msp430_enable_relax)
4276 return 1;
4278 return 0;
4282 /* GAS will call this for each fixup. It should store the correct
4283 value in the object file. */
4284 void
4285 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
4287 unsigned char * where;
4288 unsigned long insn;
4289 long value;
4291 if (fixp->fx_addsy == (symbolS *) NULL)
4293 value = *valuep;
4294 fixp->fx_done = 1;
4296 else if (fixp->fx_pcrel)
4298 segT s = S_GET_SEGMENT (fixp->fx_addsy);
4300 if (fixp->fx_addsy && (s == seg || s == absolute_section))
4302 /* FIXME: We can appear here only in case if we perform a pc
4303 relative jump to the label which is i) global, ii) locally
4304 defined or this is a jump to an absolute symbol.
4305 If this is an absolute symbol -- everything is OK.
4306 If this is a global label, we've got a symbol value defined
4307 twice:
4308 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4309 from this section start
4310 2. *valuep will contain the real offset from jump insn to the
4311 label
4312 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4313 will be incorrect. Therefore remove s_get_value. */
4314 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
4315 fixp->fx_done = 1;
4317 else
4318 value = *valuep;
4320 else
4322 value = fixp->fx_offset;
4324 if (fixp->fx_subsy != (symbolS *) NULL)
4326 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4328 value -= S_GET_VALUE (fixp->fx_subsy);
4329 fixp->fx_done = 1;
4334 fixp->fx_no_overflow = 1;
4336 /* If polymorphs are enabled and relax disabled.
4337 do not kill any relocs and pass them to linker. */
4338 if (msp430_enable_polys
4339 && !msp430_enable_relax)
4341 if (!fixp->fx_addsy
4342 || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
4343 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
4344 else
4345 fixp->fx_done = 0;
4348 if (fixp->fx_done)
4350 /* Fetch the instruction, insert the fully resolved operand
4351 value, and stuff the instruction back again. */
4352 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
4354 insn = bfd_getl16 (where);
4356 switch (fixp->fx_r_type)
4358 case BFD_RELOC_MSP430_10_PCREL:
4359 if (value & 1)
4360 as_bad_where (fixp->fx_file, fixp->fx_line,
4361 _("odd address operand: %ld"), value);
4363 /* Jumps are in words. */
4364 value >>= 1;
4365 --value; /* Correct PC. */
4367 if (value < -512 || value > 511)
4368 as_bad_where (fixp->fx_file, fixp->fx_line,
4369 _("operand out of range: %ld"), value);
4371 value &= 0x3ff; /* get rid of extended sign */
4372 bfd_putl16 ((bfd_vma) (value | insn), where);
4373 break;
4375 case BFD_RELOC_MSP430X_PCR16:
4376 case BFD_RELOC_MSP430_RL_PCREL:
4377 case BFD_RELOC_MSP430_16_PCREL:
4378 if (value & 1)
4379 as_bad_where (fixp->fx_file, fixp->fx_line,
4380 _("odd address operand: %ld"), value);
4381 /* Fall through. */
4383 case BFD_RELOC_MSP430_16_PCREL_BYTE:
4384 /* Nothing to be corrected here. */
4385 if (value < -32768 || value > 65536)
4386 as_bad_where (fixp->fx_file, fixp->fx_line,
4387 _("operand out of range: %ld"), value);
4388 /* Fall through. */
4390 case BFD_RELOC_MSP430X_ABS16:
4391 case BFD_RELOC_MSP430_16:
4392 case BFD_RELOC_16:
4393 case BFD_RELOC_MSP430_16_BYTE:
4394 value &= 0xffff; /* Get rid of extended sign. */
4395 bfd_putl16 ((bfd_vma) value, where);
4396 break;
4398 case BFD_RELOC_MSP430_ABS_HI16:
4399 value >>= 16;
4400 value &= 0xffff; /* Get rid of extended sign. */
4401 bfd_putl16 ((bfd_vma) value, where);
4402 break;
4404 case BFD_RELOC_32:
4405 bfd_putl16 ((bfd_vma) value, where);
4406 break;
4408 case BFD_RELOC_MSP430_ABS8:
4409 case BFD_RELOC_8:
4410 bfd_put_8 (NULL, (bfd_vma) value, where);
4411 break;
4413 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
4414 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
4415 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
4416 value >>= 16;
4417 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
4418 break;
4420 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
4421 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4422 value >>= 16;
4423 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
4424 break;
4426 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
4427 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4428 value >>= 16;
4429 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4430 break;
4432 case BFD_RELOC_MSP430X_PCR20_CALL:
4433 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4434 value >>= 16;
4435 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4436 break;
4438 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
4439 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
4440 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
4441 value >>= 16;
4442 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4443 break;
4445 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
4446 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4447 value >>= 16;
4448 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4449 break;
4451 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
4452 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4453 value >>= 16;
4454 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4455 break;
4457 default:
4458 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4459 fixp->fx_line, fixp->fx_r_type);
4460 break;
4463 else
4465 fixp->fx_addnumber = value;
4469 static bfd_boolean
4470 S_IS_GAS_LOCAL (symbolS * s)
4472 const char * name;
4473 unsigned int len;
4475 if (s == NULL)
4476 return FALSE;
4477 name = S_GET_NAME (s);
4478 len = strlen (name) - 1;
4480 return name[len] == 1 || name[len] == 2;
4483 /* GAS will call this to generate a reloc, passing the resulting reloc
4484 to `bfd_install_relocation'. This currently works poorly, as
4485 `bfd_install_relocation' often does the wrong thing, and instances of
4486 `tc_gen_reloc' have been written to work around the problems, which
4487 in turns makes it difficult to fix `bfd_install_relocation'. */
4489 /* If while processing a fixup, a reloc really needs to be created
4490 then it is done here. */
4492 arelent **
4493 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
4495 static arelent * no_relocs = NULL;
4496 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
4497 arelent *reloc;
4499 reloc = XNEW (arelent);
4500 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4501 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
4503 if (reloc->howto == (reloc_howto_type *) NULL)
4505 as_bad_where (fixp->fx_file, fixp->fx_line,
4506 _("reloc %d not supported by object file format"),
4507 (int) fixp->fx_r_type);
4508 free (reloc);
4509 return & no_relocs;
4512 relocs[0] = reloc;
4513 relocs[1] = NULL;
4515 if (fixp->fx_subsy
4516 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4518 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
4519 fixp->fx_subsy = NULL;
4522 if (fixp->fx_addsy && fixp->fx_subsy)
4524 asection *asec, *ssec;
4526 asec = S_GET_SEGMENT (fixp->fx_addsy);
4527 ssec = S_GET_SEGMENT (fixp->fx_subsy);
4529 /* If we have a difference between two different, non-absolute symbols
4530 we must generate two relocs (one for each symbol) and allow the
4531 linker to resolve them - relaxation may change the distances between
4532 symbols, even local symbols defined in the same section.
4534 Unfortunately we cannot do this with assembler generated local labels
4535 because there can be multiple incarnations of the same label, with
4536 exactly the same name, in any given section and the linker will have
4537 no way to identify the correct one. Instead we just have to hope
4538 that no relaxation will occur between the local label and the other
4539 symbol in the expression.
4541 Similarly we have to compute differences between symbols in the .eh_frame
4542 section as the linker is not smart enough to apply relocations there
4543 before attempting to process it. */
4544 if ((ssec != absolute_section || asec != absolute_section)
4545 && (fixp->fx_addsy != fixp->fx_subsy)
4546 && strcmp (ssec->name, ".eh_frame") != 0
4547 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
4548 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
4550 arelent * reloc2 = XNEW (arelent);
4552 relocs[0] = reloc2;
4553 relocs[1] = reloc;
4555 reloc2->address = reloc->address;
4556 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
4557 BFD_RELOC_MSP430_SYM_DIFF);
4558 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
4560 if (ssec == absolute_section)
4561 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4562 else
4564 reloc2->sym_ptr_ptr = XNEW (asymbol *);
4565 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
4568 reloc->addend = fixp->fx_offset;
4569 if (asec == absolute_section)
4571 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
4572 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4574 else
4576 reloc->sym_ptr_ptr = XNEW (asymbol *);
4577 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4580 fixp->fx_pcrel = 0;
4581 fixp->fx_done = 1;
4582 return relocs;
4584 else
4586 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4588 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
4589 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
4591 switch (fixp->fx_r_type)
4593 case BFD_RELOC_8:
4594 md_number_to_chars (fixpos, reloc->addend, 1);
4595 break;
4597 case BFD_RELOC_16:
4598 md_number_to_chars (fixpos, reloc->addend, 2);
4599 break;
4601 case BFD_RELOC_24:
4602 md_number_to_chars (fixpos, reloc->addend, 3);
4603 break;
4605 case BFD_RELOC_32:
4606 md_number_to_chars (fixpos, reloc->addend, 4);
4607 break;
4609 default:
4610 reloc->sym_ptr_ptr
4611 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
4612 return relocs;
4615 free (reloc);
4616 return & no_relocs;
4619 else
4621 #if 0
4622 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
4623 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
4625 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
4626 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4628 md_number_to_chars (fixpos, amount, 2);
4629 free (reloc);
4630 return & no_relocs;
4632 #endif
4633 reloc->sym_ptr_ptr = XNEW (asymbol *);
4634 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4635 reloc->addend = fixp->fx_offset;
4637 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
4638 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
4639 reloc->address = fixp->fx_offset;
4642 return relocs;
4646 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
4647 asection * segment_type ATTRIBUTE_UNUSED)
4649 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
4651 /* This is a jump -> pcrel mode. Nothing to do much here.
4652 Return value == 2. */
4653 fragP->fr_subtype =
4654 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
4656 else if (fragP->fr_symbol)
4658 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4659 an absolute segment, we don't know a displacement until we link
4660 object files. So it will always be long. This also applies to
4661 labels in a subsegment of current. Liker may relax it to short
4662 jump later. Return value == 8. */
4663 fragP->fr_subtype =
4664 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
4666 else
4668 /* We know the abs value. may be it is a jump to fixed address.
4669 Impossible in our case, cause all constants already handled. */
4670 fragP->fr_subtype =
4671 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
4674 return md_relax_table[fragP->fr_subtype].rlx_length;
4677 void
4678 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
4679 asection * sec ATTRIBUTE_UNUSED,
4680 fragS * fragP)
4682 char * where = 0;
4683 int rela = -1;
4684 int i;
4685 struct rcodes_s * cc = NULL;
4686 struct hcodes_s * hc = NULL;
4688 switch (fragP->fr_subtype)
4690 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
4691 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
4692 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
4693 /* We do not have to convert anything here.
4694 Just apply a fix. */
4695 rela = BFD_RELOC_MSP430_10_PCREL;
4696 break;
4698 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
4699 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
4700 /* Convert uncond branch jmp lab -> br lab. */
4701 if (target_is_430x ())
4702 cc = msp430x_rcodes + 7;
4703 else
4704 cc = msp430_rcodes + 7;
4705 where = fragP->fr_literal + fragP->fr_fix;
4706 bfd_putl16 (cc->lop0, where);
4707 rela = BFD_RELOC_MSP430_RL_PCREL;
4708 fragP->fr_fix += 2;
4709 break;
4711 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
4712 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
4714 /* Other simple branches. */
4715 int insn = bfd_getl16 (fragP->fr_opcode);
4717 insn &= 0xffff;
4718 /* Find actual instruction. */
4719 if (target_is_430x ())
4721 for (i = 0; i < 7 && !cc; i++)
4722 if (msp430x_rcodes[i].sop == insn)
4723 cc = msp430x_rcodes + i;
4725 else
4727 for (i = 0; i < 7 && !cc; i++)
4728 if (msp430_rcodes[i].sop == insn)
4729 cc = & msp430_rcodes[i];
4732 if (!cc || !cc->name)
4733 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4734 __FUNCTION__, (long) insn);
4735 where = fragP->fr_literal + fragP->fr_fix;
4736 bfd_putl16 (cc->lop0, where);
4737 bfd_putl16 (cc->lop1, where + 2);
4738 rela = BFD_RELOC_MSP430_RL_PCREL;
4739 fragP->fr_fix += 4;
4741 break;
4743 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
4744 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
4745 if (target_is_430x ())
4746 cc = msp430x_rcodes + 6;
4747 else
4748 cc = msp430_rcodes + 6;
4749 where = fragP->fr_literal + fragP->fr_fix;
4750 bfd_putl16 (cc->lop0, where);
4751 bfd_putl16 (cc->lop1, where + 2);
4752 bfd_putl16 (cc->lop2, where + 4);
4753 rela = BFD_RELOC_MSP430_RL_PCREL;
4754 fragP->fr_fix += 6;
4755 break;
4757 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4759 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4761 insn &= 0xffff;
4762 if (target_is_430x ())
4764 for (i = 0; i < 4 && !hc; i++)
4765 if (msp430x_hcodes[i].op1 == insn)
4766 hc = msp430x_hcodes + i;
4768 else
4770 for (i = 0; i < 4 && !hc; i++)
4771 if (msp430_hcodes[i].op1 == insn)
4772 hc = &msp430_hcodes[i];
4774 if (!hc || !hc->name)
4775 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4776 __FUNCTION__, (long) insn);
4777 rela = BFD_RELOC_MSP430_10_PCREL;
4778 /* Apply a fix for a first label if necessary.
4779 another fix will be applied to the next word of insn anyway. */
4780 if (hc->tlab == 2)
4781 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4782 fragP->fr_offset, TRUE, rela);
4783 fragP->fr_fix += 2;
4786 break;
4788 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4789 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4791 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4793 insn &= 0xffff;
4794 if (target_is_430x ())
4796 for (i = 0; i < 4 && !hc; i++)
4797 if (msp430x_hcodes[i].op1 == insn)
4798 hc = msp430x_hcodes + i;
4800 else
4802 for (i = 0; i < 4 && !hc; i++)
4803 if (msp430_hcodes[i].op1 == insn)
4804 hc = & msp430_hcodes[i];
4806 if (!hc || !hc->name)
4807 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4808 __FUNCTION__, (long) insn);
4809 rela = BFD_RELOC_MSP430_RL_PCREL;
4810 where = fragP->fr_literal + fragP->fr_fix;
4811 bfd_putl16 (hc->lop0, where);
4812 bfd_putl16 (hc->lop1, where + 2);
4813 bfd_putl16 (hc->lop2, where + 4);
4814 fragP->fr_fix += 6;
4816 break;
4818 default:
4819 as_fatal (_("internal inconsistency problem in %s: %lx"),
4820 __FUNCTION__, (long) fragP->fr_subtype);
4821 break;
4824 /* Now apply fix. */
4825 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4826 fragP->fr_offset, TRUE, rela);
4827 /* Just fixed 2 bytes. */
4828 fragP->fr_fix += 2;
4831 /* Relax fragment. Mostly stolen from hc11 and mcore
4832 which arches I think I know. */
4834 long
4835 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4836 long stretch ATTRIBUTE_UNUSED)
4838 long growth;
4839 offsetT aim = 0;
4840 symbolS *symbolP;
4841 const relax_typeS *this_type;
4842 const relax_typeS *start_type;
4843 relax_substateT next_state;
4844 relax_substateT this_state;
4845 const relax_typeS *table = md_relax_table;
4847 /* Nothing to be done if the frag has already max size. */
4848 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4849 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4850 return 0;
4852 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4854 symbolP = fragP->fr_symbol;
4855 if (symbol_resolved_p (symbolP))
4856 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4857 __FUNCTION__);
4858 /* We know the offset. calculate a distance. */
4859 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4862 if (!msp430_enable_relax)
4864 /* Relaxation is not enabled. So, make all jump as long ones
4865 by setting 'aim' to quite high value. */
4866 aim = 0x7fff;
4869 this_state = fragP->fr_subtype;
4870 start_type = this_type = table + this_state;
4872 if (aim < 0)
4874 /* Look backwards. */
4875 for (next_state = this_type->rlx_more; next_state;)
4876 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4877 next_state = 0;
4878 else
4880 /* Grow to next state. */
4881 this_state = next_state;
4882 this_type = table + this_state;
4883 next_state = this_type->rlx_more;
4886 else
4888 /* Look forwards. */
4889 for (next_state = this_type->rlx_more; next_state;)
4890 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4891 next_state = 0;
4892 else
4894 /* Grow to next state. */
4895 this_state = next_state;
4896 this_type = table + this_state;
4897 next_state = this_type->rlx_more;
4901 growth = this_type->rlx_length - start_type->rlx_length;
4902 if (growth != 0)
4903 fragP->fr_subtype = this_state;
4904 return growth;
4907 /* Return FALSE if the fixup in fixp should be left alone and not
4908 adjusted. We return FALSE here so that linker relaxation will
4909 work. */
4911 bfd_boolean
4912 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4914 /* If the symbol is in a non-code section then it should be OK. */
4915 if (fixp->fx_addsy
4916 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4917 return TRUE;
4919 return FALSE;
4922 /* Set the contents of the .MSP430.attributes section. */
4924 void
4925 msp430_md_end (void)
4927 if (check_for_nop)
4929 if (gen_interrupt_nops)
4931 gen_nop ();
4932 if (warn_interrupt_nops)
4933 as_warn (INSERT_NOP_AT_EOF);
4935 else if (warn_interrupt_nops)
4936 as_warn (_(WARN_NOP_AT_EOF));
4939 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4940 target_is_430x () ? 2 : 1);
4942 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4943 large_model ? 2 : 1);
4945 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4946 large_model ? 2 : 1);
4949 /* Returns FALSE if there is a msp430 specific reason why the
4950 subtraction of two same-section symbols cannot be computed by
4951 the assembler. */
4953 bfd_boolean
4954 msp430_allow_local_subtract (expressionS * left,
4955 expressionS * right,
4956 segT section)
4958 /* If the symbols are not in a code section then they are OK. */
4959 if ((section->flags & SEC_CODE) == 0)
4960 return TRUE;
4962 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4963 return TRUE;
4965 if (left->X_add_symbol == right->X_add_symbol)
4966 return TRUE;
4968 /* We have to assume that there may be instructions between the
4969 two symbols and that relaxation may increase the distance between
4970 them. */
4971 return FALSE;