1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2015 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 /* Set linkrelax here to avoid fixups in most sections. */
75 /* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
86 lt < jl jge +4; br lab
87 ltu < jlo lhs +4; br lab
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
99 'u' means unsigned compares
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
109 int index
; /* Corresponding insn_opnumb. */
110 int sop
; /* Opcode if jump length is short. */
111 long lpos
; /* Label position. */
112 long lop0
; /* Opcode 1 _word_ (16 bits). */
113 long lop1
; /* Opcode second word. */
114 long lop2
; /* Opcode third word. */
117 #define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
120 static struct rcodes_s msp430_rcodes
[] =
122 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
134 #define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
137 static struct rcodes_s msp430x_rcodes
[] =
139 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
140 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
141 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
142 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
143 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
144 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
145 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
146 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
151 /* More difficult than above and they have format 5.
154 =================================================================
155 gt > jeq +2; jge label jeq +6; jl +4; br label
156 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
157 leu <= jeq label; jlo label jeq +2; jhs +4; br label
158 le <= jeq label; jl label jeq +2; jge +4; br label
159 ================================================================= */
164 int index
; /* Corresponding insn_opnumb. */
165 int tlab
; /* Number of labels in short mode. */
166 int op0
; /* Opcode for first word of short jump. */
167 int op1
; /* Opcode for second word of short jump. */
168 int lop0
; /* Opcodes for long jump mode. */
173 static struct hcodes_s msp430_hcodes
[] =
175 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
176 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
177 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
178 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
182 static struct hcodes_s msp430x_hcodes
[] =
184 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
185 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
186 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
187 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
191 const char comment_chars
[] = ";";
192 const char line_comment_chars
[] = "#";
193 const char line_separator_chars
[] = "{";
194 const char EXP_CHARS
[] = "eE";
195 const char FLT_CHARS
[] = "dD";
197 /* Handle long expressions. */
198 extern LITTLENUM_TYPE generic_bignum
[];
200 static struct hash_control
*msp430_hash
;
203 #define STATE_UNCOND_BRANCH 1 /* jump */
204 #define STATE_NOOV_BRANCH 3 /* bltn */
205 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
206 #define STATE_EMUL_BRANCH 4
215 #define STATE_BITS10 1 /* wild guess. short jump */
216 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
217 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
219 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
220 #define RELAX_STATE(s) ((s) & 3)
221 #define RELAX_LEN(s) ((s) >> 2)
222 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
224 relax_typeS md_relax_table
[] =
232 /* Unconditional jump. */
234 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
235 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
236 {1, 1, CUBL
, 0}, /* state undef */
238 /* Simple branches. */
240 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
241 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
244 /* blt no overflow branch. */
246 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
247 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
250 /* Emulated branches. */
252 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
253 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
258 #define MAX_OP_LEN 4096
267 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
269 static inline bfd_boolean
270 target_is_430x (void)
272 return selected_isa
>= MSP_ISA_430X
;
275 static inline bfd_boolean
276 target_is_430xv2 (void)
278 return selected_isa
== MSP_ISA_430Xv2
;
281 /* Generate an absolute 16-bit relocation.
282 For the 430X we generate a relocation without linker range checking
283 if the value is being used in an extended (ie 20-bit) instruction,
284 otherwise if have a shifted expression we use a HI reloc.
285 For the 430 we generate a relocation without assembler range checking
286 if we are handling an immediate value or a byte-width instruction. */
288 #undef CHECK_RELOC_MSP430
289 #define CHECK_RELOC_MSP430(OP) \
293 : ((OP).vshift == 1) \
294 ? BFD_RELOC_MSP430_ABS_HI16 \
295 : BFD_RELOC_MSP430X_ABS16) \
296 : ((imm_op || byte_op) \
297 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
299 /* Generate a 16-bit pc-relative relocation.
300 For the 430X we generate a relocation without linkwer range checking.
301 For the 430 we generate a relocation without assembler range checking
302 if we are handling an immediate value or a byte-width instruction. */
303 #undef CHECK_RELOC_MSP430_PCREL
304 #define CHECK_RELOC_MSP430_PCREL \
306 ? BFD_RELOC_MSP430X_PCR16 \
307 : (imm_op || byte_op) \
308 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
310 /* Profiling capability:
311 It is a performance hit to use gcc's profiling approach for this tiny target.
312 Even more -- jtag hardware facility does not perform any profiling functions.
313 However we've got gdb's built-in simulator where we can do anything.
314 Therefore my suggestion is:
316 We define new section ".profiler" which holds all profiling information.
317 We define new pseudo operation .profiler which will instruct assembler to
318 add new profile entry to the object file. Profile should take place at the
323 .profiler flags,function_to_profile [, cycle_corrector, extra]
325 where 'flags' is a combination of the following chars:
328 i - function is in Init section
329 f - function is in Fini section
331 c - libC standard call
332 d - stack value Demand (saved at run-time in simulator)
333 I - Interrupt service routine
338 j - long Jump/ sjlj unwind
339 a - an Arbitrary code fragment
340 t - exTra parameter saved (constant value like frame size)
341 '""' optional: "sil" == sil
343 function_to_profile - function's address
344 cycle_corrector - a value which should be added to the cycle
345 counter, zero if omitted
346 extra - some extra parameter, zero if omitted.
349 ------------------------------
353 .LFrameOffset_fxx=0x08
354 .profiler "scdP", fxx ; function entry.
355 ; we also demand stack value to be displayed
360 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
361 ; (this is a prologue end)
362 ; note, that spare var filled with the frame size
365 .profiler cdE,fxx ; check stack
370 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
371 ret ; cause 'ret' insn takes 3 cycles
372 -------------------------------
374 This profiling approach does not produce any overhead and
376 So, even profiled code can be uploaded to the MCU. */
377 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
378 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
379 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
380 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
381 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
382 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
383 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
384 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
385 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
386 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
387 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
388 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
389 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
390 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
391 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
392 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
405 for (; x
; x
= x
>> 1)
412 /* Parse ordinary expression. */
415 parse_exp (char * s
, expressionS
* op
)
417 input_line_pointer
= s
;
419 if (op
->X_op
== O_absent
)
420 as_bad (_("missing operand"));
421 return input_line_pointer
;
425 /* Delete spaces from s: X ( r 1 2) => X(r12). */
428 del_spaces (char * s
)
436 while (ISSPACE (*m
) && *m
)
438 memmove (s
, m
, strlen (m
) + 1);
446 skip_space (char * s
)
453 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
456 extract_operand (char * from
, char * to
, int limit
)
460 /* Drop leading whitespace. */
461 from
= skip_space (from
);
463 while (size
< limit
&& *from
)
465 *(to
+ size
) = *from
;
466 if (*from
== ',' || *from
== ';' || *from
== '\n')
481 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
498 s
= input_line_pointer
;
499 end
= input_line_pointer
;
501 while (*end
&& *end
!= '\n')
504 while (*s
&& *s
!= '\n')
515 as_bad (_(".profiler pseudo requires at least two operands."));
516 input_line_pointer
= end
;
520 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
529 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
532 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
535 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
538 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
541 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
544 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
547 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
550 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
553 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
556 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
559 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
562 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
565 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
568 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
571 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
574 as_warn (_("unknown profiling flag - ignored."));
581 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
582 | MSP430_PROFILER_FLAG_EXIT
))
583 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
584 | MSP430_PROFILER_FLAG_PROLEND
585 | MSP430_PROFILER_FLAG_EPISTART
586 | MSP430_PROFILER_FLAG_EPIEND
))
587 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
588 | MSP430_PROFILER_FLAG_FINISECT
))))
590 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
591 input_line_pointer
= end
;
595 /* Generate temp symbol which denotes current location. */
596 if (now_seg
== absolute_section
) /* Paranoia ? */
598 exp1
.X_op
= O_constant
;
599 exp1
.X_add_number
= abs_section_offset
;
600 as_warn (_("profiling in absolute section?"));
604 exp1
.X_op
= O_symbol
;
605 exp1
.X_add_symbol
= symbol_temp_new_now ();
606 exp1
.X_add_number
= 0;
609 /* Generate a symbol which holds flags value. */
610 exp
.X_op
= O_constant
;
611 exp
.X_add_number
= p_flags
;
613 /* Save current section. */
617 /* Now go to .profiler section. */
618 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
621 emit_expr (& exp
, 2);
623 /* Save label value. */
624 emit_expr (& exp1
, 2);
628 /* Now get profiling info. */
629 halt
= extract_operand (input_line_pointer
, str
, 1024);
630 /* Process like ".word xxx" directive. */
631 parse_exp (str
, & exp
);
632 emit_expr (& exp
, 2);
633 input_line_pointer
= halt
;
636 /* Fill the rest with zeros. */
637 exp
.X_op
= O_constant
;
638 exp
.X_add_number
= 0;
640 emit_expr (& exp
, 2);
642 /* Return to current section. */
643 subseg_set (seg
, subseg
);
647 extract_word (char * from
, char * to
, int limit
)
652 /* Drop leading whitespace. */
653 from
= skip_space (from
);
656 /* Find the op code end. */
657 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
659 to
[size
++] = *op_end
++;
660 if (size
+ 1 >= limit
)
668 #define OPTION_MMCU 'm'
669 #define OPTION_RELAX 'Q'
670 #define OPTION_POLYMORPHS 'P'
671 #define OPTION_LARGE 'l'
672 static bfd_boolean large_model
= FALSE
;
673 #define OPTION_NO_INTR_NOPS 'N'
674 #define OPTION_INTR_NOPS 'n'
675 static bfd_boolean gen_interrupt_nops
= FALSE
;
676 #define OPTION_WARN_INTR_NOPS 'y'
677 #define OPTION_NO_WARN_INTR_NOPS 'Y'
678 static bfd_boolean warn_interrupt_nops
= TRUE
;
679 #define OPTION_MCPU 'c'
680 #define OPTION_MOVE_DATA 'd'
681 static bfd_boolean move_data
= FALSE
;
685 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
686 OPTION_SILICON_ERRATA_WARN
,
689 static unsigned int silicon_errata_fix
= 0;
690 static unsigned int silicon_errata_warn
= 0;
691 #define SILICON_ERRATA_CPU4 (1 << 0)
692 #define SILICON_ERRATA_CPU8 (1 << 1)
693 #define SILICON_ERRATA_CPU11 (1 << 2)
694 #define SILICON_ERRATA_CPU12 (1 << 3)
695 #define SILICON_ERRATA_CPU13 (1 << 4)
696 #define SILICON_ERRATA_CPU19 (1 << 5)
697 #define SILICON_ERRATA_CPU42 (1 << 6)
698 #define SILICON_ERRATA_CPU42_PLUS (1 << 7)
701 msp430_set_arch (int option
)
703 char *str
= (char *) alloca (32); /* 32 for good measure. */
705 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
707 md_parse_option (option
, str
);
708 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
709 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
712 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
713 Keep these two structures in sync.
714 The data in this structure has been extracted from the devices.csv file
715 released by TI, updated as of 8 October 2015. */
717 struct msp430_mcu_data
720 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
721 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
725 { "cc430f5123",2,8 },
726 { "cc430f5125",2,8 },
727 { "cc430f5133",2,8 },
728 { "cc430f5135",2,8 },
729 { "cc430f5137",2,8 },
730 { "cc430f5143",2,8 },
731 { "cc430f5145",2,8 },
732 { "cc430f5147",2,8 },
733 { "cc430f6125",2,8 },
734 { "cc430f6126",2,8 },
735 { "cc430f6127",2,8 },
736 { "cc430f6135",2,8 },
737 { "cc430f6137",2,8 },
738 { "cc430f6143",2,8 },
739 { "cc430f6145",2,8 },
740 { "cc430f6147",2,8 },
741 { "msp430afe221",0,2 },
742 { "msp430afe222",0,2 },
743 { "msp430afe223",0,2 },
744 { "msp430afe231",0,2 },
745 { "msp430afe232",0,2 },
746 { "msp430afe233",0,2 },
747 { "msp430afe251",0,2 },
748 { "msp430afe252",0,2 },
749 { "msp430afe253",0,2 },
750 { "msp430bt5190",2,8 },
751 { "msp430c091",0,0 },
752 { "msp430c092",0,0 },
753 { "msp430c111",0,0 },
754 { "msp430c1111",0,0 },
755 { "msp430c112",0,0 },
756 { "msp430c1121",0,0 },
757 { "msp430c1331",0,0 },
758 { "msp430c1351",0,0 },
759 { "msp430c311s",0,0 },
760 { "msp430c312",0,0 },
761 { "msp430c313",0,0 },
762 { "msp430c314",0,0 },
763 { "msp430c315",0,0 },
764 { "msp430c323",0,0 },
765 { "msp430c325",0,0 },
766 { "msp430c336",0,1 },
767 { "msp430c337",0,1 },
768 { "msp430c412",0,0 },
769 { "msp430c413",0,0 },
770 { "msp430cg4616",1,1 },
771 { "msp430cg4617",1,1 },
772 { "msp430cg4618",1,1 },
773 { "msp430cg4619",1,1 },
774 { "msp430e112",0,0 },
775 { "msp430e313",0,0 },
776 { "msp430e315",0,0 },
777 { "msp430e325",0,0 },
778 { "msp430e337",0,1 },
779 { "msp430f110",0,0 },
780 { "msp430f1101",0,0 },
781 { "msp430f1101a",0,0 },
782 { "msp430f1111",0,0 },
783 { "msp430f1111a",0,0 },
784 { "msp430f112",0,0 },
785 { "msp430f1121",0,0 },
786 { "msp430f1121a",0,0 },
787 { "msp430f1122",0,0 },
788 { "msp430f1132",0,0 },
789 { "msp430f122",0,0 },
790 { "msp430f1222",0,0 },
791 { "msp430f123",0,0 },
792 { "msp430f1232",0,0 },
793 { "msp430f133",0,0 },
794 { "msp430f135",0,0 },
795 { "msp430f147",0,1 },
796 { "msp430f1471",0,1 },
797 { "msp430f148",0,1 },
798 { "msp430f1481",0,1 },
799 { "msp430f149",0,1 },
800 { "msp430f1491",0,1 },
801 { "msp430f155",0,0 },
802 { "msp430f156",0,0 },
803 { "msp430f157",0,0 },
804 { "msp430f1610",0,1 },
805 { "msp430f1611",0,1 },
806 { "msp430f1612",0,1 },
807 { "msp430f167",0,1 },
808 { "msp430f168",0,1 },
809 { "msp430f169",0,1 },
810 { "msp430f2001",0,0 },
811 { "msp430f2002",0,0 },
812 { "msp430f2003",0,0 },
813 { "msp430f2011",0,0 },
814 { "msp430f2012",0,0 },
815 { "msp430f2013",0,0 },
816 { "msp430f2101",0,0 },
817 { "msp430f2111",0,0 },
818 { "msp430f2112",0,0 },
819 { "msp430f2121",0,0 },
820 { "msp430f2122",0,0 },
821 { "msp430f2131",0,0 },
822 { "msp430f2132",0,0 },
823 { "msp430f2232",0,0 },
824 { "msp430f2234",0,0 },
825 { "msp430f2252",0,0 },
826 { "msp430f2254",0,0 },
827 { "msp430f2272",0,0 },
828 { "msp430f2274",0,0 },
829 { "msp430f233",0,2 },
830 { "msp430f2330",0,2 },
831 { "msp430f235",0,2 },
832 { "msp430f2350",0,2 },
833 { "msp430f2370",0,2 },
834 { "msp430f2410",0,2 },
835 { "msp430f2416",1,2 },
836 { "msp430f2417",1,2 },
837 { "msp430f2418",1,2 },
838 { "msp430f2419",1,2 },
839 { "msp430f247",0,2 },
840 { "msp430f2471",0,2 },
841 { "msp430f248",0,2 },
842 { "msp430f2481",0,2 },
843 { "msp430f249",0,2 },
844 { "msp430f2491",0,2 },
845 { "msp430f2616",1,2 },
846 { "msp430f2617",1,2 },
847 { "msp430f2618",1,2 },
848 { "msp430f2619",1,2 },
849 { "msp430f412",0,0 },
850 { "msp430f413",0,0 },
851 { "msp430f4132",0,0 },
852 { "msp430f415",0,0 },
853 { "msp430f4152",0,0 },
854 { "msp430f417",0,0 },
855 { "msp430f423",0,1 },
856 { "msp430f423a",0,1 },
857 { "msp430f425",0,1 },
858 { "msp430f4250",0,0 },
859 { "msp430f425a",0,1 },
860 { "msp430f4260",0,0 },
861 { "msp430f427",0,1 },
862 { "msp430f4270",0,0 },
863 { "msp430f427a",0,1 },
864 { "msp430f435",0,0 },
865 { "msp430f4351",0,0 },
866 { "msp430f436",0,0 },
867 { "msp430f4361",0,0 },
868 { "msp430f437",0,0 },
869 { "msp430f4371",0,0 },
870 { "msp430f438",0,0 },
871 { "msp430f439",0,0 },
872 { "msp430f447",0,1 },
873 { "msp430f448",0,1 },
874 { "msp430f4481",0,1 },
875 { "msp430f449",0,1 },
876 { "msp430f4491",0,1 },
877 { "msp430f4616",1,1 },
878 { "msp430f46161",1,1 },
879 { "msp430f4617",1,1 },
880 { "msp430f46171",1,1 },
881 { "msp430f4618",1,1 },
882 { "msp430f46181",1,1 },
883 { "msp430f4619",1,1 },
884 { "msp430f46191",1,1 },
885 { "msp430f47126",1,4 },
886 { "msp430f47127",1,4 },
887 { "msp430f47163",1,4 },
888 { "msp430f47166",1,4 },
889 { "msp430f47167",1,4 },
890 { "msp430f47173",1,4 },
891 { "msp430f47176",1,4 },
892 { "msp430f47177",1,4 },
893 { "msp430f47183",1,4 },
894 { "msp430f47186",1,4 },
895 { "msp430f47187",1,4 },
896 { "msp430f47193",1,4 },
897 { "msp430f47196",1,4 },
898 { "msp430f47197",1,4 },
899 { "msp430f477",0,0 },
900 { "msp430f478",0,0 },
901 { "msp430f4783",0,4 },
902 { "msp430f4784",0,4 },
903 { "msp430f479",0,0 },
904 { "msp430f4793",0,4 },
905 { "msp430f4794",0,4 },
906 { "msp430f5131",2,8 },
907 { "msp430f5132",2,8 },
908 { "msp430f5151",2,8 },
909 { "msp430f5152",2,8 },
910 { "msp430f5171",2,8 },
911 { "msp430f5172",2,8 },
912 { "msp430f5212",2,8 },
913 { "msp430f5213",2,8 },
914 { "msp430f5214",2,8 },
915 { "msp430f5217",2,8 },
916 { "msp430f5218",2,8 },
917 { "msp430f5219",2,8 },
918 { "msp430f5222",2,8 },
919 { "msp430f5223",2,8 },
920 { "msp430f5224",2,8 },
921 { "msp430f5227",2,8 },
922 { "msp430f5228",2,8 },
923 { "msp430f5229",2,8 },
924 { "msp430f5232",2,8 },
925 { "msp430f5234",2,8 },
926 { "msp430f5237",2,8 },
927 { "msp430f5239",2,8 },
928 { "msp430f5242",2,8 },
929 { "msp430f5244",2,8 },
930 { "msp430f5247",2,8 },
931 { "msp430f5249",2,8 },
932 { "msp430f5252",2,8 },
933 { "msp430f5253",2,8 },
934 { "msp430f5254",2,8 },
935 { "msp430f5255",2,8 },
936 { "msp430f5256",2,8 },
937 { "msp430f5257",2,8 },
938 { "msp430f5258",2,8 },
939 { "msp430f5259",2,8 },
940 { "msp430f5304",2,8 },
941 { "msp430f5308",2,8 },
942 { "msp430f5309",2,8 },
943 { "msp430f5310",2,8 },
944 { "msp430f5324",2,8 },
945 { "msp430f5325",2,8 },
946 { "msp430f5326",2,8 },
947 { "msp430f5327",2,8 },
948 { "msp430f5328",2,8 },
949 { "msp430f5329",2,8 },
950 { "msp430f5333",2,8 },
951 { "msp430f5335",2,8 },
952 { "msp430f5336",2,8 },
953 { "msp430f5338",2,8 },
954 { "msp430f5340",2,8 },
955 { "msp430f5341",2,8 },
956 { "msp430f5342",2,8 },
957 { "msp430f5358",2,8 },
958 { "msp430f5359",2,8 },
959 { "msp430f5418",2,8 },
960 { "msp430f5418a",2,8 },
961 { "msp430f5419",2,8 },
962 { "msp430f5419a",2,8 },
963 { "msp430f5435",2,8 },
964 { "msp430f5435a",2,8 },
965 { "msp430f5436",2,8 },
966 { "msp430f5436a",2,8 },
967 { "msp430f5437",2,8 },
968 { "msp430f5437a",2,8 },
969 { "msp430f5438",2,8 },
970 { "msp430f5438a",2,8 },
971 { "msp430f5500",2,8 },
972 { "msp430f5501",2,8 },
973 { "msp430f5502",2,8 },
974 { "msp430f5503",2,8 },
975 { "msp430f5504",2,8 },
976 { "msp430f5505",2,8 },
977 { "msp430f5506",2,8 },
978 { "msp430f5507",2,8 },
979 { "msp430f5508",2,8 },
980 { "msp430f5509",2,8 },
981 { "msp430f5510",2,8 },
982 { "msp430f5513",2,8 },
983 { "msp430f5514",2,8 },
984 { "msp430f5515",2,8 },
985 { "msp430f5517",2,8 },
986 { "msp430f5519",2,8 },
987 { "msp430f5521",2,8 },
988 { "msp430f5522",2,8 },
989 { "msp430f5524",2,8 },
990 { "msp430f5525",2,8 },
991 { "msp430f5526",2,8 },
992 { "msp430f5527",2,8 },
993 { "msp430f5528",2,8 },
994 { "msp430f5529",2,8 },
995 { "msp430f5630",2,8 },
996 { "msp430f5631",2,8 },
997 { "msp430f5632",2,8 },
998 { "msp430f5633",2,8 },
999 { "msp430f5634",2,8 },
1000 { "msp430f5635",2,8 },
1001 { "msp430f5636",2,8 },
1002 { "msp430f5637",2,8 },
1003 { "msp430f5638",2,8 },
1004 { "msp430f5658",2,8 },
1005 { "msp430f5659",2,8 },
1006 { "msp430f5xx_6xxgeneric",2,8 },
1007 { "msp430f6433",2,8 },
1008 { "msp430f6435",2,8 },
1009 { "msp430f6436",2,8 },
1010 { "msp430f6438",2,8 },
1011 { "msp430f6458",2,8 },
1012 { "msp430f6459",2,8 },
1013 { "msp430f6630",2,8 },
1014 { "msp430f6631",2,8 },
1015 { "msp430f6632",2,8 },
1016 { "msp430f6633",2,8 },
1017 { "msp430f6634",2,8 },
1018 { "msp430f6635",2,8 },
1019 { "msp430f6636",2,8 },
1020 { "msp430f6637",2,8 },
1021 { "msp430f6638",2,8 },
1022 { "msp430f6658",2,8 },
1023 { "msp430f6659",2,8 },
1024 { "msp430f6720",2,8 },
1025 { "msp430f6720a",2,8 },
1026 { "msp430f6721",2,8 },
1027 { "msp430f6721a",2,8 },
1028 { "msp430f6723",2,8 },
1029 { "msp430f6723a",2,8 },
1030 { "msp430f6724",2,8 },
1031 { "msp430f6724a",2,8 },
1032 { "msp430f6725",2,8 },
1033 { "msp430f6725a",2,8 },
1034 { "msp430f6726",2,8 },
1035 { "msp430f6726a",2,8 },
1036 { "msp430f6730",2,8 },
1037 { "msp430f6730a",2,8 },
1038 { "msp430f6731",2,8 },
1039 { "msp430f6731a",2,8 },
1040 { "msp430f6733",2,8 },
1041 { "msp430f6733a",2,8 },
1042 { "msp430f6734",2,8 },
1043 { "msp430f6734a",2,8 },
1044 { "msp430f6735",2,8 },
1045 { "msp430f6735a",2,8 },
1046 { "msp430f6736",2,8 },
1047 { "msp430f6736a",2,8 },
1048 { "msp430f6745",2,8 },
1049 { "msp430f67451",2,8 },
1050 { "msp430f67451a",2,8 },
1051 { "msp430f6745a",2,8 },
1052 { "msp430f6746",2,8 },
1053 { "msp430f67461",2,8 },
1054 { "msp430f67461a",2,8 },
1055 { "msp430f6746a",2,8 },
1056 { "msp430f6747",2,8 },
1057 { "msp430f67471",2,8 },
1058 { "msp430f67471a",2,8 },
1059 { "msp430f6747a",2,8 },
1060 { "msp430f6748",2,8 },
1061 { "msp430f67481",2,8 },
1062 { "msp430f67481a",2,8 },
1063 { "msp430f6748a",2,8 },
1064 { "msp430f6749",2,8 },
1065 { "msp430f67491",2,8 },
1066 { "msp430f67491a",2,8 },
1067 { "msp430f6749a",2,8 },
1068 { "msp430f67621",2,8 },
1069 { "msp430f67621a",2,8 },
1070 { "msp430f67641",2,8 },
1071 { "msp430f67641a",2,8 },
1072 { "msp430f6765",2,8 },
1073 { "msp430f67651",2,8 },
1074 { "msp430f67651a",2,8 },
1075 { "msp430f6765a",2,8 },
1076 { "msp430f6766",2,8 },
1077 { "msp430f67661",2,8 },
1078 { "msp430f67661a",2,8 },
1079 { "msp430f6766a",2,8 },
1080 { "msp430f6767",2,8 },
1081 { "msp430f67671",2,8 },
1082 { "msp430f67671a",2,8 },
1083 { "msp430f6767a",2,8 },
1084 { "msp430f6768",2,8 },
1085 { "msp430f67681",2,8 },
1086 { "msp430f67681a",2,8 },
1087 { "msp430f6768a",2,8 },
1088 { "msp430f6769",2,8 },
1089 { "msp430f67691",2,8 },
1090 { "msp430f67691a",2,8 },
1091 { "msp430f6769a",2,8 },
1092 { "msp430f6775",2,8 },
1093 { "msp430f67751",2,8 },
1094 { "msp430f67751a",2,8 },
1095 { "msp430f6775a",2,8 },
1096 { "msp430f6776",2,8 },
1097 { "msp430f67761",2,8 },
1098 { "msp430f67761a",2,8 },
1099 { "msp430f6776a",2,8 },
1100 { "msp430f6777",2,8 },
1101 { "msp430f67771",2,8 },
1102 { "msp430f67771a",2,8 },
1103 { "msp430f6777a",2,8 },
1104 { "msp430f6778",2,8 },
1105 { "msp430f67781",2,8 },
1106 { "msp430f67781a",2,8 },
1107 { "msp430f6778a",2,8 },
1108 { "msp430f6779",2,8 },
1109 { "msp430f67791",2,8 },
1110 { "msp430f67791a",2,8 },
1111 { "msp430f6779a",2,8 },
1112 { "msp430fe423",0,0 },
1113 { "msp430fe4232",0,0 },
1114 { "msp430fe423a",0,0 },
1115 { "msp430fe4242",0,0 },
1116 { "msp430fe425",0,0 },
1117 { "msp430fe4252",0,0 },
1118 { "msp430fe425a",0,0 },
1119 { "msp430fe427",0,0 },
1120 { "msp430fe4272",0,0 },
1121 { "msp430fe427a",0,0 },
1122 { "msp430fg4250",0,0 },
1123 { "msp430fg4260",0,0 },
1124 { "msp430fg4270",0,0 },
1125 { "msp430fg437",0,0 },
1126 { "msp430fg438",0,0 },
1127 { "msp430fg439",0,0 },
1128 { "msp430fg4616",1,1 },
1129 { "msp430fg4617",1,1 },
1130 { "msp430fg4618",1,1 },
1131 { "msp430fg4619",1,1 },
1132 { "msp430fg477",0,0 },
1133 { "msp430fg478",0,0 },
1134 { "msp430fg479",0,0 },
1135 { "msp430fg6425",2,8 },
1136 { "msp430fg6426",2,8 },
1137 { "msp430fg6625",2,8 },
1138 { "msp430fg6626",2,8 },
1139 { "msp430fr2032",2,0 },
1140 { "msp430fr2033",2,0 },
1141 { "msp430fr2433",2,8 },
1142 { "msp430fr2xx_4xxgeneric",2,8 },
1143 { "msp430fr4131",2,0 },
1144 { "msp430fr4132",2,0 },
1145 { "msp430fr4133",2,0 },
1146 { "msp430fr5720",2,8 },
1147 { "msp430fr5721",2,8 },
1148 { "msp430fr5722",2,8 },
1149 { "msp430fr5723",2,8 },
1150 { "msp430fr5724",2,8 },
1151 { "msp430fr5725",2,8 },
1152 { "msp430fr5726",2,8 },
1153 { "msp430fr5727",2,8 },
1154 { "msp430fr5728",2,8 },
1155 { "msp430fr5729",2,8 },
1156 { "msp430fr5730",2,8 },
1157 { "msp430fr5731",2,8 },
1158 { "msp430fr5732",2,8 },
1159 { "msp430fr5733",2,8 },
1160 { "msp430fr5734",2,8 },
1161 { "msp430fr5735",2,8 },
1162 { "msp430fr5736",2,8 },
1163 { "msp430fr5737",2,8 },
1164 { "msp430fr5738",2,8 },
1165 { "msp430fr5739",2,8 },
1166 { "msp430fr57xxgeneric",2,8 },
1167 { "msp430fr5847",2,8 },
1168 { "msp430fr58471",2,8 },
1169 { "msp430fr5848",2,8 },
1170 { "msp430fr5849",2,8 },
1171 { "msp430fr5857",2,8 },
1172 { "msp430fr5858",2,8 },
1173 { "msp430fr5859",2,8 },
1174 { "msp430fr5867",2,8 },
1175 { "msp430fr58671",2,8 },
1176 { "msp430fr5868",2,8 },
1177 { "msp430fr5869",2,8 },
1178 { "msp430fr5870",2,8 },
1179 { "msp430fr5872",2,8 },
1180 { "msp430fr58721",2,8 },
1181 { "msp430fr5887",2,8 },
1182 { "msp430fr5888",2,8 },
1183 { "msp430fr5889",2,8 },
1184 { "msp430fr58891",2,8 },
1185 { "msp430fr5922",2,8 },
1186 { "msp430fr59221",2,8 },
1187 { "msp430fr5947",2,8 },
1188 { "msp430fr59471",2,8 },
1189 { "msp430fr5948",2,8 },
1190 { "msp430fr5949",2,8 },
1191 { "msp430fr5957",2,8 },
1192 { "msp430fr5958",2,8 },
1193 { "msp430fr5959",2,8 },
1194 { "msp430fr5967",2,8 },
1195 { "msp430fr5968",2,8 },
1196 { "msp430fr5969",2,8 },
1197 { "msp430fr59691",2,8 },
1198 { "msp430fr5970",2,8 },
1199 { "msp430fr5972",2,8 },
1200 { "msp430fr59721",2,8 },
1201 { "msp430fr5986",2,8 },
1202 { "msp430fr5987",2,8 },
1203 { "msp430fr5988",2,8 },
1204 { "msp430fr5989",2,8 },
1205 { "msp430fr59891",2,8 },
1206 { "msp430fr5xx_6xxgeneric",2,8 },
1207 { "msp430fr6820",2,8 },
1208 { "msp430fr6822",2,8 },
1209 { "msp430fr68221",2,8 },
1210 { "msp430fr6870",2,8 },
1211 { "msp430fr6872",2,8 },
1212 { "msp430fr68721",2,8 },
1213 { "msp430fr6877",2,8 },
1214 { "msp430fr6879",2,8 },
1215 { "msp430fr68791",2,8 },
1216 { "msp430fr6887",2,8 },
1217 { "msp430fr6888",2,8 },
1218 { "msp430fr6889",2,8 },
1219 { "msp430fr68891",2,8 },
1220 { "msp430fr6920",2,8 },
1221 { "msp430fr6922",2,8 },
1222 { "msp430fr69221",2,8 },
1223 { "msp430fr6927",2,8 },
1224 { "msp430fr69271",2,8 },
1225 { "msp430fr6928",2,8 },
1226 { "msp430fr6970",2,8 },
1227 { "msp430fr6972",2,8 },
1228 { "msp430fr69721",2,8 },
1229 { "msp430fr6977",2,8 },
1230 { "msp430fr6979",2,8 },
1231 { "msp430fr69791",2,8 },
1232 { "msp430fr6987",2,8 },
1233 { "msp430fr6988",2,8 },
1234 { "msp430fr6989",2,8 },
1235 { "msp430fr69891",2,8 },
1236 { "msp430fw423",0,0 },
1237 { "msp430fw425",0,0 },
1238 { "msp430fw427",0,0 },
1239 { "msp430fw428",0,0 },
1240 { "msp430fw429",0,0 },
1241 { "msp430g2001",0,0 },
1242 { "msp430g2101",0,0 },
1243 { "msp430g2102",0,0 },
1244 { "msp430g2111",0,0 },
1245 { "msp430g2112",0,0 },
1246 { "msp430g2113",0,0 },
1247 { "msp430g2121",0,0 },
1248 { "msp430g2131",0,0 },
1249 { "msp430g2132",0,0 },
1250 { "msp430g2152",0,0 },
1251 { "msp430g2153",0,0 },
1252 { "msp430g2201",0,0 },
1253 { "msp430g2202",0,0 },
1254 { "msp430g2203",0,0 },
1255 { "msp430g2210",0,0 },
1256 { "msp430g2211",0,0 },
1257 { "msp430g2212",0,0 },
1258 { "msp430g2213",0,0 },
1259 { "msp430g2221",0,0 },
1260 { "msp430g2230",0,0 },
1261 { "msp430g2231",0,0 },
1262 { "msp430g2232",0,0 },
1263 { "msp430g2233",0,0 },
1264 { "msp430g2252",0,0 },
1265 { "msp430g2253",0,0 },
1266 { "msp430g2302",0,0 },
1267 { "msp430g2303",0,0 },
1268 { "msp430g2312",0,0 },
1269 { "msp430g2313",0,0 },
1270 { "msp430g2332",0,0 },
1271 { "msp430g2333",0,0 },
1272 { "msp430g2352",0,0 },
1273 { "msp430g2353",0,0 },
1274 { "msp430g2402",0,0 },
1275 { "msp430g2403",0,0 },
1276 { "msp430g2412",0,0 },
1277 { "msp430g2413",0,0 },
1278 { "msp430g2432",0,0 },
1279 { "msp430g2433",0,0 },
1280 { "msp430g2444",0,0 },
1281 { "msp430g2452",0,0 },
1282 { "msp430g2453",0,0 },
1283 { "msp430g2513",0,0 },
1284 { "msp430g2533",0,0 },
1285 { "msp430g2544",0,0 },
1286 { "msp430g2553",0,0 },
1287 { "msp430g2744",0,0 },
1288 { "msp430g2755",0,0 },
1289 { "msp430g2855",0,0 },
1290 { "msp430g2955",0,0 },
1291 { "msp430i2020",0,2 },
1292 { "msp430i2021",0,2 },
1293 { "msp430i2030",0,2 },
1294 { "msp430i2031",0,2 },
1295 { "msp430i2040",0,2 },
1296 { "msp430i2041",0,2 },
1297 { "msp430i2xxgeneric",0,2 },
1298 { "msp430l092",0,0 },
1299 { "msp430p112",0,0 },
1300 { "msp430p313",0,0 },
1301 { "msp430p315",0,0 },
1302 { "msp430p315s",0,0 },
1303 { "msp430p325",0,0 },
1304 { "msp430p337",0,1 },
1305 { "msp430sl5438a",2,8 },
1306 { "msp430tch5e",0,0 },
1307 { "msp430xgeneric",2,8 },
1308 { "rf430f5144",2,8 },
1309 { "rf430f5155",2,8 },
1310 { "rf430f5175",2,8 },
1311 { "rf430frl152h",0,0 },
1312 { "rf430frl152h_rom",0,0 },
1313 { "rf430frl153h",0,0 },
1314 { "rf430frl153h_rom",0,0 },
1315 { "rf430frl154h",0,0 },
1316 { "rf430frl154h_rom",0,0 }
1320 md_parse_option (int c
, char * arg
)
1324 case OPTION_SILICON_ERRATA
:
1325 case OPTION_SILICON_ERRATA_WARN
:
1331 unsigned int length
;
1332 unsigned int bitfield
;
1335 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1336 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1337 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1338 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1339 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1340 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1341 { STRING_COMMA_LEN ("cpu42"), SILICON_ERRATA_CPU42
},
1342 { STRING_COMMA_LEN ("cpu42+"), SILICON_ERRATA_CPU42_PLUS
},
1347 for (i
= ARRAY_SIZE (erratas
); i
--;)
1348 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1350 if (c
== OPTION_SILICON_ERRATA
)
1351 silicon_errata_fix
|= erratas
[i
].bitfield
;
1353 silicon_errata_warn
|= erratas
[i
].bitfield
;
1354 arg
+= erratas
[i
].length
;
1359 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1365 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1375 as_fatal (_("MCU option requires a name\n"));
1377 if (strcasecmp ("msp430", arg
) == 0)
1378 selected_isa
= MSP_ISA_430
;
1379 else if (strcasecmp ("msp430xv2", arg
) == 0)
1380 selected_isa
= MSP_ISA_430Xv2
;
1381 else if (strcasecmp ("msp430x", arg
) == 0)
1382 selected_isa
= MSP_ISA_430X
;
1387 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1388 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1390 switch (msp430_mcu_data
[i
].revision
)
1392 case 0: selected_isa
= MSP_ISA_430
; break;
1393 case 1: selected_isa
= MSP_ISA_430X
; break;
1394 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1399 /* It is not an error if we do not match the MCU name. */
1403 if (strcmp (arg
, "430") == 0
1404 || strcasecmp (arg
, "msp430") == 0)
1405 selected_isa
= MSP_ISA_430
;
1406 else if (strcasecmp (arg
, "430x") == 0
1407 || strcasecmp (arg
, "msp430x") == 0)
1408 selected_isa
= MSP_ISA_430X
;
1409 else if (strcasecmp (arg
, "430xv2") == 0
1410 || strcasecmp (arg
, "msp430xv2") == 0)
1411 selected_isa
= MSP_ISA_430Xv2
;
1413 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1417 msp430_enable_relax
= 1;
1420 case OPTION_POLYMORPHS
:
1421 msp430_enable_polys
= 1;
1428 case OPTION_NO_INTR_NOPS
:
1429 gen_interrupt_nops
= FALSE
;
1431 case OPTION_INTR_NOPS
:
1432 gen_interrupt_nops
= TRUE
;
1435 case OPTION_WARN_INTR_NOPS
:
1436 warn_interrupt_nops
= TRUE
;
1438 case OPTION_NO_WARN_INTR_NOPS
:
1439 warn_interrupt_nops
= FALSE
;
1442 case OPTION_MOVE_DATA
:
1450 /* The intention here is to have the mere presence of these sections
1451 cause the object to have a reference to a well-known symbol. This
1452 reference pulls in the bits of the runtime (crt0) that initialize
1453 these sections. Thus, for example, the startup code to call
1454 memset() to initialize .bss will only be linked in when there is a
1455 non-empty .bss section. Otherwise, the call would exist but have a
1456 zero length parameter, which is a waste of memory and cycles.
1458 The code which initializes these sections should have a global
1459 label for these symbols, and should be marked with KEEP() in the
1463 msp430_make_init_symbols (const char * name
)
1465 if (strncmp (name
, ".bss", 4) == 0
1466 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1467 (void) symbol_find_or_make ("__crt0_init_bss");
1469 if (strncmp (name
, ".data", 5) == 0
1470 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1471 (void) symbol_find_or_make ("__crt0_movedata");
1473 /* Note - data assigned to the .either.data section may end up being
1474 placed in the .upper.data section if the .lower.data section is
1475 full. Hence the need to define the crt0 symbol. */
1476 if (strncmp (name
, ".either.data", 12) == 0
1477 || strncmp (name
, ".upper.data", 11) == 0)
1478 (void) symbol_find_or_make ("__crt0_move_highdata");
1480 /* See note about .either.data above. */
1481 if (strncmp (name
, ".upper.bss", 10) == 0
1482 || strncmp (name
, ".either.bss", 11) == 0)
1483 (void) symbol_find_or_make ("__crt0_init_highbss");
1487 msp430_section (int arg
)
1489 char * saved_ilp
= input_line_pointer
;
1490 char * name
= obj_elf_section_name ();
1492 msp430_make_init_symbols (name
);
1494 input_line_pointer
= saved_ilp
;
1495 obj_elf_section (arg
);
1499 msp430_frob_section (asection
*sec
)
1501 const char *name
= sec
->name
;
1506 msp430_make_init_symbols (name
);
1510 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1512 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1515 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1516 (void) symbol_find_or_make ("__crt0_init_bss");
1520 msp430_comm (int needs_align
)
1522 s_comm_internal (needs_align
, elf_common_parse
);
1523 (void) symbol_find_or_make ("__crt0_init_bss");
1527 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1529 char sym_name
[1024];
1530 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1532 (void) symbol_find_or_make (sym_name
);
1535 const pseudo_typeS md_pseudo_table
[] =
1537 {"arch", msp430_set_arch
, OPTION_MMCU
},
1538 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1539 {"profiler", msp430_profiler
, 0},
1540 {"section", msp430_section
, 0},
1541 {"section.s", msp430_section
, 0},
1542 {"sect", msp430_section
, 0},
1543 {"sect.s", msp430_section
, 0},
1544 {"pushsection", msp430_section
, 1},
1545 {"refsym", msp430_refsym
, 0},
1546 {"comm", msp430_comm
, 0},
1547 {"lcomm", msp430_lcomm
, 0},
1551 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1553 struct option md_longopts
[] =
1555 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1556 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1557 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1558 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1559 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1560 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1561 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1562 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1563 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1564 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1565 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1566 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1567 {NULL
, no_argument
, NULL
, 0}
1570 size_t md_longopts_size
= sizeof (md_longopts
);
1573 md_show_usage (FILE * stream
)
1576 _("MSP430 options:\n"
1577 " -mmcu=<msp430-name> - select microcontroller type\n"
1578 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1580 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1581 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1582 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19, cpu42, cpu42+\n"));
1584 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1585 " -mP - enable polymorph instructions\n"));
1587 _(" -ml - enable large code model\n"));
1589 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1591 _(" -mn - insert a NOP after changing interrupts\n"));
1593 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1595 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1597 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1601 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1607 extract_cmd (char * from
, char * to
, int limit
)
1611 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1613 *(to
+ size
) = *from
;
1624 md_atof (int type
, char * litP
, int * sizeP
)
1626 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1632 struct msp430_opcode_s
* opcode
;
1633 msp430_hash
= hash_new ();
1635 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1636 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1638 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1639 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1642 /* Returns the register number equivalent to the string T.
1643 Returns -1 if there is no such register.
1644 Skips a leading 'r' or 'R' character if there is one.
1645 Handles the register aliases PC and SP. */
1648 check_reg (char * t
)
1655 if (*t
== 'r' || *t
== 'R')
1658 if (strncasecmp (t
, "pc", 2) == 0)
1661 if (strncasecmp (t
, "sp", 2) == 0)
1664 if (strncasecmp (t
, "sr", 2) == 0)
1672 if (val
< 1 || val
> 15)
1679 msp430_srcoperand (struct msp430_operand_s
* op
,
1682 bfd_boolean
* imm_op
,
1683 bfd_boolean allow_20bit_values
,
1684 bfd_boolean constants_allowed
)
1688 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1695 /* Check if there is:
1696 llo(x) - least significant 16 bits, x &= 0xffff
1697 lhi(x) - x = (x >> 16) & 0xffff,
1698 hlo(x) - x = (x >> 32) & 0xffff,
1699 hhi(x) - x = (x >> 48) & 0xffff
1700 The value _MUST_ be constant expression: #hlo(1231231231). */
1704 if (strncasecmp (h
, "#llo(", 5) == 0)
1709 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1714 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1719 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1724 else if (strncasecmp (h
, "#lo(", 4) == 0)
1729 else if (strncasecmp (h
, "#hi(", 4) == 0)
1735 op
->reg
= 0; /* Reg PC. */
1737 op
->ol
= 1; /* Immediate will follow an instruction. */
1738 __tl
= h
+ 1 + rval
;
1740 op
->vshift
= vshift
;
1742 parse_exp (__tl
, &(op
->exp
));
1743 if (op
->exp
.X_op
== O_constant
)
1745 int x
= op
->exp
.X_add_number
;
1750 op
->exp
.X_add_number
= x
;
1752 else if (vshift
== 1)
1754 x
= (x
>> 16) & 0xffff;
1755 op
->exp
.X_add_number
= x
;
1758 else if (vshift
> 1)
1761 op
->exp
.X_add_number
= -1;
1763 op
->exp
.X_add_number
= 0; /* Nothing left. */
1764 x
= op
->exp
.X_add_number
;
1768 if (allow_20bit_values
)
1770 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1772 as_bad (_("value 0x%x out of extended range."), x
);
1776 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1778 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1782 /* Now check constants. */
1783 /* Substitute register mode with a constant generator if applicable. */
1785 if (!allow_20bit_values
)
1786 x
= (short) x
; /* Extend sign. */
1788 if (! constants_allowed
)
1820 if (bin
== 0x1200 && ! target_is_430x ())
1822 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1823 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1824 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1825 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1837 if (bin
== 0x1200 && ! target_is_430x ())
1839 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1840 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1841 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1852 else if (op
->exp
.X_op
== O_symbol
)
1855 as_bad (_("error: unsupported #foo() directive used on symbol"));
1858 else if (op
->exp
.X_op
== O_big
)
1864 op
->exp
.X_op
= O_constant
;
1865 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1866 x
= op
->exp
.X_add_number
;
1872 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1920 /* Redundant (yet) check. */
1921 else if (op
->exp
.X_op
== O_register
)
1923 (_("Registers cannot be used within immediate expression [%s]"), l
);
1925 as_bad (_("unknown operand %s"), l
);
1930 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1935 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1936 op
->am
= 1; /* mode As == 01 bin. */
1937 op
->ol
= 1; /* Immediate value followed by instruction. */
1939 parse_exp (__tl
, &(op
->exp
));
1942 if (op
->exp
.X_op
== O_constant
)
1944 int x
= op
->exp
.X_add_number
;
1946 if (allow_20bit_values
)
1948 if (x
> 0xfffff || x
< -(0x7ffff))
1950 as_bad (_("value 0x%x out of extended range."), x
);
1954 else if (x
> 65535 || x
< -32768)
1956 as_bad (_("value out of range: 0x%x"), x
);
1960 else if (op
->exp
.X_op
== O_symbol
)
1964 /* Redundant (yet) check. */
1965 if (op
->exp
.X_op
== O_register
)
1967 (_("Registers cannot be used within absolute expression [%s]"), l
);
1969 as_bad (_("unknown expression in operand %s"), l
);
1975 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1979 char *m
= strchr (l
, '+');
1983 as_bad (_("unknown addressing mode %s"), l
);
1989 if ((op
->reg
= check_reg (t
)) == -1)
1991 as_bad (_("Bad register name %s"), t
);
1999 /* PC cannot be used in indirect addressing. */
2000 if (target_is_430xv2 () && op
->reg
== 0)
2002 as_bad (_("cannot use indirect addressing with the PC"));
2009 /* Check if register indexed X(Rn). */
2012 char *h
= strrchr (l
, '(');
2013 char *m
= strrchr (l
, ')');
2022 as_bad (_("')' required"));
2030 /* Extract a register. */
2031 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2034 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2041 as_bad (_("r2 should not be used in indexed addressing mode"));
2045 /* Extract constant. */
2050 parse_exp (__tl
, &(op
->exp
));
2051 if (op
->exp
.X_op
== O_constant
)
2053 int x
= op
->exp
.X_add_number
;
2055 if (allow_20bit_values
)
2057 if (x
> 0xfffff || x
< - (0x7ffff))
2059 as_bad (_("value 0x%x out of extended range."), x
);
2063 else if (x
> 65535 || x
< -32768)
2065 as_bad (_("value out of range: 0x%x"), x
);
2077 if (op
->reg
== 1 && (x
& 1))
2079 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2080 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2081 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2082 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2085 else if (op
->exp
.X_op
== O_symbol
)
2089 /* Redundant (yet) check. */
2090 if (op
->exp
.X_op
== O_register
)
2092 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2094 as_bad (_("unknown expression in operand %s"), l
);
2102 /* Possibly register mode 'mov r1,r2'. */
2103 if ((op
->reg
= check_reg (l
)) != -1)
2111 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2115 op
->reg
= 0; /* PC relative... be careful. */
2116 /* An expression starting with a minus sign is a constant, not an address. */
2117 op
->am
= (*l
== '-' ? 3 : 1);
2121 parse_exp (__tl
, &(op
->exp
));
2127 as_bad (_("unknown addressing mode for operand %s"), l
);
2133 msp430_dstoperand (struct msp430_operand_s
* op
,
2136 bfd_boolean allow_20bit_values
,
2137 bfd_boolean constants_allowed
)
2140 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2155 parse_exp (__tl
, &(op
->exp
));
2157 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2159 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2169 ("this addressing mode is not applicable for destination operand"));
2175 /* Attempt to encode a MOVA instruction with the given operands.
2176 Returns the length of the encoded instruction if successful
2177 or 0 upon failure. If the encoding fails, an error message
2178 will be returned if a pointer is provided. */
2181 try_encode_mova (bfd_boolean imm_op
,
2183 struct msp430_operand_s
* op1
,
2184 struct msp430_operand_s
* op2
,
2185 const char ** error_message_return
)
2191 /* Only a restricted subset of the normal MSP430 addressing modes
2192 are supported here, so check for the ones that are allowed. */
2195 if (op1
->mode
== OP_EXP
)
2197 if (op2
->mode
!= OP_REG
)
2199 if (error_message_return
!= NULL
)
2200 * error_message_return
= _("expected register as second argument of %s");
2206 /* MOVA #imm20, Rdst. */
2207 bin
|= 0x80 | op2
->reg
;
2208 frag
= frag_more (4);
2209 where
= frag
- frag_now
->fr_literal
;
2210 if (op1
->exp
.X_op
== O_constant
)
2212 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2213 bfd_putl16 ((bfd_vma
) bin
, frag
);
2214 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2218 bfd_putl16 ((bfd_vma
) bin
, frag
);
2219 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2220 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2221 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2226 else if (op1
->am
== 1)
2228 /* MOVA z16(Rsrc), Rdst. */
2229 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2230 frag
= frag_more (4);
2231 where
= frag
- frag_now
->fr_literal
;
2232 bfd_putl16 ((bfd_vma
) bin
, frag
);
2233 if (op1
->exp
.X_op
== O_constant
)
2235 if (op1
->exp
.X_add_number
> 0xffff
2236 || op1
->exp
.X_add_number
< -(0x7fff))
2238 if (error_message_return
!= NULL
)
2239 * error_message_return
= _("index value too big for %s");
2242 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2246 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2247 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2249 BFD_RELOC_MSP430X_PCR16
:
2250 BFD_RELOC_MSP430X_ABS16
);
2255 if (error_message_return
!= NULL
)
2256 * error_message_return
= _("unexpected addressing mode for %s");
2259 else if (op1
->am
== 0)
2261 /* MOVA Rsrc, ... */
2262 if (op2
->mode
== OP_REG
)
2264 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2265 frag
= frag_more (2);
2266 where
= frag
- frag_now
->fr_literal
;
2267 bfd_putl16 ((bfd_vma
) bin
, frag
);
2270 else if (op2
->am
== 1)
2274 /* MOVA Rsrc, &abs20. */
2275 bin
|= 0x60 | (op1
->reg
<< 8);
2276 frag
= frag_more (4);
2277 where
= frag
- frag_now
->fr_literal
;
2278 if (op2
->exp
.X_op
== O_constant
)
2280 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2281 bfd_putl16 ((bfd_vma
) bin
, frag
);
2282 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2286 bfd_putl16 ((bfd_vma
) bin
, frag
);
2287 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2288 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2289 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2294 /* MOVA Rsrc, z16(Rdst). */
2295 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2296 frag
= frag_more (4);
2297 where
= frag
- frag_now
->fr_literal
;
2298 bfd_putl16 ((bfd_vma
) bin
, frag
);
2299 if (op2
->exp
.X_op
== O_constant
)
2301 if (op2
->exp
.X_add_number
> 0xffff
2302 || op2
->exp
.X_add_number
< -(0x7fff))
2304 if (error_message_return
!= NULL
)
2305 * error_message_return
= _("index value too big for %s");
2308 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2312 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2313 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2315 BFD_RELOC_MSP430X_PCR16
:
2316 BFD_RELOC_MSP430X_ABS16
);
2321 if (error_message_return
!= NULL
)
2322 * error_message_return
= _("unexpected addressing mode for %s");
2327 /* imm_op == FALSE. */
2329 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2331 /* MOVA &abs20, Rdst. */
2332 if (op2
->mode
!= OP_REG
)
2334 if (error_message_return
!= NULL
)
2335 * error_message_return
= _("expected register as second argument of %s");
2339 if (op2
->reg
== 2 || op2
->reg
== 3)
2341 if (error_message_return
!= NULL
)
2342 * error_message_return
= _("constant generator destination register found in %s");
2346 bin
|= 0x20 | op2
->reg
;
2347 frag
= frag_more (4);
2348 where
= frag
- frag_now
->fr_literal
;
2349 if (op1
->exp
.X_op
== O_constant
)
2351 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2352 bfd_putl16 ((bfd_vma
) bin
, frag
);
2353 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2357 bfd_putl16 ((bfd_vma
) bin
, frag
);
2358 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2359 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2360 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2364 else if (op1
->mode
== OP_REG
)
2368 /* MOVA @Rsrc+, Rdst. */
2369 if (op2
->mode
!= OP_REG
)
2371 if (error_message_return
!= NULL
)
2372 * error_message_return
= _("expected register as second argument of %s");
2376 if (op2
->reg
== 2 || op2
->reg
== 3)
2378 if (error_message_return
!= NULL
)
2379 * error_message_return
= _("constant generator destination register found in %s");
2383 if (op1
->reg
== 2 || op1
->reg
== 3)
2385 if (error_message_return
!= NULL
)
2386 * error_message_return
= _("constant generator source register found in %s");
2390 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2391 frag
= frag_more (2);
2392 where
= frag
- frag_now
->fr_literal
;
2393 bfd_putl16 ((bfd_vma
) bin
, frag
);
2396 else if (op1
->am
== 2)
2398 /* MOVA @Rsrc,Rdst */
2399 if (op2
->mode
!= OP_REG
)
2401 if (error_message_return
!= NULL
)
2402 * error_message_return
= _("expected register as second argument of %s");
2406 if (op2
->reg
== 2 || op2
->reg
== 3)
2408 if (error_message_return
!= NULL
)
2409 * error_message_return
= _("constant generator destination register found in %s");
2413 if (op1
->reg
== 2 || op1
->reg
== 3)
2415 if (error_message_return
!= NULL
)
2416 * error_message_return
= _("constant generator source register found in %s");
2420 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2421 frag
= frag_more (2);
2422 where
= frag
- frag_now
->fr_literal
;
2423 bfd_putl16 ((bfd_vma
) bin
, frag
);
2428 if (error_message_return
!= NULL
)
2429 * error_message_return
= _("unexpected addressing mode for %s");
2434 #define NOP_CHECK_INTERRUPT (1 << 0)
2435 #define NOP_CHECK_CPU12 (1 << 1)
2436 #define NOP_CHECK_CPU19 (1 << 2)
2438 static signed int check_for_nop
= 0;
2440 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2442 /* Parse instruction operands.
2443 Return binary opcode. */
2446 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2448 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2449 int insn_length
= 0;
2450 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2453 struct msp430_operand_s op1
, op2
;
2455 static short ZEROS
= 0;
2456 bfd_boolean byte_op
, imm_op
;
2459 int extended
= 0x1800;
2460 bfd_boolean extended_op
= FALSE
;
2461 bfd_boolean addr_op
;
2462 const char * error_message
;
2463 static signed int repeat_count
= 0;
2464 bfd_boolean fix_emitted
;
2466 /* Opcode is the one from opcodes table
2467 line contains something like
2476 bfd_boolean check
= FALSE
;
2479 switch (TOLOWER (* line
))
2482 /* Byte operation. */
2483 bin
|= BYTE_OPERATION
;
2489 /* "Address" ops work on 20-bit values. */
2491 bin
|= BYTE_OPERATION
;
2496 /* Word operation - this is the default. */
2504 as_warn (_("no size modifier after period, .w assumed"));
2508 as_bad (_("unrecognised instruction size modifier .%c"),
2520 if (*line
&& ! ISSPACE (*line
))
2522 as_bad (_("junk found after instruction: %s.%s"),
2523 opcode
->name
, line
);
2527 /* Catch the case where the programmer has used a ".a" size modifier on an
2528 instruction that does not support it. Look for an alternative extended
2529 instruction that has the same name without the period. Eg: "add.a"
2530 becomes "adda". Although this not an officially supported way of
2531 specifing instruction aliases other MSP430 assemblers allow it. So we
2532 support it for compatibility purposes. */
2533 if (addr_op
&& opcode
->fmt
>= 0)
2535 char * old_name
= opcode
->name
;
2538 sprintf (real_name
, "%sa", old_name
);
2539 opcode
= hash_find (msp430_hash
, real_name
);
2542 as_bad (_("instruction %s.a does not exist"), old_name
);
2545 #if 0 /* Enable for debugging. */
2546 as_warn ("treating %s.a as %s", old_name
, real_name
);
2549 bin
= opcode
->bin_opcode
;
2552 if (opcode
->fmt
!= -1
2553 && opcode
->insn_opnumb
2554 && (!*line
|| *line
== '\n'))
2556 as_bad (_("instruction %s requires %d operand(s)"),
2557 opcode
->name
, opcode
->insn_opnumb
);
2561 memset (l1
, 0, sizeof (l1
));
2562 memset (l2
, 0, sizeof (l2
));
2563 memset (&op1
, 0, sizeof (op1
));
2564 memset (&op2
, 0, sizeof (op2
));
2568 if ((fmt
= opcode
->fmt
) < 0)
2570 if (! target_is_430x ())
2572 as_bad (_("instruction %s requires MSP430X mcu"),
2583 /* If requested set the extended instruction repeat count. */
2586 if (repeat_count
> 0)
2587 extended
|= (repeat_count
- 1);
2589 extended
|= (1 << 7) | (- repeat_count
);
2592 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2599 if (! is_opcode ("nop"))
2601 bfd_boolean doit
= FALSE
;
2605 switch (check_for_nop
& - check_for_nop
)
2607 case NOP_CHECK_INTERRUPT
:
2608 if (warn_interrupt_nops
2609 || silicon_errata_warn
& SILICON_ERRATA_CPU42
2610 || silicon_errata_warn
& SILICON_ERRATA_CPU42_PLUS
)
2612 if (gen_interrupt_nops
)
2613 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2615 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2618 if (gen_interrupt_nops
2619 || silicon_errata_fix
& SILICON_ERRATA_CPU42_PLUS
)
2620 /* Emit a NOP between interrupt enable/disable.
2621 See 1.3.4.1 of the MSP430x5xx User Guide. */
2625 case NOP_CHECK_CPU12
:
2626 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2627 as_warn (_("CPU12: CMP/BIT with PC destinstion ignores next instruction"));
2629 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2633 case NOP_CHECK_CPU19
:
2634 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2635 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2637 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2642 as_bad (_("internal error: unknown nop check state"));
2645 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2647 while (check_for_nop
);
2651 frag
= frag_more (2);
2652 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2653 dwarf2_emit_insn (2);
2662 case 0: /* Emulated. */
2663 switch (opcode
->insn_opnumb
)
2666 if (is_opcode ("eint") || is_opcode ("dint"))
2667 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2669 /* Set/clear bits instructions. */
2673 extended
|= BYTE_OPERATION
;
2675 /* Emit the extension word. */
2677 frag
= frag_more (2);
2678 bfd_putl16 (extended
, frag
);
2682 frag
= frag_more (2);
2683 bfd_putl16 ((bfd_vma
) bin
, frag
);
2684 dwarf2_emit_insn (insn_length
);
2688 /* Something which works with destination operand. */
2689 line
= extract_operand (line
, l1
, sizeof (l1
));
2690 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2694 bin
|= (op1
.reg
| (op1
.am
<< 7));
2696 /* If the PC is the destination... */
2697 if (op1
.am
== 0 && op1
.reg
== 0
2698 /* ... and the opcode alters the SR. */
2699 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2700 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2702 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2703 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
2704 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2705 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
2708 /* If the status register is the destination... */
2709 if (op1
.am
== 0 && op1
.reg
== 2
2710 /* ... and the opcode alters the SR. */
2711 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2712 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2713 || is_opcode ("sbc") || is_opcode ("sxt")
2714 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2715 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2716 || is_opcode ("sbcx")
2719 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2720 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2721 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2722 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2725 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2726 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2728 /* Compute the entire instruction length, in bytes. */
2729 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2730 insn_length
+= op_length
;
2731 frag
= frag_more (op_length
);
2732 where
= frag
- frag_now
->fr_literal
;
2737 extended
|= BYTE_OPERATION
;
2739 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2741 as_bad (_("repeat instruction used with non-register mode instruction"));
2745 if (op1
.mode
== OP_EXP
)
2747 if (op1
.exp
.X_op
== O_constant
)
2748 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2750 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2751 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2752 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2754 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2755 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2758 /* Emit the extension word. */
2759 bfd_putl16 (extended
, frag
);
2764 bfd_putl16 ((bfd_vma
) bin
, frag
);
2768 if (op1
.mode
== OP_EXP
)
2770 if (op1
.exp
.X_op
== O_constant
)
2772 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2776 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2781 fix_new_exp (frag_now
, where
, 2,
2782 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2784 fix_new_exp (frag_now
, where
, 2,
2785 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2790 dwarf2_emit_insn (insn_length
);
2794 /* Shift instruction. */
2795 line
= extract_operand (line
, l1
, sizeof (l1
));
2796 strncpy (l2
, l1
, sizeof (l2
));
2797 l2
[sizeof (l2
) - 1] = '\0';
2798 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2799 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2802 break; /* An error occurred. All warnings were done before. */
2804 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2805 frag
= frag_more (insn_length
);
2806 where
= frag
- frag_now
->fr_literal
;
2808 if (target_is_430xv2 ()
2809 && op1
.mode
== OP_REG
2811 && (is_opcode ("rlax")
2812 || is_opcode ("rlcx")
2813 || is_opcode ("rla")
2814 || is_opcode ("rlc")))
2816 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2820 /* If the status register is the destination... */
2821 if (op1
.am
== 0 && op1
.reg
== 2
2822 /* ... and the opcode alters the SR. */
2823 && (is_opcode ("rla") || is_opcode ("rlc")
2824 || is_opcode ("rlax") || is_opcode ("rlcx")
2827 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2828 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2829 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2830 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2836 extended
|= BYTE_OPERATION
;
2838 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2840 as_bad (_("repeat instruction used with non-register mode instruction"));
2844 if (op1
.mode
== OP_EXP
)
2846 if (op1
.exp
.X_op
== O_constant
)
2847 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2849 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2850 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2851 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2853 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2854 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2857 if (op2
.mode
== OP_EXP
)
2859 if (op2
.exp
.X_op
== O_constant
)
2860 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2862 else if (op1
.mode
== OP_EXP
)
2863 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2864 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2865 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2867 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2868 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2869 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2872 /* Emit the extension word. */
2873 bfd_putl16 (extended
, frag
);
2878 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2879 bfd_putl16 ((bfd_vma
) bin
, frag
);
2883 if (op1
.mode
== OP_EXP
)
2885 if (op1
.exp
.X_op
== O_constant
)
2887 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2891 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2895 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2896 fix_new_exp (frag_now
, where
, 2,
2897 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2899 fix_new_exp (frag_now
, where
, 2,
2900 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2907 if (op2
.mode
== OP_EXP
)
2909 if (op2
.exp
.X_op
== O_constant
)
2911 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2915 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2919 if (op2
.reg
) /* Not PC relative. */
2920 fix_new_exp (frag_now
, where
, 2,
2921 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2923 fix_new_exp (frag_now
, where
, 2,
2924 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2929 dwarf2_emit_insn (insn_length
);
2933 /* Branch instruction => mov dst, r0. */
2936 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2940 line
= extract_operand (line
, l1
, sizeof (l1
));
2941 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2947 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2948 op_length
= 2 + 2 * op1
.ol
;
2949 frag
= frag_more (op_length
);
2950 where
= frag
- frag_now
->fr_literal
;
2951 bfd_putl16 ((bfd_vma
) bin
, frag
);
2953 if (op1
.mode
== OP_EXP
)
2955 if (op1
.exp
.X_op
== O_constant
)
2957 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2963 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2965 if (op1
.reg
|| op1
.am
== 3)
2966 fix_new_exp (frag_now
, where
, 2,
2967 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2969 fix_new_exp (frag_now
, where
, 2,
2970 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2974 dwarf2_emit_insn (insn_length
+ op_length
);
2978 /* CALLA instructions. */
2979 fix_emitted
= FALSE
;
2981 line
= extract_operand (line
, l1
, sizeof (l1
));
2984 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
2985 extended_op
, FALSE
);
2991 op_length
= 2 + 2 * op1
.ol
;
2992 frag
= frag_more (op_length
);
2993 where
= frag
- frag_now
->fr_literal
;
3001 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3002 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3005 else if (op1
.am
== 1)
3011 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3012 BFD_RELOC_MSP430X_PCR20_CALL
);
3016 bin
|= 0x50 | op1
.reg
;
3018 else if (op1
.am
== 0)
3019 bin
|= 0x40 | op1
.reg
;
3021 else if (op1
.am
== 1)
3025 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3026 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3029 else if (op1
.am
== 2)
3030 bin
|= 0x60 | op1
.reg
;
3031 else if (op1
.am
== 3)
3032 bin
|= 0x70 | op1
.reg
;
3034 bfd_putl16 ((bfd_vma
) bin
, frag
);
3036 if (op1
.mode
== OP_EXP
)
3040 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3044 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3047 fix_new_exp (frag_now
, where
+ 2, 2,
3048 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3051 dwarf2_emit_insn (insn_length
+ op_length
);
3059 /* [POP|PUSH]M[.A] #N, Rd */
3060 line
= extract_operand (line
, l1
, sizeof (l1
));
3061 line
= extract_operand (line
, l2
, sizeof (l2
));
3065 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3068 parse_exp (l1
+ 1, &(op1
.exp
));
3069 if (op1
.exp
.X_op
!= O_constant
)
3071 as_bad (_("expected constant expression for first argument of %s"),
3076 if ((reg
= check_reg (l2
)) == -1)
3078 as_bad (_("expected register as second argument of %s"),
3084 frag
= frag_more (op_length
);
3085 where
= frag
- frag_now
->fr_literal
;
3086 bin
= opcode
->bin_opcode
;
3089 n
= op1
.exp
.X_add_number
;
3090 bin
|= (n
- 1) << 4;
3091 if (is_opcode ("pushm"))
3095 if (reg
- n
+ 1 < 0)
3097 as_bad (_("Too many registers popped"));
3101 /* CPU21 errata: cannot use POPM to restore the SR register. */
3102 if (target_is_430xv2 ()
3103 && (reg
- n
+ 1 < 3)
3105 && is_opcode ("popm"))
3107 as_bad (_("Cannot use POPM to restore the SR register"));
3111 bin
|= (reg
- n
+ 1);
3114 bfd_putl16 ((bfd_vma
) bin
, frag
);
3115 dwarf2_emit_insn (op_length
);
3124 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3125 if (extended
& 0xff)
3127 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3131 line
= extract_operand (line
, l1
, sizeof (l1
));
3132 line
= extract_operand (line
, l2
, sizeof (l2
));
3136 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3139 parse_exp (l1
+ 1, &(op1
.exp
));
3140 if (op1
.exp
.X_op
!= O_constant
)
3142 as_bad (_("expected constant expression for first argument of %s"),
3146 n
= op1
.exp
.X_add_number
;
3149 as_bad (_("expected first argument of %s to be in the range 1-4"),
3154 if ((reg
= check_reg (l2
)) == -1)
3156 as_bad (_("expected register as second argument of %s"),
3161 if (target_is_430xv2 () && reg
== 0)
3163 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3168 frag
= frag_more (op_length
);
3169 where
= frag
- frag_now
->fr_literal
;
3171 bin
= opcode
->bin_opcode
;
3174 bin
|= (n
- 1) << 10;
3177 bfd_putl16 ((bfd_vma
) bin
, frag
);
3178 dwarf2_emit_insn (op_length
);
3186 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
3187 if (extended
& 0xff)
3189 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3193 line
= extract_operand (line
, l1
, sizeof (l1
));
3194 if ((reg
= check_reg (l1
)) == -1)
3196 as_bad (_("expected register as argument of %s"),
3201 if (target_is_430xv2 () && reg
== 0)
3203 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3209 /* Tricky - there is no single instruction that will do this.
3210 Encode as: RRA.B rN { BIC.B #0x80, rN */
3212 frag
= frag_more (op_length
);
3213 where
= frag
- frag_now
->fr_literal
;
3215 bfd_putl16 ((bfd_vma
) bin
, frag
);
3216 dwarf2_emit_insn (2);
3218 bfd_putl16 ((bfd_vma
) bin
, frag
+ 2);
3220 bfd_putl16 ((bfd_vma
) bin
, frag
+ 4);
3221 dwarf2_emit_insn (4);
3225 /* Encode as RRUM[.A] rN. */
3226 bin
= opcode
->bin_opcode
;
3231 frag
= frag_more (op_length
);
3232 where
= frag
- frag_now
->fr_literal
;
3233 bfd_putl16 ((bfd_vma
) bin
, frag
);
3234 dwarf2_emit_insn (op_length
);
3241 bfd_boolean need_reloc
= FALSE
;
3245 /* ADDA, CMPA and SUBA address instructions. */
3246 if (extended
& 0xff)
3248 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3252 line
= extract_operand (line
, l1
, sizeof (l1
));
3253 line
= extract_operand (line
, l2
, sizeof (l2
));
3255 bin
= opcode
->bin_opcode
;
3259 parse_exp (l1
+ 1, &(op1
.exp
));
3261 if (op1
.exp
.X_op
== O_constant
)
3263 n
= op1
.exp
.X_add_number
;
3264 if (n
> 0xfffff || n
< - (0x7ffff))
3266 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3271 bin
|= ((n
>> 16) & 0xf) << 8;
3283 if ((n
= check_reg (l1
)) == -1)
3285 as_bad (_("expected register name or constant as first argument of %s"),
3290 bin
|= (n
<< 8) | (1 << 6);
3294 if ((reg
= check_reg (l2
)) == -1)
3296 as_bad (_("expected register as second argument of %s"),
3301 frag
= frag_more (op_length
);
3302 where
= frag
- frag_now
->fr_literal
;
3305 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3306 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3308 bfd_putl16 ((bfd_vma
) bin
, frag
);
3310 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3311 dwarf2_emit_insn (op_length
);
3315 case 9: /* MOVA, BRA, RETA. */
3317 bin
= opcode
->bin_opcode
;
3319 if (is_opcode ("reta"))
3321 /* The RETA instruction does not take any arguments.
3322 The implicit first argument is @SP+.
3323 The implicit second argument is PC. */
3333 line
= extract_operand (line
, l1
, sizeof (l1
));
3334 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3335 &imm_op
, extended_op
, FALSE
);
3337 if (is_opcode ("bra"))
3339 /* This is the BRA synthetic instruction.
3340 The second argument is always PC. */
3346 line
= extract_operand (line
, l2
, sizeof (l2
));
3347 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3352 break; /* Error occurred. All warnings were done before. */
3355 /* Only a restricted subset of the normal MSP430 addressing modes
3356 are supported here, so check for the ones that are allowed. */
3357 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3358 & error_message
)) == 0)
3360 as_bad (error_message
, opcode
->name
);
3363 dwarf2_emit_insn (op_length
);
3367 line
= extract_operand (line
, l1
, sizeof l1
);
3368 /* The RPT instruction only accepted immediates and registers. */
3371 parse_exp (l1
+ 1, &(op1
.exp
));
3372 if (op1
.exp
.X_op
!= O_constant
)
3374 as_bad (_("expected constant value as argument to RPT"));
3377 if (op1
.exp
.X_add_number
< 1
3378 || op1
.exp
.X_add_number
> (1 << 4))
3380 as_bad (_("expected constant in the range 2..16"));
3384 /* We silently accept and ignore a repeat count of 1. */
3385 if (op1
.exp
.X_add_number
> 1)
3386 repeat_count
= op1
.exp
.X_add_number
;
3392 if ((reg
= check_reg (l1
)) != -1)
3395 as_warn (_("PC used as an argument to RPT"));
3397 repeat_count
= - reg
;
3401 as_bad (_("expected constant or register name as argument to RPT insn"));
3408 as_bad (_("Illegal emulated instruction "));
3413 case 1: /* Format 1, double operand. */
3414 line
= extract_operand (line
, l1
, sizeof (l1
));
3415 line
= extract_operand (line
, l2
, sizeof (l2
));
3416 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3417 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3420 break; /* Error occurred. All warnings were done before. */
3423 && is_opcode ("movx")
3425 && msp430_enable_relax
)
3427 /* This is the MOVX.A instruction. See if we can convert
3428 it into the MOVA instruction instead. This saves 2 bytes. */
3429 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3432 dwarf2_emit_insn (op_length
);
3437 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3439 /* If the PC is the destination... */
3440 if (op2
.am
== 0 && op2
.reg
== 0
3441 /* ... and the opcode alters the SR. */
3442 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3443 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3445 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3446 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
3447 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3448 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
3451 /* If the status register is the destination... */
3452 if (op2
.am
== 0 && op2
.reg
== 2
3453 /* ... and the opcode alters the SR. */
3454 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3455 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3456 || is_opcode ("xor")
3457 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3458 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3459 || is_opcode ("xorx")
3462 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3463 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3464 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3465 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3468 if ( (is_opcode ("bic") && bin
== 0xc232)
3469 || (is_opcode ("bis") && bin
== 0xd232)
3470 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3472 /* Avoid false checks when a constant value is being put into the SR. */
3473 if (op1
.mode
== OP_EXP
3474 && op1
.exp
.X_op
== O_constant
3475 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3478 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3481 if (((is_opcode ("bis") && bin
== 0xd032)
3482 || (is_opcode ("mov") && bin
== 0x4032)
3483 || (is_opcode ("xor") && bin
== 0xe032))
3484 && op1
.mode
== OP_EXP
3485 && op1
.exp
.X_op
== O_constant
3486 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3487 check_for_nop
|= NOP_CHECK_CPU19
;
3489 /* Compute the entire length of the instruction in bytes. */
3490 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3491 + 2 /* The opcode */
3492 + (2 * op1
.ol
) /* The first operand. */
3493 + (2 * op2
.ol
); /* The second operand. */
3495 insn_length
+= op_length
;
3496 frag
= frag_more (op_length
);
3497 where
= frag
- frag_now
->fr_literal
;
3502 extended
|= BYTE_OPERATION
;
3504 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3506 as_bad (_("repeat instruction used with non-register mode instruction"));
3510 /* If necessary, emit a reloc to update the extension word. */
3511 if (op1
.mode
== OP_EXP
)
3513 if (op1
.exp
.X_op
== O_constant
)
3514 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3516 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3517 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3518 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3520 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3521 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3524 if (op2
.mode
== OP_EXP
)
3526 if (op2
.exp
.X_op
== O_constant
)
3527 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3529 else if (op1
.mode
== OP_EXP
)
3530 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3531 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3532 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3535 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3536 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3537 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3540 /* Emit the extension word. */
3541 bfd_putl16 (extended
, frag
);
3546 bfd_putl16 ((bfd_vma
) bin
, frag
);
3550 if (op1
.mode
== OP_EXP
)
3552 if (op1
.exp
.X_op
== O_constant
)
3554 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3558 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3562 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3563 fix_new_exp (frag_now
, where
, 2,
3564 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3566 fix_new_exp (frag_now
, where
, 2,
3567 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3575 if (op2
.mode
== OP_EXP
)
3577 if (op2
.exp
.X_op
== O_constant
)
3579 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3583 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3587 if (op2
.reg
) /* Not PC relative. */
3588 fix_new_exp (frag_now
, where
, 2,
3589 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3591 fix_new_exp (frag_now
, where
, 2,
3592 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3597 dwarf2_emit_insn (insn_length
);
3599 /* If the PC is the destination... */
3600 if (op2
.am
== 0 && op2
.reg
== 0
3601 /* ... but the opcode does not alter the destination. */
3602 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3603 check_for_nop
|= NOP_CHECK_CPU12
;
3606 case 2: /* Single-operand mostly instr. */
3607 if (opcode
->insn_opnumb
== 0)
3609 /* reti instruction. */
3611 frag
= frag_more (2);
3612 bfd_putl16 ((bfd_vma
) bin
, frag
);
3613 dwarf2_emit_insn (insn_length
);
3617 line
= extract_operand (line
, l1
, sizeof (l1
));
3618 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3619 &imm_op
, extended_op
, TRUE
);
3621 break; /* Error in operand. */
3623 if (target_is_430xv2 ()
3624 && op1
.mode
== OP_REG
3626 && (is_opcode ("rrax")
3627 || is_opcode ("rrcx")
3628 || is_opcode ("rra")
3629 || is_opcode ("rrc")))
3631 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3635 /* If the status register is the destination... */
3636 if (op1
.am
== 0 && op1
.reg
== 2
3637 /* ... and the opcode alters the SR. */
3638 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3640 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3641 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3642 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3643 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3646 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3647 frag
= frag_more (insn_length
);
3648 where
= frag
- frag_now
->fr_literal
;
3652 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3654 /* These two instructions use a special
3655 encoding of the A/L and B/W bits. */
3656 bin
&= ~ BYTE_OPERATION
;
3660 as_bad (_("%s instruction does not accept a .b suffix"),
3665 extended
|= BYTE_OPERATION
;
3668 extended
|= BYTE_OPERATION
;
3670 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3672 as_bad (_("repeat instruction used with non-register mode instruction"));
3676 if (op1
.mode
== OP_EXP
)
3678 if (op1
.exp
.X_op
== O_constant
)
3679 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3681 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3682 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3683 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3685 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3686 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3689 /* Emit the extension word. */
3690 bfd_putl16 (extended
, frag
);
3695 bin
|= op1
.reg
| (op1
.am
<< 4);
3696 bfd_putl16 ((bfd_vma
) bin
, frag
);
3700 if (op1
.mode
== OP_EXP
)
3702 if (op1
.exp
.X_op
== O_constant
)
3704 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3708 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3712 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3713 fix_new_exp (frag_now
, where
, 2,
3714 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3716 fix_new_exp (frag_now
, where
, 2,
3717 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3722 dwarf2_emit_insn (insn_length
);
3725 case 3: /* Conditional jumps instructions. */
3726 line
= extract_operand (line
, l1
, sizeof (l1
));
3727 /* l1 is a label. */
3736 parse_exp (m
, &exp
);
3738 /* In order to handle something like:
3742 jz 4 ; skip next 4 bytes
3745 nop ; will jump here if r5 positive or zero
3747 jCOND -n ;assumes jump n bytes backward:
3757 jCOND $n ; jump from PC in either direction. */
3759 if (exp
.X_op
== O_constant
)
3761 int x
= exp
.X_add_number
;
3765 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3769 if ((*l1
== '$' && x
> 0) || x
< 0)
3774 if (x
> 512 || x
< -511)
3776 as_bad (_("Wrong displacement %d"), x
<< 1);
3781 frag
= frag_more (2); /* Instr size is 1 word. */
3784 bfd_putl16 ((bfd_vma
) bin
, frag
);
3786 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3789 frag
= frag_more (2); /* Instr size is 1 word. */
3790 where
= frag
- frag_now
->fr_literal
;
3791 fix_new_exp (frag_now
, where
, 2,
3792 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3794 bfd_putl16 ((bfd_vma
) bin
, frag
);
3796 else if (*l1
== '$')
3798 as_bad (_("instruction requires label sans '$'"));
3802 ("instruction requires label or value in range -511:512"));
3803 dwarf2_emit_insn (insn_length
);
3808 as_bad (_("instruction requires label"));
3813 case 4: /* Extended jumps. */
3814 if (!msp430_enable_polys
)
3816 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3820 line
= extract_operand (line
, l1
, sizeof (l1
));
3826 /* Ignore absolute addressing. make it PC relative anyway. */
3827 if (*m
== '#' || *m
== '$')
3830 parse_exp (m
, & exp
);
3831 if (exp
.X_op
== O_symbol
)
3833 /* Relaxation required. */
3834 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3836 if (target_is_430x ())
3837 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3839 /* The parameter to dwarf2_emit_insn is actually the offset to
3840 the start of the insn from the fix piece of instruction that
3841 was emitted. Since next fragments may have variable size we
3842 tie debug info to the beginning of the instruction. */
3844 frag
= frag_more (8);
3845 dwarf2_emit_insn (0);
3846 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3847 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3849 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3851 0, /* Offset is zero if jump dist less than 1K. */
3857 as_bad (_("instruction requires label"));
3860 case 5: /* Emulated extended branches. */
3861 if (!msp430_enable_polys
)
3863 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3866 line
= extract_operand (line
, l1
, sizeof (l1
));
3872 /* Ignore absolute addressing. make it PC relative anyway. */
3873 if (*m
== '#' || *m
== '$')
3876 parse_exp (m
, & exp
);
3877 if (exp
.X_op
== O_symbol
)
3879 /* Relaxation required. */
3880 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3882 if (target_is_430x ())
3883 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3886 frag
= frag_more (8);
3887 dwarf2_emit_insn (0);
3888 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3889 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3891 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3892 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3894 0, /* Offset is zero if jump dist less than 1K. */
3900 as_bad (_("instruction requires label"));
3904 as_bad (_("Illegal instruction or not implemented opcode."));
3907 input_line_pointer
= line
;
3912 md_assemble (char * str
)
3914 struct msp430_opcode_s
* opcode
;
3918 str
= skip_space (str
); /* Skip leading spaces. */
3919 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3923 char a
= TOLOWER (cmd
[i
]);
3930 as_bad (_("can't find opcode "));
3934 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3938 as_bad (_("unknown opcode `%s'"), cmd
);
3943 char *__t
= input_line_pointer
;
3945 msp430_operands (opcode
, str
);
3946 input_line_pointer
= __t
;
3950 /* GAS will call this function for each section at the end of the assembly,
3951 to permit the CPU backend to adjust the alignment of a section. */
3954 md_section_align (asection
* seg
, valueT addr
)
3956 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3958 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
3961 /* If you define this macro, it should return the offset between the
3962 address of a PC relative fixup and the position from which the PC
3963 relative adjustment should be made. On many processors, the base
3964 of a PC relative instruction is the next instruction, so this
3965 macro would return the length of an instruction. */
3968 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3970 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3971 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3972 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3975 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3978 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3979 Now it handles the situation when relocations
3980 have to be passed to linker. */
3982 msp430_force_relocation_local (fixS
*fixp
)
3984 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3988 if (msp430_enable_polys
3989 && !msp430_enable_relax
)
3992 return (!fixp
->fx_pcrel
3993 || generic_force_reloc (fixp
));
3997 /* GAS will call this for each fixup. It should store the correct
3998 value in the object file. */
4000 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4002 unsigned char * where
;
4006 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4011 else if (fixp
->fx_pcrel
)
4013 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4015 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4017 /* FIXME: We can appear here only in case if we perform a pc
4018 relative jump to the label which is i) global, ii) locally
4019 defined or this is a jump to an absolute symbol.
4020 If this is an absolute symbol -- everything is OK.
4021 If this is a global label, we've got a symbol value defined
4023 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4024 from this section start
4025 2. *valuep will contain the real offset from jump insn to the
4027 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4028 will be incorrect. Therefore remove s_get_value. */
4029 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4037 value
= fixp
->fx_offset
;
4039 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4041 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4043 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4049 fixp
->fx_no_overflow
= 1;
4051 /* If polymorphs are enabled and relax disabled.
4052 do not kill any relocs and pass them to linker. */
4053 if (msp430_enable_polys
4054 && !msp430_enable_relax
)
4057 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4058 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4065 /* Fetch the instruction, insert the fully resolved operand
4066 value, and stuff the instruction back again. */
4067 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4069 insn
= bfd_getl16 (where
);
4071 switch (fixp
->fx_r_type
)
4073 case BFD_RELOC_MSP430_10_PCREL
:
4075 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4076 _("odd address operand: %ld"), value
);
4078 /* Jumps are in words. */
4080 --value
; /* Correct PC. */
4082 if (value
< -512 || value
> 511)
4083 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4084 _("operand out of range: %ld"), value
);
4086 value
&= 0x3ff; /* get rid of extended sign */
4087 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4090 case BFD_RELOC_MSP430X_PCR16
:
4091 case BFD_RELOC_MSP430_RL_PCREL
:
4092 case BFD_RELOC_MSP430_16_PCREL
:
4094 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4095 _("odd address operand: %ld"), value
);
4098 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4099 /* Nothing to be corrected here. */
4100 if (value
< -32768 || value
> 65536)
4101 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4102 _("operand out of range: %ld"), value
);
4105 case BFD_RELOC_MSP430X_ABS16
:
4106 case BFD_RELOC_MSP430_16
:
4108 case BFD_RELOC_MSP430_16_BYTE
:
4109 value
&= 0xffff; /* Get rid of extended sign. */
4110 bfd_putl16 ((bfd_vma
) value
, where
);
4113 case BFD_RELOC_MSP430_ABS_HI16
:
4115 value
&= 0xffff; /* Get rid of extended sign. */
4116 bfd_putl16 ((bfd_vma
) value
, where
);
4120 bfd_putl16 ((bfd_vma
) value
, where
);
4123 case BFD_RELOC_MSP430_ABS8
:
4125 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4128 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4129 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4130 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4132 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4135 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4136 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4138 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4141 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4142 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4144 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4147 case BFD_RELOC_MSP430X_PCR20_CALL
:
4148 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4150 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4153 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4154 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4155 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4157 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4160 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4161 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4163 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4166 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4167 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4169 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4173 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4174 fixp
->fx_line
, fixp
->fx_r_type
);
4180 fixp
->fx_addnumber
= value
;
4185 S_IS_GAS_LOCAL (symbolS
* s
)
4192 name
= S_GET_NAME (s
);
4193 len
= strlen (name
) - 1;
4195 return name
[len
] == 1 || name
[len
] == 2;
4198 /* GAS will call this to generate a reloc, passing the resulting reloc
4199 to `bfd_install_relocation'. This currently works poorly, as
4200 `bfd_install_relocation' often does the wrong thing, and instances of
4201 `tc_gen_reloc' have been written to work around the problems, which
4202 in turns makes it difficult to fix `bfd_install_relocation'. */
4204 /* If while processing a fixup, a reloc really needs to be created
4205 then it is done here. */
4208 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4210 static arelent
* no_relocs
= NULL
;
4211 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4214 reloc
= xmalloc (sizeof (arelent
));
4215 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4216 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4218 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4220 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4221 _("reloc %d not supported by object file format"),
4222 (int) fixp
->fx_r_type
);
4231 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4233 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4234 fixp
->fx_subsy
= NULL
;
4237 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4239 asection
*asec
, *ssec
;
4241 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4242 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4244 /* If we have a difference between two different, non-absolute symbols
4245 we must generate two relocs (one for each symbol) and allow the
4246 linker to resolve them - relaxation may change the distances between
4247 symbols, even local symbols defined in the same section.
4249 Unfortunately we cannot do this with assembler generated local labels
4250 because there can be multiple incarnations of the same label, with
4251 exactly the same name, in any given section and the linker will have
4252 no way to identify the correct one. Instead we just have to hope
4253 that no relaxtion will occur between the local label and the other
4254 symbol in the expression.
4256 Similarly we have to compute differences between symbols in the .eh_frame
4257 section as the linker is not smart enough to apply relocations there
4258 before attempting to process it. */
4259 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4260 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4261 && strcmp (ssec
->name
, ".eh_frame") != 0
4262 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4263 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4265 arelent
* reloc2
= xmalloc (sizeof * reloc
);
4270 reloc2
->address
= reloc
->address
;
4271 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4272 BFD_RELOC_MSP430_SYM_DIFF
);
4273 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4275 if (ssec
== absolute_section
)
4276 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4279 reloc2
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4280 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4283 reloc
->addend
= fixp
->fx_offset
;
4284 if (asec
== absolute_section
)
4286 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4287 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4291 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4292 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4301 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4303 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4304 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4306 switch (fixp
->fx_r_type
)
4309 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4313 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4317 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4321 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4326 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4337 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4338 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4340 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4341 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4343 md_number_to_chars (fixpos
, amount
, 2);
4348 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4349 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4350 reloc
->addend
= fixp
->fx_offset
;
4352 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4353 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4354 reloc
->address
= fixp
->fx_offset
;
4361 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4362 asection
* segment_type ATTRIBUTE_UNUSED
)
4364 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4366 /* This is a jump -> pcrel mode. Nothing to do much here.
4367 Return value == 2. */
4369 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4371 else if (fragP
->fr_symbol
)
4373 /* Its got a segment, but its not ours. Even if fr_symbol is in
4374 an absolute segment, we don't know a displacement until we link
4375 object files. So it will always be long. This also applies to
4376 labels in a subsegment of current. Liker may relax it to short
4377 jump later. Return value == 8. */
4379 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4383 /* We know the abs value. may be it is a jump to fixed address.
4384 Impossible in our case, cause all constants already handled. */
4386 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4389 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4393 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4394 asection
* sec ATTRIBUTE_UNUSED
,
4400 struct rcodes_s
* cc
= NULL
;
4401 struct hcodes_s
* hc
= NULL
;
4403 switch (fragP
->fr_subtype
)
4405 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4406 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4407 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4408 /* We do not have to convert anything here.
4409 Just apply a fix. */
4410 rela
= BFD_RELOC_MSP430_10_PCREL
;
4413 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4414 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4415 /* Convert uncond branch jmp lab -> br lab. */
4416 if (target_is_430x ())
4417 cc
= msp430x_rcodes
+ 7;
4419 cc
= msp430_rcodes
+ 7;
4420 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4421 bfd_putl16 (cc
->lop0
, where
);
4422 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4426 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4427 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4429 /* Other simple branches. */
4430 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4433 /* Find actual instruction. */
4434 if (target_is_430x ())
4436 for (i
= 0; i
< 7 && !cc
; i
++)
4437 if (msp430x_rcodes
[i
].sop
== insn
)
4438 cc
= msp430x_rcodes
+ i
;
4442 for (i
= 0; i
< 7 && !cc
; i
++)
4443 if (msp430_rcodes
[i
].sop
== insn
)
4444 cc
= & msp430_rcodes
[i
];
4447 if (!cc
|| !cc
->name
)
4448 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4449 __FUNCTION__
, (long) insn
);
4450 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4451 bfd_putl16 (cc
->lop0
, where
);
4452 bfd_putl16 (cc
->lop1
, where
+ 2);
4453 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4458 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4459 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4460 if (target_is_430x ())
4461 cc
= msp430x_rcodes
+ 6;
4463 cc
= msp430_rcodes
+ 6;
4464 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4465 bfd_putl16 (cc
->lop0
, where
);
4466 bfd_putl16 (cc
->lop1
, where
+ 2);
4467 bfd_putl16 (cc
->lop2
, where
+ 4);
4468 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4472 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4474 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4477 if (target_is_430x ())
4479 for (i
= 0; i
< 4 && !hc
; i
++)
4480 if (msp430x_hcodes
[i
].op1
== insn
)
4481 hc
= msp430x_hcodes
+ i
;
4485 for (i
= 0; i
< 4 && !hc
; i
++)
4486 if (msp430_hcodes
[i
].op1
== insn
)
4487 hc
= &msp430_hcodes
[i
];
4489 if (!hc
|| !hc
->name
)
4490 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4491 __FUNCTION__
, (long) insn
);
4492 rela
= BFD_RELOC_MSP430_10_PCREL
;
4493 /* Apply a fix for a first label if necessary.
4494 another fix will be applied to the next word of insn anyway. */
4496 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4497 fragP
->fr_offset
, TRUE
, rela
);
4503 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4504 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4506 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4509 if (target_is_430x ())
4511 for (i
= 0; i
< 4 && !hc
; i
++)
4512 if (msp430x_hcodes
[i
].op1
== insn
)
4513 hc
= msp430x_hcodes
+ i
;
4517 for (i
= 0; i
< 4 && !hc
; i
++)
4518 if (msp430_hcodes
[i
].op1
== insn
)
4519 hc
= & msp430_hcodes
[i
];
4521 if (!hc
|| !hc
->name
)
4522 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4523 __FUNCTION__
, (long) insn
);
4524 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4525 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4526 bfd_putl16 (hc
->lop0
, where
);
4527 bfd_putl16 (hc
->lop1
, where
+ 2);
4528 bfd_putl16 (hc
->lop2
, where
+ 4);
4534 as_fatal (_("internal inconsistency problem in %s: %lx"),
4535 __FUNCTION__
, (long) fragP
->fr_subtype
);
4539 /* Now apply fix. */
4540 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4541 fragP
->fr_offset
, TRUE
, rela
);
4542 /* Just fixed 2 bytes. */
4546 /* Relax fragment. Mostly stolen from hc11 and mcore
4547 which arches I think I know. */
4550 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4551 long stretch ATTRIBUTE_UNUSED
)
4556 const relax_typeS
*this_type
;
4557 const relax_typeS
*start_type
;
4558 relax_substateT next_state
;
4559 relax_substateT this_state
;
4560 const relax_typeS
*table
= md_relax_table
;
4562 /* Nothing to be done if the frag has already max size. */
4563 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4564 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4567 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4569 symbolP
= fragP
->fr_symbol
;
4570 if (symbol_resolved_p (symbolP
))
4571 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4573 /* We know the offset. calculate a distance. */
4574 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4577 if (!msp430_enable_relax
)
4579 /* Relaxation is not enabled. So, make all jump as long ones
4580 by setting 'aim' to quite high value. */
4584 this_state
= fragP
->fr_subtype
;
4585 start_type
= this_type
= table
+ this_state
;
4589 /* Look backwards. */
4590 for (next_state
= this_type
->rlx_more
; next_state
;)
4591 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4595 /* Grow to next state. */
4596 this_state
= next_state
;
4597 this_type
= table
+ this_state
;
4598 next_state
= this_type
->rlx_more
;
4603 /* Look forwards. */
4604 for (next_state
= this_type
->rlx_more
; next_state
;)
4605 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4609 /* Grow to next state. */
4610 this_state
= next_state
;
4611 this_type
= table
+ this_state
;
4612 next_state
= this_type
->rlx_more
;
4616 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4618 fragP
->fr_subtype
= this_state
;
4622 /* Return FALSE if the fixup in fixp should be left alone and not
4623 adjusted. We return FALSE here so that linker relaxation will
4627 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4629 /* If the symbol is in a non-code section then it should be OK. */
4631 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4637 /* Set the contents of the .MSP430.attributes section. */
4640 msp430_md_end (void)
4643 as_warn ("assembly finished without a possibly needed NOP instruction");
4645 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4646 target_is_430x () ? 2 : 1);
4648 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4649 large_model
? 2 : 1);
4651 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4652 large_model
? 2 : 1);
4655 /* Returns FALSE if there is a msp430 specific reason why the
4656 subtraction of two same-section symbols cannot be computed by
4660 msp430_allow_local_subtract (expressionS
* left
,
4661 expressionS
* right
,
4664 /* If the symbols are not in a code section then they are OK. */
4665 if ((section
->flags
& SEC_CODE
) == 0)
4668 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4671 if (left
->X_add_symbol
== right
->X_add_symbol
)
4674 /* We have to assume that there may be instructions between the
4675 two symbols and that relaxation may increase the distance between