1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2016 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 linkwer 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 return input_line_pointer
;
422 /* Delete spaces from s: X ( r 1 2) => X(r12). */
425 del_spaces (char * s
)
433 while (ISSPACE (*m
) && *m
)
435 memmove (s
, m
, strlen (m
) + 1);
443 skip_space (char * s
)
450 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
453 extract_operand (char * from
, char * to
, int limit
)
457 /* Drop leading whitespace. */
458 from
= skip_space (from
);
460 while (size
< limit
&& *from
)
462 *(to
+ size
) = *from
;
463 if (*from
== ',' || *from
== ';' || *from
== '\n')
478 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
495 s
= input_line_pointer
;
496 end
= input_line_pointer
;
498 while (*end
&& *end
!= '\n')
501 while (*s
&& *s
!= '\n')
512 as_bad (_(".profiler pseudo requires at least two operands."));
513 input_line_pointer
= end
;
517 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
526 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
529 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
532 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
535 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
538 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
541 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
544 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
547 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
550 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
553 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
556 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
559 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
562 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
565 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
568 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
571 as_warn (_("unknown profiling flag - ignored."));
578 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
579 | MSP430_PROFILER_FLAG_EXIT
))
580 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
581 | MSP430_PROFILER_FLAG_PROLEND
582 | MSP430_PROFILER_FLAG_EPISTART
583 | MSP430_PROFILER_FLAG_EPIEND
))
584 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
585 | MSP430_PROFILER_FLAG_FINISECT
))))
587 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
588 input_line_pointer
= end
;
592 /* Generate temp symbol which denotes current location. */
593 if (now_seg
== absolute_section
) /* Paranoia ? */
595 exp1
.X_op
= O_constant
;
596 exp1
.X_add_number
= abs_section_offset
;
597 as_warn (_("profiling in absolute section?"));
601 exp1
.X_op
= O_symbol
;
602 exp1
.X_add_symbol
= symbol_temp_new_now ();
603 exp1
.X_add_number
= 0;
606 /* Generate a symbol which holds flags value. */
607 exp
.X_op
= O_constant
;
608 exp
.X_add_number
= p_flags
;
610 /* Save current section. */
614 /* Now go to .profiler section. */
615 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
618 emit_expr (& exp
, 2);
620 /* Save label value. */
621 emit_expr (& exp1
, 2);
625 /* Now get profiling info. */
626 halt
= extract_operand (input_line_pointer
, str
, 1024);
627 /* Process like ".word xxx" directive. */
628 parse_exp (str
, & exp
);
629 emit_expr (& exp
, 2);
630 input_line_pointer
= halt
;
633 /* Fill the rest with zeros. */
634 exp
.X_op
= O_constant
;
635 exp
.X_add_number
= 0;
637 emit_expr (& exp
, 2);
639 /* Return to current section. */
640 subseg_set (seg
, subseg
);
644 extract_word (char * from
, char * to
, int limit
)
649 /* Drop leading whitespace. */
650 from
= skip_space (from
);
653 /* Find the op code end. */
654 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
656 to
[size
++] = *op_end
++;
657 if (size
+ 1 >= limit
)
665 #define OPTION_MMCU 'm'
666 #define OPTION_RELAX 'Q'
667 #define OPTION_POLYMORPHS 'P'
668 #define OPTION_LARGE 'l'
669 static bfd_boolean large_model
= FALSE
;
670 #define OPTION_NO_INTR_NOPS 'N'
671 #define OPTION_INTR_NOPS 'n'
672 static bfd_boolean gen_interrupt_nops
= FALSE
;
673 #define OPTION_WARN_INTR_NOPS 'y'
674 #define OPTION_NO_WARN_INTR_NOPS 'Y'
675 static bfd_boolean warn_interrupt_nops
= TRUE
;
676 #define OPTION_MCPU 'c'
677 #define OPTION_MOVE_DATA 'd'
678 static bfd_boolean move_data
= FALSE
;
682 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
683 OPTION_SILICON_ERRATA_WARN
,
686 static unsigned int silicon_errata_fix
= 0;
687 static unsigned int silicon_errata_warn
= 0;
688 #define SILICON_ERRATA_CPU4 (1 << 0)
689 #define SILICON_ERRATA_CPU8 (1 << 1)
690 #define SILICON_ERRATA_CPU11 (1 << 2)
691 #define SILICON_ERRATA_CPU12 (1 << 3)
692 #define SILICON_ERRATA_CPU13 (1 << 4)
693 #define SILICON_ERRATA_CPU19 (1 << 5)
696 msp430_set_arch (int option
)
698 char str
[32]; /* 32 for good measure. */
700 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
702 md_parse_option (option
, str
);
703 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
704 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
707 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
708 Keep these two structures in sync.
709 The data in this structure has been extracted from the devices.csv file
710 released by TI, updated as of March 2016. */
712 struct msp430_mcu_data
715 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
716 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
720 { "cc430f5123",2,8 },
721 { "cc430f5125",2,8 },
722 { "cc430f5133",2,8 },
723 { "cc430f5135",2,8 },
724 { "cc430f5137",2,8 },
725 { "cc430f5143",2,8 },
726 { "cc430f5145",2,8 },
727 { "cc430f5147",2,8 },
728 { "cc430f6125",2,8 },
729 { "cc430f6126",2,8 },
730 { "cc430f6127",2,8 },
731 { "cc430f6135",2,8 },
732 { "cc430f6137",2,8 },
733 { "cc430f6143",2,8 },
734 { "cc430f6145",2,8 },
735 { "cc430f6147",2,8 },
736 { "msp430afe221",0,2 },
737 { "msp430afe222",0,2 },
738 { "msp430afe223",0,2 },
739 { "msp430afe231",0,2 },
740 { "msp430afe232",0,2 },
741 { "msp430afe233",0,2 },
742 { "msp430afe251",0,2 },
743 { "msp430afe252",0,2 },
744 { "msp430afe253",0,2 },
745 { "msp430bt5190",2,8 },
746 { "msp430c091",0,0 },
747 { "msp430c092",0,0 },
748 { "msp430c111",0,0 },
749 { "msp430c1111",0,0 },
750 { "msp430c112",0,0 },
751 { "msp430c1121",0,0 },
752 { "msp430c1331",0,0 },
753 { "msp430c1351",0,0 },
754 { "msp430c311s",0,0 },
755 { "msp430c312",0,0 },
756 { "msp430c313",0,0 },
757 { "msp430c314",0,0 },
758 { "msp430c315",0,0 },
759 { "msp430c323",0,0 },
760 { "msp430c325",0,0 },
761 { "msp430c336",0,1 },
762 { "msp430c337",0,1 },
763 { "msp430c412",0,0 },
764 { "msp430c413",0,0 },
765 { "msp430cg4616",1,1 },
766 { "msp430cg4617",1,1 },
767 { "msp430cg4618",1,1 },
768 { "msp430cg4619",1,1 },
769 { "msp430e112",0,0 },
770 { "msp430e313",0,0 },
771 { "msp430e315",0,0 },
772 { "msp430e325",0,0 },
773 { "msp430e337",0,1 },
774 { "msp430f110",0,0 },
775 { "msp430f1101",0,0 },
776 { "msp430f1101a",0,0 },
777 { "msp430f1111",0,0 },
778 { "msp430f1111a",0,0 },
779 { "msp430f112",0,0 },
780 { "msp430f1121",0,0 },
781 { "msp430f1121a",0,0 },
782 { "msp430f1122",0,0 },
783 { "msp430f1132",0,0 },
784 { "msp430f122",0,0 },
785 { "msp430f1222",0,0 },
786 { "msp430f123",0,0 },
787 { "msp430f1232",0,0 },
788 { "msp430f133",0,0 },
789 { "msp430f135",0,0 },
790 { "msp430f147",0,1 },
791 { "msp430f1471",0,1 },
792 { "msp430f148",0,1 },
793 { "msp430f1481",0,1 },
794 { "msp430f149",0,1 },
795 { "msp430f1491",0,1 },
796 { "msp430f155",0,0 },
797 { "msp430f156",0,0 },
798 { "msp430f157",0,0 },
799 { "msp430f1610",0,1 },
800 { "msp430f1611",0,1 },
801 { "msp430f1612",0,1 },
802 { "msp430f167",0,1 },
803 { "msp430f168",0,1 },
804 { "msp430f169",0,1 },
805 { "msp430f2001",0,0 },
806 { "msp430f2002",0,0 },
807 { "msp430f2003",0,0 },
808 { "msp430f2011",0,0 },
809 { "msp430f2012",0,0 },
810 { "msp430f2013",0,0 },
811 { "msp430f2101",0,0 },
812 { "msp430f2111",0,0 },
813 { "msp430f2112",0,0 },
814 { "msp430f2121",0,0 },
815 { "msp430f2122",0,0 },
816 { "msp430f2131",0,0 },
817 { "msp430f2132",0,0 },
818 { "msp430f2232",0,0 },
819 { "msp430f2234",0,0 },
820 { "msp430f2252",0,0 },
821 { "msp430f2254",0,0 },
822 { "msp430f2272",0,0 },
823 { "msp430f2274",0,0 },
824 { "msp430f233",0,2 },
825 { "msp430f2330",0,2 },
826 { "msp430f235",0,2 },
827 { "msp430f2350",0,2 },
828 { "msp430f2370",0,2 },
829 { "msp430f2410",0,2 },
830 { "msp430f2416",1,2 },
831 { "msp430f2417",1,2 },
832 { "msp430f2418",1,2 },
833 { "msp430f2419",1,2 },
834 { "msp430f247",0,2 },
835 { "msp430f2471",0,2 },
836 { "msp430f248",0,2 },
837 { "msp430f2481",0,2 },
838 { "msp430f249",0,2 },
839 { "msp430f2491",0,2 },
840 { "msp430f2616",1,2 },
841 { "msp430f2617",1,2 },
842 { "msp430f2618",1,2 },
843 { "msp430f2619",1,2 },
844 { "msp430f412",0,0 },
845 { "msp430f413",0,0 },
846 { "msp430f4132",0,0 },
847 { "msp430f415",0,0 },
848 { "msp430f4152",0,0 },
849 { "msp430f417",0,0 },
850 { "msp430f423",0,1 },
851 { "msp430f423a",0,1 },
852 { "msp430f425",0,1 },
853 { "msp430f4250",0,0 },
854 { "msp430f425a",0,1 },
855 { "msp430f4260",0,0 },
856 { "msp430f427",0,1 },
857 { "msp430f4270",0,0 },
858 { "msp430f427a",0,1 },
859 { "msp430f435",0,0 },
860 { "msp430f4351",0,0 },
861 { "msp430f436",0,0 },
862 { "msp430f4361",0,0 },
863 { "msp430f437",0,0 },
864 { "msp430f4371",0,0 },
865 { "msp430f438",0,0 },
866 { "msp430f439",0,0 },
867 { "msp430f447",0,1 },
868 { "msp430f448",0,1 },
869 { "msp430f4481",0,1 },
870 { "msp430f449",0,1 },
871 { "msp430f4491",0,1 },
872 { "msp430f4616",1,1 },
873 { "msp430f46161",1,1 },
874 { "msp430f4617",1,1 },
875 { "msp430f46171",1,1 },
876 { "msp430f4618",1,1 },
877 { "msp430f46181",1,1 },
878 { "msp430f4619",1,1 },
879 { "msp430f46191",1,1 },
880 { "msp430f47126",1,4 },
881 { "msp430f47127",1,4 },
882 { "msp430f47163",1,4 },
883 { "msp430f47166",1,4 },
884 { "msp430f47167",1,4 },
885 { "msp430f47173",1,4 },
886 { "msp430f47176",1,4 },
887 { "msp430f47177",1,4 },
888 { "msp430f47183",1,4 },
889 { "msp430f47186",1,4 },
890 { "msp430f47187",1,4 },
891 { "msp430f47193",1,4 },
892 { "msp430f47196",1,4 },
893 { "msp430f47197",1,4 },
894 { "msp430f477",0,0 },
895 { "msp430f478",0,0 },
896 { "msp430f4783",0,4 },
897 { "msp430f4784",0,4 },
898 { "msp430f479",0,0 },
899 { "msp430f4793",0,4 },
900 { "msp430f4794",0,4 },
901 { "msp430f5131",2,8 },
902 { "msp430f5132",2,8 },
903 { "msp430f5151",2,8 },
904 { "msp430f5152",2,8 },
905 { "msp430f5171",2,8 },
906 { "msp430f5172",2,8 },
907 { "msp430f5212",2,8 },
908 { "msp430f5213",2,8 },
909 { "msp430f5214",2,8 },
910 { "msp430f5217",2,8 },
911 { "msp430f5218",2,8 },
912 { "msp430f5219",2,8 },
913 { "msp430f5222",2,8 },
914 { "msp430f5223",2,8 },
915 { "msp430f5224",2,8 },
916 { "msp430f5227",2,8 },
917 { "msp430f5228",2,8 },
918 { "msp430f5229",2,8 },
919 { "msp430f5232",2,8 },
920 { "msp430f5234",2,8 },
921 { "msp430f5237",2,8 },
922 { "msp430f5239",2,8 },
923 { "msp430f5242",2,8 },
924 { "msp430f5244",2,8 },
925 { "msp430f5247",2,8 },
926 { "msp430f5249",2,8 },
927 { "msp430f5252",2,8 },
928 { "msp430f5253",2,8 },
929 { "msp430f5254",2,8 },
930 { "msp430f5255",2,8 },
931 { "msp430f5256",2,8 },
932 { "msp430f5257",2,8 },
933 { "msp430f5258",2,8 },
934 { "msp430f5259",2,8 },
935 { "msp430f5304",2,8 },
936 { "msp430f5308",2,8 },
937 { "msp430f5309",2,8 },
938 { "msp430f5310",2,8 },
939 { "msp430f5324",2,8 },
940 { "msp430f5325",2,8 },
941 { "msp430f5326",2,8 },
942 { "msp430f5327",2,8 },
943 { "msp430f5328",2,8 },
944 { "msp430f5329",2,8 },
945 { "msp430f5333",2,8 },
946 { "msp430f5335",2,8 },
947 { "msp430f5336",2,8 },
948 { "msp430f5338",2,8 },
949 { "msp430f5340",2,8 },
950 { "msp430f5341",2,8 },
951 { "msp430f5342",2,8 },
952 { "msp430f5358",2,8 },
953 { "msp430f5359",2,8 },
954 { "msp430f5418",2,8 },
955 { "msp430f5418a",2,8 },
956 { "msp430f5419",2,8 },
957 { "msp430f5419a",2,8 },
958 { "msp430f5435",2,8 },
959 { "msp430f5435a",2,8 },
960 { "msp430f5436",2,8 },
961 { "msp430f5436a",2,8 },
962 { "msp430f5437",2,8 },
963 { "msp430f5437a",2,8 },
964 { "msp430f5438",2,8 },
965 { "msp430f5438a",2,8 },
966 { "msp430f5500",2,8 },
967 { "msp430f5501",2,8 },
968 { "msp430f5502",2,8 },
969 { "msp430f5503",2,8 },
970 { "msp430f5504",2,8 },
971 { "msp430f5505",2,8 },
972 { "msp430f5506",2,8 },
973 { "msp430f5507",2,8 },
974 { "msp430f5508",2,8 },
975 { "msp430f5509",2,8 },
976 { "msp430f5510",2,8 },
977 { "msp430f5513",2,8 },
978 { "msp430f5514",2,8 },
979 { "msp430f5515",2,8 },
980 { "msp430f5517",2,8 },
981 { "msp430f5519",2,8 },
982 { "msp430f5521",2,8 },
983 { "msp430f5522",2,8 },
984 { "msp430f5524",2,8 },
985 { "msp430f5525",2,8 },
986 { "msp430f5526",2,8 },
987 { "msp430f5527",2,8 },
988 { "msp430f5528",2,8 },
989 { "msp430f5529",2,8 },
990 { "msp430f5630",2,8 },
991 { "msp430f5631",2,8 },
992 { "msp430f5632",2,8 },
993 { "msp430f5633",2,8 },
994 { "msp430f5634",2,8 },
995 { "msp430f5635",2,8 },
996 { "msp430f5636",2,8 },
997 { "msp430f5637",2,8 },
998 { "msp430f5638",2,8 },
999 { "msp430f5658",2,8 },
1000 { "msp430f5659",2,8 },
1001 { "msp430f5xx_6xxgeneric",2,8 },
1002 { "msp430f6433",2,8 },
1003 { "msp430f6435",2,8 },
1004 { "msp430f6436",2,8 },
1005 { "msp430f6438",2,8 },
1006 { "msp430f6458",2,8 },
1007 { "msp430f6459",2,8 },
1008 { "msp430f6630",2,8 },
1009 { "msp430f6631",2,8 },
1010 { "msp430f6632",2,8 },
1011 { "msp430f6633",2,8 },
1012 { "msp430f6634",2,8 },
1013 { "msp430f6635",2,8 },
1014 { "msp430f6636",2,8 },
1015 { "msp430f6637",2,8 },
1016 { "msp430f6638",2,8 },
1017 { "msp430f6658",2,8 },
1018 { "msp430f6659",2,8 },
1019 { "msp430f6720",2,8 },
1020 { "msp430f6720a",2,8 },
1021 { "msp430f6721",2,8 },
1022 { "msp430f6721a",2,8 },
1023 { "msp430f6723",2,8 },
1024 { "msp430f6723a",2,8 },
1025 { "msp430f6724",2,8 },
1026 { "msp430f6724a",2,8 },
1027 { "msp430f6725",2,8 },
1028 { "msp430f6725a",2,8 },
1029 { "msp430f6726",2,8 },
1030 { "msp430f6726a",2,8 },
1031 { "msp430f6730",2,8 },
1032 { "msp430f6730a",2,8 },
1033 { "msp430f6731",2,8 },
1034 { "msp430f6731a",2,8 },
1035 { "msp430f6733",2,8 },
1036 { "msp430f6733a",2,8 },
1037 { "msp430f6734",2,8 },
1038 { "msp430f6734a",2,8 },
1039 { "msp430f6735",2,8 },
1040 { "msp430f6735a",2,8 },
1041 { "msp430f6736",2,8 },
1042 { "msp430f6736a",2,8 },
1043 { "msp430f6745",2,8 },
1044 { "msp430f67451",2,8 },
1045 { "msp430f67451a",2,8 },
1046 { "msp430f6745a",2,8 },
1047 { "msp430f6746",2,8 },
1048 { "msp430f67461",2,8 },
1049 { "msp430f67461a",2,8 },
1050 { "msp430f6746a",2,8 },
1051 { "msp430f6747",2,8 },
1052 { "msp430f67471",2,8 },
1053 { "msp430f67471a",2,8 },
1054 { "msp430f6747a",2,8 },
1055 { "msp430f6748",2,8 },
1056 { "msp430f67481",2,8 },
1057 { "msp430f67481a",2,8 },
1058 { "msp430f6748a",2,8 },
1059 { "msp430f6749",2,8 },
1060 { "msp430f67491",2,8 },
1061 { "msp430f67491a",2,8 },
1062 { "msp430f6749a",2,8 },
1063 { "msp430f67621",2,8 },
1064 { "msp430f67621a",2,8 },
1065 { "msp430f67641",2,8 },
1066 { "msp430f67641a",2,8 },
1067 { "msp430f6765",2,8 },
1068 { "msp430f67651",2,8 },
1069 { "msp430f67651a",2,8 },
1070 { "msp430f6765a",2,8 },
1071 { "msp430f6766",2,8 },
1072 { "msp430f67661",2,8 },
1073 { "msp430f67661a",2,8 },
1074 { "msp430f6766a",2,8 },
1075 { "msp430f6767",2,8 },
1076 { "msp430f67671",2,8 },
1077 { "msp430f67671a",2,8 },
1078 { "msp430f6767a",2,8 },
1079 { "msp430f6768",2,8 },
1080 { "msp430f67681",2,8 },
1081 { "msp430f67681a",2,8 },
1082 { "msp430f6768a",2,8 },
1083 { "msp430f6769",2,8 },
1084 { "msp430f67691",2,8 },
1085 { "msp430f67691a",2,8 },
1086 { "msp430f6769a",2,8 },
1087 { "msp430f6775",2,8 },
1088 { "msp430f67751",2,8 },
1089 { "msp430f67751a",2,8 },
1090 { "msp430f6775a",2,8 },
1091 { "msp430f6776",2,8 },
1092 { "msp430f67761",2,8 },
1093 { "msp430f67761a",2,8 },
1094 { "msp430f6776a",2,8 },
1095 { "msp430f6777",2,8 },
1096 { "msp430f67771",2,8 },
1097 { "msp430f67771a",2,8 },
1098 { "msp430f6777a",2,8 },
1099 { "msp430f6778",2,8 },
1100 { "msp430f67781",2,8 },
1101 { "msp430f67781a",2,8 },
1102 { "msp430f6778a",2,8 },
1103 { "msp430f6779",2,8 },
1104 { "msp430f67791",2,8 },
1105 { "msp430f67791a",2,8 },
1106 { "msp430f6779a",2,8 },
1107 { "msp430fe423",0,0 },
1108 { "msp430fe4232",0,0 },
1109 { "msp430fe423a",0,0 },
1110 { "msp430fe4242",0,0 },
1111 { "msp430fe425",0,0 },
1112 { "msp430fe4252",0,0 },
1113 { "msp430fe425a",0,0 },
1114 { "msp430fe427",0,0 },
1115 { "msp430fe4272",0,0 },
1116 { "msp430fe427a",0,0 },
1117 { "msp430fg4250",0,0 },
1118 { "msp430fg4260",0,0 },
1119 { "msp430fg4270",0,0 },
1120 { "msp430fg437",0,0 },
1121 { "msp430fg438",0,0 },
1122 { "msp430fg439",0,0 },
1123 { "msp430fg4616",1,1 },
1124 { "msp430fg4617",1,1 },
1125 { "msp430fg4618",1,1 },
1126 { "msp430fg4619",1,1 },
1127 { "msp430fg477",0,0 },
1128 { "msp430fg478",0,0 },
1129 { "msp430fg479",0,0 },
1130 { "msp430fg6425",2,8 },
1131 { "msp430fg6426",2,8 },
1132 { "msp430fg6625",2,8 },
1133 { "msp430fg6626",2,8 },
1134 { "msp430fr2032",2,0 },
1135 { "msp430fr2033",2,0 },
1136 { "msp430fr2310",2,0 },
1137 { "msp430fr2311",2,0 },
1138 { "msp430fr2433",2,8 },
1139 { "msp430fr2532",2,8 },
1140 { "msp430fr2533",2,8 },
1141 { "msp430fr2632",2,8 },
1142 { "msp430fr2633",2,8 },
1143 { "msp430fr2xx_4xxgeneric",2,8 },
1144 { "msp430fr4131",2,0 },
1145 { "msp430fr4132",2,0 },
1146 { "msp430fr4133",2,0 },
1147 { "msp430fr5720",2,8 },
1148 { "msp430fr5721",2,8 },
1149 { "msp430fr5722",2,8 },
1150 { "msp430fr5723",2,8 },
1151 { "msp430fr5724",2,8 },
1152 { "msp430fr5725",2,8 },
1153 { "msp430fr5726",2,8 },
1154 { "msp430fr5727",2,8 },
1155 { "msp430fr5728",2,8 },
1156 { "msp430fr5729",2,8 },
1157 { "msp430fr5730",2,8 },
1158 { "msp430fr5731",2,8 },
1159 { "msp430fr5732",2,8 },
1160 { "msp430fr5733",2,8 },
1161 { "msp430fr5734",2,8 },
1162 { "msp430fr5735",2,8 },
1163 { "msp430fr5736",2,8 },
1164 { "msp430fr5737",2,8 },
1165 { "msp430fr5738",2,8 },
1166 { "msp430fr5739",2,8 },
1167 { "msp430fr57xxgeneric",2,8 },
1168 { "msp430fr5847",2,8 },
1169 { "msp430fr58471",2,8 },
1170 { "msp430fr5848",2,8 },
1171 { "msp430fr5849",2,8 },
1172 { "msp430fr5857",2,8 },
1173 { "msp430fr5858",2,8 },
1174 { "msp430fr5859",2,8 },
1175 { "msp430fr5867",2,8 },
1176 { "msp430fr5862",2,8 },
1177 { "msp430fr5864",2,8 },
1178 { "msp430fr58671",2,8 },
1179 { "msp430fr5868",2,8 },
1180 { "msp430fr5869",2,8 },
1181 { "msp430fr5870",2,8 },
1182 { "msp430fr5872",2,8 },
1183 { "msp430fr58721",2,8 },
1184 { "msp430fr5887",2,8 },
1185 { "msp430fr5888",2,8 },
1186 { "msp430fr5889",2,8 },
1187 { "msp430fr58891",2,8 },
1188 { "msp430fr5892",2,8 },
1189 { "msp430fr5894",2,8 },
1190 { "msp430fr5922",2,8 },
1191 { "msp430fr59221",2,8 },
1192 { "msp430fr5947",2,8 },
1193 { "msp430fr59471",2,8 },
1194 { "msp430fr5948",2,8 },
1195 { "msp430fr5949",2,8 },
1196 { "msp430fr5957",2,8 },
1197 { "msp430fr5958",2,8 },
1198 { "msp430fr5959",2,8 },
1199 { "msp430fr5962",2,8 },
1200 { "msp430fr5964",2,8 },
1201 { "msp430fr5967",2,8 },
1202 { "msp430fr5968",2,8 },
1203 { "msp430fr5969",2,8 },
1204 { "msp430fr59691",2,8 },
1205 { "msp430fr5970",2,8 },
1206 { "msp430fr5972",2,8 },
1207 { "msp430fr59721",2,8 },
1208 { "msp430fr5986",2,8 },
1209 { "msp430fr5987",2,8 },
1210 { "msp430fr5988",2,8 },
1211 { "msp430fr5989",2,8 },
1212 { "msp430fr59891",2,8 },
1213 { "msp430fr5992",2,8 },
1214 { "msp430fr5994",2,8 },
1215 { "msp430fr5xx_6xxgeneric",2,8 },
1216 { "msp430fr6820",2,8 },
1217 { "msp430fr6822",2,8 },
1218 { "msp430fr68221",2,8 },
1219 { "msp430fr6870",2,8 },
1220 { "msp430fr6872",2,8 },
1221 { "msp430fr68721",2,8 },
1222 { "msp430fr6877",2,8 },
1223 { "msp430fr6879",2,8 },
1224 { "msp430fr68791",2,8 },
1225 { "msp430fr6887",2,8 },
1226 { "msp430fr6888",2,8 },
1227 { "msp430fr6889",2,8 },
1228 { "msp430fr68891",2,8 },
1229 { "msp430fr6920",2,8 },
1230 { "msp430fr6922",2,8 },
1231 { "msp430fr69221",2,8 },
1232 { "msp430fr6927",2,8 },
1233 { "msp430fr69271",2,8 },
1234 { "msp430fr6928",2,8 },
1235 { "msp430fr6970",2,8 },
1236 { "msp430fr6972",2,8 },
1237 { "msp430fr69721",2,8 },
1238 { "msp430fr6977",2,8 },
1239 { "msp430fr6979",2,8 },
1240 { "msp430fr69791",2,8 },
1241 { "msp430fr6987",2,8 },
1242 { "msp430fr6988",2,8 },
1243 { "msp430fr6989",2,8 },
1244 { "msp430fr69891",2,8 },
1245 { "msp430fw423",0,0 },
1246 { "msp430fw425",0,0 },
1247 { "msp430fw427",0,0 },
1248 { "msp430fw428",0,0 },
1249 { "msp430fw429",0,0 },
1250 { "msp430g2001",0,0 },
1251 { "msp430g2101",0,0 },
1252 { "msp430g2102",0,0 },
1253 { "msp430g2111",0,0 },
1254 { "msp430g2112",0,0 },
1255 { "msp430g2113",0,0 },
1256 { "msp430g2121",0,0 },
1257 { "msp430g2131",0,0 },
1258 { "msp430g2132",0,0 },
1259 { "msp430g2152",0,0 },
1260 { "msp430g2153",0,0 },
1261 { "msp430g2201",0,0 },
1262 { "msp430g2202",0,0 },
1263 { "msp430g2203",0,0 },
1264 { "msp430g2210",0,0 },
1265 { "msp430g2211",0,0 },
1266 { "msp430g2212",0,0 },
1267 { "msp430g2213",0,0 },
1268 { "msp430g2221",0,0 },
1269 { "msp430g2230",0,0 },
1270 { "msp430g2231",0,0 },
1271 { "msp430g2232",0,0 },
1272 { "msp430g2233",0,0 },
1273 { "msp430g2252",0,0 },
1274 { "msp430g2253",0,0 },
1275 { "msp430g2302",0,0 },
1276 { "msp430g2303",0,0 },
1277 { "msp430g2312",0,0 },
1278 { "msp430g2313",0,0 },
1279 { "msp430g2332",0,0 },
1280 { "msp430g2333",0,0 },
1281 { "msp430g2352",0,0 },
1282 { "msp430g2353",0,0 },
1283 { "msp430g2402",0,0 },
1284 { "msp430g2403",0,0 },
1285 { "msp430g2412",0,0 },
1286 { "msp430g2413",0,0 },
1287 { "msp430g2432",0,0 },
1288 { "msp430g2433",0,0 },
1289 { "msp430g2444",0,0 },
1290 { "msp430g2452",0,0 },
1291 { "msp430g2453",0,0 },
1292 { "msp430g2513",0,0 },
1293 { "msp430g2533",0,0 },
1294 { "msp430g2544",0,0 },
1295 { "msp430g2553",0,0 },
1296 { "msp430g2744",0,0 },
1297 { "msp430g2755",0,0 },
1298 { "msp430g2855",0,0 },
1299 { "msp430g2955",0,0 },
1300 { "msp430i2020",0,2 },
1301 { "msp430i2021",0,2 },
1302 { "msp430i2030",0,2 },
1303 { "msp430i2031",0,2 },
1304 { "msp430i2040",0,2 },
1305 { "msp430i2041",0,2 },
1306 { "msp430i2xxgeneric",0,2 },
1307 { "msp430l092",0,0 },
1308 { "msp430p112",0,0 },
1309 { "msp430p313",0,0 },
1310 { "msp430p315",0,0 },
1311 { "msp430p315s",0,0 },
1312 { "msp430p325",0,0 },
1313 { "msp430p337",0,1 },
1314 { "msp430sl5438a",2,8 },
1315 { "msp430tch5e",0,0 },
1316 { "msp430xgeneric",2,8 },
1317 { "rf430f5144",2,8 },
1318 { "rf430f5155",2,8 },
1319 { "rf430f5175",2,8 },
1320 { "rf430frl152h",0,0 },
1321 { "rf430frl152h_rom",0,0 },
1322 { "rf430frl153h",0,0 },
1323 { "rf430frl153h_rom",0,0 },
1324 { "rf430frl154h",0,0 },
1325 { "rf430frl154h_rom",0,0 }
1329 md_parse_option (int c
, const char * arg
)
1333 case OPTION_SILICON_ERRATA
:
1334 case OPTION_SILICON_ERRATA_WARN
:
1340 unsigned int length
;
1341 unsigned int bitfield
;
1344 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1345 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1346 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1347 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1348 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1349 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1354 for (i
= ARRAY_SIZE (erratas
); i
--;)
1355 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1357 if (c
== OPTION_SILICON_ERRATA
)
1358 silicon_errata_fix
|= erratas
[i
].bitfield
;
1360 silicon_errata_warn
|= erratas
[i
].bitfield
;
1361 arg
+= erratas
[i
].length
;
1366 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1372 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1382 as_fatal (_("MCU option requires a name\n"));
1384 if (strcasecmp ("msp430", arg
) == 0)
1385 selected_isa
= MSP_ISA_430
;
1386 else if (strcasecmp ("msp430xv2", arg
) == 0)
1387 selected_isa
= MSP_ISA_430Xv2
;
1388 else if (strcasecmp ("msp430x", arg
) == 0)
1389 selected_isa
= MSP_ISA_430X
;
1394 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1395 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1397 switch (msp430_mcu_data
[i
].revision
)
1399 case 0: selected_isa
= MSP_ISA_430
; break;
1400 case 1: selected_isa
= MSP_ISA_430X
; break;
1401 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1406 /* It is not an error if we do not match the MCU name. */
1410 if (strcmp (arg
, "430") == 0
1411 || strcasecmp (arg
, "msp430") == 0)
1412 selected_isa
= MSP_ISA_430
;
1413 else if (strcasecmp (arg
, "430x") == 0
1414 || strcasecmp (arg
, "msp430x") == 0)
1415 selected_isa
= MSP_ISA_430X
;
1416 else if (strcasecmp (arg
, "430xv2") == 0
1417 || strcasecmp (arg
, "msp430xv2") == 0)
1418 selected_isa
= MSP_ISA_430Xv2
;
1420 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1424 msp430_enable_relax
= 1;
1427 case OPTION_POLYMORPHS
:
1428 msp430_enable_polys
= 1;
1435 case OPTION_NO_INTR_NOPS
:
1436 gen_interrupt_nops
= FALSE
;
1438 case OPTION_INTR_NOPS
:
1439 gen_interrupt_nops
= TRUE
;
1442 case OPTION_WARN_INTR_NOPS
:
1443 warn_interrupt_nops
= TRUE
;
1445 case OPTION_NO_WARN_INTR_NOPS
:
1446 warn_interrupt_nops
= FALSE
;
1449 case OPTION_MOVE_DATA
:
1457 /* The intention here is to have the mere presence of these sections
1458 cause the object to have a reference to a well-known symbol. This
1459 reference pulls in the bits of the runtime (crt0) that initialize
1460 these sections. Thus, for example, the startup code to call
1461 memset() to initialize .bss will only be linked in when there is a
1462 non-empty .bss section. Otherwise, the call would exist but have a
1463 zero length parameter, which is a waste of memory and cycles.
1465 The code which initializes these sections should have a global
1466 label for these symbols, and should be marked with KEEP() in the
1470 msp430_make_init_symbols (const char * name
)
1472 if (strncmp (name
, ".bss", 4) == 0
1473 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1474 (void) symbol_find_or_make ("__crt0_init_bss");
1476 if (strncmp (name
, ".data", 5) == 0
1477 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1478 (void) symbol_find_or_make ("__crt0_movedata");
1480 /* Note - data assigned to the .either.data section may end up being
1481 placed in the .upper.data section if the .lower.data section is
1482 full. Hence the need to define the crt0 symbol. */
1483 if (strncmp (name
, ".either.data", 12) == 0
1484 || strncmp (name
, ".upper.data", 11) == 0)
1485 (void) symbol_find_or_make ("__crt0_move_highdata");
1487 /* See note about .either.data above. */
1488 if (strncmp (name
, ".upper.bss", 10) == 0
1489 || strncmp (name
, ".either.bss", 11) == 0)
1490 (void) symbol_find_or_make ("__crt0_init_highbss");
1494 msp430_section (int arg
)
1496 char * saved_ilp
= input_line_pointer
;
1497 const char * name
= obj_elf_section_name ();
1499 msp430_make_init_symbols (name
);
1501 input_line_pointer
= saved_ilp
;
1502 obj_elf_section (arg
);
1506 msp430_frob_section (asection
*sec
)
1508 const char *name
= sec
->name
;
1513 msp430_make_init_symbols (name
);
1517 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1519 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1522 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1523 (void) symbol_find_or_make ("__crt0_init_bss");
1527 msp430_comm (int needs_align
)
1529 s_comm_internal (needs_align
, elf_common_parse
);
1530 (void) symbol_find_or_make ("__crt0_init_bss");
1534 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1536 char sym_name
[1024];
1537 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1539 (void) symbol_find_or_make (sym_name
);
1542 const pseudo_typeS md_pseudo_table
[] =
1544 {"arch", msp430_set_arch
, OPTION_MMCU
},
1545 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1546 {"profiler", msp430_profiler
, 0},
1547 {"section", msp430_section
, 0},
1548 {"section.s", msp430_section
, 0},
1549 {"sect", msp430_section
, 0},
1550 {"sect.s", msp430_section
, 0},
1551 {"pushsection", msp430_section
, 1},
1552 {"refsym", msp430_refsym
, 0},
1553 {"comm", msp430_comm
, 0},
1554 {"lcomm", msp430_lcomm
, 0},
1558 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1560 struct option md_longopts
[] =
1562 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1563 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1564 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1565 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1566 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1567 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1568 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1569 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1570 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1571 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1572 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1573 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1574 {NULL
, no_argument
, NULL
, 0}
1577 size_t md_longopts_size
= sizeof (md_longopts
);
1580 md_show_usage (FILE * stream
)
1583 _("MSP430 options:\n"
1584 " -mmcu=<msp430-name> - select microcontroller type\n"
1585 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1587 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1588 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1589 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1591 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1592 " -mP - enable polymorph instructions\n"));
1594 _(" -ml - enable large code model\n"));
1596 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1598 _(" -mn - insert a NOP after changing interrupts\n"));
1600 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1602 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1604 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1608 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1614 extract_cmd (char * from
, char * to
, int limit
)
1618 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1620 *(to
+ size
) = *from
;
1631 md_atof (int type
, char * litP
, int * sizeP
)
1633 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1639 struct msp430_opcode_s
* opcode
;
1640 msp430_hash
= hash_new ();
1642 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1643 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1645 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1646 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1648 /* Set linkrelax here to avoid fixups in most sections. */
1652 /* Returns the register number equivalent to the string T.
1653 Returns -1 if there is no such register.
1654 Skips a leading 'r' or 'R' character if there is one.
1655 Handles the register aliases PC and SP. */
1658 check_reg (char * t
)
1665 if (*t
== 'r' || *t
== 'R')
1668 if (strncasecmp (t
, "pc", 2) == 0)
1671 if (strncasecmp (t
, "sp", 2) == 0)
1674 if (strncasecmp (t
, "sr", 2) == 0)
1682 if (val
< 1 || val
> 15)
1689 msp430_srcoperand (struct msp430_operand_s
* op
,
1692 bfd_boolean
* imm_op
,
1693 bfd_boolean allow_20bit_values
,
1694 bfd_boolean constants_allowed
)
1698 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1705 /* Check if there is:
1706 llo(x) - least significant 16 bits, x &= 0xffff
1707 lhi(x) - x = (x >> 16) & 0xffff,
1708 hlo(x) - x = (x >> 32) & 0xffff,
1709 hhi(x) - x = (x >> 48) & 0xffff
1710 The value _MUST_ be constant expression: #hlo(1231231231). */
1714 if (strncasecmp (h
, "#llo(", 5) == 0)
1719 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1724 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1729 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1734 else if (strncasecmp (h
, "#lo(", 4) == 0)
1739 else if (strncasecmp (h
, "#hi(", 4) == 0)
1745 op
->reg
= 0; /* Reg PC. */
1747 op
->ol
= 1; /* Immediate will follow an instruction. */
1748 __tl
= h
+ 1 + rval
;
1750 op
->vshift
= vshift
;
1752 parse_exp (__tl
, &(op
->exp
));
1753 if (op
->exp
.X_op
== O_constant
)
1755 int x
= op
->exp
.X_add_number
;
1760 op
->exp
.X_add_number
= x
;
1762 else if (vshift
== 1)
1764 x
= (x
>> 16) & 0xffff;
1765 op
->exp
.X_add_number
= x
;
1768 else if (vshift
> 1)
1771 op
->exp
.X_add_number
= -1;
1773 op
->exp
.X_add_number
= 0; /* Nothing left. */
1774 x
= op
->exp
.X_add_number
;
1778 if (allow_20bit_values
)
1780 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1782 as_bad (_("value 0x%x out of extended range."), x
);
1786 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1788 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1792 /* Now check constants. */
1793 /* Substitute register mode with a constant generator if applicable. */
1795 if (!allow_20bit_values
)
1796 x
= (short) x
; /* Extend sign. */
1798 if (! constants_allowed
)
1830 if (bin
== 0x1200 && ! target_is_430x ())
1832 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1833 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1834 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1835 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1847 if (bin
== 0x1200 && ! target_is_430x ())
1849 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1850 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1851 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1862 else if (op
->exp
.X_op
== O_symbol
)
1865 as_bad (_("error: unsupported #foo() directive used on symbol"));
1868 else if (op
->exp
.X_op
== O_big
)
1874 op
->exp
.X_op
= O_constant
;
1875 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1876 x
= op
->exp
.X_add_number
;
1882 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1930 /* Redundant (yet) check. */
1931 else if (op
->exp
.X_op
== O_register
)
1933 (_("Registers cannot be used within immediate expression [%s]"), l
);
1935 as_bad (_("unknown operand %s"), l
);
1940 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1945 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1946 op
->am
= 1; /* mode As == 01 bin. */
1947 op
->ol
= 1; /* Immediate value followed by instruction. */
1949 parse_exp (__tl
, &(op
->exp
));
1952 if (op
->exp
.X_op
== O_constant
)
1954 int x
= op
->exp
.X_add_number
;
1956 if (allow_20bit_values
)
1958 if (x
> 0xfffff || x
< -(0x7ffff))
1960 as_bad (_("value 0x%x out of extended range."), x
);
1964 else if (x
> 65535 || x
< -32768)
1966 as_bad (_("value out of range: 0x%x"), x
);
1970 else if (op
->exp
.X_op
== O_symbol
)
1974 /* Redundant (yet) check. */
1975 if (op
->exp
.X_op
== O_register
)
1977 (_("Registers cannot be used within absolute expression [%s]"), l
);
1979 as_bad (_("unknown expression in operand %s"), l
);
1985 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1989 char *m
= strchr (l
, '+');
1993 as_bad (_("unknown addressing mode %s"), l
);
1999 if ((op
->reg
= check_reg (t
)) == -1)
2001 as_bad (_("Bad register name %s"), t
);
2009 /* PC cannot be used in indirect addressing. */
2010 if (target_is_430xv2 () && op
->reg
== 0)
2012 as_bad (_("cannot use indirect addressing with the PC"));
2019 /* Check if register indexed X(Rn). */
2022 char *h
= strrchr (l
, '(');
2023 char *m
= strrchr (l
, ')');
2032 as_bad (_("')' required"));
2040 /* Extract a register. */
2041 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2044 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2051 as_bad (_("r2 should not be used in indexed addressing mode"));
2055 /* Extract constant. */
2060 parse_exp (__tl
, &(op
->exp
));
2061 if (op
->exp
.X_op
== O_constant
)
2063 int x
= op
->exp
.X_add_number
;
2065 if (allow_20bit_values
)
2067 if (x
> 0xfffff || x
< - (0x7ffff))
2069 as_bad (_("value 0x%x out of extended range."), x
);
2073 else if (x
> 65535 || x
< -32768)
2075 as_bad (_("value out of range: 0x%x"), x
);
2087 if (op
->reg
== 1 && (x
& 1))
2089 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2090 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2091 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2092 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2095 else if (op
->exp
.X_op
== O_symbol
)
2099 /* Redundant (yet) check. */
2100 if (op
->exp
.X_op
== O_register
)
2102 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2104 as_bad (_("unknown expression in operand %s"), l
);
2112 /* Possibly register mode 'mov r1,r2'. */
2113 if ((op
->reg
= check_reg (l
)) != -1)
2121 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2125 op
->reg
= 0; /* PC relative... be careful. */
2126 /* An expression starting with a minus sign is a constant, not an address. */
2127 op
->am
= (*l
== '-' ? 3 : 1);
2131 parse_exp (__tl
, &(op
->exp
));
2137 as_bad (_("unknown addressing mode for operand %s"), l
);
2143 msp430_dstoperand (struct msp430_operand_s
* op
,
2146 bfd_boolean allow_20bit_values
,
2147 bfd_boolean constants_allowed
)
2150 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2159 char *__tl
= (char *) "0";
2165 parse_exp (__tl
, &(op
->exp
));
2167 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2169 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2179 ("this addressing mode is not applicable for destination operand"));
2185 /* Attempt to encode a MOVA instruction with the given operands.
2186 Returns the length of the encoded instruction if successful
2187 or 0 upon failure. If the encoding fails, an error message
2188 will be returned if a pointer is provided. */
2191 try_encode_mova (bfd_boolean imm_op
,
2193 struct msp430_operand_s
* op1
,
2194 struct msp430_operand_s
* op2
,
2195 const char ** error_message_return
)
2201 /* Only a restricted subset of the normal MSP430 addressing modes
2202 are supported here, so check for the ones that are allowed. */
2205 if (op1
->mode
== OP_EXP
)
2207 if (op2
->mode
!= OP_REG
)
2209 if (error_message_return
!= NULL
)
2210 * error_message_return
= _("expected register as second argument of %s");
2216 /* MOVA #imm20, Rdst. */
2217 bin
|= 0x80 | op2
->reg
;
2218 frag
= frag_more (4);
2219 where
= frag
- frag_now
->fr_literal
;
2220 if (op1
->exp
.X_op
== O_constant
)
2222 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2223 bfd_putl16 ((bfd_vma
) bin
, frag
);
2224 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2228 bfd_putl16 ((bfd_vma
) bin
, frag
);
2229 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2230 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2231 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2236 else if (op1
->am
== 1)
2238 /* MOVA z16(Rsrc), Rdst. */
2239 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2240 frag
= frag_more (4);
2241 where
= frag
- frag_now
->fr_literal
;
2242 bfd_putl16 ((bfd_vma
) bin
, frag
);
2243 if (op1
->exp
.X_op
== O_constant
)
2245 if (op1
->exp
.X_add_number
> 0xffff
2246 || op1
->exp
.X_add_number
< -(0x7fff))
2248 if (error_message_return
!= NULL
)
2249 * error_message_return
= _("index value too big for %s");
2252 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2256 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2257 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2259 BFD_RELOC_MSP430X_PCR16
:
2260 BFD_RELOC_MSP430X_ABS16
);
2265 if (error_message_return
!= NULL
)
2266 * error_message_return
= _("unexpected addressing mode for %s");
2269 else if (op1
->am
== 0)
2271 /* MOVA Rsrc, ... */
2272 if (op2
->mode
== OP_REG
)
2274 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2275 frag
= frag_more (2);
2276 where
= frag
- frag_now
->fr_literal
;
2277 bfd_putl16 ((bfd_vma
) bin
, frag
);
2280 else if (op2
->am
== 1)
2284 /* MOVA Rsrc, &abs20. */
2285 bin
|= 0x60 | (op1
->reg
<< 8);
2286 frag
= frag_more (4);
2287 where
= frag
- frag_now
->fr_literal
;
2288 if (op2
->exp
.X_op
== O_constant
)
2290 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2291 bfd_putl16 ((bfd_vma
) bin
, frag
);
2292 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2296 bfd_putl16 ((bfd_vma
) bin
, frag
);
2297 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2298 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2299 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2304 /* MOVA Rsrc, z16(Rdst). */
2305 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2306 frag
= frag_more (4);
2307 where
= frag
- frag_now
->fr_literal
;
2308 bfd_putl16 ((bfd_vma
) bin
, frag
);
2309 if (op2
->exp
.X_op
== O_constant
)
2311 if (op2
->exp
.X_add_number
> 0xffff
2312 || op2
->exp
.X_add_number
< -(0x7fff))
2314 if (error_message_return
!= NULL
)
2315 * error_message_return
= _("index value too big for %s");
2318 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2322 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2323 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2325 BFD_RELOC_MSP430X_PCR16
:
2326 BFD_RELOC_MSP430X_ABS16
);
2331 if (error_message_return
!= NULL
)
2332 * error_message_return
= _("unexpected addressing mode for %s");
2337 /* imm_op == FALSE. */
2339 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2341 /* MOVA &abs20, Rdst. */
2342 if (op2
->mode
!= OP_REG
)
2344 if (error_message_return
!= NULL
)
2345 * error_message_return
= _("expected register as second argument of %s");
2349 if (op2
->reg
== 2 || op2
->reg
== 3)
2351 if (error_message_return
!= NULL
)
2352 * error_message_return
= _("constant generator destination register found in %s");
2356 bin
|= 0x20 | op2
->reg
;
2357 frag
= frag_more (4);
2358 where
= frag
- frag_now
->fr_literal
;
2359 if (op1
->exp
.X_op
== O_constant
)
2361 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2362 bfd_putl16 ((bfd_vma
) bin
, frag
);
2363 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2367 bfd_putl16 ((bfd_vma
) bin
, frag
);
2368 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2369 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2370 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2374 else if (op1
->mode
== OP_REG
)
2378 /* MOVA @Rsrc+, Rdst. */
2379 if (op2
->mode
!= OP_REG
)
2381 if (error_message_return
!= NULL
)
2382 * error_message_return
= _("expected register as second argument of %s");
2386 if (op2
->reg
== 2 || op2
->reg
== 3)
2388 if (error_message_return
!= NULL
)
2389 * error_message_return
= _("constant generator destination register found in %s");
2393 if (op1
->reg
== 2 || op1
->reg
== 3)
2395 if (error_message_return
!= NULL
)
2396 * error_message_return
= _("constant generator source register found in %s");
2400 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2401 frag
= frag_more (2);
2402 where
= frag
- frag_now
->fr_literal
;
2403 bfd_putl16 ((bfd_vma
) bin
, frag
);
2406 else if (op1
->am
== 2)
2408 /* MOVA @Rsrc,Rdst */
2409 if (op2
->mode
!= OP_REG
)
2411 if (error_message_return
!= NULL
)
2412 * error_message_return
= _("expected register as second argument of %s");
2416 if (op2
->reg
== 2 || op2
->reg
== 3)
2418 if (error_message_return
!= NULL
)
2419 * error_message_return
= _("constant generator destination register found in %s");
2423 if (op1
->reg
== 2 || op1
->reg
== 3)
2425 if (error_message_return
!= NULL
)
2426 * error_message_return
= _("constant generator source register found in %s");
2430 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2431 frag
= frag_more (2);
2432 where
= frag
- frag_now
->fr_literal
;
2433 bfd_putl16 ((bfd_vma
) bin
, frag
);
2438 if (error_message_return
!= NULL
)
2439 * error_message_return
= _("unexpected addressing mode for %s");
2444 #define NOP_CHECK_INTERRUPT (1 << 0)
2445 #define NOP_CHECK_CPU12 (1 << 1)
2446 #define NOP_CHECK_CPU19 (1 << 2)
2448 static signed int check_for_nop
= 0;
2450 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2452 /* Parse instruction operands.
2453 Return binary opcode. */
2456 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2458 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2459 int insn_length
= 0;
2460 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2463 struct msp430_operand_s op1
, op2
;
2465 static short ZEROS
= 0;
2466 bfd_boolean byte_op
, imm_op
;
2469 int extended
= 0x1800;
2470 bfd_boolean extended_op
= FALSE
;
2471 bfd_boolean addr_op
;
2472 const char * error_message
;
2473 static signed int repeat_count
= 0;
2474 static bfd_boolean prev_insn_is_nop
= FALSE
;
2475 bfd_boolean fix_emitted
;
2477 /* Opcode is the one from opcodes table
2478 line contains something like
2487 bfd_boolean check
= FALSE
;
2490 switch (TOLOWER (* line
))
2493 /* Byte operation. */
2494 bin
|= BYTE_OPERATION
;
2500 /* "Address" ops work on 20-bit values. */
2502 bin
|= BYTE_OPERATION
;
2507 /* Word operation - this is the default. */
2515 as_warn (_("no size modifier after period, .w assumed"));
2519 as_bad (_("unrecognised instruction size modifier .%c"),
2531 if (*line
&& ! ISSPACE (*line
))
2533 as_bad (_("junk found after instruction: %s.%s"),
2534 opcode
->name
, line
);
2538 /* Catch the case where the programmer has used a ".a" size modifier on an
2539 instruction that does not support it. Look for an alternative extended
2540 instruction that has the same name without the period. Eg: "add.a"
2541 becomes "adda". Although this not an officially supported way of
2542 specifing instruction aliases other MSP430 assemblers allow it. So we
2543 support it for compatibility purposes. */
2544 if (addr_op
&& opcode
->fmt
>= 0)
2546 const char * old_name
= opcode
->name
;
2549 sprintf (real_name
, "%sa", old_name
);
2550 opcode
= hash_find (msp430_hash
, real_name
);
2553 as_bad (_("instruction %s.a does not exist"), old_name
);
2556 #if 0 /* Enable for debugging. */
2557 as_warn ("treating %s.a as %s", old_name
, real_name
);
2560 bin
= opcode
->bin_opcode
;
2563 if (opcode
->fmt
!= -1
2564 && opcode
->insn_opnumb
2565 && (!*line
|| *line
== '\n'))
2567 as_bad (_("instruction %s requires %d operand(s)"),
2568 opcode
->name
, opcode
->insn_opnumb
);
2572 memset (l1
, 0, sizeof (l1
));
2573 memset (l2
, 0, sizeof (l2
));
2574 memset (&op1
, 0, sizeof (op1
));
2575 memset (&op2
, 0, sizeof (op2
));
2579 if ((fmt
= opcode
->fmt
) < 0)
2581 if (! target_is_430x ())
2583 as_bad (_("instruction %s requires MSP430X mcu"),
2594 /* If requested set the extended instruction repeat count. */
2597 if (repeat_count
> 0)
2598 extended
|= (repeat_count
- 1);
2600 extended
|= (1 << 7) | (- repeat_count
);
2603 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2610 if (! is_opcode ("nop"))
2612 bfd_boolean doit
= FALSE
;
2616 switch (check_for_nop
& - check_for_nop
)
2618 case NOP_CHECK_INTERRUPT
:
2619 if (warn_interrupt_nops
)
2621 if (gen_interrupt_nops
)
2622 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2624 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2627 if (gen_interrupt_nops
)
2628 /* Emit a NOP between interrupt enable/disable.
2629 See 1.3.4.1 of the MSP430x5xx User Guide. */
2633 case NOP_CHECK_CPU12
:
2634 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2635 as_warn (_("CPU12: CMP/BIT with PC destinstion ignores next instruction"));
2637 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2641 case NOP_CHECK_CPU19
:
2642 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2643 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2645 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2650 as_bad (_("internal error: unknown nop check state"));
2653 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2655 while (check_for_nop
);
2659 frag
= frag_more (2);
2660 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2661 dwarf2_emit_insn (2);
2670 case 0: /* Emulated. */
2671 switch (opcode
->insn_opnumb
)
2674 if (is_opcode ("eint"))
2676 if (! prev_insn_is_nop
)
2678 if (gen_interrupt_nops
)
2680 frag
= frag_more (2);
2681 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2682 dwarf2_emit_insn (2);
2684 if (warn_interrupt_nops
)
2685 as_warn (_("inserting a NOP before EINT"));
2687 else if (warn_interrupt_nops
)
2688 as_warn (_("a NOP might be needed before the EINT"));
2691 else if (is_opcode ("dint"))
2692 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2694 /* Set/clear bits instructions. */
2698 extended
|= BYTE_OPERATION
;
2700 /* Emit the extension word. */
2702 frag
= frag_more (2);
2703 bfd_putl16 (extended
, frag
);
2707 frag
= frag_more (2);
2708 bfd_putl16 ((bfd_vma
) bin
, frag
);
2709 dwarf2_emit_insn (insn_length
);
2713 /* Something which works with destination operand. */
2714 line
= extract_operand (line
, l1
, sizeof (l1
));
2715 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2719 bin
|= (op1
.reg
| (op1
.am
<< 7));
2721 /* If the PC is the destination... */
2722 if (op1
.am
== 0 && op1
.reg
== 0
2723 /* ... and the opcode alters the SR. */
2724 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2725 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2727 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2728 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
2729 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2730 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
2733 /* If the status register is the destination... */
2734 if (op1
.am
== 0 && op1
.reg
== 2
2735 /* ... and the opcode alters the SR. */
2736 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2737 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2738 || is_opcode ("sbc") || is_opcode ("sxt")
2739 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2740 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2741 || is_opcode ("sbcx")
2744 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2745 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2746 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2747 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2750 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2751 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2753 /* Compute the entire instruction length, in bytes. */
2754 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2755 insn_length
+= op_length
;
2756 frag
= frag_more (op_length
);
2757 where
= frag
- frag_now
->fr_literal
;
2762 extended
|= BYTE_OPERATION
;
2764 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2766 as_bad (_("repeat instruction used with non-register mode instruction"));
2770 if (op1
.mode
== OP_EXP
)
2772 if (op1
.exp
.X_op
== O_constant
)
2773 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2775 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2776 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2777 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2779 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2780 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2783 /* Emit the extension word. */
2784 bfd_putl16 (extended
, frag
);
2789 bfd_putl16 ((bfd_vma
) bin
, frag
);
2793 if (op1
.mode
== OP_EXP
)
2795 if (op1
.exp
.X_op
== O_constant
)
2797 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2801 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2806 fix_new_exp (frag_now
, where
, 2,
2807 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2809 fix_new_exp (frag_now
, where
, 2,
2810 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2815 dwarf2_emit_insn (insn_length
);
2819 /* Shift instruction. */
2820 line
= extract_operand (line
, l1
, sizeof (l1
));
2821 strncpy (l2
, l1
, sizeof (l2
));
2822 l2
[sizeof (l2
) - 1] = '\0';
2823 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2824 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2827 break; /* An error occurred. All warnings were done before. */
2829 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2830 frag
= frag_more (insn_length
);
2831 where
= frag
- frag_now
->fr_literal
;
2833 if (target_is_430xv2 ()
2834 && op1
.mode
== OP_REG
2836 && (is_opcode ("rlax")
2837 || is_opcode ("rlcx")
2838 || is_opcode ("rla")
2839 || is_opcode ("rlc")))
2841 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2845 /* If the status register is the destination... */
2846 if (op1
.am
== 0 && op1
.reg
== 2
2847 /* ... and the opcode alters the SR. */
2848 && (is_opcode ("rla") || is_opcode ("rlc")
2849 || is_opcode ("rlax") || is_opcode ("rlcx")
2852 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2853 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2854 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2855 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2861 extended
|= BYTE_OPERATION
;
2863 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2865 as_bad (_("repeat instruction used with non-register mode instruction"));
2869 if (op1
.mode
== OP_EXP
)
2871 if (op1
.exp
.X_op
== O_constant
)
2872 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2874 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2875 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2876 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2878 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2879 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2882 if (op2
.mode
== OP_EXP
)
2884 if (op2
.exp
.X_op
== O_constant
)
2885 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2887 else if (op1
.mode
== OP_EXP
)
2888 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2889 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2890 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2892 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2893 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2894 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2897 /* Emit the extension word. */
2898 bfd_putl16 (extended
, frag
);
2903 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2904 bfd_putl16 ((bfd_vma
) bin
, frag
);
2908 if (op1
.mode
== OP_EXP
)
2910 if (op1
.exp
.X_op
== O_constant
)
2912 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2916 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2920 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2921 fix_new_exp (frag_now
, where
, 2,
2922 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2924 fix_new_exp (frag_now
, where
, 2,
2925 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2932 if (op2
.mode
== OP_EXP
)
2934 if (op2
.exp
.X_op
== O_constant
)
2936 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2940 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2944 if (op2
.reg
) /* Not PC relative. */
2945 fix_new_exp (frag_now
, where
, 2,
2946 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2948 fix_new_exp (frag_now
, where
, 2,
2949 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2954 dwarf2_emit_insn (insn_length
);
2958 /* Branch instruction => mov dst, r0. */
2961 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2965 line
= extract_operand (line
, l1
, sizeof (l1
));
2966 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2972 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2973 op_length
= 2 + 2 * op1
.ol
;
2974 frag
= frag_more (op_length
);
2975 where
= frag
- frag_now
->fr_literal
;
2976 bfd_putl16 ((bfd_vma
) bin
, frag
);
2978 if (op1
.mode
== OP_EXP
)
2980 if (op1
.exp
.X_op
== O_constant
)
2982 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2988 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2990 if (op1
.reg
|| op1
.am
== 3)
2991 fix_new_exp (frag_now
, where
, 2,
2992 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2994 fix_new_exp (frag_now
, where
, 2,
2995 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2999 dwarf2_emit_insn (insn_length
+ op_length
);
3003 /* CALLA instructions. */
3004 fix_emitted
= FALSE
;
3006 line
= extract_operand (line
, l1
, sizeof (l1
));
3009 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3010 extended_op
, FALSE
);
3016 op_length
= 2 + 2 * op1
.ol
;
3017 frag
= frag_more (op_length
);
3018 where
= frag
- frag_now
->fr_literal
;
3026 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3027 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3030 else if (op1
.am
== 1)
3036 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3037 BFD_RELOC_MSP430X_PCR20_CALL
);
3041 bin
|= 0x50 | op1
.reg
;
3043 else if (op1
.am
== 0)
3044 bin
|= 0x40 | op1
.reg
;
3046 else if (op1
.am
== 1)
3050 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3051 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3054 else if (op1
.am
== 2)
3055 bin
|= 0x60 | op1
.reg
;
3056 else if (op1
.am
== 3)
3057 bin
|= 0x70 | op1
.reg
;
3059 bfd_putl16 ((bfd_vma
) bin
, frag
);
3061 if (op1
.mode
== OP_EXP
)
3065 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3069 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3072 fix_new_exp (frag_now
, where
+ 2, 2,
3073 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3076 dwarf2_emit_insn (insn_length
+ op_length
);
3084 /* [POP|PUSH]M[.A] #N, Rd */
3085 line
= extract_operand (line
, l1
, sizeof (l1
));
3086 line
= extract_operand (line
, l2
, sizeof (l2
));
3090 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3093 parse_exp (l1
+ 1, &(op1
.exp
));
3094 if (op1
.exp
.X_op
!= O_constant
)
3096 as_bad (_("expected constant expression for first argument of %s"),
3101 if ((reg
= check_reg (l2
)) == -1)
3103 as_bad (_("expected register as second argument of %s"),
3109 frag
= frag_more (op_length
);
3110 where
= frag
- frag_now
->fr_literal
;
3111 bin
= opcode
->bin_opcode
;
3114 n
= op1
.exp
.X_add_number
;
3115 bin
|= (n
- 1) << 4;
3116 if (is_opcode ("pushm"))
3120 if (reg
- n
+ 1 < 0)
3122 as_bad (_("Too many registers popped"));
3126 /* CPU21 errata: cannot use POPM to restore the SR register. */
3127 if (target_is_430xv2 ()
3128 && (reg
- n
+ 1 < 3)
3130 && is_opcode ("popm"))
3132 as_bad (_("Cannot use POPM to restore the SR register"));
3136 bin
|= (reg
- n
+ 1);
3139 bfd_putl16 ((bfd_vma
) bin
, frag
);
3140 dwarf2_emit_insn (op_length
);
3149 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3150 if (extended
& 0xff)
3152 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3156 line
= extract_operand (line
, l1
, sizeof (l1
));
3157 line
= extract_operand (line
, l2
, sizeof (l2
));
3161 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3164 parse_exp (l1
+ 1, &(op1
.exp
));
3165 if (op1
.exp
.X_op
!= O_constant
)
3167 as_bad (_("expected constant expression for first argument of %s"),
3171 n
= op1
.exp
.X_add_number
;
3174 as_bad (_("expected first argument of %s to be in the range 1-4"),
3179 if ((reg
= check_reg (l2
)) == -1)
3181 as_bad (_("expected register as second argument of %s"),
3186 if (target_is_430xv2 () && reg
== 0)
3188 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3193 frag
= frag_more (op_length
);
3194 where
= frag
- frag_now
->fr_literal
;
3196 bin
= opcode
->bin_opcode
;
3199 bin
|= (n
- 1) << 10;
3202 bfd_putl16 ((bfd_vma
) bin
, frag
);
3203 dwarf2_emit_insn (op_length
);
3209 bfd_boolean need_reloc
= FALSE
;
3213 /* ADDA, CMPA and SUBA address instructions. */
3214 if (extended
& 0xff)
3216 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3220 line
= extract_operand (line
, l1
, sizeof (l1
));
3221 line
= extract_operand (line
, l2
, sizeof (l2
));
3223 bin
= opcode
->bin_opcode
;
3227 parse_exp (l1
+ 1, &(op1
.exp
));
3229 if (op1
.exp
.X_op
== O_constant
)
3231 n
= op1
.exp
.X_add_number
;
3232 if (n
> 0xfffff || n
< - (0x7ffff))
3234 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3239 bin
|= ((n
>> 16) & 0xf) << 8;
3251 if ((n
= check_reg (l1
)) == -1)
3253 as_bad (_("expected register name or constant as first argument of %s"),
3258 bin
|= (n
<< 8) | (1 << 6);
3262 if ((reg
= check_reg (l2
)) == -1)
3264 as_bad (_("expected register as second argument of %s"),
3269 frag
= frag_more (op_length
);
3270 where
= frag
- frag_now
->fr_literal
;
3273 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3274 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3276 bfd_putl16 ((bfd_vma
) bin
, frag
);
3278 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3279 dwarf2_emit_insn (op_length
);
3283 case 9: /* MOVA, BRA, RETA. */
3285 bin
= opcode
->bin_opcode
;
3287 if (is_opcode ("reta"))
3289 /* The RETA instruction does not take any arguments.
3290 The implicit first argument is @SP+.
3291 The implicit second argument is PC. */
3301 line
= extract_operand (line
, l1
, sizeof (l1
));
3302 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3303 &imm_op
, extended_op
, FALSE
);
3305 if (is_opcode ("bra"))
3307 /* This is the BRA synthetic instruction.
3308 The second argument is always PC. */
3314 line
= extract_operand (line
, l2
, sizeof (l2
));
3315 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3320 break; /* Error occurred. All warnings were done before. */
3323 /* Only a restricted subset of the normal MSP430 addressing modes
3324 are supported here, so check for the ones that are allowed. */
3325 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3326 & error_message
)) == 0)
3328 as_bad (error_message
, opcode
->name
);
3331 dwarf2_emit_insn (op_length
);
3335 line
= extract_operand (line
, l1
, sizeof l1
);
3336 /* The RPT instruction only accepted immediates and registers. */
3339 parse_exp (l1
+ 1, &(op1
.exp
));
3340 if (op1
.exp
.X_op
!= O_constant
)
3342 as_bad (_("expected constant value as argument to RPT"));
3345 if (op1
.exp
.X_add_number
< 1
3346 || op1
.exp
.X_add_number
> (1 << 4))
3348 as_bad (_("expected constant in the range 2..16"));
3352 /* We silently accept and ignore a repeat count of 1. */
3353 if (op1
.exp
.X_add_number
> 1)
3354 repeat_count
= op1
.exp
.X_add_number
;
3360 if ((reg
= check_reg (l1
)) != -1)
3363 as_warn (_("PC used as an argument to RPT"));
3365 repeat_count
= - reg
;
3369 as_bad (_("expected constant or register name as argument to RPT insn"));
3376 as_bad (_("Illegal emulated instruction "));
3381 case 1: /* Format 1, double operand. */
3382 line
= extract_operand (line
, l1
, sizeof (l1
));
3383 line
= extract_operand (line
, l2
, sizeof (l2
));
3384 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3385 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3388 break; /* Error occurred. All warnings were done before. */
3391 && is_opcode ("movx")
3393 && msp430_enable_relax
)
3395 /* This is the MOVX.A instruction. See if we can convert
3396 it into the MOVA instruction instead. This saves 2 bytes. */
3397 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3400 dwarf2_emit_insn (op_length
);
3405 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3407 /* If the PC is the destination... */
3408 if (op2
.am
== 0 && op2
.reg
== 0
3409 /* ... and the opcode alters the SR. */
3410 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3411 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3413 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3414 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
3415 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3416 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
3419 /* If the status register is the destination... */
3420 if (op2
.am
== 0 && op2
.reg
== 2
3421 /* ... and the opcode alters the SR. */
3422 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3423 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3424 || is_opcode ("xor")
3425 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3426 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3427 || is_opcode ("xorx")
3430 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3431 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3432 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3433 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3436 if ( (is_opcode ("bic") && bin
== 0xc232)
3437 || (is_opcode ("bis") && bin
== 0xd232)
3438 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3440 /* Avoid false checks when a constant value is being put into the SR. */
3441 if (op1
.mode
== OP_EXP
3442 && op1
.exp
.X_op
== O_constant
3443 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3446 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3449 if (((is_opcode ("bis") && bin
== 0xd032)
3450 || (is_opcode ("mov") && bin
== 0x4032)
3451 || (is_opcode ("xor") && bin
== 0xe032))
3452 && op1
.mode
== OP_EXP
3453 && op1
.exp
.X_op
== O_constant
3454 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3455 check_for_nop
|= NOP_CHECK_CPU19
;
3457 /* Compute the entire length of the instruction in bytes. */
3458 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3459 + 2 /* The opcode */
3460 + (2 * op1
.ol
) /* The first operand. */
3461 + (2 * op2
.ol
); /* The second operand. */
3463 insn_length
+= op_length
;
3464 frag
= frag_more (op_length
);
3465 where
= frag
- frag_now
->fr_literal
;
3470 extended
|= BYTE_OPERATION
;
3472 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3474 as_bad (_("repeat instruction used with non-register mode instruction"));
3478 /* If necessary, emit a reloc to update the extension word. */
3479 if (op1
.mode
== OP_EXP
)
3481 if (op1
.exp
.X_op
== O_constant
)
3482 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3484 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3485 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3486 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3488 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3489 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3492 if (op2
.mode
== OP_EXP
)
3494 if (op2
.exp
.X_op
== O_constant
)
3495 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3497 else if (op1
.mode
== OP_EXP
)
3498 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3499 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3500 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3503 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3504 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3505 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3508 /* Emit the extension word. */
3509 bfd_putl16 (extended
, frag
);
3514 bfd_putl16 ((bfd_vma
) bin
, frag
);
3518 if (op1
.mode
== OP_EXP
)
3520 if (op1
.exp
.X_op
== O_constant
)
3522 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3526 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3530 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3531 fix_new_exp (frag_now
, where
, 2,
3532 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3534 fix_new_exp (frag_now
, where
, 2,
3535 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3543 if (op2
.mode
== OP_EXP
)
3545 if (op2
.exp
.X_op
== O_constant
)
3547 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3551 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3555 if (op2
.reg
) /* Not PC relative. */
3556 fix_new_exp (frag_now
, where
, 2,
3557 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3559 fix_new_exp (frag_now
, where
, 2,
3560 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3565 dwarf2_emit_insn (insn_length
);
3567 /* If the PC is the destination... */
3568 if (op2
.am
== 0 && op2
.reg
== 0
3569 /* ... but the opcode does not alter the destination. */
3570 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3571 check_for_nop
|= NOP_CHECK_CPU12
;
3574 case 2: /* Single-operand mostly instr. */
3575 if (opcode
->insn_opnumb
== 0)
3577 /* reti instruction. */
3579 frag
= frag_more (2);
3580 bfd_putl16 ((bfd_vma
) bin
, frag
);
3581 dwarf2_emit_insn (insn_length
);
3585 line
= extract_operand (line
, l1
, sizeof (l1
));
3586 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3587 &imm_op
, extended_op
, TRUE
);
3589 break; /* Error in operand. */
3591 if (target_is_430xv2 ()
3592 && op1
.mode
== OP_REG
3594 && (is_opcode ("rrax")
3595 || is_opcode ("rrcx")
3596 || is_opcode ("rra")
3597 || is_opcode ("rrc")))
3599 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3603 /* If the status register is the destination... */
3604 if (op1
.am
== 0 && op1
.reg
== 2
3605 /* ... and the opcode alters the SR. */
3606 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3608 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3609 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3610 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3611 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3614 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3615 frag
= frag_more (insn_length
);
3616 where
= frag
- frag_now
->fr_literal
;
3620 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3622 /* These two instructions use a special
3623 encoding of the A/L and B/W bits. */
3624 bin
&= ~ BYTE_OPERATION
;
3628 as_bad (_("%s instruction does not accept a .b suffix"),
3633 extended
|= BYTE_OPERATION
;
3636 extended
|= BYTE_OPERATION
;
3638 if (is_opcode ("rrux"))
3639 extended
|= IGNORE_CARRY_BIT
;
3641 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3643 as_bad (_("repeat instruction used with non-register mode instruction"));
3647 if (op1
.mode
== OP_EXP
)
3649 if (op1
.exp
.X_op
== O_constant
)
3650 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3652 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3653 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3654 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3656 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3657 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3660 /* Emit the extension word. */
3661 bfd_putl16 (extended
, frag
);
3666 bin
|= op1
.reg
| (op1
.am
<< 4);
3667 bfd_putl16 ((bfd_vma
) bin
, frag
);
3671 if (op1
.mode
== OP_EXP
)
3673 if (op1
.exp
.X_op
== O_constant
)
3675 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3679 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3683 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3684 fix_new_exp (frag_now
, where
, 2,
3685 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3687 fix_new_exp (frag_now
, where
, 2,
3688 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3693 dwarf2_emit_insn (insn_length
);
3696 case 3: /* Conditional jumps instructions. */
3697 line
= extract_operand (line
, l1
, sizeof (l1
));
3698 /* l1 is a label. */
3707 parse_exp (m
, &exp
);
3709 /* In order to handle something like:
3713 jz 4 ; skip next 4 bytes
3716 nop ; will jump here if r5 positive or zero
3718 jCOND -n ;assumes jump n bytes backward:
3728 jCOND $n ; jump from PC in either direction. */
3730 if (exp
.X_op
== O_constant
)
3732 int x
= exp
.X_add_number
;
3736 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3740 if ((*l1
== '$' && x
> 0) || x
< 0)
3745 if (x
> 512 || x
< -511)
3747 as_bad (_("Wrong displacement %d"), x
<< 1);
3752 frag
= frag_more (2); /* Instr size is 1 word. */
3755 bfd_putl16 ((bfd_vma
) bin
, frag
);
3757 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3760 frag
= frag_more (2); /* Instr size is 1 word. */
3761 where
= frag
- frag_now
->fr_literal
;
3762 fix_new_exp (frag_now
, where
, 2,
3763 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3765 bfd_putl16 ((bfd_vma
) bin
, frag
);
3767 else if (*l1
== '$')
3769 as_bad (_("instruction requires label sans '$'"));
3773 ("instruction requires label or value in range -511:512"));
3774 dwarf2_emit_insn (insn_length
);
3779 as_bad (_("instruction requires label"));
3784 case 4: /* Extended jumps. */
3785 if (!msp430_enable_polys
)
3787 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3791 line
= extract_operand (line
, l1
, sizeof (l1
));
3797 /* Ignore absolute addressing. make it PC relative anyway. */
3798 if (*m
== '#' || *m
== '$')
3801 parse_exp (m
, & exp
);
3802 if (exp
.X_op
== O_symbol
)
3804 /* Relaxation required. */
3805 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3807 if (target_is_430x ())
3808 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3810 /* The parameter to dwarf2_emit_insn is actually the offset to
3811 the start of the insn from the fix piece of instruction that
3812 was emitted. Since next fragments may have variable size we
3813 tie debug info to the beginning of the instruction. */
3815 frag
= frag_more (8);
3816 dwarf2_emit_insn (0);
3817 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3818 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3820 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3822 0, /* Offset is zero if jump dist less than 1K. */
3828 as_bad (_("instruction requires label"));
3831 case 5: /* Emulated extended branches. */
3832 if (!msp430_enable_polys
)
3834 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3837 line
= extract_operand (line
, l1
, sizeof (l1
));
3843 /* Ignore absolute addressing. make it PC relative anyway. */
3844 if (*m
== '#' || *m
== '$')
3847 parse_exp (m
, & exp
);
3848 if (exp
.X_op
== O_symbol
)
3850 /* Relaxation required. */
3851 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3853 if (target_is_430x ())
3854 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3857 frag
= frag_more (8);
3858 dwarf2_emit_insn (0);
3859 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3860 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3862 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3863 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3865 0, /* Offset is zero if jump dist less than 1K. */
3871 as_bad (_("instruction requires label"));
3875 as_bad (_("Illegal instruction or not implemented opcode."));
3878 if (is_opcode ("nop"))
3879 prev_insn_is_nop
= TRUE
;
3881 prev_insn_is_nop
= FALSE
;
3883 input_line_pointer
= line
;
3888 md_assemble (char * str
)
3890 struct msp430_opcode_s
* opcode
;
3894 str
= skip_space (str
); /* Skip leading spaces. */
3895 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3899 char a
= TOLOWER (cmd
[i
]);
3906 as_bad (_("can't find opcode "));
3910 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3914 as_bad (_("unknown opcode `%s'"), cmd
);
3919 char *__t
= input_line_pointer
;
3921 msp430_operands (opcode
, str
);
3922 input_line_pointer
= __t
;
3926 /* GAS will call this function for each section at the end of the assembly,
3927 to permit the CPU backend to adjust the alignment of a section. */
3930 md_section_align (asection
* seg
, valueT addr
)
3932 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3934 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
3937 /* If you define this macro, it should return the offset between the
3938 address of a PC relative fixup and the position from which the PC
3939 relative adjustment should be made. On many processors, the base
3940 of a PC relative instruction is the next instruction, so this
3941 macro would return the length of an instruction. */
3944 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3946 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3947 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3948 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3951 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3954 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3955 Now it handles the situation when relocations
3956 have to be passed to linker. */
3958 msp430_force_relocation_local (fixS
*fixp
)
3960 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3964 if (msp430_enable_polys
3965 && !msp430_enable_relax
)
3968 return (!fixp
->fx_pcrel
3969 || generic_force_reloc (fixp
));
3973 /* GAS will call this for each fixup. It should store the correct
3974 value in the object file. */
3976 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3978 unsigned char * where
;
3982 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3987 else if (fixp
->fx_pcrel
)
3989 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3991 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3993 /* FIXME: We can appear here only in case if we perform a pc
3994 relative jump to the label which is i) global, ii) locally
3995 defined or this is a jump to an absolute symbol.
3996 If this is an absolute symbol -- everything is OK.
3997 If this is a global label, we've got a symbol value defined
3999 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4000 from this section start
4001 2. *valuep will contain the real offset from jump insn to the
4003 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4004 will be incorrect. Therefore remove s_get_value. */
4005 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4013 value
= fixp
->fx_offset
;
4015 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4017 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4019 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4025 fixp
->fx_no_overflow
= 1;
4027 /* If polymorphs are enabled and relax disabled.
4028 do not kill any relocs and pass them to linker. */
4029 if (msp430_enable_polys
4030 && !msp430_enable_relax
)
4033 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4034 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4041 /* Fetch the instruction, insert the fully resolved operand
4042 value, and stuff the instruction back again. */
4043 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4045 insn
= bfd_getl16 (where
);
4047 switch (fixp
->fx_r_type
)
4049 case BFD_RELOC_MSP430_10_PCREL
:
4051 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4052 _("odd address operand: %ld"), value
);
4054 /* Jumps are in words. */
4056 --value
; /* Correct PC. */
4058 if (value
< -512 || value
> 511)
4059 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4060 _("operand out of range: %ld"), value
);
4062 value
&= 0x3ff; /* get rid of extended sign */
4063 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4066 case BFD_RELOC_MSP430X_PCR16
:
4067 case BFD_RELOC_MSP430_RL_PCREL
:
4068 case BFD_RELOC_MSP430_16_PCREL
:
4070 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4071 _("odd address operand: %ld"), value
);
4074 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4075 /* Nothing to be corrected here. */
4076 if (value
< -32768 || value
> 65536)
4077 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4078 _("operand out of range: %ld"), value
);
4081 case BFD_RELOC_MSP430X_ABS16
:
4082 case BFD_RELOC_MSP430_16
:
4084 case BFD_RELOC_MSP430_16_BYTE
:
4085 value
&= 0xffff; /* Get rid of extended sign. */
4086 bfd_putl16 ((bfd_vma
) value
, where
);
4089 case BFD_RELOC_MSP430_ABS_HI16
:
4091 value
&= 0xffff; /* Get rid of extended sign. */
4092 bfd_putl16 ((bfd_vma
) value
, where
);
4096 bfd_putl16 ((bfd_vma
) value
, where
);
4099 case BFD_RELOC_MSP430_ABS8
:
4101 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4104 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4105 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4106 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4108 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4111 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4112 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4114 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4117 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4118 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4120 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4123 case BFD_RELOC_MSP430X_PCR20_CALL
:
4124 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4126 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4129 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4130 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4131 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4133 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4136 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4137 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4139 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4142 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4143 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4145 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4149 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4150 fixp
->fx_line
, fixp
->fx_r_type
);
4156 fixp
->fx_addnumber
= value
;
4161 S_IS_GAS_LOCAL (symbolS
* s
)
4168 name
= S_GET_NAME (s
);
4169 len
= strlen (name
) - 1;
4171 return name
[len
] == 1 || name
[len
] == 2;
4174 /* GAS will call this to generate a reloc, passing the resulting reloc
4175 to `bfd_install_relocation'. This currently works poorly, as
4176 `bfd_install_relocation' often does the wrong thing, and instances of
4177 `tc_gen_reloc' have been written to work around the problems, which
4178 in turns makes it difficult to fix `bfd_install_relocation'. */
4180 /* If while processing a fixup, a reloc really needs to be created
4181 then it is done here. */
4184 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4186 static arelent
* no_relocs
= NULL
;
4187 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4190 reloc
= XNEW (arelent
);
4191 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4192 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4194 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4196 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4197 _("reloc %d not supported by object file format"),
4198 (int) fixp
->fx_r_type
);
4207 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4209 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4210 fixp
->fx_subsy
= NULL
;
4213 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4215 asection
*asec
, *ssec
;
4217 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4218 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4220 /* If we have a difference between two different, non-absolute symbols
4221 we must generate two relocs (one for each symbol) and allow the
4222 linker to resolve them - relaxation may change the distances between
4223 symbols, even local symbols defined in the same section.
4225 Unfortunately we cannot do this with assembler generated local labels
4226 because there can be multiple incarnations of the same label, with
4227 exactly the same name, in any given section and the linker will have
4228 no way to identify the correct one. Instead we just have to hope
4229 that no relaxtion will occur between the local label and the other
4230 symbol in the expression.
4232 Similarly we have to compute differences between symbols in the .eh_frame
4233 section as the linker is not smart enough to apply relocations there
4234 before attempting to process it. */
4235 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4236 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4237 && strcmp (ssec
->name
, ".eh_frame") != 0
4238 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4239 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4241 arelent
* reloc2
= XNEW (arelent
);
4246 reloc2
->address
= reloc
->address
;
4247 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4248 BFD_RELOC_MSP430_SYM_DIFF
);
4249 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4251 if (ssec
== absolute_section
)
4252 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4255 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4256 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4259 reloc
->addend
= fixp
->fx_offset
;
4260 if (asec
== absolute_section
)
4262 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4263 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4267 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4268 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4277 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4279 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4280 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4282 switch (fixp
->fx_r_type
)
4285 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4289 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4293 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4297 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4302 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4313 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4314 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4316 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4317 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4319 md_number_to_chars (fixpos
, amount
, 2);
4324 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4325 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4326 reloc
->addend
= fixp
->fx_offset
;
4328 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4329 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4330 reloc
->address
= fixp
->fx_offset
;
4337 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4338 asection
* segment_type ATTRIBUTE_UNUSED
)
4340 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4342 /* This is a jump -> pcrel mode. Nothing to do much here.
4343 Return value == 2. */
4345 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4347 else if (fragP
->fr_symbol
)
4349 /* Its got a segment, but its not ours. Even if fr_symbol is in
4350 an absolute segment, we don't know a displacement until we link
4351 object files. So it will always be long. This also applies to
4352 labels in a subsegment of current. Liker may relax it to short
4353 jump later. Return value == 8. */
4355 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4359 /* We know the abs value. may be it is a jump to fixed address.
4360 Impossible in our case, cause all constants already handled. */
4362 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4365 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4369 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4370 asection
* sec ATTRIBUTE_UNUSED
,
4376 struct rcodes_s
* cc
= NULL
;
4377 struct hcodes_s
* hc
= NULL
;
4379 switch (fragP
->fr_subtype
)
4381 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4382 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4383 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4384 /* We do not have to convert anything here.
4385 Just apply a fix. */
4386 rela
= BFD_RELOC_MSP430_10_PCREL
;
4389 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4390 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4391 /* Convert uncond branch jmp lab -> br lab. */
4392 if (target_is_430x ())
4393 cc
= msp430x_rcodes
+ 7;
4395 cc
= msp430_rcodes
+ 7;
4396 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4397 bfd_putl16 (cc
->lop0
, where
);
4398 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4402 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4403 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4405 /* Other simple branches. */
4406 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4409 /* Find actual instruction. */
4410 if (target_is_430x ())
4412 for (i
= 0; i
< 7 && !cc
; i
++)
4413 if (msp430x_rcodes
[i
].sop
== insn
)
4414 cc
= msp430x_rcodes
+ i
;
4418 for (i
= 0; i
< 7 && !cc
; i
++)
4419 if (msp430_rcodes
[i
].sop
== insn
)
4420 cc
= & msp430_rcodes
[i
];
4423 if (!cc
|| !cc
->name
)
4424 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4425 __FUNCTION__
, (long) insn
);
4426 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4427 bfd_putl16 (cc
->lop0
, where
);
4428 bfd_putl16 (cc
->lop1
, where
+ 2);
4429 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4434 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4435 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4436 if (target_is_430x ())
4437 cc
= msp430x_rcodes
+ 6;
4439 cc
= msp430_rcodes
+ 6;
4440 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4441 bfd_putl16 (cc
->lop0
, where
);
4442 bfd_putl16 (cc
->lop1
, where
+ 2);
4443 bfd_putl16 (cc
->lop2
, where
+ 4);
4444 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4448 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4450 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4453 if (target_is_430x ())
4455 for (i
= 0; i
< 4 && !hc
; i
++)
4456 if (msp430x_hcodes
[i
].op1
== insn
)
4457 hc
= msp430x_hcodes
+ i
;
4461 for (i
= 0; i
< 4 && !hc
; i
++)
4462 if (msp430_hcodes
[i
].op1
== insn
)
4463 hc
= &msp430_hcodes
[i
];
4465 if (!hc
|| !hc
->name
)
4466 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4467 __FUNCTION__
, (long) insn
);
4468 rela
= BFD_RELOC_MSP430_10_PCREL
;
4469 /* Apply a fix for a first label if necessary.
4470 another fix will be applied to the next word of insn anyway. */
4472 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4473 fragP
->fr_offset
, TRUE
, rela
);
4479 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4480 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4482 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4485 if (target_is_430x ())
4487 for (i
= 0; i
< 4 && !hc
; i
++)
4488 if (msp430x_hcodes
[i
].op1
== insn
)
4489 hc
= msp430x_hcodes
+ i
;
4493 for (i
= 0; i
< 4 && !hc
; i
++)
4494 if (msp430_hcodes
[i
].op1
== insn
)
4495 hc
= & msp430_hcodes
[i
];
4497 if (!hc
|| !hc
->name
)
4498 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4499 __FUNCTION__
, (long) insn
);
4500 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4501 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4502 bfd_putl16 (hc
->lop0
, where
);
4503 bfd_putl16 (hc
->lop1
, where
+ 2);
4504 bfd_putl16 (hc
->lop2
, where
+ 4);
4510 as_fatal (_("internal inconsistency problem in %s: %lx"),
4511 __FUNCTION__
, (long) fragP
->fr_subtype
);
4515 /* Now apply fix. */
4516 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4517 fragP
->fr_offset
, TRUE
, rela
);
4518 /* Just fixed 2 bytes. */
4522 /* Relax fragment. Mostly stolen from hc11 and mcore
4523 which arches I think I know. */
4526 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4527 long stretch ATTRIBUTE_UNUSED
)
4532 const relax_typeS
*this_type
;
4533 const relax_typeS
*start_type
;
4534 relax_substateT next_state
;
4535 relax_substateT this_state
;
4536 const relax_typeS
*table
= md_relax_table
;
4538 /* Nothing to be done if the frag has already max size. */
4539 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4540 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4543 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4545 symbolP
= fragP
->fr_symbol
;
4546 if (symbol_resolved_p (symbolP
))
4547 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4549 /* We know the offset. calculate a distance. */
4550 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4553 if (!msp430_enable_relax
)
4555 /* Relaxation is not enabled. So, make all jump as long ones
4556 by setting 'aim' to quite high value. */
4560 this_state
= fragP
->fr_subtype
;
4561 start_type
= this_type
= table
+ this_state
;
4565 /* Look backwards. */
4566 for (next_state
= this_type
->rlx_more
; next_state
;)
4567 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4571 /* Grow to next state. */
4572 this_state
= next_state
;
4573 this_type
= table
+ this_state
;
4574 next_state
= this_type
->rlx_more
;
4579 /* Look forwards. */
4580 for (next_state
= this_type
->rlx_more
; next_state
;)
4581 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4585 /* Grow to next state. */
4586 this_state
= next_state
;
4587 this_type
= table
+ this_state
;
4588 next_state
= this_type
->rlx_more
;
4592 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4594 fragP
->fr_subtype
= this_state
;
4598 /* Return FALSE if the fixup in fixp should be left alone and not
4599 adjusted. We return FALSE here so that linker relaxation will
4603 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4605 /* If the symbol is in a non-code section then it should be OK. */
4607 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4613 /* Set the contents of the .MSP430.attributes section. */
4616 msp430_md_end (void)
4619 as_warn ("assembly finished without a possibly needed NOP instruction");
4621 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4622 target_is_430x () ? 2 : 1);
4624 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4625 large_model
? 2 : 1);
4627 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4628 large_model
? 2 : 1);
4631 /* Returns FALSE if there is a msp430 specific reason why the
4632 subtraction of two same-section symbols cannot be computed by
4636 msp430_allow_local_subtract (expressionS
* left
,
4637 expressionS
* right
,
4640 /* If the symbols are not in a code section then they are OK. */
4641 if ((section
->flags
& SEC_CODE
) == 0)
4644 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4647 if (left
->X_add_symbol
== right
->X_add_symbol
)
4650 /* We have to assume that there may be instructions between the
4651 two symbols and that relaxation may increase the distance between