1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2019 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
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 struct hash_control
*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
;
266 static inline bfd_boolean
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
272 static inline bfd_boolean
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation.
279 For the 430X we generate a relocation without linker range checking
280 if the value is being used in an extended (ie 20-bit) instruction,
281 otherwise if have a shifted expression we use a HI reloc.
282 For the 430 we generate a relocation without assembler range checking
283 if we are handling an immediate value or a byte-width instruction. */
285 #undef CHECK_RELOC_MSP430
286 #define CHECK_RELOC_MSP430(OP) \
290 : ((OP).vshift == 1) \
291 ? BFD_RELOC_MSP430_ABS_HI16 \
292 : BFD_RELOC_MSP430X_ABS16) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
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"));
418 /* Our caller is likely to check that the entire expression was parsed.
419 If we have found a hex constant with an 'h' suffix, ilp will be left
420 pointing at the 'h', so skip it here. */
421 if (input_line_pointer
!= NULL
422 && op
->X_op
== O_constant
423 && (*input_line_pointer
== 'h' || *input_line_pointer
== 'H'))
424 ++ input_line_pointer
;
425 return input_line_pointer
;
429 /* Delete spaces from s: X ( r 1 2) => X(r12). */
432 del_spaces (char * s
)
440 while (ISSPACE (*m
) && *m
)
442 memmove (s
, m
, strlen (m
) + 1);
450 skip_space (char * s
)
457 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
460 extract_operand (char * from
, char * to
, int limit
)
464 /* Drop leading whitespace. */
465 from
= skip_space (from
);
467 while (size
< limit
&& *from
)
469 *(to
+ size
) = *from
;
470 if (*from
== ',' || *from
== ';' || *from
== '\n')
485 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
502 s
= input_line_pointer
;
503 end
= input_line_pointer
;
505 while (*end
&& *end
!= '\n')
508 while (*s
&& *s
!= '\n')
519 as_bad (_(".profiler pseudo requires at least two operands."));
520 input_line_pointer
= end
;
524 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
533 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
536 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
539 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
542 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
545 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
548 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
551 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
554 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
557 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
560 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
563 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
566 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
569 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
572 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
575 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
578 as_warn (_("unknown profiling flag - ignored."));
585 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
586 | MSP430_PROFILER_FLAG_EXIT
))
587 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
588 | MSP430_PROFILER_FLAG_PROLEND
589 | MSP430_PROFILER_FLAG_EPISTART
590 | MSP430_PROFILER_FLAG_EPIEND
))
591 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
592 | MSP430_PROFILER_FLAG_FINISECT
))))
594 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
595 input_line_pointer
= end
;
599 /* Generate temp symbol which denotes current location. */
600 if (now_seg
== absolute_section
) /* Paranoia ? */
602 exp1
.X_op
= O_constant
;
603 exp1
.X_add_number
= abs_section_offset
;
604 as_warn (_("profiling in absolute section?"));
608 exp1
.X_op
= O_symbol
;
609 exp1
.X_add_symbol
= symbol_temp_new_now ();
610 exp1
.X_add_number
= 0;
613 /* Generate a symbol which holds flags value. */
614 exp
.X_op
= O_constant
;
615 exp
.X_add_number
= p_flags
;
617 /* Save current section. */
621 /* Now go to .profiler section. */
622 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0, 0);
625 emit_expr (& exp
, 2);
627 /* Save label value. */
628 emit_expr (& exp1
, 2);
632 /* Now get profiling info. */
633 halt
= extract_operand (input_line_pointer
, str
, 1024);
634 /* Process like ".word xxx" directive. */
635 (void) parse_exp (str
, & exp
);
636 emit_expr (& exp
, 2);
637 input_line_pointer
= halt
;
640 /* Fill the rest with zeros. */
641 exp
.X_op
= O_constant
;
642 exp
.X_add_number
= 0;
644 emit_expr (& exp
, 2);
646 /* Return to current section. */
647 subseg_set (seg
, subseg
);
651 extract_word (char * from
, char * to
, int limit
)
656 /* Drop leading whitespace. */
657 from
= skip_space (from
);
660 /* Find the op code end. */
661 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
663 to
[size
++] = *op_end
++;
664 if (size
+ 1 >= limit
)
672 #define OPTION_MMCU 'm'
673 #define OPTION_RELAX 'Q'
674 #define OPTION_POLYMORPHS 'P'
675 #define OPTION_LARGE 'l'
676 static bfd_boolean large_model
= FALSE
;
677 #define OPTION_NO_INTR_NOPS 'N'
678 #define OPTION_INTR_NOPS 'n'
679 static bfd_boolean gen_interrupt_nops
= FALSE
;
680 #define OPTION_WARN_INTR_NOPS 'y'
681 #define OPTION_NO_WARN_INTR_NOPS 'Y'
682 static bfd_boolean warn_interrupt_nops
= TRUE
;
683 #define OPTION_UNKNOWN_INTR_NOPS 'u'
684 #define OPTION_NO_UNKNOWN_INTR_NOPS 'U'
685 static bfd_boolean do_unknown_interrupt_nops
= TRUE
;
686 #define OPTION_MCPU 'c'
687 #define OPTION_MOVE_DATA 'd'
688 static bfd_boolean move_data
= FALSE
;
689 #define OPTION_DATA_REGION 'r'
690 static bfd_boolean upper_data_region_in_use
= FALSE
;
694 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
695 OPTION_SILICON_ERRATA_WARN
,
698 static unsigned int silicon_errata_fix
= 0;
699 static unsigned int silicon_errata_warn
= 0;
700 #define SILICON_ERRATA_CPU4 (1 << 0)
701 #define SILICON_ERRATA_CPU8 (1 << 1)
702 #define SILICON_ERRATA_CPU11 (1 << 2)
703 #define SILICON_ERRATA_CPU12 (1 << 3)
704 #define SILICON_ERRATA_CPU13 (1 << 4)
705 #define SILICON_ERRATA_CPU19 (1 << 5)
708 msp430_set_arch (int option
)
710 char str
[32]; /* 32 for good measure. */
712 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
714 md_parse_option (option
, str
);
715 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
716 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
719 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
720 Keep these two structures in sync.
721 The data in this structure has been extracted from version 1.194 of the
722 devices.csv file released by TI in September 2016. */
724 struct msp430_mcu_data
727 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
728 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
732 { "cc430f5123",2,8 },
733 { "cc430f5125",2,8 },
734 { "cc430f5133",2,8 },
735 { "cc430f5135",2,8 },
736 { "cc430f5137",2,8 },
737 { "cc430f5143",2,8 },
738 { "cc430f5145",2,8 },
739 { "cc430f5147",2,8 },
740 { "cc430f6125",2,8 },
741 { "cc430f6126",2,8 },
742 { "cc430f6127",2,8 },
743 { "cc430f6135",2,8 },
744 { "cc430f6137",2,8 },
745 { "cc430f6143",2,8 },
746 { "cc430f6145",2,8 },
747 { "cc430f6147",2,8 },
748 { "msp430afe221",0,2 },
749 { "msp430afe222",0,2 },
750 { "msp430afe223",0,2 },
751 { "msp430afe231",0,2 },
752 { "msp430afe232",0,2 },
753 { "msp430afe233",0,2 },
754 { "msp430afe251",0,2 },
755 { "msp430afe252",0,2 },
756 { "msp430afe253",0,2 },
757 { "msp430bt5190",2,8 },
758 { "msp430c091",0,0 },
759 { "msp430c092",0,0 },
760 { "msp430c111",0,0 },
761 { "msp430c1111",0,0 },
762 { "msp430c112",0,0 },
763 { "msp430c1121",0,0 },
764 { "msp430c1331",0,0 },
765 { "msp430c1351",0,0 },
766 { "msp430c311s",0,0 },
767 { "msp430c312",0,0 },
768 { "msp430c313",0,0 },
769 { "msp430c314",0,0 },
770 { "msp430c315",0,0 },
771 { "msp430c323",0,0 },
772 { "msp430c325",0,0 },
773 { "msp430c336",0,1 },
774 { "msp430c337",0,1 },
775 { "msp430c412",0,0 },
776 { "msp430c413",0,0 },
777 { "msp430cg4616",1,1 },
778 { "msp430cg4617",1,1 },
779 { "msp430cg4618",1,1 },
780 { "msp430cg4619",1,1 },
781 { "msp430e112",0,0 },
782 { "msp430e313",0,0 },
783 { "msp430e315",0,0 },
784 { "msp430e325",0,0 },
785 { "msp430e337",0,1 },
786 { "msp430f110",0,0 },
787 { "msp430f1101",0,0 },
788 { "msp430f1101a",0,0 },
789 { "msp430f1111",0,0 },
790 { "msp430f1111a",0,0 },
791 { "msp430f112",0,0 },
792 { "msp430f1121",0,0 },
793 { "msp430f1121a",0,0 },
794 { "msp430f1122",0,0 },
795 { "msp430f1132",0,0 },
796 { "msp430f122",0,0 },
797 { "msp430f1222",0,0 },
798 { "msp430f123",0,0 },
799 { "msp430f1232",0,0 },
800 { "msp430f133",0,0 },
801 { "msp430f135",0,0 },
802 { "msp430f147",0,1 },
803 { "msp430f1471",0,1 },
804 { "msp430f148",0,1 },
805 { "msp430f1481",0,1 },
806 { "msp430f149",0,1 },
807 { "msp430f1491",0,1 },
808 { "msp430f155",0,0 },
809 { "msp430f156",0,0 },
810 { "msp430f157",0,0 },
811 { "msp430f1610",0,1 },
812 { "msp430f1611",0,1 },
813 { "msp430f1612",0,1 },
814 { "msp430f167",0,1 },
815 { "msp430f168",0,1 },
816 { "msp430f169",0,1 },
817 { "msp430f2001",0,0 },
818 { "msp430f2002",0,0 },
819 { "msp430f2003",0,0 },
820 { "msp430f2011",0,0 },
821 { "msp430f2012",0,0 },
822 { "msp430f2013",0,0 },
823 { "msp430f2101",0,0 },
824 { "msp430f2111",0,0 },
825 { "msp430f2112",0,0 },
826 { "msp430f2121",0,0 },
827 { "msp430f2122",0,0 },
828 { "msp430f2131",0,0 },
829 { "msp430f2132",0,0 },
830 { "msp430f2232",0,0 },
831 { "msp430f2234",0,0 },
832 { "msp430f2252",0,0 },
833 { "msp430f2254",0,0 },
834 { "msp430f2272",0,0 },
835 { "msp430f2274",0,0 },
836 { "msp430f233",0,2 },
837 { "msp430f2330",0,2 },
838 { "msp430f235",0,2 },
839 { "msp430f2350",0,2 },
840 { "msp430f2370",0,2 },
841 { "msp430f2410",0,2 },
842 { "msp430f2416",1,2 },
843 { "msp430f2417",1,2 },
844 { "msp430f2418",1,2 },
845 { "msp430f2419",1,2 },
846 { "msp430f247",0,2 },
847 { "msp430f2471",0,2 },
848 { "msp430f248",0,2 },
849 { "msp430f2481",0,2 },
850 { "msp430f249",0,2 },
851 { "msp430f2491",0,2 },
852 { "msp430f2616",1,2 },
853 { "msp430f2617",1,2 },
854 { "msp430f2618",1,2 },
855 { "msp430f2619",1,2 },
856 { "msp430f412",0,0 },
857 { "msp430f413",0,0 },
858 { "msp430f4132",0,0 },
859 { "msp430f415",0,0 },
860 { "msp430f4152",0,0 },
861 { "msp430f417",0,0 },
862 { "msp430f423",0,1 },
863 { "msp430f423a",0,1 },
864 { "msp430f425",0,1 },
865 { "msp430f4250",0,0 },
866 { "msp430f425a",0,1 },
867 { "msp430f4260",0,0 },
868 { "msp430f427",0,1 },
869 { "msp430f4270",0,0 },
870 { "msp430f427a",0,1 },
871 { "msp430f435",0,0 },
872 { "msp430f4351",0,0 },
873 { "msp430f436",0,0 },
874 { "msp430f4361",0,0 },
875 { "msp430f437",0,0 },
876 { "msp430f4371",0,0 },
877 { "msp430f438",0,0 },
878 { "msp430f439",0,0 },
879 { "msp430f447",0,1 },
880 { "msp430f448",0,1 },
881 { "msp430f4481",0,1 },
882 { "msp430f449",0,1 },
883 { "msp430f4491",0,1 },
884 { "msp430f4616",1,1 },
885 { "msp430f46161",1,1 },
886 { "msp430f4617",1,1 },
887 { "msp430f46171",1,1 },
888 { "msp430f4618",1,1 },
889 { "msp430f46181",1,1 },
890 { "msp430f4619",1,1 },
891 { "msp430f46191",1,1 },
892 { "msp430f47126",1,4 },
893 { "msp430f47127",1,4 },
894 { "msp430f47163",1,4 },
895 { "msp430f47166",1,4 },
896 { "msp430f47167",1,4 },
897 { "msp430f47173",1,4 },
898 { "msp430f47176",1,4 },
899 { "msp430f47177",1,4 },
900 { "msp430f47183",1,4 },
901 { "msp430f47186",1,4 },
902 { "msp430f47187",1,4 },
903 { "msp430f47193",1,4 },
904 { "msp430f47196",1,4 },
905 { "msp430f47197",1,4 },
906 { "msp430f477",0,0 },
907 { "msp430f478",0,0 },
908 { "msp430f4783",0,4 },
909 { "msp430f4784",0,4 },
910 { "msp430f479",0,0 },
911 { "msp430f4793",0,4 },
912 { "msp430f4794",0,4 },
913 { "msp430f5131",2,8 },
914 { "msp430f5132",2,8 },
915 { "msp430f5151",2,8 },
916 { "msp430f5152",2,8 },
917 { "msp430f5171",2,8 },
918 { "msp430f5172",2,8 },
919 { "msp430f5212",2,8 },
920 { "msp430f5213",2,8 },
921 { "msp430f5214",2,8 },
922 { "msp430f5217",2,8 },
923 { "msp430f5218",2,8 },
924 { "msp430f5219",2,8 },
925 { "msp430f5222",2,8 },
926 { "msp430f5223",2,8 },
927 { "msp430f5224",2,8 },
928 { "msp430f5227",2,8 },
929 { "msp430f5228",2,8 },
930 { "msp430f5229",2,8 },
931 { "msp430f5232",2,8 },
932 { "msp430f5234",2,8 },
933 { "msp430f5237",2,8 },
934 { "msp430f5239",2,8 },
935 { "msp430f5242",2,8 },
936 { "msp430f5244",2,8 },
937 { "msp430f5247",2,8 },
938 { "msp430f5249",2,8 },
939 { "msp430f5252",2,8 },
940 { "msp430f5253",2,8 },
941 { "msp430f5254",2,8 },
942 { "msp430f5255",2,8 },
943 { "msp430f5256",2,8 },
944 { "msp430f5257",2,8 },
945 { "msp430f5258",2,8 },
946 { "msp430f5259",2,8 },
947 { "msp430f5304",2,8 },
948 { "msp430f5308",2,8 },
949 { "msp430f5309",2,8 },
950 { "msp430f5310",2,8 },
951 { "msp430f5324",2,8 },
952 { "msp430f5325",2,8 },
953 { "msp430f5326",2,8 },
954 { "msp430f5327",2,8 },
955 { "msp430f5328",2,8 },
956 { "msp430f5329",2,8 },
957 { "msp430f5333",2,8 },
958 { "msp430f5335",2,8 },
959 { "msp430f5336",2,8 },
960 { "msp430f5338",2,8 },
961 { "msp430f5340",2,8 },
962 { "msp430f5341",2,8 },
963 { "msp430f5342",2,8 },
964 { "msp430f5358",2,8 },
965 { "msp430f5359",2,8 },
966 { "msp430f5418",2,8 },
967 { "msp430f5418a",2,8 },
968 { "msp430f5419",2,8 },
969 { "msp430f5419a",2,8 },
970 { "msp430f5435",2,8 },
971 { "msp430f5435a",2,8 },
972 { "msp430f5436",2,8 },
973 { "msp430f5436a",2,8 },
974 { "msp430f5437",2,8 },
975 { "msp430f5437a",2,8 },
976 { "msp430f5438",2,8 },
977 { "msp430f5438a",2,8 },
978 { "msp430f5500",2,8 },
979 { "msp430f5501",2,8 },
980 { "msp430f5502",2,8 },
981 { "msp430f5503",2,8 },
982 { "msp430f5504",2,8 },
983 { "msp430f5505",2,8 },
984 { "msp430f5506",2,8 },
985 { "msp430f5507",2,8 },
986 { "msp430f5508",2,8 },
987 { "msp430f5509",2,8 },
988 { "msp430f5510",2,8 },
989 { "msp430f5513",2,8 },
990 { "msp430f5514",2,8 },
991 { "msp430f5515",2,8 },
992 { "msp430f5517",2,8 },
993 { "msp430f5519",2,8 },
994 { "msp430f5521",2,8 },
995 { "msp430f5522",2,8 },
996 { "msp430f5524",2,8 },
997 { "msp430f5525",2,8 },
998 { "msp430f5526",2,8 },
999 { "msp430f5527",2,8 },
1000 { "msp430f5528",2,8 },
1001 { "msp430f5529",2,8 },
1002 { "msp430f5630",2,8 },
1003 { "msp430f5631",2,8 },
1004 { "msp430f5632",2,8 },
1005 { "msp430f5633",2,8 },
1006 { "msp430f5634",2,8 },
1007 { "msp430f5635",2,8 },
1008 { "msp430f5636",2,8 },
1009 { "msp430f5637",2,8 },
1010 { "msp430f5638",2,8 },
1011 { "msp430f5658",2,8 },
1012 { "msp430f5659",2,8 },
1013 { "msp430f5xx_6xxgeneric",2,8 },
1014 { "msp430f6433",2,8 },
1015 { "msp430f6435",2,8 },
1016 { "msp430f6436",2,8 },
1017 { "msp430f6438",2,8 },
1018 { "msp430f6458",2,8 },
1019 { "msp430f6459",2,8 },
1020 { "msp430f6630",2,8 },
1021 { "msp430f6631",2,8 },
1022 { "msp430f6632",2,8 },
1023 { "msp430f6633",2,8 },
1024 { "msp430f6634",2,8 },
1025 { "msp430f6635",2,8 },
1026 { "msp430f6636",2,8 },
1027 { "msp430f6637",2,8 },
1028 { "msp430f6638",2,8 },
1029 { "msp430f6658",2,8 },
1030 { "msp430f6659",2,8 },
1031 { "msp430f6720",2,8 },
1032 { "msp430f6720a",2,8 },
1033 { "msp430f6721",2,8 },
1034 { "msp430f6721a",2,8 },
1035 { "msp430f6723",2,8 },
1036 { "msp430f6723a",2,8 },
1037 { "msp430f6724",2,8 },
1038 { "msp430f6724a",2,8 },
1039 { "msp430f6725",2,8 },
1040 { "msp430f6725a",2,8 },
1041 { "msp430f6726",2,8 },
1042 { "msp430f6726a",2,8 },
1043 { "msp430f6730",2,8 },
1044 { "msp430f6730a",2,8 },
1045 { "msp430f6731",2,8 },
1046 { "msp430f6731a",2,8 },
1047 { "msp430f6733",2,8 },
1048 { "msp430f6733a",2,8 },
1049 { "msp430f6734",2,8 },
1050 { "msp430f6734a",2,8 },
1051 { "msp430f6735",2,8 },
1052 { "msp430f6735a",2,8 },
1053 { "msp430f6736",2,8 },
1054 { "msp430f6736a",2,8 },
1055 { "msp430f6745",2,8 },
1056 { "msp430f67451",2,8 },
1057 { "msp430f67451a",2,8 },
1058 { "msp430f6745a",2,8 },
1059 { "msp430f6746",2,8 },
1060 { "msp430f67461",2,8 },
1061 { "msp430f67461a",2,8 },
1062 { "msp430f6746a",2,8 },
1063 { "msp430f6747",2,8 },
1064 { "msp430f67471",2,8 },
1065 { "msp430f67471a",2,8 },
1066 { "msp430f6747a",2,8 },
1067 { "msp430f6748",2,8 },
1068 { "msp430f67481",2,8 },
1069 { "msp430f67481a",2,8 },
1070 { "msp430f6748a",2,8 },
1071 { "msp430f6749",2,8 },
1072 { "msp430f67491",2,8 },
1073 { "msp430f67491a",2,8 },
1074 { "msp430f6749a",2,8 },
1075 { "msp430f67621",2,8 },
1076 { "msp430f67621a",2,8 },
1077 { "msp430f67641",2,8 },
1078 { "msp430f67641a",2,8 },
1079 { "msp430f6765",2,8 },
1080 { "msp430f67651",2,8 },
1081 { "msp430f67651a",2,8 },
1082 { "msp430f6765a",2,8 },
1083 { "msp430f6766",2,8 },
1084 { "msp430f67661",2,8 },
1085 { "msp430f67661a",2,8 },
1086 { "msp430f6766a",2,8 },
1087 { "msp430f6767",2,8 },
1088 { "msp430f67671",2,8 },
1089 { "msp430f67671a",2,8 },
1090 { "msp430f6767a",2,8 },
1091 { "msp430f6768",2,8 },
1092 { "msp430f67681",2,8 },
1093 { "msp430f67681a",2,8 },
1094 { "msp430f6768a",2,8 },
1095 { "msp430f6769",2,8 },
1096 { "msp430f67691",2,8 },
1097 { "msp430f67691a",2,8 },
1098 { "msp430f6769a",2,8 },
1099 { "msp430f6775",2,8 },
1100 { "msp430f67751",2,8 },
1101 { "msp430f67751a",2,8 },
1102 { "msp430f6775a",2,8 },
1103 { "msp430f6776",2,8 },
1104 { "msp430f67761",2,8 },
1105 { "msp430f67761a",2,8 },
1106 { "msp430f6776a",2,8 },
1107 { "msp430f6777",2,8 },
1108 { "msp430f67771",2,8 },
1109 { "msp430f67771a",2,8 },
1110 { "msp430f6777a",2,8 },
1111 { "msp430f6778",2,8 },
1112 { "msp430f67781",2,8 },
1113 { "msp430f67781a",2,8 },
1114 { "msp430f6778a",2,8 },
1115 { "msp430f6779",2,8 },
1116 { "msp430f67791",2,8 },
1117 { "msp430f67791a",2,8 },
1118 { "msp430f6779a",2,8 },
1119 { "msp430fe423",0,0 },
1120 { "msp430fe4232",0,0 },
1121 { "msp430fe423a",0,0 },
1122 { "msp430fe4242",0,0 },
1123 { "msp430fe425",0,0 },
1124 { "msp430fe4252",0,0 },
1125 { "msp430fe425a",0,0 },
1126 { "msp430fe427",0,0 },
1127 { "msp430fe4272",0,0 },
1128 { "msp430fe427a",0,0 },
1129 { "msp430fg4250",0,0 },
1130 { "msp430fg4260",0,0 },
1131 { "msp430fg4270",0,0 },
1132 { "msp430fg437",0,0 },
1133 { "msp430fg438",0,0 },
1134 { "msp430fg439",0,0 },
1135 { "msp430fg4616",1,1 },
1136 { "msp430fg4617",1,1 },
1137 { "msp430fg4618",1,1 },
1138 { "msp430fg4619",1,1 },
1139 { "msp430fg477",0,0 },
1140 { "msp430fg478",0,0 },
1141 { "msp430fg479",0,0 },
1142 { "msp430fg6425",2,8 },
1143 { "msp430fg6426",2,8 },
1144 { "msp430fg6625",2,8 },
1145 { "msp430fg6626",2,8 },
1146 { "msp430fr2032",2,0 },
1147 { "msp430fr2033",2,0 },
1148 { "msp430fr2110",2,0 },
1149 { "msp430fr2111",2,0 },
1150 { "msp430fr2310",2,0 },
1151 { "msp430fr2311",2,0 },
1152 { "msp430fr2433",2,8 },
1153 { "msp430fr2532",2,8 },
1154 { "msp430fr2533",2,8 },
1155 { "msp430fr2632",2,8 },
1156 { "msp430fr2633",2,8 },
1157 { "msp430fr2xx_4xxgeneric",2,8 },
1158 { "msp430fr4131",2,0 },
1159 { "msp430fr4132",2,0 },
1160 { "msp430fr4133",2,0 },
1161 { "msp430fr5720",2,8 },
1162 { "msp430fr5721",2,8 },
1163 { "msp430fr5722",2,8 },
1164 { "msp430fr5723",2,8 },
1165 { "msp430fr5724",2,8 },
1166 { "msp430fr5725",2,8 },
1167 { "msp430fr5726",2,8 },
1168 { "msp430fr5727",2,8 },
1169 { "msp430fr5728",2,8 },
1170 { "msp430fr5729",2,8 },
1171 { "msp430fr5730",2,8 },
1172 { "msp430fr5731",2,8 },
1173 { "msp430fr5732",2,8 },
1174 { "msp430fr5733",2,8 },
1175 { "msp430fr5734",2,8 },
1176 { "msp430fr5735",2,8 },
1177 { "msp430fr5736",2,8 },
1178 { "msp430fr5737",2,8 },
1179 { "msp430fr5738",2,8 },
1180 { "msp430fr5739",2,8 },
1181 { "msp430fr57xxgeneric",2,8 },
1182 { "msp430fr5847",2,8 },
1183 { "msp430fr58471",2,8 },
1184 { "msp430fr5848",2,8 },
1185 { "msp430fr5849",2,8 },
1186 { "msp430fr5857",2,8 },
1187 { "msp430fr5858",2,8 },
1188 { "msp430fr5859",2,8 },
1189 { "msp430fr5867",2,8 },
1190 { "msp430fr58671",2,8 },
1191 { "msp430fr5868",2,8 },
1192 { "msp430fr5869",2,8 },
1193 { "msp430fr5870",2,8 },
1194 { "msp430fr5872",2,8 },
1195 { "msp430fr58721",2,8 },
1196 { "msp430fr5887",2,8 },
1197 { "msp430fr5888",2,8 },
1198 { "msp430fr5889",2,8 },
1199 { "msp430fr58891",2,8 },
1200 { "msp430fr5922",2,8 },
1201 { "msp430fr59221",2,8 },
1202 { "msp430fr5947",2,8 },
1203 { "msp430fr59471",2,8 },
1204 { "msp430fr5948",2,8 },
1205 { "msp430fr5949",2,8 },
1206 { "msp430fr5957",2,8 },
1207 { "msp430fr5958",2,8 },
1208 { "msp430fr5959",2,8 },
1209 { "msp430fr5962",2,8 },
1210 { "msp430fr5964",2,8 },
1211 { "msp430fr5967",2,8 },
1212 { "msp430fr5968",2,8 },
1213 { "msp430fr5969",2,8 },
1214 { "msp430fr59691",2,8 },
1215 { "msp430fr5970",2,8 },
1216 { "msp430fr5972",2,8 },
1217 { "msp430fr59721",2,8 },
1218 { "msp430fr5986",2,8 },
1219 { "msp430fr5987",2,8 },
1220 { "msp430fr5988",2,8 },
1221 { "msp430fr5989",2,8 },
1222 { "msp430fr59891",2,8 },
1223 { "msp430fr5992",2,8 },
1224 { "msp430fr5994",2,8 },
1225 { "msp430fr59941",2,8 },
1226 { "msp430fr5xx_6xxgeneric",2,8 },
1227 { "msp430fr6820",2,8 },
1228 { "msp430fr6822",2,8 },
1229 { "msp430fr68221",2,8 },
1230 { "msp430fr6870",2,8 },
1231 { "msp430fr6872",2,8 },
1232 { "msp430fr68721",2,8 },
1233 { "msp430fr6877",2,8 },
1234 { "msp430fr6879",2,8 },
1235 { "msp430fr68791",2,8 },
1236 { "msp430fr6887",2,8 },
1237 { "msp430fr6888",2,8 },
1238 { "msp430fr6889",2,8 },
1239 { "msp430fr68891",2,8 },
1240 { "msp430fr6920",2,8 },
1241 { "msp430fr6922",2,8 },
1242 { "msp430fr69221",2,8 },
1243 { "msp430fr6927",2,8 },
1244 { "msp430fr69271",2,8 },
1245 { "msp430fr6928",2,8 },
1246 { "msp430fr6970",2,8 },
1247 { "msp430fr6972",2,8 },
1248 { "msp430fr69721",2,8 },
1249 { "msp430fr6977",2,8 },
1250 { "msp430fr6979",2,8 },
1251 { "msp430fr69791",2,8 },
1252 { "msp430fr6987",2,8 },
1253 { "msp430fr6988",2,8 },
1254 { "msp430fr6989",2,8 },
1255 { "msp430fr69891",2,8 },
1256 { "msp430fw423",0,0 },
1257 { "msp430fw425",0,0 },
1258 { "msp430fw427",0,0 },
1259 { "msp430fw428",0,0 },
1260 { "msp430fw429",0,0 },
1261 { "msp430g2001",0,0 },
1262 { "msp430g2101",0,0 },
1263 { "msp430g2102",0,0 },
1264 { "msp430g2111",0,0 },
1265 { "msp430g2112",0,0 },
1266 { "msp430g2113",0,0 },
1267 { "msp430g2121",0,0 },
1268 { "msp430g2131",0,0 },
1269 { "msp430g2132",0,0 },
1270 { "msp430g2152",0,0 },
1271 { "msp430g2153",0,0 },
1272 { "msp430g2201",0,0 },
1273 { "msp430g2202",0,0 },
1274 { "msp430g2203",0,0 },
1275 { "msp430g2210",0,0 },
1276 { "msp430g2211",0,0 },
1277 { "msp430g2212",0,0 },
1278 { "msp430g2213",0,0 },
1279 { "msp430g2221",0,0 },
1280 { "msp430g2230",0,0 },
1281 { "msp430g2231",0,0 },
1282 { "msp430g2232",0,0 },
1283 { "msp430g2233",0,0 },
1284 { "msp430g2252",0,0 },
1285 { "msp430g2253",0,0 },
1286 { "msp430g2302",0,0 },
1287 { "msp430g2303",0,0 },
1288 { "msp430g2312",0,0 },
1289 { "msp430g2313",0,0 },
1290 { "msp430g2332",0,0 },
1291 { "msp430g2333",0,0 },
1292 { "msp430g2352",0,0 },
1293 { "msp430g2353",0,0 },
1294 { "msp430g2402",0,0 },
1295 { "msp430g2403",0,0 },
1296 { "msp430g2412",0,0 },
1297 { "msp430g2413",0,0 },
1298 { "msp430g2432",0,0 },
1299 { "msp430g2433",0,0 },
1300 { "msp430g2444",0,0 },
1301 { "msp430g2452",0,0 },
1302 { "msp430g2453",0,0 },
1303 { "msp430g2513",0,0 },
1304 { "msp430g2533",0,0 },
1305 { "msp430g2544",0,0 },
1306 { "msp430g2553",0,0 },
1307 { "msp430g2744",0,0 },
1308 { "msp430g2755",0,0 },
1309 { "msp430g2855",0,0 },
1310 { "msp430g2955",0,0 },
1311 { "msp430i2020",0,2 },
1312 { "msp430i2021",0,2 },
1313 { "msp430i2030",0,2 },
1314 { "msp430i2031",0,2 },
1315 { "msp430i2040",0,2 },
1316 { "msp430i2041",0,2 },
1317 { "msp430i2xxgeneric",0,2 },
1318 { "msp430l092",0,0 },
1319 { "msp430p112",0,0 },
1320 { "msp430p313",0,0 },
1321 { "msp430p315",0,0 },
1322 { "msp430p315s",0,0 },
1323 { "msp430p325",0,0 },
1324 { "msp430p337",0,1 },
1325 { "msp430sl5438a",2,8 },
1326 { "msp430tch5e",0,0 },
1327 { "msp430xgeneric",2,8 },
1328 { "rf430f5144",2,8 },
1329 { "rf430f5155",2,8 },
1330 { "rf430f5175",2,8 },
1331 { "rf430frl152h",0,0 },
1332 { "rf430frl152h_rom",0,0 },
1333 { "rf430frl153h",0,0 },
1334 { "rf430frl153h_rom",0,0 },
1335 { "rf430frl154h",0,0 },
1336 { "rf430frl154h_rom",0,0 }
1340 md_parse_option (int c
, const char * arg
)
1344 case OPTION_SILICON_ERRATA
:
1345 case OPTION_SILICON_ERRATA_WARN
:
1351 unsigned int length
;
1352 unsigned int bitfield
;
1355 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1356 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1357 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1358 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1359 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1360 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1365 for (i
= ARRAY_SIZE (erratas
); i
--;)
1366 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1368 if (c
== OPTION_SILICON_ERRATA
)
1369 silicon_errata_fix
|= erratas
[i
].bitfield
;
1371 silicon_errata_warn
|= erratas
[i
].bitfield
;
1372 arg
+= erratas
[i
].length
;
1377 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1383 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1393 as_fatal (_("MCU option requires a name\n"));
1395 if (strcasecmp ("msp430", arg
) == 0)
1396 selected_isa
= MSP_ISA_430
;
1397 else if (strcasecmp ("msp430xv2", arg
) == 0)
1398 selected_isa
= MSP_ISA_430Xv2
;
1399 else if (strcasecmp ("msp430x", arg
) == 0)
1400 selected_isa
= MSP_ISA_430X
;
1405 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1406 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1408 switch (msp430_mcu_data
[i
].revision
)
1410 case 0: selected_isa
= MSP_ISA_430
; break;
1411 case 1: selected_isa
= MSP_ISA_430X
; break;
1412 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1417 /* It is not an error if we do not match the MCU name. */
1421 if (strcmp (arg
, "430") == 0
1422 || strcasecmp (arg
, "msp430") == 0)
1423 selected_isa
= MSP_ISA_430
;
1424 else if (strcasecmp (arg
, "430x") == 0
1425 || strcasecmp (arg
, "msp430x") == 0)
1426 selected_isa
= MSP_ISA_430X
;
1427 else if (strcasecmp (arg
, "430xv2") == 0
1428 || strcasecmp (arg
, "msp430xv2") == 0)
1429 selected_isa
= MSP_ISA_430Xv2
;
1431 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1435 msp430_enable_relax
= 1;
1438 case OPTION_POLYMORPHS
:
1439 msp430_enable_polys
= 1;
1446 case OPTION_NO_INTR_NOPS
:
1447 gen_interrupt_nops
= FALSE
;
1449 case OPTION_INTR_NOPS
:
1450 gen_interrupt_nops
= TRUE
;
1453 case OPTION_WARN_INTR_NOPS
:
1454 warn_interrupt_nops
= TRUE
;
1456 case OPTION_NO_WARN_INTR_NOPS
:
1457 warn_interrupt_nops
= FALSE
;
1460 case OPTION_UNKNOWN_INTR_NOPS
:
1461 do_unknown_interrupt_nops
= TRUE
;
1463 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1464 do_unknown_interrupt_nops
= FALSE
;
1467 case OPTION_MOVE_DATA
:
1471 case OPTION_DATA_REGION
:
1472 if (strcmp (arg
, "upper") == 0
1473 || strcmp (arg
, "either") == 0)
1474 upper_data_region_in_use
= TRUE
;
1481 /* The intention here is to have the mere presence of these sections
1482 cause the object to have a reference to a well-known symbol. This
1483 reference pulls in the bits of the runtime (crt0) that initialize
1484 these sections. Thus, for example, the startup code to call
1485 memset() to initialize .bss will only be linked in when there is a
1486 non-empty .bss section. Otherwise, the call would exist but have a
1487 zero length parameter, which is a waste of memory and cycles.
1489 The code which initializes these sections should have a global
1490 label for these symbols, and should be marked with KEEP() in the
1494 msp430_make_init_symbols (const char * name
)
1496 if (strncmp (name
, ".bss", 4) == 0
1497 || strncmp (name
, ".lower.bss", 10) == 0
1498 || strncmp (name
, ".either.bss", 11) == 0
1499 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1500 (void) symbol_find_or_make ("__crt0_init_bss");
1502 if (strncmp (name
, ".data", 5) == 0
1503 || strncmp (name
, ".lower.data", 11) == 0
1504 || strncmp (name
, ".either.data", 12) == 0
1505 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1506 (void) symbol_find_or_make ("__crt0_movedata");
1507 /* Note - data assigned to the .either.data section may end up being
1508 placed in the .upper.data section if the .lower.data section is
1509 full. Hence the need to define the crt0 symbol.
1510 The linker may create upper or either data sections, even when none exist
1511 at the moment, so use the value of the data-region flag to determine if
1512 the symbol is needed. */
1513 if (strncmp (name
, ".either.data", 12) == 0
1514 || strncmp (name
, ".upper.data", 11) == 0
1515 || upper_data_region_in_use
)
1516 (void) symbol_find_or_make ("__crt0_move_highdata");
1518 /* See note about .either.data above. */
1519 if (strncmp (name
, ".upper.bss", 10) == 0
1520 || strncmp (name
, ".either.bss", 11) == 0
1521 || upper_data_region_in_use
)
1522 (void) symbol_find_or_make ("__crt0_init_highbss");
1526 msp430_section (int arg
)
1528 char * saved_ilp
= input_line_pointer
;
1529 const char * name
= obj_elf_section_name ();
1531 msp430_make_init_symbols (name
);
1533 input_line_pointer
= saved_ilp
;
1534 obj_elf_section (arg
);
1538 msp430_frob_section (asection
*sec
)
1540 const char *name
= sec
->name
;
1545 msp430_make_init_symbols (name
);
1549 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1551 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1554 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1555 (void) symbol_find_or_make ("__crt0_init_bss");
1559 msp430_comm (int needs_align
)
1561 s_comm_internal (needs_align
, elf_common_parse
);
1562 (void) symbol_find_or_make ("__crt0_init_bss");
1566 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1568 char sym_name
[1024];
1569 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1571 (void) symbol_find_or_make (sym_name
);
1574 const pseudo_typeS md_pseudo_table
[] =
1576 {"arch", msp430_set_arch
, OPTION_MMCU
},
1577 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1578 {"profiler", msp430_profiler
, 0},
1579 {"section", msp430_section
, 0},
1580 {"section.s", msp430_section
, 0},
1581 {"sect", msp430_section
, 0},
1582 {"sect.s", msp430_section
, 0},
1583 {"pushsection", msp430_section
, 1},
1584 {"refsym", msp430_refsym
, 0},
1585 {"comm", msp430_comm
, 0},
1586 {"lcomm", msp430_lcomm
, 0},
1590 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1592 struct option md_longopts
[] =
1594 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1595 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1596 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1597 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1598 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1599 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1600 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1601 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1602 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1603 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1604 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1605 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1606 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1607 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1608 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1609 {NULL
, no_argument
, NULL
, 0}
1612 size_t md_longopts_size
= sizeof (md_longopts
);
1615 md_show_usage (FILE * stream
)
1618 _("MSP430 options:\n"
1619 " -mmcu=<msp430-name> - select microcontroller type\n"
1620 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1622 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1623 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1624 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1626 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1627 " -mP - enable polymorph instructions\n"));
1629 _(" -ml - enable large code model\n"));
1631 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1633 _(" -mn - insert a NOP after changing interrupts\n"));
1635 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1637 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1639 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1640 " known how the state is changed, do not warn/insert NOPs\n"));
1642 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1643 " known how the state is changed, warn/insert NOPs (default)\n"
1644 " -mn and/or -my are required for this to have any effect\n"));
1646 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1648 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1653 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1659 extract_cmd (char * from
, char * to
, int limit
)
1663 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1665 *(to
+ size
) = *from
;
1676 md_atof (int type
, char * litP
, int * sizeP
)
1678 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1684 struct msp430_opcode_s
* opcode
;
1685 msp430_hash
= hash_new ();
1687 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1688 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1690 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1691 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1693 /* Set linkrelax here to avoid fixups in most sections. */
1697 static inline bfd_boolean
1698 is_regname_end (char c
)
1700 return (c
== 0 || ! ISALNUM (c
));
1703 /* Returns the register number equivalent to the string T.
1704 Returns -1 if there is no such register.
1705 Skips a leading 'r' or 'R' character if there is one.
1706 Handles the register aliases PC and SP. */
1709 check_reg (char * t
)
1712 signed long int val
;
1714 if (t
== NULL
|| t
[0] == 0)
1717 if (*t
== 'r' || *t
== 'R')
1720 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1723 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1726 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1729 if (*t
== '0' && is_regname_end (t
[1]))
1732 val
= strtol (t
, & endt
, 0);
1734 if (val
< 1 || val
> 15)
1737 if (is_regname_end (*endt
))
1744 msp430_srcoperand (struct msp430_operand_s
* op
,
1747 bfd_boolean
* imm_op
,
1748 bfd_boolean allow_20bit_values
,
1749 bfd_boolean constants_allowed
)
1754 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1761 /* Check if there is:
1762 llo(x) - least significant 16 bits, x &= 0xffff
1763 lhi(x) - x = (x >> 16) & 0xffff,
1764 hlo(x) - x = (x >> 32) & 0xffff,
1765 hhi(x) - x = (x >> 48) & 0xffff
1766 The value _MUST_ be constant expression: #hlo(1231231231). */
1770 if (strncasecmp (h
, "#llo(", 5) == 0)
1775 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1780 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1785 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1790 else if (strncasecmp (h
, "#lo(", 4) == 0)
1795 else if (strncasecmp (h
, "#hi(", 4) == 0)
1801 op
->reg
= 0; /* Reg PC. */
1803 op
->ol
= 1; /* Immediate will follow an instruction. */
1804 __tl
= h
+ 1 + rval
;
1806 op
->vshift
= vshift
;
1808 end
= parse_exp (__tl
, &(op
->exp
));
1809 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1811 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1814 if (op
->exp
.X_op
== O_constant
)
1816 int x
= op
->exp
.X_add_number
;
1821 op
->exp
.X_add_number
= x
;
1823 else if (vshift
== 1)
1825 x
= (x
>> 16) & 0xffff;
1826 op
->exp
.X_add_number
= x
;
1829 else if (vshift
> 1)
1832 op
->exp
.X_add_number
= -1;
1834 op
->exp
.X_add_number
= 0; /* Nothing left. */
1835 x
= op
->exp
.X_add_number
;
1839 if (allow_20bit_values
)
1841 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1843 as_bad (_("value 0x%x out of extended range."), x
);
1847 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1849 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1853 /* Now check constants. */
1854 /* Substitute register mode with a constant generator if applicable. */
1856 if (!allow_20bit_values
)
1857 x
= (short) x
; /* Extend sign. */
1859 if (! constants_allowed
)
1891 if (bin
== 0x1200 && ! target_is_430x ())
1893 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1894 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1895 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1896 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1908 if (bin
== 0x1200 && ! target_is_430x ())
1910 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1911 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1912 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1923 else if (op
->exp
.X_op
== O_symbol
)
1926 as_bad (_("error: unsupported #foo() directive used on symbol"));
1929 else if (op
->exp
.X_op
== O_big
)
1935 op
->exp
.X_op
= O_constant
;
1936 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1937 x
= op
->exp
.X_add_number
;
1943 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
1991 /* Redundant (yet) check. */
1992 else if (op
->exp
.X_op
== O_register
)
1994 (_("Registers cannot be used within immediate expression [%s]"), l
);
1996 as_bad (_("unknown operand %s"), l
);
2001 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2006 op
->reg
= 2; /* reg 2 in absolute addr mode. */
2007 op
->am
= 1; /* mode As == 01 bin. */
2008 op
->ol
= 1; /* Immediate value followed by instruction. */
2010 end
= parse_exp (__tl
, &(op
->exp
));
2011 if (end
!= NULL
&& *end
!= 0)
2013 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
2018 if (op
->exp
.X_op
== O_constant
)
2020 int x
= op
->exp
.X_add_number
;
2022 if (allow_20bit_values
)
2024 if (x
> 0xfffff || x
< -(0x7ffff))
2026 as_bad (_("value 0x%x out of extended range."), x
);
2030 else if (x
> 65535 || x
< -32768)
2032 as_bad (_("value out of range: 0x%x"), x
);
2036 else if (op
->exp
.X_op
== O_symbol
)
2040 /* Redundant (yet) check. */
2041 if (op
->exp
.X_op
== O_register
)
2043 (_("Registers cannot be used within absolute expression [%s]"), l
);
2045 as_bad (_("unknown expression in operand %s"), l
);
2051 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2055 char *m
= strchr (l
, '+');
2059 as_bad (_("unknown addressing mode %s"), l
);
2065 if ((op
->reg
= check_reg (t
)) == -1)
2067 as_bad (_("Bad register name %s"), t
);
2075 /* PC cannot be used in indirect addressing. */
2076 if (target_is_430xv2 () && op
->reg
== 0)
2078 as_bad (_("cannot use indirect addressing with the PC"));
2085 /* Check if register indexed X(Rn). */
2088 char *h
= strrchr (l
, '(');
2089 char *m
= strrchr (l
, ')');
2098 as_bad (_("')' required"));
2106 /* Extract a register. */
2107 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2110 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2117 as_bad (_("r2 should not be used in indexed addressing mode"));
2121 /* Extract constant. */
2126 end
= parse_exp (__tl
, &(op
->exp
));
2127 if (end
!= NULL
&& *end
!= 0)
2129 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2132 if (op
->exp
.X_op
== O_constant
)
2134 int x
= op
->exp
.X_add_number
;
2136 if (allow_20bit_values
)
2138 if (x
> 0xfffff || x
< - (0x7ffff))
2140 as_bad (_("value 0x%x out of extended range."), x
);
2144 else if (x
> 65535 || x
< -32768)
2146 as_bad (_("value out of range: 0x%x"), x
);
2158 if (op
->reg
== 1 && (x
& 1))
2160 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2161 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2162 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2163 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2166 else if (op
->exp
.X_op
== O_symbol
)
2170 /* Redundant (yet) check. */
2171 if (op
->exp
.X_op
== O_register
)
2173 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2175 as_bad (_("unknown expression in operand %s"), l
);
2183 /* Possibly register mode 'mov r1,r2'. */
2184 if ((op
->reg
= check_reg (l
)) != -1)
2192 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2194 op
->reg
= 0; /* PC relative... be careful. */
2195 /* An expression starting with a minus sign is a constant, not an address. */
2196 op
->am
= (*l
== '-' ? 3 : 1);
2200 end
= parse_exp (__tl
, &(op
->exp
));
2201 if (end
!= NULL
&& * end
!= 0)
2203 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2211 msp430_dstoperand (struct msp430_operand_s
* op
,
2214 bfd_boolean allow_20bit_values
,
2215 bfd_boolean constants_allowed
)
2218 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2227 char *__tl
= (char *) "0";
2233 (void) parse_exp (__tl
, &(op
->exp
));
2235 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2237 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2247 ("this addressing mode is not applicable for destination operand"));
2253 /* Attempt to encode a MOVA instruction with the given operands.
2254 Returns the length of the encoded instruction if successful
2255 or 0 upon failure. If the encoding fails, an error message
2256 will be returned if a pointer is provided. */
2259 try_encode_mova (bfd_boolean imm_op
,
2261 struct msp430_operand_s
* op1
,
2262 struct msp430_operand_s
* op2
,
2263 const char ** error_message_return
)
2269 /* Only a restricted subset of the normal MSP430 addressing modes
2270 are supported here, so check for the ones that are allowed. */
2273 if (op1
->mode
== OP_EXP
)
2275 if (op2
->mode
!= OP_REG
)
2277 if (error_message_return
!= NULL
)
2278 * error_message_return
= _("expected register as second argument of %s");
2284 /* MOVA #imm20, Rdst. */
2285 bin
|= 0x80 | op2
->reg
;
2286 frag
= frag_more (4);
2287 where
= frag
- frag_now
->fr_literal
;
2288 if (op1
->exp
.X_op
== O_constant
)
2290 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2291 bfd_putl16 ((bfd_vma
) bin
, frag
);
2292 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2296 bfd_putl16 ((bfd_vma
) bin
, frag
);
2297 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2298 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2299 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2304 else if (op1
->am
== 1)
2306 /* MOVA z16(Rsrc), Rdst. */
2307 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2308 frag
= frag_more (4);
2309 where
= frag
- frag_now
->fr_literal
;
2310 bfd_putl16 ((bfd_vma
) bin
, frag
);
2311 if (op1
->exp
.X_op
== O_constant
)
2313 if (op1
->exp
.X_add_number
> 0xffff
2314 || op1
->exp
.X_add_number
< -(0x7fff))
2316 if (error_message_return
!= NULL
)
2317 * error_message_return
= _("index value too big for %s");
2320 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2324 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2325 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2327 BFD_RELOC_MSP430X_PCR16
:
2328 BFD_RELOC_MSP430X_ABS16
);
2333 if (error_message_return
!= NULL
)
2334 * error_message_return
= _("unexpected addressing mode for %s");
2337 else if (op1
->am
== 0)
2339 /* MOVA Rsrc, ... */
2340 if (op2
->mode
== OP_REG
)
2342 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2343 frag
= frag_more (2);
2344 where
= frag
- frag_now
->fr_literal
;
2345 bfd_putl16 ((bfd_vma
) bin
, frag
);
2348 else if (op2
->am
== 1)
2352 /* MOVA Rsrc, &abs20. */
2353 bin
|= 0x60 | (op1
->reg
<< 8);
2354 frag
= frag_more (4);
2355 where
= frag
- frag_now
->fr_literal
;
2356 if (op2
->exp
.X_op
== O_constant
)
2358 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2359 bfd_putl16 ((bfd_vma
) bin
, frag
);
2360 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2364 bfd_putl16 ((bfd_vma
) bin
, frag
);
2365 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2366 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2367 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2372 /* MOVA Rsrc, z16(Rdst). */
2373 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2374 frag
= frag_more (4);
2375 where
= frag
- frag_now
->fr_literal
;
2376 bfd_putl16 ((bfd_vma
) bin
, frag
);
2377 if (op2
->exp
.X_op
== O_constant
)
2379 if (op2
->exp
.X_add_number
> 0xffff
2380 || op2
->exp
.X_add_number
< -(0x7fff))
2382 if (error_message_return
!= NULL
)
2383 * error_message_return
= _("index value too big for %s");
2386 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2390 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2391 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2393 BFD_RELOC_MSP430X_PCR16
:
2394 BFD_RELOC_MSP430X_ABS16
);
2399 if (error_message_return
!= NULL
)
2400 * error_message_return
= _("unexpected addressing mode for %s");
2405 /* imm_op == FALSE. */
2407 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2409 /* MOVA &abs20, Rdst. */
2410 if (op2
->mode
!= OP_REG
)
2412 if (error_message_return
!= NULL
)
2413 * error_message_return
= _("expected register as second argument of %s");
2417 if (op2
->reg
== 2 || op2
->reg
== 3)
2419 if (error_message_return
!= NULL
)
2420 * error_message_return
= _("constant generator destination register found in %s");
2424 bin
|= 0x20 | op2
->reg
;
2425 frag
= frag_more (4);
2426 where
= frag
- frag_now
->fr_literal
;
2427 if (op1
->exp
.X_op
== O_constant
)
2429 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2430 bfd_putl16 ((bfd_vma
) bin
, frag
);
2431 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2435 bfd_putl16 ((bfd_vma
) bin
, frag
);
2436 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2437 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2438 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2442 else if (op1
->mode
== OP_REG
)
2446 /* MOVA @Rsrc+, Rdst. */
2447 if (op2
->mode
!= OP_REG
)
2449 if (error_message_return
!= NULL
)
2450 * error_message_return
= _("expected register as second argument of %s");
2454 if (op2
->reg
== 2 || op2
->reg
== 3)
2456 if (error_message_return
!= NULL
)
2457 * error_message_return
= _("constant generator destination register found in %s");
2461 if (op1
->reg
== 2 || op1
->reg
== 3)
2463 if (error_message_return
!= NULL
)
2464 * error_message_return
= _("constant generator source register found in %s");
2468 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2469 frag
= frag_more (2);
2470 where
= frag
- frag_now
->fr_literal
;
2471 bfd_putl16 ((bfd_vma
) bin
, frag
);
2474 else if (op1
->am
== 2)
2476 /* MOVA @Rsrc,Rdst */
2477 if (op2
->mode
!= OP_REG
)
2479 if (error_message_return
!= NULL
)
2480 * error_message_return
= _("expected register as second argument of %s");
2484 if (op2
->reg
== 2 || op2
->reg
== 3)
2486 if (error_message_return
!= NULL
)
2487 * error_message_return
= _("constant generator destination register found in %s");
2491 if (op1
->reg
== 2 || op1
->reg
== 3)
2493 if (error_message_return
!= NULL
)
2494 * error_message_return
= _("constant generator source register found in %s");
2498 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2499 frag
= frag_more (2);
2500 where
= frag
- frag_now
->fr_literal
;
2501 bfd_putl16 ((bfd_vma
) bin
, frag
);
2506 if (error_message_return
!= NULL
)
2507 * error_message_return
= _("unexpected addressing mode for %s");
2512 #define NOP_CHECK_INTERRUPT (1 << 0)
2513 #define NOP_CHECK_CPU12 (1 << 1)
2514 #define NOP_CHECK_CPU19 (1 << 2)
2516 static signed int check_for_nop
= 0;
2518 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2520 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2521 For MOV insns, more sophisticated processing is needed to determine if they
2522 result in enabling/disabling interrupts. */
2523 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2524 || ((strcmp (OPCODE, "bic") == 0) \
2526 || ((strcmp (OPCODE, "clr") == 0) \
2529 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2530 || ((strcmp (OPCODE, "bis") == 0) \
2533 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2534 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2535 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2536 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2537 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2538 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2540 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2541 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2542 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2543 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2544 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2545 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2551 frag
= frag_more (2);
2552 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2553 dwarf2_emit_insn (2);
2556 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2558 warn_eint_nop (bfd_boolean prev_insn_is_nop
, bfd_boolean prev_insn_is_dint
)
2560 if (prev_insn_is_nop
2561 /* If the last insn was a DINT, we will have already warned that a NOP is
2562 required after it. */
2563 || prev_insn_is_dint
2564 /* 430 ISA does not require a NOP before EINT. */
2565 || (! target_is_430x ()))
2567 if (gen_interrupt_nops
)
2570 if (warn_interrupt_nops
)
2571 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2573 else if (warn_interrupt_nops
)
2574 as_warn (_(WARN_NOP_BEFORE_EINT
));
2577 /* Use when unsure what effect the insn will have on the interrupt status,
2578 to insert/warn about adding a NOP before the current insn. */
2580 warn_unsure_interrupt (bfd_boolean prev_insn_is_nop
,
2581 bfd_boolean prev_insn_is_dint
)
2583 if (prev_insn_is_nop
2584 /* If the last insn was a DINT, we will have already warned that a NOP is
2585 required after it. */
2586 || prev_insn_is_dint
2587 /* 430 ISA does not require a NOP before EINT or DINT. */
2588 || (! target_is_430x ()))
2590 if (gen_interrupt_nops
)
2593 if (warn_interrupt_nops
)
2594 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2596 else if (warn_interrupt_nops
)
2597 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2600 /* Parse instruction operands.
2601 Return binary opcode. */
2604 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2606 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2607 int insn_length
= 0;
2608 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2612 struct msp430_operand_s op1
, op2
;
2614 static short ZEROS
= 0;
2615 bfd_boolean byte_op
, imm_op
;
2618 int extended
= 0x1800;
2619 bfd_boolean extended_op
= FALSE
;
2620 bfd_boolean addr_op
;
2621 const char * error_message
;
2622 static signed int repeat_count
= 0;
2623 static bfd_boolean prev_insn_is_nop
= FALSE
;
2624 static bfd_boolean prev_insn_is_dint
= FALSE
;
2625 static bfd_boolean prev_insn_is_eint
= FALSE
;
2626 /* We might decide before the end of the function that the current insn is
2627 equivalent to DINT/EINT. */
2628 bfd_boolean this_insn_is_dint
= FALSE
;
2629 bfd_boolean this_insn_is_eint
= FALSE
;
2630 bfd_boolean fix_emitted
;
2632 /* Opcode is the one from opcodes table
2633 line contains something like
2642 bfd_boolean check
= FALSE
;
2645 switch (TOLOWER (* line
))
2648 /* Byte operation. */
2649 bin
|= BYTE_OPERATION
;
2655 /* "Address" ops work on 20-bit values. */
2657 bin
|= BYTE_OPERATION
;
2662 /* Word operation - this is the default. */
2670 as_warn (_("no size modifier after period, .w assumed"));
2674 as_bad (_("unrecognised instruction size modifier .%c"),
2686 if (*line
&& ! ISSPACE (*line
))
2688 as_bad (_("junk found after instruction: %s.%s"),
2689 opcode
->name
, line
);
2693 /* Catch the case where the programmer has used a ".a" size modifier on an
2694 instruction that does not support it. Look for an alternative extended
2695 instruction that has the same name without the period. Eg: "add.a"
2696 becomes "adda". Although this not an officially supported way of
2697 specifying instruction aliases other MSP430 assemblers allow it. So we
2698 support it for compatibility purposes. */
2699 if (addr_op
&& opcode
->fmt
>= 0)
2701 const char * old_name
= opcode
->name
;
2704 sprintf (real_name
, "%sa", old_name
);
2705 opcode
= hash_find (msp430_hash
, real_name
);
2708 as_bad (_("instruction %s.a does not exist"), old_name
);
2711 #if 0 /* Enable for debugging. */
2712 as_warn ("treating %s.a as %s", old_name
, real_name
);
2715 bin
= opcode
->bin_opcode
;
2718 if (opcode
->fmt
!= -1
2719 && opcode
->insn_opnumb
2720 && (!*line
|| *line
== '\n'))
2722 as_bad (ngettext ("instruction %s requires %d operand",
2723 "instruction %s requires %d operands",
2724 opcode
->insn_opnumb
),
2725 opcode
->name
, opcode
->insn_opnumb
);
2729 memset (l1
, 0, sizeof (l1
));
2730 memset (l2
, 0, sizeof (l2
));
2731 memset (&op1
, 0, sizeof (op1
));
2732 memset (&op2
, 0, sizeof (op2
));
2736 if ((fmt
= opcode
->fmt
) < 0)
2738 if (! target_is_430x ())
2740 as_bad (_("instruction %s requires MSP430X mcu"),
2751 /* If requested set the extended instruction repeat count. */
2754 if (repeat_count
> 0)
2755 extended
|= (repeat_count
- 1);
2757 extended
|= (1 << 7) | (- repeat_count
);
2760 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2765 /* The previous instruction set this flag if it wants to check if this insn
2769 if (! is_opcode ("nop"))
2773 switch (check_for_nop
& - check_for_nop
)
2775 case NOP_CHECK_INTERRUPT
:
2776 /* NOP_CHECK_INTERRUPT rules:
2777 1. 430 and 430x ISA require a NOP after DINT.
2778 2. Only the 430x ISA requires NOP before EINT (this has
2779 been dealt with in the previous call to this function).
2780 3. Only the 430x ISA requires NOP after every EINT.
2782 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2784 if (prev_insn_is_dint
)
2786 if (gen_interrupt_nops
)
2789 if (warn_interrupt_nops
)
2790 as_warn (_(INSERT_NOP_AFTER_DINT
));
2793 as_warn (_(WARN_NOP_AFTER_DINT
));
2795 else if (prev_insn_is_eint
)
2797 if (gen_interrupt_nops
)
2800 if (warn_interrupt_nops
)
2801 as_warn (_(INSERT_NOP_AFTER_EINT
));
2804 as_warn (_(WARN_NOP_AFTER_EINT
));
2806 /* If we get here it's because the last instruction was
2807 determined to either disable or enable interrupts, but
2808 we're not sure which.
2809 We have no information yet about what effect the
2810 current instruction has on interrupts, that has to be
2812 The last insn may have required a NOP after it, so we
2813 deal with that now. */
2816 if (gen_interrupt_nops
)
2819 if (warn_interrupt_nops
)
2820 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2823 /* warn_unsure_interrupt was called on the previous
2825 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
2830 case NOP_CHECK_CPU12
:
2831 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2832 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2834 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2838 case NOP_CHECK_CPU19
:
2839 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2840 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2842 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2847 as_bad (_("internal error: unknown nop check state"));
2850 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2852 while (check_for_nop
);
2859 case 0: /* Emulated. */
2860 switch (opcode
->insn_opnumb
)
2863 if (is_opcode ("eint"))
2864 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
2866 /* Set/clear bits instructions. */
2870 extended
|= BYTE_OPERATION
;
2872 /* Emit the extension word. */
2874 frag
= frag_more (2);
2875 bfd_putl16 (extended
, frag
);
2879 frag
= frag_more (2);
2880 bfd_putl16 ((bfd_vma
) bin
, frag
);
2881 dwarf2_emit_insn (insn_length
);
2885 /* Something which works with destination operand. */
2886 line
= extract_operand (line
, l1
, sizeof (l1
));
2887 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2891 bin
|= (op1
.reg
| (op1
.am
<< 7));
2893 /* If the PC is the destination... */
2894 if (op1
.am
== 0 && op1
.reg
== 0
2895 /* ... and the opcode alters the SR. */
2896 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2897 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2899 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2900 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2901 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2902 as_warn (_("CPU11: PC is destination of SR altering instruction"));
2905 /* If the status register is the destination... */
2906 if (op1
.am
== 0 && op1
.reg
== 2
2907 /* ... and the opcode alters the SR. */
2908 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2909 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2910 || is_opcode ("sbc") || is_opcode ("sxt")
2911 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2912 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2913 || is_opcode ("sbcx")
2916 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2917 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2918 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2919 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2922 /* Compute the entire instruction length, in bytes. */
2923 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2924 insn_length
+= op_length
;
2925 frag
= frag_more (op_length
);
2926 where
= frag
- frag_now
->fr_literal
;
2931 extended
|= BYTE_OPERATION
;
2933 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2935 as_bad (_("repeat instruction used with non-register mode instruction"));
2939 if (op1
.mode
== OP_EXP
)
2941 if (op1
.exp
.X_op
== O_constant
)
2942 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2944 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2945 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2946 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2948 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2949 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2952 /* Emit the extension word. */
2953 bfd_putl16 (extended
, frag
);
2958 bfd_putl16 ((bfd_vma
) bin
, frag
);
2962 if (op1
.mode
== OP_EXP
)
2964 if (op1
.exp
.X_op
== O_constant
)
2966 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2970 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2975 fix_new_exp (frag_now
, where
, 2,
2976 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2978 fix_new_exp (frag_now
, where
, 2,
2979 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2984 dwarf2_emit_insn (insn_length
);
2988 /* Shift instruction. */
2989 line
= extract_operand (line
, l1
, sizeof (l1
));
2990 strncpy (l2
, l1
, sizeof (l2
));
2991 l2
[sizeof (l2
) - 1] = '\0';
2992 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2993 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2996 break; /* An error occurred. All warnings were done before. */
2998 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2999 frag
= frag_more (insn_length
);
3000 where
= frag
- frag_now
->fr_literal
;
3002 if (target_is_430xv2 ()
3003 && op1
.mode
== OP_REG
3005 && (is_opcode ("rlax")
3006 || is_opcode ("rlcx")
3007 || is_opcode ("rla")
3008 || is_opcode ("rlc")))
3010 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3014 /* If the status register is the destination... */
3015 if (op1
.am
== 0 && op1
.reg
== 2
3016 /* ... and the opcode alters the SR. */
3017 && (is_opcode ("rla") || is_opcode ("rlc")
3018 || is_opcode ("rlax") || is_opcode ("rlcx")
3019 || is_opcode ("sxt") || is_opcode ("sxtx")
3020 || is_opcode ("swpb")
3023 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3024 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3025 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3026 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3032 extended
|= BYTE_OPERATION
;
3034 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3036 as_bad (_("repeat instruction used with non-register mode instruction"));
3040 if (op1
.mode
== OP_EXP
)
3042 if (op1
.exp
.X_op
== O_constant
)
3043 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3045 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3046 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3047 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3049 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3050 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3053 if (op2
.mode
== OP_EXP
)
3055 if (op2
.exp
.X_op
== O_constant
)
3056 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3058 else if (op1
.mode
== OP_EXP
)
3059 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3060 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3061 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3063 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3064 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3065 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3068 /* Emit the extension word. */
3069 bfd_putl16 (extended
, frag
);
3074 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3075 bfd_putl16 ((bfd_vma
) bin
, frag
);
3079 if (op1
.mode
== OP_EXP
)
3081 if (op1
.exp
.X_op
== O_constant
)
3083 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3087 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3091 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3092 fix_new_exp (frag_now
, where
, 2,
3093 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3095 fix_new_exp (frag_now
, where
, 2,
3096 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3103 if (op2
.mode
== OP_EXP
)
3105 if (op2
.exp
.X_op
== O_constant
)
3107 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3111 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3115 if (op2
.reg
) /* Not PC relative. */
3116 fix_new_exp (frag_now
, where
, 2,
3117 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3119 fix_new_exp (frag_now
, where
, 2,
3120 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3125 dwarf2_emit_insn (insn_length
);
3129 /* Branch instruction => mov dst, r0. */
3132 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3136 line
= extract_operand (line
, l1
, sizeof (l1
));
3137 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3143 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3144 op_length
= 2 + 2 * op1
.ol
;
3145 frag
= frag_more (op_length
);
3146 where
= frag
- frag_now
->fr_literal
;
3147 bfd_putl16 ((bfd_vma
) bin
, frag
);
3149 if (op1
.mode
== OP_EXP
)
3151 if (op1
.exp
.X_op
== O_constant
)
3153 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3159 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3161 if (op1
.reg
|| op1
.am
== 3)
3162 fix_new_exp (frag_now
, where
, 2,
3163 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3165 fix_new_exp (frag_now
, where
, 2,
3166 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3170 dwarf2_emit_insn (insn_length
+ op_length
);
3174 /* CALLA instructions. */
3175 fix_emitted
= FALSE
;
3177 line
= extract_operand (line
, l1
, sizeof (l1
));
3180 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3181 extended_op
, FALSE
);
3187 op_length
= 2 + 2 * op1
.ol
;
3188 frag
= frag_more (op_length
);
3189 where
= frag
- frag_now
->fr_literal
;
3197 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3198 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3201 else if (op1
.am
== 1)
3207 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3208 BFD_RELOC_MSP430X_PCR20_CALL
);
3212 bin
|= 0x50 | op1
.reg
;
3214 else if (op1
.am
== 0)
3215 bin
|= 0x40 | op1
.reg
;
3217 else if (op1
.am
== 1)
3221 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3222 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3225 else if (op1
.am
== 2)
3226 bin
|= 0x60 | op1
.reg
;
3227 else if (op1
.am
== 3)
3228 bin
|= 0x70 | op1
.reg
;
3230 bfd_putl16 ((bfd_vma
) bin
, frag
);
3232 if (op1
.mode
== OP_EXP
)
3236 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3240 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3243 fix_new_exp (frag_now
, where
+ 2, 2,
3244 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3247 dwarf2_emit_insn (insn_length
+ op_length
);
3255 /* [POP|PUSH]M[.A] #N, Rd */
3256 line
= extract_operand (line
, l1
, sizeof (l1
));
3257 line
= extract_operand (line
, l2
, sizeof (l2
));
3261 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3264 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3265 if (end
!= NULL
&& *end
!= 0)
3267 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3270 if (op1
.exp
.X_op
!= O_constant
)
3272 as_bad (_("expected constant expression as first argument of %s"),
3277 if ((reg
= check_reg (l2
)) == -1)
3279 as_bad (_("expected register as second argument of %s"),
3285 frag
= frag_more (op_length
);
3286 where
= frag
- frag_now
->fr_literal
;
3287 bin
= opcode
->bin_opcode
;
3290 n
= op1
.exp
.X_add_number
;
3291 bin
|= (n
- 1) << 4;
3292 if (is_opcode ("pushm"))
3296 if (reg
- n
+ 1 < 0)
3298 as_bad (_("Too many registers popped"));
3302 /* CPU21 errata: cannot use POPM to restore the SR register. */
3303 if (target_is_430xv2 ()
3304 && (reg
- n
+ 1 < 3)
3306 && is_opcode ("popm"))
3308 as_bad (_("Cannot use POPM to restore the SR register"));
3312 bin
|= (reg
- n
+ 1);
3315 bfd_putl16 ((bfd_vma
) bin
, frag
);
3316 dwarf2_emit_insn (op_length
);
3325 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3326 if (extended
& 0xff)
3328 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3332 line
= extract_operand (line
, l1
, sizeof (l1
));
3333 line
= extract_operand (line
, l2
, sizeof (l2
));
3337 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3340 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3341 if (end
!= NULL
&& *end
!= 0)
3343 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3346 if (op1
.exp
.X_op
!= O_constant
)
3348 as_bad (_("expected constant expression as first argument of %s"),
3352 n
= op1
.exp
.X_add_number
;
3355 as_bad (_("expected first argument of %s to be in the range 1-4"),
3360 if ((reg
= check_reg (l2
)) == -1)
3362 as_bad (_("expected register as second argument of %s"),
3367 if (target_is_430xv2 () && reg
== 0)
3369 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3374 frag
= frag_more (op_length
);
3375 where
= frag
- frag_now
->fr_literal
;
3377 bin
= opcode
->bin_opcode
;
3380 bin
|= (n
- 1) << 10;
3383 bfd_putl16 ((bfd_vma
) bin
, frag
);
3384 dwarf2_emit_insn (op_length
);
3390 bfd_boolean need_reloc
= FALSE
;
3394 /* ADDA, CMPA and SUBA address instructions. */
3395 if (extended
& 0xff)
3397 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3401 line
= extract_operand (line
, l1
, sizeof (l1
));
3402 line
= extract_operand (line
, l2
, sizeof (l2
));
3404 bin
= opcode
->bin_opcode
;
3408 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3409 if (end
!= NULL
&& *end
!= 0)
3411 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3415 if (op1
.exp
.X_op
== O_constant
)
3417 n
= op1
.exp
.X_add_number
;
3418 if (n
> 0xfffff || n
< - (0x7ffff))
3420 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3425 bin
|= ((n
>> 16) & 0xf) << 8;
3437 if ((n
= check_reg (l1
)) == -1)
3439 as_bad (_("expected register name or constant as first argument of %s"),
3444 bin
|= (n
<< 8) | (1 << 6);
3448 if ((reg
= check_reg (l2
)) == -1)
3450 as_bad (_("expected register as second argument of %s"),
3455 frag
= frag_more (op_length
);
3456 where
= frag
- frag_now
->fr_literal
;
3459 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3460 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3462 bfd_putl16 ((bfd_vma
) bin
, frag
);
3464 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3465 dwarf2_emit_insn (op_length
);
3469 case 9: /* MOVA, BRA, RETA. */
3471 bin
= opcode
->bin_opcode
;
3473 if (is_opcode ("reta"))
3475 /* The RETA instruction does not take any arguments.
3476 The implicit first argument is @SP+.
3477 The implicit second argument is PC. */
3487 line
= extract_operand (line
, l1
, sizeof (l1
));
3488 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3489 &imm_op
, extended_op
, FALSE
);
3491 if (is_opcode ("bra"))
3493 /* This is the BRA synthetic instruction.
3494 The second argument is always PC. */
3500 line
= extract_operand (line
, l2
, sizeof (l2
));
3501 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3506 break; /* Error occurred. All warnings were done before. */
3509 /* Only a restricted subset of the normal MSP430 addressing modes
3510 are supported here, so check for the ones that are allowed. */
3511 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3512 & error_message
)) == 0)
3514 as_bad (error_message
, opcode
->name
);
3517 dwarf2_emit_insn (op_length
);
3521 line
= extract_operand (line
, l1
, sizeof l1
);
3522 /* The RPT instruction only accepted immediates and registers. */
3525 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3526 if (end
!= NULL
&& *end
!= 0)
3528 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3531 if (op1
.exp
.X_op
!= O_constant
)
3533 as_bad (_("expected constant value as argument to RPT"));
3536 if (op1
.exp
.X_add_number
< 1
3537 || op1
.exp
.X_add_number
> (1 << 4))
3539 as_bad (_("expected constant in the range 2..16"));
3543 /* We silently accept and ignore a repeat count of 1. */
3544 if (op1
.exp
.X_add_number
> 1)
3545 repeat_count
= op1
.exp
.X_add_number
;
3551 if ((reg
= check_reg (l1
)) != -1)
3554 as_warn (_("PC used as an argument to RPT"));
3556 repeat_count
= - reg
;
3560 as_bad (_("expected constant or register name as argument to RPT insn"));
3567 as_bad (_("Illegal emulated instruction"));
3572 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3573 From f5 ref man 6.3.3:
3574 The 16-bit Status Register (SR, also called R2), used as a source or
3575 destination register, can only be used in register mode addressed
3576 with word instructions. */
3578 case 1: /* Format 1, double operand. */
3579 line
= extract_operand (line
, l1
, sizeof (l1
));
3580 line
= extract_operand (line
, l2
, sizeof (l2
));
3581 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3582 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3585 break; /* Error occurred. All warnings were done before. */
3588 && is_opcode ("movx")
3590 && msp430_enable_relax
)
3592 /* This is the MOVX.A instruction. See if we can convert
3593 it into the MOVA instruction instead. This saves 2 bytes. */
3594 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3597 dwarf2_emit_insn (op_length
);
3602 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3604 /* If the PC is the destination... */
3605 if (op2
.am
== 0 && op2
.reg
== 0
3606 /* ... and the opcode alters the SR. */
3607 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3608 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3610 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3611 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3612 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3613 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3616 /* If the status register is the destination... */
3617 if (op2
.am
== 0 && op2
.reg
== 2
3618 /* ... and the opcode alters the SR. */
3619 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3620 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3621 || is_opcode ("xor")
3622 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3623 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3624 || is_opcode ("xorx")
3627 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3628 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3629 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3630 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3633 /* Chain these checks for SR manipulations so we can warn if they are not
3635 if (((is_opcode ("bis") && bin
== 0xd032)
3636 || (is_opcode ("mov") && bin
== 0x4032)
3637 || (is_opcode ("xor") && bin
== 0xe032))
3638 && op1
.mode
== OP_EXP
3639 && op1
.exp
.X_op
== O_constant
3640 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3641 check_for_nop
|= NOP_CHECK_CPU19
;
3642 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3644 /* Any MOV with the SR as the destination either enables or disables
3646 if (op1
.mode
== OP_EXP
3647 && op1
.exp
.X_op
== O_constant
)
3649 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3651 /* The GIE bit is being set. */
3652 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3653 this_insn_is_eint
= TRUE
;
3656 /* The GIE bit is being cleared. */
3657 this_insn_is_dint
= TRUE
;
3659 /* If an immediate value which is covered by the constant generator
3660 is the src, then op1 will have been changed to either R2 or R3 by
3662 The only constants covered by CG1 and CG2, which have bit 3 set
3663 and therefore would enable interrupts when writing to the SR, are
3664 R2 with addresing mode 0b11 and R3 with 0b11.
3665 The addressing mode is in bits 5:4 of the binary opcode. */
3666 else if (op1
.mode
== OP_REG
3667 && (op1
.reg
== 2 || op1
.reg
== 3)
3668 && (bin
& 0x30) == 0x30)
3670 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3671 this_insn_is_eint
= TRUE
;
3673 /* Any other use of the constant generator with destination R2, will
3674 disable interrupts. */
3675 else if (op1
.mode
== OP_REG
3676 && (op1
.reg
== 2 || op1
.reg
== 3))
3677 this_insn_is_dint
= TRUE
;
3678 else if (do_unknown_interrupt_nops
)
3680 /* FIXME: Couldn't work out whether the insn is enabling or
3681 disabling interrupts, so for safety need to treat it as both
3683 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3684 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3687 else if (is_eint (opcode
->name
, bin
))
3688 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3689 else if ((bin
& 0x32) == 0x32)
3691 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3692 * an interrupt state change if a write happens. */
3693 /* FIXME: How strict to be here? */
3697 /* Compute the entire length of the instruction in bytes. */
3698 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3699 + 2 /* The opcode */
3700 + (2 * op1
.ol
) /* The first operand. */
3701 + (2 * op2
.ol
); /* The second operand. */
3703 insn_length
+= op_length
;
3704 frag
= frag_more (op_length
);
3705 where
= frag
- frag_now
->fr_literal
;
3710 extended
|= BYTE_OPERATION
;
3712 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3714 as_bad (_("repeat instruction used with non-register mode instruction"));
3718 /* If necessary, emit a reloc to update the extension word. */
3719 if (op1
.mode
== OP_EXP
)
3721 if (op1
.exp
.X_op
== O_constant
)
3722 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3724 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3725 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3726 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3728 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3729 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3732 if (op2
.mode
== OP_EXP
)
3734 if (op2
.exp
.X_op
== O_constant
)
3735 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3737 else if (op1
.mode
== OP_EXP
)
3738 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3739 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3740 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3743 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3744 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3745 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3748 /* Emit the extension word. */
3749 bfd_putl16 (extended
, frag
);
3754 bfd_putl16 ((bfd_vma
) bin
, frag
);
3758 if (op1
.mode
== OP_EXP
)
3760 if (op1
.exp
.X_op
== O_constant
)
3762 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3766 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3770 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3771 fix_new_exp (frag_now
, where
, 2,
3772 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3774 fix_new_exp (frag_now
, where
, 2,
3775 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3783 if (op2
.mode
== OP_EXP
)
3785 if (op2
.exp
.X_op
== O_constant
)
3787 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3791 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3795 if (op2
.reg
) /* Not PC relative. */
3796 fix_new_exp (frag_now
, where
, 2,
3797 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3799 fix_new_exp (frag_now
, where
, 2,
3800 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3805 dwarf2_emit_insn (insn_length
);
3807 /* If the PC is the destination... */
3808 if (op2
.am
== 0 && op2
.reg
== 0
3809 /* ... but the opcode does not alter the destination. */
3810 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3811 check_for_nop
|= NOP_CHECK_CPU12
;
3814 case 2: /* Single-operand mostly instr. */
3815 if (opcode
->insn_opnumb
== 0)
3817 /* reti instruction. */
3819 frag
= frag_more (2);
3820 bfd_putl16 ((bfd_vma
) bin
, frag
);
3821 dwarf2_emit_insn (insn_length
);
3825 line
= extract_operand (line
, l1
, sizeof (l1
));
3826 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3827 &imm_op
, extended_op
, TRUE
);
3829 break; /* Error in operand. */
3831 if (target_is_430xv2 ()
3832 && op1
.mode
== OP_REG
3834 && (is_opcode ("rrax")
3835 || is_opcode ("rrcx")
3836 || is_opcode ("rra")
3837 || is_opcode ("rrc")))
3839 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3843 /* If the status register is the destination... */
3844 if (op1
.am
== 0 && op1
.reg
== 2
3845 /* ... and the opcode alters the SR. */
3846 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3848 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3849 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3850 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3851 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3854 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3855 frag
= frag_more (insn_length
);
3856 where
= frag
- frag_now
->fr_literal
;
3860 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3862 /* These two instructions use a special
3863 encoding of the A/L and B/W bits. */
3864 bin
&= ~ BYTE_OPERATION
;
3868 as_bad (_("%s instruction does not accept a .b suffix"),
3873 extended
|= BYTE_OPERATION
;
3876 extended
|= BYTE_OPERATION
;
3878 if (is_opcode ("rrux"))
3879 extended
|= IGNORE_CARRY_BIT
;
3881 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3883 as_bad (_("repeat instruction used with non-register mode instruction"));
3887 if (op1
.mode
== OP_EXP
)
3889 if (op1
.exp
.X_op
== O_constant
)
3890 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3892 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3893 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3894 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3896 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3897 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3900 /* Emit the extension word. */
3901 bfd_putl16 (extended
, frag
);
3906 bin
|= op1
.reg
| (op1
.am
<< 4);
3907 bfd_putl16 ((bfd_vma
) bin
, frag
);
3911 if (op1
.mode
== OP_EXP
)
3913 if (op1
.exp
.X_op
== O_constant
)
3915 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3919 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3923 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3924 fix_new_exp (frag_now
, where
, 2,
3925 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3927 fix_new_exp (frag_now
, where
, 2,
3928 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3933 dwarf2_emit_insn (insn_length
);
3936 case 3: /* Conditional jumps instructions. */
3937 line
= extract_operand (line
, l1
, sizeof (l1
));
3938 /* l1 is a label. */
3947 end
= parse_exp (m
, &exp
);
3948 if (end
!= NULL
&& *end
!= 0)
3950 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3954 /* In order to handle something like:
3958 jz 4 ; skip next 4 bytes
3961 nop ; will jump here if r5 positive or zero
3963 jCOND -n ;assumes jump n bytes backward:
3973 jCOND $n ; jump from PC in either direction. */
3975 if (exp
.X_op
== O_constant
)
3977 int x
= exp
.X_add_number
;
3981 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3985 if ((*l1
== '$' && x
> 0) || x
< 0)
3990 if (x
> 512 || x
< -511)
3992 as_bad (_("Wrong displacement %d"), x
<< 1);
3997 frag
= frag_more (2); /* Instr size is 1 word. */
4000 bfd_putl16 ((bfd_vma
) bin
, frag
);
4002 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4005 frag
= frag_more (2); /* Instr size is 1 word. */
4006 where
= frag
- frag_now
->fr_literal
;
4007 fix_new_exp (frag_now
, where
, 2,
4008 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
4010 bfd_putl16 ((bfd_vma
) bin
, frag
);
4012 else if (*l1
== '$')
4014 as_bad (_("instruction requires label sans '$'"));
4018 ("instruction requires label or value in range -511:512"));
4019 dwarf2_emit_insn (insn_length
);
4024 as_bad (_("instruction requires label"));
4029 case 4: /* Extended jumps. */
4030 if (!msp430_enable_polys
)
4032 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4036 line
= extract_operand (line
, l1
, sizeof (l1
));
4042 /* Ignore absolute addressing. make it PC relative anyway. */
4043 if (*m
== '#' || *m
== '$')
4046 end
= parse_exp (m
, & exp
);
4047 if (end
!= NULL
&& *end
!= 0)
4049 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4052 if (exp
.X_op
== O_symbol
)
4054 /* Relaxation required. */
4055 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4057 if (target_is_430x ())
4058 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4060 /* The parameter to dwarf2_emit_insn is actually the offset to
4061 the start of the insn from the fix piece of instruction that
4062 was emitted. Since next fragments may have variable size we
4063 tie debug info to the beginning of the instruction. */
4065 frag
= frag_more (8);
4066 dwarf2_emit_insn (0);
4067 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4068 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4070 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4072 0, /* Offset is zero if jump dist less than 1K. */
4078 as_bad (_("instruction requires label"));
4081 case 5: /* Emulated extended branches. */
4082 if (!msp430_enable_polys
)
4084 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4087 line
= extract_operand (line
, l1
, sizeof (l1
));
4093 /* Ignore absolute addressing. make it PC relative anyway. */
4094 if (*m
== '#' || *m
== '$')
4097 end
= parse_exp (m
, & exp
);
4098 if (end
!= NULL
&& *end
!= 0)
4100 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4103 if (exp
.X_op
== O_symbol
)
4105 /* Relaxation required. */
4106 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4108 if (target_is_430x ())
4109 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4112 frag
= frag_more (8);
4113 dwarf2_emit_insn (0);
4114 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4115 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4117 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4118 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4120 0, /* Offset is zero if jump dist less than 1K. */
4126 as_bad (_("instruction requires label"));
4130 as_bad (_("Illegal instruction or not implemented opcode."));
4133 if (is_opcode ("nop"))
4135 prev_insn_is_nop
= TRUE
;
4136 prev_insn_is_dint
= FALSE
;
4137 prev_insn_is_eint
= FALSE
;
4139 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4141 prev_insn_is_dint
= TRUE
;
4142 prev_insn_is_eint
= FALSE
;
4143 prev_insn_is_nop
= FALSE
;
4144 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4146 /* NOP is not needed after EINT for 430 ISA. */
4147 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4149 prev_insn_is_eint
= TRUE
;
4150 prev_insn_is_nop
= FALSE
;
4151 prev_insn_is_dint
= FALSE
;
4152 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4156 prev_insn_is_nop
= FALSE
;
4157 prev_insn_is_dint
= FALSE
;
4158 prev_insn_is_eint
= FALSE
;
4161 input_line_pointer
= line
;
4166 md_assemble (char * str
)
4168 struct msp430_opcode_s
* opcode
;
4172 str
= skip_space (str
); /* Skip leading spaces. */
4173 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4177 char a
= TOLOWER (cmd
[i
]);
4184 as_bad (_("can't find opcode"));
4188 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
4192 as_bad (_("unknown opcode `%s'"), cmd
);
4197 char *__t
= input_line_pointer
;
4199 msp430_operands (opcode
, str
);
4200 input_line_pointer
= __t
;
4204 /* GAS will call this function for each section at the end of the assembly,
4205 to permit the CPU backend to adjust the alignment of a section. */
4208 md_section_align (asection
* seg
, valueT addr
)
4210 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4212 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4215 /* If you define this macro, it should return the offset between the
4216 address of a PC relative fixup and the position from which the PC
4217 relative adjustment should be made. On many processors, the base
4218 of a PC relative instruction is the next instruction, so this
4219 macro would return the length of an instruction. */
4222 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4224 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4225 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4226 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4229 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4232 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4233 Now it handles the situation when relocations
4234 have to be passed to linker. */
4236 msp430_force_relocation_local (fixS
*fixp
)
4238 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4242 if (msp430_enable_polys
4243 && !msp430_enable_relax
)
4250 /* GAS will call this for each fixup. It should store the correct
4251 value in the object file. */
4253 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4255 unsigned char * where
;
4259 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4264 else if (fixp
->fx_pcrel
)
4266 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4268 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4270 /* FIXME: We can appear here only in case if we perform a pc
4271 relative jump to the label which is i) global, ii) locally
4272 defined or this is a jump to an absolute symbol.
4273 If this is an absolute symbol -- everything is OK.
4274 If this is a global label, we've got a symbol value defined
4276 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4277 from this section start
4278 2. *valuep will contain the real offset from jump insn to the
4280 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4281 will be incorrect. Therefore remove s_get_value. */
4282 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4290 value
= fixp
->fx_offset
;
4292 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4294 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4296 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4302 fixp
->fx_no_overflow
= 1;
4304 /* If polymorphs are enabled and relax disabled.
4305 do not kill any relocs and pass them to linker. */
4306 if (msp430_enable_polys
4307 && !msp430_enable_relax
)
4310 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4311 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4318 /* Fetch the instruction, insert the fully resolved operand
4319 value, and stuff the instruction back again. */
4320 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4322 insn
= bfd_getl16 (where
);
4324 switch (fixp
->fx_r_type
)
4326 case BFD_RELOC_MSP430_10_PCREL
:
4328 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4329 _("odd address operand: %ld"), value
);
4331 /* Jumps are in words. */
4333 --value
; /* Correct PC. */
4335 if (value
< -512 || value
> 511)
4336 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4337 _("operand out of range: %ld"), value
);
4339 value
&= 0x3ff; /* get rid of extended sign */
4340 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4343 case BFD_RELOC_MSP430X_PCR16
:
4344 case BFD_RELOC_MSP430_RL_PCREL
:
4345 case BFD_RELOC_MSP430_16_PCREL
:
4347 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4348 _("odd address operand: %ld"), value
);
4351 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4352 /* Nothing to be corrected here. */
4353 if (value
< -32768 || value
> 65536)
4354 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4355 _("operand out of range: %ld"), value
);
4358 case BFD_RELOC_MSP430X_ABS16
:
4359 case BFD_RELOC_MSP430_16
:
4361 case BFD_RELOC_MSP430_16_BYTE
:
4362 value
&= 0xffff; /* Get rid of extended sign. */
4363 bfd_putl16 ((bfd_vma
) value
, where
);
4366 case BFD_RELOC_MSP430_ABS_HI16
:
4368 value
&= 0xffff; /* Get rid of extended sign. */
4369 bfd_putl16 ((bfd_vma
) value
, where
);
4373 bfd_putl16 ((bfd_vma
) value
, where
);
4376 case BFD_RELOC_MSP430_ABS8
:
4378 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4381 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4382 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4383 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4385 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4388 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4389 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4391 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4394 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4395 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4397 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4400 case BFD_RELOC_MSP430X_PCR20_CALL
:
4401 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4403 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4406 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4407 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4408 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4410 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4413 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4414 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4416 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4419 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4420 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4422 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4426 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4427 fixp
->fx_line
, fixp
->fx_r_type
);
4433 fixp
->fx_addnumber
= value
;
4438 S_IS_GAS_LOCAL (symbolS
* s
)
4445 name
= S_GET_NAME (s
);
4446 len
= strlen (name
) - 1;
4448 return name
[len
] == 1 || name
[len
] == 2;
4451 /* GAS will call this to generate a reloc, passing the resulting reloc
4452 to `bfd_install_relocation'. This currently works poorly, as
4453 `bfd_install_relocation' often does the wrong thing, and instances of
4454 `tc_gen_reloc' have been written to work around the problems, which
4455 in turns makes it difficult to fix `bfd_install_relocation'. */
4457 /* If while processing a fixup, a reloc really needs to be created
4458 then it is done here. */
4461 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4463 static arelent
* no_relocs
= NULL
;
4464 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4467 reloc
= XNEW (arelent
);
4468 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4469 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4471 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4473 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4474 _("reloc %d not supported by object file format"),
4475 (int) fixp
->fx_r_type
);
4484 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4486 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4487 fixp
->fx_subsy
= NULL
;
4490 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4492 asection
*asec
, *ssec
;
4494 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4495 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4497 /* If we have a difference between two different, non-absolute symbols
4498 we must generate two relocs (one for each symbol) and allow the
4499 linker to resolve them - relaxation may change the distances between
4500 symbols, even local symbols defined in the same section.
4502 Unfortunately we cannot do this with assembler generated local labels
4503 because there can be multiple incarnations of the same label, with
4504 exactly the same name, in any given section and the linker will have
4505 no way to identify the correct one. Instead we just have to hope
4506 that no relaxation will occur between the local label and the other
4507 symbol in the expression.
4509 Similarly we have to compute differences between symbols in the .eh_frame
4510 section as the linker is not smart enough to apply relocations there
4511 before attempting to process it. */
4512 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4513 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4514 && strcmp (ssec
->name
, ".eh_frame") != 0
4515 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4516 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4518 arelent
* reloc2
= XNEW (arelent
);
4523 reloc2
->address
= reloc
->address
;
4524 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4525 BFD_RELOC_MSP430_SYM_DIFF
);
4526 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4528 if (ssec
== absolute_section
)
4529 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4532 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4533 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4536 reloc
->addend
= fixp
->fx_offset
;
4537 if (asec
== absolute_section
)
4539 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4540 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4544 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4545 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4554 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4556 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4557 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4559 switch (fixp
->fx_r_type
)
4562 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4566 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4570 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4574 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4579 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4590 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4591 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4593 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4594 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4596 md_number_to_chars (fixpos
, amount
, 2);
4601 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4602 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4603 reloc
->addend
= fixp
->fx_offset
;
4605 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4606 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4607 reloc
->address
= fixp
->fx_offset
;
4614 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4615 asection
* segment_type ATTRIBUTE_UNUSED
)
4617 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4619 /* This is a jump -> pcrel mode. Nothing to do much here.
4620 Return value == 2. */
4622 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4624 else if (fragP
->fr_symbol
)
4626 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4627 an absolute segment, we don't know a displacement until we link
4628 object files. So it will always be long. This also applies to
4629 labels in a subsegment of current. Liker may relax it to short
4630 jump later. Return value == 8. */
4632 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4636 /* We know the abs value. may be it is a jump to fixed address.
4637 Impossible in our case, cause all constants already handled. */
4639 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4642 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4646 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4647 asection
* sec ATTRIBUTE_UNUSED
,
4653 struct rcodes_s
* cc
= NULL
;
4654 struct hcodes_s
* hc
= NULL
;
4656 switch (fragP
->fr_subtype
)
4658 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4659 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4660 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4661 /* We do not have to convert anything here.
4662 Just apply a fix. */
4663 rela
= BFD_RELOC_MSP430_10_PCREL
;
4666 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4667 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4668 /* Convert uncond branch jmp lab -> br lab. */
4669 if (target_is_430x ())
4670 cc
= msp430x_rcodes
+ 7;
4672 cc
= msp430_rcodes
+ 7;
4673 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4674 bfd_putl16 (cc
->lop0
, where
);
4675 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4679 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4680 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4682 /* Other simple branches. */
4683 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4686 /* Find actual instruction. */
4687 if (target_is_430x ())
4689 for (i
= 0; i
< 7 && !cc
; i
++)
4690 if (msp430x_rcodes
[i
].sop
== insn
)
4691 cc
= msp430x_rcodes
+ i
;
4695 for (i
= 0; i
< 7 && !cc
; i
++)
4696 if (msp430_rcodes
[i
].sop
== insn
)
4697 cc
= & msp430_rcodes
[i
];
4700 if (!cc
|| !cc
->name
)
4701 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4702 __FUNCTION__
, (long) insn
);
4703 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4704 bfd_putl16 (cc
->lop0
, where
);
4705 bfd_putl16 (cc
->lop1
, where
+ 2);
4706 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4711 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4712 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4713 if (target_is_430x ())
4714 cc
= msp430x_rcodes
+ 6;
4716 cc
= msp430_rcodes
+ 6;
4717 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4718 bfd_putl16 (cc
->lop0
, where
);
4719 bfd_putl16 (cc
->lop1
, where
+ 2);
4720 bfd_putl16 (cc
->lop2
, where
+ 4);
4721 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4725 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4727 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4730 if (target_is_430x ())
4732 for (i
= 0; i
< 4 && !hc
; i
++)
4733 if (msp430x_hcodes
[i
].op1
== insn
)
4734 hc
= msp430x_hcodes
+ i
;
4738 for (i
= 0; i
< 4 && !hc
; i
++)
4739 if (msp430_hcodes
[i
].op1
== insn
)
4740 hc
= &msp430_hcodes
[i
];
4742 if (!hc
|| !hc
->name
)
4743 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4744 __FUNCTION__
, (long) insn
);
4745 rela
= BFD_RELOC_MSP430_10_PCREL
;
4746 /* Apply a fix for a first label if necessary.
4747 another fix will be applied to the next word of insn anyway. */
4749 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4750 fragP
->fr_offset
, TRUE
, rela
);
4756 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4757 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4759 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4762 if (target_is_430x ())
4764 for (i
= 0; i
< 4 && !hc
; i
++)
4765 if (msp430x_hcodes
[i
].op1
== insn
)
4766 hc
= msp430x_hcodes
+ i
;
4770 for (i
= 0; i
< 4 && !hc
; i
++)
4771 if (msp430_hcodes
[i
].op1
== insn
)
4772 hc
= & msp430_hcodes
[i
];
4774 if (!hc
|| !hc
->name
)
4775 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4776 __FUNCTION__
, (long) insn
);
4777 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4778 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4779 bfd_putl16 (hc
->lop0
, where
);
4780 bfd_putl16 (hc
->lop1
, where
+ 2);
4781 bfd_putl16 (hc
->lop2
, where
+ 4);
4787 as_fatal (_("internal inconsistency problem in %s: %lx"),
4788 __FUNCTION__
, (long) fragP
->fr_subtype
);
4792 /* Now apply fix. */
4793 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4794 fragP
->fr_offset
, TRUE
, rela
);
4795 /* Just fixed 2 bytes. */
4799 /* Relax fragment. Mostly stolen from hc11 and mcore
4800 which arches I think I know. */
4803 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4804 long stretch ATTRIBUTE_UNUSED
)
4809 const relax_typeS
*this_type
;
4810 const relax_typeS
*start_type
;
4811 relax_substateT next_state
;
4812 relax_substateT this_state
;
4813 const relax_typeS
*table
= md_relax_table
;
4815 /* Nothing to be done if the frag has already max size. */
4816 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4817 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4820 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4822 symbolP
= fragP
->fr_symbol
;
4823 if (symbol_resolved_p (symbolP
))
4824 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4826 /* We know the offset. calculate a distance. */
4827 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4830 if (!msp430_enable_relax
)
4832 /* Relaxation is not enabled. So, make all jump as long ones
4833 by setting 'aim' to quite high value. */
4837 this_state
= fragP
->fr_subtype
;
4838 start_type
= this_type
= table
+ this_state
;
4842 /* Look backwards. */
4843 for (next_state
= this_type
->rlx_more
; next_state
;)
4844 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4848 /* Grow to next state. */
4849 this_state
= next_state
;
4850 this_type
= table
+ this_state
;
4851 next_state
= this_type
->rlx_more
;
4856 /* Look forwards. */
4857 for (next_state
= this_type
->rlx_more
; next_state
;)
4858 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4862 /* Grow to next state. */
4863 this_state
= next_state
;
4864 this_type
= table
+ this_state
;
4865 next_state
= this_type
->rlx_more
;
4869 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4871 fragP
->fr_subtype
= this_state
;
4875 /* Return FALSE if the fixup in fixp should be left alone and not
4876 adjusted. We return FALSE here so that linker relaxation will
4880 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4882 /* If the symbol is in a non-code section then it should be OK. */
4884 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4890 /* Set the contents of the .MSP430.attributes section. */
4893 msp430_md_end (void)
4897 if (gen_interrupt_nops
)
4900 if (warn_interrupt_nops
)
4901 as_warn (INSERT_NOP_AT_EOF
);
4903 else if (warn_interrupt_nops
)
4904 as_warn (_(WARN_NOP_AT_EOF
));
4907 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4908 target_is_430x () ? 2 : 1);
4910 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4911 large_model
? 2 : 1);
4913 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4914 large_model
? 2 : 1);
4917 /* Returns FALSE if there is a msp430 specific reason why the
4918 subtraction of two same-section symbols cannot be computed by
4922 msp430_allow_local_subtract (expressionS
* left
,
4923 expressionS
* right
,
4926 /* If the symbols are not in a code section then they are OK. */
4927 if ((section
->flags
& SEC_CODE
) == 0)
4930 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4933 if (left
->X_add_symbol
== right
->X_add_symbol
)
4936 /* We have to assume that there may be instructions between the
4937 two symbols and that relaxation may increase the distance between