1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* 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)
699 msp430_set_arch (int option
)
701 char *str
= (char *) alloca (32); /* 32 for good measure. */
703 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
705 md_parse_option (option
, str
);
706 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
707 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
710 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
711 Keep these two structures in sync.
712 The data in this structure has been extracted from the devices.csv file
713 released by TI, updated as of 8 October 2015. */
715 struct msp430_mcu_data
718 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
719 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
723 { "cc430f5123",2,8 },
724 { "cc430f5125",2,8 },
725 { "cc430f5133",2,8 },
726 { "cc430f5135",2,8 },
727 { "cc430f5137",2,8 },
728 { "cc430f5143",2,8 },
729 { "cc430f5145",2,8 },
730 { "cc430f5147",2,8 },
731 { "cc430f6125",2,8 },
732 { "cc430f6126",2,8 },
733 { "cc430f6127",2,8 },
734 { "cc430f6135",2,8 },
735 { "cc430f6137",2,8 },
736 { "cc430f6143",2,8 },
737 { "cc430f6145",2,8 },
738 { "cc430f6147",2,8 },
739 { "msp430afe221",0,2 },
740 { "msp430afe222",0,2 },
741 { "msp430afe223",0,2 },
742 { "msp430afe231",0,2 },
743 { "msp430afe232",0,2 },
744 { "msp430afe233",0,2 },
745 { "msp430afe251",0,2 },
746 { "msp430afe252",0,2 },
747 { "msp430afe253",0,2 },
748 { "msp430bt5190",2,8 },
749 { "msp430c091",0,0 },
750 { "msp430c092",0,0 },
751 { "msp430c111",0,0 },
752 { "msp430c1111",0,0 },
753 { "msp430c112",0,0 },
754 { "msp430c1121",0,0 },
755 { "msp430c1331",0,0 },
756 { "msp430c1351",0,0 },
757 { "msp430c311s",0,0 },
758 { "msp430c312",0,0 },
759 { "msp430c313",0,0 },
760 { "msp430c314",0,0 },
761 { "msp430c315",0,0 },
762 { "msp430c323",0,0 },
763 { "msp430c325",0,0 },
764 { "msp430c336",0,1 },
765 { "msp430c337",0,1 },
766 { "msp430c412",0,0 },
767 { "msp430c413",0,0 },
768 { "msp430cg4616",1,1 },
769 { "msp430cg4617",1,1 },
770 { "msp430cg4618",1,1 },
771 { "msp430cg4619",1,1 },
772 { "msp430e112",0,0 },
773 { "msp430e313",0,0 },
774 { "msp430e315",0,0 },
775 { "msp430e325",0,0 },
776 { "msp430e337",0,1 },
777 { "msp430f110",0,0 },
778 { "msp430f1101",0,0 },
779 { "msp430f1101a",0,0 },
780 { "msp430f1111",0,0 },
781 { "msp430f1111a",0,0 },
782 { "msp430f112",0,0 },
783 { "msp430f1121",0,0 },
784 { "msp430f1121a",0,0 },
785 { "msp430f1122",0,0 },
786 { "msp430f1132",0,0 },
787 { "msp430f122",0,0 },
788 { "msp430f1222",0,0 },
789 { "msp430f123",0,0 },
790 { "msp430f1232",0,0 },
791 { "msp430f133",0,0 },
792 { "msp430f135",0,0 },
793 { "msp430f147",0,1 },
794 { "msp430f1471",0,1 },
795 { "msp430f148",0,1 },
796 { "msp430f1481",0,1 },
797 { "msp430f149",0,1 },
798 { "msp430f1491",0,1 },
799 { "msp430f155",0,0 },
800 { "msp430f156",0,0 },
801 { "msp430f157",0,0 },
802 { "msp430f1610",0,1 },
803 { "msp430f1611",0,1 },
804 { "msp430f1612",0,1 },
805 { "msp430f167",0,1 },
806 { "msp430f168",0,1 },
807 { "msp430f169",0,1 },
808 { "msp430f2001",0,0 },
809 { "msp430f2002",0,0 },
810 { "msp430f2003",0,0 },
811 { "msp430f2011",0,0 },
812 { "msp430f2012",0,0 },
813 { "msp430f2013",0,0 },
814 { "msp430f2101",0,0 },
815 { "msp430f2111",0,0 },
816 { "msp430f2112",0,0 },
817 { "msp430f2121",0,0 },
818 { "msp430f2122",0,0 },
819 { "msp430f2131",0,0 },
820 { "msp430f2132",0,0 },
821 { "msp430f2232",0,0 },
822 { "msp430f2234",0,0 },
823 { "msp430f2252",0,0 },
824 { "msp430f2254",0,0 },
825 { "msp430f2272",0,0 },
826 { "msp430f2274",0,0 },
827 { "msp430f233",0,2 },
828 { "msp430f2330",0,2 },
829 { "msp430f235",0,2 },
830 { "msp430f2350",0,2 },
831 { "msp430f2370",0,2 },
832 { "msp430f2410",0,2 },
833 { "msp430f2416",1,2 },
834 { "msp430f2417",1,2 },
835 { "msp430f2418",1,2 },
836 { "msp430f2419",1,2 },
837 { "msp430f247",0,2 },
838 { "msp430f2471",0,2 },
839 { "msp430f248",0,2 },
840 { "msp430f2481",0,2 },
841 { "msp430f249",0,2 },
842 { "msp430f2491",0,2 },
843 { "msp430f2616",1,2 },
844 { "msp430f2617",1,2 },
845 { "msp430f2618",1,2 },
846 { "msp430f2619",1,2 },
847 { "msp430f412",0,0 },
848 { "msp430f413",0,0 },
849 { "msp430f4132",0,0 },
850 { "msp430f415",0,0 },
851 { "msp430f4152",0,0 },
852 { "msp430f417",0,0 },
853 { "msp430f423",0,1 },
854 { "msp430f423a",0,1 },
855 { "msp430f425",0,1 },
856 { "msp430f4250",0,0 },
857 { "msp430f425a",0,1 },
858 { "msp430f4260",0,0 },
859 { "msp430f427",0,1 },
860 { "msp430f4270",0,0 },
861 { "msp430f427a",0,1 },
862 { "msp430f435",0,0 },
863 { "msp430f4351",0,0 },
864 { "msp430f436",0,0 },
865 { "msp430f4361",0,0 },
866 { "msp430f437",0,0 },
867 { "msp430f4371",0,0 },
868 { "msp430f438",0,0 },
869 { "msp430f439",0,0 },
870 { "msp430f447",0,1 },
871 { "msp430f448",0,1 },
872 { "msp430f4481",0,1 },
873 { "msp430f449",0,1 },
874 { "msp430f4491",0,1 },
875 { "msp430f4616",1,1 },
876 { "msp430f46161",1,1 },
877 { "msp430f4617",1,1 },
878 { "msp430f46171",1,1 },
879 { "msp430f4618",1,1 },
880 { "msp430f46181",1,1 },
881 { "msp430f4619",1,1 },
882 { "msp430f46191",1,1 },
883 { "msp430f47126",1,4 },
884 { "msp430f47127",1,4 },
885 { "msp430f47163",1,4 },
886 { "msp430f47166",1,4 },
887 { "msp430f47167",1,4 },
888 { "msp430f47173",1,4 },
889 { "msp430f47176",1,4 },
890 { "msp430f47177",1,4 },
891 { "msp430f47183",1,4 },
892 { "msp430f47186",1,4 },
893 { "msp430f47187",1,4 },
894 { "msp430f47193",1,4 },
895 { "msp430f47196",1,4 },
896 { "msp430f47197",1,4 },
897 { "msp430f477",0,0 },
898 { "msp430f478",0,0 },
899 { "msp430f4783",0,4 },
900 { "msp430f4784",0,4 },
901 { "msp430f479",0,0 },
902 { "msp430f4793",0,4 },
903 { "msp430f4794",0,4 },
904 { "msp430f5131",2,8 },
905 { "msp430f5132",2,8 },
906 { "msp430f5151",2,8 },
907 { "msp430f5152",2,8 },
908 { "msp430f5171",2,8 },
909 { "msp430f5172",2,8 },
910 { "msp430f5212",2,8 },
911 { "msp430f5213",2,8 },
912 { "msp430f5214",2,8 },
913 { "msp430f5217",2,8 },
914 { "msp430f5218",2,8 },
915 { "msp430f5219",2,8 },
916 { "msp430f5222",2,8 },
917 { "msp430f5223",2,8 },
918 { "msp430f5224",2,8 },
919 { "msp430f5227",2,8 },
920 { "msp430f5228",2,8 },
921 { "msp430f5229",2,8 },
922 { "msp430f5232",2,8 },
923 { "msp430f5234",2,8 },
924 { "msp430f5237",2,8 },
925 { "msp430f5239",2,8 },
926 { "msp430f5242",2,8 },
927 { "msp430f5244",2,8 },
928 { "msp430f5247",2,8 },
929 { "msp430f5249",2,8 },
930 { "msp430f5252",2,8 },
931 { "msp430f5253",2,8 },
932 { "msp430f5254",2,8 },
933 { "msp430f5255",2,8 },
934 { "msp430f5256",2,8 },
935 { "msp430f5257",2,8 },
936 { "msp430f5258",2,8 },
937 { "msp430f5259",2,8 },
938 { "msp430f5304",2,8 },
939 { "msp430f5308",2,8 },
940 { "msp430f5309",2,8 },
941 { "msp430f5310",2,8 },
942 { "msp430f5324",2,8 },
943 { "msp430f5325",2,8 },
944 { "msp430f5326",2,8 },
945 { "msp430f5327",2,8 },
946 { "msp430f5328",2,8 },
947 { "msp430f5329",2,8 },
948 { "msp430f5333",2,8 },
949 { "msp430f5335",2,8 },
950 { "msp430f5336",2,8 },
951 { "msp430f5338",2,8 },
952 { "msp430f5340",2,8 },
953 { "msp430f5341",2,8 },
954 { "msp430f5342",2,8 },
955 { "msp430f5358",2,8 },
956 { "msp430f5359",2,8 },
957 { "msp430f5418",2,8 },
958 { "msp430f5418a",2,8 },
959 { "msp430f5419",2,8 },
960 { "msp430f5419a",2,8 },
961 { "msp430f5435",2,8 },
962 { "msp430f5435a",2,8 },
963 { "msp430f5436",2,8 },
964 { "msp430f5436a",2,8 },
965 { "msp430f5437",2,8 },
966 { "msp430f5437a",2,8 },
967 { "msp430f5438",2,8 },
968 { "msp430f5438a",2,8 },
969 { "msp430f5500",2,8 },
970 { "msp430f5501",2,8 },
971 { "msp430f5502",2,8 },
972 { "msp430f5503",2,8 },
973 { "msp430f5504",2,8 },
974 { "msp430f5505",2,8 },
975 { "msp430f5506",2,8 },
976 { "msp430f5507",2,8 },
977 { "msp430f5508",2,8 },
978 { "msp430f5509",2,8 },
979 { "msp430f5510",2,8 },
980 { "msp430f5513",2,8 },
981 { "msp430f5514",2,8 },
982 { "msp430f5515",2,8 },
983 { "msp430f5517",2,8 },
984 { "msp430f5519",2,8 },
985 { "msp430f5521",2,8 },
986 { "msp430f5522",2,8 },
987 { "msp430f5524",2,8 },
988 { "msp430f5525",2,8 },
989 { "msp430f5526",2,8 },
990 { "msp430f5527",2,8 },
991 { "msp430f5528",2,8 },
992 { "msp430f5529",2,8 },
993 { "msp430f5630",2,8 },
994 { "msp430f5631",2,8 },
995 { "msp430f5632",2,8 },
996 { "msp430f5633",2,8 },
997 { "msp430f5634",2,8 },
998 { "msp430f5635",2,8 },
999 { "msp430f5636",2,8 },
1000 { "msp430f5637",2,8 },
1001 { "msp430f5638",2,8 },
1002 { "msp430f5658",2,8 },
1003 { "msp430f5659",2,8 },
1004 { "msp430f5xx_6xxgeneric",2,8 },
1005 { "msp430f6433",2,8 },
1006 { "msp430f6435",2,8 },
1007 { "msp430f6436",2,8 },
1008 { "msp430f6438",2,8 },
1009 { "msp430f6458",2,8 },
1010 { "msp430f6459",2,8 },
1011 { "msp430f6630",2,8 },
1012 { "msp430f6631",2,8 },
1013 { "msp430f6632",2,8 },
1014 { "msp430f6633",2,8 },
1015 { "msp430f6634",2,8 },
1016 { "msp430f6635",2,8 },
1017 { "msp430f6636",2,8 },
1018 { "msp430f6637",2,8 },
1019 { "msp430f6638",2,8 },
1020 { "msp430f6658",2,8 },
1021 { "msp430f6659",2,8 },
1022 { "msp430f6720",2,8 },
1023 { "msp430f6720a",2,8 },
1024 { "msp430f6721",2,8 },
1025 { "msp430f6721a",2,8 },
1026 { "msp430f6723",2,8 },
1027 { "msp430f6723a",2,8 },
1028 { "msp430f6724",2,8 },
1029 { "msp430f6724a",2,8 },
1030 { "msp430f6725",2,8 },
1031 { "msp430f6725a",2,8 },
1032 { "msp430f6726",2,8 },
1033 { "msp430f6726a",2,8 },
1034 { "msp430f6730",2,8 },
1035 { "msp430f6730a",2,8 },
1036 { "msp430f6731",2,8 },
1037 { "msp430f6731a",2,8 },
1038 { "msp430f6733",2,8 },
1039 { "msp430f6733a",2,8 },
1040 { "msp430f6734",2,8 },
1041 { "msp430f6734a",2,8 },
1042 { "msp430f6735",2,8 },
1043 { "msp430f6735a",2,8 },
1044 { "msp430f6736",2,8 },
1045 { "msp430f6736a",2,8 },
1046 { "msp430f6745",2,8 },
1047 { "msp430f67451",2,8 },
1048 { "msp430f67451a",2,8 },
1049 { "msp430f6745a",2,8 },
1050 { "msp430f6746",2,8 },
1051 { "msp430f67461",2,8 },
1052 { "msp430f67461a",2,8 },
1053 { "msp430f6746a",2,8 },
1054 { "msp430f6747",2,8 },
1055 { "msp430f67471",2,8 },
1056 { "msp430f67471a",2,8 },
1057 { "msp430f6747a",2,8 },
1058 { "msp430f6748",2,8 },
1059 { "msp430f67481",2,8 },
1060 { "msp430f67481a",2,8 },
1061 { "msp430f6748a",2,8 },
1062 { "msp430f6749",2,8 },
1063 { "msp430f67491",2,8 },
1064 { "msp430f67491a",2,8 },
1065 { "msp430f6749a",2,8 },
1066 { "msp430f67621",2,8 },
1067 { "msp430f67621a",2,8 },
1068 { "msp430f67641",2,8 },
1069 { "msp430f67641a",2,8 },
1070 { "msp430f6765",2,8 },
1071 { "msp430f67651",2,8 },
1072 { "msp430f67651a",2,8 },
1073 { "msp430f6765a",2,8 },
1074 { "msp430f6766",2,8 },
1075 { "msp430f67661",2,8 },
1076 { "msp430f67661a",2,8 },
1077 { "msp430f6766a",2,8 },
1078 { "msp430f6767",2,8 },
1079 { "msp430f67671",2,8 },
1080 { "msp430f67671a",2,8 },
1081 { "msp430f6767a",2,8 },
1082 { "msp430f6768",2,8 },
1083 { "msp430f67681",2,8 },
1084 { "msp430f67681a",2,8 },
1085 { "msp430f6768a",2,8 },
1086 { "msp430f6769",2,8 },
1087 { "msp430f67691",2,8 },
1088 { "msp430f67691a",2,8 },
1089 { "msp430f6769a",2,8 },
1090 { "msp430f6775",2,8 },
1091 { "msp430f67751",2,8 },
1092 { "msp430f67751a",2,8 },
1093 { "msp430f6775a",2,8 },
1094 { "msp430f6776",2,8 },
1095 { "msp430f67761",2,8 },
1096 { "msp430f67761a",2,8 },
1097 { "msp430f6776a",2,8 },
1098 { "msp430f6777",2,8 },
1099 { "msp430f67771",2,8 },
1100 { "msp430f67771a",2,8 },
1101 { "msp430f6777a",2,8 },
1102 { "msp430f6778",2,8 },
1103 { "msp430f67781",2,8 },
1104 { "msp430f67781a",2,8 },
1105 { "msp430f6778a",2,8 },
1106 { "msp430f6779",2,8 },
1107 { "msp430f67791",2,8 },
1108 { "msp430f67791a",2,8 },
1109 { "msp430f6779a",2,8 },
1110 { "msp430fe423",0,0 },
1111 { "msp430fe4232",0,0 },
1112 { "msp430fe423a",0,0 },
1113 { "msp430fe4242",0,0 },
1114 { "msp430fe425",0,0 },
1115 { "msp430fe4252",0,0 },
1116 { "msp430fe425a",0,0 },
1117 { "msp430fe427",0,0 },
1118 { "msp430fe4272",0,0 },
1119 { "msp430fe427a",0,0 },
1120 { "msp430fg4250",0,0 },
1121 { "msp430fg4260",0,0 },
1122 { "msp430fg4270",0,0 },
1123 { "msp430fg437",0,0 },
1124 { "msp430fg438",0,0 },
1125 { "msp430fg439",0,0 },
1126 { "msp430fg4616",1,1 },
1127 { "msp430fg4617",1,1 },
1128 { "msp430fg4618",1,1 },
1129 { "msp430fg4619",1,1 },
1130 { "msp430fg477",0,0 },
1131 { "msp430fg478",0,0 },
1132 { "msp430fg479",0,0 },
1133 { "msp430fg6425",2,8 },
1134 { "msp430fg6426",2,8 },
1135 { "msp430fg6625",2,8 },
1136 { "msp430fg6626",2,8 },
1137 { "msp430fr2032",2,0 },
1138 { "msp430fr2033",2,0 },
1139 { "msp430fr2433",2,8 },
1140 { "msp430fr2xx_4xxgeneric",2,8 },
1141 { "msp430fr4131",2,0 },
1142 { "msp430fr4132",2,0 },
1143 { "msp430fr4133",2,0 },
1144 { "msp430fr5720",2,8 },
1145 { "msp430fr5721",2,8 },
1146 { "msp430fr5722",2,8 },
1147 { "msp430fr5723",2,8 },
1148 { "msp430fr5724",2,8 },
1149 { "msp430fr5725",2,8 },
1150 { "msp430fr5726",2,8 },
1151 { "msp430fr5727",2,8 },
1152 { "msp430fr5728",2,8 },
1153 { "msp430fr5729",2,8 },
1154 { "msp430fr5730",2,8 },
1155 { "msp430fr5731",2,8 },
1156 { "msp430fr5732",2,8 },
1157 { "msp430fr5733",2,8 },
1158 { "msp430fr5734",2,8 },
1159 { "msp430fr5735",2,8 },
1160 { "msp430fr5736",2,8 },
1161 { "msp430fr5737",2,8 },
1162 { "msp430fr5738",2,8 },
1163 { "msp430fr5739",2,8 },
1164 { "msp430fr57xxgeneric",2,8 },
1165 { "msp430fr5847",2,8 },
1166 { "msp430fr58471",2,8 },
1167 { "msp430fr5848",2,8 },
1168 { "msp430fr5849",2,8 },
1169 { "msp430fr5857",2,8 },
1170 { "msp430fr5858",2,8 },
1171 { "msp430fr5859",2,8 },
1172 { "msp430fr5867",2,8 },
1173 { "msp430fr58671",2,8 },
1174 { "msp430fr5868",2,8 },
1175 { "msp430fr5869",2,8 },
1176 { "msp430fr5870",2,8 },
1177 { "msp430fr5872",2,8 },
1178 { "msp430fr58721",2,8 },
1179 { "msp430fr5887",2,8 },
1180 { "msp430fr5888",2,8 },
1181 { "msp430fr5889",2,8 },
1182 { "msp430fr58891",2,8 },
1183 { "msp430fr5922",2,8 },
1184 { "msp430fr59221",2,8 },
1185 { "msp430fr5947",2,8 },
1186 { "msp430fr59471",2,8 },
1187 { "msp430fr5948",2,8 },
1188 { "msp430fr5949",2,8 },
1189 { "msp430fr5957",2,8 },
1190 { "msp430fr5958",2,8 },
1191 { "msp430fr5959",2,8 },
1192 { "msp430fr5967",2,8 },
1193 { "msp430fr5968",2,8 },
1194 { "msp430fr5969",2,8 },
1195 { "msp430fr59691",2,8 },
1196 { "msp430fr5970",2,8 },
1197 { "msp430fr5972",2,8 },
1198 { "msp430fr59721",2,8 },
1199 { "msp430fr5986",2,8 },
1200 { "msp430fr5987",2,8 },
1201 { "msp430fr5988",2,8 },
1202 { "msp430fr5989",2,8 },
1203 { "msp430fr59891",2,8 },
1204 { "msp430fr5xx_6xxgeneric",2,8 },
1205 { "msp430fr6820",2,8 },
1206 { "msp430fr6822",2,8 },
1207 { "msp430fr68221",2,8 },
1208 { "msp430fr6870",2,8 },
1209 { "msp430fr6872",2,8 },
1210 { "msp430fr68721",2,8 },
1211 { "msp430fr6877",2,8 },
1212 { "msp430fr6879",2,8 },
1213 { "msp430fr68791",2,8 },
1214 { "msp430fr6887",2,8 },
1215 { "msp430fr6888",2,8 },
1216 { "msp430fr6889",2,8 },
1217 { "msp430fr68891",2,8 },
1218 { "msp430fr6920",2,8 },
1219 { "msp430fr6922",2,8 },
1220 { "msp430fr69221",2,8 },
1221 { "msp430fr6927",2,8 },
1222 { "msp430fr69271",2,8 },
1223 { "msp430fr6928",2,8 },
1224 { "msp430fr6970",2,8 },
1225 { "msp430fr6972",2,8 },
1226 { "msp430fr69721",2,8 },
1227 { "msp430fr6977",2,8 },
1228 { "msp430fr6979",2,8 },
1229 { "msp430fr69791",2,8 },
1230 { "msp430fr6987",2,8 },
1231 { "msp430fr6988",2,8 },
1232 { "msp430fr6989",2,8 },
1233 { "msp430fr69891",2,8 },
1234 { "msp430fw423",0,0 },
1235 { "msp430fw425",0,0 },
1236 { "msp430fw427",0,0 },
1237 { "msp430fw428",0,0 },
1238 { "msp430fw429",0,0 },
1239 { "msp430g2001",0,0 },
1240 { "msp430g2101",0,0 },
1241 { "msp430g2102",0,0 },
1242 { "msp430g2111",0,0 },
1243 { "msp430g2112",0,0 },
1244 { "msp430g2113",0,0 },
1245 { "msp430g2121",0,0 },
1246 { "msp430g2131",0,0 },
1247 { "msp430g2132",0,0 },
1248 { "msp430g2152",0,0 },
1249 { "msp430g2153",0,0 },
1250 { "msp430g2201",0,0 },
1251 { "msp430g2202",0,0 },
1252 { "msp430g2203",0,0 },
1253 { "msp430g2210",0,0 },
1254 { "msp430g2211",0,0 },
1255 { "msp430g2212",0,0 },
1256 { "msp430g2213",0,0 },
1257 { "msp430g2221",0,0 },
1258 { "msp430g2230",0,0 },
1259 { "msp430g2231",0,0 },
1260 { "msp430g2232",0,0 },
1261 { "msp430g2233",0,0 },
1262 { "msp430g2252",0,0 },
1263 { "msp430g2253",0,0 },
1264 { "msp430g2302",0,0 },
1265 { "msp430g2303",0,0 },
1266 { "msp430g2312",0,0 },
1267 { "msp430g2313",0,0 },
1268 { "msp430g2332",0,0 },
1269 { "msp430g2333",0,0 },
1270 { "msp430g2352",0,0 },
1271 { "msp430g2353",0,0 },
1272 { "msp430g2402",0,0 },
1273 { "msp430g2403",0,0 },
1274 { "msp430g2412",0,0 },
1275 { "msp430g2413",0,0 },
1276 { "msp430g2432",0,0 },
1277 { "msp430g2433",0,0 },
1278 { "msp430g2444",0,0 },
1279 { "msp430g2452",0,0 },
1280 { "msp430g2453",0,0 },
1281 { "msp430g2513",0,0 },
1282 { "msp430g2533",0,0 },
1283 { "msp430g2544",0,0 },
1284 { "msp430g2553",0,0 },
1285 { "msp430g2744",0,0 },
1286 { "msp430g2755",0,0 },
1287 { "msp430g2855",0,0 },
1288 { "msp430g2955",0,0 },
1289 { "msp430i2020",0,2 },
1290 { "msp430i2021",0,2 },
1291 { "msp430i2030",0,2 },
1292 { "msp430i2031",0,2 },
1293 { "msp430i2040",0,2 },
1294 { "msp430i2041",0,2 },
1295 { "msp430i2xxgeneric",0,2 },
1296 { "msp430l092",0,0 },
1297 { "msp430p112",0,0 },
1298 { "msp430p313",0,0 },
1299 { "msp430p315",0,0 },
1300 { "msp430p315s",0,0 },
1301 { "msp430p325",0,0 },
1302 { "msp430p337",0,1 },
1303 { "msp430sl5438a",2,8 },
1304 { "msp430tch5e",0,0 },
1305 { "msp430xgeneric",2,8 },
1306 { "rf430f5144",2,8 },
1307 { "rf430f5155",2,8 },
1308 { "rf430f5175",2,8 },
1309 { "rf430frl152h",0,0 },
1310 { "rf430frl152h_rom",0,0 },
1311 { "rf430frl153h",0,0 },
1312 { "rf430frl153h_rom",0,0 },
1313 { "rf430frl154h",0,0 },
1314 { "rf430frl154h_rom",0,0 }
1318 md_parse_option (int c
, char * arg
)
1322 case OPTION_SILICON_ERRATA
:
1323 case OPTION_SILICON_ERRATA_WARN
:
1329 unsigned int length
;
1330 unsigned int bitfield
;
1333 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1334 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1335 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1336 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1337 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1338 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1343 for (i
= ARRAY_SIZE (erratas
); i
--;)
1344 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1346 if (c
== OPTION_SILICON_ERRATA
)
1347 silicon_errata_fix
|= erratas
[i
].bitfield
;
1349 silicon_errata_warn
|= erratas
[i
].bitfield
;
1350 arg
+= erratas
[i
].length
;
1355 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1361 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1371 as_fatal (_("MCU option requires a name\n"));
1373 if (strcasecmp ("msp430", arg
) == 0)
1374 selected_isa
= MSP_ISA_430
;
1375 else if (strcasecmp ("msp430xv2", arg
) == 0)
1376 selected_isa
= MSP_ISA_430Xv2
;
1377 else if (strcasecmp ("msp430x", arg
) == 0)
1378 selected_isa
= MSP_ISA_430X
;
1383 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1384 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1386 switch (msp430_mcu_data
[i
].revision
)
1388 case 0: selected_isa
= MSP_ISA_430
; break;
1389 case 1: selected_isa
= MSP_ISA_430X
; break;
1390 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1395 /* It is not an error if we do not match the MCU name. */
1399 if (strcmp (arg
, "430") == 0
1400 || strcasecmp (arg
, "msp430") == 0)
1401 selected_isa
= MSP_ISA_430
;
1402 else if (strcasecmp (arg
, "430x") == 0
1403 || strcasecmp (arg
, "msp430x") == 0)
1404 selected_isa
= MSP_ISA_430X
;
1405 else if (strcasecmp (arg
, "430xv2") == 0
1406 || strcasecmp (arg
, "msp430xv2") == 0)
1407 selected_isa
= MSP_ISA_430Xv2
;
1409 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1413 msp430_enable_relax
= 1;
1416 case OPTION_POLYMORPHS
:
1417 msp430_enable_polys
= 1;
1424 case OPTION_NO_INTR_NOPS
:
1425 gen_interrupt_nops
= FALSE
;
1427 case OPTION_INTR_NOPS
:
1428 gen_interrupt_nops
= TRUE
;
1431 case OPTION_WARN_INTR_NOPS
:
1432 warn_interrupt_nops
= TRUE
;
1434 case OPTION_NO_WARN_INTR_NOPS
:
1435 warn_interrupt_nops
= FALSE
;
1438 case OPTION_MOVE_DATA
:
1446 /* The intention here is to have the mere presence of these sections
1447 cause the object to have a reference to a well-known symbol. This
1448 reference pulls in the bits of the runtime (crt0) that initialize
1449 these sections. Thus, for example, the startup code to call
1450 memset() to initialize .bss will only be linked in when there is a
1451 non-empty .bss section. Otherwise, the call would exist but have a
1452 zero length parameter, which is a waste of memory and cycles.
1454 The code which initializes these sections should have a global
1455 label for these symbols, and should be marked with KEEP() in the
1459 msp430_make_init_symbols (const char * name
)
1461 if (strncmp (name
, ".bss", 4) == 0
1462 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1463 (void) symbol_find_or_make ("__crt0_init_bss");
1465 if (strncmp (name
, ".data", 5) == 0
1466 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1467 (void) symbol_find_or_make ("__crt0_movedata");
1469 /* Note - data assigned to the .either.data section may end up being
1470 placed in the .upper.data section if the .lower.data section is
1471 full. Hence the need to define the crt0 symbol. */
1472 if (strncmp (name
, ".either.data", 12) == 0
1473 || strncmp (name
, ".upper.data", 11) == 0)
1474 (void) symbol_find_or_make ("__crt0_move_highdata");
1476 /* See note about .either.data above. */
1477 if (strncmp (name
, ".upper.bss", 10) == 0
1478 || strncmp (name
, ".either.bss", 11) == 0)
1479 (void) symbol_find_or_make ("__crt0_init_highbss");
1483 msp430_section (int arg
)
1485 char * saved_ilp
= input_line_pointer
;
1486 char * name
= obj_elf_section_name ();
1488 msp430_make_init_symbols (name
);
1490 input_line_pointer
= saved_ilp
;
1491 obj_elf_section (arg
);
1495 msp430_frob_section (asection
*sec
)
1497 const char *name
= sec
->name
;
1502 msp430_make_init_symbols (name
);
1506 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1508 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1511 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1512 (void) symbol_find_or_make ("__crt0_init_bss");
1516 msp430_comm (int needs_align
)
1518 s_comm_internal (needs_align
, elf_common_parse
);
1519 (void) symbol_find_or_make ("__crt0_init_bss");
1523 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1525 char sym_name
[1024];
1526 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1528 (void) symbol_find_or_make (sym_name
);
1531 const pseudo_typeS md_pseudo_table
[] =
1533 {"arch", msp430_set_arch
, OPTION_MMCU
},
1534 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1535 {"profiler", msp430_profiler
, 0},
1536 {"section", msp430_section
, 0},
1537 {"section.s", msp430_section
, 0},
1538 {"sect", msp430_section
, 0},
1539 {"sect.s", msp430_section
, 0},
1540 {"pushsection", msp430_section
, 1},
1541 {"refsym", msp430_refsym
, 0},
1542 {"comm", msp430_comm
, 0},
1543 {"lcomm", msp430_lcomm
, 0},
1547 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1549 struct option md_longopts
[] =
1551 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1552 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1553 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1554 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1555 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1556 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1557 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1558 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1559 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1560 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1561 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1562 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1563 {NULL
, no_argument
, NULL
, 0}
1566 size_t md_longopts_size
= sizeof (md_longopts
);
1569 md_show_usage (FILE * stream
)
1572 _("MSP430 options:\n"
1573 " -mmcu=<msp430-name> - select microcontroller type\n"
1574 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1576 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1577 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1578 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1580 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1581 " -mP - enable polymorph instructions\n"));
1583 _(" -ml - enable large code model\n"));
1585 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1587 _(" -mn - insert a NOP after changing interrupts\n"));
1589 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1591 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1593 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1597 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1603 extract_cmd (char * from
, char * to
, int limit
)
1607 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1609 *(to
+ size
) = *from
;
1620 md_atof (int type
, char * litP
, int * sizeP
)
1622 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1628 struct msp430_opcode_s
* opcode
;
1629 msp430_hash
= hash_new ();
1631 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1632 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1634 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1635 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1638 /* Returns the register number equivalent to the string T.
1639 Returns -1 if there is no such register.
1640 Skips a leading 'r' or 'R' character if there is one.
1641 Handles the register aliases PC and SP. */
1644 check_reg (char * t
)
1651 if (*t
== 'r' || *t
== 'R')
1654 if (strncasecmp (t
, "pc", 2) == 0)
1657 if (strncasecmp (t
, "sp", 2) == 0)
1660 if (strncasecmp (t
, "sr", 2) == 0)
1668 if (val
< 1 || val
> 15)
1675 msp430_srcoperand (struct msp430_operand_s
* op
,
1678 bfd_boolean
* imm_op
,
1679 bfd_boolean allow_20bit_values
,
1680 bfd_boolean constants_allowed
)
1684 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1691 /* Check if there is:
1692 llo(x) - least significant 16 bits, x &= 0xffff
1693 lhi(x) - x = (x >> 16) & 0xffff,
1694 hlo(x) - x = (x >> 32) & 0xffff,
1695 hhi(x) - x = (x >> 48) & 0xffff
1696 The value _MUST_ be constant expression: #hlo(1231231231). */
1700 if (strncasecmp (h
, "#llo(", 5) == 0)
1705 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1710 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1715 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1720 else if (strncasecmp (h
, "#lo(", 4) == 0)
1725 else if (strncasecmp (h
, "#hi(", 4) == 0)
1731 op
->reg
= 0; /* Reg PC. */
1733 op
->ol
= 1; /* Immediate will follow an instruction. */
1734 __tl
= h
+ 1 + rval
;
1736 op
->vshift
= vshift
;
1738 parse_exp (__tl
, &(op
->exp
));
1739 if (op
->exp
.X_op
== O_constant
)
1741 int x
= op
->exp
.X_add_number
;
1746 op
->exp
.X_add_number
= x
;
1748 else if (vshift
== 1)
1750 x
= (x
>> 16) & 0xffff;
1751 op
->exp
.X_add_number
= x
;
1754 else if (vshift
> 1)
1757 op
->exp
.X_add_number
= -1;
1759 op
->exp
.X_add_number
= 0; /* Nothing left. */
1760 x
= op
->exp
.X_add_number
;
1764 if (allow_20bit_values
)
1766 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1768 as_bad (_("value 0x%x out of extended range."), x
);
1772 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1774 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1778 /* Now check constants. */
1779 /* Substitute register mode with a constant generator if applicable. */
1781 if (!allow_20bit_values
)
1782 x
= (short) x
; /* Extend sign. */
1784 if (! constants_allowed
)
1816 if (bin
== 0x1200 && ! target_is_430x ())
1818 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1819 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1820 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1821 /* No need to check silicon_errata_fixes - this fix is always implemented. */
1833 if (bin
== 0x1200 && ! target_is_430x ())
1835 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1836 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
1837 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
1848 else if (op
->exp
.X_op
== O_symbol
)
1851 as_bad (_("error: unsupported #foo() directive used on symbol"));
1854 else if (op
->exp
.X_op
== O_big
)
1860 op
->exp
.X_op
= O_constant
;
1861 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1862 x
= op
->exp
.X_add_number
;
1868 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1916 /* Redundant (yet) check. */
1917 else if (op
->exp
.X_op
== O_register
)
1919 (_("Registers cannot be used within immediate expression [%s]"), l
);
1921 as_bad (_("unknown operand %s"), l
);
1926 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1931 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1932 op
->am
= 1; /* mode As == 01 bin. */
1933 op
->ol
= 1; /* Immediate value followed by instruction. */
1935 parse_exp (__tl
, &(op
->exp
));
1938 if (op
->exp
.X_op
== O_constant
)
1940 int x
= op
->exp
.X_add_number
;
1942 if (allow_20bit_values
)
1944 if (x
> 0xfffff || x
< -(0x7ffff))
1946 as_bad (_("value 0x%x out of extended range."), x
);
1950 else if (x
> 65535 || x
< -32768)
1952 as_bad (_("value out of range: 0x%x"), x
);
1956 else if (op
->exp
.X_op
== O_symbol
)
1960 /* Redundant (yet) check. */
1961 if (op
->exp
.X_op
== O_register
)
1963 (_("Registers cannot be used within absolute expression [%s]"), l
);
1965 as_bad (_("unknown expression in operand %s"), l
);
1971 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1975 char *m
= strchr (l
, '+');
1979 as_bad (_("unknown addressing mode %s"), l
);
1985 if ((op
->reg
= check_reg (t
)) == -1)
1987 as_bad (_("Bad register name %s"), t
);
1995 /* PC cannot be used in indirect addressing. */
1996 if (target_is_430xv2 () && op
->reg
== 0)
1998 as_bad (_("cannot use indirect addressing with the PC"));
2005 /* Check if register indexed X(Rn). */
2008 char *h
= strrchr (l
, '(');
2009 char *m
= strrchr (l
, ')');
2018 as_bad (_("')' required"));
2026 /* Extract a register. */
2027 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2030 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2037 as_bad (_("r2 should not be used in indexed addressing mode"));
2041 /* Extract constant. */
2046 parse_exp (__tl
, &(op
->exp
));
2047 if (op
->exp
.X_op
== O_constant
)
2049 int x
= op
->exp
.X_add_number
;
2051 if (allow_20bit_values
)
2053 if (x
> 0xfffff || x
< - (0x7ffff))
2055 as_bad (_("value 0x%x out of extended range."), x
);
2059 else if (x
> 65535 || x
< -32768)
2061 as_bad (_("value out of range: 0x%x"), x
);
2073 if (op
->reg
== 1 && (x
& 1))
2075 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2076 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2077 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2078 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2081 else if (op
->exp
.X_op
== O_symbol
)
2085 /* Redundant (yet) check. */
2086 if (op
->exp
.X_op
== O_register
)
2088 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2090 as_bad (_("unknown expression in operand %s"), l
);
2098 /* Possibly register mode 'mov r1,r2'. */
2099 if ((op
->reg
= check_reg (l
)) != -1)
2107 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2111 op
->reg
= 0; /* PC relative... be careful. */
2112 /* An expression starting with a minus sign is a constant, not an address. */
2113 op
->am
= (*l
== '-' ? 3 : 1);
2117 parse_exp (__tl
, &(op
->exp
));
2123 as_bad (_("unknown addressing mode for operand %s"), l
);
2129 msp430_dstoperand (struct msp430_operand_s
* op
,
2132 bfd_boolean allow_20bit_values
,
2133 bfd_boolean constants_allowed
)
2136 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2151 parse_exp (__tl
, &(op
->exp
));
2153 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2155 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2165 ("this addressing mode is not applicable for destination operand"));
2171 /* Attempt to encode a MOVA instruction with the given operands.
2172 Returns the length of the encoded instruction if successful
2173 or 0 upon failure. If the encoding fails, an error message
2174 will be returned if a pointer is provided. */
2177 try_encode_mova (bfd_boolean imm_op
,
2179 struct msp430_operand_s
* op1
,
2180 struct msp430_operand_s
* op2
,
2181 const char ** error_message_return
)
2187 /* Only a restricted subset of the normal MSP430 addressing modes
2188 are supported here, so check for the ones that are allowed. */
2191 if (op1
->mode
== OP_EXP
)
2193 if (op2
->mode
!= OP_REG
)
2195 if (error_message_return
!= NULL
)
2196 * error_message_return
= _("expected register as second argument of %s");
2202 /* MOVA #imm20, Rdst. */
2203 bin
|= 0x80 | op2
->reg
;
2204 frag
= frag_more (4);
2205 where
= frag
- frag_now
->fr_literal
;
2206 if (op1
->exp
.X_op
== O_constant
)
2208 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2209 bfd_putl16 ((bfd_vma
) bin
, frag
);
2210 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2214 bfd_putl16 ((bfd_vma
) bin
, frag
);
2215 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2216 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2217 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2222 else if (op1
->am
== 1)
2224 /* MOVA z16(Rsrc), Rdst. */
2225 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2226 frag
= frag_more (4);
2227 where
= frag
- frag_now
->fr_literal
;
2228 bfd_putl16 ((bfd_vma
) bin
, frag
);
2229 if (op1
->exp
.X_op
== O_constant
)
2231 if (op1
->exp
.X_add_number
> 0xffff
2232 || op1
->exp
.X_add_number
< -(0x7fff))
2234 if (error_message_return
!= NULL
)
2235 * error_message_return
= _("index value too big for %s");
2238 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2242 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2243 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2245 BFD_RELOC_MSP430X_PCR16
:
2246 BFD_RELOC_MSP430X_ABS16
);
2251 if (error_message_return
!= NULL
)
2252 * error_message_return
= _("unexpected addressing mode for %s");
2255 else if (op1
->am
== 0)
2257 /* MOVA Rsrc, ... */
2258 if (op2
->mode
== OP_REG
)
2260 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2261 frag
= frag_more (2);
2262 where
= frag
- frag_now
->fr_literal
;
2263 bfd_putl16 ((bfd_vma
) bin
, frag
);
2266 else if (op2
->am
== 1)
2270 /* MOVA Rsrc, &abs20. */
2271 bin
|= 0x60 | (op1
->reg
<< 8);
2272 frag
= frag_more (4);
2273 where
= frag
- frag_now
->fr_literal
;
2274 if (op2
->exp
.X_op
== O_constant
)
2276 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2277 bfd_putl16 ((bfd_vma
) bin
, frag
);
2278 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2282 bfd_putl16 ((bfd_vma
) bin
, frag
);
2283 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2284 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2285 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2290 /* MOVA Rsrc, z16(Rdst). */
2291 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2292 frag
= frag_more (4);
2293 where
= frag
- frag_now
->fr_literal
;
2294 bfd_putl16 ((bfd_vma
) bin
, frag
);
2295 if (op2
->exp
.X_op
== O_constant
)
2297 if (op2
->exp
.X_add_number
> 0xffff
2298 || op2
->exp
.X_add_number
< -(0x7fff))
2300 if (error_message_return
!= NULL
)
2301 * error_message_return
= _("index value too big for %s");
2304 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2308 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2309 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2311 BFD_RELOC_MSP430X_PCR16
:
2312 BFD_RELOC_MSP430X_ABS16
);
2317 if (error_message_return
!= NULL
)
2318 * error_message_return
= _("unexpected addressing mode for %s");
2323 /* imm_op == FALSE. */
2325 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2327 /* MOVA &abs20, Rdst. */
2328 if (op2
->mode
!= OP_REG
)
2330 if (error_message_return
!= NULL
)
2331 * error_message_return
= _("expected register as second argument of %s");
2335 if (op2
->reg
== 2 || op2
->reg
== 3)
2337 if (error_message_return
!= NULL
)
2338 * error_message_return
= _("constant generator destination register found in %s");
2342 bin
|= 0x20 | op2
->reg
;
2343 frag
= frag_more (4);
2344 where
= frag
- frag_now
->fr_literal
;
2345 if (op1
->exp
.X_op
== O_constant
)
2347 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2348 bfd_putl16 ((bfd_vma
) bin
, frag
);
2349 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2353 bfd_putl16 ((bfd_vma
) bin
, frag
);
2354 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2355 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2356 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2360 else if (op1
->mode
== OP_REG
)
2364 /* MOVA @Rsrc+, Rdst. */
2365 if (op2
->mode
!= OP_REG
)
2367 if (error_message_return
!= NULL
)
2368 * error_message_return
= _("expected register as second argument of %s");
2372 if (op2
->reg
== 2 || op2
->reg
== 3)
2374 if (error_message_return
!= NULL
)
2375 * error_message_return
= _("constant generator destination register found in %s");
2379 if (op1
->reg
== 2 || op1
->reg
== 3)
2381 if (error_message_return
!= NULL
)
2382 * error_message_return
= _("constant generator source register found in %s");
2386 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2387 frag
= frag_more (2);
2388 where
= frag
- frag_now
->fr_literal
;
2389 bfd_putl16 ((bfd_vma
) bin
, frag
);
2392 else if (op1
->am
== 2)
2394 /* MOVA @Rsrc,Rdst */
2395 if (op2
->mode
!= OP_REG
)
2397 if (error_message_return
!= NULL
)
2398 * error_message_return
= _("expected register as second argument of %s");
2402 if (op2
->reg
== 2 || op2
->reg
== 3)
2404 if (error_message_return
!= NULL
)
2405 * error_message_return
= _("constant generator destination register found in %s");
2409 if (op1
->reg
== 2 || op1
->reg
== 3)
2411 if (error_message_return
!= NULL
)
2412 * error_message_return
= _("constant generator source register found in %s");
2416 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2417 frag
= frag_more (2);
2418 where
= frag
- frag_now
->fr_literal
;
2419 bfd_putl16 ((bfd_vma
) bin
, frag
);
2424 if (error_message_return
!= NULL
)
2425 * error_message_return
= _("unexpected addressing mode for %s");
2430 #define NOP_CHECK_INTERRUPT (1 << 0)
2431 #define NOP_CHECK_CPU12 (1 << 1)
2432 #define NOP_CHECK_CPU19 (1 << 2)
2434 static signed int check_for_nop
= 0;
2436 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2438 /* Parse instruction operands.
2439 Return binary opcode. */
2442 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2444 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2445 int insn_length
= 0;
2446 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2449 struct msp430_operand_s op1
, op2
;
2451 static short ZEROS
= 0;
2452 bfd_boolean byte_op
, imm_op
;
2455 int extended
= 0x1800;
2456 bfd_boolean extended_op
= FALSE
;
2457 bfd_boolean addr_op
;
2458 const char * error_message
;
2459 static signed int repeat_count
= 0;
2460 bfd_boolean fix_emitted
;
2462 /* Opcode is the one from opcodes table
2463 line contains something like
2472 bfd_boolean check
= FALSE
;
2475 switch (TOLOWER (* line
))
2478 /* Byte operation. */
2479 bin
|= BYTE_OPERATION
;
2485 /* "Address" ops work on 20-bit values. */
2487 bin
|= BYTE_OPERATION
;
2492 /* Word operation - this is the default. */
2500 as_warn (_("no size modifier after period, .w assumed"));
2504 as_bad (_("unrecognised instruction size modifier .%c"),
2516 if (*line
&& ! ISSPACE (*line
))
2518 as_bad (_("junk found after instruction: %s.%s"),
2519 opcode
->name
, line
);
2523 /* Catch the case where the programmer has used a ".a" size modifier on an
2524 instruction that does not support it. Look for an alternative extended
2525 instruction that has the same name without the period. Eg: "add.a"
2526 becomes "adda". Although this not an officially supported way of
2527 specifing instruction aliases other MSP430 assemblers allow it. So we
2528 support it for compatibility purposes. */
2529 if (addr_op
&& opcode
->fmt
>= 0)
2531 char * old_name
= opcode
->name
;
2534 sprintf (real_name
, "%sa", old_name
);
2535 opcode
= hash_find (msp430_hash
, real_name
);
2538 as_bad (_("instruction %s.a does not exist"), old_name
);
2541 #if 0 /* Enable for debugging. */
2542 as_warn ("treating %s.a as %s", old_name
, real_name
);
2545 bin
= opcode
->bin_opcode
;
2548 if (opcode
->fmt
!= -1
2549 && opcode
->insn_opnumb
2550 && (!*line
|| *line
== '\n'))
2552 as_bad (_("instruction %s requires %d operand(s)"),
2553 opcode
->name
, opcode
->insn_opnumb
);
2557 memset (l1
, 0, sizeof (l1
));
2558 memset (l2
, 0, sizeof (l2
));
2559 memset (&op1
, 0, sizeof (op1
));
2560 memset (&op2
, 0, sizeof (op2
));
2564 if ((fmt
= opcode
->fmt
) < 0)
2566 if (! target_is_430x ())
2568 as_bad (_("instruction %s requires MSP430X mcu"),
2579 /* If requested set the extended instruction repeat count. */
2582 if (repeat_count
> 0)
2583 extended
|= (repeat_count
- 1);
2585 extended
|= (1 << 7) | (- repeat_count
);
2588 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2595 if (! is_opcode ("nop"))
2597 bfd_boolean doit
= FALSE
;
2601 switch (check_for_nop
& - check_for_nop
)
2603 case NOP_CHECK_INTERRUPT
:
2604 if (warn_interrupt_nops
)
2606 if (gen_interrupt_nops
)
2607 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2609 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2612 if (gen_interrupt_nops
)
2613 /* Emit a NOP between interrupt enable/disable.
2614 See 1.3.4.1 of the MSP430x5xx User Guide. */
2618 case NOP_CHECK_CPU12
:
2619 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2620 as_warn (_("CPU12: CMP/BIT with PC destinstion ignores next instruction"));
2622 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2626 case NOP_CHECK_CPU19
:
2627 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2628 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2630 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
2635 as_bad (_("internal error: unknown nop check state"));
2638 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
2640 while (check_for_nop
);
2644 frag
= frag_more (2);
2645 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2646 dwarf2_emit_insn (2);
2655 case 0: /* Emulated. */
2656 switch (opcode
->insn_opnumb
)
2659 if (is_opcode ("eint") || is_opcode ("dint"))
2660 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2662 /* Set/clear bits instructions. */
2666 extended
|= BYTE_OPERATION
;
2668 /* Emit the extension word. */
2670 frag
= frag_more (2);
2671 bfd_putl16 (extended
, frag
);
2675 frag
= frag_more (2);
2676 bfd_putl16 ((bfd_vma
) bin
, frag
);
2677 dwarf2_emit_insn (insn_length
);
2681 /* Something which works with destination operand. */
2682 line
= extract_operand (line
, l1
, sizeof (l1
));
2683 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2687 bin
|= (op1
.reg
| (op1
.am
<< 7));
2689 /* If the PC is the destination... */
2690 if (op1
.am
== 0 && op1
.reg
== 0
2691 /* ... and the opcode alters the SR. */
2692 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2693 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
2695 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
2696 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
2697 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
2698 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
2701 /* If the status register is the destination... */
2702 if (op1
.am
== 0 && op1
.reg
== 2
2703 /* ... and the opcode alters the SR. */
2704 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2705 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2706 || is_opcode ("sbc") || is_opcode ("sxt")
2707 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2708 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2709 || is_opcode ("sbcx")
2712 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2713 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2714 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2715 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2718 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2719 check_for_nop
|= NOP_CHECK_INTERRUPT
;
2721 /* Compute the entire instruction length, in bytes. */
2722 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2723 insn_length
+= op_length
;
2724 frag
= frag_more (op_length
);
2725 where
= frag
- frag_now
->fr_literal
;
2730 extended
|= BYTE_OPERATION
;
2732 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2734 as_bad (_("repeat instruction used with non-register mode instruction"));
2738 if (op1
.mode
== OP_EXP
)
2740 if (op1
.exp
.X_op
== O_constant
)
2741 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2743 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2744 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2745 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2747 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2748 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2751 /* Emit the extension word. */
2752 bfd_putl16 (extended
, frag
);
2757 bfd_putl16 ((bfd_vma
) bin
, frag
);
2761 if (op1
.mode
== OP_EXP
)
2763 if (op1
.exp
.X_op
== O_constant
)
2765 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2769 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2774 fix_new_exp (frag_now
, where
, 2,
2775 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2777 fix_new_exp (frag_now
, where
, 2,
2778 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2783 dwarf2_emit_insn (insn_length
);
2787 /* Shift instruction. */
2788 line
= extract_operand (line
, l1
, sizeof (l1
));
2789 strncpy (l2
, l1
, sizeof (l2
));
2790 l2
[sizeof (l2
) - 1] = '\0';
2791 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2792 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2795 break; /* An error occurred. All warnings were done before. */
2797 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2798 frag
= frag_more (insn_length
);
2799 where
= frag
- frag_now
->fr_literal
;
2801 if (target_is_430xv2 ()
2802 && op1
.mode
== OP_REG
2804 && (is_opcode ("rlax")
2805 || is_opcode ("rlcx")
2806 || is_opcode ("rla")
2807 || is_opcode ("rlc")))
2809 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2813 /* If the status register is the destination... */
2814 if (op1
.am
== 0 && op1
.reg
== 2
2815 /* ... and the opcode alters the SR. */
2816 && (is_opcode ("rla") || is_opcode ("rlc")
2817 || is_opcode ("rlax") || is_opcode ("rlcx")
2820 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
2821 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2822 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
2823 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2829 extended
|= BYTE_OPERATION
;
2831 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2833 as_bad (_("repeat instruction used with non-register mode instruction"));
2837 if (op1
.mode
== OP_EXP
)
2839 if (op1
.exp
.X_op
== O_constant
)
2840 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2842 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2843 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2844 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2846 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2847 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2850 if (op2
.mode
== OP_EXP
)
2852 if (op2
.exp
.X_op
== O_constant
)
2853 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2855 else if (op1
.mode
== OP_EXP
)
2856 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2857 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2858 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2860 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2861 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2862 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2865 /* Emit the extension word. */
2866 bfd_putl16 (extended
, frag
);
2871 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2872 bfd_putl16 ((bfd_vma
) bin
, frag
);
2876 if (op1
.mode
== OP_EXP
)
2878 if (op1
.exp
.X_op
== O_constant
)
2880 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2884 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2888 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2889 fix_new_exp (frag_now
, where
, 2,
2890 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2892 fix_new_exp (frag_now
, where
, 2,
2893 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2900 if (op2
.mode
== OP_EXP
)
2902 if (op2
.exp
.X_op
== O_constant
)
2904 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2908 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2912 if (op2
.reg
) /* Not PC relative. */
2913 fix_new_exp (frag_now
, where
, 2,
2914 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2916 fix_new_exp (frag_now
, where
, 2,
2917 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2922 dwarf2_emit_insn (insn_length
);
2926 /* Branch instruction => mov dst, r0. */
2929 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2933 line
= extract_operand (line
, l1
, sizeof (l1
));
2934 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2940 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2941 op_length
= 2 + 2 * op1
.ol
;
2942 frag
= frag_more (op_length
);
2943 where
= frag
- frag_now
->fr_literal
;
2944 bfd_putl16 ((bfd_vma
) bin
, frag
);
2946 if (op1
.mode
== OP_EXP
)
2948 if (op1
.exp
.X_op
== O_constant
)
2950 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2956 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2958 if (op1
.reg
|| op1
.am
== 3)
2959 fix_new_exp (frag_now
, where
, 2,
2960 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2962 fix_new_exp (frag_now
, where
, 2,
2963 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2967 dwarf2_emit_insn (insn_length
+ op_length
);
2971 /* CALLA instructions. */
2972 fix_emitted
= FALSE
;
2974 line
= extract_operand (line
, l1
, sizeof (l1
));
2977 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
2978 extended_op
, FALSE
);
2984 op_length
= 2 + 2 * op1
.ol
;
2985 frag
= frag_more (op_length
);
2986 where
= frag
- frag_now
->fr_literal
;
2994 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2995 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2998 else if (op1
.am
== 1)
3004 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3005 BFD_RELOC_MSP430X_PCR20_CALL
);
3009 bin
|= 0x50 | op1
.reg
;
3011 else if (op1
.am
== 0)
3012 bin
|= 0x40 | op1
.reg
;
3014 else if (op1
.am
== 1)
3018 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3019 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3022 else if (op1
.am
== 2)
3023 bin
|= 0x60 | op1
.reg
;
3024 else if (op1
.am
== 3)
3025 bin
|= 0x70 | op1
.reg
;
3027 bfd_putl16 ((bfd_vma
) bin
, frag
);
3029 if (op1
.mode
== OP_EXP
)
3033 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3037 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3040 fix_new_exp (frag_now
, where
+ 2, 2,
3041 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3044 dwarf2_emit_insn (insn_length
+ op_length
);
3052 /* [POP|PUSH]M[.A] #N, Rd */
3053 line
= extract_operand (line
, l1
, sizeof (l1
));
3054 line
= extract_operand (line
, l2
, sizeof (l2
));
3058 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3061 parse_exp (l1
+ 1, &(op1
.exp
));
3062 if (op1
.exp
.X_op
!= O_constant
)
3064 as_bad (_("expected constant expression for first argument of %s"),
3069 if ((reg
= check_reg (l2
)) == -1)
3071 as_bad (_("expected register as second argument of %s"),
3077 frag
= frag_more (op_length
);
3078 where
= frag
- frag_now
->fr_literal
;
3079 bin
= opcode
->bin_opcode
;
3082 n
= op1
.exp
.X_add_number
;
3083 bin
|= (n
- 1) << 4;
3084 if (is_opcode ("pushm"))
3088 if (reg
- n
+ 1 < 0)
3090 as_bad (_("Too many registers popped"));
3094 /* CPU21 errata: cannot use POPM to restore the SR register. */
3095 if (target_is_430xv2 ()
3096 && (reg
- n
+ 1 < 3)
3098 && is_opcode ("popm"))
3100 as_bad (_("Cannot use POPM to restore the SR register"));
3104 bin
|= (reg
- n
+ 1);
3107 bfd_putl16 ((bfd_vma
) bin
, frag
);
3108 dwarf2_emit_insn (op_length
);
3117 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3118 if (extended
& 0xff)
3120 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3124 line
= extract_operand (line
, l1
, sizeof (l1
));
3125 line
= extract_operand (line
, l2
, sizeof (l2
));
3129 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3132 parse_exp (l1
+ 1, &(op1
.exp
));
3133 if (op1
.exp
.X_op
!= O_constant
)
3135 as_bad (_("expected constant expression for first argument of %s"),
3139 n
= op1
.exp
.X_add_number
;
3142 as_bad (_("expected first argument of %s to be in the range 1-4"),
3147 if ((reg
= check_reg (l2
)) == -1)
3149 as_bad (_("expected register as second argument of %s"),
3154 if (target_is_430xv2 () && reg
== 0)
3156 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3161 frag
= frag_more (op_length
);
3162 where
= frag
- frag_now
->fr_literal
;
3164 bin
= opcode
->bin_opcode
;
3167 bin
|= (n
- 1) << 10;
3170 bfd_putl16 ((bfd_vma
) bin
, frag
);
3171 dwarf2_emit_insn (op_length
);
3177 bfd_boolean need_reloc
= FALSE
;
3181 /* ADDA, CMPA and SUBA address instructions. */
3182 if (extended
& 0xff)
3184 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3188 line
= extract_operand (line
, l1
, sizeof (l1
));
3189 line
= extract_operand (line
, l2
, sizeof (l2
));
3191 bin
= opcode
->bin_opcode
;
3195 parse_exp (l1
+ 1, &(op1
.exp
));
3197 if (op1
.exp
.X_op
== O_constant
)
3199 n
= op1
.exp
.X_add_number
;
3200 if (n
> 0xfffff || n
< - (0x7ffff))
3202 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3207 bin
|= ((n
>> 16) & 0xf) << 8;
3219 if ((n
= check_reg (l1
)) == -1)
3221 as_bad (_("expected register name or constant as first argument of %s"),
3226 bin
|= (n
<< 8) | (1 << 6);
3230 if ((reg
= check_reg (l2
)) == -1)
3232 as_bad (_("expected register as second argument of %s"),
3237 frag
= frag_more (op_length
);
3238 where
= frag
- frag_now
->fr_literal
;
3241 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3242 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3244 bfd_putl16 ((bfd_vma
) bin
, frag
);
3246 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3247 dwarf2_emit_insn (op_length
);
3251 case 9: /* MOVA, BRA, RETA. */
3253 bin
= opcode
->bin_opcode
;
3255 if (is_opcode ("reta"))
3257 /* The RETA instruction does not take any arguments.
3258 The implicit first argument is @SP+.
3259 The implicit second argument is PC. */
3269 line
= extract_operand (line
, l1
, sizeof (l1
));
3270 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3271 &imm_op
, extended_op
, FALSE
);
3273 if (is_opcode ("bra"))
3275 /* This is the BRA synthetic instruction.
3276 The second argument is always PC. */
3282 line
= extract_operand (line
, l2
, sizeof (l2
));
3283 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3288 break; /* Error occurred. All warnings were done before. */
3291 /* Only a restricted subset of the normal MSP430 addressing modes
3292 are supported here, so check for the ones that are allowed. */
3293 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3294 & error_message
)) == 0)
3296 as_bad (error_message
, opcode
->name
);
3299 dwarf2_emit_insn (op_length
);
3303 line
= extract_operand (line
, l1
, sizeof l1
);
3304 /* The RPT instruction only accepted immediates and registers. */
3307 parse_exp (l1
+ 1, &(op1
.exp
));
3308 if (op1
.exp
.X_op
!= O_constant
)
3310 as_bad (_("expected constant value as argument to RPT"));
3313 if (op1
.exp
.X_add_number
< 1
3314 || op1
.exp
.X_add_number
> (1 << 4))
3316 as_bad (_("expected constant in the range 2..16"));
3320 /* We silently accept and ignore a repeat count of 1. */
3321 if (op1
.exp
.X_add_number
> 1)
3322 repeat_count
= op1
.exp
.X_add_number
;
3328 if ((reg
= check_reg (l1
)) != -1)
3331 as_warn (_("PC used as an argument to RPT"));
3333 repeat_count
= - reg
;
3337 as_bad (_("expected constant or register name as argument to RPT insn"));
3344 as_bad (_("Illegal emulated instruction "));
3349 case 1: /* Format 1, double operand. */
3350 line
= extract_operand (line
, l1
, sizeof (l1
));
3351 line
= extract_operand (line
, l2
, sizeof (l2
));
3352 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3353 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3356 break; /* Error occurred. All warnings were done before. */
3359 && is_opcode ("movx")
3361 && msp430_enable_relax
)
3363 /* This is the MOVX.A instruction. See if we can convert
3364 it into the MOVA instruction instead. This saves 2 bytes. */
3365 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3368 dwarf2_emit_insn (op_length
);
3373 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3375 /* If the PC is the destination... */
3376 if (op2
.am
== 0 && op2
.reg
== 0
3377 /* ... and the opcode alters the SR. */
3378 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3379 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3381 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3382 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
3383 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3384 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
3387 /* If the status register is the destination... */
3388 if (op2
.am
== 0 && op2
.reg
== 2
3389 /* ... and the opcode alters the SR. */
3390 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3391 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3392 || is_opcode ("xor")
3393 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3394 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3395 || is_opcode ("xorx")
3398 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3399 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3400 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3401 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3404 if ( (is_opcode ("bic") && bin
== 0xc232)
3405 || (is_opcode ("bis") && bin
== 0xd232)
3406 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3408 /* Avoid false checks when a constant value is being put into the SR. */
3409 if (op1
.mode
== OP_EXP
3410 && op1
.exp
.X_op
== O_constant
3411 && (op1
.exp
.X_add_number
& 0x8) != 0x8)
3414 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3417 if (((is_opcode ("bis") && bin
== 0xd032)
3418 || (is_opcode ("mov") && bin
== 0x4032)
3419 || (is_opcode ("xor") && bin
== 0xe032))
3420 && op1
.mode
== OP_EXP
3421 && op1
.exp
.X_op
== O_constant
3422 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3423 check_for_nop
|= NOP_CHECK_CPU19
;
3425 /* Compute the entire length of the instruction in bytes. */
3426 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3427 + 2 /* The opcode */
3428 + (2 * op1
.ol
) /* The first operand. */
3429 + (2 * op2
.ol
); /* The second operand. */
3431 insn_length
+= op_length
;
3432 frag
= frag_more (op_length
);
3433 where
= frag
- frag_now
->fr_literal
;
3438 extended
|= BYTE_OPERATION
;
3440 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3442 as_bad (_("repeat instruction used with non-register mode instruction"));
3446 /* If necessary, emit a reloc to update the extension word. */
3447 if (op1
.mode
== OP_EXP
)
3449 if (op1
.exp
.X_op
== O_constant
)
3450 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3452 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3453 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3454 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3456 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3457 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3460 if (op2
.mode
== OP_EXP
)
3462 if (op2
.exp
.X_op
== O_constant
)
3463 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3465 else if (op1
.mode
== OP_EXP
)
3466 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3467 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3468 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3471 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3472 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3473 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3476 /* Emit the extension word. */
3477 bfd_putl16 (extended
, frag
);
3482 bfd_putl16 ((bfd_vma
) bin
, frag
);
3486 if (op1
.mode
== OP_EXP
)
3488 if (op1
.exp
.X_op
== O_constant
)
3490 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3494 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3498 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3499 fix_new_exp (frag_now
, where
, 2,
3500 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3502 fix_new_exp (frag_now
, where
, 2,
3503 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3511 if (op2
.mode
== OP_EXP
)
3513 if (op2
.exp
.X_op
== O_constant
)
3515 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3519 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3523 if (op2
.reg
) /* Not PC relative. */
3524 fix_new_exp (frag_now
, where
, 2,
3525 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3527 fix_new_exp (frag_now
, where
, 2,
3528 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3533 dwarf2_emit_insn (insn_length
);
3535 /* If the PC is the destination... */
3536 if (op2
.am
== 0 && op2
.reg
== 0
3537 /* ... but the opcode does not alter the destination. */
3538 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3539 check_for_nop
|= NOP_CHECK_CPU12
;
3542 case 2: /* Single-operand mostly instr. */
3543 if (opcode
->insn_opnumb
== 0)
3545 /* reti instruction. */
3547 frag
= frag_more (2);
3548 bfd_putl16 ((bfd_vma
) bin
, frag
);
3549 dwarf2_emit_insn (insn_length
);
3553 line
= extract_operand (line
, l1
, sizeof (l1
));
3554 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3555 &imm_op
, extended_op
, TRUE
);
3557 break; /* Error in operand. */
3559 if (target_is_430xv2 ()
3560 && op1
.mode
== OP_REG
3562 && (is_opcode ("rrax")
3563 || is_opcode ("rrcx")
3564 || is_opcode ("rra")
3565 || is_opcode ("rrc")))
3567 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3571 /* If the status register is the destination... */
3572 if (op1
.am
== 0 && op1
.reg
== 2
3573 /* ... and the opcode alters the SR. */
3574 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3576 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3577 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3578 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3579 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3582 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3583 frag
= frag_more (insn_length
);
3584 where
= frag
- frag_now
->fr_literal
;
3588 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3590 /* These two instructions use a special
3591 encoding of the A/L and B/W bits. */
3592 bin
&= ~ BYTE_OPERATION
;
3596 as_bad (_("%s instruction does not accept a .b suffix"),
3601 extended
|= BYTE_OPERATION
;
3604 extended
|= BYTE_OPERATION
;
3606 if (is_opcode ("rrux"))
3607 extended
|= IGNORE_CARRY_BIT
;
3609 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3611 as_bad (_("repeat instruction used with non-register mode instruction"));
3615 if (op1
.mode
== OP_EXP
)
3617 if (op1
.exp
.X_op
== O_constant
)
3618 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3620 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3621 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3622 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3624 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3625 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3628 /* Emit the extension word. */
3629 bfd_putl16 (extended
, frag
);
3634 bin
|= op1
.reg
| (op1
.am
<< 4);
3635 bfd_putl16 ((bfd_vma
) bin
, frag
);
3639 if (op1
.mode
== OP_EXP
)
3641 if (op1
.exp
.X_op
== O_constant
)
3643 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3647 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3651 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3652 fix_new_exp (frag_now
, where
, 2,
3653 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3655 fix_new_exp (frag_now
, where
, 2,
3656 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3661 dwarf2_emit_insn (insn_length
);
3664 case 3: /* Conditional jumps instructions. */
3665 line
= extract_operand (line
, l1
, sizeof (l1
));
3666 /* l1 is a label. */
3675 parse_exp (m
, &exp
);
3677 /* In order to handle something like:
3681 jz 4 ; skip next 4 bytes
3684 nop ; will jump here if r5 positive or zero
3686 jCOND -n ;assumes jump n bytes backward:
3696 jCOND $n ; jump from PC in either direction. */
3698 if (exp
.X_op
== O_constant
)
3700 int x
= exp
.X_add_number
;
3704 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3708 if ((*l1
== '$' && x
> 0) || x
< 0)
3713 if (x
> 512 || x
< -511)
3715 as_bad (_("Wrong displacement %d"), x
<< 1);
3720 frag
= frag_more (2); /* Instr size is 1 word. */
3723 bfd_putl16 ((bfd_vma
) bin
, frag
);
3725 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3728 frag
= frag_more (2); /* Instr size is 1 word. */
3729 where
= frag
- frag_now
->fr_literal
;
3730 fix_new_exp (frag_now
, where
, 2,
3731 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3733 bfd_putl16 ((bfd_vma
) bin
, frag
);
3735 else if (*l1
== '$')
3737 as_bad (_("instruction requires label sans '$'"));
3741 ("instruction requires label or value in range -511:512"));
3742 dwarf2_emit_insn (insn_length
);
3747 as_bad (_("instruction requires label"));
3752 case 4: /* Extended jumps. */
3753 if (!msp430_enable_polys
)
3755 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3759 line
= extract_operand (line
, l1
, sizeof (l1
));
3765 /* Ignore absolute addressing. make it PC relative anyway. */
3766 if (*m
== '#' || *m
== '$')
3769 parse_exp (m
, & exp
);
3770 if (exp
.X_op
== O_symbol
)
3772 /* Relaxation required. */
3773 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3775 if (target_is_430x ())
3776 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3778 /* The parameter to dwarf2_emit_insn is actually the offset to
3779 the start of the insn from the fix piece of instruction that
3780 was emitted. Since next fragments may have variable size we
3781 tie debug info to the beginning of the instruction. */
3783 frag
= frag_more (8);
3784 dwarf2_emit_insn (0);
3785 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3786 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3788 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3790 0, /* Offset is zero if jump dist less than 1K. */
3796 as_bad (_("instruction requires label"));
3799 case 5: /* Emulated extended branches. */
3800 if (!msp430_enable_polys
)
3802 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3805 line
= extract_operand (line
, l1
, sizeof (l1
));
3811 /* Ignore absolute addressing. make it PC relative anyway. */
3812 if (*m
== '#' || *m
== '$')
3815 parse_exp (m
, & exp
);
3816 if (exp
.X_op
== O_symbol
)
3818 /* Relaxation required. */
3819 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3821 if (target_is_430x ())
3822 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3825 frag
= frag_more (8);
3826 dwarf2_emit_insn (0);
3827 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3828 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3830 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3831 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3833 0, /* Offset is zero if jump dist less than 1K. */
3839 as_bad (_("instruction requires label"));
3843 as_bad (_("Illegal instruction or not implemented opcode."));
3846 input_line_pointer
= line
;
3851 md_assemble (char * str
)
3853 struct msp430_opcode_s
* opcode
;
3857 str
= skip_space (str
); /* Skip leading spaces. */
3858 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3862 char a
= TOLOWER (cmd
[i
]);
3869 as_bad (_("can't find opcode "));
3873 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3877 as_bad (_("unknown opcode `%s'"), cmd
);
3882 char *__t
= input_line_pointer
;
3884 msp430_operands (opcode
, str
);
3885 input_line_pointer
= __t
;
3889 /* GAS will call this function for each section at the end of the assembly,
3890 to permit the CPU backend to adjust the alignment of a section. */
3893 md_section_align (asection
* seg
, valueT addr
)
3895 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3897 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
3900 /* If you define this macro, it should return the offset between the
3901 address of a PC relative fixup and the position from which the PC
3902 relative adjustment should be made. On many processors, the base
3903 of a PC relative instruction is the next instruction, so this
3904 macro would return the length of an instruction. */
3907 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3909 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3910 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3911 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3914 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3917 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3918 Now it handles the situation when relocations
3919 have to be passed to linker. */
3921 msp430_force_relocation_local (fixS
*fixp
)
3923 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3927 if (msp430_enable_polys
3928 && !msp430_enable_relax
)
3931 return (!fixp
->fx_pcrel
3932 || generic_force_reloc (fixp
));
3936 /* GAS will call this for each fixup. It should store the correct
3937 value in the object file. */
3939 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3941 unsigned char * where
;
3945 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3950 else if (fixp
->fx_pcrel
)
3952 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3954 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3956 /* FIXME: We can appear here only in case if we perform a pc
3957 relative jump to the label which is i) global, ii) locally
3958 defined or this is a jump to an absolute symbol.
3959 If this is an absolute symbol -- everything is OK.
3960 If this is a global label, we've got a symbol value defined
3962 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3963 from this section start
3964 2. *valuep will contain the real offset from jump insn to the
3966 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3967 will be incorrect. Therefore remove s_get_value. */
3968 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
3976 value
= fixp
->fx_offset
;
3978 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
3980 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3982 value
-= S_GET_VALUE (fixp
->fx_subsy
);
3988 fixp
->fx_no_overflow
= 1;
3990 /* If polymorphs are enabled and relax disabled.
3991 do not kill any relocs and pass them to linker. */
3992 if (msp430_enable_polys
3993 && !msp430_enable_relax
)
3996 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
3997 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4004 /* Fetch the instruction, insert the fully resolved operand
4005 value, and stuff the instruction back again. */
4006 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4008 insn
= bfd_getl16 (where
);
4010 switch (fixp
->fx_r_type
)
4012 case BFD_RELOC_MSP430_10_PCREL
:
4014 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4015 _("odd address operand: %ld"), value
);
4017 /* Jumps are in words. */
4019 --value
; /* Correct PC. */
4021 if (value
< -512 || value
> 511)
4022 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4023 _("operand out of range: %ld"), value
);
4025 value
&= 0x3ff; /* get rid of extended sign */
4026 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4029 case BFD_RELOC_MSP430X_PCR16
:
4030 case BFD_RELOC_MSP430_RL_PCREL
:
4031 case BFD_RELOC_MSP430_16_PCREL
:
4033 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4034 _("odd address operand: %ld"), value
);
4037 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4038 /* Nothing to be corrected here. */
4039 if (value
< -32768 || value
> 65536)
4040 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4041 _("operand out of range: %ld"), value
);
4044 case BFD_RELOC_MSP430X_ABS16
:
4045 case BFD_RELOC_MSP430_16
:
4047 case BFD_RELOC_MSP430_16_BYTE
:
4048 value
&= 0xffff; /* Get rid of extended sign. */
4049 bfd_putl16 ((bfd_vma
) value
, where
);
4052 case BFD_RELOC_MSP430_ABS_HI16
:
4054 value
&= 0xffff; /* Get rid of extended sign. */
4055 bfd_putl16 ((bfd_vma
) value
, where
);
4059 bfd_putl16 ((bfd_vma
) value
, where
);
4062 case BFD_RELOC_MSP430_ABS8
:
4064 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4067 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4068 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4069 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4071 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4074 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4075 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4077 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4080 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4081 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4083 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4086 case BFD_RELOC_MSP430X_PCR20_CALL
:
4087 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4089 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4092 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4093 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4094 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4096 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4099 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4100 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4102 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4105 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4106 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4108 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4112 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4113 fixp
->fx_line
, fixp
->fx_r_type
);
4119 fixp
->fx_addnumber
= value
;
4124 S_IS_GAS_LOCAL (symbolS
* s
)
4131 name
= S_GET_NAME (s
);
4132 len
= strlen (name
) - 1;
4134 return name
[len
] == 1 || name
[len
] == 2;
4137 /* GAS will call this to generate a reloc, passing the resulting reloc
4138 to `bfd_install_relocation'. This currently works poorly, as
4139 `bfd_install_relocation' often does the wrong thing, and instances of
4140 `tc_gen_reloc' have been written to work around the problems, which
4141 in turns makes it difficult to fix `bfd_install_relocation'. */
4143 /* If while processing a fixup, a reloc really needs to be created
4144 then it is done here. */
4147 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4149 static arelent
* no_relocs
= NULL
;
4150 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4153 reloc
= xmalloc (sizeof (arelent
));
4154 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4155 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4157 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4159 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4160 _("reloc %d not supported by object file format"),
4161 (int) fixp
->fx_r_type
);
4170 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4172 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4173 fixp
->fx_subsy
= NULL
;
4176 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4178 asection
*asec
, *ssec
;
4180 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4181 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4183 /* If we have a difference between two different, non-absolute symbols
4184 we must generate two relocs (one for each symbol) and allow the
4185 linker to resolve them - relaxation may change the distances between
4186 symbols, even local symbols defined in the same section.
4188 Unfortunately we cannot do this with assembler generated local labels
4189 because there can be multiple incarnations of the same label, with
4190 exactly the same name, in any given section and the linker will have
4191 no way to identify the correct one. Instead we just have to hope
4192 that no relaxtion will occur between the local label and the other
4193 symbol in the expression.
4195 Similarly we have to compute differences between symbols in the .eh_frame
4196 section as the linker is not smart enough to apply relocations there
4197 before attempting to process it. */
4198 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4199 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4200 && strcmp (ssec
->name
, ".eh_frame") != 0
4201 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4202 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4204 arelent
* reloc2
= xmalloc (sizeof * reloc
);
4209 reloc2
->address
= reloc
->address
;
4210 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4211 BFD_RELOC_MSP430_SYM_DIFF
);
4212 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4214 if (ssec
== absolute_section
)
4215 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4218 reloc2
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4219 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4222 reloc
->addend
= fixp
->fx_offset
;
4223 if (asec
== absolute_section
)
4225 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4226 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4230 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4231 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4240 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4242 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4243 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4245 switch (fixp
->fx_r_type
)
4248 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4252 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4256 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4260 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4265 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4276 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4277 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4279 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4280 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4282 md_number_to_chars (fixpos
, amount
, 2);
4287 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4288 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4289 reloc
->addend
= fixp
->fx_offset
;
4291 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4292 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4293 reloc
->address
= fixp
->fx_offset
;
4300 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4301 asection
* segment_type ATTRIBUTE_UNUSED
)
4303 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4305 /* This is a jump -> pcrel mode. Nothing to do much here.
4306 Return value == 2. */
4308 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4310 else if (fragP
->fr_symbol
)
4312 /* Its got a segment, but its not ours. Even if fr_symbol is in
4313 an absolute segment, we don't know a displacement until we link
4314 object files. So it will always be long. This also applies to
4315 labels in a subsegment of current. Liker may relax it to short
4316 jump later. Return value == 8. */
4318 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4322 /* We know the abs value. may be it is a jump to fixed address.
4323 Impossible in our case, cause all constants already handled. */
4325 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4328 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4332 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4333 asection
* sec ATTRIBUTE_UNUSED
,
4339 struct rcodes_s
* cc
= NULL
;
4340 struct hcodes_s
* hc
= NULL
;
4342 switch (fragP
->fr_subtype
)
4344 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4345 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4346 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4347 /* We do not have to convert anything here.
4348 Just apply a fix. */
4349 rela
= BFD_RELOC_MSP430_10_PCREL
;
4352 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4353 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4354 /* Convert uncond branch jmp lab -> br lab. */
4355 if (target_is_430x ())
4356 cc
= msp430x_rcodes
+ 7;
4358 cc
= msp430_rcodes
+ 7;
4359 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4360 bfd_putl16 (cc
->lop0
, where
);
4361 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4365 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4366 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4368 /* Other simple branches. */
4369 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4372 /* Find actual instruction. */
4373 if (target_is_430x ())
4375 for (i
= 0; i
< 7 && !cc
; i
++)
4376 if (msp430x_rcodes
[i
].sop
== insn
)
4377 cc
= msp430x_rcodes
+ i
;
4381 for (i
= 0; i
< 7 && !cc
; i
++)
4382 if (msp430_rcodes
[i
].sop
== insn
)
4383 cc
= & msp430_rcodes
[i
];
4386 if (!cc
|| !cc
->name
)
4387 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4388 __FUNCTION__
, (long) insn
);
4389 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4390 bfd_putl16 (cc
->lop0
, where
);
4391 bfd_putl16 (cc
->lop1
, where
+ 2);
4392 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4397 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4398 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4399 if (target_is_430x ())
4400 cc
= msp430x_rcodes
+ 6;
4402 cc
= msp430_rcodes
+ 6;
4403 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4404 bfd_putl16 (cc
->lop0
, where
);
4405 bfd_putl16 (cc
->lop1
, where
+ 2);
4406 bfd_putl16 (cc
->lop2
, where
+ 4);
4407 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4411 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4413 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4416 if (target_is_430x ())
4418 for (i
= 0; i
< 4 && !hc
; i
++)
4419 if (msp430x_hcodes
[i
].op1
== insn
)
4420 hc
= msp430x_hcodes
+ i
;
4424 for (i
= 0; i
< 4 && !hc
; i
++)
4425 if (msp430_hcodes
[i
].op1
== insn
)
4426 hc
= &msp430_hcodes
[i
];
4428 if (!hc
|| !hc
->name
)
4429 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4430 __FUNCTION__
, (long) insn
);
4431 rela
= BFD_RELOC_MSP430_10_PCREL
;
4432 /* Apply a fix for a first label if necessary.
4433 another fix will be applied to the next word of insn anyway. */
4435 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4436 fragP
->fr_offset
, TRUE
, rela
);
4442 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4443 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4445 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4448 if (target_is_430x ())
4450 for (i
= 0; i
< 4 && !hc
; i
++)
4451 if (msp430x_hcodes
[i
].op1
== insn
)
4452 hc
= msp430x_hcodes
+ i
;
4456 for (i
= 0; i
< 4 && !hc
; i
++)
4457 if (msp430_hcodes
[i
].op1
== insn
)
4458 hc
= & msp430_hcodes
[i
];
4460 if (!hc
|| !hc
->name
)
4461 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4462 __FUNCTION__
, (long) insn
);
4463 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4464 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4465 bfd_putl16 (hc
->lop0
, where
);
4466 bfd_putl16 (hc
->lop1
, where
+ 2);
4467 bfd_putl16 (hc
->lop2
, where
+ 4);
4473 as_fatal (_("internal inconsistency problem in %s: %lx"),
4474 __FUNCTION__
, (long) fragP
->fr_subtype
);
4478 /* Now apply fix. */
4479 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4480 fragP
->fr_offset
, TRUE
, rela
);
4481 /* Just fixed 2 bytes. */
4485 /* Relax fragment. Mostly stolen from hc11 and mcore
4486 which arches I think I know. */
4489 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4490 long stretch ATTRIBUTE_UNUSED
)
4495 const relax_typeS
*this_type
;
4496 const relax_typeS
*start_type
;
4497 relax_substateT next_state
;
4498 relax_substateT this_state
;
4499 const relax_typeS
*table
= md_relax_table
;
4501 /* Nothing to be done if the frag has already max size. */
4502 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4503 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4506 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4508 symbolP
= fragP
->fr_symbol
;
4509 if (symbol_resolved_p (symbolP
))
4510 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4512 /* We know the offset. calculate a distance. */
4513 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4516 if (!msp430_enable_relax
)
4518 /* Relaxation is not enabled. So, make all jump as long ones
4519 by setting 'aim' to quite high value. */
4523 this_state
= fragP
->fr_subtype
;
4524 start_type
= this_type
= table
+ this_state
;
4528 /* Look backwards. */
4529 for (next_state
= this_type
->rlx_more
; next_state
;)
4530 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4534 /* Grow to next state. */
4535 this_state
= next_state
;
4536 this_type
= table
+ this_state
;
4537 next_state
= this_type
->rlx_more
;
4542 /* Look forwards. */
4543 for (next_state
= this_type
->rlx_more
; next_state
;)
4544 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4548 /* Grow to next state. */
4549 this_state
= next_state
;
4550 this_type
= table
+ this_state
;
4551 next_state
= this_type
->rlx_more
;
4555 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4557 fragP
->fr_subtype
= this_state
;
4561 /* Return FALSE if the fixup in fixp should be left alone and not
4562 adjusted. We return FALSE here so that linker relaxation will
4566 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4568 /* If the symbol is in a non-code section then it should be OK. */
4570 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4576 /* Set the contents of the .MSP430.attributes section. */
4579 msp430_md_end (void)
4582 as_warn ("assembly finished without a possibly needed NOP instruction");
4584 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4585 target_is_430x () ? 2 : 1);
4587 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4588 large_model
? 2 : 1);
4590 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4591 large_model
? 2 : 1);
4594 /* Returns FALSE if there is a msp430 specific reason why the
4595 subtraction of two same-section symbols cannot be computed by
4599 msp430_allow_local_subtract (expressionS
* left
,
4600 expressionS
* right
,
4603 /* If the symbols are not in a code section then they are OK. */
4604 if ((section
->flags
& SEC_CODE
) == 0)
4607 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4610 if (left
->X_add_symbol
== right
->X_add_symbol
)
4613 /* We have to assume that there may be instructions between the
4614 two symbols and that relaxation may increase the distance between