1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2017 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
106 int index
; /* Corresponding insn_opnumb. */
107 int sop
; /* Opcode if jump length is short. */
108 long lpos
; /* Label position. */
109 long lop0
; /* Opcode 1 _word_ (16 bits). */
110 long lop1
; /* Opcode second word. */
111 long lop2
; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes
[] =
119 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
131 #define MSP430_RLC(n,i,sop,o1) \
132 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
134 static struct rcodes_s msp430x_rcodes
[] =
136 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
137 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
138 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
139 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
140 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
141 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
142 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
143 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
148 /* More difficult than above and they have format 5.
151 =================================================================
152 gt > jeq +2; jge label jeq +6; jl +4; br label
153 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
154 leu <= jeq label; jlo label jeq +2; jhs +4; br label
155 le <= jeq label; jl label jeq +2; jge +4; br label
156 ================================================================= */
161 int index
; /* Corresponding insn_opnumb. */
162 int tlab
; /* Number of labels in short mode. */
163 int op0
; /* Opcode for first word of short jump. */
164 int op1
; /* Opcode for second word of short jump. */
165 int lop0
; /* Opcodes for long jump mode. */
170 static struct hcodes_s msp430_hcodes
[] =
172 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
173 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
174 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
175 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 static struct hcodes_s msp430x_hcodes
[] =
181 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
182 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
183 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
184 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 const char comment_chars
[] = ";";
189 const char line_comment_chars
[] = "#";
190 const char line_separator_chars
[] = "{";
191 const char EXP_CHARS
[] = "eE";
192 const char FLT_CHARS
[] = "dD";
194 /* Handle long expressions. */
195 extern LITTLENUM_TYPE generic_bignum
[];
197 static struct hash_control
*msp430_hash
;
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
212 #define STATE_BITS10 1 /* wild guess. short jump */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
214 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table
[] =
229 /* Unconditional jump. */
231 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
232 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
233 {1, 1, CUBL
, 0}, /* state undef */
235 /* Simple branches. */
237 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
238 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
241 /* blt no overflow branch. */
243 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
244 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
247 /* Emulated branches. */
249 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
250 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
266 static inline bfd_boolean
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
272 static inline bfd_boolean
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation.
279 For the 430X we generate a relocation without linker range checking
280 if the value is being used in an extended (ie 20-bit) instruction,
281 otherwise if have a shifted expression we use a HI reloc.
282 For the 430 we generate a relocation without assembler range checking
283 if we are handling an immediate value or a byte-width instruction. */
285 #undef CHECK_RELOC_MSP430
286 #define CHECK_RELOC_MSP430(OP) \
290 : ((OP).vshift == 1) \
291 ? BFD_RELOC_MSP430_ABS_HI16 \
292 : BFD_RELOC_MSP430X_ABS16) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
303 ? BFD_RELOC_MSP430X_PCR16 \
304 : (imm_op || byte_op) \
305 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
307 /* Profiling capability:
308 It is a performance hit to use gcc's profiling approach for this tiny target.
309 Even more -- jtag hardware facility does not perform any profiling functions.
310 However we've got gdb's built-in simulator where we can do anything.
311 Therefore my suggestion is:
313 We define new section ".profiler" which holds all profiling information.
314 We define new pseudo operation .profiler which will instruct assembler to
315 add new profile entry to the object file. Profile should take place at the
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
325 i - function is in Init section
326 f - function is in Fini section
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
335 j - long Jump/ sjlj unwind
336 a - an Arbitrary code fragment
337 t - exTra parameter saved (constant value like frame size)
338 '""' optional: "sil" == sil
340 function_to_profile - function's address
341 cycle_corrector - a value which should be added to the cycle
342 counter, zero if omitted
343 extra - some extra parameter, zero if omitted.
346 ------------------------------
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
357 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
358 ; (this is a prologue end)
359 ; note, that spare var filled with the frame size
362 .profiler cdE,fxx ; check stack
367 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
368 ret ; cause 'ret' insn takes 3 cycles
369 -------------------------------
371 This profiling approach does not produce any overhead and
373 So, even profiled code can be uploaded to the MCU. */
374 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
375 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
376 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
377 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
378 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
379 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
380 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
381 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
382 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
383 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
384 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
385 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
386 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
387 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
388 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
389 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
402 for (; x
; x
= x
>> 1)
409 /* Parse ordinary expression. */
412 parse_exp (char * s
, expressionS
* op
)
414 input_line_pointer
= s
;
416 if (op
->X_op
== O_absent
)
417 as_bad (_("missing operand"));
418 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 version 1.194 of the
710 devices.csv file released by TI in September 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 { "msp430fr2110",2,0 },
1137 { "msp430fr2111",2,0 },
1138 { "msp430fr2310",2,0 },
1139 { "msp430fr2311",2,0 },
1140 { "msp430fr2433",2,8 },
1141 { "msp430fr2532",2,8 },
1142 { "msp430fr2533",2,8 },
1143 { "msp430fr2632",2,8 },
1144 { "msp430fr2633",2,8 },
1145 { "msp430fr2xx_4xxgeneric",2,8 },
1146 { "msp430fr4131",2,0 },
1147 { "msp430fr4132",2,0 },
1148 { "msp430fr4133",2,0 },
1149 { "msp430fr5720",2,8 },
1150 { "msp430fr5721",2,8 },
1151 { "msp430fr5722",2,8 },
1152 { "msp430fr5723",2,8 },
1153 { "msp430fr5724",2,8 },
1154 { "msp430fr5725",2,8 },
1155 { "msp430fr5726",2,8 },
1156 { "msp430fr5727",2,8 },
1157 { "msp430fr5728",2,8 },
1158 { "msp430fr5729",2,8 },
1159 { "msp430fr5730",2,8 },
1160 { "msp430fr5731",2,8 },
1161 { "msp430fr5732",2,8 },
1162 { "msp430fr5733",2,8 },
1163 { "msp430fr5734",2,8 },
1164 { "msp430fr5735",2,8 },
1165 { "msp430fr5736",2,8 },
1166 { "msp430fr5737",2,8 },
1167 { "msp430fr5738",2,8 },
1168 { "msp430fr5739",2,8 },
1169 { "msp430fr57xxgeneric",2,8 },
1170 { "msp430fr5847",2,8 },
1171 { "msp430fr58471",2,8 },
1172 { "msp430fr5848",2,8 },
1173 { "msp430fr5849",2,8 },
1174 { "msp430fr5857",2,8 },
1175 { "msp430fr5858",2,8 },
1176 { "msp430fr5859",2,8 },
1177 { "msp430fr5867",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 { "msp430fr5922",2,8 },
1189 { "msp430fr59221",2,8 },
1190 { "msp430fr5947",2,8 },
1191 { "msp430fr59471",2,8 },
1192 { "msp430fr5948",2,8 },
1193 { "msp430fr5949",2,8 },
1194 { "msp430fr5957",2,8 },
1195 { "msp430fr5958",2,8 },
1196 { "msp430fr5959",2,8 },
1197 { "msp430fr5962",2,8 },
1198 { "msp430fr5964",2,8 },
1199 { "msp430fr5967",2,8 },
1200 { "msp430fr5968",2,8 },
1201 { "msp430fr5969",2,8 },
1202 { "msp430fr59691",2,8 },
1203 { "msp430fr5970",2,8 },
1204 { "msp430fr5972",2,8 },
1205 { "msp430fr59721",2,8 },
1206 { "msp430fr5986",2,8 },
1207 { "msp430fr5987",2,8 },
1208 { "msp430fr5988",2,8 },
1209 { "msp430fr5989",2,8 },
1210 { "msp430fr59891",2,8 },
1211 { "msp430fr5992",2,8 },
1212 { "msp430fr5994",2,8 },
1213 { "msp430fr59941",2,8 },
1214 { "msp430fr5xx_6xxgeneric",2,8 },
1215 { "msp430fr6820",2,8 },
1216 { "msp430fr6822",2,8 },
1217 { "msp430fr68221",2,8 },
1218 { "msp430fr6870",2,8 },
1219 { "msp430fr6872",2,8 },
1220 { "msp430fr68721",2,8 },
1221 { "msp430fr6877",2,8 },
1222 { "msp430fr6879",2,8 },
1223 { "msp430fr68791",2,8 },
1224 { "msp430fr6887",2,8 },
1225 { "msp430fr6888",2,8 },
1226 { "msp430fr6889",2,8 },
1227 { "msp430fr68891",2,8 },
1228 { "msp430fr6920",2,8 },
1229 { "msp430fr6922",2,8 },
1230 { "msp430fr69221",2,8 },
1231 { "msp430fr6927",2,8 },
1232 { "msp430fr69271",2,8 },
1233 { "msp430fr6928",2,8 },
1234 { "msp430fr6970",2,8 },
1235 { "msp430fr6972",2,8 },
1236 { "msp430fr69721",2,8 },
1237 { "msp430fr6977",2,8 },
1238 { "msp430fr6979",2,8 },
1239 { "msp430fr69791",2,8 },
1240 { "msp430fr6987",2,8 },
1241 { "msp430fr6988",2,8 },
1242 { "msp430fr6989",2,8 },
1243 { "msp430fr69891",2,8 },
1244 { "msp430fw423",0,0 },
1245 { "msp430fw425",0,0 },
1246 { "msp430fw427",0,0 },
1247 { "msp430fw428",0,0 },
1248 { "msp430fw429",0,0 },
1249 { "msp430g2001",0,0 },
1250 { "msp430g2101",0,0 },
1251 { "msp430g2102",0,0 },
1252 { "msp430g2111",0,0 },
1253 { "msp430g2112",0,0 },
1254 { "msp430g2113",0,0 },
1255 { "msp430g2121",0,0 },
1256 { "msp430g2131",0,0 },
1257 { "msp430g2132",0,0 },
1258 { "msp430g2152",0,0 },
1259 { "msp430g2153",0,0 },
1260 { "msp430g2201",0,0 },
1261 { "msp430g2202",0,0 },
1262 { "msp430g2203",0,0 },
1263 { "msp430g2210",0,0 },
1264 { "msp430g2211",0,0 },
1265 { "msp430g2212",0,0 },
1266 { "msp430g2213",0,0 },
1267 { "msp430g2221",0,0 },
1268 { "msp430g2230",0,0 },
1269 { "msp430g2231",0,0 },
1270 { "msp430g2232",0,0 },
1271 { "msp430g2233",0,0 },
1272 { "msp430g2252",0,0 },
1273 { "msp430g2253",0,0 },
1274 { "msp430g2302",0,0 },
1275 { "msp430g2303",0,0 },
1276 { "msp430g2312",0,0 },
1277 { "msp430g2313",0,0 },
1278 { "msp430g2332",0,0 },
1279 { "msp430g2333",0,0 },
1280 { "msp430g2352",0,0 },
1281 { "msp430g2353",0,0 },
1282 { "msp430g2402",0,0 },
1283 { "msp430g2403",0,0 },
1284 { "msp430g2412",0,0 },
1285 { "msp430g2413",0,0 },
1286 { "msp430g2432",0,0 },
1287 { "msp430g2433",0,0 },
1288 { "msp430g2444",0,0 },
1289 { "msp430g2452",0,0 },
1290 { "msp430g2453",0,0 },
1291 { "msp430g2513",0,0 },
1292 { "msp430g2533",0,0 },
1293 { "msp430g2544",0,0 },
1294 { "msp430g2553",0,0 },
1295 { "msp430g2744",0,0 },
1296 { "msp430g2755",0,0 },
1297 { "msp430g2855",0,0 },
1298 { "msp430g2955",0,0 },
1299 { "msp430i2020",0,2 },
1300 { "msp430i2021",0,2 },
1301 { "msp430i2030",0,2 },
1302 { "msp430i2031",0,2 },
1303 { "msp430i2040",0,2 },
1304 { "msp430i2041",0,2 },
1305 { "msp430i2xxgeneric",0,2 },
1306 { "msp430l092",0,0 },
1307 { "msp430p112",0,0 },
1308 { "msp430p313",0,0 },
1309 { "msp430p315",0,0 },
1310 { "msp430p315s",0,0 },
1311 { "msp430p325",0,0 },
1312 { "msp430p337",0,1 },
1313 { "msp430sl5438a",2,8 },
1314 { "msp430tch5e",0,0 },
1315 { "msp430xgeneric",2,8 },
1316 { "rf430f5144",2,8 },
1317 { "rf430f5155",2,8 },
1318 { "rf430f5175",2,8 },
1319 { "rf430frl152h",0,0 },
1320 { "rf430frl152h_rom",0,0 },
1321 { "rf430frl153h",0,0 },
1322 { "rf430frl153h_rom",0,0 },
1323 { "rf430frl154h",0,0 },
1324 { "rf430frl154h_rom",0,0 }
1328 md_parse_option (int c
, const char * arg
)
1332 case OPTION_SILICON_ERRATA
:
1333 case OPTION_SILICON_ERRATA_WARN
:
1339 unsigned int length
;
1340 unsigned int bitfield
;
1343 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1344 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1345 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1346 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1347 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1348 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1353 for (i
= ARRAY_SIZE (erratas
); i
--;)
1354 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1356 if (c
== OPTION_SILICON_ERRATA
)
1357 silicon_errata_fix
|= erratas
[i
].bitfield
;
1359 silicon_errata_warn
|= erratas
[i
].bitfield
;
1360 arg
+= erratas
[i
].length
;
1365 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1371 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1381 as_fatal (_("MCU option requires a name\n"));
1383 if (strcasecmp ("msp430", arg
) == 0)
1384 selected_isa
= MSP_ISA_430
;
1385 else if (strcasecmp ("msp430xv2", arg
) == 0)
1386 selected_isa
= MSP_ISA_430Xv2
;
1387 else if (strcasecmp ("msp430x", arg
) == 0)
1388 selected_isa
= MSP_ISA_430X
;
1393 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1394 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1396 switch (msp430_mcu_data
[i
].revision
)
1398 case 0: selected_isa
= MSP_ISA_430
; break;
1399 case 1: selected_isa
= MSP_ISA_430X
; break;
1400 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1405 /* It is not an error if we do not match the MCU name. */
1409 if (strcmp (arg
, "430") == 0
1410 || strcasecmp (arg
, "msp430") == 0)
1411 selected_isa
= MSP_ISA_430
;
1412 else if (strcasecmp (arg
, "430x") == 0
1413 || strcasecmp (arg
, "msp430x") == 0)
1414 selected_isa
= MSP_ISA_430X
;
1415 else if (strcasecmp (arg
, "430xv2") == 0
1416 || strcasecmp (arg
, "msp430xv2") == 0)
1417 selected_isa
= MSP_ISA_430Xv2
;
1419 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1423 msp430_enable_relax
= 1;
1426 case OPTION_POLYMORPHS
:
1427 msp430_enable_polys
= 1;
1434 case OPTION_NO_INTR_NOPS
:
1435 gen_interrupt_nops
= FALSE
;
1437 case OPTION_INTR_NOPS
:
1438 gen_interrupt_nops
= TRUE
;
1441 case OPTION_WARN_INTR_NOPS
:
1442 warn_interrupt_nops
= TRUE
;
1444 case OPTION_NO_WARN_INTR_NOPS
:
1445 warn_interrupt_nops
= FALSE
;
1448 case OPTION_MOVE_DATA
:
1456 /* The intention here is to have the mere presence of these sections
1457 cause the object to have a reference to a well-known symbol. This
1458 reference pulls in the bits of the runtime (crt0) that initialize
1459 these sections. Thus, for example, the startup code to call
1460 memset() to initialize .bss will only be linked in when there is a
1461 non-empty .bss section. Otherwise, the call would exist but have a
1462 zero length parameter, which is a waste of memory and cycles.
1464 The code which initializes these sections should have a global
1465 label for these symbols, and should be marked with KEEP() in the
1469 msp430_make_init_symbols (const char * name
)
1471 if (strncmp (name
, ".bss", 4) == 0
1472 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1473 (void) symbol_find_or_make ("__crt0_init_bss");
1475 if (strncmp (name
, ".data", 5) == 0
1476 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1477 (void) symbol_find_or_make ("__crt0_movedata");
1479 /* Note - data assigned to the .either.data section may end up being
1480 placed in the .upper.data section if the .lower.data section is
1481 full. Hence the need to define the crt0 symbol. */
1482 if (strncmp (name
, ".either.data", 12) == 0
1483 || strncmp (name
, ".upper.data", 11) == 0)
1484 (void) symbol_find_or_make ("__crt0_move_highdata");
1486 /* See note about .either.data above. */
1487 if (strncmp (name
, ".upper.bss", 10) == 0
1488 || strncmp (name
, ".either.bss", 11) == 0)
1489 (void) symbol_find_or_make ("__crt0_init_highbss");
1493 msp430_section (int arg
)
1495 char * saved_ilp
= input_line_pointer
;
1496 const char * name
= obj_elf_section_name ();
1498 msp430_make_init_symbols (name
);
1500 input_line_pointer
= saved_ilp
;
1501 obj_elf_section (arg
);
1505 msp430_frob_section (asection
*sec
)
1507 const char *name
= sec
->name
;
1512 msp430_make_init_symbols (name
);
1516 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1518 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1521 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1522 (void) symbol_find_or_make ("__crt0_init_bss");
1526 msp430_comm (int needs_align
)
1528 s_comm_internal (needs_align
, elf_common_parse
);
1529 (void) symbol_find_or_make ("__crt0_init_bss");
1533 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1535 char sym_name
[1024];
1536 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1538 (void) symbol_find_or_make (sym_name
);
1541 const pseudo_typeS md_pseudo_table
[] =
1543 {"arch", msp430_set_arch
, OPTION_MMCU
},
1544 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1545 {"profiler", msp430_profiler
, 0},
1546 {"section", msp430_section
, 0},
1547 {"section.s", msp430_section
, 0},
1548 {"sect", msp430_section
, 0},
1549 {"sect.s", msp430_section
, 0},
1550 {"pushsection", msp430_section
, 1},
1551 {"refsym", msp430_refsym
, 0},
1552 {"comm", msp430_comm
, 0},
1553 {"lcomm", msp430_lcomm
, 0},
1557 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1559 struct option md_longopts
[] =
1561 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1562 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1563 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1564 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1565 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1566 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1567 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1568 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1569 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1570 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1571 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1572 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1573 {NULL
, no_argument
, NULL
, 0}
1576 size_t md_longopts_size
= sizeof (md_longopts
);
1579 md_show_usage (FILE * stream
)
1582 _("MSP430 options:\n"
1583 " -mmcu=<msp430-name> - select microcontroller type\n"
1584 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1586 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1587 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1588 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1590 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1591 " -mP - enable polymorph instructions\n"));
1593 _(" -ml - enable large code model\n"));
1595 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1597 _(" -mn - insert a NOP after changing interrupts\n"));
1599 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1601 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1603 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1607 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1613 extract_cmd (char * from
, char * to
, int limit
)
1617 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1619 *(to
+ size
) = *from
;
1630 md_atof (int type
, char * litP
, int * sizeP
)
1632 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1638 struct msp430_opcode_s
* opcode
;
1639 msp430_hash
= hash_new ();
1641 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1642 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1644 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1645 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1647 /* Set linkrelax here to avoid fixups in most sections. */
1651 /* Returns the register number equivalent to the string T.
1652 Returns -1 if there is no such register.
1653 Skips a leading 'r' or 'R' character if there is one.
1654 Handles the register aliases PC and SP. */
1657 check_reg (char * t
)
1664 if (*t
== 'r' || *t
== 'R')
1667 if (strncasecmp (t
, "pc", 2) == 0)
1670 if (strncasecmp (t
, "sp", 2) == 0)
1673 if (strncasecmp (t
, "sr", 2) == 0)
1681 if (val
< 1 || val
> 15)
1688 msp430_srcoperand (struct msp430_operand_s
* op
,
1691 bfd_boolean
* imm_op
,
1692 bfd_boolean allow_20bit_values
,
1693 bfd_boolean constants_allowed
)
1697 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1704 /* Check if there is:
1705 llo(x) - least significant 16 bits, x &= 0xffff
1706 lhi(x) - x = (x >> 16) & 0xffff,
1707 hlo(x) - x = (x >> 32) & 0xffff,
1708 hhi(x) - x = (x >> 48) & 0xffff
1709 The value _MUST_ be constant expression: #hlo(1231231231). */
1713 if (strncasecmp (h
, "#llo(", 5) == 0)
1718 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1723 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1728 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1733 else if (strncasecmp (h
, "#lo(", 4) == 0)
1738 else if (strncasecmp (h
, "#hi(", 4) == 0)
1744 op
->reg
= 0; /* Reg PC. */
1746 op
->ol
= 1; /* Immediate will follow an instruction. */
1747 __tl
= h
+ 1 + rval
;
1749 op
->vshift
= vshift
;
1751 parse_exp (__tl
, &(op
->exp
));
1752 if (op
->exp
.X_op
== O_constant
)
1754 int x
= op
->exp
.X_add_number
;
1759 op
->exp
.X_add_number
= x
;
1761 else if (vshift
== 1)
1763 x
= (x
>> 16) & 0xffff;
1764 op
->exp
.X_add_number
= x
;
1767 else if (vshift
> 1)
1770 op
->exp
.X_add_number
= -1;
1772 op
->exp
.X_add_number
= 0; /* Nothing left. */
1773 x
= op
->exp
.X_add_number
;
1777 if (allow_20bit_values
)
1779 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1781 as_bad (_("value 0x%x out of extended range."), x
);
1785 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1787 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1791 /* Now check constants. */
1792 /* Substitute register mode with a constant generator if applicable. */
1794 if (!allow_20bit_values
)
1795 x
= (short) x
; /* Extend sign. */
1797 if (! constants_allowed
)
1829 if (bin
== 0x1200 && ! target_is_430x ())
1831 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1832 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1833 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1834 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1846 if (bin
== 0x1200 && ! target_is_430x ())
1848 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1849 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1850 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1861 else if (op
->exp
.X_op
== O_symbol
)
1864 as_bad (_("error: unsupported #foo() directive used on symbol"));
1867 else if (op
->exp
.X_op
== O_big
)
1873 op
->exp
.X_op
= O_constant
;
1874 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1875 x
= op
->exp
.X_add_number
;
1881 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
1929 /* Redundant (yet) check. */
1930 else if (op
->exp
.X_op
== O_register
)
1932 (_("Registers cannot be used within immediate expression [%s]"), l
);
1934 as_bad (_("unknown operand %s"), l
);
1939 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1944 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1945 op
->am
= 1; /* mode As == 01 bin. */
1946 op
->ol
= 1; /* Immediate value followed by instruction. */
1948 parse_exp (__tl
, &(op
->exp
));
1951 if (op
->exp
.X_op
== O_constant
)
1953 int x
= op
->exp
.X_add_number
;
1955 if (allow_20bit_values
)
1957 if (x
> 0xfffff || x
< -(0x7ffff))
1959 as_bad (_("value 0x%x out of extended range."), x
);
1963 else if (x
> 65535 || x
< -32768)
1965 as_bad (_("value out of range: 0x%x"), x
);
1969 else if (op
->exp
.X_op
== O_symbol
)
1973 /* Redundant (yet) check. */
1974 if (op
->exp
.X_op
== O_register
)
1976 (_("Registers cannot be used within absolute expression [%s]"), l
);
1978 as_bad (_("unknown expression in operand %s"), l
);
1984 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1988 char *m
= strchr (l
, '+');
1992 as_bad (_("unknown addressing mode %s"), l
);
1998 if ((op
->reg
= check_reg (t
)) == -1)
2000 as_bad (_("Bad register name %s"), t
);
2008 /* PC cannot be used in indirect addressing. */
2009 if (target_is_430xv2 () && op
->reg
== 0)
2011 as_bad (_("cannot use indirect addressing with the PC"));
2018 /* Check if register indexed X(Rn). */
2021 char *h
= strrchr (l
, '(');
2022 char *m
= strrchr (l
, ')');
2031 as_bad (_("')' required"));
2039 /* Extract a register. */
2040 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2043 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2050 as_bad (_("r2 should not be used in indexed addressing mode"));
2054 /* Extract constant. */
2059 parse_exp (__tl
, &(op
->exp
));
2060 if (op
->exp
.X_op
== O_constant
)
2062 int x
= op
->exp
.X_add_number
;
2064 if (allow_20bit_values
)
2066 if (x
> 0xfffff || x
< - (0x7ffff))
2068 as_bad (_("value 0x%x out of extended range."), x
);
2072 else if (x
> 65535 || x
< -32768)
2074 as_bad (_("value out of range: 0x%x"), x
);
2086 if (op
->reg
== 1 && (x
& 1))
2088 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2089 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2090 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2091 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2094 else if (op
->exp
.X_op
== O_symbol
)
2098 /* Redundant (yet) check. */
2099 if (op
->exp
.X_op
== O_register
)
2101 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2103 as_bad (_("unknown expression in operand %s"), l
);
2111 /* Possibly register mode 'mov r1,r2'. */
2112 if ((op
->reg
= check_reg (l
)) != -1)
2120 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2124 op
->reg
= 0; /* PC relative... be careful. */
2125 /* An expression starting with a minus sign is a constant, not an address. */
2126 op
->am
= (*l
== '-' ? 3 : 1);
2130 parse_exp (__tl
, &(op
->exp
));
2136 as_bad (_("unknown addressing mode for operand %s"), l
);
2142 msp430_dstoperand (struct msp430_operand_s
* op
,
2145 bfd_boolean allow_20bit_values
,
2146 bfd_boolean constants_allowed
)
2149 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2158 char *__tl
= (char *) "0";
2164 parse_exp (__tl
, &(op
->exp
));
2166 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2168 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2178 ("this addressing mode is not applicable for destination operand"));
2184 /* Attempt to encode a MOVA instruction with the given operands.
2185 Returns the length of the encoded instruction if successful
2186 or 0 upon failure. If the encoding fails, an error message
2187 will be returned if a pointer is provided. */
2190 try_encode_mova (bfd_boolean imm_op
,
2192 struct msp430_operand_s
* op1
,
2193 struct msp430_operand_s
* op2
,
2194 const char ** error_message_return
)
2200 /* Only a restricted subset of the normal MSP430 addressing modes
2201 are supported here, so check for the ones that are allowed. */
2204 if (op1
->mode
== OP_EXP
)
2206 if (op2
->mode
!= OP_REG
)
2208 if (error_message_return
!= NULL
)
2209 * error_message_return
= _("expected register as second argument of %s");
2215 /* MOVA #imm20, Rdst. */
2216 bin
|= 0x80 | op2
->reg
;
2217 frag
= frag_more (4);
2218 where
= frag
- frag_now
->fr_literal
;
2219 if (op1
->exp
.X_op
== O_constant
)
2221 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2222 bfd_putl16 ((bfd_vma
) bin
, frag
);
2223 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2227 bfd_putl16 ((bfd_vma
) bin
, frag
);
2228 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2229 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2230 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2235 else if (op1
->am
== 1)
2237 /* MOVA z16(Rsrc), Rdst. */
2238 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2239 frag
= frag_more (4);
2240 where
= frag
- frag_now
->fr_literal
;
2241 bfd_putl16 ((bfd_vma
) bin
, frag
);
2242 if (op1
->exp
.X_op
== O_constant
)
2244 if (op1
->exp
.X_add_number
> 0xffff
2245 || op1
->exp
.X_add_number
< -(0x7fff))
2247 if (error_message_return
!= NULL
)
2248 * error_message_return
= _("index value too big for %s");
2251 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2255 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2256 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2258 BFD_RELOC_MSP430X_PCR16
:
2259 BFD_RELOC_MSP430X_ABS16
);
2264 if (error_message_return
!= NULL
)
2265 * error_message_return
= _("unexpected addressing mode for %s");
2268 else if (op1
->am
== 0)
2270 /* MOVA Rsrc, ... */
2271 if (op2
->mode
== OP_REG
)
2273 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2274 frag
= frag_more (2);
2275 where
= frag
- frag_now
->fr_literal
;
2276 bfd_putl16 ((bfd_vma
) bin
, frag
);
2279 else if (op2
->am
== 1)
2283 /* MOVA Rsrc, &abs20. */
2284 bin
|= 0x60 | (op1
->reg
<< 8);
2285 frag
= frag_more (4);
2286 where
= frag
- frag_now
->fr_literal
;
2287 if (op2
->exp
.X_op
== O_constant
)
2289 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2290 bfd_putl16 ((bfd_vma
) bin
, frag
);
2291 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2295 bfd_putl16 ((bfd_vma
) bin
, frag
);
2296 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2297 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2298 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2303 /* MOVA Rsrc, z16(Rdst). */
2304 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2305 frag
= frag_more (4);
2306 where
= frag
- frag_now
->fr_literal
;
2307 bfd_putl16 ((bfd_vma
) bin
, frag
);
2308 if (op2
->exp
.X_op
== O_constant
)
2310 if (op2
->exp
.X_add_number
> 0xffff
2311 || op2
->exp
.X_add_number
< -(0x7fff))
2313 if (error_message_return
!= NULL
)
2314 * error_message_return
= _("index value too big for %s");
2317 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2321 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2322 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2324 BFD_RELOC_MSP430X_PCR16
:
2325 BFD_RELOC_MSP430X_ABS16
);
2330 if (error_message_return
!= NULL
)
2331 * error_message_return
= _("unexpected addressing mode for %s");
2336 /* imm_op == FALSE. */
2338 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2340 /* MOVA &abs20, Rdst. */
2341 if (op2
->mode
!= OP_REG
)
2343 if (error_message_return
!= NULL
)
2344 * error_message_return
= _("expected register as second argument of %s");
2348 if (op2
->reg
== 2 || op2
->reg
== 3)
2350 if (error_message_return
!= NULL
)
2351 * error_message_return
= _("constant generator destination register found in %s");
2355 bin
|= 0x20 | op2
->reg
;
2356 frag
= frag_more (4);
2357 where
= frag
- frag_now
->fr_literal
;
2358 if (op1
->exp
.X_op
== O_constant
)
2360 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2361 bfd_putl16 ((bfd_vma
) bin
, frag
);
2362 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2366 bfd_putl16 ((bfd_vma
) bin
, frag
);
2367 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2368 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2369 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2373 else if (op1
->mode
== OP_REG
)
2377 /* MOVA @Rsrc+, Rdst. */
2378 if (op2
->mode
!= OP_REG
)
2380 if (error_message_return
!= NULL
)
2381 * error_message_return
= _("expected register as second argument of %s");
2385 if (op2
->reg
== 2 || op2
->reg
== 3)
2387 if (error_message_return
!= NULL
)
2388 * error_message_return
= _("constant generator destination register found in %s");
2392 if (op1
->reg
== 2 || op1
->reg
== 3)
2394 if (error_message_return
!= NULL
)
2395 * error_message_return
= _("constant generator source register found in %s");
2399 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2400 frag
= frag_more (2);
2401 where
= frag
- frag_now
->fr_literal
;
2402 bfd_putl16 ((bfd_vma
) bin
, frag
);
2405 else if (op1
->am
== 2)
2407 /* MOVA @Rsrc,Rdst */
2408 if (op2
->mode
!= OP_REG
)
2410 if (error_message_return
!= NULL
)
2411 * error_message_return
= _("expected register as second argument of %s");
2415 if (op2
->reg
== 2 || op2
->reg
== 3)
2417 if (error_message_return
!= NULL
)
2418 * error_message_return
= _("constant generator destination register found in %s");
2422 if (op1
->reg
== 2 || op1
->reg
== 3)
2424 if (error_message_return
!= NULL
)
2425 * error_message_return
= _("constant generator source register found in %s");
2429 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2430 frag
= frag_more (2);
2431 where
= frag
- frag_now
->fr_literal
;
2432 bfd_putl16 ((bfd_vma
) bin
, frag
);
2437 if (error_message_return
!= NULL
)
2438 * error_message_return
= _("unexpected addressing mode for %s");
2443 #define NOP_CHECK_INTERRUPT (1 << 0)
2444 #define NOP_CHECK_CPU12 (1 << 1)
2445 #define NOP_CHECK_CPU19 (1 << 2)
2447 static signed int check_for_nop
= 0;
2449 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2451 /* Parse instruction operands.
2452 Return binary opcode. */
2455 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2457 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2458 int insn_length
= 0;
2459 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2462 struct msp430_operand_s op1
, op2
;
2464 static short ZEROS
= 0;
2465 bfd_boolean byte_op
, imm_op
;
2468 int extended
= 0x1800;
2469 bfd_boolean extended_op
= FALSE
;
2470 bfd_boolean addr_op
;
2471 const char * error_message
;
2472 static signed int repeat_count
= 0;
2473 static bfd_boolean prev_insn_is_nop
= FALSE
;
2474 bfd_boolean fix_emitted
;
2476 /* Opcode is the one from opcodes table
2477 line contains something like
2486 bfd_boolean check
= FALSE
;
2489 switch (TOLOWER (* line
))
2492 /* Byte operation. */
2493 bin
|= BYTE_OPERATION
;
2499 /* "Address" ops work on 20-bit values. */
2501 bin
|= BYTE_OPERATION
;
2506 /* Word operation - this is the default. */
2514 as_warn (_("no size modifier after period, .w assumed"));
2518 as_bad (_("unrecognised instruction size modifier .%c"),
2530 if (*line
&& ! ISSPACE (*line
))
2532 as_bad (_("junk found after instruction: %s.%s"),
2533 opcode
->name
, line
);
2537 /* Catch the case where the programmer has used a ".a" size modifier on an
2538 instruction that does not support it. Look for an alternative extended
2539 instruction that has the same name without the period. Eg: "add.a"
2540 becomes "adda". Although this not an officially supported way of
2541 specifying instruction aliases other MSP430 assemblers allow it. So we
2542 support it for compatibility purposes. */
2543 if (addr_op
&& opcode
->fmt
>= 0)
2545 const char * old_name
= opcode
->name
;
2548 sprintf (real_name
, "%sa", old_name
);
2549 opcode
= hash_find (msp430_hash
, real_name
);
2552 as_bad (_("instruction %s.a does not exist"), old_name
);
2555 #if 0 /* Enable for debugging. */
2556 as_warn ("treating %s.a as %s", old_name
, real_name
);
2559 bin
= opcode
->bin_opcode
;
2562 if (opcode
->fmt
!= -1
2563 && opcode
->insn_opnumb
2564 && (!*line
|| *line
== '\n'))
2566 as_bad (_("instruction %s requires %d operand(s)"),
2567 opcode
->name
, opcode
->insn_opnumb
);
2571 memset (l1
, 0, sizeof (l1
));
2572 memset (l2
, 0, sizeof (l2
));
2573 memset (&op1
, 0, sizeof (op1
));
2574 memset (&op2
, 0, sizeof (op2
));
2578 if ((fmt
= opcode
->fmt
) < 0)
2580 if (! target_is_430x ())
2582 as_bad (_("instruction %s requires MSP430X mcu"),
2593 /* If requested set the extended instruction repeat count. */
2596 if (repeat_count
> 0)
2597 extended
|= (repeat_count
- 1);
2599 extended
|= (1 << 7) | (- repeat_count
);
2602 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2609 if (! is_opcode ("nop"))
2611 bfd_boolean doit
= FALSE
;
2615 switch (check_for_nop
& - check_for_nop
)
2617 case NOP_CHECK_INTERRUPT
:
2618 if (warn_interrupt_nops
)
2620 if (gen_interrupt_nops
)
2621 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2623 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2626 if (gen_interrupt_nops
)
2627 /* Emit a NOP between interrupt enable/disable.
2628 See 1.3.4.1 of the MSP430x5xx User Guide. */
2632 case NOP_CHECK_CPU12
:
2633 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2634 as_warn (_("CPU12: CMP/BIT with PC destinstion ignores next instruction"));
2636 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2640 case NOP_CHECK_CPU19
:
2641 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2642 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2644 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2649 as_bad (_("internal error: unknown nop check state"));
2652 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2654 while (check_for_nop
);
2658 frag
= frag_more (2);
2659 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2660 dwarf2_emit_insn (2);
2669 case 0: /* Emulated. */
2670 switch (opcode
->insn_opnumb
)
2673 if (is_opcode ("eint"))
2675 if (! prev_insn_is_nop
)
2677 if (gen_interrupt_nops
)
2679 frag
= frag_more (2);
2680 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2681 dwarf2_emit_insn (2);
2683 if (warn_interrupt_nops
)
2684 as_warn (_("inserting a NOP before EINT"));
2686 else if (warn_interrupt_nops
)
2687 as_warn (_("a NOP might be needed before the EINT"));
2690 else if (is_opcode ("dint"))
2691 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2693 /* Set/clear bits instructions. */
2697 extended
|= BYTE_OPERATION
;
2699 /* Emit the extension word. */
2701 frag
= frag_more (2);
2702 bfd_putl16 (extended
, frag
);
2706 frag
= frag_more (2);
2707 bfd_putl16 ((bfd_vma
) bin
, frag
);
2708 dwarf2_emit_insn (insn_length
);
2712 /* Something which works with destination operand. */
2713 line
= extract_operand (line
, l1
, sizeof (l1
));
2714 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2718 bin
|= (op1
.reg
| (op1
.am
<< 7));
2720 /* If the PC is the destination... */
2721 if (op1
.am
== 0 && op1
.reg
== 0
2722 /* ... and the opcode alters the SR. */
2723 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2724 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2726 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2727 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
2728 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2729 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
2732 /* If the status register is the destination... */
2733 if (op1
.am
== 0 && op1
.reg
== 2
2734 /* ... and the opcode alters the SR. */
2735 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2736 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2737 || is_opcode ("sbc") || is_opcode ("sxt")
2738 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2739 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2740 || is_opcode ("sbcx")
2743 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2744 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2745 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2746 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2749 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2750 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2752 /* Compute the entire instruction length, in bytes. */
2753 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2754 insn_length
+= op_length
;
2755 frag
= frag_more (op_length
);
2756 where
= frag
- frag_now
->fr_literal
;
2761 extended
|= BYTE_OPERATION
;
2763 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2765 as_bad (_("repeat instruction used with non-register mode instruction"));
2769 if (op1
.mode
== OP_EXP
)
2771 if (op1
.exp
.X_op
== O_constant
)
2772 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2774 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2775 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2776 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2778 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2779 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2782 /* Emit the extension word. */
2783 bfd_putl16 (extended
, frag
);
2788 bfd_putl16 ((bfd_vma
) bin
, frag
);
2792 if (op1
.mode
== OP_EXP
)
2794 if (op1
.exp
.X_op
== O_constant
)
2796 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2800 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2805 fix_new_exp (frag_now
, where
, 2,
2806 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2808 fix_new_exp (frag_now
, where
, 2,
2809 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2814 dwarf2_emit_insn (insn_length
);
2818 /* Shift instruction. */
2819 line
= extract_operand (line
, l1
, sizeof (l1
));
2820 strncpy (l2
, l1
, sizeof (l2
));
2821 l2
[sizeof (l2
) - 1] = '\0';
2822 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2823 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2826 break; /* An error occurred. All warnings were done before. */
2828 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2829 frag
= frag_more (insn_length
);
2830 where
= frag
- frag_now
->fr_literal
;
2832 if (target_is_430xv2 ()
2833 && op1
.mode
== OP_REG
2835 && (is_opcode ("rlax")
2836 || is_opcode ("rlcx")
2837 || is_opcode ("rla")
2838 || is_opcode ("rlc")))
2840 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2844 /* If the status register is the destination... */
2845 if (op1
.am
== 0 && op1
.reg
== 2
2846 /* ... and the opcode alters the SR. */
2847 && (is_opcode ("rla") || is_opcode ("rlc")
2848 || is_opcode ("rlax") || is_opcode ("rlcx")
2851 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2852 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2853 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2854 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2860 extended
|= BYTE_OPERATION
;
2862 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2864 as_bad (_("repeat instruction used with non-register mode instruction"));
2868 if (op1
.mode
== OP_EXP
)
2870 if (op1
.exp
.X_op
== O_constant
)
2871 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2873 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2874 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2875 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2877 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2878 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2881 if (op2
.mode
== OP_EXP
)
2883 if (op2
.exp
.X_op
== O_constant
)
2884 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2886 else if (op1
.mode
== OP_EXP
)
2887 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2888 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2889 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2891 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2892 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2893 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2896 /* Emit the extension word. */
2897 bfd_putl16 (extended
, frag
);
2902 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2903 bfd_putl16 ((bfd_vma
) bin
, frag
);
2907 if (op1
.mode
== OP_EXP
)
2909 if (op1
.exp
.X_op
== O_constant
)
2911 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2915 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2919 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2920 fix_new_exp (frag_now
, where
, 2,
2921 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2923 fix_new_exp (frag_now
, where
, 2,
2924 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2931 if (op2
.mode
== OP_EXP
)
2933 if (op2
.exp
.X_op
== O_constant
)
2935 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2939 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2943 if (op2
.reg
) /* Not PC relative. */
2944 fix_new_exp (frag_now
, where
, 2,
2945 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2947 fix_new_exp (frag_now
, where
, 2,
2948 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2953 dwarf2_emit_insn (insn_length
);
2957 /* Branch instruction => mov dst, r0. */
2960 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2964 line
= extract_operand (line
, l1
, sizeof (l1
));
2965 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2971 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2972 op_length
= 2 + 2 * op1
.ol
;
2973 frag
= frag_more (op_length
);
2974 where
= frag
- frag_now
->fr_literal
;
2975 bfd_putl16 ((bfd_vma
) bin
, frag
);
2977 if (op1
.mode
== OP_EXP
)
2979 if (op1
.exp
.X_op
== O_constant
)
2981 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2987 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2989 if (op1
.reg
|| op1
.am
== 3)
2990 fix_new_exp (frag_now
, where
, 2,
2991 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2993 fix_new_exp (frag_now
, where
, 2,
2994 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2998 dwarf2_emit_insn (insn_length
+ op_length
);
3002 /* CALLA instructions. */
3003 fix_emitted
= FALSE
;
3005 line
= extract_operand (line
, l1
, sizeof (l1
));
3008 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3009 extended_op
, FALSE
);
3015 op_length
= 2 + 2 * op1
.ol
;
3016 frag
= frag_more (op_length
);
3017 where
= frag
- frag_now
->fr_literal
;
3025 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3026 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3029 else if (op1
.am
== 1)
3035 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3036 BFD_RELOC_MSP430X_PCR20_CALL
);
3040 bin
|= 0x50 | op1
.reg
;
3042 else if (op1
.am
== 0)
3043 bin
|= 0x40 | op1
.reg
;
3045 else if (op1
.am
== 1)
3049 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3050 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3053 else if (op1
.am
== 2)
3054 bin
|= 0x60 | op1
.reg
;
3055 else if (op1
.am
== 3)
3056 bin
|= 0x70 | op1
.reg
;
3058 bfd_putl16 ((bfd_vma
) bin
, frag
);
3060 if (op1
.mode
== OP_EXP
)
3064 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3068 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3071 fix_new_exp (frag_now
, where
+ 2, 2,
3072 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3075 dwarf2_emit_insn (insn_length
+ op_length
);
3083 /* [POP|PUSH]M[.A] #N, Rd */
3084 line
= extract_operand (line
, l1
, sizeof (l1
));
3085 line
= extract_operand (line
, l2
, sizeof (l2
));
3089 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3092 parse_exp (l1
+ 1, &(op1
.exp
));
3093 if (op1
.exp
.X_op
!= O_constant
)
3095 as_bad (_("expected constant expression as first argument of %s"),
3100 if ((reg
= check_reg (l2
)) == -1)
3102 as_bad (_("expected register as second argument of %s"),
3108 frag
= frag_more (op_length
);
3109 where
= frag
- frag_now
->fr_literal
;
3110 bin
= opcode
->bin_opcode
;
3113 n
= op1
.exp
.X_add_number
;
3114 bin
|= (n
- 1) << 4;
3115 if (is_opcode ("pushm"))
3119 if (reg
- n
+ 1 < 0)
3121 as_bad (_("Too many registers popped"));
3125 /* CPU21 errata: cannot use POPM to restore the SR register. */
3126 if (target_is_430xv2 ()
3127 && (reg
- n
+ 1 < 3)
3129 && is_opcode ("popm"))
3131 as_bad (_("Cannot use POPM to restore the SR register"));
3135 bin
|= (reg
- n
+ 1);
3138 bfd_putl16 ((bfd_vma
) bin
, frag
);
3139 dwarf2_emit_insn (op_length
);
3148 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3149 if (extended
& 0xff)
3151 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3155 line
= extract_operand (line
, l1
, sizeof (l1
));
3156 line
= extract_operand (line
, l2
, sizeof (l2
));
3160 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3163 parse_exp (l1
+ 1, &(op1
.exp
));
3164 if (op1
.exp
.X_op
!= O_constant
)
3166 as_bad (_("expected constant expression as first argument of %s"),
3170 n
= op1
.exp
.X_add_number
;
3173 as_bad (_("expected first argument of %s to be in the range 1-4"),
3178 if ((reg
= check_reg (l2
)) == -1)
3180 as_bad (_("expected register as second argument of %s"),
3185 if (target_is_430xv2 () && reg
== 0)
3187 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3192 frag
= frag_more (op_length
);
3193 where
= frag
- frag_now
->fr_literal
;
3195 bin
= opcode
->bin_opcode
;
3198 bin
|= (n
- 1) << 10;
3201 bfd_putl16 ((bfd_vma
) bin
, frag
);
3202 dwarf2_emit_insn (op_length
);
3208 bfd_boolean need_reloc
= FALSE
;
3212 /* ADDA, CMPA and SUBA address instructions. */
3213 if (extended
& 0xff)
3215 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3219 line
= extract_operand (line
, l1
, sizeof (l1
));
3220 line
= extract_operand (line
, l2
, sizeof (l2
));
3222 bin
= opcode
->bin_opcode
;
3226 parse_exp (l1
+ 1, &(op1
.exp
));
3228 if (op1
.exp
.X_op
== O_constant
)
3230 n
= op1
.exp
.X_add_number
;
3231 if (n
> 0xfffff || n
< - (0x7ffff))
3233 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3238 bin
|= ((n
>> 16) & 0xf) << 8;
3250 if ((n
= check_reg (l1
)) == -1)
3252 as_bad (_("expected register name or constant as first argument of %s"),
3257 bin
|= (n
<< 8) | (1 << 6);
3261 if ((reg
= check_reg (l2
)) == -1)
3263 as_bad (_("expected register as second argument of %s"),
3268 frag
= frag_more (op_length
);
3269 where
= frag
- frag_now
->fr_literal
;
3272 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3273 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3275 bfd_putl16 ((bfd_vma
) bin
, frag
);
3277 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3278 dwarf2_emit_insn (op_length
);
3282 case 9: /* MOVA, BRA, RETA. */
3284 bin
= opcode
->bin_opcode
;
3286 if (is_opcode ("reta"))
3288 /* The RETA instruction does not take any arguments.
3289 The implicit first argument is @SP+.
3290 The implicit second argument is PC. */
3300 line
= extract_operand (line
, l1
, sizeof (l1
));
3301 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3302 &imm_op
, extended_op
, FALSE
);
3304 if (is_opcode ("bra"))
3306 /* This is the BRA synthetic instruction.
3307 The second argument is always PC. */
3313 line
= extract_operand (line
, l2
, sizeof (l2
));
3314 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3319 break; /* Error occurred. All warnings were done before. */
3322 /* Only a restricted subset of the normal MSP430 addressing modes
3323 are supported here, so check for the ones that are allowed. */
3324 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3325 & error_message
)) == 0)
3327 as_bad (error_message
, opcode
->name
);
3330 dwarf2_emit_insn (op_length
);
3334 line
= extract_operand (line
, l1
, sizeof l1
);
3335 /* The RPT instruction only accepted immediates and registers. */
3338 parse_exp (l1
+ 1, &(op1
.exp
));
3339 if (op1
.exp
.X_op
!= O_constant
)
3341 as_bad (_("expected constant value as argument to RPT"));
3344 if (op1
.exp
.X_add_number
< 1
3345 || op1
.exp
.X_add_number
> (1 << 4))
3347 as_bad (_("expected constant in the range 2..16"));
3351 /* We silently accept and ignore a repeat count of 1. */
3352 if (op1
.exp
.X_add_number
> 1)
3353 repeat_count
= op1
.exp
.X_add_number
;
3359 if ((reg
= check_reg (l1
)) != -1)
3362 as_warn (_("PC used as an argument to RPT"));
3364 repeat_count
= - reg
;
3368 as_bad (_("expected constant or register name as argument to RPT insn"));
3375 as_bad (_("Illegal emulated instruction"));
3380 case 1: /* Format 1, double operand. */
3381 line
= extract_operand (line
, l1
, sizeof (l1
));
3382 line
= extract_operand (line
, l2
, sizeof (l2
));
3383 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3384 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3387 break; /* Error occurred. All warnings were done before. */
3390 && is_opcode ("movx")
3392 && msp430_enable_relax
)
3394 /* This is the MOVX.A instruction. See if we can convert
3395 it into the MOVA instruction instead. This saves 2 bytes. */
3396 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3399 dwarf2_emit_insn (op_length
);
3404 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3406 /* If the PC is the destination... */
3407 if (op2
.am
== 0 && op2
.reg
== 0
3408 /* ... and the opcode alters the SR. */
3409 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3410 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3412 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3413 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
3414 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3415 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
3418 /* If the status register is the destination... */
3419 if (op2
.am
== 0 && op2
.reg
== 2
3420 /* ... and the opcode alters the SR. */
3421 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3422 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3423 || is_opcode ("xor")
3424 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3425 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3426 || is_opcode ("xorx")
3429 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3430 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3431 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3432 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3435 if ( (is_opcode ("bic") && bin
== 0xc232)
3436 || (is_opcode ("bis") && bin
== 0xd232)
3437 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3439 /* Avoid false checks when a constant value is being put into the SR. */
3440 if (op1
.mode
== OP_EXP
3441 && op1
.exp
.X_op
== O_constant
3442 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3445 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3448 if (((is_opcode ("bis") && bin
== 0xd032)
3449 || (is_opcode ("mov") && bin
== 0x4032)
3450 || (is_opcode ("xor") && bin
== 0xe032))
3451 && op1
.mode
== OP_EXP
3452 && op1
.exp
.X_op
== O_constant
3453 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3454 check_for_nop
|= NOP_CHECK_CPU19
;
3456 /* Compute the entire length of the instruction in bytes. */
3457 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3458 + 2 /* The opcode */
3459 + (2 * op1
.ol
) /* The first operand. */
3460 + (2 * op2
.ol
); /* The second operand. */
3462 insn_length
+= op_length
;
3463 frag
= frag_more (op_length
);
3464 where
= frag
- frag_now
->fr_literal
;
3469 extended
|= BYTE_OPERATION
;
3471 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3473 as_bad (_("repeat instruction used with non-register mode instruction"));
3477 /* If necessary, emit a reloc to update the extension word. */
3478 if (op1
.mode
== OP_EXP
)
3480 if (op1
.exp
.X_op
== O_constant
)
3481 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3483 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3484 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3485 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3487 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3488 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3491 if (op2
.mode
== OP_EXP
)
3493 if (op2
.exp
.X_op
== O_constant
)
3494 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3496 else if (op1
.mode
== OP_EXP
)
3497 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3498 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3499 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3502 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3503 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3504 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3507 /* Emit the extension word. */
3508 bfd_putl16 (extended
, frag
);
3513 bfd_putl16 ((bfd_vma
) bin
, frag
);
3517 if (op1
.mode
== OP_EXP
)
3519 if (op1
.exp
.X_op
== O_constant
)
3521 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3525 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3529 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3530 fix_new_exp (frag_now
, where
, 2,
3531 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3533 fix_new_exp (frag_now
, where
, 2,
3534 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3542 if (op2
.mode
== OP_EXP
)
3544 if (op2
.exp
.X_op
== O_constant
)
3546 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3550 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3554 if (op2
.reg
) /* Not PC relative. */
3555 fix_new_exp (frag_now
, where
, 2,
3556 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3558 fix_new_exp (frag_now
, where
, 2,
3559 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3564 dwarf2_emit_insn (insn_length
);
3566 /* If the PC is the destination... */
3567 if (op2
.am
== 0 && op2
.reg
== 0
3568 /* ... but the opcode does not alter the destination. */
3569 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3570 check_for_nop
|= NOP_CHECK_CPU12
;
3573 case 2: /* Single-operand mostly instr. */
3574 if (opcode
->insn_opnumb
== 0)
3576 /* reti instruction. */
3578 frag
= frag_more (2);
3579 bfd_putl16 ((bfd_vma
) bin
, frag
);
3580 dwarf2_emit_insn (insn_length
);
3584 line
= extract_operand (line
, l1
, sizeof (l1
));
3585 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3586 &imm_op
, extended_op
, TRUE
);
3588 break; /* Error in operand. */
3590 if (target_is_430xv2 ()
3591 && op1
.mode
== OP_REG
3593 && (is_opcode ("rrax")
3594 || is_opcode ("rrcx")
3595 || is_opcode ("rra")
3596 || is_opcode ("rrc")))
3598 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3602 /* If the status register is the destination... */
3603 if (op1
.am
== 0 && op1
.reg
== 2
3604 /* ... and the opcode alters the SR. */
3605 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3607 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3608 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3609 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3610 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3613 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3614 frag
= frag_more (insn_length
);
3615 where
= frag
- frag_now
->fr_literal
;
3619 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3621 /* These two instructions use a special
3622 encoding of the A/L and B/W bits. */
3623 bin
&= ~ BYTE_OPERATION
;
3627 as_bad (_("%s instruction does not accept a .b suffix"),
3632 extended
|= BYTE_OPERATION
;
3635 extended
|= BYTE_OPERATION
;
3637 if (is_opcode ("rrux"))
3638 extended
|= IGNORE_CARRY_BIT
;
3640 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3642 as_bad (_("repeat instruction used with non-register mode instruction"));
3646 if (op1
.mode
== OP_EXP
)
3648 if (op1
.exp
.X_op
== O_constant
)
3649 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3651 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3652 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3653 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3655 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3656 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3659 /* Emit the extension word. */
3660 bfd_putl16 (extended
, frag
);
3665 bin
|= op1
.reg
| (op1
.am
<< 4);
3666 bfd_putl16 ((bfd_vma
) bin
, frag
);
3670 if (op1
.mode
== OP_EXP
)
3672 if (op1
.exp
.X_op
== O_constant
)
3674 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3678 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3682 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3683 fix_new_exp (frag_now
, where
, 2,
3684 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3686 fix_new_exp (frag_now
, where
, 2,
3687 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3692 dwarf2_emit_insn (insn_length
);
3695 case 3: /* Conditional jumps instructions. */
3696 line
= extract_operand (line
, l1
, sizeof (l1
));
3697 /* l1 is a label. */
3706 parse_exp (m
, &exp
);
3708 /* In order to handle something like:
3712 jz 4 ; skip next 4 bytes
3715 nop ; will jump here if r5 positive or zero
3717 jCOND -n ;assumes jump n bytes backward:
3727 jCOND $n ; jump from PC in either direction. */
3729 if (exp
.X_op
== O_constant
)
3731 int x
= exp
.X_add_number
;
3735 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3739 if ((*l1
== '$' && x
> 0) || x
< 0)
3744 if (x
> 512 || x
< -511)
3746 as_bad (_("Wrong displacement %d"), x
<< 1);
3751 frag
= frag_more (2); /* Instr size is 1 word. */
3754 bfd_putl16 ((bfd_vma
) bin
, frag
);
3756 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3759 frag
= frag_more (2); /* Instr size is 1 word. */
3760 where
= frag
- frag_now
->fr_literal
;
3761 fix_new_exp (frag_now
, where
, 2,
3762 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3764 bfd_putl16 ((bfd_vma
) bin
, frag
);
3766 else if (*l1
== '$')
3768 as_bad (_("instruction requires label sans '$'"));
3772 ("instruction requires label or value in range -511:512"));
3773 dwarf2_emit_insn (insn_length
);
3778 as_bad (_("instruction requires label"));
3783 case 4: /* Extended jumps. */
3784 if (!msp430_enable_polys
)
3786 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3790 line
= extract_operand (line
, l1
, sizeof (l1
));
3796 /* Ignore absolute addressing. make it PC relative anyway. */
3797 if (*m
== '#' || *m
== '$')
3800 parse_exp (m
, & exp
);
3801 if (exp
.X_op
== O_symbol
)
3803 /* Relaxation required. */
3804 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3806 if (target_is_430x ())
3807 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3809 /* The parameter to dwarf2_emit_insn is actually the offset to
3810 the start of the insn from the fix piece of instruction that
3811 was emitted. Since next fragments may have variable size we
3812 tie debug info to the beginning of the instruction. */
3814 frag
= frag_more (8);
3815 dwarf2_emit_insn (0);
3816 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3817 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3819 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3821 0, /* Offset is zero if jump dist less than 1K. */
3827 as_bad (_("instruction requires label"));
3830 case 5: /* Emulated extended branches. */
3831 if (!msp430_enable_polys
)
3833 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3836 line
= extract_operand (line
, l1
, sizeof (l1
));
3842 /* Ignore absolute addressing. make it PC relative anyway. */
3843 if (*m
== '#' || *m
== '$')
3846 parse_exp (m
, & exp
);
3847 if (exp
.X_op
== O_symbol
)
3849 /* Relaxation required. */
3850 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3852 if (target_is_430x ())
3853 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3856 frag
= frag_more (8);
3857 dwarf2_emit_insn (0);
3858 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3859 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3861 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3862 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3864 0, /* Offset is zero if jump dist less than 1K. */
3870 as_bad (_("instruction requires label"));
3874 as_bad (_("Illegal instruction or not implemented opcode."));
3877 if (is_opcode ("nop"))
3878 prev_insn_is_nop
= TRUE
;
3880 prev_insn_is_nop
= FALSE
;
3882 input_line_pointer
= line
;
3887 md_assemble (char * str
)
3889 struct msp430_opcode_s
* opcode
;
3893 str
= skip_space (str
); /* Skip leading spaces. */
3894 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3898 char a
= TOLOWER (cmd
[i
]);
3905 as_bad (_("can't find opcode"));
3909 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3913 as_bad (_("unknown opcode `%s'"), cmd
);
3918 char *__t
= input_line_pointer
;
3920 msp430_operands (opcode
, str
);
3921 input_line_pointer
= __t
;
3925 /* GAS will call this function for each section at the end of the assembly,
3926 to permit the CPU backend to adjust the alignment of a section. */
3929 md_section_align (asection
* seg
, valueT addr
)
3931 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3933 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
3936 /* If you define this macro, it should return the offset between the
3937 address of a PC relative fixup and the position from which the PC
3938 relative adjustment should be made. On many processors, the base
3939 of a PC relative instruction is the next instruction, so this
3940 macro would return the length of an instruction. */
3943 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3945 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3946 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3947 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3950 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3953 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3954 Now it handles the situation when relocations
3955 have to be passed to linker. */
3957 msp430_force_relocation_local (fixS
*fixp
)
3959 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3963 if (msp430_enable_polys
3964 && !msp430_enable_relax
)
3967 return (!fixp
->fx_pcrel
3968 || generic_force_reloc (fixp
));
3972 /* GAS will call this for each fixup. It should store the correct
3973 value in the object file. */
3975 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3977 unsigned char * where
;
3981 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3986 else if (fixp
->fx_pcrel
)
3988 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3990 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3992 /* FIXME: We can appear here only in case if we perform a pc
3993 relative jump to the label which is i) global, ii) locally
3994 defined or this is a jump to an absolute symbol.
3995 If this is an absolute symbol -- everything is OK.
3996 If this is a global label, we've got a symbol value defined
3998 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3999 from this section start
4000 2. *valuep will contain the real offset from jump insn to the
4002 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4003 will be incorrect. Therefore remove s_get_value. */
4004 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4012 value
= fixp
->fx_offset
;
4014 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4016 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4018 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4024 fixp
->fx_no_overflow
= 1;
4026 /* If polymorphs are enabled and relax disabled.
4027 do not kill any relocs and pass them to linker. */
4028 if (msp430_enable_polys
4029 && !msp430_enable_relax
)
4032 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4033 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4040 /* Fetch the instruction, insert the fully resolved operand
4041 value, and stuff the instruction back again. */
4042 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4044 insn
= bfd_getl16 (where
);
4046 switch (fixp
->fx_r_type
)
4048 case BFD_RELOC_MSP430_10_PCREL
:
4050 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4051 _("odd address operand: %ld"), value
);
4053 /* Jumps are in words. */
4055 --value
; /* Correct PC. */
4057 if (value
< -512 || value
> 511)
4058 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4059 _("operand out of range: %ld"), value
);
4061 value
&= 0x3ff; /* get rid of extended sign */
4062 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4065 case BFD_RELOC_MSP430X_PCR16
:
4066 case BFD_RELOC_MSP430_RL_PCREL
:
4067 case BFD_RELOC_MSP430_16_PCREL
:
4069 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4070 _("odd address operand: %ld"), value
);
4073 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4074 /* Nothing to be corrected here. */
4075 if (value
< -32768 || value
> 65536)
4076 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4077 _("operand out of range: %ld"), value
);
4080 case BFD_RELOC_MSP430X_ABS16
:
4081 case BFD_RELOC_MSP430_16
:
4083 case BFD_RELOC_MSP430_16_BYTE
:
4084 value
&= 0xffff; /* Get rid of extended sign. */
4085 bfd_putl16 ((bfd_vma
) value
, where
);
4088 case BFD_RELOC_MSP430_ABS_HI16
:
4090 value
&= 0xffff; /* Get rid of extended sign. */
4091 bfd_putl16 ((bfd_vma
) value
, where
);
4095 bfd_putl16 ((bfd_vma
) value
, where
);
4098 case BFD_RELOC_MSP430_ABS8
:
4100 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4103 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4104 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4105 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4107 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4110 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4111 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4113 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4116 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4117 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4119 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4122 case BFD_RELOC_MSP430X_PCR20_CALL
:
4123 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4125 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4128 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4129 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4130 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4132 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4135 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4136 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4138 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4141 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4142 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4144 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4148 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4149 fixp
->fx_line
, fixp
->fx_r_type
);
4155 fixp
->fx_addnumber
= value
;
4160 S_IS_GAS_LOCAL (symbolS
* s
)
4167 name
= S_GET_NAME (s
);
4168 len
= strlen (name
) - 1;
4170 return name
[len
] == 1 || name
[len
] == 2;
4173 /* GAS will call this to generate a reloc, passing the resulting reloc
4174 to `bfd_install_relocation'. This currently works poorly, as
4175 `bfd_install_relocation' often does the wrong thing, and instances of
4176 `tc_gen_reloc' have been written to work around the problems, which
4177 in turns makes it difficult to fix `bfd_install_relocation'. */
4179 /* If while processing a fixup, a reloc really needs to be created
4180 then it is done here. */
4183 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4185 static arelent
* no_relocs
= NULL
;
4186 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4189 reloc
= XNEW (arelent
);
4190 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4191 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4193 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4195 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4196 _("reloc %d not supported by object file format"),
4197 (int) fixp
->fx_r_type
);
4206 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4208 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4209 fixp
->fx_subsy
= NULL
;
4212 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4214 asection
*asec
, *ssec
;
4216 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4217 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4219 /* If we have a difference between two different, non-absolute symbols
4220 we must generate two relocs (one for each symbol) and allow the
4221 linker to resolve them - relaxation may change the distances between
4222 symbols, even local symbols defined in the same section.
4224 Unfortunately we cannot do this with assembler generated local labels
4225 because there can be multiple incarnations of the same label, with
4226 exactly the same name, in any given section and the linker will have
4227 no way to identify the correct one. Instead we just have to hope
4228 that no relaxation will occur between the local label and the other
4229 symbol in the expression.
4231 Similarly we have to compute differences between symbols in the .eh_frame
4232 section as the linker is not smart enough to apply relocations there
4233 before attempting to process it. */
4234 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4235 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4236 && strcmp (ssec
->name
, ".eh_frame") != 0
4237 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4238 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4240 arelent
* reloc2
= XNEW (arelent
);
4245 reloc2
->address
= reloc
->address
;
4246 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4247 BFD_RELOC_MSP430_SYM_DIFF
);
4248 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4250 if (ssec
== absolute_section
)
4251 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4254 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4255 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4258 reloc
->addend
= fixp
->fx_offset
;
4259 if (asec
== absolute_section
)
4261 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4262 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4266 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4267 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4276 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4278 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4279 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4281 switch (fixp
->fx_r_type
)
4284 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4288 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4292 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4296 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4301 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4312 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4313 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4315 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4316 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4318 md_number_to_chars (fixpos
, amount
, 2);
4323 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4324 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4325 reloc
->addend
= fixp
->fx_offset
;
4327 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4328 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4329 reloc
->address
= fixp
->fx_offset
;
4336 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4337 asection
* segment_type ATTRIBUTE_UNUSED
)
4339 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4341 /* This is a jump -> pcrel mode. Nothing to do much here.
4342 Return value == 2. */
4344 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4346 else if (fragP
->fr_symbol
)
4348 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4349 an absolute segment, we don't know a displacement until we link
4350 object files. So it will always be long. This also applies to
4351 labels in a subsegment of current. Liker may relax it to short
4352 jump later. Return value == 8. */
4354 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4358 /* We know the abs value. may be it is a jump to fixed address.
4359 Impossible in our case, cause all constants already handled. */
4361 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4364 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4368 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4369 asection
* sec ATTRIBUTE_UNUSED
,
4375 struct rcodes_s
* cc
= NULL
;
4376 struct hcodes_s
* hc
= NULL
;
4378 switch (fragP
->fr_subtype
)
4380 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4381 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4382 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4383 /* We do not have to convert anything here.
4384 Just apply a fix. */
4385 rela
= BFD_RELOC_MSP430_10_PCREL
;
4388 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4389 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4390 /* Convert uncond branch jmp lab -> br lab. */
4391 if (target_is_430x ())
4392 cc
= msp430x_rcodes
+ 7;
4394 cc
= msp430_rcodes
+ 7;
4395 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4396 bfd_putl16 (cc
->lop0
, where
);
4397 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4401 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4402 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4404 /* Other simple branches. */
4405 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4408 /* Find actual instruction. */
4409 if (target_is_430x ())
4411 for (i
= 0; i
< 7 && !cc
; i
++)
4412 if (msp430x_rcodes
[i
].sop
== insn
)
4413 cc
= msp430x_rcodes
+ i
;
4417 for (i
= 0; i
< 7 && !cc
; i
++)
4418 if (msp430_rcodes
[i
].sop
== insn
)
4419 cc
= & msp430_rcodes
[i
];
4422 if (!cc
|| !cc
->name
)
4423 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4424 __FUNCTION__
, (long) insn
);
4425 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4426 bfd_putl16 (cc
->lop0
, where
);
4427 bfd_putl16 (cc
->lop1
, where
+ 2);
4428 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4433 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4434 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4435 if (target_is_430x ())
4436 cc
= msp430x_rcodes
+ 6;
4438 cc
= msp430_rcodes
+ 6;
4439 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4440 bfd_putl16 (cc
->lop0
, where
);
4441 bfd_putl16 (cc
->lop1
, where
+ 2);
4442 bfd_putl16 (cc
->lop2
, where
+ 4);
4443 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4447 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4449 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4452 if (target_is_430x ())
4454 for (i
= 0; i
< 4 && !hc
; i
++)
4455 if (msp430x_hcodes
[i
].op1
== insn
)
4456 hc
= msp430x_hcodes
+ i
;
4460 for (i
= 0; i
< 4 && !hc
; i
++)
4461 if (msp430_hcodes
[i
].op1
== insn
)
4462 hc
= &msp430_hcodes
[i
];
4464 if (!hc
|| !hc
->name
)
4465 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4466 __FUNCTION__
, (long) insn
);
4467 rela
= BFD_RELOC_MSP430_10_PCREL
;
4468 /* Apply a fix for a first label if necessary.
4469 another fix will be applied to the next word of insn anyway. */
4471 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4472 fragP
->fr_offset
, TRUE
, rela
);
4478 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4479 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4481 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4484 if (target_is_430x ())
4486 for (i
= 0; i
< 4 && !hc
; i
++)
4487 if (msp430x_hcodes
[i
].op1
== insn
)
4488 hc
= msp430x_hcodes
+ i
;
4492 for (i
= 0; i
< 4 && !hc
; i
++)
4493 if (msp430_hcodes
[i
].op1
== insn
)
4494 hc
= & msp430_hcodes
[i
];
4496 if (!hc
|| !hc
->name
)
4497 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4498 __FUNCTION__
, (long) insn
);
4499 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4500 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4501 bfd_putl16 (hc
->lop0
, where
);
4502 bfd_putl16 (hc
->lop1
, where
+ 2);
4503 bfd_putl16 (hc
->lop2
, where
+ 4);
4509 as_fatal (_("internal inconsistency problem in %s: %lx"),
4510 __FUNCTION__
, (long) fragP
->fr_subtype
);
4514 /* Now apply fix. */
4515 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4516 fragP
->fr_offset
, TRUE
, rela
);
4517 /* Just fixed 2 bytes. */
4521 /* Relax fragment. Mostly stolen from hc11 and mcore
4522 which arches I think I know. */
4525 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4526 long stretch ATTRIBUTE_UNUSED
)
4531 const relax_typeS
*this_type
;
4532 const relax_typeS
*start_type
;
4533 relax_substateT next_state
;
4534 relax_substateT this_state
;
4535 const relax_typeS
*table
= md_relax_table
;
4537 /* Nothing to be done if the frag has already max size. */
4538 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4539 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4542 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4544 symbolP
= fragP
->fr_symbol
;
4545 if (symbol_resolved_p (symbolP
))
4546 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4548 /* We know the offset. calculate a distance. */
4549 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4552 if (!msp430_enable_relax
)
4554 /* Relaxation is not enabled. So, make all jump as long ones
4555 by setting 'aim' to quite high value. */
4559 this_state
= fragP
->fr_subtype
;
4560 start_type
= this_type
= table
+ this_state
;
4564 /* Look backwards. */
4565 for (next_state
= this_type
->rlx_more
; next_state
;)
4566 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4570 /* Grow to next state. */
4571 this_state
= next_state
;
4572 this_type
= table
+ this_state
;
4573 next_state
= this_type
->rlx_more
;
4578 /* Look forwards. */
4579 for (next_state
= this_type
->rlx_more
; next_state
;)
4580 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4584 /* Grow to next state. */
4585 this_state
= next_state
;
4586 this_type
= table
+ this_state
;
4587 next_state
= this_type
->rlx_more
;
4591 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4593 fragP
->fr_subtype
= this_state
;
4597 /* Return FALSE if the fixup in fixp should be left alone and not
4598 adjusted. We return FALSE here so that linker relaxation will
4602 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4604 /* If the symbol is in a non-code section then it should be OK. */
4606 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4612 /* Set the contents of the .MSP430.attributes section. */
4615 msp430_md_end (void)
4618 as_warn ("assembly finished without a possibly needed NOP instruction");
4620 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4621 target_is_430x () ? 2 : 1);
4623 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4624 large_model
? 2 : 1);
4626 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4627 large_model
? 2 : 1);
4630 /* Returns FALSE if there is a msp430 specific reason why the
4631 subtraction of two same-section symbols cannot be computed by
4635 msp430_allow_local_subtract (expressionS
* left
,
4636 expressionS
* right
,
4639 /* If the symbols are not in a code section then they are OK. */
4640 if ((section
->flags
& SEC_CODE
) == 0)
4643 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4646 if (left
->X_add_symbol
== right
->X_add_symbol
)
4649 /* We have to assume that there may be instructions between the
4650 two symbols and that relaxation may increase the distance between