1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2017 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 /* Returns the register number equivalent to the string T.
1676 Returns -1 if there is no such register.
1677 Skips a leading 'r' or 'R' character if there is one.
1678 Handles the register aliases PC and SP. */
1681 check_reg (char * t
)
1688 if (*t
== 'r' || *t
== 'R')
1691 if (strncasecmp (t
, "pc", 2) == 0)
1694 if (strncasecmp (t
, "sp", 2) == 0)
1697 if (strncasecmp (t
, "sr", 2) == 0)
1705 if (val
< 1 || val
> 15)
1712 msp430_srcoperand (struct msp430_operand_s
* op
,
1715 bfd_boolean
* imm_op
,
1716 bfd_boolean allow_20bit_values
,
1717 bfd_boolean constants_allowed
)
1722 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1729 /* Check if there is:
1730 llo(x) - least significant 16 bits, x &= 0xffff
1731 lhi(x) - x = (x >> 16) & 0xffff,
1732 hlo(x) - x = (x >> 32) & 0xffff,
1733 hhi(x) - x = (x >> 48) & 0xffff
1734 The value _MUST_ be constant expression: #hlo(1231231231). */
1738 if (strncasecmp (h
, "#llo(", 5) == 0)
1743 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1748 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1753 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1758 else if (strncasecmp (h
, "#lo(", 4) == 0)
1763 else if (strncasecmp (h
, "#hi(", 4) == 0)
1769 op
->reg
= 0; /* Reg PC. */
1771 op
->ol
= 1; /* Immediate will follow an instruction. */
1772 __tl
= h
+ 1 + rval
;
1774 op
->vshift
= vshift
;
1776 end
= parse_exp (__tl
, &(op
->exp
));
1777 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1779 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1782 if (op
->exp
.X_op
== O_constant
)
1784 int x
= op
->exp
.X_add_number
;
1789 op
->exp
.X_add_number
= x
;
1791 else if (vshift
== 1)
1793 x
= (x
>> 16) & 0xffff;
1794 op
->exp
.X_add_number
= x
;
1797 else if (vshift
> 1)
1800 op
->exp
.X_add_number
= -1;
1802 op
->exp
.X_add_number
= 0; /* Nothing left. */
1803 x
= op
->exp
.X_add_number
;
1807 if (allow_20bit_values
)
1809 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1811 as_bad (_("value 0x%x out of extended range."), x
);
1815 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1817 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1821 /* Now check constants. */
1822 /* Substitute register mode with a constant generator if applicable. */
1824 if (!allow_20bit_values
)
1825 x
= (short) x
; /* Extend sign. */
1827 if (! constants_allowed
)
1859 if (bin
== 0x1200 && ! target_is_430x ())
1861 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1862 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1863 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1864 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1876 if (bin
== 0x1200 && ! target_is_430x ())
1878 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1879 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1880 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1891 else if (op
->exp
.X_op
== O_symbol
)
1894 as_bad (_("error: unsupported #foo() directive used on symbol"));
1897 else if (op
->exp
.X_op
== O_big
)
1903 op
->exp
.X_op
= O_constant
;
1904 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1905 x
= op
->exp
.X_add_number
;
1911 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
1959 /* Redundant (yet) check. */
1960 else if (op
->exp
.X_op
== O_register
)
1962 (_("Registers cannot be used within immediate expression [%s]"), l
);
1964 as_bad (_("unknown operand %s"), l
);
1969 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1974 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1975 op
->am
= 1; /* mode As == 01 bin. */
1976 op
->ol
= 1; /* Immediate value followed by instruction. */
1978 end
= parse_exp (__tl
, &(op
->exp
));
1979 if (end
!= NULL
&& *end
!= 0)
1981 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
1986 if (op
->exp
.X_op
== O_constant
)
1988 int x
= op
->exp
.X_add_number
;
1990 if (allow_20bit_values
)
1992 if (x
> 0xfffff || x
< -(0x7ffff))
1994 as_bad (_("value 0x%x out of extended range."), x
);
1998 else if (x
> 65535 || x
< -32768)
2000 as_bad (_("value out of range: 0x%x"), x
);
2004 else if (op
->exp
.X_op
== O_symbol
)
2008 /* Redundant (yet) check. */
2009 if (op
->exp
.X_op
== O_register
)
2011 (_("Registers cannot be used within absolute expression [%s]"), l
);
2013 as_bad (_("unknown expression in operand %s"), l
);
2019 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2023 char *m
= strchr (l
, '+');
2027 as_bad (_("unknown addressing mode %s"), l
);
2033 if ((op
->reg
= check_reg (t
)) == -1)
2035 as_bad (_("Bad register name %s"), t
);
2043 /* PC cannot be used in indirect addressing. */
2044 if (target_is_430xv2 () && op
->reg
== 0)
2046 as_bad (_("cannot use indirect addressing with the PC"));
2053 /* Check if register indexed X(Rn). */
2056 char *h
= strrchr (l
, '(');
2057 char *m
= strrchr (l
, ')');
2066 as_bad (_("')' required"));
2074 /* Extract a register. */
2075 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2078 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2085 as_bad (_("r2 should not be used in indexed addressing mode"));
2089 /* Extract constant. */
2094 end
= parse_exp (__tl
, &(op
->exp
));
2095 if (end
!= NULL
&& *end
!= 0)
2097 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2100 if (op
->exp
.X_op
== O_constant
)
2102 int x
= op
->exp
.X_add_number
;
2104 if (allow_20bit_values
)
2106 if (x
> 0xfffff || x
< - (0x7ffff))
2108 as_bad (_("value 0x%x out of extended range."), x
);
2112 else if (x
> 65535 || x
< -32768)
2114 as_bad (_("value out of range: 0x%x"), x
);
2126 if (op
->reg
== 1 && (x
& 1))
2128 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2129 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2130 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2131 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2134 else if (op
->exp
.X_op
== O_symbol
)
2138 /* Redundant (yet) check. */
2139 if (op
->exp
.X_op
== O_register
)
2141 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2143 as_bad (_("unknown expression in operand %s"), l
);
2151 /* Possibly register mode 'mov r1,r2'. */
2152 if ((op
->reg
= check_reg (l
)) != -1)
2160 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2162 op
->reg
= 0; /* PC relative... be careful. */
2163 /* An expression starting with a minus sign is a constant, not an address. */
2164 op
->am
= (*l
== '-' ? 3 : 1);
2168 end
= parse_exp (__tl
, &(op
->exp
));
2169 if (end
!= NULL
&& * end
!= 0)
2171 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2179 msp430_dstoperand (struct msp430_operand_s
* op
,
2182 bfd_boolean allow_20bit_values
,
2183 bfd_boolean constants_allowed
)
2186 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2195 char *__tl
= (char *) "0";
2201 (void) parse_exp (__tl
, &(op
->exp
));
2203 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2205 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2215 ("this addressing mode is not applicable for destination operand"));
2221 /* Attempt to encode a MOVA instruction with the given operands.
2222 Returns the length of the encoded instruction if successful
2223 or 0 upon failure. If the encoding fails, an error message
2224 will be returned if a pointer is provided. */
2227 try_encode_mova (bfd_boolean imm_op
,
2229 struct msp430_operand_s
* op1
,
2230 struct msp430_operand_s
* op2
,
2231 const char ** error_message_return
)
2237 /* Only a restricted subset of the normal MSP430 addressing modes
2238 are supported here, so check for the ones that are allowed. */
2241 if (op1
->mode
== OP_EXP
)
2243 if (op2
->mode
!= OP_REG
)
2245 if (error_message_return
!= NULL
)
2246 * error_message_return
= _("expected register as second argument of %s");
2252 /* MOVA #imm20, Rdst. */
2253 bin
|= 0x80 | op2
->reg
;
2254 frag
= frag_more (4);
2255 where
= frag
- frag_now
->fr_literal
;
2256 if (op1
->exp
.X_op
== O_constant
)
2258 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2259 bfd_putl16 ((bfd_vma
) bin
, frag
);
2260 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2264 bfd_putl16 ((bfd_vma
) bin
, frag
);
2265 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2266 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2267 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2272 else if (op1
->am
== 1)
2274 /* MOVA z16(Rsrc), Rdst. */
2275 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2276 frag
= frag_more (4);
2277 where
= frag
- frag_now
->fr_literal
;
2278 bfd_putl16 ((bfd_vma
) bin
, frag
);
2279 if (op1
->exp
.X_op
== O_constant
)
2281 if (op1
->exp
.X_add_number
> 0xffff
2282 || op1
->exp
.X_add_number
< -(0x7fff))
2284 if (error_message_return
!= NULL
)
2285 * error_message_return
= _("index value too big for %s");
2288 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2292 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2293 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2295 BFD_RELOC_MSP430X_PCR16
:
2296 BFD_RELOC_MSP430X_ABS16
);
2301 if (error_message_return
!= NULL
)
2302 * error_message_return
= _("unexpected addressing mode for %s");
2305 else if (op1
->am
== 0)
2307 /* MOVA Rsrc, ... */
2308 if (op2
->mode
== OP_REG
)
2310 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2311 frag
= frag_more (2);
2312 where
= frag
- frag_now
->fr_literal
;
2313 bfd_putl16 ((bfd_vma
) bin
, frag
);
2316 else if (op2
->am
== 1)
2320 /* MOVA Rsrc, &abs20. */
2321 bin
|= 0x60 | (op1
->reg
<< 8);
2322 frag
= frag_more (4);
2323 where
= frag
- frag_now
->fr_literal
;
2324 if (op2
->exp
.X_op
== O_constant
)
2326 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2327 bfd_putl16 ((bfd_vma
) bin
, frag
);
2328 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2332 bfd_putl16 ((bfd_vma
) bin
, frag
);
2333 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2334 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2335 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2340 /* MOVA Rsrc, z16(Rdst). */
2341 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2342 frag
= frag_more (4);
2343 where
= frag
- frag_now
->fr_literal
;
2344 bfd_putl16 ((bfd_vma
) bin
, frag
);
2345 if (op2
->exp
.X_op
== O_constant
)
2347 if (op2
->exp
.X_add_number
> 0xffff
2348 || op2
->exp
.X_add_number
< -(0x7fff))
2350 if (error_message_return
!= NULL
)
2351 * error_message_return
= _("index value too big for %s");
2354 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2358 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2359 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2361 BFD_RELOC_MSP430X_PCR16
:
2362 BFD_RELOC_MSP430X_ABS16
);
2367 if (error_message_return
!= NULL
)
2368 * error_message_return
= _("unexpected addressing mode for %s");
2373 /* imm_op == FALSE. */
2375 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2377 /* MOVA &abs20, Rdst. */
2378 if (op2
->mode
!= OP_REG
)
2380 if (error_message_return
!= NULL
)
2381 * error_message_return
= _("expected register as second argument of %s");
2385 if (op2
->reg
== 2 || op2
->reg
== 3)
2387 if (error_message_return
!= NULL
)
2388 * error_message_return
= _("constant generator destination register found in %s");
2392 bin
|= 0x20 | op2
->reg
;
2393 frag
= frag_more (4);
2394 where
= frag
- frag_now
->fr_literal
;
2395 if (op1
->exp
.X_op
== O_constant
)
2397 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2398 bfd_putl16 ((bfd_vma
) bin
, frag
);
2399 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2403 bfd_putl16 ((bfd_vma
) bin
, frag
);
2404 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2405 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2406 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2410 else if (op1
->mode
== OP_REG
)
2414 /* MOVA @Rsrc+, Rdst. */
2415 if (op2
->mode
!= OP_REG
)
2417 if (error_message_return
!= NULL
)
2418 * error_message_return
= _("expected register as second argument of %s");
2422 if (op2
->reg
== 2 || op2
->reg
== 3)
2424 if (error_message_return
!= NULL
)
2425 * error_message_return
= _("constant generator destination register found in %s");
2429 if (op1
->reg
== 2 || op1
->reg
== 3)
2431 if (error_message_return
!= NULL
)
2432 * error_message_return
= _("constant generator source register found in %s");
2436 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2437 frag
= frag_more (2);
2438 where
= frag
- frag_now
->fr_literal
;
2439 bfd_putl16 ((bfd_vma
) bin
, frag
);
2442 else if (op1
->am
== 2)
2444 /* MOVA @Rsrc,Rdst */
2445 if (op2
->mode
!= OP_REG
)
2447 if (error_message_return
!= NULL
)
2448 * error_message_return
= _("expected register as second argument of %s");
2452 if (op2
->reg
== 2 || op2
->reg
== 3)
2454 if (error_message_return
!= NULL
)
2455 * error_message_return
= _("constant generator destination register found in %s");
2459 if (op1
->reg
== 2 || op1
->reg
== 3)
2461 if (error_message_return
!= NULL
)
2462 * error_message_return
= _("constant generator source register found in %s");
2466 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2467 frag
= frag_more (2);
2468 where
= frag
- frag_now
->fr_literal
;
2469 bfd_putl16 ((bfd_vma
) bin
, frag
);
2474 if (error_message_return
!= NULL
)
2475 * error_message_return
= _("unexpected addressing mode for %s");
2480 #define NOP_CHECK_INTERRUPT (1 << 0)
2481 #define NOP_CHECK_CPU12 (1 << 1)
2482 #define NOP_CHECK_CPU19 (1 << 2)
2484 static signed int check_for_nop
= 0;
2486 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2488 /* Parse instruction operands.
2489 Return binary opcode. */
2492 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2494 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2495 int insn_length
= 0;
2496 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2500 struct msp430_operand_s op1
, op2
;
2502 static short ZEROS
= 0;
2503 bfd_boolean byte_op
, imm_op
;
2506 int extended
= 0x1800;
2507 bfd_boolean extended_op
= FALSE
;
2508 bfd_boolean addr_op
;
2509 const char * error_message
;
2510 static signed int repeat_count
= 0;
2511 static bfd_boolean prev_insn_is_nop
= FALSE
;
2512 bfd_boolean fix_emitted
;
2514 /* Opcode is the one from opcodes table
2515 line contains something like
2524 bfd_boolean check
= FALSE
;
2527 switch (TOLOWER (* line
))
2530 /* Byte operation. */
2531 bin
|= BYTE_OPERATION
;
2537 /* "Address" ops work on 20-bit values. */
2539 bin
|= BYTE_OPERATION
;
2544 /* Word operation - this is the default. */
2552 as_warn (_("no size modifier after period, .w assumed"));
2556 as_bad (_("unrecognised instruction size modifier .%c"),
2568 if (*line
&& ! ISSPACE (*line
))
2570 as_bad (_("junk found after instruction: %s.%s"),
2571 opcode
->name
, line
);
2575 /* Catch the case where the programmer has used a ".a" size modifier on an
2576 instruction that does not support it. Look for an alternative extended
2577 instruction that has the same name without the period. Eg: "add.a"
2578 becomes "adda". Although this not an officially supported way of
2579 specifying instruction aliases other MSP430 assemblers allow it. So we
2580 support it for compatibility purposes. */
2581 if (addr_op
&& opcode
->fmt
>= 0)
2583 const char * old_name
= opcode
->name
;
2586 sprintf (real_name
, "%sa", old_name
);
2587 opcode
= hash_find (msp430_hash
, real_name
);
2590 as_bad (_("instruction %s.a does not exist"), old_name
);
2593 #if 0 /* Enable for debugging. */
2594 as_warn ("treating %s.a as %s", old_name
, real_name
);
2597 bin
= opcode
->bin_opcode
;
2600 if (opcode
->fmt
!= -1
2601 && opcode
->insn_opnumb
2602 && (!*line
|| *line
== '\n'))
2604 as_bad (ngettext ("instruction %s requires %d operand",
2605 "instruction %s requires %d operands",
2606 opcode
->insn_opnumb
),
2607 opcode
->name
, opcode
->insn_opnumb
);
2611 memset (l1
, 0, sizeof (l1
));
2612 memset (l2
, 0, sizeof (l2
));
2613 memset (&op1
, 0, sizeof (op1
));
2614 memset (&op2
, 0, sizeof (op2
));
2618 if ((fmt
= opcode
->fmt
) < 0)
2620 if (! target_is_430x ())
2622 as_bad (_("instruction %s requires MSP430X mcu"),
2633 /* If requested set the extended instruction repeat count. */
2636 if (repeat_count
> 0)
2637 extended
|= (repeat_count
- 1);
2639 extended
|= (1 << 7) | (- repeat_count
);
2642 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2649 if (! is_opcode ("nop"))
2651 bfd_boolean doit
= FALSE
;
2655 switch (check_for_nop
& - check_for_nop
)
2657 case NOP_CHECK_INTERRUPT
:
2658 if (warn_interrupt_nops
)
2660 if (gen_interrupt_nops
)
2661 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2663 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2666 if (gen_interrupt_nops
)
2667 /* Emit a NOP between interrupt enable/disable.
2668 See 1.3.4.1 of the MSP430x5xx User Guide. */
2672 case NOP_CHECK_CPU12
:
2673 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2674 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2676 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2680 case NOP_CHECK_CPU19
:
2681 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2682 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2684 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2689 as_bad (_("internal error: unknown nop check state"));
2692 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2694 while (check_for_nop
);
2698 frag
= frag_more (2);
2699 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2700 dwarf2_emit_insn (2);
2709 case 0: /* Emulated. */
2710 switch (opcode
->insn_opnumb
)
2713 if (is_opcode ("eint"))
2715 if (! prev_insn_is_nop
)
2717 if (gen_interrupt_nops
)
2719 frag
= frag_more (2);
2720 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2721 dwarf2_emit_insn (2);
2723 if (warn_interrupt_nops
)
2724 as_warn (_("inserting a NOP before EINT"));
2726 else if (warn_interrupt_nops
)
2727 as_warn (_("a NOP might be needed before the EINT"));
2730 else if (is_opcode ("dint"))
2731 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2733 /* Set/clear bits instructions. */
2737 extended
|= BYTE_OPERATION
;
2739 /* Emit the extension word. */
2741 frag
= frag_more (2);
2742 bfd_putl16 (extended
, frag
);
2746 frag
= frag_more (2);
2747 bfd_putl16 ((bfd_vma
) bin
, frag
);
2748 dwarf2_emit_insn (insn_length
);
2752 /* Something which works with destination operand. */
2753 line
= extract_operand (line
, l1
, sizeof (l1
));
2754 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2758 bin
|= (op1
.reg
| (op1
.am
<< 7));
2760 /* If the PC is the destination... */
2761 if (op1
.am
== 0 && op1
.reg
== 0
2762 /* ... and the opcode alters the SR. */
2763 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2764 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2766 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2767 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2768 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2769 as_warn (_("CPU11: PC is destination of SR altering instruction"));
2772 /* If the status register is the destination... */
2773 if (op1
.am
== 0 && op1
.reg
== 2
2774 /* ... and the opcode alters the SR. */
2775 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2776 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2777 || is_opcode ("sbc") || is_opcode ("sxt")
2778 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2779 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2780 || is_opcode ("sbcx")
2783 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2784 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2785 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2786 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2789 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2790 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2792 /* Compute the entire instruction length, in bytes. */
2793 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2794 insn_length
+= op_length
;
2795 frag
= frag_more (op_length
);
2796 where
= frag
- frag_now
->fr_literal
;
2801 extended
|= BYTE_OPERATION
;
2803 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2805 as_bad (_("repeat instruction used with non-register mode instruction"));
2809 if (op1
.mode
== OP_EXP
)
2811 if (op1
.exp
.X_op
== O_constant
)
2812 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2814 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2815 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2816 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2818 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2819 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2822 /* Emit the extension word. */
2823 bfd_putl16 (extended
, frag
);
2828 bfd_putl16 ((bfd_vma
) bin
, frag
);
2832 if (op1
.mode
== OP_EXP
)
2834 if (op1
.exp
.X_op
== O_constant
)
2836 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2840 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2845 fix_new_exp (frag_now
, where
, 2,
2846 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2848 fix_new_exp (frag_now
, where
, 2,
2849 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2854 dwarf2_emit_insn (insn_length
);
2858 /* Shift instruction. */
2859 line
= extract_operand (line
, l1
, sizeof (l1
));
2860 strncpy (l2
, l1
, sizeof (l2
));
2861 l2
[sizeof (l2
) - 1] = '\0';
2862 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2863 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2866 break; /* An error occurred. All warnings were done before. */
2868 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2869 frag
= frag_more (insn_length
);
2870 where
= frag
- frag_now
->fr_literal
;
2872 if (target_is_430xv2 ()
2873 && op1
.mode
== OP_REG
2875 && (is_opcode ("rlax")
2876 || is_opcode ("rlcx")
2877 || is_opcode ("rla")
2878 || is_opcode ("rlc")))
2880 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2884 /* If the status register is the destination... */
2885 if (op1
.am
== 0 && op1
.reg
== 2
2886 /* ... and the opcode alters the SR. */
2887 && (is_opcode ("rla") || is_opcode ("rlc")
2888 || is_opcode ("rlax") || is_opcode ("rlcx")
2891 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2892 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2893 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2894 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2900 extended
|= BYTE_OPERATION
;
2902 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2904 as_bad (_("repeat instruction used with non-register mode instruction"));
2908 if (op1
.mode
== OP_EXP
)
2910 if (op1
.exp
.X_op
== O_constant
)
2911 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2913 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2914 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2915 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2917 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2918 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2921 if (op2
.mode
== OP_EXP
)
2923 if (op2
.exp
.X_op
== O_constant
)
2924 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2926 else if (op1
.mode
== OP_EXP
)
2927 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2928 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2929 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2931 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2932 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2933 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2936 /* Emit the extension word. */
2937 bfd_putl16 (extended
, frag
);
2942 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2943 bfd_putl16 ((bfd_vma
) bin
, frag
);
2947 if (op1
.mode
== OP_EXP
)
2949 if (op1
.exp
.X_op
== O_constant
)
2951 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2955 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2959 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2960 fix_new_exp (frag_now
, where
, 2,
2961 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2963 fix_new_exp (frag_now
, where
, 2,
2964 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2971 if (op2
.mode
== OP_EXP
)
2973 if (op2
.exp
.X_op
== O_constant
)
2975 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2979 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2983 if (op2
.reg
) /* Not PC relative. */
2984 fix_new_exp (frag_now
, where
, 2,
2985 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2987 fix_new_exp (frag_now
, where
, 2,
2988 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2993 dwarf2_emit_insn (insn_length
);
2997 /* Branch instruction => mov dst, r0. */
3000 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3004 line
= extract_operand (line
, l1
, sizeof (l1
));
3005 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3011 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3012 op_length
= 2 + 2 * op1
.ol
;
3013 frag
= frag_more (op_length
);
3014 where
= frag
- frag_now
->fr_literal
;
3015 bfd_putl16 ((bfd_vma
) bin
, frag
);
3017 if (op1
.mode
== OP_EXP
)
3019 if (op1
.exp
.X_op
== O_constant
)
3021 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3027 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3029 if (op1
.reg
|| op1
.am
== 3)
3030 fix_new_exp (frag_now
, where
, 2,
3031 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3033 fix_new_exp (frag_now
, where
, 2,
3034 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3038 dwarf2_emit_insn (insn_length
+ op_length
);
3042 /* CALLA instructions. */
3043 fix_emitted
= FALSE
;
3045 line
= extract_operand (line
, l1
, sizeof (l1
));
3048 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3049 extended_op
, FALSE
);
3055 op_length
= 2 + 2 * op1
.ol
;
3056 frag
= frag_more (op_length
);
3057 where
= frag
- frag_now
->fr_literal
;
3065 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3066 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3069 else if (op1
.am
== 1)
3075 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3076 BFD_RELOC_MSP430X_PCR20_CALL
);
3080 bin
|= 0x50 | op1
.reg
;
3082 else if (op1
.am
== 0)
3083 bin
|= 0x40 | op1
.reg
;
3085 else if (op1
.am
== 1)
3089 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3090 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3093 else if (op1
.am
== 2)
3094 bin
|= 0x60 | op1
.reg
;
3095 else if (op1
.am
== 3)
3096 bin
|= 0x70 | op1
.reg
;
3098 bfd_putl16 ((bfd_vma
) bin
, frag
);
3100 if (op1
.mode
== OP_EXP
)
3104 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3108 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3111 fix_new_exp (frag_now
, where
+ 2, 2,
3112 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3115 dwarf2_emit_insn (insn_length
+ op_length
);
3123 /* [POP|PUSH]M[.A] #N, Rd */
3124 line
= extract_operand (line
, l1
, sizeof (l1
));
3125 line
= extract_operand (line
, l2
, sizeof (l2
));
3129 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3132 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3133 if (end
!= NULL
&& *end
!= 0)
3135 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3138 if (op1
.exp
.X_op
!= O_constant
)
3140 as_bad (_("expected constant expression as first argument of %s"),
3145 if ((reg
= check_reg (l2
)) == -1)
3147 as_bad (_("expected register as second argument of %s"),
3153 frag
= frag_more (op_length
);
3154 where
= frag
- frag_now
->fr_literal
;
3155 bin
= opcode
->bin_opcode
;
3158 n
= op1
.exp
.X_add_number
;
3159 bin
|= (n
- 1) << 4;
3160 if (is_opcode ("pushm"))
3164 if (reg
- n
+ 1 < 0)
3166 as_bad (_("Too many registers popped"));
3170 /* CPU21 errata: cannot use POPM to restore the SR register. */
3171 if (target_is_430xv2 ()
3172 && (reg
- n
+ 1 < 3)
3174 && is_opcode ("popm"))
3176 as_bad (_("Cannot use POPM to restore the SR register"));
3180 bin
|= (reg
- n
+ 1);
3183 bfd_putl16 ((bfd_vma
) bin
, frag
);
3184 dwarf2_emit_insn (op_length
);
3193 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3194 if (extended
& 0xff)
3196 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3200 line
= extract_operand (line
, l1
, sizeof (l1
));
3201 line
= extract_operand (line
, l2
, sizeof (l2
));
3205 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3208 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3209 if (end
!= NULL
&& *end
!= 0)
3211 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3214 if (op1
.exp
.X_op
!= O_constant
)
3216 as_bad (_("expected constant expression as first argument of %s"),
3220 n
= op1
.exp
.X_add_number
;
3223 as_bad (_("expected first argument of %s to be in the range 1-4"),
3228 if ((reg
= check_reg (l2
)) == -1)
3230 as_bad (_("expected register as second argument of %s"),
3235 if (target_is_430xv2 () && reg
== 0)
3237 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3242 frag
= frag_more (op_length
);
3243 where
= frag
- frag_now
->fr_literal
;
3245 bin
= opcode
->bin_opcode
;
3248 bin
|= (n
- 1) << 10;
3251 bfd_putl16 ((bfd_vma
) bin
, frag
);
3252 dwarf2_emit_insn (op_length
);
3258 bfd_boolean need_reloc
= FALSE
;
3262 /* ADDA, CMPA and SUBA address instructions. */
3263 if (extended
& 0xff)
3265 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3269 line
= extract_operand (line
, l1
, sizeof (l1
));
3270 line
= extract_operand (line
, l2
, sizeof (l2
));
3272 bin
= opcode
->bin_opcode
;
3276 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3277 if (end
!= NULL
&& *end
!= 0)
3279 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3283 if (op1
.exp
.X_op
== O_constant
)
3285 n
= op1
.exp
.X_add_number
;
3286 if (n
> 0xfffff || n
< - (0x7ffff))
3288 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3293 bin
|= ((n
>> 16) & 0xf) << 8;
3305 if ((n
= check_reg (l1
)) == -1)
3307 as_bad (_("expected register name or constant as first argument of %s"),
3312 bin
|= (n
<< 8) | (1 << 6);
3316 if ((reg
= check_reg (l2
)) == -1)
3318 as_bad (_("expected register as second argument of %s"),
3323 frag
= frag_more (op_length
);
3324 where
= frag
- frag_now
->fr_literal
;
3327 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3328 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3330 bfd_putl16 ((bfd_vma
) bin
, frag
);
3332 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3333 dwarf2_emit_insn (op_length
);
3337 case 9: /* MOVA, BRA, RETA. */
3339 bin
= opcode
->bin_opcode
;
3341 if (is_opcode ("reta"))
3343 /* The RETA instruction does not take any arguments.
3344 The implicit first argument is @SP+.
3345 The implicit second argument is PC. */
3355 line
= extract_operand (line
, l1
, sizeof (l1
));
3356 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3357 &imm_op
, extended_op
, FALSE
);
3359 if (is_opcode ("bra"))
3361 /* This is the BRA synthetic instruction.
3362 The second argument is always PC. */
3368 line
= extract_operand (line
, l2
, sizeof (l2
));
3369 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3374 break; /* Error occurred. All warnings were done before. */
3377 /* Only a restricted subset of the normal MSP430 addressing modes
3378 are supported here, so check for the ones that are allowed. */
3379 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3380 & error_message
)) == 0)
3382 as_bad (error_message
, opcode
->name
);
3385 dwarf2_emit_insn (op_length
);
3389 line
= extract_operand (line
, l1
, sizeof l1
);
3390 /* The RPT instruction only accepted immediates and registers. */
3393 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3394 if (end
!= NULL
&& *end
!= 0)
3396 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3399 if (op1
.exp
.X_op
!= O_constant
)
3401 as_bad (_("expected constant value as argument to RPT"));
3404 if (op1
.exp
.X_add_number
< 1
3405 || op1
.exp
.X_add_number
> (1 << 4))
3407 as_bad (_("expected constant in the range 2..16"));
3411 /* We silently accept and ignore a repeat count of 1. */
3412 if (op1
.exp
.X_add_number
> 1)
3413 repeat_count
= op1
.exp
.X_add_number
;
3419 if ((reg
= check_reg (l1
)) != -1)
3422 as_warn (_("PC used as an argument to RPT"));
3424 repeat_count
= - reg
;
3428 as_bad (_("expected constant or register name as argument to RPT insn"));
3435 as_bad (_("Illegal emulated instruction"));
3440 case 1: /* Format 1, double operand. */
3441 line
= extract_operand (line
, l1
, sizeof (l1
));
3442 line
= extract_operand (line
, l2
, sizeof (l2
));
3443 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3444 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3447 break; /* Error occurred. All warnings were done before. */
3450 && is_opcode ("movx")
3452 && msp430_enable_relax
)
3454 /* This is the MOVX.A instruction. See if we can convert
3455 it into the MOVA instruction instead. This saves 2 bytes. */
3456 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3459 dwarf2_emit_insn (op_length
);
3464 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3466 /* If the PC is the destination... */
3467 if (op2
.am
== 0 && op2
.reg
== 0
3468 /* ... and the opcode alters the SR. */
3469 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3470 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3472 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3473 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3474 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3475 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3478 /* If the status register is the destination... */
3479 if (op2
.am
== 0 && op2
.reg
== 2
3480 /* ... and the opcode alters the SR. */
3481 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3482 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3483 || is_opcode ("xor")
3484 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3485 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3486 || is_opcode ("xorx")
3489 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3490 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3491 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3492 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3495 if ( (is_opcode ("bic") && bin
== 0xc232)
3496 || (is_opcode ("bis") && bin
== 0xd232)
3497 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3499 /* Avoid false checks when a constant value is being put into the SR. */
3500 if (op1
.mode
== OP_EXP
3501 && op1
.exp
.X_op
== O_constant
3502 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3505 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3508 if (((is_opcode ("bis") && bin
== 0xd032)
3509 || (is_opcode ("mov") && bin
== 0x4032)
3510 || (is_opcode ("xor") && bin
== 0xe032))
3511 && op1
.mode
== OP_EXP
3512 && op1
.exp
.X_op
== O_constant
3513 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3514 check_for_nop
|= NOP_CHECK_CPU19
;
3516 /* Compute the entire length of the instruction in bytes. */
3517 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3518 + 2 /* The opcode */
3519 + (2 * op1
.ol
) /* The first operand. */
3520 + (2 * op2
.ol
); /* The second operand. */
3522 insn_length
+= op_length
;
3523 frag
= frag_more (op_length
);
3524 where
= frag
- frag_now
->fr_literal
;
3529 extended
|= BYTE_OPERATION
;
3531 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3533 as_bad (_("repeat instruction used with non-register mode instruction"));
3537 /* If necessary, emit a reloc to update the extension word. */
3538 if (op1
.mode
== OP_EXP
)
3540 if (op1
.exp
.X_op
== O_constant
)
3541 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3543 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3544 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3545 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3547 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3548 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3551 if (op2
.mode
== OP_EXP
)
3553 if (op2
.exp
.X_op
== O_constant
)
3554 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3556 else if (op1
.mode
== OP_EXP
)
3557 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3558 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3559 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3562 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3563 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3564 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3567 /* Emit the extension word. */
3568 bfd_putl16 (extended
, frag
);
3573 bfd_putl16 ((bfd_vma
) bin
, frag
);
3577 if (op1
.mode
== OP_EXP
)
3579 if (op1
.exp
.X_op
== O_constant
)
3581 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3585 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3589 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3590 fix_new_exp (frag_now
, where
, 2,
3591 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3593 fix_new_exp (frag_now
, where
, 2,
3594 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3602 if (op2
.mode
== OP_EXP
)
3604 if (op2
.exp
.X_op
== O_constant
)
3606 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3610 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3614 if (op2
.reg
) /* Not PC relative. */
3615 fix_new_exp (frag_now
, where
, 2,
3616 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3618 fix_new_exp (frag_now
, where
, 2,
3619 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3624 dwarf2_emit_insn (insn_length
);
3626 /* If the PC is the destination... */
3627 if (op2
.am
== 0 && op2
.reg
== 0
3628 /* ... but the opcode does not alter the destination. */
3629 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3630 check_for_nop
|= NOP_CHECK_CPU12
;
3633 case 2: /* Single-operand mostly instr. */
3634 if (opcode
->insn_opnumb
== 0)
3636 /* reti instruction. */
3638 frag
= frag_more (2);
3639 bfd_putl16 ((bfd_vma
) bin
, frag
);
3640 dwarf2_emit_insn (insn_length
);
3644 line
= extract_operand (line
, l1
, sizeof (l1
));
3645 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3646 &imm_op
, extended_op
, TRUE
);
3648 break; /* Error in operand. */
3650 if (target_is_430xv2 ()
3651 && op1
.mode
== OP_REG
3653 && (is_opcode ("rrax")
3654 || is_opcode ("rrcx")
3655 || is_opcode ("rra")
3656 || is_opcode ("rrc")))
3658 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3662 /* If the status register is the destination... */
3663 if (op1
.am
== 0 && op1
.reg
== 2
3664 /* ... and the opcode alters the SR. */
3665 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3667 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3668 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3669 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3670 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3673 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3674 frag
= frag_more (insn_length
);
3675 where
= frag
- frag_now
->fr_literal
;
3679 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3681 /* These two instructions use a special
3682 encoding of the A/L and B/W bits. */
3683 bin
&= ~ BYTE_OPERATION
;
3687 as_bad (_("%s instruction does not accept a .b suffix"),
3692 extended
|= BYTE_OPERATION
;
3695 extended
|= BYTE_OPERATION
;
3697 if (is_opcode ("rrux"))
3698 extended
|= IGNORE_CARRY_BIT
;
3700 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3702 as_bad (_("repeat instruction used with non-register mode instruction"));
3706 if (op1
.mode
== OP_EXP
)
3708 if (op1
.exp
.X_op
== O_constant
)
3709 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3711 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3712 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3713 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3715 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3716 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3719 /* Emit the extension word. */
3720 bfd_putl16 (extended
, frag
);
3725 bin
|= op1
.reg
| (op1
.am
<< 4);
3726 bfd_putl16 ((bfd_vma
) bin
, frag
);
3730 if (op1
.mode
== OP_EXP
)
3732 if (op1
.exp
.X_op
== O_constant
)
3734 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3738 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3742 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3743 fix_new_exp (frag_now
, where
, 2,
3744 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3746 fix_new_exp (frag_now
, where
, 2,
3747 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3752 dwarf2_emit_insn (insn_length
);
3755 case 3: /* Conditional jumps instructions. */
3756 line
= extract_operand (line
, l1
, sizeof (l1
));
3757 /* l1 is a label. */
3766 end
= parse_exp (m
, &exp
);
3767 if (end
!= NULL
&& *end
!= 0)
3769 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3773 /* In order to handle something like:
3777 jz 4 ; skip next 4 bytes
3780 nop ; will jump here if r5 positive or zero
3782 jCOND -n ;assumes jump n bytes backward:
3792 jCOND $n ; jump from PC in either direction. */
3794 if (exp
.X_op
== O_constant
)
3796 int x
= exp
.X_add_number
;
3800 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3804 if ((*l1
== '$' && x
> 0) || x
< 0)
3809 if (x
> 512 || x
< -511)
3811 as_bad (_("Wrong displacement %d"), x
<< 1);
3816 frag
= frag_more (2); /* Instr size is 1 word. */
3819 bfd_putl16 ((bfd_vma
) bin
, frag
);
3821 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3824 frag
= frag_more (2); /* Instr size is 1 word. */
3825 where
= frag
- frag_now
->fr_literal
;
3826 fix_new_exp (frag_now
, where
, 2,
3827 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3829 bfd_putl16 ((bfd_vma
) bin
, frag
);
3831 else if (*l1
== '$')
3833 as_bad (_("instruction requires label sans '$'"));
3837 ("instruction requires label or value in range -511:512"));
3838 dwarf2_emit_insn (insn_length
);
3843 as_bad (_("instruction requires label"));
3848 case 4: /* Extended jumps. */
3849 if (!msp430_enable_polys
)
3851 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3855 line
= extract_operand (line
, l1
, sizeof (l1
));
3861 /* Ignore absolute addressing. make it PC relative anyway. */
3862 if (*m
== '#' || *m
== '$')
3865 end
= parse_exp (m
, & exp
);
3866 if (end
!= NULL
&& *end
!= 0)
3868 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3871 if (exp
.X_op
== O_symbol
)
3873 /* Relaxation required. */
3874 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3876 if (target_is_430x ())
3877 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3879 /* The parameter to dwarf2_emit_insn is actually the offset to
3880 the start of the insn from the fix piece of instruction that
3881 was emitted. Since next fragments may have variable size we
3882 tie debug info to the beginning of the instruction. */
3884 frag
= frag_more (8);
3885 dwarf2_emit_insn (0);
3886 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3887 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3889 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3891 0, /* Offset is zero if jump dist less than 1K. */
3897 as_bad (_("instruction requires label"));
3900 case 5: /* Emulated extended branches. */
3901 if (!msp430_enable_polys
)
3903 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3906 line
= extract_operand (line
, l1
, sizeof (l1
));
3912 /* Ignore absolute addressing. make it PC relative anyway. */
3913 if (*m
== '#' || *m
== '$')
3916 end
= parse_exp (m
, & exp
);
3917 if (end
!= NULL
&& *end
!= 0)
3919 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3922 if (exp
.X_op
== O_symbol
)
3924 /* Relaxation required. */
3925 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3927 if (target_is_430x ())
3928 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3931 frag
= frag_more (8);
3932 dwarf2_emit_insn (0);
3933 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3934 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3936 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3937 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3939 0, /* Offset is zero if jump dist less than 1K. */
3945 as_bad (_("instruction requires label"));
3949 as_bad (_("Illegal instruction or not implemented opcode."));
3952 if (is_opcode ("nop"))
3953 prev_insn_is_nop
= TRUE
;
3955 prev_insn_is_nop
= FALSE
;
3957 input_line_pointer
= line
;
3962 md_assemble (char * str
)
3964 struct msp430_opcode_s
* opcode
;
3968 str
= skip_space (str
); /* Skip leading spaces. */
3969 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3973 char a
= TOLOWER (cmd
[i
]);
3980 as_bad (_("can't find opcode"));
3984 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3988 as_bad (_("unknown opcode `%s'"), cmd
);
3993 char *__t
= input_line_pointer
;
3995 msp430_operands (opcode
, str
);
3996 input_line_pointer
= __t
;
4000 /* GAS will call this function for each section at the end of the assembly,
4001 to permit the CPU backend to adjust the alignment of a section. */
4004 md_section_align (asection
* seg
, valueT addr
)
4006 int align
= bfd_get_section_alignment (stdoutput
, seg
);
4008 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4011 /* If you define this macro, it should return the offset between the
4012 address of a PC relative fixup and the position from which the PC
4013 relative adjustment should be made. On many processors, the base
4014 of a PC relative instruction is the next instruction, so this
4015 macro would return the length of an instruction. */
4018 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4020 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4021 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4022 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4025 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4028 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4029 Now it handles the situation when relocations
4030 have to be passed to linker. */
4032 msp430_force_relocation_local (fixS
*fixp
)
4034 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4038 if (msp430_enable_polys
4039 && !msp430_enable_relax
)
4046 /* GAS will call this for each fixup. It should store the correct
4047 value in the object file. */
4049 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4051 unsigned char * where
;
4055 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4060 else if (fixp
->fx_pcrel
)
4062 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4064 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4066 /* FIXME: We can appear here only in case if we perform a pc
4067 relative jump to the label which is i) global, ii) locally
4068 defined or this is a jump to an absolute symbol.
4069 If this is an absolute symbol -- everything is OK.
4070 If this is a global label, we've got a symbol value defined
4072 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4073 from this section start
4074 2. *valuep will contain the real offset from jump insn to the
4076 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4077 will be incorrect. Therefore remove s_get_value. */
4078 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4086 value
= fixp
->fx_offset
;
4088 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4090 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4092 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4098 fixp
->fx_no_overflow
= 1;
4100 /* If polymorphs are enabled and relax disabled.
4101 do not kill any relocs and pass them to linker. */
4102 if (msp430_enable_polys
4103 && !msp430_enable_relax
)
4106 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4107 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4114 /* Fetch the instruction, insert the fully resolved operand
4115 value, and stuff the instruction back again. */
4116 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4118 insn
= bfd_getl16 (where
);
4120 switch (fixp
->fx_r_type
)
4122 case BFD_RELOC_MSP430_10_PCREL
:
4124 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4125 _("odd address operand: %ld"), value
);
4127 /* Jumps are in words. */
4129 --value
; /* Correct PC. */
4131 if (value
< -512 || value
> 511)
4132 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4133 _("operand out of range: %ld"), value
);
4135 value
&= 0x3ff; /* get rid of extended sign */
4136 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4139 case BFD_RELOC_MSP430X_PCR16
:
4140 case BFD_RELOC_MSP430_RL_PCREL
:
4141 case BFD_RELOC_MSP430_16_PCREL
:
4143 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4144 _("odd address operand: %ld"), value
);
4147 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4148 /* Nothing to be corrected here. */
4149 if (value
< -32768 || value
> 65536)
4150 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4151 _("operand out of range: %ld"), value
);
4154 case BFD_RELOC_MSP430X_ABS16
:
4155 case BFD_RELOC_MSP430_16
:
4157 case BFD_RELOC_MSP430_16_BYTE
:
4158 value
&= 0xffff; /* Get rid of extended sign. */
4159 bfd_putl16 ((bfd_vma
) value
, where
);
4162 case BFD_RELOC_MSP430_ABS_HI16
:
4164 value
&= 0xffff; /* Get rid of extended sign. */
4165 bfd_putl16 ((bfd_vma
) value
, where
);
4169 bfd_putl16 ((bfd_vma
) value
, where
);
4172 case BFD_RELOC_MSP430_ABS8
:
4174 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4177 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4178 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4179 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4181 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4184 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4185 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4187 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4190 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4191 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4193 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4196 case BFD_RELOC_MSP430X_PCR20_CALL
:
4197 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4199 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4202 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4203 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4204 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4206 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4209 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4210 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4212 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4215 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4216 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4218 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4222 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4223 fixp
->fx_line
, fixp
->fx_r_type
);
4229 fixp
->fx_addnumber
= value
;
4234 S_IS_GAS_LOCAL (symbolS
* s
)
4241 name
= S_GET_NAME (s
);
4242 len
= strlen (name
) - 1;
4244 return name
[len
] == 1 || name
[len
] == 2;
4247 /* GAS will call this to generate a reloc, passing the resulting reloc
4248 to `bfd_install_relocation'. This currently works poorly, as
4249 `bfd_install_relocation' often does the wrong thing, and instances of
4250 `tc_gen_reloc' have been written to work around the problems, which
4251 in turns makes it difficult to fix `bfd_install_relocation'. */
4253 /* If while processing a fixup, a reloc really needs to be created
4254 then it is done here. */
4257 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4259 static arelent
* no_relocs
= NULL
;
4260 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4263 reloc
= XNEW (arelent
);
4264 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4265 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4267 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4269 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4270 _("reloc %d not supported by object file format"),
4271 (int) fixp
->fx_r_type
);
4280 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4282 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4283 fixp
->fx_subsy
= NULL
;
4286 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4288 asection
*asec
, *ssec
;
4290 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4291 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4293 /* If we have a difference between two different, non-absolute symbols
4294 we must generate two relocs (one for each symbol) and allow the
4295 linker to resolve them - relaxation may change the distances between
4296 symbols, even local symbols defined in the same section.
4298 Unfortunately we cannot do this with assembler generated local labels
4299 because there can be multiple incarnations of the same label, with
4300 exactly the same name, in any given section and the linker will have
4301 no way to identify the correct one. Instead we just have to hope
4302 that no relaxation will occur between the local label and the other
4303 symbol in the expression.
4305 Similarly we have to compute differences between symbols in the .eh_frame
4306 section as the linker is not smart enough to apply relocations there
4307 before attempting to process it. */
4308 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4309 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4310 && strcmp (ssec
->name
, ".eh_frame") != 0
4311 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4312 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4314 arelent
* reloc2
= XNEW (arelent
);
4319 reloc2
->address
= reloc
->address
;
4320 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4321 BFD_RELOC_MSP430_SYM_DIFF
);
4322 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4324 if (ssec
== absolute_section
)
4325 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4328 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4329 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4332 reloc
->addend
= fixp
->fx_offset
;
4333 if (asec
== absolute_section
)
4335 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4336 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4340 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4341 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4350 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4352 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4353 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4355 switch (fixp
->fx_r_type
)
4358 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4362 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4366 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4370 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4375 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4386 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4387 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4389 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4390 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4392 md_number_to_chars (fixpos
, amount
, 2);
4397 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4398 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4399 reloc
->addend
= fixp
->fx_offset
;
4401 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4402 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4403 reloc
->address
= fixp
->fx_offset
;
4410 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4411 asection
* segment_type ATTRIBUTE_UNUSED
)
4413 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4415 /* This is a jump -> pcrel mode. Nothing to do much here.
4416 Return value == 2. */
4418 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4420 else if (fragP
->fr_symbol
)
4422 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4423 an absolute segment, we don't know a displacement until we link
4424 object files. So it will always be long. This also applies to
4425 labels in a subsegment of current. Liker may relax it to short
4426 jump later. Return value == 8. */
4428 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4432 /* We know the abs value. may be it is a jump to fixed address.
4433 Impossible in our case, cause all constants already handled. */
4435 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4438 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4442 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4443 asection
* sec ATTRIBUTE_UNUSED
,
4449 struct rcodes_s
* cc
= NULL
;
4450 struct hcodes_s
* hc
= NULL
;
4452 switch (fragP
->fr_subtype
)
4454 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4455 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4456 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4457 /* We do not have to convert anything here.
4458 Just apply a fix. */
4459 rela
= BFD_RELOC_MSP430_10_PCREL
;
4462 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4463 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4464 /* Convert uncond branch jmp lab -> br lab. */
4465 if (target_is_430x ())
4466 cc
= msp430x_rcodes
+ 7;
4468 cc
= msp430_rcodes
+ 7;
4469 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4470 bfd_putl16 (cc
->lop0
, where
);
4471 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4475 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4476 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4478 /* Other simple branches. */
4479 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4482 /* Find actual instruction. */
4483 if (target_is_430x ())
4485 for (i
= 0; i
< 7 && !cc
; i
++)
4486 if (msp430x_rcodes
[i
].sop
== insn
)
4487 cc
= msp430x_rcodes
+ i
;
4491 for (i
= 0; i
< 7 && !cc
; i
++)
4492 if (msp430_rcodes
[i
].sop
== insn
)
4493 cc
= & msp430_rcodes
[i
];
4496 if (!cc
|| !cc
->name
)
4497 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4498 __FUNCTION__
, (long) insn
);
4499 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4500 bfd_putl16 (cc
->lop0
, where
);
4501 bfd_putl16 (cc
->lop1
, where
+ 2);
4502 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4507 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4508 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4509 if (target_is_430x ())
4510 cc
= msp430x_rcodes
+ 6;
4512 cc
= msp430_rcodes
+ 6;
4513 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4514 bfd_putl16 (cc
->lop0
, where
);
4515 bfd_putl16 (cc
->lop1
, where
+ 2);
4516 bfd_putl16 (cc
->lop2
, where
+ 4);
4517 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4521 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4523 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4526 if (target_is_430x ())
4528 for (i
= 0; i
< 4 && !hc
; i
++)
4529 if (msp430x_hcodes
[i
].op1
== insn
)
4530 hc
= msp430x_hcodes
+ i
;
4534 for (i
= 0; i
< 4 && !hc
; i
++)
4535 if (msp430_hcodes
[i
].op1
== insn
)
4536 hc
= &msp430_hcodes
[i
];
4538 if (!hc
|| !hc
->name
)
4539 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4540 __FUNCTION__
, (long) insn
);
4541 rela
= BFD_RELOC_MSP430_10_PCREL
;
4542 /* Apply a fix for a first label if necessary.
4543 another fix will be applied to the next word of insn anyway. */
4545 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4546 fragP
->fr_offset
, TRUE
, rela
);
4552 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4553 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4555 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4558 if (target_is_430x ())
4560 for (i
= 0; i
< 4 && !hc
; i
++)
4561 if (msp430x_hcodes
[i
].op1
== insn
)
4562 hc
= msp430x_hcodes
+ i
;
4566 for (i
= 0; i
< 4 && !hc
; i
++)
4567 if (msp430_hcodes
[i
].op1
== insn
)
4568 hc
= & msp430_hcodes
[i
];
4570 if (!hc
|| !hc
->name
)
4571 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4572 __FUNCTION__
, (long) insn
);
4573 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4574 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4575 bfd_putl16 (hc
->lop0
, where
);
4576 bfd_putl16 (hc
->lop1
, where
+ 2);
4577 bfd_putl16 (hc
->lop2
, where
+ 4);
4583 as_fatal (_("internal inconsistency problem in %s: %lx"),
4584 __FUNCTION__
, (long) fragP
->fr_subtype
);
4588 /* Now apply fix. */
4589 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4590 fragP
->fr_offset
, TRUE
, rela
);
4591 /* Just fixed 2 bytes. */
4595 /* Relax fragment. Mostly stolen from hc11 and mcore
4596 which arches I think I know. */
4599 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4600 long stretch ATTRIBUTE_UNUSED
)
4605 const relax_typeS
*this_type
;
4606 const relax_typeS
*start_type
;
4607 relax_substateT next_state
;
4608 relax_substateT this_state
;
4609 const relax_typeS
*table
= md_relax_table
;
4611 /* Nothing to be done if the frag has already max size. */
4612 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4613 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4616 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4618 symbolP
= fragP
->fr_symbol
;
4619 if (symbol_resolved_p (symbolP
))
4620 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4622 /* We know the offset. calculate a distance. */
4623 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4626 if (!msp430_enable_relax
)
4628 /* Relaxation is not enabled. So, make all jump as long ones
4629 by setting 'aim' to quite high value. */
4633 this_state
= fragP
->fr_subtype
;
4634 start_type
= this_type
= table
+ this_state
;
4638 /* Look backwards. */
4639 for (next_state
= this_type
->rlx_more
; next_state
;)
4640 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4644 /* Grow to next state. */
4645 this_state
= next_state
;
4646 this_type
= table
+ this_state
;
4647 next_state
= this_type
->rlx_more
;
4652 /* Look forwards. */
4653 for (next_state
= this_type
->rlx_more
; next_state
;)
4654 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4658 /* Grow to next state. */
4659 this_state
= next_state
;
4660 this_type
= table
+ this_state
;
4661 next_state
= this_type
->rlx_more
;
4665 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4667 fragP
->fr_subtype
= this_state
;
4671 /* Return FALSE if the fixup in fixp should be left alone and not
4672 adjusted. We return FALSE here so that linker relaxation will
4676 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4678 /* If the symbol is in a non-code section then it should be OK. */
4680 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4686 /* Set the contents of the .MSP430.attributes section. */
4689 msp430_md_end (void)
4692 as_warn ("assembly finished without a possibly needed NOP instruction");
4694 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4695 target_is_430x () ? 2 : 1);
4697 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4698 large_model
? 2 : 1);
4700 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4701 large_model
? 2 : 1);
4704 /* Returns FALSE if there is a msp430 specific reason why the
4705 subtraction of two same-section symbols cannot be computed by
4709 msp430_allow_local_subtract (expressionS
* left
,
4710 expressionS
* right
,
4713 /* If the symbols are not in a code section then they are OK. */
4714 if ((section
->flags
& SEC_CODE
) == 0)
4717 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4720 if (left
->X_add_symbol
== right
->X_add_symbol
)
4723 /* We have to assume that there may be instructions between the
4724 two symbols and that relaxation may increase the distance between