1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2022 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)
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. */
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
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
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
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. */
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},
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},
148 /* More difficult than above and they have format 5.
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 ================================================================= */
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. */
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 },
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 },
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 htab_t msp430_hash
;
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
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
[] =
229 /* Unconditional jump. */
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. */
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 */
241 /* blt no overflow branch. */
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 */
247 /* Emulated branches. */
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 */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions
280 For the 430X we generate a 430 relocation only for the case where part of an
281 expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate
283 For the 430 we generate a relocation without assembler range checking
284 if we are handling an immediate value or a byte-width instruction. */
286 #undef CHECK_RELOC_MSP430
287 #define CHECK_RELOC_MSP430(OP) \
289 ? ((OP).expp == MSP_EXPP_ALL \
290 ? BFD_RELOC_MSP430X_ABS16 \
291 : ((OP).vshift == 1 \
292 ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \
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 \
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
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
325 i - function is in Init section
326 f - function is in Fini section
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
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.
346 ------------------------------
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
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
362 .profiler cdE,fxx ; check stack
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
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 /* ? */
402 for (; x
; x
= x
>> 1)
409 /* Parse ordinary expression. */
412 parse_exp (char * s
, expressionS
* op
)
414 input_line_pointer
= s
;
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). */
433 del_spaces (char * s
)
441 while (ISSPACE (*m
) && *m
)
443 memmove (s
, m
, strlen (m
) + 1);
451 skip_space (char * s
)
458 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
461 extract_operand (char * from
, char * to
, int limit
)
465 /* Drop leading whitespace. */
466 from
= skip_space (from
);
468 while (size
< limit
&& *from
)
470 *(to
+ size
) = *from
;
471 if (*from
== ',' || *from
== ';' || *from
== '\n')
486 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
503 s
= input_line_pointer
;
504 end
= input_line_pointer
;
506 while (*end
&& *end
!= '\n')
509 while (*s
&& *s
!= '\n')
520 as_bad (_(".profiler pseudo requires at least two operands."));
521 input_line_pointer
= end
;
525 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
534 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
537 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
540 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
543 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
546 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
549 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
552 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
555 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
558 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
561 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
564 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
567 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
570 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
573 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
576 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
579 as_warn (_("unknown profiling flag - ignored."));
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
;
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?"));
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. */
622 /* Now go to .profiler section. */
623 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
626 emit_expr (& exp
, 2);
628 /* Save label value. */
629 emit_expr (& exp1
, 2);
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;
645 emit_expr (& exp
, 2);
647 /* Return to current section. */
648 subseg_set (seg
, subseg
);
652 extract_word (char * from
, char * to
, int limit
)
657 /* Drop leading whitespace. */
658 from
= skip_space (from
);
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
)
673 #define OPTION_MMCU 'm'
674 #define OPTION_RELAX 'Q'
675 #define OPTION_POLYMORPHS 'P'
676 #define OPTION_LARGE 'l'
677 static bool large_model
= false;
678 #define OPTION_NO_INTR_NOPS 'N'
679 #define OPTION_INTR_NOPS 'n'
680 static bool gen_interrupt_nops
= false;
681 #define OPTION_WARN_INTR_NOPS 'y'
682 #define OPTION_NO_WARN_INTR_NOPS 'Y'
683 static bool warn_interrupt_nops
= true;
684 #define OPTION_UNKNOWN_INTR_NOPS 'u'
685 #define OPTION_NO_UNKNOWN_INTR_NOPS 'U'
686 static bool do_unknown_interrupt_nops
= true;
687 #define OPTION_MCPU 'c'
688 #define OPTION_DATA_REGION 'r'
689 static bool upper_data_region_in_use
= false;
690 /* The default is to use the lower region only. */
691 static bool lower_data_region_only
= true;
693 /* Deprecated option, silently ignore it for compatibility with GCC <= 10. */
694 #define OPTION_MOVE_DATA 'd'
698 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
699 OPTION_SILICON_ERRATA_WARN
,
702 static unsigned int silicon_errata_fix
= 0;
703 static unsigned int silicon_errata_warn
= 0;
704 #define SILICON_ERRATA_CPU4 (1 << 0)
705 #define SILICON_ERRATA_CPU8 (1 << 1)
706 #define SILICON_ERRATA_CPU11 (1 << 2)
707 #define SILICON_ERRATA_CPU12 (1 << 3)
708 #define SILICON_ERRATA_CPU13 (1 << 4)
709 #define SILICON_ERRATA_CPU19 (1 << 5)
712 msp430_set_arch (int option
)
714 char str
[32]; /* 32 for good measure. */
716 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
718 md_parse_option (option
, str
);
719 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
720 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
723 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
724 Keep these two structures in sync.
725 The data in this structure has been extracted from version 1.194 of the
726 devices.csv file released by TI in September 2016. */
728 struct msp430_mcu_data
731 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
732 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
736 { "cc430f5123",2,8 },
737 { "cc430f5125",2,8 },
738 { "cc430f5133",2,8 },
739 { "cc430f5135",2,8 },
740 { "cc430f5137",2,8 },
741 { "cc430f5143",2,8 },
742 { "cc430f5145",2,8 },
743 { "cc430f5147",2,8 },
744 { "cc430f6125",2,8 },
745 { "cc430f6126",2,8 },
746 { "cc430f6127",2,8 },
747 { "cc430f6135",2,8 },
748 { "cc430f6137",2,8 },
749 { "cc430f6143",2,8 },
750 { "cc430f6145",2,8 },
751 { "cc430f6147",2,8 },
752 { "msp430afe221",0,2 },
753 { "msp430afe222",0,2 },
754 { "msp430afe223",0,2 },
755 { "msp430afe231",0,2 },
756 { "msp430afe232",0,2 },
757 { "msp430afe233",0,2 },
758 { "msp430afe251",0,2 },
759 { "msp430afe252",0,2 },
760 { "msp430afe253",0,2 },
761 { "msp430bt5190",2,8 },
762 { "msp430c091",0,0 },
763 { "msp430c092",0,0 },
764 { "msp430c111",0,0 },
765 { "msp430c1111",0,0 },
766 { "msp430c112",0,0 },
767 { "msp430c1121",0,0 },
768 { "msp430c1331",0,0 },
769 { "msp430c1351",0,0 },
770 { "msp430c311s",0,0 },
771 { "msp430c312",0,0 },
772 { "msp430c313",0,0 },
773 { "msp430c314",0,0 },
774 { "msp430c315",0,0 },
775 { "msp430c323",0,0 },
776 { "msp430c325",0,0 },
777 { "msp430c336",0,1 },
778 { "msp430c337",0,1 },
779 { "msp430c412",0,0 },
780 { "msp430c413",0,0 },
781 { "msp430cg4616",1,1 },
782 { "msp430cg4617",1,1 },
783 { "msp430cg4618",1,1 },
784 { "msp430cg4619",1,1 },
785 { "msp430e112",0,0 },
786 { "msp430e313",0,0 },
787 { "msp430e315",0,0 },
788 { "msp430e325",0,0 },
789 { "msp430e337",0,1 },
790 { "msp430f110",0,0 },
791 { "msp430f1101",0,0 },
792 { "msp430f1101a",0,0 },
793 { "msp430f1111",0,0 },
794 { "msp430f1111a",0,0 },
795 { "msp430f112",0,0 },
796 { "msp430f1121",0,0 },
797 { "msp430f1121a",0,0 },
798 { "msp430f1122",0,0 },
799 { "msp430f1132",0,0 },
800 { "msp430f122",0,0 },
801 { "msp430f1222",0,0 },
802 { "msp430f123",0,0 },
803 { "msp430f1232",0,0 },
804 { "msp430f133",0,0 },
805 { "msp430f135",0,0 },
806 { "msp430f147",0,1 },
807 { "msp430f1471",0,1 },
808 { "msp430f148",0,1 },
809 { "msp430f1481",0,1 },
810 { "msp430f149",0,1 },
811 { "msp430f1491",0,1 },
812 { "msp430f155",0,0 },
813 { "msp430f156",0,0 },
814 { "msp430f157",0,0 },
815 { "msp430f1610",0,1 },
816 { "msp430f1611",0,1 },
817 { "msp430f1612",0,1 },
818 { "msp430f167",0,1 },
819 { "msp430f168",0,1 },
820 { "msp430f169",0,1 },
821 { "msp430f2001",0,0 },
822 { "msp430f2002",0,0 },
823 { "msp430f2003",0,0 },
824 { "msp430f2011",0,0 },
825 { "msp430f2012",0,0 },
826 { "msp430f2013",0,0 },
827 { "msp430f2101",0,0 },
828 { "msp430f2111",0,0 },
829 { "msp430f2112",0,0 },
830 { "msp430f2121",0,0 },
831 { "msp430f2122",0,0 },
832 { "msp430f2131",0,0 },
833 { "msp430f2132",0,0 },
834 { "msp430f2232",0,0 },
835 { "msp430f2234",0,0 },
836 { "msp430f2252",0,0 },
837 { "msp430f2254",0,0 },
838 { "msp430f2272",0,0 },
839 { "msp430f2274",0,0 },
840 { "msp430f233",0,2 },
841 { "msp430f2330",0,2 },
842 { "msp430f235",0,2 },
843 { "msp430f2350",0,2 },
844 { "msp430f2370",0,2 },
845 { "msp430f2410",0,2 },
846 { "msp430f2416",1,2 },
847 { "msp430f2417",1,2 },
848 { "msp430f2418",1,2 },
849 { "msp430f2419",1,2 },
850 { "msp430f247",0,2 },
851 { "msp430f2471",0,2 },
852 { "msp430f248",0,2 },
853 { "msp430f2481",0,2 },
854 { "msp430f249",0,2 },
855 { "msp430f2491",0,2 },
856 { "msp430f2616",1,2 },
857 { "msp430f2617",1,2 },
858 { "msp430f2618",1,2 },
859 { "msp430f2619",1,2 },
860 { "msp430f412",0,0 },
861 { "msp430f413",0,0 },
862 { "msp430f4132",0,0 },
863 { "msp430f415",0,0 },
864 { "msp430f4152",0,0 },
865 { "msp430f417",0,0 },
866 { "msp430f423",0,1 },
867 { "msp430f423a",0,1 },
868 { "msp430f425",0,1 },
869 { "msp430f4250",0,0 },
870 { "msp430f425a",0,1 },
871 { "msp430f4260",0,0 },
872 { "msp430f427",0,1 },
873 { "msp430f4270",0,0 },
874 { "msp430f427a",0,1 },
875 { "msp430f435",0,0 },
876 { "msp430f4351",0,0 },
877 { "msp430f436",0,0 },
878 { "msp430f4361",0,0 },
879 { "msp430f437",0,0 },
880 { "msp430f4371",0,0 },
881 { "msp430f438",0,0 },
882 { "msp430f439",0,0 },
883 { "msp430f447",0,1 },
884 { "msp430f448",0,1 },
885 { "msp430f4481",0,1 },
886 { "msp430f449",0,1 },
887 { "msp430f4491",0,1 },
888 { "msp430f4616",1,1 },
889 { "msp430f46161",1,1 },
890 { "msp430f4617",1,1 },
891 { "msp430f46171",1,1 },
892 { "msp430f4618",1,1 },
893 { "msp430f46181",1,1 },
894 { "msp430f4619",1,1 },
895 { "msp430f46191",1,1 },
896 { "msp430f47126",1,4 },
897 { "msp430f47127",1,4 },
898 { "msp430f47163",1,4 },
899 { "msp430f47166",1,4 },
900 { "msp430f47167",1,4 },
901 { "msp430f47173",1,4 },
902 { "msp430f47176",1,4 },
903 { "msp430f47177",1,4 },
904 { "msp430f47183",1,4 },
905 { "msp430f47186",1,4 },
906 { "msp430f47187",1,4 },
907 { "msp430f47193",1,4 },
908 { "msp430f47196",1,4 },
909 { "msp430f47197",1,4 },
910 { "msp430f477",0,0 },
911 { "msp430f478",0,0 },
912 { "msp430f4783",0,4 },
913 { "msp430f4784",0,4 },
914 { "msp430f479",0,0 },
915 { "msp430f4793",0,4 },
916 { "msp430f4794",0,4 },
917 { "msp430f5131",2,8 },
918 { "msp430f5132",2,8 },
919 { "msp430f5151",2,8 },
920 { "msp430f5152",2,8 },
921 { "msp430f5171",2,8 },
922 { "msp430f5172",2,8 },
923 { "msp430f5212",2,8 },
924 { "msp430f5213",2,8 },
925 { "msp430f5214",2,8 },
926 { "msp430f5217",2,8 },
927 { "msp430f5218",2,8 },
928 { "msp430f5219",2,8 },
929 { "msp430f5222",2,8 },
930 { "msp430f5223",2,8 },
931 { "msp430f5224",2,8 },
932 { "msp430f5227",2,8 },
933 { "msp430f5228",2,8 },
934 { "msp430f5229",2,8 },
935 { "msp430f5232",2,8 },
936 { "msp430f5234",2,8 },
937 { "msp430f5237",2,8 },
938 { "msp430f5239",2,8 },
939 { "msp430f5242",2,8 },
940 { "msp430f5244",2,8 },
941 { "msp430f5247",2,8 },
942 { "msp430f5249",2,8 },
943 { "msp430f5252",2,8 },
944 { "msp430f5253",2,8 },
945 { "msp430f5254",2,8 },
946 { "msp430f5255",2,8 },
947 { "msp430f5256",2,8 },
948 { "msp430f5257",2,8 },
949 { "msp430f5258",2,8 },
950 { "msp430f5259",2,8 },
951 { "msp430f5304",2,8 },
952 { "msp430f5308",2,8 },
953 { "msp430f5309",2,8 },
954 { "msp430f5310",2,8 },
955 { "msp430f5324",2,8 },
956 { "msp430f5325",2,8 },
957 { "msp430f5326",2,8 },
958 { "msp430f5327",2,8 },
959 { "msp430f5328",2,8 },
960 { "msp430f5329",2,8 },
961 { "msp430f5333",2,8 },
962 { "msp430f5335",2,8 },
963 { "msp430f5336",2,8 },
964 { "msp430f5338",2,8 },
965 { "msp430f5340",2,8 },
966 { "msp430f5341",2,8 },
967 { "msp430f5342",2,8 },
968 { "msp430f5358",2,8 },
969 { "msp430f5359",2,8 },
970 { "msp430f5418",2,8 },
971 { "msp430f5418a",2,8 },
972 { "msp430f5419",2,8 },
973 { "msp430f5419a",2,8 },
974 { "msp430f5435",2,8 },
975 { "msp430f5435a",2,8 },
976 { "msp430f5436",2,8 },
977 { "msp430f5436a",2,8 },
978 { "msp430f5437",2,8 },
979 { "msp430f5437a",2,8 },
980 { "msp430f5438",2,8 },
981 { "msp430f5438a",2,8 },
982 { "msp430f5500",2,8 },
983 { "msp430f5501",2,8 },
984 { "msp430f5502",2,8 },
985 { "msp430f5503",2,8 },
986 { "msp430f5504",2,8 },
987 { "msp430f5505",2,8 },
988 { "msp430f5506",2,8 },
989 { "msp430f5507",2,8 },
990 { "msp430f5508",2,8 },
991 { "msp430f5509",2,8 },
992 { "msp430f5510",2,8 },
993 { "msp430f5513",2,8 },
994 { "msp430f5514",2,8 },
995 { "msp430f5515",2,8 },
996 { "msp430f5517",2,8 },
997 { "msp430f5519",2,8 },
998 { "msp430f5521",2,8 },
999 { "msp430f5522",2,8 },
1000 { "msp430f5524",2,8 },
1001 { "msp430f5525",2,8 },
1002 { "msp430f5526",2,8 },
1003 { "msp430f5527",2,8 },
1004 { "msp430f5528",2,8 },
1005 { "msp430f5529",2,8 },
1006 { "msp430f5630",2,8 },
1007 { "msp430f5631",2,8 },
1008 { "msp430f5632",2,8 },
1009 { "msp430f5633",2,8 },
1010 { "msp430f5634",2,8 },
1011 { "msp430f5635",2,8 },
1012 { "msp430f5636",2,8 },
1013 { "msp430f5637",2,8 },
1014 { "msp430f5638",2,8 },
1015 { "msp430f5658",2,8 },
1016 { "msp430f5659",2,8 },
1017 { "msp430f5xx_6xxgeneric",2,8 },
1018 { "msp430f6433",2,8 },
1019 { "msp430f6435",2,8 },
1020 { "msp430f6436",2,8 },
1021 { "msp430f6438",2,8 },
1022 { "msp430f6458",2,8 },
1023 { "msp430f6459",2,8 },
1024 { "msp430f6630",2,8 },
1025 { "msp430f6631",2,8 },
1026 { "msp430f6632",2,8 },
1027 { "msp430f6633",2,8 },
1028 { "msp430f6634",2,8 },
1029 { "msp430f6635",2,8 },
1030 { "msp430f6636",2,8 },
1031 { "msp430f6637",2,8 },
1032 { "msp430f6638",2,8 },
1033 { "msp430f6658",2,8 },
1034 { "msp430f6659",2,8 },
1035 { "msp430f6720",2,8 },
1036 { "msp430f6720a",2,8 },
1037 { "msp430f6721",2,8 },
1038 { "msp430f6721a",2,8 },
1039 { "msp430f6723",2,8 },
1040 { "msp430f6723a",2,8 },
1041 { "msp430f6724",2,8 },
1042 { "msp430f6724a",2,8 },
1043 { "msp430f6725",2,8 },
1044 { "msp430f6725a",2,8 },
1045 { "msp430f6726",2,8 },
1046 { "msp430f6726a",2,8 },
1047 { "msp430f6730",2,8 },
1048 { "msp430f6730a",2,8 },
1049 { "msp430f6731",2,8 },
1050 { "msp430f6731a",2,8 },
1051 { "msp430f6733",2,8 },
1052 { "msp430f6733a",2,8 },
1053 { "msp430f6734",2,8 },
1054 { "msp430f6734a",2,8 },
1055 { "msp430f6735",2,8 },
1056 { "msp430f6735a",2,8 },
1057 { "msp430f6736",2,8 },
1058 { "msp430f6736a",2,8 },
1059 { "msp430f6745",2,8 },
1060 { "msp430f67451",2,8 },
1061 { "msp430f67451a",2,8 },
1062 { "msp430f6745a",2,8 },
1063 { "msp430f6746",2,8 },
1064 { "msp430f67461",2,8 },
1065 { "msp430f67461a",2,8 },
1066 { "msp430f6746a",2,8 },
1067 { "msp430f6747",2,8 },
1068 { "msp430f67471",2,8 },
1069 { "msp430f67471a",2,8 },
1070 { "msp430f6747a",2,8 },
1071 { "msp430f6748",2,8 },
1072 { "msp430f67481",2,8 },
1073 { "msp430f67481a",2,8 },
1074 { "msp430f6748a",2,8 },
1075 { "msp430f6749",2,8 },
1076 { "msp430f67491",2,8 },
1077 { "msp430f67491a",2,8 },
1078 { "msp430f6749a",2,8 },
1079 { "msp430f67621",2,8 },
1080 { "msp430f67621a",2,8 },
1081 { "msp430f67641",2,8 },
1082 { "msp430f67641a",2,8 },
1083 { "msp430f6765",2,8 },
1084 { "msp430f67651",2,8 },
1085 { "msp430f67651a",2,8 },
1086 { "msp430f6765a",2,8 },
1087 { "msp430f6766",2,8 },
1088 { "msp430f67661",2,8 },
1089 { "msp430f67661a",2,8 },
1090 { "msp430f6766a",2,8 },
1091 { "msp430f6767",2,8 },
1092 { "msp430f67671",2,8 },
1093 { "msp430f67671a",2,8 },
1094 { "msp430f6767a",2,8 },
1095 { "msp430f6768",2,8 },
1096 { "msp430f67681",2,8 },
1097 { "msp430f67681a",2,8 },
1098 { "msp430f6768a",2,8 },
1099 { "msp430f6769",2,8 },
1100 { "msp430f67691",2,8 },
1101 { "msp430f67691a",2,8 },
1102 { "msp430f6769a",2,8 },
1103 { "msp430f6775",2,8 },
1104 { "msp430f67751",2,8 },
1105 { "msp430f67751a",2,8 },
1106 { "msp430f6775a",2,8 },
1107 { "msp430f6776",2,8 },
1108 { "msp430f67761",2,8 },
1109 { "msp430f67761a",2,8 },
1110 { "msp430f6776a",2,8 },
1111 { "msp430f6777",2,8 },
1112 { "msp430f67771",2,8 },
1113 { "msp430f67771a",2,8 },
1114 { "msp430f6777a",2,8 },
1115 { "msp430f6778",2,8 },
1116 { "msp430f67781",2,8 },
1117 { "msp430f67781a",2,8 },
1118 { "msp430f6778a",2,8 },
1119 { "msp430f6779",2,8 },
1120 { "msp430f67791",2,8 },
1121 { "msp430f67791a",2,8 },
1122 { "msp430f6779a",2,8 },
1123 { "msp430fe423",0,0 },
1124 { "msp430fe4232",0,0 },
1125 { "msp430fe423a",0,0 },
1126 { "msp430fe4242",0,0 },
1127 { "msp430fe425",0,0 },
1128 { "msp430fe4252",0,0 },
1129 { "msp430fe425a",0,0 },
1130 { "msp430fe427",0,0 },
1131 { "msp430fe4272",0,0 },
1132 { "msp430fe427a",0,0 },
1133 { "msp430fg4250",0,0 },
1134 { "msp430fg4260",0,0 },
1135 { "msp430fg4270",0,0 },
1136 { "msp430fg437",0,0 },
1137 { "msp430fg438",0,0 },
1138 { "msp430fg439",0,0 },
1139 { "msp430fg4616",1,1 },
1140 { "msp430fg4617",1,1 },
1141 { "msp430fg4618",1,1 },
1142 { "msp430fg4619",1,1 },
1143 { "msp430fg477",0,0 },
1144 { "msp430fg478",0,0 },
1145 { "msp430fg479",0,0 },
1146 { "msp430fg6425",2,8 },
1147 { "msp430fg6426",2,8 },
1148 { "msp430fg6625",2,8 },
1149 { "msp430fg6626",2,8 },
1150 { "msp430fr2032",2,0 },
1151 { "msp430fr2033",2,0 },
1152 { "msp430fr2110",2,0 },
1153 { "msp430fr2111",2,0 },
1154 { "msp430fr2310",2,0 },
1155 { "msp430fr2311",2,0 },
1156 { "msp430fr2433",2,8 },
1157 { "msp430fr2532",2,8 },
1158 { "msp430fr2533",2,8 },
1159 { "msp430fr2632",2,8 },
1160 { "msp430fr2633",2,8 },
1161 { "msp430fr2xx_4xxgeneric",2,8 },
1162 { "msp430fr4131",2,0 },
1163 { "msp430fr4132",2,0 },
1164 { "msp430fr4133",2,0 },
1165 { "msp430fr5720",2,8 },
1166 { "msp430fr5721",2,8 },
1167 { "msp430fr5722",2,8 },
1168 { "msp430fr5723",2,8 },
1169 { "msp430fr5724",2,8 },
1170 { "msp430fr5725",2,8 },
1171 { "msp430fr5726",2,8 },
1172 { "msp430fr5727",2,8 },
1173 { "msp430fr5728",2,8 },
1174 { "msp430fr5729",2,8 },
1175 { "msp430fr5730",2,8 },
1176 { "msp430fr5731",2,8 },
1177 { "msp430fr5732",2,8 },
1178 { "msp430fr5733",2,8 },
1179 { "msp430fr5734",2,8 },
1180 { "msp430fr5735",2,8 },
1181 { "msp430fr5736",2,8 },
1182 { "msp430fr5737",2,8 },
1183 { "msp430fr5738",2,8 },
1184 { "msp430fr5739",2,8 },
1185 { "msp430fr57xxgeneric",2,8 },
1186 { "msp430fr5847",2,8 },
1187 { "msp430fr58471",2,8 },
1188 { "msp430fr5848",2,8 },
1189 { "msp430fr5849",2,8 },
1190 { "msp430fr5857",2,8 },
1191 { "msp430fr5858",2,8 },
1192 { "msp430fr5859",2,8 },
1193 { "msp430fr5867",2,8 },
1194 { "msp430fr58671",2,8 },
1195 { "msp430fr5868",2,8 },
1196 { "msp430fr5869",2,8 },
1197 { "msp430fr5870",2,8 },
1198 { "msp430fr5872",2,8 },
1199 { "msp430fr58721",2,8 },
1200 { "msp430fr5887",2,8 },
1201 { "msp430fr5888",2,8 },
1202 { "msp430fr5889",2,8 },
1203 { "msp430fr58891",2,8 },
1204 { "msp430fr5922",2,8 },
1205 { "msp430fr59221",2,8 },
1206 { "msp430fr5947",2,8 },
1207 { "msp430fr59471",2,8 },
1208 { "msp430fr5948",2,8 },
1209 { "msp430fr5949",2,8 },
1210 { "msp430fr5957",2,8 },
1211 { "msp430fr5958",2,8 },
1212 { "msp430fr5959",2,8 },
1213 { "msp430fr5962",2,8 },
1214 { "msp430fr5964",2,8 },
1215 { "msp430fr5967",2,8 },
1216 { "msp430fr5968",2,8 },
1217 { "msp430fr5969",2,8 },
1218 { "msp430fr59691",2,8 },
1219 { "msp430fr5970",2,8 },
1220 { "msp430fr5972",2,8 },
1221 { "msp430fr59721",2,8 },
1222 { "msp430fr5986",2,8 },
1223 { "msp430fr5987",2,8 },
1224 { "msp430fr5988",2,8 },
1225 { "msp430fr5989",2,8 },
1226 { "msp430fr59891",2,8 },
1227 { "msp430fr5992",2,8 },
1228 { "msp430fr5994",2,8 },
1229 { "msp430fr59941",2,8 },
1230 { "msp430fr5xx_6xxgeneric",2,8 },
1231 { "msp430fr6820",2,8 },
1232 { "msp430fr6822",2,8 },
1233 { "msp430fr68221",2,8 },
1234 { "msp430fr6870",2,8 },
1235 { "msp430fr6872",2,8 },
1236 { "msp430fr68721",2,8 },
1237 { "msp430fr6877",2,8 },
1238 { "msp430fr6879",2,8 },
1239 { "msp430fr68791",2,8 },
1240 { "msp430fr6887",2,8 },
1241 { "msp430fr6888",2,8 },
1242 { "msp430fr6889",2,8 },
1243 { "msp430fr68891",2,8 },
1244 { "msp430fr6920",2,8 },
1245 { "msp430fr6922",2,8 },
1246 { "msp430fr69221",2,8 },
1247 { "msp430fr6927",2,8 },
1248 { "msp430fr69271",2,8 },
1249 { "msp430fr6928",2,8 },
1250 { "msp430fr6970",2,8 },
1251 { "msp430fr6972",2,8 },
1252 { "msp430fr69721",2,8 },
1253 { "msp430fr6977",2,8 },
1254 { "msp430fr6979",2,8 },
1255 { "msp430fr69791",2,8 },
1256 { "msp430fr6987",2,8 },
1257 { "msp430fr6988",2,8 },
1258 { "msp430fr6989",2,8 },
1259 { "msp430fr69891",2,8 },
1260 { "msp430fw423",0,0 },
1261 { "msp430fw425",0,0 },
1262 { "msp430fw427",0,0 },
1263 { "msp430fw428",0,0 },
1264 { "msp430fw429",0,0 },
1265 { "msp430g2001",0,0 },
1266 { "msp430g2101",0,0 },
1267 { "msp430g2102",0,0 },
1268 { "msp430g2111",0,0 },
1269 { "msp430g2112",0,0 },
1270 { "msp430g2113",0,0 },
1271 { "msp430g2121",0,0 },
1272 { "msp430g2131",0,0 },
1273 { "msp430g2132",0,0 },
1274 { "msp430g2152",0,0 },
1275 { "msp430g2153",0,0 },
1276 { "msp430g2201",0,0 },
1277 { "msp430g2202",0,0 },
1278 { "msp430g2203",0,0 },
1279 { "msp430g2210",0,0 },
1280 { "msp430g2211",0,0 },
1281 { "msp430g2212",0,0 },
1282 { "msp430g2213",0,0 },
1283 { "msp430g2221",0,0 },
1284 { "msp430g2230",0,0 },
1285 { "msp430g2231",0,0 },
1286 { "msp430g2232",0,0 },
1287 { "msp430g2233",0,0 },
1288 { "msp430g2252",0,0 },
1289 { "msp430g2253",0,0 },
1290 { "msp430g2302",0,0 },
1291 { "msp430g2303",0,0 },
1292 { "msp430g2312",0,0 },
1293 { "msp430g2313",0,0 },
1294 { "msp430g2332",0,0 },
1295 { "msp430g2333",0,0 },
1296 { "msp430g2352",0,0 },
1297 { "msp430g2353",0,0 },
1298 { "msp430g2402",0,0 },
1299 { "msp430g2403",0,0 },
1300 { "msp430g2412",0,0 },
1301 { "msp430g2413",0,0 },
1302 { "msp430g2432",0,0 },
1303 { "msp430g2433",0,0 },
1304 { "msp430g2444",0,0 },
1305 { "msp430g2452",0,0 },
1306 { "msp430g2453",0,0 },
1307 { "msp430g2513",0,0 },
1308 { "msp430g2533",0,0 },
1309 { "msp430g2544",0,0 },
1310 { "msp430g2553",0,0 },
1311 { "msp430g2744",0,0 },
1312 { "msp430g2755",0,0 },
1313 { "msp430g2855",0,0 },
1314 { "msp430g2955",0,0 },
1315 { "msp430i2020",0,2 },
1316 { "msp430i2021",0,2 },
1317 { "msp430i2030",0,2 },
1318 { "msp430i2031",0,2 },
1319 { "msp430i2040",0,2 },
1320 { "msp430i2041",0,2 },
1321 { "msp430i2xxgeneric",0,2 },
1322 { "msp430l092",0,0 },
1323 { "msp430p112",0,0 },
1324 { "msp430p313",0,0 },
1325 { "msp430p315",0,0 },
1326 { "msp430p315s",0,0 },
1327 { "msp430p325",0,0 },
1328 { "msp430p337",0,1 },
1329 { "msp430sl5438a",2,8 },
1330 { "msp430tch5e",0,0 },
1331 { "msp430xgeneric",2,8 },
1332 { "rf430f5144",2,8 },
1333 { "rf430f5155",2,8 },
1334 { "rf430f5175",2,8 },
1335 { "rf430frl152h",0,0 },
1336 { "rf430frl152h_rom",0,0 },
1337 { "rf430frl153h",0,0 },
1338 { "rf430frl153h_rom",0,0 },
1339 { "rf430frl154h",0,0 },
1340 { "rf430frl154h_rom",0,0 }
1344 md_parse_option (int c
, const char * arg
)
1348 case OPTION_SILICON_ERRATA
:
1349 case OPTION_SILICON_ERRATA_WARN
:
1355 unsigned int length
;
1356 unsigned int bitfield
;
1359 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1360 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1361 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1362 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1363 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1364 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1369 for (i
= ARRAY_SIZE (erratas
); i
--;)
1370 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1372 if (c
== OPTION_SILICON_ERRATA
)
1373 silicon_errata_fix
|= erratas
[i
].bitfield
;
1375 silicon_errata_warn
|= erratas
[i
].bitfield
;
1376 arg
+= erratas
[i
].length
;
1381 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1387 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1397 as_fatal (_("MCU option requires a name\n"));
1399 if (strcasecmp ("msp430", arg
) == 0)
1400 selected_isa
= MSP_ISA_430
;
1401 else if (strcasecmp ("msp430xv2", arg
) == 0)
1402 selected_isa
= MSP_ISA_430Xv2
;
1403 else if (strcasecmp ("msp430x", arg
) == 0)
1404 selected_isa
= MSP_ISA_430X
;
1409 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1410 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1412 switch (msp430_mcu_data
[i
].revision
)
1414 case 0: selected_isa
= MSP_ISA_430
; break;
1415 case 1: selected_isa
= MSP_ISA_430X
; break;
1416 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1421 /* It is not an error if we do not match the MCU name. */
1425 if (strcmp (arg
, "430") == 0
1426 || strcasecmp (arg
, "msp430") == 0)
1427 selected_isa
= MSP_ISA_430
;
1428 else if (strcasecmp (arg
, "430x") == 0
1429 || strcasecmp (arg
, "msp430x") == 0)
1430 selected_isa
= MSP_ISA_430X
;
1431 else if (strcasecmp (arg
, "430xv2") == 0
1432 || strcasecmp (arg
, "msp430xv2") == 0)
1433 selected_isa
= MSP_ISA_430Xv2
;
1435 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1439 msp430_enable_relax
= 1;
1442 case OPTION_POLYMORPHS
:
1443 msp430_enable_polys
= 1;
1450 case OPTION_NO_INTR_NOPS
:
1451 gen_interrupt_nops
= false;
1453 case OPTION_INTR_NOPS
:
1454 gen_interrupt_nops
= true;
1457 case OPTION_WARN_INTR_NOPS
:
1458 warn_interrupt_nops
= true;
1460 case OPTION_NO_WARN_INTR_NOPS
:
1461 warn_interrupt_nops
= false;
1464 case OPTION_UNKNOWN_INTR_NOPS
:
1465 do_unknown_interrupt_nops
= true;
1467 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1468 do_unknown_interrupt_nops
= false;
1471 case OPTION_MOVE_DATA
:
1472 /* Silently ignored. */
1475 case OPTION_DATA_REGION
:
1476 if (strcmp (arg
, "upper") == 0
1477 || strcmp (arg
, "either") == 0)
1478 upper_data_region_in_use
= true;
1479 if (strcmp (arg
, "upper") == 0
1480 || strcmp (arg
, "either") == 0
1481 /* With data-region=none, the compiler has generated code assuming
1482 data could be in the upper region, but nothing has been explicitly
1484 || strcmp (arg
, "none") == 0)
1485 lower_data_region_only
= false;
1492 /* The intention here is to have the mere presence of these sections
1493 cause the object to have a reference to a well-known symbol. This
1494 reference pulls in the bits of the runtime (crt0) that initialize
1495 these sections. Thus, for example, the startup code to call
1496 memset() to initialize .bss will only be linked in when there is a
1497 non-empty .bss section. Otherwise, the call would exist but have a
1498 zero length parameter, which is a waste of memory and cycles.
1500 The code which initializes these sections should have a global
1501 label for these symbols, and should be marked with KEEP() in the
1505 msp430_make_init_symbols (const char * name
)
1507 if (startswith (name
, ".bss")
1508 || startswith (name
, ".lower.bss")
1509 || startswith (name
, ".either.bss")
1510 || startswith (name
, ".gnu.linkonce.b."))
1511 (void) symbol_find_or_make ("__crt0_init_bss");
1513 if (startswith (name
, ".data")
1514 || startswith (name
, ".lower.data")
1515 || startswith (name
, ".either.data")
1516 || startswith (name
, ".gnu.linkonce.d."))
1517 (void) symbol_find_or_make ("__crt0_movedata");
1518 /* Note - data assigned to the .either.data section may end up being
1519 placed in the .upper.data section if the .lower.data section is
1520 full. Hence the need to define the crt0 symbol.
1521 The linker may create upper or either data sections, even when none exist
1522 at the moment, so use the value of the data-region flag to determine if
1523 the symbol is needed. */
1524 if (startswith (name
, ".either.data")
1525 || startswith (name
, ".upper.data")
1526 || upper_data_region_in_use
)
1527 (void) symbol_find_or_make ("__crt0_move_highdata");
1529 /* See note about .either.data above. */
1530 if (startswith (name
, ".upper.bss")
1531 || startswith (name
, ".either.bss")
1532 || upper_data_region_in_use
)
1533 (void) symbol_find_or_make ("__crt0_init_highbss");
1535 /* The following symbols are for the crt0 functions that run through
1536 the different .*_array sections and call the functions placed there.
1537 - init_array stores global static C++ constructors to run before main.
1538 - preinit_array is not expected to ever be used for MSP430.
1539 GCC only places initialization functions for runtime "sanitizers"
1540 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1541 - fini_array stores global static C++ destructors to run after calling
1542 exit() or returning from main.
1543 __crt0_run_array is required to actually call the functions in the above
1545 if (startswith (name
, ".init_array"))
1547 (void) symbol_find_or_make ("__crt0_run_init_array");
1548 (void) symbol_find_or_make ("__crt0_run_array");
1550 else if (startswith (name
, ".preinit_array"))
1552 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1553 (void) symbol_find_or_make ("__crt0_run_array");
1555 else if (startswith (name
, ".fini_array"))
1557 (void) symbol_find_or_make ("__crt0_run_fini_array");
1558 (void) symbol_find_or_make ("__crt0_run_array");
1563 msp430_section (int arg
)
1565 char * saved_ilp
= input_line_pointer
;
1566 const char * name
= obj_elf_section_name ();
1568 msp430_make_init_symbols (name
);
1570 input_line_pointer
= saved_ilp
;
1571 obj_elf_section (arg
);
1575 msp430_frob_section (asection
*sec
)
1577 const char *name
= sec
->name
;
1582 msp430_make_init_symbols (name
);
1586 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1588 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1591 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1592 (void) symbol_find_or_make ("__crt0_init_bss");
1596 msp430_comm (int needs_align
)
1598 s_comm_internal (needs_align
, elf_common_parse
);
1599 (void) symbol_find_or_make ("__crt0_init_bss");
1603 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1605 char sym_name
[1024];
1606 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1608 (void) symbol_find_or_make (sym_name
);
1611 /* Handle a .mspabi_attribute or .gnu_attribute directive.
1612 attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute.
1613 This is only used for validating the attributes in the assembly file against
1614 the options gas has been invoked with. If the attributes and options are
1615 compatible then we add the attributes to the assembly file in
1618 msp430_object_attribute (int attr_type
)
1620 char tag_name_s
[32];
1621 char tag_value_s
[32];
1622 int tag_name
, tag_value
;
1623 /* First operand is the tag name, second is the tag value e.g.
1624 ".mspabi_attribute 4, 2". */
1625 input_line_pointer
= extract_operand (input_line_pointer
, tag_name_s
, 32);
1626 input_line_pointer
= extract_operand (input_line_pointer
, tag_value_s
, 32);
1627 tag_name
= atoi (tag_name_s
);
1628 tag_value
= atoi (tag_value_s
);
1629 /* If the attribute directive is present, the tag_value should never be set
1631 if (tag_name
== 0 || tag_value
== 0)
1632 as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"),
1633 tag_name_s
, tag_value_s
, (attr_type
? ".gnu_attribute"
1634 : ".mspabi_attribute"));
1635 else if (attr_type
== 0)
1636 /* Handle .mspabi_attribute. */
1639 case OFBA_MSPABI_Tag_ISA
:
1642 case OFBA_MSPABI_Val_ISA_MSP430
:
1643 if (target_is_430x ())
1644 as_bad (_("file was compiled for the 430 ISA but the %s ISA is "
1645 "selected"), (target_is_430xv2 () ? "430X" : "430Xv2"));
1647 case OFBA_MSPABI_Val_ISA_MSP430X
:
1648 if (!target_is_430x ())
1649 as_bad (_("file was compiled for the 430X ISA but the 430 ISA is "
1653 as_bad (_("unknown MSPABI build attribute value '%d' for "
1654 "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"),
1655 tag_value
, OFBA_MSPABI_Tag_ISA
);
1659 case OFBA_MSPABI_Tag_Code_Model
:
1661 case OFBA_MSPABI_Tag_Data_Model
:
1662 /* FIXME: Might we want to set the memory model to large if the assembly
1663 file has the large model attribute, but -ml has not been passed? */
1666 case OFBA_MSPABI_Val_Code_Model_SMALL
:
1668 as_bad (_("file was compiled for the small memory model, but the "
1669 "large memory model is selected"));
1671 case OFBA_MSPABI_Val_Code_Model_LARGE
:
1673 as_bad (_("file was compiled for the large memory model, "
1674 "but the small memory model is selected"));
1677 as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) "
1678 "in .mspabi_attribute directive"), tag_value
,
1679 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1680 ? "OFBA_MSPABI_Tag_Code_Model"
1681 : "OFBA_MSPABI_Tag_Data_Model"),
1682 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1683 ? OFBA_MSPABI_Tag_Code_Model
1684 : OFBA_MSPABI_Tag_Data_Model
));
1689 as_bad (_("unknown MSPABI build attribute tag '%d' in "
1690 ".mspabi_attribute directive"), tag_name
);
1693 else if (attr_type
== 1)
1694 /* Handle .gnu_attribute. */
1697 case Tag_GNU_MSP430_Data_Region
:
1698 /* This attribute is only applicable in the large memory model. */
1703 case Val_GNU_MSP430_Data_Region_Lower
:
1704 if (!lower_data_region_only
)
1705 as_bad (_("file was compiled assuming all data will be in the "
1706 "lower memory region, but the upper region is in use"));
1708 case Val_GNU_MSP430_Data_Region_Any
:
1709 if (lower_data_region_only
)
1710 as_bad (_("file was compiled assuming data could be in the upper "
1711 "memory region, but the lower data region is "
1712 "exclusively in use"));
1715 as_bad (_("unknown GNU build attribute value '%d' for "
1716 "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute "
1717 "directive"), tag_value
, Tag_GNU_MSP430_Data_Region
);
1721 as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"),
1725 const pseudo_typeS md_pseudo_table
[] =
1727 {"arch", msp430_set_arch
, OPTION_MMCU
},
1728 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1729 {"profiler", msp430_profiler
, 0},
1730 {"section", msp430_section
, 0},
1731 {"section.s", msp430_section
, 0},
1732 {"sect", msp430_section
, 0},
1733 {"sect.s", msp430_section
, 0},
1734 {"pushsection", msp430_section
, 1},
1735 {"refsym", msp430_refsym
, 0},
1736 {"comm", msp430_comm
, 0},
1737 {"lcomm", msp430_lcomm
, 0},
1738 {"mspabi_attribute", msp430_object_attribute
, 0},
1739 {"gnu_attribute", msp430_object_attribute
, 1},
1743 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1745 struct option md_longopts
[] =
1747 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1748 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1749 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1750 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1751 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1752 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1753 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1754 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1755 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1756 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1757 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1758 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1759 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1760 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1761 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1762 {NULL
, no_argument
, NULL
, 0}
1765 size_t md_longopts_size
= sizeof (md_longopts
);
1768 md_show_usage (FILE * stream
)
1771 _("MSP430 options:\n"
1772 " -mmcu=<msp430-name> - select microcontroller type\n"
1773 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1775 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1776 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1777 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1779 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1780 " -mP - enable polymorph instructions\n"));
1782 _(" -ml - enable large code model\n"));
1784 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1786 _(" -mn - insert a NOP after changing interrupts\n"));
1788 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1790 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1792 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1793 " known how the state is changed, do not warn/insert NOPs\n"));
1795 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1796 " known how the state is changed, warn/insert NOPs (default)\n"
1797 " -mn and/or -my are required for this to have any effect\n"));
1799 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1804 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1810 extract_cmd (char * from
, char * to
, int limit
)
1814 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1816 *(to
+ size
) = *from
;
1827 md_atof (int type
, char * litP
, int * sizeP
)
1829 return ieee_md_atof (type
, litP
, sizeP
, false);
1835 struct msp430_opcode_s
* opcode
;
1836 msp430_hash
= str_htab_create ();
1838 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1839 str_hash_insert (msp430_hash
, opcode
->name
, opcode
, 0);
1841 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1842 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1844 /* Set linkrelax here to avoid fixups in most sections. */
1849 is_regname_end (char c
)
1851 return (c
== 0 || ! ISALNUM (c
));
1854 /* Returns the register number equivalent to the string T.
1855 Returns -1 if there is no such register.
1856 Skips a leading 'r' or 'R' character if there is one.
1857 Handles the register aliases PC and SP. */
1860 check_reg (char * t
)
1863 signed long int val
;
1865 if (t
== NULL
|| t
[0] == 0)
1868 if (*t
== 'r' || *t
== 'R')
1871 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1874 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1877 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1880 if (*t
== '0' && is_regname_end (t
[1]))
1883 val
= strtol (t
, & endt
, 0);
1885 if (val
< 1 || val
> 15)
1888 if (is_regname_end (*endt
))
1895 msp430_srcoperand (struct msp430_operand_s
* op
,
1899 bool allow_20bit_values
,
1900 bool constants_allowed
)
1905 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1911 /* Use all parts of the constant expression by default. */
1912 enum msp430_expp_e expp
= MSP_EXPP_ALL
;
1914 /* Check if there is:
1915 llo(x) - least significant 16 bits, x &= 0xffff
1916 lhi(x) - x = (x >> 16) & 0xffff,
1917 hlo(x) - x = (x >> 32) & 0xffff,
1918 hhi(x) - x = (x >> 48) & 0xffff
1919 The value _MUST_ be an immediate expression: #hlo(1231231231). */
1923 if (strncasecmp (h
, "#llo(", 5) == 0)
1927 expp
= MSP_EXPP_LLO
;
1929 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1933 expp
= MSP_EXPP_LHI
;
1935 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1939 expp
= MSP_EXPP_HLO
;
1941 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1945 expp
= MSP_EXPP_HHI
;
1947 else if (strncasecmp (h
, "#lo(", 4) == 0)
1953 else if (strncasecmp (h
, "#hi(", 4) == 0)
1960 op
->reg
= 0; /* Reg PC. */
1962 op
->ol
= 1; /* Immediate will follow an instruction. */
1963 __tl
= h
+ 1 + rval
;
1965 op
->vshift
= vshift
;
1968 end
= parse_exp (__tl
, &(op
->exp
));
1969 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1971 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1974 if (op
->exp
.X_op
== O_constant
)
1976 int x
= op
->exp
.X_add_number
;
1981 op
->exp
.X_add_number
= x
;
1983 else if (vshift
== 1)
1985 x
= (x
>> 16) & 0xffff;
1986 op
->exp
.X_add_number
= x
;
1989 else if (vshift
> 1)
1992 op
->exp
.X_add_number
= -1;
1994 op
->exp
.X_add_number
= 0; /* Nothing left. */
1995 x
= op
->exp
.X_add_number
;
1999 if (allow_20bit_values
)
2001 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
2003 as_bad (_("value 0x%x out of extended range."), x
);
2007 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
2009 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
2013 /* Now check constants. */
2014 /* Substitute register mode with a constant generator if applicable. */
2016 if (!allow_20bit_values
)
2017 x
= (short) x
; /* Extend sign. */
2019 if (! constants_allowed
)
2051 if (bin
== 0x1200 && ! target_is_430x ())
2053 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
2054 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2055 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
2056 /* No need to check silicon_errata_fixes - this fix is always implemented. */
2068 if (bin
== 0x1200 && ! target_is_430x ())
2070 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
2071 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2072 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
2083 else if (op
->exp
.X_op
== O_symbol
)
2086 as_bad (_("error: unsupported #foo() directive used on symbol"));
2089 else if (op
->exp
.X_op
== O_big
)
2095 op
->exp
.X_op
= O_constant
;
2096 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
2097 x
= op
->exp
.X_add_number
;
2103 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
2151 /* Redundant (yet) check. */
2152 else if (op
->exp
.X_op
== O_register
)
2154 (_("Registers cannot be used within immediate expression [%s]"), l
);
2156 as_bad (_("unknown operand %s"), l
);
2161 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2166 op
->reg
= 2; /* Reg 2 in absolute addr mode. */
2167 op
->am
= 1; /* Mode As == 01 bin. */
2168 op
->ol
= 1; /* Immediate value followed by instruction. */
2170 end
= parse_exp (__tl
, &(op
->exp
));
2171 if (end
!= NULL
&& *end
!= 0)
2173 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
2178 op
->expp
= MSP_EXPP_ALL
;
2179 if (op
->exp
.X_op
== O_constant
)
2181 int x
= op
->exp
.X_add_number
;
2183 if (allow_20bit_values
)
2185 if (x
> 0xfffff || x
< -(0x7ffff))
2187 as_bad (_("value 0x%x out of extended range."), x
);
2191 else if (x
> 65535 || x
< -32768)
2193 as_bad (_("value out of range: 0x%x"), x
);
2197 else if (op
->exp
.X_op
== O_symbol
)
2201 /* Redundant (yet) check. */
2202 if (op
->exp
.X_op
== O_register
)
2204 (_("Registers cannot be used within absolute expression [%s]"), l
);
2206 as_bad (_("unknown expression in operand %s"), l
);
2212 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2216 char *m
= strchr (l
, '+');
2220 as_bad (_("unknown addressing mode %s"), l
);
2226 if ((op
->reg
= check_reg (t
)) == -1)
2228 as_bad (_("Bad register name %s"), t
);
2236 /* PC cannot be used in indirect addressing. */
2237 if (target_is_430xv2 () && op
->reg
== 0)
2239 as_bad (_("cannot use indirect addressing with the PC"));
2246 /* Check if register indexed X(Rn). */
2249 char *h
= strrchr (l
, '(');
2250 char *m
= strrchr (l
, ')');
2259 as_bad (_("')' required"));
2267 /* Extract a register. */
2268 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2271 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2278 as_bad (_("r2 should not be used in indexed addressing mode"));
2282 /* Extract constant. */
2287 op
->expp
= MSP_EXPP_ALL
;
2288 end
= parse_exp (__tl
, &(op
->exp
));
2289 if (end
!= NULL
&& *end
!= 0)
2291 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2294 if (op
->exp
.X_op
== O_constant
)
2296 int x
= op
->exp
.X_add_number
;
2298 if (allow_20bit_values
)
2300 if (x
> 0xfffff || x
< - (0x7ffff))
2302 as_bad (_("value 0x%x out of extended range."), x
);
2306 else if (x
> 65535 || x
< -32768)
2308 as_bad (_("value out of range: 0x%x"), x
);
2320 if (op
->reg
== 1 && (x
& 1))
2322 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2323 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2324 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2325 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2328 else if (op
->exp
.X_op
== O_symbol
)
2332 /* Redundant (yet) check. */
2333 if (op
->exp
.X_op
== O_register
)
2335 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2337 as_bad (_("unknown expression in operand %s"), l
);
2345 /* Possibly register mode 'mov r1,r2'. */
2346 if ((op
->reg
= check_reg (l
)) != -1)
2354 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2356 op
->reg
= 0; /* PC relative... be careful. */
2357 /* An expression starting with a minus sign is a constant, not an address. */
2358 op
->am
= (*l
== '-' ? 3 : 1);
2361 op
->expp
= MSP_EXPP_ALL
;
2363 end
= parse_exp (__tl
, &(op
->exp
));
2364 if (end
!= NULL
&& * end
!= 0)
2366 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2374 msp430_dstoperand (struct msp430_operand_s
* op
,
2377 bool allow_20bit_values
,
2378 bool constants_allowed
)
2381 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2390 char *__tl
= (char *) "0";
2396 op
->expp
= MSP_EXPP_ALL
;
2397 (void) parse_exp (__tl
, &(op
->exp
));
2399 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2401 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2411 ("this addressing mode is not applicable for destination operand"));
2417 /* Attempt to encode a MOVA instruction with the given operands.
2418 Returns the length of the encoded instruction if successful
2419 or 0 upon failure. If the encoding fails, an error message
2420 will be returned if a pointer is provided. */
2423 try_encode_mova (bool imm_op
,
2425 struct msp430_operand_s
* op1
,
2426 struct msp430_operand_s
* op2
,
2427 const char ** error_message_return
)
2433 /* Only a restricted subset of the normal MSP430 addressing modes
2434 are supported here, so check for the ones that are allowed. */
2437 if (op1
->mode
== OP_EXP
)
2439 if (op2
->mode
!= OP_REG
)
2441 if (error_message_return
!= NULL
)
2442 * error_message_return
= _("expected register as second argument of %s");
2448 /* MOVA #imm20, Rdst. */
2449 bin
|= 0x80 | op2
->reg
;
2450 frag
= frag_more (4);
2451 where
= frag
- frag_now
->fr_literal
;
2452 if (op1
->exp
.X_op
== O_constant
)
2454 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2455 bfd_putl16 ((bfd_vma
) bin
, frag
);
2456 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2460 bfd_putl16 ((bfd_vma
) bin
, frag
);
2461 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), false,
2462 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2463 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2468 else if (op1
->am
== 1)
2470 /* MOVA z16(Rsrc), Rdst. */
2471 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2472 frag
= frag_more (4);
2473 where
= frag
- frag_now
->fr_literal
;
2474 bfd_putl16 ((bfd_vma
) bin
, frag
);
2475 if (op1
->exp
.X_op
== O_constant
)
2477 if (op1
->exp
.X_add_number
> 0xffff
2478 || op1
->exp
.X_add_number
< -(0x7fff))
2480 if (error_message_return
!= NULL
)
2481 * error_message_return
= _("index value too big for %s");
2484 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2488 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2489 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), false,
2491 BFD_RELOC_MSP430X_PCR16
:
2492 BFD_RELOC_MSP430X_ABS16
);
2497 if (error_message_return
!= NULL
)
2498 * error_message_return
= _("unexpected addressing mode for %s");
2501 else if (op1
->am
== 0)
2503 /* MOVA Rsrc, ... */
2504 if (op2
->mode
== OP_REG
)
2506 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2507 frag
= frag_more (2);
2508 where
= frag
- frag_now
->fr_literal
;
2509 bfd_putl16 ((bfd_vma
) bin
, frag
);
2512 else if (op2
->am
== 1)
2516 /* MOVA Rsrc, &abs20. */
2517 bin
|= 0x60 | (op1
->reg
<< 8);
2518 frag
= frag_more (4);
2519 where
= frag
- frag_now
->fr_literal
;
2520 if (op2
->exp
.X_op
== O_constant
)
2522 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2523 bfd_putl16 ((bfd_vma
) bin
, frag
);
2524 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2528 bfd_putl16 ((bfd_vma
) bin
, frag
);
2529 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2530 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), false,
2531 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2536 /* MOVA Rsrc, z16(Rdst). */
2537 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2538 frag
= frag_more (4);
2539 where
= frag
- frag_now
->fr_literal
;
2540 bfd_putl16 ((bfd_vma
) bin
, frag
);
2541 if (op2
->exp
.X_op
== O_constant
)
2543 if (op2
->exp
.X_add_number
> 0xffff
2544 || op2
->exp
.X_add_number
< -(0x7fff))
2546 if (error_message_return
!= NULL
)
2547 * error_message_return
= _("index value too big for %s");
2550 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2554 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2555 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), false,
2557 BFD_RELOC_MSP430X_PCR16
:
2558 BFD_RELOC_MSP430X_ABS16
);
2563 if (error_message_return
!= NULL
)
2564 * error_message_return
= _("unexpected addressing mode for %s");
2569 /* imm_op == false. */
2571 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2573 /* MOVA &abs20, Rdst. */
2574 if (op2
->mode
!= OP_REG
)
2576 if (error_message_return
!= NULL
)
2577 * error_message_return
= _("expected register as second argument of %s");
2581 if (op2
->reg
== 2 || op2
->reg
== 3)
2583 if (error_message_return
!= NULL
)
2584 * error_message_return
= _("constant generator destination register found in %s");
2588 bin
|= 0x20 | op2
->reg
;
2589 frag
= frag_more (4);
2590 where
= frag
- frag_now
->fr_literal
;
2591 if (op1
->exp
.X_op
== O_constant
)
2593 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2594 bfd_putl16 ((bfd_vma
) bin
, frag
);
2595 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2599 bfd_putl16 ((bfd_vma
) bin
, frag
);
2600 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2601 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), false,
2602 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2606 else if (op1
->mode
== OP_REG
)
2610 /* MOVA @Rsrc+, Rdst. */
2611 if (op2
->mode
!= OP_REG
)
2613 if (error_message_return
!= NULL
)
2614 * error_message_return
= _("expected register as second argument of %s");
2618 if (op2
->reg
== 2 || op2
->reg
== 3)
2620 if (error_message_return
!= NULL
)
2621 * error_message_return
= _("constant generator destination register found in %s");
2625 if (op1
->reg
== 2 || op1
->reg
== 3)
2627 if (error_message_return
!= NULL
)
2628 * error_message_return
= _("constant generator source register found in %s");
2632 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2633 frag
= frag_more (2);
2634 where
= frag
- frag_now
->fr_literal
;
2635 bfd_putl16 ((bfd_vma
) bin
, frag
);
2638 else if (op1
->am
== 2)
2640 /* MOVA @Rsrc,Rdst */
2641 if (op2
->mode
!= OP_REG
)
2643 if (error_message_return
!= NULL
)
2644 * error_message_return
= _("expected register as second argument of %s");
2648 if (op2
->reg
== 2 || op2
->reg
== 3)
2650 if (error_message_return
!= NULL
)
2651 * error_message_return
= _("constant generator destination register found in %s");
2655 if (op1
->reg
== 2 || op1
->reg
== 3)
2657 if (error_message_return
!= NULL
)
2658 * error_message_return
= _("constant generator source register found in %s");
2662 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2663 frag
= frag_more (2);
2664 where
= frag
- frag_now
->fr_literal
;
2665 bfd_putl16 ((bfd_vma
) bin
, frag
);
2670 if (error_message_return
!= NULL
)
2671 * error_message_return
= _("unexpected addressing mode for %s");
2676 #define NOP_CHECK_INTERRUPT (1 << 0)
2677 #define NOP_CHECK_CPU12 (1 << 1)
2678 #define NOP_CHECK_CPU19 (1 << 2)
2680 static signed int check_for_nop
= 0;
2682 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2684 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2685 For MOV insns, more sophisticated processing is needed to determine if they
2686 result in enabling/disabling interrupts. */
2687 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2688 || ((strcmp (OPCODE, "bic") == 0) \
2690 || ((strcmp (OPCODE, "clr") == 0) \
2693 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2694 || ((strcmp (OPCODE, "bis") == 0) \
2697 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2698 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2699 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2700 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2701 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2702 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2704 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2705 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2706 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2707 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2708 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2709 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2715 frag
= frag_more (2);
2716 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2717 dwarf2_emit_insn (2);
2720 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2723 warn_eint_nop (bool prev_insn_is_nop
, bool prev_insn_is_dint
)
2725 if (prev_insn_is_nop
2726 /* If the last insn was a DINT, we will have already warned that a NOP is
2727 required after it. */
2728 || prev_insn_is_dint
2729 /* 430 ISA does not require a NOP before EINT. */
2730 || (! target_is_430x ()))
2733 if (gen_interrupt_nops
)
2736 if (warn_interrupt_nops
)
2737 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2739 else if (warn_interrupt_nops
)
2740 as_warn (_(WARN_NOP_BEFORE_EINT
));
2743 /* Use when unsure what effect the insn will have on the interrupt status,
2744 to insert/warn about adding a NOP before the current insn. */
2747 warn_unsure_interrupt (bool prev_insn_is_nop
,
2748 bool prev_insn_is_dint
)
2750 if (prev_insn_is_nop
2751 /* If the last insn was a DINT, we will have already warned that a NOP is
2752 required after it. */
2753 || prev_insn_is_dint
2754 /* 430 ISA does not require a NOP before EINT or DINT. */
2755 || (! target_is_430x ()))
2758 if (gen_interrupt_nops
)
2761 if (warn_interrupt_nops
)
2762 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2764 else if (warn_interrupt_nops
)
2765 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2768 /* Parse instruction operands.
2769 Return binary opcode. */
2772 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2774 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2775 int insn_length
= 0;
2776 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2780 struct msp430_operand_s op1
, op2
;
2782 static short ZEROS
= 0;
2783 bool byte_op
, imm_op
;
2786 int extended
= 0x1800;
2787 bool extended_op
= false;
2789 const char * error_message
;
2790 static signed int repeat_count
= 0;
2791 static bool prev_insn_is_nop
= false;
2792 static bool prev_insn_is_dint
= false;
2793 static bool prev_insn_is_eint
= false;
2794 /* We might decide before the end of the function that the current insn is
2795 equivalent to DINT/EINT. */
2796 bool this_insn_is_dint
= false;
2797 bool this_insn_is_eint
= false;
2800 /* Opcode is the one from opcodes table
2801 line contains something like
2813 switch (TOLOWER (* line
))
2816 /* Byte operation. */
2817 bin
|= BYTE_OPERATION
;
2823 /* "Address" ops work on 20-bit values. */
2825 bin
|= BYTE_OPERATION
;
2830 /* Word operation - this is the default. */
2838 as_warn (_("no size modifier after period, .w assumed"));
2842 as_bad (_("unrecognised instruction size modifier .%c"),
2854 if (*line
&& ! ISSPACE (*line
))
2856 as_bad (_("junk found after instruction: %s.%s"),
2857 opcode
->name
, line
);
2861 /* Catch the case where the programmer has used a ".a" size modifier on an
2862 instruction that does not support it. Look for an alternative extended
2863 instruction that has the same name without the period. Eg: "add.a"
2864 becomes "adda". Although this not an officially supported way of
2865 specifying instruction aliases other MSP430 assemblers allow it. So we
2866 support it for compatibility purposes. */
2867 if (addr_op
&& opcode
->fmt
>= 0)
2869 const char * old_name
= opcode
->name
;
2872 sprintf (real_name
, "%sa", old_name
);
2873 opcode
= str_hash_find (msp430_hash
, real_name
);
2876 as_bad (_("instruction %s.a does not exist"), old_name
);
2879 #if 0 /* Enable for debugging. */
2880 as_warn ("treating %s.a as %s", old_name
, real_name
);
2883 bin
= opcode
->bin_opcode
;
2886 if (opcode
->fmt
!= -1
2887 && opcode
->insn_opnumb
2888 && (!*line
|| *line
== '\n'))
2890 as_bad (ngettext ("instruction %s requires %d operand",
2891 "instruction %s requires %d operands",
2892 opcode
->insn_opnumb
),
2893 opcode
->name
, opcode
->insn_opnumb
);
2897 memset (l1
, 0, sizeof (l1
));
2898 memset (l2
, 0, sizeof (l2
));
2899 memset (&op1
, 0, sizeof (op1
));
2900 memset (&op2
, 0, sizeof (op2
));
2904 if ((fmt
= opcode
->fmt
) < 0)
2906 if (! target_is_430x ())
2908 as_bad (_("instruction %s requires MSP430X mcu"),
2919 /* If requested set the extended instruction repeat count. */
2922 if (repeat_count
> 0)
2923 extended
|= (repeat_count
- 1);
2925 extended
|= (1 << 7) | (- repeat_count
);
2928 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2933 /* The previous instruction set this flag if it wants to check if this insn
2937 if (! is_opcode ("nop"))
2941 switch (check_for_nop
& - check_for_nop
)
2943 case NOP_CHECK_INTERRUPT
:
2944 /* NOP_CHECK_INTERRUPT rules:
2945 1. 430 and 430x ISA require a NOP after DINT.
2946 2. Only the 430x ISA requires NOP before EINT (this has
2947 been dealt with in the previous call to this function).
2948 3. Only the 430x ISA requires NOP after every EINT.
2950 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2952 if (prev_insn_is_dint
)
2954 if (gen_interrupt_nops
)
2957 if (warn_interrupt_nops
)
2958 as_warn (_(INSERT_NOP_AFTER_DINT
));
2961 as_warn (_(WARN_NOP_AFTER_DINT
));
2963 else if (prev_insn_is_eint
)
2965 if (gen_interrupt_nops
)
2968 if (warn_interrupt_nops
)
2969 as_warn (_(INSERT_NOP_AFTER_EINT
));
2972 as_warn (_(WARN_NOP_AFTER_EINT
));
2974 /* If we get here it's because the last instruction was
2975 determined to either disable or enable interrupts, but
2976 we're not sure which.
2977 We have no information yet about what effect the
2978 current instruction has on interrupts, that has to be
2980 The last insn may have required a NOP after it, so we
2981 deal with that now. */
2984 if (gen_interrupt_nops
)
2987 if (warn_interrupt_nops
)
2988 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2991 /* warn_unsure_interrupt was called on the previous
2993 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
2998 case NOP_CHECK_CPU12
:
2999 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
3000 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
3002 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
3006 case NOP_CHECK_CPU19
:
3007 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
3008 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
3010 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
3015 as_bad (_("internal error: unknown nop check state"));
3018 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
3020 while (check_for_nop
);
3029 switch (opcode
->insn_opnumb
)
3032 if (is_opcode ("eint"))
3033 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3035 /* Set/clear bits instructions. */
3039 extended
|= BYTE_OPERATION
;
3041 /* Emit the extension word. */
3043 frag
= frag_more (2);
3044 bfd_putl16 (extended
, frag
);
3048 frag
= frag_more (2);
3049 bfd_putl16 ((bfd_vma
) bin
, frag
);
3050 dwarf2_emit_insn (insn_length
);
3054 /* Something which works with destination operand. */
3055 line
= extract_operand (line
, l1
, sizeof (l1
));
3056 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, true);
3060 bin
|= (op1
.reg
| (op1
.am
<< 7));
3062 /* If the PC is the destination... */
3063 if (op1
.am
== 0 && op1
.reg
== 0
3064 /* ... and the opcode alters the SR. */
3065 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3066 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3068 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3069 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3070 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3071 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3074 /* If the status register is the destination... */
3075 if (op1
.am
== 0 && op1
.reg
== 2
3076 /* ... and the opcode alters the SR. */
3077 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
3078 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
3079 || is_opcode ("sbc") || is_opcode ("sxt")
3080 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
3081 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
3082 || is_opcode ("sbcx")
3085 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3086 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3087 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3088 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3091 /* Compute the entire instruction length, in bytes. */
3092 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3093 insn_length
+= op_length
;
3094 frag
= frag_more (op_length
);
3095 where
= frag
- frag_now
->fr_literal
;
3100 extended
|= BYTE_OPERATION
;
3102 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3104 as_bad (_("repeat instruction used with non-register mode instruction"));
3108 if (op1
.mode
== OP_EXP
)
3110 if (op1
.exp
.X_op
== O_constant
)
3111 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3113 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3114 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3115 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3117 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3118 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3121 /* Emit the extension word. */
3122 bfd_putl16 (extended
, frag
);
3127 bfd_putl16 ((bfd_vma
) bin
, frag
);
3131 if (op1
.mode
== OP_EXP
)
3133 if (op1
.exp
.X_op
== O_constant
)
3135 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3139 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3144 fix_new_exp (frag_now
, where
, 2,
3145 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3147 fix_new_exp (frag_now
, where
, 2,
3148 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3153 dwarf2_emit_insn (insn_length
);
3157 /* Shift instruction. */
3158 line
= extract_operand (line
, l1
, sizeof (l1
));
3159 strncpy (l2
, l1
, sizeof (l2
));
3160 l2
[sizeof (l2
) - 1] = '\0';
3161 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, true);
3162 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, true);
3165 break; /* An error occurred. All warnings were done before. */
3167 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
3168 frag
= frag_more (insn_length
);
3169 where
= frag
- frag_now
->fr_literal
;
3171 if (target_is_430xv2 ()
3172 && op1
.mode
== OP_REG
3174 && (is_opcode ("rlax")
3175 || is_opcode ("rlcx")
3176 || is_opcode ("rla")
3177 || is_opcode ("rlc")))
3179 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3183 /* If the status register is the destination... */
3184 if (op1
.am
== 0 && op1
.reg
== 2
3185 /* ... and the opcode alters the SR. */
3186 && (is_opcode ("rla") || is_opcode ("rlc")
3187 || is_opcode ("rlax") || is_opcode ("rlcx")
3188 || is_opcode ("sxt") || is_opcode ("sxtx")
3189 || is_opcode ("swpb")
3192 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3193 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3194 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3195 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3201 extended
|= BYTE_OPERATION
;
3203 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3205 as_bad (_("repeat instruction used with non-register mode instruction"));
3209 if (op1
.mode
== OP_EXP
)
3211 if (op1
.exp
.X_op
== O_constant
)
3212 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3214 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3215 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3216 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3218 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3219 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3222 if (op2
.mode
== OP_EXP
)
3224 if (op2
.exp
.X_op
== O_constant
)
3225 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3227 else if (op1
.mode
== OP_EXP
)
3228 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), false,
3229 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3230 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3232 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), false,
3233 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3234 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3237 /* Emit the extension word. */
3238 bfd_putl16 (extended
, frag
);
3243 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3244 bfd_putl16 ((bfd_vma
) bin
, frag
);
3248 if (op1
.mode
== OP_EXP
)
3250 if (op1
.exp
.X_op
== O_constant
)
3252 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3256 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3260 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3261 fix_new_exp (frag_now
, where
, 2,
3262 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3264 fix_new_exp (frag_now
, where
, 2,
3265 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3272 if (op2
.mode
== OP_EXP
)
3274 if (op2
.exp
.X_op
== O_constant
)
3276 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3280 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3284 if (op2
.reg
) /* Not PC relative. */
3285 fix_new_exp (frag_now
, where
, 2,
3286 &(op2
.exp
), false, CHECK_RELOC_MSP430 (op2
));
3288 fix_new_exp (frag_now
, where
, 2,
3289 &(op2
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3294 dwarf2_emit_insn (insn_length
);
3298 /* Branch instruction => mov dst, r0. */
3301 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3305 line
= extract_operand (line
, l1
, sizeof (l1
));
3306 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, false);
3312 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3313 op_length
= 2 + 2 * op1
.ol
;
3314 frag
= frag_more (op_length
);
3315 where
= frag
- frag_now
->fr_literal
;
3316 bfd_putl16 ((bfd_vma
) bin
, frag
);
3318 if (op1
.mode
== OP_EXP
)
3320 if (op1
.exp
.X_op
== O_constant
)
3322 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3328 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3330 if (op1
.reg
|| op1
.am
== 3)
3331 fix_new_exp (frag_now
, where
, 2,
3332 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3334 fix_new_exp (frag_now
, where
, 2,
3335 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3339 dwarf2_emit_insn (insn_length
+ op_length
);
3343 /* CALLA instructions. */
3344 fix_emitted
= false;
3346 line
= extract_operand (line
, l1
, sizeof (l1
));
3349 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3350 extended_op
, false);
3356 op_length
= 2 + 2 * op1
.ol
;
3357 frag
= frag_more (op_length
);
3358 where
= frag
- frag_now
->fr_literal
;
3366 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3367 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3370 else if (op1
.am
== 1)
3376 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3377 BFD_RELOC_MSP430X_PCR20_CALL
);
3381 bin
|= 0x50 | op1
.reg
;
3383 else if (op1
.am
== 0)
3384 bin
|= 0x40 | op1
.reg
;
3386 else if (op1
.am
== 1)
3390 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3391 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3394 else if (op1
.am
== 2)
3395 bin
|= 0x60 | op1
.reg
;
3396 else if (op1
.am
== 3)
3397 bin
|= 0x70 | op1
.reg
;
3399 bfd_putl16 ((bfd_vma
) bin
, frag
);
3401 if (op1
.mode
== OP_EXP
)
3405 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3409 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3412 fix_new_exp (frag_now
, where
+ 2, 2,
3413 &(op1
.exp
), false, BFD_RELOC_16
);
3416 dwarf2_emit_insn (insn_length
+ op_length
);
3424 /* [POP|PUSH]M[.A] #N, Rd */
3425 line
= extract_operand (line
, l1
, sizeof (l1
));
3426 line
= extract_operand (line
, l2
, sizeof (l2
));
3430 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3433 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3434 if (end
!= NULL
&& *end
!= 0)
3436 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3439 if (op1
.exp
.X_op
!= O_constant
)
3441 as_bad (_("expected constant expression as first argument of %s"),
3446 if ((reg
= check_reg (l2
)) == -1)
3448 as_bad (_("expected register as second argument of %s"),
3454 frag
= frag_more (op_length
);
3455 where
= frag
- frag_now
->fr_literal
;
3456 bin
= opcode
->bin_opcode
;
3459 n
= op1
.exp
.X_add_number
;
3460 bin
|= (n
- 1) << 4;
3461 if (is_opcode ("pushm"))
3465 if (reg
- n
+ 1 < 0)
3467 as_bad (_("Too many registers popped"));
3471 /* CPU21 errata: cannot use POPM to restore the SR register. */
3472 if (target_is_430xv2 ()
3473 && (reg
- n
+ 1 < 3)
3475 && is_opcode ("popm"))
3477 as_bad (_("Cannot use POPM to restore the SR register"));
3481 bin
|= (reg
- n
+ 1);
3484 bfd_putl16 ((bfd_vma
) bin
, frag
);
3485 dwarf2_emit_insn (op_length
);
3494 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3495 if (extended
& 0xff)
3497 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3501 line
= extract_operand (line
, l1
, sizeof (l1
));
3502 line
= extract_operand (line
, l2
, sizeof (l2
));
3506 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3509 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3510 if (end
!= NULL
&& *end
!= 0)
3512 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3515 if (op1
.exp
.X_op
!= O_constant
)
3517 as_bad (_("expected constant expression as first argument of %s"),
3521 n
= op1
.exp
.X_add_number
;
3524 as_bad (_("expected first argument of %s to be in the range 1-4"),
3529 if ((reg
= check_reg (l2
)) == -1)
3531 as_bad (_("expected register as second argument of %s"),
3536 if (target_is_430xv2 () && reg
== 0)
3538 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3543 frag
= frag_more (op_length
);
3544 where
= frag
- frag_now
->fr_literal
;
3546 bin
= opcode
->bin_opcode
;
3549 bin
|= (n
- 1) << 10;
3552 bfd_putl16 ((bfd_vma
) bin
, frag
);
3553 dwarf2_emit_insn (op_length
);
3559 bool need_reloc
= false;
3563 /* ADDA, CMPA and SUBA address instructions. */
3564 if (extended
& 0xff)
3566 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3570 line
= extract_operand (line
, l1
, sizeof (l1
));
3571 line
= extract_operand (line
, l2
, sizeof (l2
));
3573 bin
= opcode
->bin_opcode
;
3577 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3578 if (end
!= NULL
&& *end
!= 0)
3580 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3584 if (op1
.exp
.X_op
== O_constant
)
3586 n
= op1
.exp
.X_add_number
;
3587 if (n
> 0xfffff || n
< - (0x7ffff))
3589 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3594 bin
|= ((n
>> 16) & 0xf) << 8;
3606 if ((n
= check_reg (l1
)) == -1)
3608 as_bad (_("expected register name or constant as first argument of %s"),
3613 bin
|= (n
<< 8) | (1 << 6);
3617 if ((reg
= check_reg (l2
)) == -1)
3619 as_bad (_("expected register as second argument of %s"),
3624 frag
= frag_more (op_length
);
3625 where
= frag
- frag_now
->fr_literal
;
3628 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3629 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3631 bfd_putl16 ((bfd_vma
) bin
, frag
);
3633 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3634 dwarf2_emit_insn (op_length
);
3638 case 9: /* MOVA, BRA, RETA. */
3640 bin
= opcode
->bin_opcode
;
3642 if (is_opcode ("reta"))
3644 /* The RETA instruction does not take any arguments.
3645 The implicit first argument is @SP+.
3646 The implicit second argument is PC. */
3656 line
= extract_operand (line
, l1
, sizeof (l1
));
3657 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3658 &imm_op
, extended_op
, false);
3660 if (is_opcode ("bra"))
3662 /* This is the BRA synthetic instruction.
3663 The second argument is always PC. */
3669 line
= extract_operand (line
, l2
, sizeof (l2
));
3670 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3675 break; /* Error occurred. All warnings were done before. */
3678 /* Only a restricted subset of the normal MSP430 addressing modes
3679 are supported here, so check for the ones that are allowed. */
3680 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3681 & error_message
)) == 0)
3683 as_bad (error_message
, opcode
->name
);
3686 dwarf2_emit_insn (op_length
);
3690 line
= extract_operand (line
, l1
, sizeof l1
);
3691 /* The RPT instruction only accepted immediates and registers. */
3694 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3695 if (end
!= NULL
&& *end
!= 0)
3697 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3700 if (op1
.exp
.X_op
!= O_constant
)
3702 as_bad (_("expected constant value as argument to RPT"));
3705 if (op1
.exp
.X_add_number
< 1
3706 || op1
.exp
.X_add_number
> (1 << 4))
3708 as_bad (_("expected constant in the range 2..16"));
3712 /* We silently accept and ignore a repeat count of 1. */
3713 if (op1
.exp
.X_add_number
> 1)
3714 repeat_count
= op1
.exp
.X_add_number
;
3720 if ((reg
= check_reg (l1
)) != -1)
3723 as_warn (_("PC used as an argument to RPT"));
3725 repeat_count
= - reg
;
3729 as_bad (_("expected constant or register name as argument to RPT insn"));
3736 as_bad (_("Illegal emulated instruction"));
3741 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3742 From f5 ref man 6.3.3:
3743 The 16-bit Status Register (SR, also called R2), used as a source or
3744 destination register, can only be used in register mode addressed
3745 with word instructions. */
3747 case 1: /* Format 1, double operand. */
3748 line
= extract_operand (line
, l1
, sizeof (l1
));
3749 line
= extract_operand (line
, l2
, sizeof (l2
));
3750 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, true);
3751 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, true);
3754 break; /* Error occurred. All warnings were done before. */
3757 && is_opcode ("movx")
3759 && msp430_enable_relax
)
3761 /* This is the MOVX.A instruction. See if we can convert
3762 it into the MOVA instruction instead. This saves 2 bytes. */
3763 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3766 dwarf2_emit_insn (op_length
);
3771 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3773 /* If the PC is the destination... */
3774 if (op2
.am
== 0 && op2
.reg
== 0
3775 /* ... and the opcode alters the SR. */
3776 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3777 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3779 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3780 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3781 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3782 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3785 /* If the status register is the destination... */
3786 if (op2
.am
== 0 && op2
.reg
== 2
3787 /* ... and the opcode alters the SR. */
3788 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3789 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3790 || is_opcode ("xor")
3791 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3792 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3793 || is_opcode ("xorx")
3796 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3797 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3798 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3799 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3802 /* Chain these checks for SR manipulations so we can warn if they are not
3804 if (((is_opcode ("bis") && bin
== 0xd032)
3805 || (is_opcode ("mov") && bin
== 0x4032)
3806 || (is_opcode ("xor") && bin
== 0xe032))
3807 && op1
.mode
== OP_EXP
3808 && op1
.exp
.X_op
== O_constant
3809 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3810 check_for_nop
|= NOP_CHECK_CPU19
;
3811 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3813 /* Any MOV with the SR as the destination either enables or disables
3815 if (op1
.mode
== OP_EXP
3816 && op1
.exp
.X_op
== O_constant
)
3818 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3820 /* The GIE bit is being set. */
3821 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3822 this_insn_is_eint
= true;
3825 /* The GIE bit is being cleared. */
3826 this_insn_is_dint
= true;
3828 /* If an immediate value which is covered by the constant generator
3829 is the src, then op1 will have been changed to either R2 or R3 by
3831 The only constants covered by CG1 and CG2, which have bit 3 set
3832 and therefore would enable interrupts when writing to the SR, are
3833 R2 with addresing mode 0b11 and R3 with 0b11.
3834 The addressing mode is in bits 5:4 of the binary opcode. */
3835 else if (op1
.mode
== OP_REG
3836 && (op1
.reg
== 2 || op1
.reg
== 3)
3837 && (bin
& 0x30) == 0x30)
3839 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3840 this_insn_is_eint
= true;
3842 /* Any other use of the constant generator with destination R2, will
3843 disable interrupts. */
3844 else if (op1
.mode
== OP_REG
3845 && (op1
.reg
== 2 || op1
.reg
== 3))
3846 this_insn_is_dint
= true;
3847 else if (do_unknown_interrupt_nops
)
3849 /* FIXME: Couldn't work out whether the insn is enabling or
3850 disabling interrupts, so for safety need to treat it as both
3852 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3853 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3856 else if (is_eint (opcode
->name
, bin
))
3857 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3858 else if ((bin
& 0x32) == 0x32)
3860 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3861 * an interrupt state change if a write happens. */
3862 /* FIXME: How strict to be here? */
3866 /* Compute the entire length of the instruction in bytes. */
3867 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3868 + 2 /* The opcode */
3869 + (2 * op1
.ol
) /* The first operand. */
3870 + (2 * op2
.ol
); /* The second operand. */
3872 insn_length
+= op_length
;
3873 frag
= frag_more (op_length
);
3874 where
= frag
- frag_now
->fr_literal
;
3879 extended
|= BYTE_OPERATION
;
3881 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3883 as_bad (_("repeat instruction used with non-register mode instruction"));
3887 /* If necessary, emit a reloc to update the extension word. */
3888 if (op1
.mode
== OP_EXP
)
3890 if (op1
.exp
.X_op
== O_constant
)
3891 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3893 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3894 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3895 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3897 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3898 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3901 if (op2
.mode
== OP_EXP
)
3903 if (op2
.exp
.X_op
== O_constant
)
3904 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3906 else if (op1
.mode
== OP_EXP
)
3907 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), false,
3908 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3909 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3912 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), false,
3913 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3914 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3917 /* Emit the extension word. */
3918 bfd_putl16 (extended
, frag
);
3923 bfd_putl16 ((bfd_vma
) bin
, frag
);
3927 if (op1
.mode
== OP_EXP
)
3929 if (op1
.exp
.X_op
== O_constant
)
3931 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3935 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3939 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3940 fix_new_exp (frag_now
, where
, 2,
3941 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3943 fix_new_exp (frag_now
, where
, 2,
3944 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3952 if (op2
.mode
== OP_EXP
)
3954 if (op2
.exp
.X_op
== O_constant
)
3956 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3960 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3964 if (op2
.reg
) /* Not PC relative. */
3965 fix_new_exp (frag_now
, where
, 2,
3966 &(op2
.exp
), false, CHECK_RELOC_MSP430 (op2
));
3968 fix_new_exp (frag_now
, where
, 2,
3969 &(op2
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3974 dwarf2_emit_insn (insn_length
);
3976 /* If the PC is the destination... */
3977 if (op2
.am
== 0 && op2
.reg
== 0
3978 /* ... but the opcode does not alter the destination. */
3979 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3980 check_for_nop
|= NOP_CHECK_CPU12
;
3983 case 2: /* Single-operand mostly instr. */
3984 if (opcode
->insn_opnumb
== 0)
3986 /* reti instruction. */
3988 frag
= frag_more (2);
3989 bfd_putl16 ((bfd_vma
) bin
, frag
);
3990 dwarf2_emit_insn (insn_length
);
3994 line
= extract_operand (line
, l1
, sizeof (l1
));
3995 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3996 &imm_op
, extended_op
, true);
3998 break; /* Error in operand. */
4000 if (target_is_430xv2 ()
4001 && op1
.mode
== OP_REG
4003 && (is_opcode ("rrax")
4004 || is_opcode ("rrcx")
4005 || is_opcode ("rra")
4006 || is_opcode ("rrc")))
4008 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
4012 /* If the status register is the destination... */
4013 if (op1
.am
== 0 && op1
.reg
== 2
4014 /* ... and the opcode alters the SR. */
4015 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
4017 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
4018 as_bad (_("CPU13: SR is destination of SR altering instruction"));
4019 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
4020 as_warn (_("CPU13: SR is destination of SR altering instruction"));
4023 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
4024 frag
= frag_more (insn_length
);
4025 where
= frag
- frag_now
->fr_literal
;
4029 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
4031 /* These two instructions use a special
4032 encoding of the A/L and B/W bits. */
4033 bin
&= ~ BYTE_OPERATION
;
4037 as_bad (_("%s instruction does not accept a .b suffix"),
4042 extended
|= BYTE_OPERATION
;
4045 extended
|= BYTE_OPERATION
;
4047 if (is_opcode ("rrux"))
4048 extended
|= IGNORE_CARRY_BIT
;
4050 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
4052 as_bad (_("repeat instruction used with non-register mode instruction"));
4056 if (op1
.mode
== OP_EXP
)
4058 if (op1
.exp
.X_op
== O_constant
)
4059 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
4061 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4062 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
4063 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
4065 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
4066 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
4069 /* Emit the extension word. */
4070 bfd_putl16 (extended
, frag
);
4075 bin
|= op1
.reg
| (op1
.am
<< 4);
4076 bfd_putl16 ((bfd_vma
) bin
, frag
);
4080 if (op1
.mode
== OP_EXP
)
4082 if (op1
.exp
.X_op
== O_constant
)
4084 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
4088 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
4092 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4093 fix_new_exp (frag_now
, where
, 2,
4094 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
4096 fix_new_exp (frag_now
, where
, 2,
4097 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
4102 dwarf2_emit_insn (insn_length
);
4105 case 3: /* Conditional jumps instructions. */
4106 line
= extract_operand (line
, l1
, sizeof (l1
));
4107 /* l1 is a label. */
4116 end
= parse_exp (m
, &exp
);
4117 if (end
!= NULL
&& *end
!= 0)
4119 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4123 /* In order to handle something like:
4127 jz 4 ; skip next 4 bytes
4130 nop ; will jump here if r5 positive or zero
4132 jCOND -n ;assumes jump n bytes backward:
4142 jCOND $n ; jump from PC in either direction. */
4144 if (exp
.X_op
== O_constant
)
4146 int x
= exp
.X_add_number
;
4150 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
4154 if ((*l1
== '$' && x
> 0) || x
< 0)
4159 if (x
> 512 || x
< -511)
4161 as_bad (_("Wrong displacement %d"), x
<< 1);
4166 frag
= frag_more (2); /* Instr size is 1 word. */
4169 bfd_putl16 ((bfd_vma
) bin
, frag
);
4171 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4174 frag
= frag_more (2); /* Instr size is 1 word. */
4175 where
= frag
- frag_now
->fr_literal
;
4176 fix_new_exp (frag_now
, where
, 2,
4177 &exp
, true, BFD_RELOC_MSP430_10_PCREL
);
4179 bfd_putl16 ((bfd_vma
) bin
, frag
);
4181 else if (*l1
== '$')
4183 as_bad (_("instruction requires label sans '$'"));
4187 ("instruction requires label or value in range -511:512"));
4188 dwarf2_emit_insn (insn_length
);
4193 as_bad (_("instruction requires label"));
4198 case 4: /* Extended jumps. */
4199 if (!msp430_enable_polys
)
4201 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4205 line
= extract_operand (line
, l1
, sizeof (l1
));
4211 /* Ignore absolute addressing. make it PC relative anyway. */
4212 if (*m
== '#' || *m
== '$')
4215 end
= parse_exp (m
, & exp
);
4216 if (end
!= NULL
&& *end
!= 0)
4218 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4221 if (exp
.X_op
== O_symbol
)
4223 /* Relaxation required. */
4224 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4226 if (target_is_430x ())
4227 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4229 /* The parameter to dwarf2_emit_insn is actually the offset to
4230 the start of the insn from the fix piece of instruction that
4231 was emitted. Since next fragments may have variable size we
4232 tie debug info to the beginning of the instruction. */
4234 frag
= frag_more (8);
4235 dwarf2_emit_insn (0);
4236 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4237 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4239 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4241 0, /* Offset is zero if jump dist less than 1K. */
4247 as_bad (_("instruction requires label"));
4250 case 5: /* Emulated extended branches. */
4251 if (!msp430_enable_polys
)
4253 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4256 line
= extract_operand (line
, l1
, sizeof (l1
));
4262 /* Ignore absolute addressing. make it PC relative anyway. */
4263 if (*m
== '#' || *m
== '$')
4266 end
= parse_exp (m
, & exp
);
4267 if (end
!= NULL
&& *end
!= 0)
4269 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4272 if (exp
.X_op
== O_symbol
)
4274 /* Relaxation required. */
4275 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4277 if (target_is_430x ())
4278 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4281 frag
= frag_more (8);
4282 dwarf2_emit_insn (0);
4283 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4284 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4286 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4287 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4289 0, /* Offset is zero if jump dist less than 1K. */
4295 as_bad (_("instruction requires label"));
4299 as_bad (_("Illegal instruction or not implemented opcode."));
4302 if (is_opcode ("nop"))
4304 prev_insn_is_nop
= true;
4305 prev_insn_is_dint
= false;
4306 prev_insn_is_eint
= false;
4308 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4310 prev_insn_is_dint
= true;
4311 prev_insn_is_eint
= false;
4312 prev_insn_is_nop
= false;
4313 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4315 /* NOP is not needed after EINT for 430 ISA. */
4316 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4318 prev_insn_is_eint
= true;
4319 prev_insn_is_nop
= false;
4320 prev_insn_is_dint
= false;
4321 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4325 prev_insn_is_nop
= false;
4326 prev_insn_is_dint
= false;
4327 prev_insn_is_eint
= false;
4330 input_line_pointer
= line
;
4335 md_assemble (char * str
)
4337 struct msp430_opcode_s
* opcode
;
4341 str
= skip_space (str
); /* Skip leading spaces. */
4342 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4346 char a
= TOLOWER (cmd
[i
]);
4353 as_bad (_("can't find opcode"));
4357 opcode
= (struct msp430_opcode_s
*) str_hash_find (msp430_hash
, cmd
);
4361 as_bad (_("unknown opcode `%s'"), cmd
);
4366 char *__t
= input_line_pointer
;
4368 msp430_operands (opcode
, str
);
4369 input_line_pointer
= __t
;
4373 /* GAS will call this function for each section at the end of the assembly,
4374 to permit the CPU backend to adjust the alignment of a section. */
4377 md_section_align (asection
* seg
, valueT addr
)
4379 int align
= bfd_section_alignment (seg
);
4381 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4384 /* If you define this macro, it should return the offset between the
4385 address of a PC relative fixup and the position from which the PC
4386 relative adjustment should be made. On many processors, the base
4387 of a PC relative instruction is the next instruction, so this
4388 macro would return the length of an instruction. */
4391 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4393 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4394 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4395 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4398 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4401 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4402 Now it handles the situation when relocations
4403 have to be passed to linker. */
4405 msp430_force_relocation_local (fixS
*fixp
)
4407 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4411 if (msp430_enable_polys
4412 && !msp430_enable_relax
)
4419 /* GAS will call this for each fixup. It should store the correct
4420 value in the object file. */
4422 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4424 unsigned char * where
;
4428 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4433 else if (fixp
->fx_pcrel
)
4435 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4437 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4439 /* FIXME: We can appear here only in case if we perform a pc
4440 relative jump to the label which is i) global, ii) locally
4441 defined or this is a jump to an absolute symbol.
4442 If this is an absolute symbol -- everything is OK.
4443 If this is a global label, we've got a symbol value defined
4445 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4446 from this section start
4447 2. *valuep will contain the real offset from jump insn to the
4449 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4450 will be incorrect. Therefore remove s_get_value. */
4451 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4459 value
= fixp
->fx_offset
;
4461 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4463 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4465 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4471 fixp
->fx_no_overflow
= 1;
4473 /* If polymorphs are enabled and relax disabled.
4474 do not kill any relocs and pass them to linker. */
4475 if (msp430_enable_polys
4476 && !msp430_enable_relax
)
4479 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4480 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4487 /* Fetch the instruction, insert the fully resolved operand
4488 value, and stuff the instruction back again. */
4489 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4491 insn
= bfd_getl16 (where
);
4493 switch (fixp
->fx_r_type
)
4495 case BFD_RELOC_MSP430_10_PCREL
:
4497 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4498 _("odd address operand: %ld"), value
);
4500 /* Jumps are in words. */
4502 --value
; /* Correct PC. */
4504 if (value
< -512 || value
> 511)
4505 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4506 _("operand out of range: %ld"), value
);
4508 value
&= 0x3ff; /* get rid of extended sign */
4509 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4512 case BFD_RELOC_MSP430X_PCR16
:
4513 case BFD_RELOC_MSP430_RL_PCREL
:
4514 case BFD_RELOC_MSP430_16_PCREL
:
4516 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4517 _("odd address operand: %ld"), value
);
4520 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4521 /* Nothing to be corrected here. */
4522 if (value
< -32768 || value
> 65536)
4523 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4524 _("operand out of range: %ld"), value
);
4527 case BFD_RELOC_MSP430X_ABS16
:
4528 case BFD_RELOC_MSP430_16
:
4530 case BFD_RELOC_MSP430_16_BYTE
:
4531 value
&= 0xffff; /* Get rid of extended sign. */
4532 bfd_putl16 ((bfd_vma
) value
, where
);
4535 case BFD_RELOC_MSP430_ABS_HI16
:
4537 value
&= 0xffff; /* Get rid of extended sign. */
4538 bfd_putl16 ((bfd_vma
) value
, where
);
4542 bfd_putl16 ((bfd_vma
) value
, where
);
4545 case BFD_RELOC_MSP430_ABS8
:
4547 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4550 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4551 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4552 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4554 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4557 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4558 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4560 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4563 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4564 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4566 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4569 case BFD_RELOC_MSP430X_PCR20_CALL
:
4570 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4572 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4575 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4576 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4577 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4579 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4582 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4583 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4585 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4588 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4589 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4591 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4595 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4596 fixp
->fx_line
, fixp
->fx_r_type
);
4602 fixp
->fx_addnumber
= value
;
4607 S_IS_GAS_LOCAL (symbolS
* s
)
4614 name
= S_GET_NAME (s
);
4615 len
= strlen (name
) - 1;
4617 return name
[len
] == 1 || name
[len
] == 2;
4620 /* GAS will call this to generate a reloc, passing the resulting reloc
4621 to `bfd_install_relocation'. This currently works poorly, as
4622 `bfd_install_relocation' often does the wrong thing, and instances of
4623 `tc_gen_reloc' have been written to work around the problems, which
4624 in turns makes it difficult to fix `bfd_install_relocation'. */
4626 /* If while processing a fixup, a reloc really needs to be created
4627 then it is done here. */
4630 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4632 static arelent
* no_relocs
= NULL
;
4633 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4636 reloc
= XNEW (arelent
);
4637 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4638 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4640 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4642 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4643 _("reloc %d not supported by object file format"),
4644 (int) fixp
->fx_r_type
);
4653 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4655 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4656 fixp
->fx_subsy
= NULL
;
4659 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4661 asection
*asec
, *ssec
;
4663 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4664 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4666 /* If we have a difference between two different, non-absolute symbols
4667 we must generate two relocs (one for each symbol) and allow the
4668 linker to resolve them - relaxation may change the distances between
4669 symbols, even local symbols defined in the same section.
4671 Unfortunately we cannot do this with assembler generated local labels
4672 because there can be multiple incarnations of the same label, with
4673 exactly the same name, in any given section and the linker will have
4674 no way to identify the correct one. Instead we just have to hope
4675 that no relaxation will occur between the local label and the other
4676 symbol in the expression.
4678 Similarly we have to compute differences between symbols in the .eh_frame
4679 section as the linker is not smart enough to apply relocations there
4680 before attempting to process it. */
4681 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4682 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4683 && strcmp (ssec
->name
, ".eh_frame") != 0
4684 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4685 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4687 arelent
* reloc2
= XNEW (arelent
);
4692 reloc2
->address
= reloc
->address
;
4693 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4694 BFD_RELOC_MSP430_SYM_DIFF
);
4695 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4697 if (ssec
== absolute_section
)
4698 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4701 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4702 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4705 reloc
->addend
= fixp
->fx_offset
;
4706 if (asec
== absolute_section
)
4708 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4709 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4713 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4714 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4723 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4725 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4726 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4728 switch (fixp
->fx_r_type
)
4731 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4735 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4739 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4743 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4748 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4759 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4760 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4762 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4763 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4765 md_number_to_chars (fixpos
, amount
, 2);
4770 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4771 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4772 reloc
->addend
= fixp
->fx_offset
;
4774 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4775 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4776 reloc
->address
= fixp
->fx_offset
;
4783 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4784 asection
* segment_type ATTRIBUTE_UNUSED
)
4786 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4788 /* This is a jump -> pcrel mode. Nothing to do much here.
4789 Return value == 2. */
4791 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4793 else if (fragP
->fr_symbol
)
4795 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4796 an absolute segment, we don't know a displacement until we link
4797 object files. So it will always be long. This also applies to
4798 labels in a subsegment of current. Liker may relax it to short
4799 jump later. Return value == 8. */
4801 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4805 /* We know the abs value. may be it is a jump to fixed address.
4806 Impossible in our case, cause all constants already handled. */
4808 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4811 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4815 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4816 asection
* sec ATTRIBUTE_UNUSED
,
4822 struct rcodes_s
* cc
= NULL
;
4823 struct hcodes_s
* hc
= NULL
;
4825 switch (fragP
->fr_subtype
)
4827 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4828 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4829 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4830 /* We do not have to convert anything here.
4831 Just apply a fix. */
4832 rela
= BFD_RELOC_MSP430_10_PCREL
;
4835 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4836 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4837 /* Convert uncond branch jmp lab -> br lab. */
4838 if (target_is_430x ())
4839 cc
= msp430x_rcodes
+ 7;
4841 cc
= msp430_rcodes
+ 7;
4842 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4843 bfd_putl16 (cc
->lop0
, where
);
4844 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4848 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4849 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4851 /* Other simple branches. */
4852 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4855 /* Find actual instruction. */
4856 if (target_is_430x ())
4858 for (i
= 0; i
< 7 && !cc
; i
++)
4859 if (msp430x_rcodes
[i
].sop
== insn
)
4860 cc
= msp430x_rcodes
+ i
;
4864 for (i
= 0; i
< 7 && !cc
; i
++)
4865 if (msp430_rcodes
[i
].sop
== insn
)
4866 cc
= & msp430_rcodes
[i
];
4869 if (!cc
|| !cc
->name
)
4870 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4871 __FUNCTION__
, (long) insn
);
4872 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4873 bfd_putl16 (cc
->lop0
, where
);
4874 bfd_putl16 (cc
->lop1
, where
+ 2);
4875 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4880 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4881 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4882 if (target_is_430x ())
4883 cc
= msp430x_rcodes
+ 6;
4885 cc
= msp430_rcodes
+ 6;
4886 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4887 bfd_putl16 (cc
->lop0
, where
);
4888 bfd_putl16 (cc
->lop1
, where
+ 2);
4889 bfd_putl16 (cc
->lop2
, where
+ 4);
4890 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4894 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4896 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4899 if (target_is_430x ())
4901 for (i
= 0; i
< 4 && !hc
; i
++)
4902 if (msp430x_hcodes
[i
].op1
== insn
)
4903 hc
= msp430x_hcodes
+ i
;
4907 for (i
= 0; i
< 4 && !hc
; i
++)
4908 if (msp430_hcodes
[i
].op1
== insn
)
4909 hc
= &msp430_hcodes
[i
];
4911 if (!hc
|| !hc
->name
)
4912 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4913 __FUNCTION__
, (long) insn
);
4914 rela
= BFD_RELOC_MSP430_10_PCREL
;
4915 /* Apply a fix for a first label if necessary.
4916 another fix will be applied to the next word of insn anyway. */
4918 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4919 fragP
->fr_offset
, true, rela
);
4925 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4926 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4928 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4931 if (target_is_430x ())
4933 for (i
= 0; i
< 4 && !hc
; i
++)
4934 if (msp430x_hcodes
[i
].op1
== insn
)
4935 hc
= msp430x_hcodes
+ i
;
4939 for (i
= 0; i
< 4 && !hc
; i
++)
4940 if (msp430_hcodes
[i
].op1
== insn
)
4941 hc
= & msp430_hcodes
[i
];
4943 if (!hc
|| !hc
->name
)
4944 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4945 __FUNCTION__
, (long) insn
);
4946 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4947 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4948 bfd_putl16 (hc
->lop0
, where
);
4949 bfd_putl16 (hc
->lop1
, where
+ 2);
4950 bfd_putl16 (hc
->lop2
, where
+ 4);
4956 as_fatal (_("internal inconsistency problem in %s: %lx"),
4957 __FUNCTION__
, (long) fragP
->fr_subtype
);
4961 /* Now apply fix. */
4962 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4963 fragP
->fr_offset
, true, rela
);
4964 /* Just fixed 2 bytes. */
4968 /* Relax fragment. Mostly stolen from hc11 and mcore
4969 which arches I think I know. */
4972 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4973 long stretch ATTRIBUTE_UNUSED
)
4978 const relax_typeS
*this_type
;
4979 const relax_typeS
*start_type
;
4980 relax_substateT next_state
;
4981 relax_substateT this_state
;
4982 const relax_typeS
*table
= md_relax_table
;
4984 /* Nothing to be done if the frag has already max size. */
4985 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4986 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4989 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4991 symbolP
= fragP
->fr_symbol
;
4992 if (symbol_resolved_p (symbolP
))
4993 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4995 /* We know the offset. calculate a distance. */
4996 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4999 if (!msp430_enable_relax
)
5001 /* Relaxation is not enabled. So, make all jump as long ones
5002 by setting 'aim' to quite high value. */
5006 this_state
= fragP
->fr_subtype
;
5007 start_type
= this_type
= table
+ this_state
;
5011 /* Look backwards. */
5012 for (next_state
= this_type
->rlx_more
; next_state
;)
5013 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
5017 /* Grow to next state. */
5018 this_state
= next_state
;
5019 this_type
= table
+ this_state
;
5020 next_state
= this_type
->rlx_more
;
5025 /* Look forwards. */
5026 for (next_state
= this_type
->rlx_more
; next_state
;)
5027 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
5031 /* Grow to next state. */
5032 this_state
= next_state
;
5033 this_type
= table
+ this_state
;
5034 next_state
= this_type
->rlx_more
;
5038 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5040 fragP
->fr_subtype
= this_state
;
5044 /* Return FALSE if the fixup in fixp should be left alone and not
5045 adjusted. We return FALSE here so that linker relaxation will
5049 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
5051 /* If the symbol is in a non-code section then it should be OK. */
5053 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
5059 /* Scan uleb128 subtraction expressions and insert fixups for them.
5060 e.g., .uleb128 .L1 - .L0
5061 Because relaxation may change the value of the subtraction, we
5062 must resolve them at link-time. */
5065 msp430_insert_uleb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
5066 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
5068 segment_info_type
*seginfo
= seg_info (sec
);
5071 subseg_set (sec
, 0);
5073 for (fragP
= seginfo
->frchainP
->frch_root
;
5074 fragP
; fragP
= fragP
->fr_next
)
5076 expressionS
*exp
, *exp_dup
;
5078 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_symbol
== NULL
)
5081 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
5083 if (exp
->X_op
!= O_subtract
)
5086 /* FIXME: Skip for .sleb128. */
5087 if (fragP
->fr_subtype
!= 0)
5090 exp_dup
= xmemdup (exp
, sizeof (*exp
), sizeof (*exp
));
5091 exp_dup
->X_op
= O_symbol
;
5092 exp_dup
->X_op_symbol
= NULL
;
5094 /* Emit the SUB relocation first, since the SET relocation will write out
5096 exp_dup
->X_add_symbol
= exp
->X_op_symbol
;
5097 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
5098 exp_dup
, 0, BFD_RELOC_MSP430_SUB_ULEB128
);
5100 exp_dup
->X_add_symbol
= exp
->X_add_symbol
;
5101 /* Insert relocations to resolve the subtraction at link-time. */
5102 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
5103 exp_dup
, 0, BFD_RELOC_MSP430_SET_ULEB128
);
5108 /* Called after all assembly has been done. */
5110 msp430_md_end (void)
5114 if (gen_interrupt_nops
)
5117 if (warn_interrupt_nops
)
5118 as_warn (INSERT_NOP_AT_EOF
);
5120 else if (warn_interrupt_nops
)
5121 as_warn (_(WARN_NOP_AT_EOF
));
5124 /* Insert relocations for uleb128 directives, so the values can be recomputed
5126 bfd_map_over_sections (stdoutput
, msp430_insert_uleb128_fixes
, NULL
);
5128 /* We have already emitted an error if any of the following attributes
5129 disagree with the attributes in the input assembly file. See
5130 msp430_object_attribute. */
5131 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
5132 target_is_430x () ? OFBA_MSPABI_Val_ISA_MSP430X
5133 : OFBA_MSPABI_Val_ISA_MSP430
);
5135 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
5136 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5137 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5139 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
5140 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5141 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5143 /* The data region GNU attribute is ignored for the small memory model. */
5145 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_GNU
,
5146 Tag_GNU_MSP430_Data_Region
, lower_data_region_only
5147 ? Val_GNU_MSP430_Data_Region_Lower
5148 : Val_GNU_MSP430_Data_Region_Any
);
5151 /* Returns FALSE if there is a msp430 specific reason why the
5152 subtraction of two same-section symbols cannot be computed by
5156 msp430_allow_local_subtract (expressionS
* left
,
5157 expressionS
* right
,
5160 /* If the symbols are not in a code section then they are OK. */
5161 if ((section
->flags
& SEC_CODE
) == 0)
5164 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
5167 if (left
->X_add_symbol
== right
->X_add_symbol
)
5170 /* We have to assume that there may be instructions between the
5171 two symbols and that relaxation may increase the distance between