1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2018 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_MCPU 'c'
684 #define OPTION_MOVE_DATA 'd'
685 static bfd_boolean move_data
= FALSE
;
686 #define OPTION_DATA_REGION 'r'
687 static bfd_boolean upper_data_region_in_use
= FALSE
;
691 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
692 OPTION_SILICON_ERRATA_WARN
,
695 static unsigned int silicon_errata_fix
= 0;
696 static unsigned int silicon_errata_warn
= 0;
697 #define SILICON_ERRATA_CPU4 (1 << 0)
698 #define SILICON_ERRATA_CPU8 (1 << 1)
699 #define SILICON_ERRATA_CPU11 (1 << 2)
700 #define SILICON_ERRATA_CPU12 (1 << 3)
701 #define SILICON_ERRATA_CPU13 (1 << 4)
702 #define SILICON_ERRATA_CPU19 (1 << 5)
705 msp430_set_arch (int option
)
707 char str
[32]; /* 32 for good measure. */
709 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
711 md_parse_option (option
, str
);
712 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
713 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
716 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
717 Keep these two structures in sync.
718 The data in this structure has been extracted from version 1.194 of the
719 devices.csv file released by TI in September 2016. */
721 struct msp430_mcu_data
724 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
725 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
729 { "cc430f5123",2,8 },
730 { "cc430f5125",2,8 },
731 { "cc430f5133",2,8 },
732 { "cc430f5135",2,8 },
733 { "cc430f5137",2,8 },
734 { "cc430f5143",2,8 },
735 { "cc430f5145",2,8 },
736 { "cc430f5147",2,8 },
737 { "cc430f6125",2,8 },
738 { "cc430f6126",2,8 },
739 { "cc430f6127",2,8 },
740 { "cc430f6135",2,8 },
741 { "cc430f6137",2,8 },
742 { "cc430f6143",2,8 },
743 { "cc430f6145",2,8 },
744 { "cc430f6147",2,8 },
745 { "msp430afe221",0,2 },
746 { "msp430afe222",0,2 },
747 { "msp430afe223",0,2 },
748 { "msp430afe231",0,2 },
749 { "msp430afe232",0,2 },
750 { "msp430afe233",0,2 },
751 { "msp430afe251",0,2 },
752 { "msp430afe252",0,2 },
753 { "msp430afe253",0,2 },
754 { "msp430bt5190",2,8 },
755 { "msp430c091",0,0 },
756 { "msp430c092",0,0 },
757 { "msp430c111",0,0 },
758 { "msp430c1111",0,0 },
759 { "msp430c112",0,0 },
760 { "msp430c1121",0,0 },
761 { "msp430c1331",0,0 },
762 { "msp430c1351",0,0 },
763 { "msp430c311s",0,0 },
764 { "msp430c312",0,0 },
765 { "msp430c313",0,0 },
766 { "msp430c314",0,0 },
767 { "msp430c315",0,0 },
768 { "msp430c323",0,0 },
769 { "msp430c325",0,0 },
770 { "msp430c336",0,1 },
771 { "msp430c337",0,1 },
772 { "msp430c412",0,0 },
773 { "msp430c413",0,0 },
774 { "msp430cg4616",1,1 },
775 { "msp430cg4617",1,1 },
776 { "msp430cg4618",1,1 },
777 { "msp430cg4619",1,1 },
778 { "msp430e112",0,0 },
779 { "msp430e313",0,0 },
780 { "msp430e315",0,0 },
781 { "msp430e325",0,0 },
782 { "msp430e337",0,1 },
783 { "msp430f110",0,0 },
784 { "msp430f1101",0,0 },
785 { "msp430f1101a",0,0 },
786 { "msp430f1111",0,0 },
787 { "msp430f1111a",0,0 },
788 { "msp430f112",0,0 },
789 { "msp430f1121",0,0 },
790 { "msp430f1121a",0,0 },
791 { "msp430f1122",0,0 },
792 { "msp430f1132",0,0 },
793 { "msp430f122",0,0 },
794 { "msp430f1222",0,0 },
795 { "msp430f123",0,0 },
796 { "msp430f1232",0,0 },
797 { "msp430f133",0,0 },
798 { "msp430f135",0,0 },
799 { "msp430f147",0,1 },
800 { "msp430f1471",0,1 },
801 { "msp430f148",0,1 },
802 { "msp430f1481",0,1 },
803 { "msp430f149",0,1 },
804 { "msp430f1491",0,1 },
805 { "msp430f155",0,0 },
806 { "msp430f156",0,0 },
807 { "msp430f157",0,0 },
808 { "msp430f1610",0,1 },
809 { "msp430f1611",0,1 },
810 { "msp430f1612",0,1 },
811 { "msp430f167",0,1 },
812 { "msp430f168",0,1 },
813 { "msp430f169",0,1 },
814 { "msp430f2001",0,0 },
815 { "msp430f2002",0,0 },
816 { "msp430f2003",0,0 },
817 { "msp430f2011",0,0 },
818 { "msp430f2012",0,0 },
819 { "msp430f2013",0,0 },
820 { "msp430f2101",0,0 },
821 { "msp430f2111",0,0 },
822 { "msp430f2112",0,0 },
823 { "msp430f2121",0,0 },
824 { "msp430f2122",0,0 },
825 { "msp430f2131",0,0 },
826 { "msp430f2132",0,0 },
827 { "msp430f2232",0,0 },
828 { "msp430f2234",0,0 },
829 { "msp430f2252",0,0 },
830 { "msp430f2254",0,0 },
831 { "msp430f2272",0,0 },
832 { "msp430f2274",0,0 },
833 { "msp430f233",0,2 },
834 { "msp430f2330",0,2 },
835 { "msp430f235",0,2 },
836 { "msp430f2350",0,2 },
837 { "msp430f2370",0,2 },
838 { "msp430f2410",0,2 },
839 { "msp430f2416",1,2 },
840 { "msp430f2417",1,2 },
841 { "msp430f2418",1,2 },
842 { "msp430f2419",1,2 },
843 { "msp430f247",0,2 },
844 { "msp430f2471",0,2 },
845 { "msp430f248",0,2 },
846 { "msp430f2481",0,2 },
847 { "msp430f249",0,2 },
848 { "msp430f2491",0,2 },
849 { "msp430f2616",1,2 },
850 { "msp430f2617",1,2 },
851 { "msp430f2618",1,2 },
852 { "msp430f2619",1,2 },
853 { "msp430f412",0,0 },
854 { "msp430f413",0,0 },
855 { "msp430f4132",0,0 },
856 { "msp430f415",0,0 },
857 { "msp430f4152",0,0 },
858 { "msp430f417",0,0 },
859 { "msp430f423",0,1 },
860 { "msp430f423a",0,1 },
861 { "msp430f425",0,1 },
862 { "msp430f4250",0,0 },
863 { "msp430f425a",0,1 },
864 { "msp430f4260",0,0 },
865 { "msp430f427",0,1 },
866 { "msp430f4270",0,0 },
867 { "msp430f427a",0,1 },
868 { "msp430f435",0,0 },
869 { "msp430f4351",0,0 },
870 { "msp430f436",0,0 },
871 { "msp430f4361",0,0 },
872 { "msp430f437",0,0 },
873 { "msp430f4371",0,0 },
874 { "msp430f438",0,0 },
875 { "msp430f439",0,0 },
876 { "msp430f447",0,1 },
877 { "msp430f448",0,1 },
878 { "msp430f4481",0,1 },
879 { "msp430f449",0,1 },
880 { "msp430f4491",0,1 },
881 { "msp430f4616",1,1 },
882 { "msp430f46161",1,1 },
883 { "msp430f4617",1,1 },
884 { "msp430f46171",1,1 },
885 { "msp430f4618",1,1 },
886 { "msp430f46181",1,1 },
887 { "msp430f4619",1,1 },
888 { "msp430f46191",1,1 },
889 { "msp430f47126",1,4 },
890 { "msp430f47127",1,4 },
891 { "msp430f47163",1,4 },
892 { "msp430f47166",1,4 },
893 { "msp430f47167",1,4 },
894 { "msp430f47173",1,4 },
895 { "msp430f47176",1,4 },
896 { "msp430f47177",1,4 },
897 { "msp430f47183",1,4 },
898 { "msp430f47186",1,4 },
899 { "msp430f47187",1,4 },
900 { "msp430f47193",1,4 },
901 { "msp430f47196",1,4 },
902 { "msp430f47197",1,4 },
903 { "msp430f477",0,0 },
904 { "msp430f478",0,0 },
905 { "msp430f4783",0,4 },
906 { "msp430f4784",0,4 },
907 { "msp430f479",0,0 },
908 { "msp430f4793",0,4 },
909 { "msp430f4794",0,4 },
910 { "msp430f5131",2,8 },
911 { "msp430f5132",2,8 },
912 { "msp430f5151",2,8 },
913 { "msp430f5152",2,8 },
914 { "msp430f5171",2,8 },
915 { "msp430f5172",2,8 },
916 { "msp430f5212",2,8 },
917 { "msp430f5213",2,8 },
918 { "msp430f5214",2,8 },
919 { "msp430f5217",2,8 },
920 { "msp430f5218",2,8 },
921 { "msp430f5219",2,8 },
922 { "msp430f5222",2,8 },
923 { "msp430f5223",2,8 },
924 { "msp430f5224",2,8 },
925 { "msp430f5227",2,8 },
926 { "msp430f5228",2,8 },
927 { "msp430f5229",2,8 },
928 { "msp430f5232",2,8 },
929 { "msp430f5234",2,8 },
930 { "msp430f5237",2,8 },
931 { "msp430f5239",2,8 },
932 { "msp430f5242",2,8 },
933 { "msp430f5244",2,8 },
934 { "msp430f5247",2,8 },
935 { "msp430f5249",2,8 },
936 { "msp430f5252",2,8 },
937 { "msp430f5253",2,8 },
938 { "msp430f5254",2,8 },
939 { "msp430f5255",2,8 },
940 { "msp430f5256",2,8 },
941 { "msp430f5257",2,8 },
942 { "msp430f5258",2,8 },
943 { "msp430f5259",2,8 },
944 { "msp430f5304",2,8 },
945 { "msp430f5308",2,8 },
946 { "msp430f5309",2,8 },
947 { "msp430f5310",2,8 },
948 { "msp430f5324",2,8 },
949 { "msp430f5325",2,8 },
950 { "msp430f5326",2,8 },
951 { "msp430f5327",2,8 },
952 { "msp430f5328",2,8 },
953 { "msp430f5329",2,8 },
954 { "msp430f5333",2,8 },
955 { "msp430f5335",2,8 },
956 { "msp430f5336",2,8 },
957 { "msp430f5338",2,8 },
958 { "msp430f5340",2,8 },
959 { "msp430f5341",2,8 },
960 { "msp430f5342",2,8 },
961 { "msp430f5358",2,8 },
962 { "msp430f5359",2,8 },
963 { "msp430f5418",2,8 },
964 { "msp430f5418a",2,8 },
965 { "msp430f5419",2,8 },
966 { "msp430f5419a",2,8 },
967 { "msp430f5435",2,8 },
968 { "msp430f5435a",2,8 },
969 { "msp430f5436",2,8 },
970 { "msp430f5436a",2,8 },
971 { "msp430f5437",2,8 },
972 { "msp430f5437a",2,8 },
973 { "msp430f5438",2,8 },
974 { "msp430f5438a",2,8 },
975 { "msp430f5500",2,8 },
976 { "msp430f5501",2,8 },
977 { "msp430f5502",2,8 },
978 { "msp430f5503",2,8 },
979 { "msp430f5504",2,8 },
980 { "msp430f5505",2,8 },
981 { "msp430f5506",2,8 },
982 { "msp430f5507",2,8 },
983 { "msp430f5508",2,8 },
984 { "msp430f5509",2,8 },
985 { "msp430f5510",2,8 },
986 { "msp430f5513",2,8 },
987 { "msp430f5514",2,8 },
988 { "msp430f5515",2,8 },
989 { "msp430f5517",2,8 },
990 { "msp430f5519",2,8 },
991 { "msp430f5521",2,8 },
992 { "msp430f5522",2,8 },
993 { "msp430f5524",2,8 },
994 { "msp430f5525",2,8 },
995 { "msp430f5526",2,8 },
996 { "msp430f5527",2,8 },
997 { "msp430f5528",2,8 },
998 { "msp430f5529",2,8 },
999 { "msp430f5630",2,8 },
1000 { "msp430f5631",2,8 },
1001 { "msp430f5632",2,8 },
1002 { "msp430f5633",2,8 },
1003 { "msp430f5634",2,8 },
1004 { "msp430f5635",2,8 },
1005 { "msp430f5636",2,8 },
1006 { "msp430f5637",2,8 },
1007 { "msp430f5638",2,8 },
1008 { "msp430f5658",2,8 },
1009 { "msp430f5659",2,8 },
1010 { "msp430f5xx_6xxgeneric",2,8 },
1011 { "msp430f6433",2,8 },
1012 { "msp430f6435",2,8 },
1013 { "msp430f6436",2,8 },
1014 { "msp430f6438",2,8 },
1015 { "msp430f6458",2,8 },
1016 { "msp430f6459",2,8 },
1017 { "msp430f6630",2,8 },
1018 { "msp430f6631",2,8 },
1019 { "msp430f6632",2,8 },
1020 { "msp430f6633",2,8 },
1021 { "msp430f6634",2,8 },
1022 { "msp430f6635",2,8 },
1023 { "msp430f6636",2,8 },
1024 { "msp430f6637",2,8 },
1025 { "msp430f6638",2,8 },
1026 { "msp430f6658",2,8 },
1027 { "msp430f6659",2,8 },
1028 { "msp430f6720",2,8 },
1029 { "msp430f6720a",2,8 },
1030 { "msp430f6721",2,8 },
1031 { "msp430f6721a",2,8 },
1032 { "msp430f6723",2,8 },
1033 { "msp430f6723a",2,8 },
1034 { "msp430f6724",2,8 },
1035 { "msp430f6724a",2,8 },
1036 { "msp430f6725",2,8 },
1037 { "msp430f6725a",2,8 },
1038 { "msp430f6726",2,8 },
1039 { "msp430f6726a",2,8 },
1040 { "msp430f6730",2,8 },
1041 { "msp430f6730a",2,8 },
1042 { "msp430f6731",2,8 },
1043 { "msp430f6731a",2,8 },
1044 { "msp430f6733",2,8 },
1045 { "msp430f6733a",2,8 },
1046 { "msp430f6734",2,8 },
1047 { "msp430f6734a",2,8 },
1048 { "msp430f6735",2,8 },
1049 { "msp430f6735a",2,8 },
1050 { "msp430f6736",2,8 },
1051 { "msp430f6736a",2,8 },
1052 { "msp430f6745",2,8 },
1053 { "msp430f67451",2,8 },
1054 { "msp430f67451a",2,8 },
1055 { "msp430f6745a",2,8 },
1056 { "msp430f6746",2,8 },
1057 { "msp430f67461",2,8 },
1058 { "msp430f67461a",2,8 },
1059 { "msp430f6746a",2,8 },
1060 { "msp430f6747",2,8 },
1061 { "msp430f67471",2,8 },
1062 { "msp430f67471a",2,8 },
1063 { "msp430f6747a",2,8 },
1064 { "msp430f6748",2,8 },
1065 { "msp430f67481",2,8 },
1066 { "msp430f67481a",2,8 },
1067 { "msp430f6748a",2,8 },
1068 { "msp430f6749",2,8 },
1069 { "msp430f67491",2,8 },
1070 { "msp430f67491a",2,8 },
1071 { "msp430f6749a",2,8 },
1072 { "msp430f67621",2,8 },
1073 { "msp430f67621a",2,8 },
1074 { "msp430f67641",2,8 },
1075 { "msp430f67641a",2,8 },
1076 { "msp430f6765",2,8 },
1077 { "msp430f67651",2,8 },
1078 { "msp430f67651a",2,8 },
1079 { "msp430f6765a",2,8 },
1080 { "msp430f6766",2,8 },
1081 { "msp430f67661",2,8 },
1082 { "msp430f67661a",2,8 },
1083 { "msp430f6766a",2,8 },
1084 { "msp430f6767",2,8 },
1085 { "msp430f67671",2,8 },
1086 { "msp430f67671a",2,8 },
1087 { "msp430f6767a",2,8 },
1088 { "msp430f6768",2,8 },
1089 { "msp430f67681",2,8 },
1090 { "msp430f67681a",2,8 },
1091 { "msp430f6768a",2,8 },
1092 { "msp430f6769",2,8 },
1093 { "msp430f67691",2,8 },
1094 { "msp430f67691a",2,8 },
1095 { "msp430f6769a",2,8 },
1096 { "msp430f6775",2,8 },
1097 { "msp430f67751",2,8 },
1098 { "msp430f67751a",2,8 },
1099 { "msp430f6775a",2,8 },
1100 { "msp430f6776",2,8 },
1101 { "msp430f67761",2,8 },
1102 { "msp430f67761a",2,8 },
1103 { "msp430f6776a",2,8 },
1104 { "msp430f6777",2,8 },
1105 { "msp430f67771",2,8 },
1106 { "msp430f67771a",2,8 },
1107 { "msp430f6777a",2,8 },
1108 { "msp430f6778",2,8 },
1109 { "msp430f67781",2,8 },
1110 { "msp430f67781a",2,8 },
1111 { "msp430f6778a",2,8 },
1112 { "msp430f6779",2,8 },
1113 { "msp430f67791",2,8 },
1114 { "msp430f67791a",2,8 },
1115 { "msp430f6779a",2,8 },
1116 { "msp430fe423",0,0 },
1117 { "msp430fe4232",0,0 },
1118 { "msp430fe423a",0,0 },
1119 { "msp430fe4242",0,0 },
1120 { "msp430fe425",0,0 },
1121 { "msp430fe4252",0,0 },
1122 { "msp430fe425a",0,0 },
1123 { "msp430fe427",0,0 },
1124 { "msp430fe4272",0,0 },
1125 { "msp430fe427a",0,0 },
1126 { "msp430fg4250",0,0 },
1127 { "msp430fg4260",0,0 },
1128 { "msp430fg4270",0,0 },
1129 { "msp430fg437",0,0 },
1130 { "msp430fg438",0,0 },
1131 { "msp430fg439",0,0 },
1132 { "msp430fg4616",1,1 },
1133 { "msp430fg4617",1,1 },
1134 { "msp430fg4618",1,1 },
1135 { "msp430fg4619",1,1 },
1136 { "msp430fg477",0,0 },
1137 { "msp430fg478",0,0 },
1138 { "msp430fg479",0,0 },
1139 { "msp430fg6425",2,8 },
1140 { "msp430fg6426",2,8 },
1141 { "msp430fg6625",2,8 },
1142 { "msp430fg6626",2,8 },
1143 { "msp430fr2032",2,0 },
1144 { "msp430fr2033",2,0 },
1145 { "msp430fr2110",2,0 },
1146 { "msp430fr2111",2,0 },
1147 { "msp430fr2310",2,0 },
1148 { "msp430fr2311",2,0 },
1149 { "msp430fr2433",2,8 },
1150 { "msp430fr2532",2,8 },
1151 { "msp430fr2533",2,8 },
1152 { "msp430fr2632",2,8 },
1153 { "msp430fr2633",2,8 },
1154 { "msp430fr2xx_4xxgeneric",2,8 },
1155 { "msp430fr4131",2,0 },
1156 { "msp430fr4132",2,0 },
1157 { "msp430fr4133",2,0 },
1158 { "msp430fr5720",2,8 },
1159 { "msp430fr5721",2,8 },
1160 { "msp430fr5722",2,8 },
1161 { "msp430fr5723",2,8 },
1162 { "msp430fr5724",2,8 },
1163 { "msp430fr5725",2,8 },
1164 { "msp430fr5726",2,8 },
1165 { "msp430fr5727",2,8 },
1166 { "msp430fr5728",2,8 },
1167 { "msp430fr5729",2,8 },
1168 { "msp430fr5730",2,8 },
1169 { "msp430fr5731",2,8 },
1170 { "msp430fr5732",2,8 },
1171 { "msp430fr5733",2,8 },
1172 { "msp430fr5734",2,8 },
1173 { "msp430fr5735",2,8 },
1174 { "msp430fr5736",2,8 },
1175 { "msp430fr5737",2,8 },
1176 { "msp430fr5738",2,8 },
1177 { "msp430fr5739",2,8 },
1178 { "msp430fr57xxgeneric",2,8 },
1179 { "msp430fr5847",2,8 },
1180 { "msp430fr58471",2,8 },
1181 { "msp430fr5848",2,8 },
1182 { "msp430fr5849",2,8 },
1183 { "msp430fr5857",2,8 },
1184 { "msp430fr5858",2,8 },
1185 { "msp430fr5859",2,8 },
1186 { "msp430fr5867",2,8 },
1187 { "msp430fr58671",2,8 },
1188 { "msp430fr5868",2,8 },
1189 { "msp430fr5869",2,8 },
1190 { "msp430fr5870",2,8 },
1191 { "msp430fr5872",2,8 },
1192 { "msp430fr58721",2,8 },
1193 { "msp430fr5887",2,8 },
1194 { "msp430fr5888",2,8 },
1195 { "msp430fr5889",2,8 },
1196 { "msp430fr58891",2,8 },
1197 { "msp430fr5922",2,8 },
1198 { "msp430fr59221",2,8 },
1199 { "msp430fr5947",2,8 },
1200 { "msp430fr59471",2,8 },
1201 { "msp430fr5948",2,8 },
1202 { "msp430fr5949",2,8 },
1203 { "msp430fr5957",2,8 },
1204 { "msp430fr5958",2,8 },
1205 { "msp430fr5959",2,8 },
1206 { "msp430fr5962",2,8 },
1207 { "msp430fr5964",2,8 },
1208 { "msp430fr5967",2,8 },
1209 { "msp430fr5968",2,8 },
1210 { "msp430fr5969",2,8 },
1211 { "msp430fr59691",2,8 },
1212 { "msp430fr5970",2,8 },
1213 { "msp430fr5972",2,8 },
1214 { "msp430fr59721",2,8 },
1215 { "msp430fr5986",2,8 },
1216 { "msp430fr5987",2,8 },
1217 { "msp430fr5988",2,8 },
1218 { "msp430fr5989",2,8 },
1219 { "msp430fr59891",2,8 },
1220 { "msp430fr5992",2,8 },
1221 { "msp430fr5994",2,8 },
1222 { "msp430fr59941",2,8 },
1223 { "msp430fr5xx_6xxgeneric",2,8 },
1224 { "msp430fr6820",2,8 },
1225 { "msp430fr6822",2,8 },
1226 { "msp430fr68221",2,8 },
1227 { "msp430fr6870",2,8 },
1228 { "msp430fr6872",2,8 },
1229 { "msp430fr68721",2,8 },
1230 { "msp430fr6877",2,8 },
1231 { "msp430fr6879",2,8 },
1232 { "msp430fr68791",2,8 },
1233 { "msp430fr6887",2,8 },
1234 { "msp430fr6888",2,8 },
1235 { "msp430fr6889",2,8 },
1236 { "msp430fr68891",2,8 },
1237 { "msp430fr6920",2,8 },
1238 { "msp430fr6922",2,8 },
1239 { "msp430fr69221",2,8 },
1240 { "msp430fr6927",2,8 },
1241 { "msp430fr69271",2,8 },
1242 { "msp430fr6928",2,8 },
1243 { "msp430fr6970",2,8 },
1244 { "msp430fr6972",2,8 },
1245 { "msp430fr69721",2,8 },
1246 { "msp430fr6977",2,8 },
1247 { "msp430fr6979",2,8 },
1248 { "msp430fr69791",2,8 },
1249 { "msp430fr6987",2,8 },
1250 { "msp430fr6988",2,8 },
1251 { "msp430fr6989",2,8 },
1252 { "msp430fr69891",2,8 },
1253 { "msp430fw423",0,0 },
1254 { "msp430fw425",0,0 },
1255 { "msp430fw427",0,0 },
1256 { "msp430fw428",0,0 },
1257 { "msp430fw429",0,0 },
1258 { "msp430g2001",0,0 },
1259 { "msp430g2101",0,0 },
1260 { "msp430g2102",0,0 },
1261 { "msp430g2111",0,0 },
1262 { "msp430g2112",0,0 },
1263 { "msp430g2113",0,0 },
1264 { "msp430g2121",0,0 },
1265 { "msp430g2131",0,0 },
1266 { "msp430g2132",0,0 },
1267 { "msp430g2152",0,0 },
1268 { "msp430g2153",0,0 },
1269 { "msp430g2201",0,0 },
1270 { "msp430g2202",0,0 },
1271 { "msp430g2203",0,0 },
1272 { "msp430g2210",0,0 },
1273 { "msp430g2211",0,0 },
1274 { "msp430g2212",0,0 },
1275 { "msp430g2213",0,0 },
1276 { "msp430g2221",0,0 },
1277 { "msp430g2230",0,0 },
1278 { "msp430g2231",0,0 },
1279 { "msp430g2232",0,0 },
1280 { "msp430g2233",0,0 },
1281 { "msp430g2252",0,0 },
1282 { "msp430g2253",0,0 },
1283 { "msp430g2302",0,0 },
1284 { "msp430g2303",0,0 },
1285 { "msp430g2312",0,0 },
1286 { "msp430g2313",0,0 },
1287 { "msp430g2332",0,0 },
1288 { "msp430g2333",0,0 },
1289 { "msp430g2352",0,0 },
1290 { "msp430g2353",0,0 },
1291 { "msp430g2402",0,0 },
1292 { "msp430g2403",0,0 },
1293 { "msp430g2412",0,0 },
1294 { "msp430g2413",0,0 },
1295 { "msp430g2432",0,0 },
1296 { "msp430g2433",0,0 },
1297 { "msp430g2444",0,0 },
1298 { "msp430g2452",0,0 },
1299 { "msp430g2453",0,0 },
1300 { "msp430g2513",0,0 },
1301 { "msp430g2533",0,0 },
1302 { "msp430g2544",0,0 },
1303 { "msp430g2553",0,0 },
1304 { "msp430g2744",0,0 },
1305 { "msp430g2755",0,0 },
1306 { "msp430g2855",0,0 },
1307 { "msp430g2955",0,0 },
1308 { "msp430i2020",0,2 },
1309 { "msp430i2021",0,2 },
1310 { "msp430i2030",0,2 },
1311 { "msp430i2031",0,2 },
1312 { "msp430i2040",0,2 },
1313 { "msp430i2041",0,2 },
1314 { "msp430i2xxgeneric",0,2 },
1315 { "msp430l092",0,0 },
1316 { "msp430p112",0,0 },
1317 { "msp430p313",0,0 },
1318 { "msp430p315",0,0 },
1319 { "msp430p315s",0,0 },
1320 { "msp430p325",0,0 },
1321 { "msp430p337",0,1 },
1322 { "msp430sl5438a",2,8 },
1323 { "msp430tch5e",0,0 },
1324 { "msp430xgeneric",2,8 },
1325 { "rf430f5144",2,8 },
1326 { "rf430f5155",2,8 },
1327 { "rf430f5175",2,8 },
1328 { "rf430frl152h",0,0 },
1329 { "rf430frl152h_rom",0,0 },
1330 { "rf430frl153h",0,0 },
1331 { "rf430frl153h_rom",0,0 },
1332 { "rf430frl154h",0,0 },
1333 { "rf430frl154h_rom",0,0 }
1337 md_parse_option (int c
, const char * arg
)
1341 case OPTION_SILICON_ERRATA
:
1342 case OPTION_SILICON_ERRATA_WARN
:
1348 unsigned int length
;
1349 unsigned int bitfield
;
1352 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1353 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1354 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1355 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1356 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1357 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1362 for (i
= ARRAY_SIZE (erratas
); i
--;)
1363 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1365 if (c
== OPTION_SILICON_ERRATA
)
1366 silicon_errata_fix
|= erratas
[i
].bitfield
;
1368 silicon_errata_warn
|= erratas
[i
].bitfield
;
1369 arg
+= erratas
[i
].length
;
1374 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1380 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1390 as_fatal (_("MCU option requires a name\n"));
1392 if (strcasecmp ("msp430", arg
) == 0)
1393 selected_isa
= MSP_ISA_430
;
1394 else if (strcasecmp ("msp430xv2", arg
) == 0)
1395 selected_isa
= MSP_ISA_430Xv2
;
1396 else if (strcasecmp ("msp430x", arg
) == 0)
1397 selected_isa
= MSP_ISA_430X
;
1402 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1403 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1405 switch (msp430_mcu_data
[i
].revision
)
1407 case 0: selected_isa
= MSP_ISA_430
; break;
1408 case 1: selected_isa
= MSP_ISA_430X
; break;
1409 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1414 /* It is not an error if we do not match the MCU name. */
1418 if (strcmp (arg
, "430") == 0
1419 || strcasecmp (arg
, "msp430") == 0)
1420 selected_isa
= MSP_ISA_430
;
1421 else if (strcasecmp (arg
, "430x") == 0
1422 || strcasecmp (arg
, "msp430x") == 0)
1423 selected_isa
= MSP_ISA_430X
;
1424 else if (strcasecmp (arg
, "430xv2") == 0
1425 || strcasecmp (arg
, "msp430xv2") == 0)
1426 selected_isa
= MSP_ISA_430Xv2
;
1428 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1432 msp430_enable_relax
= 1;
1435 case OPTION_POLYMORPHS
:
1436 msp430_enable_polys
= 1;
1443 case OPTION_NO_INTR_NOPS
:
1444 gen_interrupt_nops
= FALSE
;
1446 case OPTION_INTR_NOPS
:
1447 gen_interrupt_nops
= TRUE
;
1450 case OPTION_WARN_INTR_NOPS
:
1451 warn_interrupt_nops
= TRUE
;
1453 case OPTION_NO_WARN_INTR_NOPS
:
1454 warn_interrupt_nops
= FALSE
;
1457 case OPTION_MOVE_DATA
:
1461 case OPTION_DATA_REGION
:
1462 if (strcmp (arg
, "upper") == 0
1463 || strcmp (arg
, "either") == 0)
1464 upper_data_region_in_use
= TRUE
;
1471 /* The intention here is to have the mere presence of these sections
1472 cause the object to have a reference to a well-known symbol. This
1473 reference pulls in the bits of the runtime (crt0) that initialize
1474 these sections. Thus, for example, the startup code to call
1475 memset() to initialize .bss will only be linked in when there is a
1476 non-empty .bss section. Otherwise, the call would exist but have a
1477 zero length parameter, which is a waste of memory and cycles.
1479 The code which initializes these sections should have a global
1480 label for these symbols, and should be marked with KEEP() in the
1484 msp430_make_init_symbols (const char * name
)
1486 if (strncmp (name
, ".bss", 4) == 0
1487 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1488 (void) symbol_find_or_make ("__crt0_init_bss");
1490 if (strncmp (name
, ".data", 5) == 0
1491 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1492 (void) symbol_find_or_make ("__crt0_movedata");
1494 /* Note - data assigned to the .either.data section may end up being
1495 placed in the .upper.data section if the .lower.data section is
1496 full. Hence the need to define the crt0 symbol.
1497 The linker may create upper or either data sections, even when none exist
1498 at the moment, so use the value of the data-region flag to determine if
1499 the symbol is needed. */
1500 if (strncmp (name
, ".either.data", 12) == 0
1501 || strncmp (name
, ".upper.data", 11) == 0
1502 || upper_data_region_in_use
)
1503 (void) symbol_find_or_make ("__crt0_move_highdata");
1505 /* See note about .either.data above. */
1506 if (strncmp (name
, ".upper.bss", 10) == 0
1507 || strncmp (name
, ".either.bss", 11) == 0
1508 || upper_data_region_in_use
)
1509 (void) symbol_find_or_make ("__crt0_init_highbss");
1513 msp430_section (int arg
)
1515 char * saved_ilp
= input_line_pointer
;
1516 const char * name
= obj_elf_section_name ();
1518 msp430_make_init_symbols (name
);
1520 input_line_pointer
= saved_ilp
;
1521 obj_elf_section (arg
);
1525 msp430_frob_section (asection
*sec
)
1527 const char *name
= sec
->name
;
1532 msp430_make_init_symbols (name
);
1536 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1538 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1541 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1542 (void) symbol_find_or_make ("__crt0_init_bss");
1546 msp430_comm (int needs_align
)
1548 s_comm_internal (needs_align
, elf_common_parse
);
1549 (void) symbol_find_or_make ("__crt0_init_bss");
1553 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1555 char sym_name
[1024];
1556 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1558 (void) symbol_find_or_make (sym_name
);
1561 const pseudo_typeS md_pseudo_table
[] =
1563 {"arch", msp430_set_arch
, OPTION_MMCU
},
1564 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1565 {"profiler", msp430_profiler
, 0},
1566 {"section", msp430_section
, 0},
1567 {"section.s", msp430_section
, 0},
1568 {"sect", msp430_section
, 0},
1569 {"sect.s", msp430_section
, 0},
1570 {"pushsection", msp430_section
, 1},
1571 {"refsym", msp430_refsym
, 0},
1572 {"comm", msp430_comm
, 0},
1573 {"lcomm", msp430_lcomm
, 0},
1577 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1579 struct option md_longopts
[] =
1581 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1582 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1583 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1584 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1585 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1586 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1587 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1588 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1589 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1590 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1591 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1592 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1593 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1594 {NULL
, no_argument
, NULL
, 0}
1597 size_t md_longopts_size
= sizeof (md_longopts
);
1600 md_show_usage (FILE * stream
)
1603 _("MSP430 options:\n"
1604 " -mmcu=<msp430-name> - select microcontroller type\n"
1605 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1607 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1608 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1609 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1611 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1612 " -mP - enable polymorph instructions\n"));
1614 _(" -ml - enable large code model\n"));
1616 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1618 _(" -mn - insert a NOP after changing interrupts\n"));
1620 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1622 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1624 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1626 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1631 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1637 extract_cmd (char * from
, char * to
, int limit
)
1641 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1643 *(to
+ size
) = *from
;
1654 md_atof (int type
, char * litP
, int * sizeP
)
1656 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1662 struct msp430_opcode_s
* opcode
;
1663 msp430_hash
= hash_new ();
1665 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1666 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1668 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1669 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1671 /* Set linkrelax here to avoid fixups in most sections. */
1675 static inline bfd_boolean
1676 is_regname_end (char c
)
1678 return (c
== 0 || ! ISALNUM (c
));
1681 /* Returns the register number equivalent to the string T.
1682 Returns -1 if there is no such register.
1683 Skips a leading 'r' or 'R' character if there is one.
1684 Handles the register aliases PC and SP. */
1687 check_reg (char * t
)
1690 signed long int val
;
1692 if (t
== NULL
|| t
[0] == 0)
1695 if (*t
== 'r' || *t
== 'R')
1698 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1701 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1704 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1707 if (*t
== '0' && is_regname_end (t
[1]))
1710 val
= strtol (t
, & endt
, 0);
1712 if (val
< 1 || val
> 15)
1715 if (is_regname_end (*endt
))
1722 msp430_srcoperand (struct msp430_operand_s
* op
,
1725 bfd_boolean
* imm_op
,
1726 bfd_boolean allow_20bit_values
,
1727 bfd_boolean constants_allowed
)
1732 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1739 /* Check if there is:
1740 llo(x) - least significant 16 bits, x &= 0xffff
1741 lhi(x) - x = (x >> 16) & 0xffff,
1742 hlo(x) - x = (x >> 32) & 0xffff,
1743 hhi(x) - x = (x >> 48) & 0xffff
1744 The value _MUST_ be constant expression: #hlo(1231231231). */
1748 if (strncasecmp (h
, "#llo(", 5) == 0)
1753 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1758 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1763 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1768 else if (strncasecmp (h
, "#lo(", 4) == 0)
1773 else if (strncasecmp (h
, "#hi(", 4) == 0)
1779 op
->reg
= 0; /* Reg PC. */
1781 op
->ol
= 1; /* Immediate will follow an instruction. */
1782 __tl
= h
+ 1 + rval
;
1784 op
->vshift
= vshift
;
1786 end
= parse_exp (__tl
, &(op
->exp
));
1787 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1789 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1792 if (op
->exp
.X_op
== O_constant
)
1794 int x
= op
->exp
.X_add_number
;
1799 op
->exp
.X_add_number
= x
;
1801 else if (vshift
== 1)
1803 x
= (x
>> 16) & 0xffff;
1804 op
->exp
.X_add_number
= x
;
1807 else if (vshift
> 1)
1810 op
->exp
.X_add_number
= -1;
1812 op
->exp
.X_add_number
= 0; /* Nothing left. */
1813 x
= op
->exp
.X_add_number
;
1817 if (allow_20bit_values
)
1819 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1821 as_bad (_("value 0x%x out of extended range."), x
);
1825 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1827 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1831 /* Now check constants. */
1832 /* Substitute register mode with a constant generator if applicable. */
1834 if (!allow_20bit_values
)
1835 x
= (short) x
; /* Extend sign. */
1837 if (! constants_allowed
)
1869 if (bin
== 0x1200 && ! target_is_430x ())
1871 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1872 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1873 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1874 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1886 if (bin
== 0x1200 && ! target_is_430x ())
1888 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1889 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1890 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1901 else if (op
->exp
.X_op
== O_symbol
)
1904 as_bad (_("error: unsupported #foo() directive used on symbol"));
1907 else if (op
->exp
.X_op
== O_big
)
1913 op
->exp
.X_op
= O_constant
;
1914 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1915 x
= op
->exp
.X_add_number
;
1921 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
1969 /* Redundant (yet) check. */
1970 else if (op
->exp
.X_op
== O_register
)
1972 (_("Registers cannot be used within immediate expression [%s]"), l
);
1974 as_bad (_("unknown operand %s"), l
);
1979 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1984 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1985 op
->am
= 1; /* mode As == 01 bin. */
1986 op
->ol
= 1; /* Immediate value followed by instruction. */
1988 end
= parse_exp (__tl
, &(op
->exp
));
1989 if (end
!= NULL
&& *end
!= 0)
1991 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
1996 if (op
->exp
.X_op
== O_constant
)
1998 int x
= op
->exp
.X_add_number
;
2000 if (allow_20bit_values
)
2002 if (x
> 0xfffff || x
< -(0x7ffff))
2004 as_bad (_("value 0x%x out of extended range."), x
);
2008 else if (x
> 65535 || x
< -32768)
2010 as_bad (_("value out of range: 0x%x"), x
);
2014 else if (op
->exp
.X_op
== O_symbol
)
2018 /* Redundant (yet) check. */
2019 if (op
->exp
.X_op
== O_register
)
2021 (_("Registers cannot be used within absolute expression [%s]"), l
);
2023 as_bad (_("unknown expression in operand %s"), l
);
2029 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2033 char *m
= strchr (l
, '+');
2037 as_bad (_("unknown addressing mode %s"), l
);
2043 if ((op
->reg
= check_reg (t
)) == -1)
2045 as_bad (_("Bad register name %s"), t
);
2053 /* PC cannot be used in indirect addressing. */
2054 if (target_is_430xv2 () && op
->reg
== 0)
2056 as_bad (_("cannot use indirect addressing with the PC"));
2063 /* Check if register indexed X(Rn). */
2066 char *h
= strrchr (l
, '(');
2067 char *m
= strrchr (l
, ')');
2076 as_bad (_("')' required"));
2084 /* Extract a register. */
2085 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2088 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2095 as_bad (_("r2 should not be used in indexed addressing mode"));
2099 /* Extract constant. */
2104 end
= parse_exp (__tl
, &(op
->exp
));
2105 if (end
!= NULL
&& *end
!= 0)
2107 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2110 if (op
->exp
.X_op
== O_constant
)
2112 int x
= op
->exp
.X_add_number
;
2114 if (allow_20bit_values
)
2116 if (x
> 0xfffff || x
< - (0x7ffff))
2118 as_bad (_("value 0x%x out of extended range."), x
);
2122 else if (x
> 65535 || x
< -32768)
2124 as_bad (_("value out of range: 0x%x"), x
);
2136 if (op
->reg
== 1 && (x
& 1))
2138 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2139 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2140 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2141 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2144 else if (op
->exp
.X_op
== O_symbol
)
2148 /* Redundant (yet) check. */
2149 if (op
->exp
.X_op
== O_register
)
2151 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2153 as_bad (_("unknown expression in operand %s"), l
);
2161 /* Possibly register mode 'mov r1,r2'. */
2162 if ((op
->reg
= check_reg (l
)) != -1)
2170 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2172 op
->reg
= 0; /* PC relative... be careful. */
2173 /* An expression starting with a minus sign is a constant, not an address. */
2174 op
->am
= (*l
== '-' ? 3 : 1);
2178 end
= parse_exp (__tl
, &(op
->exp
));
2179 if (end
!= NULL
&& * end
!= 0)
2181 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2189 msp430_dstoperand (struct msp430_operand_s
* op
,
2192 bfd_boolean allow_20bit_values
,
2193 bfd_boolean constants_allowed
)
2196 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2205 char *__tl
= (char *) "0";
2211 (void) parse_exp (__tl
, &(op
->exp
));
2213 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2215 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2225 ("this addressing mode is not applicable for destination operand"));
2231 /* Attempt to encode a MOVA instruction with the given operands.
2232 Returns the length of the encoded instruction if successful
2233 or 0 upon failure. If the encoding fails, an error message
2234 will be returned if a pointer is provided. */
2237 try_encode_mova (bfd_boolean imm_op
,
2239 struct msp430_operand_s
* op1
,
2240 struct msp430_operand_s
* op2
,
2241 const char ** error_message_return
)
2247 /* Only a restricted subset of the normal MSP430 addressing modes
2248 are supported here, so check for the ones that are allowed. */
2251 if (op1
->mode
== OP_EXP
)
2253 if (op2
->mode
!= OP_REG
)
2255 if (error_message_return
!= NULL
)
2256 * error_message_return
= _("expected register as second argument of %s");
2262 /* MOVA #imm20, Rdst. */
2263 bin
|= 0x80 | op2
->reg
;
2264 frag
= frag_more (4);
2265 where
= frag
- frag_now
->fr_literal
;
2266 if (op1
->exp
.X_op
== O_constant
)
2268 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2269 bfd_putl16 ((bfd_vma
) bin
, frag
);
2270 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2274 bfd_putl16 ((bfd_vma
) bin
, frag
);
2275 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2276 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2277 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2282 else if (op1
->am
== 1)
2284 /* MOVA z16(Rsrc), Rdst. */
2285 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2286 frag
= frag_more (4);
2287 where
= frag
- frag_now
->fr_literal
;
2288 bfd_putl16 ((bfd_vma
) bin
, frag
);
2289 if (op1
->exp
.X_op
== O_constant
)
2291 if (op1
->exp
.X_add_number
> 0xffff
2292 || op1
->exp
.X_add_number
< -(0x7fff))
2294 if (error_message_return
!= NULL
)
2295 * error_message_return
= _("index value too big for %s");
2298 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2302 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2303 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2305 BFD_RELOC_MSP430X_PCR16
:
2306 BFD_RELOC_MSP430X_ABS16
);
2311 if (error_message_return
!= NULL
)
2312 * error_message_return
= _("unexpected addressing mode for %s");
2315 else if (op1
->am
== 0)
2317 /* MOVA Rsrc, ... */
2318 if (op2
->mode
== OP_REG
)
2320 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2321 frag
= frag_more (2);
2322 where
= frag
- frag_now
->fr_literal
;
2323 bfd_putl16 ((bfd_vma
) bin
, frag
);
2326 else if (op2
->am
== 1)
2330 /* MOVA Rsrc, &abs20. */
2331 bin
|= 0x60 | (op1
->reg
<< 8);
2332 frag
= frag_more (4);
2333 where
= frag
- frag_now
->fr_literal
;
2334 if (op2
->exp
.X_op
== O_constant
)
2336 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2337 bfd_putl16 ((bfd_vma
) bin
, frag
);
2338 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2342 bfd_putl16 ((bfd_vma
) bin
, frag
);
2343 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2344 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2345 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2350 /* MOVA Rsrc, z16(Rdst). */
2351 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2352 frag
= frag_more (4);
2353 where
= frag
- frag_now
->fr_literal
;
2354 bfd_putl16 ((bfd_vma
) bin
, frag
);
2355 if (op2
->exp
.X_op
== O_constant
)
2357 if (op2
->exp
.X_add_number
> 0xffff
2358 || op2
->exp
.X_add_number
< -(0x7fff))
2360 if (error_message_return
!= NULL
)
2361 * error_message_return
= _("index value too big for %s");
2364 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2368 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2369 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2371 BFD_RELOC_MSP430X_PCR16
:
2372 BFD_RELOC_MSP430X_ABS16
);
2377 if (error_message_return
!= NULL
)
2378 * error_message_return
= _("unexpected addressing mode for %s");
2383 /* imm_op == FALSE. */
2385 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2387 /* MOVA &abs20, Rdst. */
2388 if (op2
->mode
!= OP_REG
)
2390 if (error_message_return
!= NULL
)
2391 * error_message_return
= _("expected register as second argument of %s");
2395 if (op2
->reg
== 2 || op2
->reg
== 3)
2397 if (error_message_return
!= NULL
)
2398 * error_message_return
= _("constant generator destination register found in %s");
2402 bin
|= 0x20 | op2
->reg
;
2403 frag
= frag_more (4);
2404 where
= frag
- frag_now
->fr_literal
;
2405 if (op1
->exp
.X_op
== O_constant
)
2407 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2408 bfd_putl16 ((bfd_vma
) bin
, frag
);
2409 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2413 bfd_putl16 ((bfd_vma
) bin
, frag
);
2414 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2415 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2416 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2420 else if (op1
->mode
== OP_REG
)
2424 /* MOVA @Rsrc+, Rdst. */
2425 if (op2
->mode
!= OP_REG
)
2427 if (error_message_return
!= NULL
)
2428 * error_message_return
= _("expected register as second argument of %s");
2432 if (op2
->reg
== 2 || op2
->reg
== 3)
2434 if (error_message_return
!= NULL
)
2435 * error_message_return
= _("constant generator destination register found in %s");
2439 if (op1
->reg
== 2 || op1
->reg
== 3)
2441 if (error_message_return
!= NULL
)
2442 * error_message_return
= _("constant generator source register found in %s");
2446 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2447 frag
= frag_more (2);
2448 where
= frag
- frag_now
->fr_literal
;
2449 bfd_putl16 ((bfd_vma
) bin
, frag
);
2452 else if (op1
->am
== 2)
2454 /* MOVA @Rsrc,Rdst */
2455 if (op2
->mode
!= OP_REG
)
2457 if (error_message_return
!= NULL
)
2458 * error_message_return
= _("expected register as second argument of %s");
2462 if (op2
->reg
== 2 || op2
->reg
== 3)
2464 if (error_message_return
!= NULL
)
2465 * error_message_return
= _("constant generator destination register found in %s");
2469 if (op1
->reg
== 2 || op1
->reg
== 3)
2471 if (error_message_return
!= NULL
)
2472 * error_message_return
= _("constant generator source register found in %s");
2476 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2477 frag
= frag_more (2);
2478 where
= frag
- frag_now
->fr_literal
;
2479 bfd_putl16 ((bfd_vma
) bin
, frag
);
2484 if (error_message_return
!= NULL
)
2485 * error_message_return
= _("unexpected addressing mode for %s");
2490 #define NOP_CHECK_INTERRUPT (1 << 0)
2491 #define NOP_CHECK_CPU12 (1 << 1)
2492 #define NOP_CHECK_CPU19 (1 << 2)
2494 static signed int check_for_nop
= 0;
2496 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2498 /* Parse instruction operands.
2499 Return binary opcode. */
2502 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2504 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2505 int insn_length
= 0;
2506 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2510 struct msp430_operand_s op1
, op2
;
2512 static short ZEROS
= 0;
2513 bfd_boolean byte_op
, imm_op
;
2516 int extended
= 0x1800;
2517 bfd_boolean extended_op
= FALSE
;
2518 bfd_boolean addr_op
;
2519 const char * error_message
;
2520 static signed int repeat_count
= 0;
2521 static bfd_boolean prev_insn_is_nop
= FALSE
;
2522 bfd_boolean fix_emitted
;
2524 /* Opcode is the one from opcodes table
2525 line contains something like
2534 bfd_boolean check
= FALSE
;
2537 switch (TOLOWER (* line
))
2540 /* Byte operation. */
2541 bin
|= BYTE_OPERATION
;
2547 /* "Address" ops work on 20-bit values. */
2549 bin
|= BYTE_OPERATION
;
2554 /* Word operation - this is the default. */
2562 as_warn (_("no size modifier after period, .w assumed"));
2566 as_bad (_("unrecognised instruction size modifier .%c"),
2578 if (*line
&& ! ISSPACE (*line
))
2580 as_bad (_("junk found after instruction: %s.%s"),
2581 opcode
->name
, line
);
2585 /* Catch the case where the programmer has used a ".a" size modifier on an
2586 instruction that does not support it. Look for an alternative extended
2587 instruction that has the same name without the period. Eg: "add.a"
2588 becomes "adda". Although this not an officially supported way of
2589 specifying instruction aliases other MSP430 assemblers allow it. So we
2590 support it for compatibility purposes. */
2591 if (addr_op
&& opcode
->fmt
>= 0)
2593 const char * old_name
= opcode
->name
;
2596 sprintf (real_name
, "%sa", old_name
);
2597 opcode
= hash_find (msp430_hash
, real_name
);
2600 as_bad (_("instruction %s.a does not exist"), old_name
);
2603 #if 0 /* Enable for debugging. */
2604 as_warn ("treating %s.a as %s", old_name
, real_name
);
2607 bin
= opcode
->bin_opcode
;
2610 if (opcode
->fmt
!= -1
2611 && opcode
->insn_opnumb
2612 && (!*line
|| *line
== '\n'))
2614 as_bad (ngettext ("instruction %s requires %d operand",
2615 "instruction %s requires %d operands",
2616 opcode
->insn_opnumb
),
2617 opcode
->name
, opcode
->insn_opnumb
);
2621 memset (l1
, 0, sizeof (l1
));
2622 memset (l2
, 0, sizeof (l2
));
2623 memset (&op1
, 0, sizeof (op1
));
2624 memset (&op2
, 0, sizeof (op2
));
2628 if ((fmt
= opcode
->fmt
) < 0)
2630 if (! target_is_430x ())
2632 as_bad (_("instruction %s requires MSP430X mcu"),
2643 /* If requested set the extended instruction repeat count. */
2646 if (repeat_count
> 0)
2647 extended
|= (repeat_count
- 1);
2649 extended
|= (1 << 7) | (- repeat_count
);
2652 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2659 if (! is_opcode ("nop"))
2661 bfd_boolean doit
= FALSE
;
2665 switch (check_for_nop
& - check_for_nop
)
2667 case NOP_CHECK_INTERRUPT
:
2668 if (warn_interrupt_nops
)
2670 if (gen_interrupt_nops
)
2671 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2673 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2676 if (gen_interrupt_nops
)
2677 /* Emit a NOP between interrupt enable/disable.
2678 See 1.3.4.1 of the MSP430x5xx User Guide. */
2682 case NOP_CHECK_CPU12
:
2683 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2684 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2686 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2690 case NOP_CHECK_CPU19
:
2691 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2692 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2694 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2699 as_bad (_("internal error: unknown nop check state"));
2702 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2704 while (check_for_nop
);
2708 frag
= frag_more (2);
2709 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2710 dwarf2_emit_insn (2);
2719 case 0: /* Emulated. */
2720 switch (opcode
->insn_opnumb
)
2723 if (is_opcode ("eint"))
2725 if (! prev_insn_is_nop
)
2727 if (gen_interrupt_nops
)
2729 frag
= frag_more (2);
2730 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2731 dwarf2_emit_insn (2);
2733 if (warn_interrupt_nops
)
2734 as_warn (_("inserting a NOP before EINT"));
2736 else if (warn_interrupt_nops
)
2737 as_warn (_("a NOP might be needed before the EINT"));
2740 else if (is_opcode ("dint"))
2741 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2743 /* Set/clear bits instructions. */
2747 extended
|= BYTE_OPERATION
;
2749 /* Emit the extension word. */
2751 frag
= frag_more (2);
2752 bfd_putl16 (extended
, frag
);
2756 frag
= frag_more (2);
2757 bfd_putl16 ((bfd_vma
) bin
, frag
);
2758 dwarf2_emit_insn (insn_length
);
2762 /* Something which works with destination operand. */
2763 line
= extract_operand (line
, l1
, sizeof (l1
));
2764 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2768 bin
|= (op1
.reg
| (op1
.am
<< 7));
2770 /* If the PC is the destination... */
2771 if (op1
.am
== 0 && op1
.reg
== 0
2772 /* ... and the opcode alters the SR. */
2773 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2774 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2776 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2777 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2778 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2779 as_warn (_("CPU11: PC is destination of SR altering instruction"));
2782 /* If the status register is the destination... */
2783 if (op1
.am
== 0 && op1
.reg
== 2
2784 /* ... and the opcode alters the SR. */
2785 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2786 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2787 || is_opcode ("sbc") || is_opcode ("sxt")
2788 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2789 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2790 || is_opcode ("sbcx")
2793 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2794 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2795 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2796 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2799 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2800 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2802 /* Compute the entire instruction length, in bytes. */
2803 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2804 insn_length
+= op_length
;
2805 frag
= frag_more (op_length
);
2806 where
= frag
- frag_now
->fr_literal
;
2811 extended
|= BYTE_OPERATION
;
2813 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2815 as_bad (_("repeat instruction used with non-register mode instruction"));
2819 if (op1
.mode
== OP_EXP
)
2821 if (op1
.exp
.X_op
== O_constant
)
2822 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2824 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2825 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2826 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2828 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2829 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2832 /* Emit the extension word. */
2833 bfd_putl16 (extended
, frag
);
2838 bfd_putl16 ((bfd_vma
) bin
, frag
);
2842 if (op1
.mode
== OP_EXP
)
2844 if (op1
.exp
.X_op
== O_constant
)
2846 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2850 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2855 fix_new_exp (frag_now
, where
, 2,
2856 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2858 fix_new_exp (frag_now
, where
, 2,
2859 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2864 dwarf2_emit_insn (insn_length
);
2868 /* Shift instruction. */
2869 line
= extract_operand (line
, l1
, sizeof (l1
));
2870 strncpy (l2
, l1
, sizeof (l2
));
2871 l2
[sizeof (l2
) - 1] = '\0';
2872 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2873 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2876 break; /* An error occurred. All warnings were done before. */
2878 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2879 frag
= frag_more (insn_length
);
2880 where
= frag
- frag_now
->fr_literal
;
2882 if (target_is_430xv2 ()
2883 && op1
.mode
== OP_REG
2885 && (is_opcode ("rlax")
2886 || is_opcode ("rlcx")
2887 || is_opcode ("rla")
2888 || is_opcode ("rlc")))
2890 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2894 /* If the status register is the destination... */
2895 if (op1
.am
== 0 && op1
.reg
== 2
2896 /* ... and the opcode alters the SR. */
2897 && (is_opcode ("rla") || is_opcode ("rlc")
2898 || is_opcode ("rlax") || is_opcode ("rlcx")
2901 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2902 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2903 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2904 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2910 extended
|= BYTE_OPERATION
;
2912 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2914 as_bad (_("repeat instruction used with non-register mode instruction"));
2918 if (op1
.mode
== OP_EXP
)
2920 if (op1
.exp
.X_op
== O_constant
)
2921 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2923 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2924 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2925 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2927 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2928 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2931 if (op2
.mode
== OP_EXP
)
2933 if (op2
.exp
.X_op
== O_constant
)
2934 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2936 else if (op1
.mode
== OP_EXP
)
2937 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2938 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2939 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2941 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2942 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2943 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2946 /* Emit the extension word. */
2947 bfd_putl16 (extended
, frag
);
2952 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2953 bfd_putl16 ((bfd_vma
) bin
, frag
);
2957 if (op1
.mode
== OP_EXP
)
2959 if (op1
.exp
.X_op
== O_constant
)
2961 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2965 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2969 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2970 fix_new_exp (frag_now
, where
, 2,
2971 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2973 fix_new_exp (frag_now
, where
, 2,
2974 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2981 if (op2
.mode
== OP_EXP
)
2983 if (op2
.exp
.X_op
== O_constant
)
2985 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2989 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2993 if (op2
.reg
) /* Not PC relative. */
2994 fix_new_exp (frag_now
, where
, 2,
2995 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2997 fix_new_exp (frag_now
, where
, 2,
2998 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3003 dwarf2_emit_insn (insn_length
);
3007 /* Branch instruction => mov dst, r0. */
3010 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3014 line
= extract_operand (line
, l1
, sizeof (l1
));
3015 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3021 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3022 op_length
= 2 + 2 * op1
.ol
;
3023 frag
= frag_more (op_length
);
3024 where
= frag
- frag_now
->fr_literal
;
3025 bfd_putl16 ((bfd_vma
) bin
, frag
);
3027 if (op1
.mode
== OP_EXP
)
3029 if (op1
.exp
.X_op
== O_constant
)
3031 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3037 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3039 if (op1
.reg
|| op1
.am
== 3)
3040 fix_new_exp (frag_now
, where
, 2,
3041 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3043 fix_new_exp (frag_now
, where
, 2,
3044 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3048 dwarf2_emit_insn (insn_length
+ op_length
);
3052 /* CALLA instructions. */
3053 fix_emitted
= FALSE
;
3055 line
= extract_operand (line
, l1
, sizeof (l1
));
3058 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3059 extended_op
, FALSE
);
3065 op_length
= 2 + 2 * op1
.ol
;
3066 frag
= frag_more (op_length
);
3067 where
= frag
- frag_now
->fr_literal
;
3075 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3076 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3079 else if (op1
.am
== 1)
3085 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3086 BFD_RELOC_MSP430X_PCR20_CALL
);
3090 bin
|= 0x50 | op1
.reg
;
3092 else if (op1
.am
== 0)
3093 bin
|= 0x40 | op1
.reg
;
3095 else if (op1
.am
== 1)
3099 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3100 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3103 else if (op1
.am
== 2)
3104 bin
|= 0x60 | op1
.reg
;
3105 else if (op1
.am
== 3)
3106 bin
|= 0x70 | op1
.reg
;
3108 bfd_putl16 ((bfd_vma
) bin
, frag
);
3110 if (op1
.mode
== OP_EXP
)
3114 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3118 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3121 fix_new_exp (frag_now
, where
+ 2, 2,
3122 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3125 dwarf2_emit_insn (insn_length
+ op_length
);
3133 /* [POP|PUSH]M[.A] #N, Rd */
3134 line
= extract_operand (line
, l1
, sizeof (l1
));
3135 line
= extract_operand (line
, l2
, sizeof (l2
));
3139 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3142 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3143 if (end
!= NULL
&& *end
!= 0)
3145 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3148 if (op1
.exp
.X_op
!= O_constant
)
3150 as_bad (_("expected constant expression as first argument of %s"),
3155 if ((reg
= check_reg (l2
)) == -1)
3157 as_bad (_("expected register as second argument of %s"),
3163 frag
= frag_more (op_length
);
3164 where
= frag
- frag_now
->fr_literal
;
3165 bin
= opcode
->bin_opcode
;
3168 n
= op1
.exp
.X_add_number
;
3169 bin
|= (n
- 1) << 4;
3170 if (is_opcode ("pushm"))
3174 if (reg
- n
+ 1 < 0)
3176 as_bad (_("Too many registers popped"));
3180 /* CPU21 errata: cannot use POPM to restore the SR register. */
3181 if (target_is_430xv2 ()
3182 && (reg
- n
+ 1 < 3)
3184 && is_opcode ("popm"))
3186 as_bad (_("Cannot use POPM to restore the SR register"));
3190 bin
|= (reg
- n
+ 1);
3193 bfd_putl16 ((bfd_vma
) bin
, frag
);
3194 dwarf2_emit_insn (op_length
);
3203 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3204 if (extended
& 0xff)
3206 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3210 line
= extract_operand (line
, l1
, sizeof (l1
));
3211 line
= extract_operand (line
, l2
, sizeof (l2
));
3215 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3218 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3219 if (end
!= NULL
&& *end
!= 0)
3221 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3224 if (op1
.exp
.X_op
!= O_constant
)
3226 as_bad (_("expected constant expression as first argument of %s"),
3230 n
= op1
.exp
.X_add_number
;
3233 as_bad (_("expected first argument of %s to be in the range 1-4"),
3238 if ((reg
= check_reg (l2
)) == -1)
3240 as_bad (_("expected register as second argument of %s"),
3245 if (target_is_430xv2 () && reg
== 0)
3247 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3252 frag
= frag_more (op_length
);
3253 where
= frag
- frag_now
->fr_literal
;
3255 bin
= opcode
->bin_opcode
;
3258 bin
|= (n
- 1) << 10;
3261 bfd_putl16 ((bfd_vma
) bin
, frag
);
3262 dwarf2_emit_insn (op_length
);
3268 bfd_boolean need_reloc
= FALSE
;
3272 /* ADDA, CMPA and SUBA address instructions. */
3273 if (extended
& 0xff)
3275 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3279 line
= extract_operand (line
, l1
, sizeof (l1
));
3280 line
= extract_operand (line
, l2
, sizeof (l2
));
3282 bin
= opcode
->bin_opcode
;
3286 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3287 if (end
!= NULL
&& *end
!= 0)
3289 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3293 if (op1
.exp
.X_op
== O_constant
)
3295 n
= op1
.exp
.X_add_number
;
3296 if (n
> 0xfffff || n
< - (0x7ffff))
3298 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3303 bin
|= ((n
>> 16) & 0xf) << 8;
3315 if ((n
= check_reg (l1
)) == -1)
3317 as_bad (_("expected register name or constant as first argument of %s"),
3322 bin
|= (n
<< 8) | (1 << 6);
3326 if ((reg
= check_reg (l2
)) == -1)
3328 as_bad (_("expected register as second argument of %s"),
3333 frag
= frag_more (op_length
);
3334 where
= frag
- frag_now
->fr_literal
;
3337 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3338 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3340 bfd_putl16 ((bfd_vma
) bin
, frag
);
3342 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3343 dwarf2_emit_insn (op_length
);
3347 case 9: /* MOVA, BRA, RETA. */
3349 bin
= opcode
->bin_opcode
;
3351 if (is_opcode ("reta"))
3353 /* The RETA instruction does not take any arguments.
3354 The implicit first argument is @SP+.
3355 The implicit second argument is PC. */
3365 line
= extract_operand (line
, l1
, sizeof (l1
));
3366 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3367 &imm_op
, extended_op
, FALSE
);
3369 if (is_opcode ("bra"))
3371 /* This is the BRA synthetic instruction.
3372 The second argument is always PC. */
3378 line
= extract_operand (line
, l2
, sizeof (l2
));
3379 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3384 break; /* Error occurred. All warnings were done before. */
3387 /* Only a restricted subset of the normal MSP430 addressing modes
3388 are supported here, so check for the ones that are allowed. */
3389 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3390 & error_message
)) == 0)
3392 as_bad (error_message
, opcode
->name
);
3395 dwarf2_emit_insn (op_length
);
3399 line
= extract_operand (line
, l1
, sizeof l1
);
3400 /* The RPT instruction only accepted immediates and registers. */
3403 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3404 if (end
!= NULL
&& *end
!= 0)
3406 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3409 if (op1
.exp
.X_op
!= O_constant
)
3411 as_bad (_("expected constant value as argument to RPT"));
3414 if (op1
.exp
.X_add_number
< 1
3415 || op1
.exp
.X_add_number
> (1 << 4))
3417 as_bad (_("expected constant in the range 2..16"));
3421 /* We silently accept and ignore a repeat count of 1. */
3422 if (op1
.exp
.X_add_number
> 1)
3423 repeat_count
= op1
.exp
.X_add_number
;
3429 if ((reg
= check_reg (l1
)) != -1)
3432 as_warn (_("PC used as an argument to RPT"));
3434 repeat_count
= - reg
;
3438 as_bad (_("expected constant or register name as argument to RPT insn"));
3445 as_bad (_("Illegal emulated instruction"));
3450 case 1: /* Format 1, double operand. */
3451 line
= extract_operand (line
, l1
, sizeof (l1
));
3452 line
= extract_operand (line
, l2
, sizeof (l2
));
3453 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3454 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3457 break; /* Error occurred. All warnings were done before. */
3460 && is_opcode ("movx")
3462 && msp430_enable_relax
)
3464 /* This is the MOVX.A instruction. See if we can convert
3465 it into the MOVA instruction instead. This saves 2 bytes. */
3466 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3469 dwarf2_emit_insn (op_length
);
3474 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3476 /* If the PC is the destination... */
3477 if (op2
.am
== 0 && op2
.reg
== 0
3478 /* ... and the opcode alters the SR. */
3479 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3480 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3482 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3483 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3484 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3485 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3488 /* If the status register is the destination... */
3489 if (op2
.am
== 0 && op2
.reg
== 2
3490 /* ... and the opcode alters the SR. */
3491 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3492 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3493 || is_opcode ("xor")
3494 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3495 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3496 || is_opcode ("xorx")
3499 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3500 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3501 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3502 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3505 if ( (is_opcode ("bic") && bin
== 0xc232)
3506 || (is_opcode ("bis") && bin
== 0xd232)
3507 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3509 /* Avoid false checks when a constant value is being put into the SR. */
3510 if (op1
.mode
== OP_EXP
3511 && op1
.exp
.X_op
== O_constant
3512 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3515 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3518 if (((is_opcode ("bis") && bin
== 0xd032)
3519 || (is_opcode ("mov") && bin
== 0x4032)
3520 || (is_opcode ("xor") && bin
== 0xe032))
3521 && op1
.mode
== OP_EXP
3522 && op1
.exp
.X_op
== O_constant
3523 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3524 check_for_nop
|= NOP_CHECK_CPU19
;
3526 /* Compute the entire length of the instruction in bytes. */
3527 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3528 + 2 /* The opcode */
3529 + (2 * op1
.ol
) /* The first operand. */
3530 + (2 * op2
.ol
); /* The second operand. */
3532 insn_length
+= op_length
;
3533 frag
= frag_more (op_length
);
3534 where
= frag
- frag_now
->fr_literal
;
3539 extended
|= BYTE_OPERATION
;
3541 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3543 as_bad (_("repeat instruction used with non-register mode instruction"));
3547 /* If necessary, emit a reloc to update the extension word. */
3548 if (op1
.mode
== OP_EXP
)
3550 if (op1
.exp
.X_op
== O_constant
)
3551 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3553 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3554 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3555 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3557 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3558 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3561 if (op2
.mode
== OP_EXP
)
3563 if (op2
.exp
.X_op
== O_constant
)
3564 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3566 else if (op1
.mode
== OP_EXP
)
3567 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3568 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3569 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3572 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3573 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3574 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3577 /* Emit the extension word. */
3578 bfd_putl16 (extended
, frag
);
3583 bfd_putl16 ((bfd_vma
) bin
, frag
);
3587 if (op1
.mode
== OP_EXP
)
3589 if (op1
.exp
.X_op
== O_constant
)
3591 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3595 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3599 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3600 fix_new_exp (frag_now
, where
, 2,
3601 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3603 fix_new_exp (frag_now
, where
, 2,
3604 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3612 if (op2
.mode
== OP_EXP
)
3614 if (op2
.exp
.X_op
== O_constant
)
3616 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3620 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3624 if (op2
.reg
) /* Not PC relative. */
3625 fix_new_exp (frag_now
, where
, 2,
3626 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3628 fix_new_exp (frag_now
, where
, 2,
3629 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3634 dwarf2_emit_insn (insn_length
);
3636 /* If the PC is the destination... */
3637 if (op2
.am
== 0 && op2
.reg
== 0
3638 /* ... but the opcode does not alter the destination. */
3639 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3640 check_for_nop
|= NOP_CHECK_CPU12
;
3643 case 2: /* Single-operand mostly instr. */
3644 if (opcode
->insn_opnumb
== 0)
3646 /* reti instruction. */
3648 frag
= frag_more (2);
3649 bfd_putl16 ((bfd_vma
) bin
, frag
);
3650 dwarf2_emit_insn (insn_length
);
3654 line
= extract_operand (line
, l1
, sizeof (l1
));
3655 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3656 &imm_op
, extended_op
, TRUE
);
3658 break; /* Error in operand. */
3660 if (target_is_430xv2 ()
3661 && op1
.mode
== OP_REG
3663 && (is_opcode ("rrax")
3664 || is_opcode ("rrcx")
3665 || is_opcode ("rra")
3666 || is_opcode ("rrc")))
3668 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3672 /* If the status register is the destination... */
3673 if (op1
.am
== 0 && op1
.reg
== 2
3674 /* ... and the opcode alters the SR. */
3675 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3677 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3678 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3679 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3680 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3683 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3684 frag
= frag_more (insn_length
);
3685 where
= frag
- frag_now
->fr_literal
;
3689 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3691 /* These two instructions use a special
3692 encoding of the A/L and B/W bits. */
3693 bin
&= ~ BYTE_OPERATION
;
3697 as_bad (_("%s instruction does not accept a .b suffix"),
3702 extended
|= BYTE_OPERATION
;
3705 extended
|= BYTE_OPERATION
;
3707 if (is_opcode ("rrux"))
3708 extended
|= IGNORE_CARRY_BIT
;
3710 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3712 as_bad (_("repeat instruction used with non-register mode instruction"));
3716 if (op1
.mode
== OP_EXP
)
3718 if (op1
.exp
.X_op
== O_constant
)
3719 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3721 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3722 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3723 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3725 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3726 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3729 /* Emit the extension word. */
3730 bfd_putl16 (extended
, frag
);
3735 bin
|= op1
.reg
| (op1
.am
<< 4);
3736 bfd_putl16 ((bfd_vma
) bin
, frag
);
3740 if (op1
.mode
== OP_EXP
)
3742 if (op1
.exp
.X_op
== O_constant
)
3744 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3748 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3752 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3753 fix_new_exp (frag_now
, where
, 2,
3754 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3756 fix_new_exp (frag_now
, where
, 2,
3757 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3762 dwarf2_emit_insn (insn_length
);
3765 case 3: /* Conditional jumps instructions. */
3766 line
= extract_operand (line
, l1
, sizeof (l1
));
3767 /* l1 is a label. */
3776 end
= parse_exp (m
, &exp
);
3777 if (end
!= NULL
&& *end
!= 0)
3779 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3783 /* In order to handle something like:
3787 jz 4 ; skip next 4 bytes
3790 nop ; will jump here if r5 positive or zero
3792 jCOND -n ;assumes jump n bytes backward:
3802 jCOND $n ; jump from PC in either direction. */
3804 if (exp
.X_op
== O_constant
)
3806 int x
= exp
.X_add_number
;
3810 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3814 if ((*l1
== '$' && x
> 0) || x
< 0)
3819 if (x
> 512 || x
< -511)
3821 as_bad (_("Wrong displacement %d"), x
<< 1);
3826 frag
= frag_more (2); /* Instr size is 1 word. */
3829 bfd_putl16 ((bfd_vma
) bin
, frag
);
3831 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3834 frag
= frag_more (2); /* Instr size is 1 word. */
3835 where
= frag
- frag_now
->fr_literal
;
3836 fix_new_exp (frag_now
, where
, 2,
3837 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3839 bfd_putl16 ((bfd_vma
) bin
, frag
);
3841 else if (*l1
== '$')
3843 as_bad (_("instruction requires label sans '$'"));
3847 ("instruction requires label or value in range -511:512"));
3848 dwarf2_emit_insn (insn_length
);
3853 as_bad (_("instruction requires label"));
3858 case 4: /* Extended jumps. */
3859 if (!msp430_enable_polys
)
3861 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3865 line
= extract_operand (line
, l1
, sizeof (l1
));
3871 /* Ignore absolute addressing. make it PC relative anyway. */
3872 if (*m
== '#' || *m
== '$')
3875 end
= parse_exp (m
, & exp
);
3876 if (end
!= NULL
&& *end
!= 0)
3878 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3881 if (exp
.X_op
== O_symbol
)
3883 /* Relaxation required. */
3884 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3886 if (target_is_430x ())
3887 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3889 /* The parameter to dwarf2_emit_insn is actually the offset to
3890 the start of the insn from the fix piece of instruction that
3891 was emitted. Since next fragments may have variable size we
3892 tie debug info to the beginning of the instruction. */
3894 frag
= frag_more (8);
3895 dwarf2_emit_insn (0);
3896 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3897 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3899 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3901 0, /* Offset is zero if jump dist less than 1K. */
3907 as_bad (_("instruction requires label"));
3910 case 5: /* Emulated extended branches. */
3911 if (!msp430_enable_polys
)
3913 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3916 line
= extract_operand (line
, l1
, sizeof (l1
));
3922 /* Ignore absolute addressing. make it PC relative anyway. */
3923 if (*m
== '#' || *m
== '$')
3926 end
= parse_exp (m
, & exp
);
3927 if (end
!= NULL
&& *end
!= 0)
3929 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3932 if (exp
.X_op
== O_symbol
)
3934 /* Relaxation required. */
3935 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3937 if (target_is_430x ())
3938 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3941 frag
= frag_more (8);
3942 dwarf2_emit_insn (0);
3943 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3944 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3946 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3947 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3949 0, /* Offset is zero if jump dist less than 1K. */
3955 as_bad (_("instruction requires label"));
3959 as_bad (_("Illegal instruction or not implemented opcode."));
3962 if (is_opcode ("nop"))
3963 prev_insn_is_nop
= TRUE
;
3965 prev_insn_is_nop
= FALSE
;
3967 input_line_pointer
= line
;
3972 md_assemble (char * str
)
3974 struct msp430_opcode_s
* opcode
;
3978 str
= skip_space (str
); /* Skip leading spaces. */
3979 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3983 char a
= TOLOWER (cmd
[i
]);
3990 as_bad (_("can't find opcode"));
3994 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3998 as_bad (_("unknown opcode `%s'"), cmd
);
4003 char *__t
= input_line_pointer
;
4005 msp430_operands (opcode
, str
);
4006 input_line_pointer
= __t
;
4010 /* GAS will call this function for each section at the end of the assembly,
4011 to permit the CPU backend to adjust the alignment of a section. */
4014 md_section_align (asection
* seg
, valueT addr
)
4016 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4018 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4021 /* If you define this macro, it should return the offset between the
4022 address of a PC relative fixup and the position from which the PC
4023 relative adjustment should be made. On many processors, the base
4024 of a PC relative instruction is the next instruction, so this
4025 macro would return the length of an instruction. */
4028 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4030 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4031 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4032 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4035 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4038 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4039 Now it handles the situation when relocations
4040 have to be passed to linker. */
4042 msp430_force_relocation_local (fixS
*fixp
)
4044 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4048 if (msp430_enable_polys
4049 && !msp430_enable_relax
)
4056 /* GAS will call this for each fixup. It should store the correct
4057 value in the object file. */
4059 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4061 unsigned char * where
;
4065 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4070 else if (fixp
->fx_pcrel
)
4072 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4074 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4076 /* FIXME: We can appear here only in case if we perform a pc
4077 relative jump to the label which is i) global, ii) locally
4078 defined or this is a jump to an absolute symbol.
4079 If this is an absolute symbol -- everything is OK.
4080 If this is a global label, we've got a symbol value defined
4082 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4083 from this section start
4084 2. *valuep will contain the real offset from jump insn to the
4086 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4087 will be incorrect. Therefore remove s_get_value. */
4088 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4096 value
= fixp
->fx_offset
;
4098 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4100 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4102 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4108 fixp
->fx_no_overflow
= 1;
4110 /* If polymorphs are enabled and relax disabled.
4111 do not kill any relocs and pass them to linker. */
4112 if (msp430_enable_polys
4113 && !msp430_enable_relax
)
4116 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4117 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4124 /* Fetch the instruction, insert the fully resolved operand
4125 value, and stuff the instruction back again. */
4126 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4128 insn
= bfd_getl16 (where
);
4130 switch (fixp
->fx_r_type
)
4132 case BFD_RELOC_MSP430_10_PCREL
:
4134 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4135 _("odd address operand: %ld"), value
);
4137 /* Jumps are in words. */
4139 --value
; /* Correct PC. */
4141 if (value
< -512 || value
> 511)
4142 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4143 _("operand out of range: %ld"), value
);
4145 value
&= 0x3ff; /* get rid of extended sign */
4146 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4149 case BFD_RELOC_MSP430X_PCR16
:
4150 case BFD_RELOC_MSP430_RL_PCREL
:
4151 case BFD_RELOC_MSP430_16_PCREL
:
4153 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4154 _("odd address operand: %ld"), value
);
4157 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4158 /* Nothing to be corrected here. */
4159 if (value
< -32768 || value
> 65536)
4160 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4161 _("operand out of range: %ld"), value
);
4164 case BFD_RELOC_MSP430X_ABS16
:
4165 case BFD_RELOC_MSP430_16
:
4167 case BFD_RELOC_MSP430_16_BYTE
:
4168 value
&= 0xffff; /* Get rid of extended sign. */
4169 bfd_putl16 ((bfd_vma
) value
, where
);
4172 case BFD_RELOC_MSP430_ABS_HI16
:
4174 value
&= 0xffff; /* Get rid of extended sign. */
4175 bfd_putl16 ((bfd_vma
) value
, where
);
4179 bfd_putl16 ((bfd_vma
) value
, where
);
4182 case BFD_RELOC_MSP430_ABS8
:
4184 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4187 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4188 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4189 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4191 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4194 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4195 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4197 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4200 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4201 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4203 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4206 case BFD_RELOC_MSP430X_PCR20_CALL
:
4207 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4209 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4212 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4213 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4214 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4216 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4219 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4220 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4222 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4225 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4226 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4228 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4232 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4233 fixp
->fx_line
, fixp
->fx_r_type
);
4239 fixp
->fx_addnumber
= value
;
4244 S_IS_GAS_LOCAL (symbolS
* s
)
4251 name
= S_GET_NAME (s
);
4252 len
= strlen (name
) - 1;
4254 return name
[len
] == 1 || name
[len
] == 2;
4257 /* GAS will call this to generate a reloc, passing the resulting reloc
4258 to `bfd_install_relocation'. This currently works poorly, as
4259 `bfd_install_relocation' often does the wrong thing, and instances of
4260 `tc_gen_reloc' have been written to work around the problems, which
4261 in turns makes it difficult to fix `bfd_install_relocation'. */
4263 /* If while processing a fixup, a reloc really needs to be created
4264 then it is done here. */
4267 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4269 static arelent
* no_relocs
= NULL
;
4270 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4273 reloc
= XNEW (arelent
);
4274 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4275 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4277 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4279 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4280 _("reloc %d not supported by object file format"),
4281 (int) fixp
->fx_r_type
);
4290 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4292 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4293 fixp
->fx_subsy
= NULL
;
4296 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4298 asection
*asec
, *ssec
;
4300 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4301 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4303 /* If we have a difference between two different, non-absolute symbols
4304 we must generate two relocs (one for each symbol) and allow the
4305 linker to resolve them - relaxation may change the distances between
4306 symbols, even local symbols defined in the same section.
4308 Unfortunately we cannot do this with assembler generated local labels
4309 because there can be multiple incarnations of the same label, with
4310 exactly the same name, in any given section and the linker will have
4311 no way to identify the correct one. Instead we just have to hope
4312 that no relaxation will occur between the local label and the other
4313 symbol in the expression.
4315 Similarly we have to compute differences between symbols in the .eh_frame
4316 section as the linker is not smart enough to apply relocations there
4317 before attempting to process it. */
4318 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4319 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4320 && strcmp (ssec
->name
, ".eh_frame") != 0
4321 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4322 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4324 arelent
* reloc2
= XNEW (arelent
);
4329 reloc2
->address
= reloc
->address
;
4330 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4331 BFD_RELOC_MSP430_SYM_DIFF
);
4332 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4334 if (ssec
== absolute_section
)
4335 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4338 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4339 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4342 reloc
->addend
= fixp
->fx_offset
;
4343 if (asec
== absolute_section
)
4345 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4346 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4350 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4351 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4360 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4362 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4363 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4365 switch (fixp
->fx_r_type
)
4368 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4372 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4376 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4380 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4385 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4396 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4397 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4399 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4400 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4402 md_number_to_chars (fixpos
, amount
, 2);
4407 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4408 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4409 reloc
->addend
= fixp
->fx_offset
;
4411 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4412 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4413 reloc
->address
= fixp
->fx_offset
;
4420 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4421 asection
* segment_type ATTRIBUTE_UNUSED
)
4423 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4425 /* This is a jump -> pcrel mode. Nothing to do much here.
4426 Return value == 2. */
4428 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4430 else if (fragP
->fr_symbol
)
4432 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4433 an absolute segment, we don't know a displacement until we link
4434 object files. So it will always be long. This also applies to
4435 labels in a subsegment of current. Liker may relax it to short
4436 jump later. Return value == 8. */
4438 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4442 /* We know the abs value. may be it is a jump to fixed address.
4443 Impossible in our case, cause all constants already handled. */
4445 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4448 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4452 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4453 asection
* sec ATTRIBUTE_UNUSED
,
4459 struct rcodes_s
* cc
= NULL
;
4460 struct hcodes_s
* hc
= NULL
;
4462 switch (fragP
->fr_subtype
)
4464 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4465 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4466 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4467 /* We do not have to convert anything here.
4468 Just apply a fix. */
4469 rela
= BFD_RELOC_MSP430_10_PCREL
;
4472 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4473 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4474 /* Convert uncond branch jmp lab -> br lab. */
4475 if (target_is_430x ())
4476 cc
= msp430x_rcodes
+ 7;
4478 cc
= msp430_rcodes
+ 7;
4479 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4480 bfd_putl16 (cc
->lop0
, where
);
4481 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4485 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4486 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4488 /* Other simple branches. */
4489 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4492 /* Find actual instruction. */
4493 if (target_is_430x ())
4495 for (i
= 0; i
< 7 && !cc
; i
++)
4496 if (msp430x_rcodes
[i
].sop
== insn
)
4497 cc
= msp430x_rcodes
+ i
;
4501 for (i
= 0; i
< 7 && !cc
; i
++)
4502 if (msp430_rcodes
[i
].sop
== insn
)
4503 cc
= & msp430_rcodes
[i
];
4506 if (!cc
|| !cc
->name
)
4507 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4508 __FUNCTION__
, (long) insn
);
4509 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4510 bfd_putl16 (cc
->lop0
, where
);
4511 bfd_putl16 (cc
->lop1
, where
+ 2);
4512 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4517 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4518 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4519 if (target_is_430x ())
4520 cc
= msp430x_rcodes
+ 6;
4522 cc
= msp430_rcodes
+ 6;
4523 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4524 bfd_putl16 (cc
->lop0
, where
);
4525 bfd_putl16 (cc
->lop1
, where
+ 2);
4526 bfd_putl16 (cc
->lop2
, where
+ 4);
4527 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4531 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4533 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4536 if (target_is_430x ())
4538 for (i
= 0; i
< 4 && !hc
; i
++)
4539 if (msp430x_hcodes
[i
].op1
== insn
)
4540 hc
= msp430x_hcodes
+ i
;
4544 for (i
= 0; i
< 4 && !hc
; i
++)
4545 if (msp430_hcodes
[i
].op1
== insn
)
4546 hc
= &msp430_hcodes
[i
];
4548 if (!hc
|| !hc
->name
)
4549 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4550 __FUNCTION__
, (long) insn
);
4551 rela
= BFD_RELOC_MSP430_10_PCREL
;
4552 /* Apply a fix for a first label if necessary.
4553 another fix will be applied to the next word of insn anyway. */
4555 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4556 fragP
->fr_offset
, TRUE
, rela
);
4562 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4563 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4565 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4568 if (target_is_430x ())
4570 for (i
= 0; i
< 4 && !hc
; i
++)
4571 if (msp430x_hcodes
[i
].op1
== insn
)
4572 hc
= msp430x_hcodes
+ i
;
4576 for (i
= 0; i
< 4 && !hc
; i
++)
4577 if (msp430_hcodes
[i
].op1
== insn
)
4578 hc
= & msp430_hcodes
[i
];
4580 if (!hc
|| !hc
->name
)
4581 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4582 __FUNCTION__
, (long) insn
);
4583 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4584 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4585 bfd_putl16 (hc
->lop0
, where
);
4586 bfd_putl16 (hc
->lop1
, where
+ 2);
4587 bfd_putl16 (hc
->lop2
, where
+ 4);
4593 as_fatal (_("internal inconsistency problem in %s: %lx"),
4594 __FUNCTION__
, (long) fragP
->fr_subtype
);
4598 /* Now apply fix. */
4599 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4600 fragP
->fr_offset
, TRUE
, rela
);
4601 /* Just fixed 2 bytes. */
4605 /* Relax fragment. Mostly stolen from hc11 and mcore
4606 which arches I think I know. */
4609 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4610 long stretch ATTRIBUTE_UNUSED
)
4615 const relax_typeS
*this_type
;
4616 const relax_typeS
*start_type
;
4617 relax_substateT next_state
;
4618 relax_substateT this_state
;
4619 const relax_typeS
*table
= md_relax_table
;
4621 /* Nothing to be done if the frag has already max size. */
4622 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4623 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4626 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4628 symbolP
= fragP
->fr_symbol
;
4629 if (symbol_resolved_p (symbolP
))
4630 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4632 /* We know the offset. calculate a distance. */
4633 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4636 if (!msp430_enable_relax
)
4638 /* Relaxation is not enabled. So, make all jump as long ones
4639 by setting 'aim' to quite high value. */
4643 this_state
= fragP
->fr_subtype
;
4644 start_type
= this_type
= table
+ this_state
;
4648 /* Look backwards. */
4649 for (next_state
= this_type
->rlx_more
; next_state
;)
4650 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4654 /* Grow to next state. */
4655 this_state
= next_state
;
4656 this_type
= table
+ this_state
;
4657 next_state
= this_type
->rlx_more
;
4662 /* Look forwards. */
4663 for (next_state
= this_type
->rlx_more
; next_state
;)
4664 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4668 /* Grow to next state. */
4669 this_state
= next_state
;
4670 this_type
= table
+ this_state
;
4671 next_state
= this_type
->rlx_more
;
4675 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4677 fragP
->fr_subtype
= this_state
;
4681 /* Return FALSE if the fixup in fixp should be left alone and not
4682 adjusted. We return FALSE here so that linker relaxation will
4686 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4688 /* If the symbol is in a non-code section then it should be OK. */
4690 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4696 /* Set the contents of the .MSP430.attributes section. */
4699 msp430_md_end (void)
4702 as_warn ("assembly finished without a possibly needed NOP instruction");
4704 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4705 target_is_430x () ? 2 : 1);
4707 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4708 large_model
? 2 : 1);
4710 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4711 large_model
? 2 : 1);
4714 /* Returns FALSE if there is a msp430 specific reason why the
4715 subtraction of two same-section symbols cannot be computed by
4719 msp430_allow_local_subtract (expressionS
* left
,
4720 expressionS
* right
,
4723 /* If the symbols are not in a code section then they are OK. */
4724 if ((section
->flags
& SEC_CODE
) == 0)
4727 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4730 if (left
->X_add_symbol
== right
->X_add_symbol
)
4733 /* We have to assume that there may be instructions between the
4734 two symbols and that relaxation may increase the distance between