1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2024 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
106 int index
; /* Corresponding insn_opnumb. */
107 int sop
; /* Opcode if jump length is short. */
108 long lpos
; /* Label position. */
109 long lop0
; /* Opcode 1 _word_ (16 bits). */
110 long lop1
; /* Opcode second word. */
111 long lop2
; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes
[] =
119 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
131 #define MSP430_RLC(n,i,sop,o1) \
132 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
134 static struct rcodes_s msp430x_rcodes
[] =
136 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
137 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
138 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
139 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
140 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
141 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
142 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
143 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
148 /* More difficult than above and they have format 5.
151 =================================================================
152 gt > jeq +2; jge label jeq +6; jl +4; br label
153 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
154 leu <= jeq label; jlo label jeq +2; jhs +4; br label
155 le <= jeq label; jl label jeq +2; jge +4; br label
156 ================================================================= */
161 int index
; /* Corresponding insn_opnumb. */
162 int tlab
; /* Number of labels in short mode. */
163 int op0
; /* Opcode for first word of short jump. */
164 int op1
; /* Opcode for second word of short jump. */
165 int lop0
; /* Opcodes for long jump mode. */
170 static struct hcodes_s msp430_hcodes
[] =
172 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
173 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
174 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
175 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 static struct hcodes_s msp430x_hcodes
[] =
181 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
182 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
183 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
184 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 const char comment_chars
[] = ";";
189 const char line_comment_chars
[] = "#";
190 const char line_separator_chars
[] = "{";
191 const char EXP_CHARS
[] = "eE";
192 const char FLT_CHARS
[] = "dD";
194 /* Handle long expressions. */
195 extern LITTLENUM_TYPE generic_bignum
[];
197 static htab_t msp430_hash
;
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
212 #define STATE_BITS10 1 /* Wild guess. short jump. */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */
214 #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table
[] =
229 /* Unconditional jump. */
231 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
232 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
233 {1, 1, CUBL
, 0}, /* state undef */
235 /* Simple branches. */
237 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
238 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
241 /* blt no overflow branch. */
243 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
244 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
247 /* Emulated branches. */
249 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
250 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation, for 430 (!extended_op) instructions
280 For the 430X we generate a 430 relocation only for the case where part of an
281 expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate
283 For the 430 we generate a relocation without assembler range checking
284 if we are handling an immediate value or a byte-width instruction. */
286 #undef CHECK_RELOC_MSP430
287 #define CHECK_RELOC_MSP430(OP) \
289 ? ((OP).expp == MSP_EXPP_ALL \
290 ? BFD_RELOC_MSP430X_ABS16 \
291 : ((OP).vshift == 1 \
292 ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
303 ? BFD_RELOC_MSP430X_PCR16 \
304 : (imm_op || byte_op) \
305 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
307 /* Profiling capability:
308 It is a performance hit to use gcc's profiling approach for this tiny target.
309 Even more -- jtag hardware facility does not perform any profiling functions.
310 However we've got gdb's built-in simulator where we can do anything.
311 Therefore my suggestion is:
313 We define new section ".profiler" which holds all profiling information.
314 We define new pseudo operation .profiler which will instruct assembler to
315 add new profile entry to the object file. Profile should take place at the
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
325 i - function is in Init section
326 f - function is in Fini section
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
335 j - long Jump/ sjlj unwind
336 a - an Arbitrary code fragment
337 t - exTra parameter saved (constant value like frame size)
338 '""' optional: "sil" == sil
340 function_to_profile - function's address
341 cycle_corrector - a value which should be added to the cycle
342 counter, zero if omitted
343 extra - some extra parameter, zero if omitted.
346 ------------------------------
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
357 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
358 ; (this is a prologue end)
359 ; note, that spare var filled with the frame size
362 .profiler cdE,fxx ; check stack
367 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
368 ret ; cause 'ret' insn takes 3 cycles
369 -------------------------------
371 This profiling approach does not produce any overhead and
373 So, even profiled code can be uploaded to the MCU. */
374 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
375 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
376 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
377 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
378 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
379 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
380 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
381 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
382 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
383 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
384 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
385 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
386 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
387 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
388 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
389 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
402 for (; x
; x
= x
>> 1)
409 /* Parse ordinary expression. */
412 parse_exp (char * s
, expressionS
* op
)
414 input_line_pointer
= s
;
416 if (op
->X_op
== O_absent
)
417 as_bad (_("missing operand"));
419 resolve_register (op
);
421 /* Our caller is likely to check that the entire expression was parsed.
422 If we have found a hex constant with an 'h' suffix, ilp will be left
423 pointing at the 'h', so skip it here. */
424 if (input_line_pointer
!= NULL
425 && op
->X_op
== O_constant
426 && (*input_line_pointer
== 'h' || *input_line_pointer
== 'H'))
427 ++ input_line_pointer
;
428 return input_line_pointer
;
432 /* Delete spaces from s: X ( r 1 2) => X(r12). */
435 del_spaces (char * s
)
443 while (ISSPACE (*m
) && *m
)
445 memmove (s
, m
, strlen (m
) + 1);
453 skip_space (char * s
)
460 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
463 extract_operand (char * from
, char * to
, int limit
)
467 /* Drop leading whitespace. */
468 from
= skip_space (from
);
470 while (size
< limit
&& *from
)
472 *(to
+ size
) = *from
;
473 if (*from
== ',' || *from
== ';' || *from
== '\n')
488 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
505 s
= input_line_pointer
;
506 end
= input_line_pointer
;
508 while (*end
&& *end
!= '\n')
511 while (*s
&& *s
!= '\n')
522 as_bad (_(".profiler pseudo requires at least two operands."));
523 input_line_pointer
= end
;
527 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
536 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
539 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
542 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
545 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
548 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
551 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
554 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
557 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
560 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
563 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
566 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
569 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
572 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
575 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
578 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
581 as_warn (_("unknown profiling flag - ignored."));
588 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
589 | MSP430_PROFILER_FLAG_EXIT
))
590 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
591 | MSP430_PROFILER_FLAG_PROLEND
592 | MSP430_PROFILER_FLAG_EPISTART
593 | MSP430_PROFILER_FLAG_EPIEND
))
594 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
595 | MSP430_PROFILER_FLAG_FINISECT
))))
597 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
598 input_line_pointer
= end
;
602 /* Generate temp symbol which denotes current location. */
603 if (now_seg
== absolute_section
) /* Paranoia ? */
605 exp1
.X_op
= O_constant
;
606 exp1
.X_add_number
= abs_section_offset
;
607 as_warn (_("profiling in absolute section?"));
611 exp1
.X_op
= O_symbol
;
612 exp1
.X_add_symbol
= symbol_temp_new_now ();
613 exp1
.X_add_number
= 0;
616 /* Generate a symbol which holds flags value. */
617 exp
.X_op
= O_constant
;
618 exp
.X_add_number
= p_flags
;
620 /* Save current section. */
624 /* Now go to .profiler section. */
625 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, false);
628 emit_expr (& exp
, 2);
630 /* Save label value. */
631 emit_expr (& exp1
, 2);
635 /* Now get profiling info. */
636 halt
= extract_operand (input_line_pointer
, str
, 1024);
637 /* Process like ".word xxx" directive. */
638 (void) parse_exp (str
, & exp
);
639 emit_expr (& exp
, 2);
640 input_line_pointer
= halt
;
643 /* Fill the rest with zeros. */
644 exp
.X_op
= O_constant
;
645 exp
.X_add_number
= 0;
647 emit_expr (& exp
, 2);
649 /* Return to current section. */
650 subseg_set (seg
, subseg
);
654 extract_word (char * from
, char * to
, int limit
)
659 /* Drop leading whitespace. */
660 from
= skip_space (from
);
663 /* Find the op code end. */
664 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
666 to
[size
++] = *op_end
++;
667 if (size
+ 1 >= limit
)
675 #define OPTION_MMCU 'm'
676 #define OPTION_RELAX 'Q'
677 #define OPTION_POLYMORPHS 'P'
678 #define OPTION_LARGE 'l'
679 static bool large_model
= false;
680 #define OPTION_NO_INTR_NOPS 'N'
681 #define OPTION_INTR_NOPS 'n'
682 static bool gen_interrupt_nops
= false;
683 #define OPTION_WARN_INTR_NOPS 'y'
684 #define OPTION_NO_WARN_INTR_NOPS 'Y'
685 static bool warn_interrupt_nops
= true;
686 #define OPTION_UNKNOWN_INTR_NOPS 'u'
687 #define OPTION_NO_UNKNOWN_INTR_NOPS 'U'
688 static bool do_unknown_interrupt_nops
= true;
689 #define OPTION_MCPU 'c'
690 #define OPTION_DATA_REGION 'r'
691 static bool upper_data_region_in_use
= false;
692 /* The default is to use the lower region only. */
693 static bool lower_data_region_only
= true;
695 /* Deprecated option, silently ignore it for compatibility with GCC <= 10. */
696 #define OPTION_MOVE_DATA 'd'
700 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
701 OPTION_SILICON_ERRATA_WARN
,
704 static unsigned int silicon_errata_fix
= 0;
705 static unsigned int silicon_errata_warn
= 0;
706 #define SILICON_ERRATA_CPU4 (1 << 0)
707 #define SILICON_ERRATA_CPU8 (1 << 1)
708 #define SILICON_ERRATA_CPU11 (1 << 2)
709 #define SILICON_ERRATA_CPU12 (1 << 3)
710 #define SILICON_ERRATA_CPU13 (1 << 4)
711 #define SILICON_ERRATA_CPU19 (1 << 5)
714 msp430_set_arch (int option
)
716 char str
[32]; /* 32 for good measure. */
718 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
720 md_parse_option (option
, str
);
721 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
722 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
725 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
726 Keep these two structures in sync.
727 The data in this structure has been extracted from version 1.194 of the
728 devices.csv file released by TI in September 2016. */
730 struct msp430_mcu_data
733 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
734 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
738 { "cc430f5123",2,8 },
739 { "cc430f5125",2,8 },
740 { "cc430f5133",2,8 },
741 { "cc430f5135",2,8 },
742 { "cc430f5137",2,8 },
743 { "cc430f5143",2,8 },
744 { "cc430f5145",2,8 },
745 { "cc430f5147",2,8 },
746 { "cc430f6125",2,8 },
747 { "cc430f6126",2,8 },
748 { "cc430f6127",2,8 },
749 { "cc430f6135",2,8 },
750 { "cc430f6137",2,8 },
751 { "cc430f6143",2,8 },
752 { "cc430f6145",2,8 },
753 { "cc430f6147",2,8 },
754 { "msp430afe221",0,2 },
755 { "msp430afe222",0,2 },
756 { "msp430afe223",0,2 },
757 { "msp430afe231",0,2 },
758 { "msp430afe232",0,2 },
759 { "msp430afe233",0,2 },
760 { "msp430afe251",0,2 },
761 { "msp430afe252",0,2 },
762 { "msp430afe253",0,2 },
763 { "msp430bt5190",2,8 },
764 { "msp430c091",0,0 },
765 { "msp430c092",0,0 },
766 { "msp430c111",0,0 },
767 { "msp430c1111",0,0 },
768 { "msp430c112",0,0 },
769 { "msp430c1121",0,0 },
770 { "msp430c1331",0,0 },
771 { "msp430c1351",0,0 },
772 { "msp430c311s",0,0 },
773 { "msp430c312",0,0 },
774 { "msp430c313",0,0 },
775 { "msp430c314",0,0 },
776 { "msp430c315",0,0 },
777 { "msp430c323",0,0 },
778 { "msp430c325",0,0 },
779 { "msp430c336",0,1 },
780 { "msp430c337",0,1 },
781 { "msp430c412",0,0 },
782 { "msp430c413",0,0 },
783 { "msp430cg4616",1,1 },
784 { "msp430cg4617",1,1 },
785 { "msp430cg4618",1,1 },
786 { "msp430cg4619",1,1 },
787 { "msp430e112",0,0 },
788 { "msp430e313",0,0 },
789 { "msp430e315",0,0 },
790 { "msp430e325",0,0 },
791 { "msp430e337",0,1 },
792 { "msp430f110",0,0 },
793 { "msp430f1101",0,0 },
794 { "msp430f1101a",0,0 },
795 { "msp430f1111",0,0 },
796 { "msp430f1111a",0,0 },
797 { "msp430f112",0,0 },
798 { "msp430f1121",0,0 },
799 { "msp430f1121a",0,0 },
800 { "msp430f1122",0,0 },
801 { "msp430f1132",0,0 },
802 { "msp430f122",0,0 },
803 { "msp430f1222",0,0 },
804 { "msp430f123",0,0 },
805 { "msp430f1232",0,0 },
806 { "msp430f133",0,0 },
807 { "msp430f135",0,0 },
808 { "msp430f147",0,1 },
809 { "msp430f1471",0,1 },
810 { "msp430f148",0,1 },
811 { "msp430f1481",0,1 },
812 { "msp430f149",0,1 },
813 { "msp430f1491",0,1 },
814 { "msp430f155",0,0 },
815 { "msp430f156",0,0 },
816 { "msp430f157",0,0 },
817 { "msp430f1610",0,1 },
818 { "msp430f1611",0,1 },
819 { "msp430f1612",0,1 },
820 { "msp430f167",0,1 },
821 { "msp430f168",0,1 },
822 { "msp430f169",0,1 },
823 { "msp430f2001",0,0 },
824 { "msp430f2002",0,0 },
825 { "msp430f2003",0,0 },
826 { "msp430f2011",0,0 },
827 { "msp430f2012",0,0 },
828 { "msp430f2013",0,0 },
829 { "msp430f2101",0,0 },
830 { "msp430f2111",0,0 },
831 { "msp430f2112",0,0 },
832 { "msp430f2121",0,0 },
833 { "msp430f2122",0,0 },
834 { "msp430f2131",0,0 },
835 { "msp430f2132",0,0 },
836 { "msp430f2232",0,0 },
837 { "msp430f2234",0,0 },
838 { "msp430f2252",0,0 },
839 { "msp430f2254",0,0 },
840 { "msp430f2272",0,0 },
841 { "msp430f2274",0,0 },
842 { "msp430f233",0,2 },
843 { "msp430f2330",0,2 },
844 { "msp430f235",0,2 },
845 { "msp430f2350",0,2 },
846 { "msp430f2370",0,2 },
847 { "msp430f2410",0,2 },
848 { "msp430f2416",1,2 },
849 { "msp430f2417",1,2 },
850 { "msp430f2418",1,2 },
851 { "msp430f2419",1,2 },
852 { "msp430f247",0,2 },
853 { "msp430f2471",0,2 },
854 { "msp430f248",0,2 },
855 { "msp430f2481",0,2 },
856 { "msp430f249",0,2 },
857 { "msp430f2491",0,2 },
858 { "msp430f2616",1,2 },
859 { "msp430f2617",1,2 },
860 { "msp430f2618",1,2 },
861 { "msp430f2619",1,2 },
862 { "msp430f412",0,0 },
863 { "msp430f413",0,0 },
864 { "msp430f4132",0,0 },
865 { "msp430f415",0,0 },
866 { "msp430f4152",0,0 },
867 { "msp430f417",0,0 },
868 { "msp430f423",0,1 },
869 { "msp430f423a",0,1 },
870 { "msp430f425",0,1 },
871 { "msp430f4250",0,0 },
872 { "msp430f425a",0,1 },
873 { "msp430f4260",0,0 },
874 { "msp430f427",0,1 },
875 { "msp430f4270",0,0 },
876 { "msp430f427a",0,1 },
877 { "msp430f435",0,0 },
878 { "msp430f4351",0,0 },
879 { "msp430f436",0,0 },
880 { "msp430f4361",0,0 },
881 { "msp430f437",0,0 },
882 { "msp430f4371",0,0 },
883 { "msp430f438",0,0 },
884 { "msp430f439",0,0 },
885 { "msp430f447",0,1 },
886 { "msp430f448",0,1 },
887 { "msp430f4481",0,1 },
888 { "msp430f449",0,1 },
889 { "msp430f4491",0,1 },
890 { "msp430f4616",1,1 },
891 { "msp430f46161",1,1 },
892 { "msp430f4617",1,1 },
893 { "msp430f46171",1,1 },
894 { "msp430f4618",1,1 },
895 { "msp430f46181",1,1 },
896 { "msp430f4619",1,1 },
897 { "msp430f46191",1,1 },
898 { "msp430f47126",1,4 },
899 { "msp430f47127",1,4 },
900 { "msp430f47163",1,4 },
901 { "msp430f47166",1,4 },
902 { "msp430f47167",1,4 },
903 { "msp430f47173",1,4 },
904 { "msp430f47176",1,4 },
905 { "msp430f47177",1,4 },
906 { "msp430f47183",1,4 },
907 { "msp430f47186",1,4 },
908 { "msp430f47187",1,4 },
909 { "msp430f47193",1,4 },
910 { "msp430f47196",1,4 },
911 { "msp430f47197",1,4 },
912 { "msp430f477",0,0 },
913 { "msp430f478",0,0 },
914 { "msp430f4783",0,4 },
915 { "msp430f4784",0,4 },
916 { "msp430f479",0,0 },
917 { "msp430f4793",0,4 },
918 { "msp430f4794",0,4 },
919 { "msp430f5131",2,8 },
920 { "msp430f5132",2,8 },
921 { "msp430f5151",2,8 },
922 { "msp430f5152",2,8 },
923 { "msp430f5171",2,8 },
924 { "msp430f5172",2,8 },
925 { "msp430f5212",2,8 },
926 { "msp430f5213",2,8 },
927 { "msp430f5214",2,8 },
928 { "msp430f5217",2,8 },
929 { "msp430f5218",2,8 },
930 { "msp430f5219",2,8 },
931 { "msp430f5222",2,8 },
932 { "msp430f5223",2,8 },
933 { "msp430f5224",2,8 },
934 { "msp430f5227",2,8 },
935 { "msp430f5228",2,8 },
936 { "msp430f5229",2,8 },
937 { "msp430f5232",2,8 },
938 { "msp430f5234",2,8 },
939 { "msp430f5237",2,8 },
940 { "msp430f5239",2,8 },
941 { "msp430f5242",2,8 },
942 { "msp430f5244",2,8 },
943 { "msp430f5247",2,8 },
944 { "msp430f5249",2,8 },
945 { "msp430f5252",2,8 },
946 { "msp430f5253",2,8 },
947 { "msp430f5254",2,8 },
948 { "msp430f5255",2,8 },
949 { "msp430f5256",2,8 },
950 { "msp430f5257",2,8 },
951 { "msp430f5258",2,8 },
952 { "msp430f5259",2,8 },
953 { "msp430f5304",2,8 },
954 { "msp430f5308",2,8 },
955 { "msp430f5309",2,8 },
956 { "msp430f5310",2,8 },
957 { "msp430f5324",2,8 },
958 { "msp430f5325",2,8 },
959 { "msp430f5326",2,8 },
960 { "msp430f5327",2,8 },
961 { "msp430f5328",2,8 },
962 { "msp430f5329",2,8 },
963 { "msp430f5333",2,8 },
964 { "msp430f5335",2,8 },
965 { "msp430f5336",2,8 },
966 { "msp430f5338",2,8 },
967 { "msp430f5340",2,8 },
968 { "msp430f5341",2,8 },
969 { "msp430f5342",2,8 },
970 { "msp430f5358",2,8 },
971 { "msp430f5359",2,8 },
972 { "msp430f5418",2,8 },
973 { "msp430f5418a",2,8 },
974 { "msp430f5419",2,8 },
975 { "msp430f5419a",2,8 },
976 { "msp430f5435",2,8 },
977 { "msp430f5435a",2,8 },
978 { "msp430f5436",2,8 },
979 { "msp430f5436a",2,8 },
980 { "msp430f5437",2,8 },
981 { "msp430f5437a",2,8 },
982 { "msp430f5438",2,8 },
983 { "msp430f5438a",2,8 },
984 { "msp430f5500",2,8 },
985 { "msp430f5501",2,8 },
986 { "msp430f5502",2,8 },
987 { "msp430f5503",2,8 },
988 { "msp430f5504",2,8 },
989 { "msp430f5505",2,8 },
990 { "msp430f5506",2,8 },
991 { "msp430f5507",2,8 },
992 { "msp430f5508",2,8 },
993 { "msp430f5509",2,8 },
994 { "msp430f5510",2,8 },
995 { "msp430f5513",2,8 },
996 { "msp430f5514",2,8 },
997 { "msp430f5515",2,8 },
998 { "msp430f5517",2,8 },
999 { "msp430f5519",2,8 },
1000 { "msp430f5521",2,8 },
1001 { "msp430f5522",2,8 },
1002 { "msp430f5524",2,8 },
1003 { "msp430f5525",2,8 },
1004 { "msp430f5526",2,8 },
1005 { "msp430f5527",2,8 },
1006 { "msp430f5528",2,8 },
1007 { "msp430f5529",2,8 },
1008 { "msp430f5630",2,8 },
1009 { "msp430f5631",2,8 },
1010 { "msp430f5632",2,8 },
1011 { "msp430f5633",2,8 },
1012 { "msp430f5634",2,8 },
1013 { "msp430f5635",2,8 },
1014 { "msp430f5636",2,8 },
1015 { "msp430f5637",2,8 },
1016 { "msp430f5638",2,8 },
1017 { "msp430f5658",2,8 },
1018 { "msp430f5659",2,8 },
1019 { "msp430f5xx_6xxgeneric",2,8 },
1020 { "msp430f6433",2,8 },
1021 { "msp430f6435",2,8 },
1022 { "msp430f6436",2,8 },
1023 { "msp430f6438",2,8 },
1024 { "msp430f6458",2,8 },
1025 { "msp430f6459",2,8 },
1026 { "msp430f6630",2,8 },
1027 { "msp430f6631",2,8 },
1028 { "msp430f6632",2,8 },
1029 { "msp430f6633",2,8 },
1030 { "msp430f6634",2,8 },
1031 { "msp430f6635",2,8 },
1032 { "msp430f6636",2,8 },
1033 { "msp430f6637",2,8 },
1034 { "msp430f6638",2,8 },
1035 { "msp430f6658",2,8 },
1036 { "msp430f6659",2,8 },
1037 { "msp430f6720",2,8 },
1038 { "msp430f6720a",2,8 },
1039 { "msp430f6721",2,8 },
1040 { "msp430f6721a",2,8 },
1041 { "msp430f6723",2,8 },
1042 { "msp430f6723a",2,8 },
1043 { "msp430f6724",2,8 },
1044 { "msp430f6724a",2,8 },
1045 { "msp430f6725",2,8 },
1046 { "msp430f6725a",2,8 },
1047 { "msp430f6726",2,8 },
1048 { "msp430f6726a",2,8 },
1049 { "msp430f6730",2,8 },
1050 { "msp430f6730a",2,8 },
1051 { "msp430f6731",2,8 },
1052 { "msp430f6731a",2,8 },
1053 { "msp430f6733",2,8 },
1054 { "msp430f6733a",2,8 },
1055 { "msp430f6734",2,8 },
1056 { "msp430f6734a",2,8 },
1057 { "msp430f6735",2,8 },
1058 { "msp430f6735a",2,8 },
1059 { "msp430f6736",2,8 },
1060 { "msp430f6736a",2,8 },
1061 { "msp430f6745",2,8 },
1062 { "msp430f67451",2,8 },
1063 { "msp430f67451a",2,8 },
1064 { "msp430f6745a",2,8 },
1065 { "msp430f6746",2,8 },
1066 { "msp430f67461",2,8 },
1067 { "msp430f67461a",2,8 },
1068 { "msp430f6746a",2,8 },
1069 { "msp430f6747",2,8 },
1070 { "msp430f67471",2,8 },
1071 { "msp430f67471a",2,8 },
1072 { "msp430f6747a",2,8 },
1073 { "msp430f6748",2,8 },
1074 { "msp430f67481",2,8 },
1075 { "msp430f67481a",2,8 },
1076 { "msp430f6748a",2,8 },
1077 { "msp430f6749",2,8 },
1078 { "msp430f67491",2,8 },
1079 { "msp430f67491a",2,8 },
1080 { "msp430f6749a",2,8 },
1081 { "msp430f67621",2,8 },
1082 { "msp430f67621a",2,8 },
1083 { "msp430f67641",2,8 },
1084 { "msp430f67641a",2,8 },
1085 { "msp430f6765",2,8 },
1086 { "msp430f67651",2,8 },
1087 { "msp430f67651a",2,8 },
1088 { "msp430f6765a",2,8 },
1089 { "msp430f6766",2,8 },
1090 { "msp430f67661",2,8 },
1091 { "msp430f67661a",2,8 },
1092 { "msp430f6766a",2,8 },
1093 { "msp430f6767",2,8 },
1094 { "msp430f67671",2,8 },
1095 { "msp430f67671a",2,8 },
1096 { "msp430f6767a",2,8 },
1097 { "msp430f6768",2,8 },
1098 { "msp430f67681",2,8 },
1099 { "msp430f67681a",2,8 },
1100 { "msp430f6768a",2,8 },
1101 { "msp430f6769",2,8 },
1102 { "msp430f67691",2,8 },
1103 { "msp430f67691a",2,8 },
1104 { "msp430f6769a",2,8 },
1105 { "msp430f6775",2,8 },
1106 { "msp430f67751",2,8 },
1107 { "msp430f67751a",2,8 },
1108 { "msp430f6775a",2,8 },
1109 { "msp430f6776",2,8 },
1110 { "msp430f67761",2,8 },
1111 { "msp430f67761a",2,8 },
1112 { "msp430f6776a",2,8 },
1113 { "msp430f6777",2,8 },
1114 { "msp430f67771",2,8 },
1115 { "msp430f67771a",2,8 },
1116 { "msp430f6777a",2,8 },
1117 { "msp430f6778",2,8 },
1118 { "msp430f67781",2,8 },
1119 { "msp430f67781a",2,8 },
1120 { "msp430f6778a",2,8 },
1121 { "msp430f6779",2,8 },
1122 { "msp430f67791",2,8 },
1123 { "msp430f67791a",2,8 },
1124 { "msp430f6779a",2,8 },
1125 { "msp430fe423",0,0 },
1126 { "msp430fe4232",0,0 },
1127 { "msp430fe423a",0,0 },
1128 { "msp430fe4242",0,0 },
1129 { "msp430fe425",0,0 },
1130 { "msp430fe4252",0,0 },
1131 { "msp430fe425a",0,0 },
1132 { "msp430fe427",0,0 },
1133 { "msp430fe4272",0,0 },
1134 { "msp430fe427a",0,0 },
1135 { "msp430fg4250",0,0 },
1136 { "msp430fg4260",0,0 },
1137 { "msp430fg4270",0,0 },
1138 { "msp430fg437",0,0 },
1139 { "msp430fg438",0,0 },
1140 { "msp430fg439",0,0 },
1141 { "msp430fg4616",1,1 },
1142 { "msp430fg4617",1,1 },
1143 { "msp430fg4618",1,1 },
1144 { "msp430fg4619",1,1 },
1145 { "msp430fg477",0,0 },
1146 { "msp430fg478",0,0 },
1147 { "msp430fg479",0,0 },
1148 { "msp430fg6425",2,8 },
1149 { "msp430fg6426",2,8 },
1150 { "msp430fg6625",2,8 },
1151 { "msp430fg6626",2,8 },
1152 { "msp430fr2032",2,0 },
1153 { "msp430fr2033",2,0 },
1154 { "msp430fr2110",2,0 },
1155 { "msp430fr2111",2,0 },
1156 { "msp430fr2310",2,0 },
1157 { "msp430fr2311",2,0 },
1158 { "msp430fr2433",2,8 },
1159 { "msp430fr2532",2,8 },
1160 { "msp430fr2533",2,8 },
1161 { "msp430fr2632",2,8 },
1162 { "msp430fr2633",2,8 },
1163 { "msp430fr2xx_4xxgeneric",2,8 },
1164 { "msp430fr4131",2,0 },
1165 { "msp430fr4132",2,0 },
1166 { "msp430fr4133",2,0 },
1167 { "msp430fr5720",2,8 },
1168 { "msp430fr5721",2,8 },
1169 { "msp430fr5722",2,8 },
1170 { "msp430fr5723",2,8 },
1171 { "msp430fr5724",2,8 },
1172 { "msp430fr5725",2,8 },
1173 { "msp430fr5726",2,8 },
1174 { "msp430fr5727",2,8 },
1175 { "msp430fr5728",2,8 },
1176 { "msp430fr5729",2,8 },
1177 { "msp430fr5730",2,8 },
1178 { "msp430fr5731",2,8 },
1179 { "msp430fr5732",2,8 },
1180 { "msp430fr5733",2,8 },
1181 { "msp430fr5734",2,8 },
1182 { "msp430fr5735",2,8 },
1183 { "msp430fr5736",2,8 },
1184 { "msp430fr5737",2,8 },
1185 { "msp430fr5738",2,8 },
1186 { "msp430fr5739",2,8 },
1187 { "msp430fr57xxgeneric",2,8 },
1188 { "msp430fr5847",2,8 },
1189 { "msp430fr58471",2,8 },
1190 { "msp430fr5848",2,8 },
1191 { "msp430fr5849",2,8 },
1192 { "msp430fr5857",2,8 },
1193 { "msp430fr5858",2,8 },
1194 { "msp430fr5859",2,8 },
1195 { "msp430fr5867",2,8 },
1196 { "msp430fr58671",2,8 },
1197 { "msp430fr5868",2,8 },
1198 { "msp430fr5869",2,8 },
1199 { "msp430fr5870",2,8 },
1200 { "msp430fr5872",2,8 },
1201 { "msp430fr58721",2,8 },
1202 { "msp430fr5887",2,8 },
1203 { "msp430fr5888",2,8 },
1204 { "msp430fr5889",2,8 },
1205 { "msp430fr58891",2,8 },
1206 { "msp430fr5922",2,8 },
1207 { "msp430fr59221",2,8 },
1208 { "msp430fr5947",2,8 },
1209 { "msp430fr59471",2,8 },
1210 { "msp430fr5948",2,8 },
1211 { "msp430fr5949",2,8 },
1212 { "msp430fr5957",2,8 },
1213 { "msp430fr5958",2,8 },
1214 { "msp430fr5959",2,8 },
1215 { "msp430fr5962",2,8 },
1216 { "msp430fr5964",2,8 },
1217 { "msp430fr5967",2,8 },
1218 { "msp430fr5968",2,8 },
1219 { "msp430fr5969",2,8 },
1220 { "msp430fr59691",2,8 },
1221 { "msp430fr5970",2,8 },
1222 { "msp430fr5972",2,8 },
1223 { "msp430fr59721",2,8 },
1224 { "msp430fr5986",2,8 },
1225 { "msp430fr5987",2,8 },
1226 { "msp430fr5988",2,8 },
1227 { "msp430fr5989",2,8 },
1228 { "msp430fr59891",2,8 },
1229 { "msp430fr5992",2,8 },
1230 { "msp430fr5994",2,8 },
1231 { "msp430fr59941",2,8 },
1232 { "msp430fr5xx_6xxgeneric",2,8 },
1233 { "msp430fr6820",2,8 },
1234 { "msp430fr6822",2,8 },
1235 { "msp430fr68221",2,8 },
1236 { "msp430fr6870",2,8 },
1237 { "msp430fr6872",2,8 },
1238 { "msp430fr68721",2,8 },
1239 { "msp430fr6877",2,8 },
1240 { "msp430fr6879",2,8 },
1241 { "msp430fr68791",2,8 },
1242 { "msp430fr6887",2,8 },
1243 { "msp430fr6888",2,8 },
1244 { "msp430fr6889",2,8 },
1245 { "msp430fr68891",2,8 },
1246 { "msp430fr6920",2,8 },
1247 { "msp430fr6922",2,8 },
1248 { "msp430fr69221",2,8 },
1249 { "msp430fr6927",2,8 },
1250 { "msp430fr69271",2,8 },
1251 { "msp430fr6928",2,8 },
1252 { "msp430fr6970",2,8 },
1253 { "msp430fr6972",2,8 },
1254 { "msp430fr69721",2,8 },
1255 { "msp430fr6977",2,8 },
1256 { "msp430fr6979",2,8 },
1257 { "msp430fr69791",2,8 },
1258 { "msp430fr6987",2,8 },
1259 { "msp430fr6988",2,8 },
1260 { "msp430fr6989",2,8 },
1261 { "msp430fr69891",2,8 },
1262 { "msp430fw423",0,0 },
1263 { "msp430fw425",0,0 },
1264 { "msp430fw427",0,0 },
1265 { "msp430fw428",0,0 },
1266 { "msp430fw429",0,0 },
1267 { "msp430g2001",0,0 },
1268 { "msp430g2101",0,0 },
1269 { "msp430g2102",0,0 },
1270 { "msp430g2111",0,0 },
1271 { "msp430g2112",0,0 },
1272 { "msp430g2113",0,0 },
1273 { "msp430g2121",0,0 },
1274 { "msp430g2131",0,0 },
1275 { "msp430g2132",0,0 },
1276 { "msp430g2152",0,0 },
1277 { "msp430g2153",0,0 },
1278 { "msp430g2201",0,0 },
1279 { "msp430g2202",0,0 },
1280 { "msp430g2203",0,0 },
1281 { "msp430g2210",0,0 },
1282 { "msp430g2211",0,0 },
1283 { "msp430g2212",0,0 },
1284 { "msp430g2213",0,0 },
1285 { "msp430g2221",0,0 },
1286 { "msp430g2230",0,0 },
1287 { "msp430g2231",0,0 },
1288 { "msp430g2232",0,0 },
1289 { "msp430g2233",0,0 },
1290 { "msp430g2252",0,0 },
1291 { "msp430g2253",0,0 },
1292 { "msp430g2302",0,0 },
1293 { "msp430g2303",0,0 },
1294 { "msp430g2312",0,0 },
1295 { "msp430g2313",0,0 },
1296 { "msp430g2332",0,0 },
1297 { "msp430g2333",0,0 },
1298 { "msp430g2352",0,0 },
1299 { "msp430g2353",0,0 },
1300 { "msp430g2402",0,0 },
1301 { "msp430g2403",0,0 },
1302 { "msp430g2412",0,0 },
1303 { "msp430g2413",0,0 },
1304 { "msp430g2432",0,0 },
1305 { "msp430g2433",0,0 },
1306 { "msp430g2444",0,0 },
1307 { "msp430g2452",0,0 },
1308 { "msp430g2453",0,0 },
1309 { "msp430g2513",0,0 },
1310 { "msp430g2533",0,0 },
1311 { "msp430g2544",0,0 },
1312 { "msp430g2553",0,0 },
1313 { "msp430g2744",0,0 },
1314 { "msp430g2755",0,0 },
1315 { "msp430g2855",0,0 },
1316 { "msp430g2955",0,0 },
1317 { "msp430i2020",0,2 },
1318 { "msp430i2021",0,2 },
1319 { "msp430i2030",0,2 },
1320 { "msp430i2031",0,2 },
1321 { "msp430i2040",0,2 },
1322 { "msp430i2041",0,2 },
1323 { "msp430i2xxgeneric",0,2 },
1324 { "msp430l092",0,0 },
1325 { "msp430p112",0,0 },
1326 { "msp430p313",0,0 },
1327 { "msp430p315",0,0 },
1328 { "msp430p315s",0,0 },
1329 { "msp430p325",0,0 },
1330 { "msp430p337",0,1 },
1331 { "msp430sl5438a",2,8 },
1332 { "msp430tch5e",0,0 },
1333 { "msp430xgeneric",2,8 },
1334 { "rf430f5144",2,8 },
1335 { "rf430f5155",2,8 },
1336 { "rf430f5175",2,8 },
1337 { "rf430frl152h",0,0 },
1338 { "rf430frl152h_rom",0,0 },
1339 { "rf430frl153h",0,0 },
1340 { "rf430frl153h_rom",0,0 },
1341 { "rf430frl154h",0,0 },
1342 { "rf430frl154h_rom",0,0 }
1346 md_parse_option (int c
, const char * arg
)
1350 case OPTION_SILICON_ERRATA
:
1351 case OPTION_SILICON_ERRATA_WARN
:
1357 unsigned int length
;
1358 unsigned int bitfield
;
1361 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1362 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1363 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1364 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1365 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1366 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1371 for (i
= ARRAY_SIZE (erratas
); i
--;)
1372 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1374 if (c
== OPTION_SILICON_ERRATA
)
1375 silicon_errata_fix
|= erratas
[i
].bitfield
;
1377 silicon_errata_warn
|= erratas
[i
].bitfield
;
1378 arg
+= erratas
[i
].length
;
1383 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1389 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1399 as_fatal (_("MCU option requires a name\n"));
1401 if (strcasecmp ("msp430", arg
) == 0)
1402 selected_isa
= MSP_ISA_430
;
1403 else if (strcasecmp ("msp430xv2", arg
) == 0)
1404 selected_isa
= MSP_ISA_430Xv2
;
1405 else if (strcasecmp ("msp430x", arg
) == 0)
1406 selected_isa
= MSP_ISA_430X
;
1411 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1412 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1414 switch (msp430_mcu_data
[i
].revision
)
1416 case 0: selected_isa
= MSP_ISA_430
; break;
1417 case 1: selected_isa
= MSP_ISA_430X
; break;
1418 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1423 /* It is not an error if we do not match the MCU name. */
1427 if (strcmp (arg
, "430") == 0
1428 || strcasecmp (arg
, "msp430") == 0)
1429 selected_isa
= MSP_ISA_430
;
1430 else if (strcasecmp (arg
, "430x") == 0
1431 || strcasecmp (arg
, "msp430x") == 0)
1432 selected_isa
= MSP_ISA_430X
;
1433 else if (strcasecmp (arg
, "430xv2") == 0
1434 || strcasecmp (arg
, "msp430xv2") == 0)
1435 selected_isa
= MSP_ISA_430Xv2
;
1437 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1441 msp430_enable_relax
= 1;
1444 case OPTION_POLYMORPHS
:
1445 msp430_enable_polys
= 1;
1452 case OPTION_NO_INTR_NOPS
:
1453 gen_interrupt_nops
= false;
1455 case OPTION_INTR_NOPS
:
1456 gen_interrupt_nops
= true;
1459 case OPTION_WARN_INTR_NOPS
:
1460 warn_interrupt_nops
= true;
1462 case OPTION_NO_WARN_INTR_NOPS
:
1463 warn_interrupt_nops
= false;
1466 case OPTION_UNKNOWN_INTR_NOPS
:
1467 do_unknown_interrupt_nops
= true;
1469 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1470 do_unknown_interrupt_nops
= false;
1473 case OPTION_MOVE_DATA
:
1474 /* Silently ignored. */
1477 case OPTION_DATA_REGION
:
1478 if (strcmp (arg
, "upper") == 0
1479 || strcmp (arg
, "either") == 0)
1480 upper_data_region_in_use
= true;
1481 if (strcmp (arg
, "upper") == 0
1482 || strcmp (arg
, "either") == 0
1483 /* With data-region=none, the compiler has generated code assuming
1484 data could be in the upper region, but nothing has been explicitly
1486 || strcmp (arg
, "none") == 0)
1487 lower_data_region_only
= false;
1494 /* The intention here is to have the mere presence of these sections
1495 cause the object to have a reference to a well-known symbol. This
1496 reference pulls in the bits of the runtime (crt0) that initialize
1497 these sections. Thus, for example, the startup code to call
1498 memset() to initialize .bss will only be linked in when there is a
1499 non-empty .bss section. Otherwise, the call would exist but have a
1500 zero length parameter, which is a waste of memory and cycles.
1502 The code which initializes these sections should have a global
1503 label for these symbols, and should be marked with KEEP() in the
1507 msp430_make_init_symbols (const char * name
)
1509 if (startswith (name
, ".bss")
1510 || startswith (name
, ".lower.bss")
1511 || startswith (name
, ".either.bss")
1512 || startswith (name
, ".gnu.linkonce.b."))
1513 (void) symbol_find_or_make ("__crt0_init_bss");
1515 if (startswith (name
, ".data")
1516 || startswith (name
, ".lower.data")
1517 || startswith (name
, ".either.data")
1518 || startswith (name
, ".gnu.linkonce.d."))
1519 (void) symbol_find_or_make ("__crt0_movedata");
1520 /* Note - data assigned to the .either.data section may end up being
1521 placed in the .upper.data section if the .lower.data section is
1522 full. Hence the need to define the crt0 symbol.
1523 The linker may create upper or either data sections, even when none exist
1524 at the moment, so use the value of the data-region flag to determine if
1525 the symbol is needed. */
1526 if (startswith (name
, ".either.data")
1527 || startswith (name
, ".upper.data")
1528 || upper_data_region_in_use
)
1529 (void) symbol_find_or_make ("__crt0_move_highdata");
1531 /* See note about .either.data above. */
1532 if (startswith (name
, ".upper.bss")
1533 || startswith (name
, ".either.bss")
1534 || upper_data_region_in_use
)
1535 (void) symbol_find_or_make ("__crt0_init_highbss");
1537 /* The following symbols are for the crt0 functions that run through
1538 the different .*_array sections and call the functions placed there.
1539 - init_array stores global static C++ constructors to run before main.
1540 - preinit_array is not expected to ever be used for MSP430.
1541 GCC only places initialization functions for runtime "sanitizers"
1542 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1543 - fini_array stores global static C++ destructors to run after calling
1544 exit() or returning from main.
1545 __crt0_run_array is required to actually call the functions in the above
1547 if (startswith (name
, ".init_array"))
1549 (void) symbol_find_or_make ("__crt0_run_init_array");
1550 (void) symbol_find_or_make ("__crt0_run_array");
1552 else if (startswith (name
, ".preinit_array"))
1554 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1555 (void) symbol_find_or_make ("__crt0_run_array");
1557 else if (startswith (name
, ".fini_array"))
1559 (void) symbol_find_or_make ("__crt0_run_fini_array");
1560 (void) symbol_find_or_make ("__crt0_run_array");
1565 msp430_section (int arg
)
1567 char * saved_ilp
= input_line_pointer
;
1568 const char * name
= obj_elf_section_name ();
1570 msp430_make_init_symbols (name
);
1572 input_line_pointer
= saved_ilp
;
1573 obj_elf_section (arg
);
1577 msp430_frob_section (asection
*sec
)
1579 const char *name
= sec
->name
;
1584 msp430_make_init_symbols (name
);
1588 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1590 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1593 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1594 (void) symbol_find_or_make ("__crt0_init_bss");
1598 msp430_comm (int needs_align
)
1600 s_comm_internal (needs_align
, elf_common_parse
);
1601 (void) symbol_find_or_make ("__crt0_init_bss");
1605 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1607 char sym_name
[1024];
1608 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1610 (void) symbol_find_or_make (sym_name
);
1613 /* Handle a .mspabi_attribute or .gnu_attribute directive.
1614 attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute.
1615 This is only used for validating the attributes in the assembly file against
1616 the options gas has been invoked with. If the attributes and options are
1617 compatible then we add the attributes to the assembly file in
1618 msp430_md_finish. */
1620 msp430_object_attribute (int attr_type
)
1622 char tag_name_s
[32];
1623 char tag_value_s
[32];
1624 int tag_name
, tag_value
;
1625 /* First operand is the tag name, second is the tag value e.g.
1626 ".mspabi_attribute 4, 2". */
1627 input_line_pointer
= extract_operand (input_line_pointer
, tag_name_s
, 32);
1628 input_line_pointer
= extract_operand (input_line_pointer
, tag_value_s
, 32);
1629 tag_name
= atoi (tag_name_s
);
1630 tag_value
= atoi (tag_value_s
);
1631 /* If the attribute directive is present, the tag_value should never be set
1633 if (tag_name
== 0 || tag_value
== 0)
1634 as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"),
1635 tag_name_s
, tag_value_s
, (attr_type
? ".gnu_attribute"
1636 : ".mspabi_attribute"));
1637 else if (attr_type
== 0)
1638 /* Handle .mspabi_attribute. */
1641 case OFBA_MSPABI_Tag_ISA
:
1644 case OFBA_MSPABI_Val_ISA_MSP430
:
1645 if (target_is_430x ())
1646 as_bad (_("file was compiled for the 430 ISA but the %s ISA is "
1647 "selected"), (target_is_430xv2 () ? "430X" : "430Xv2"));
1649 case OFBA_MSPABI_Val_ISA_MSP430X
:
1650 if (!target_is_430x ())
1651 as_bad (_("file was compiled for the 430X ISA but the 430 ISA is "
1655 as_bad (_("unknown MSPABI build attribute value '%d' for "
1656 "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"),
1657 tag_value
, OFBA_MSPABI_Tag_ISA
);
1661 case OFBA_MSPABI_Tag_Code_Model
:
1663 case OFBA_MSPABI_Tag_Data_Model
:
1664 /* FIXME: Might we want to set the memory model to large if the assembly
1665 file has the large model attribute, but -ml has not been passed? */
1668 case OFBA_MSPABI_Val_Code_Model_SMALL
:
1670 as_bad (_("file was compiled for the small memory model, but the "
1671 "large memory model is selected"));
1673 case OFBA_MSPABI_Val_Code_Model_LARGE
:
1675 as_bad (_("file was compiled for the large memory model, "
1676 "but the small memory model is selected"));
1679 as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) "
1680 "in .mspabi_attribute directive"), tag_value
,
1681 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1682 ? "OFBA_MSPABI_Tag_Code_Model"
1683 : "OFBA_MSPABI_Tag_Data_Model"),
1684 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1685 ? OFBA_MSPABI_Tag_Code_Model
1686 : OFBA_MSPABI_Tag_Data_Model
));
1691 as_bad (_("unknown MSPABI build attribute tag '%d' in "
1692 ".mspabi_attribute directive"), tag_name
);
1695 else if (attr_type
== 1)
1696 /* Handle .gnu_attribute. */
1699 case Tag_GNU_MSP430_Data_Region
:
1700 /* This attribute is only applicable in the large memory model. */
1705 case Val_GNU_MSP430_Data_Region_Lower
:
1706 if (!lower_data_region_only
)
1707 as_bad (_("file was compiled assuming all data will be in the "
1708 "lower memory region, but the upper region is in use"));
1710 case Val_GNU_MSP430_Data_Region_Any
:
1711 if (lower_data_region_only
)
1712 as_bad (_("file was compiled assuming data could be in the upper "
1713 "memory region, but the lower data region is "
1714 "exclusively in use"));
1717 as_bad (_("unknown GNU build attribute value '%d' for "
1718 "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute "
1719 "directive"), tag_value
, Tag_GNU_MSP430_Data_Region
);
1723 as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"),
1727 const pseudo_typeS md_pseudo_table
[] =
1729 {"arch", msp430_set_arch
, OPTION_MMCU
},
1730 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1731 {"profiler", msp430_profiler
, 0},
1732 {"section", msp430_section
, 0},
1733 {"section.s", msp430_section
, 0},
1734 {"sect", msp430_section
, 0},
1735 {"sect.s", msp430_section
, 0},
1736 {"pushsection", msp430_section
, 1},
1737 {"refsym", msp430_refsym
, 0},
1738 {"comm", msp430_comm
, 0},
1739 {"lcomm", msp430_lcomm
, 0},
1740 {"mspabi_attribute", msp430_object_attribute
, 0},
1741 {"gnu_attribute", msp430_object_attribute
, 1},
1745 const char md_shortopts
[] = "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1747 const struct option md_longopts
[] =
1749 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1750 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1751 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1752 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1753 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1754 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1755 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1756 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1757 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1758 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1759 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1760 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1761 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1762 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1763 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1764 {NULL
, no_argument
, NULL
, 0}
1767 const size_t md_longopts_size
= sizeof (md_longopts
);
1770 md_show_usage (FILE * stream
)
1773 _("MSP430 options:\n"
1774 " -mmcu=<msp430-name> - select microcontroller type\n"
1775 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1777 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1778 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1779 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1781 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1782 " -mP - enable polymorph instructions\n"));
1784 _(" -ml - enable large code model\n"));
1786 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1788 _(" -mn - insert a NOP after changing interrupts\n"));
1790 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1792 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1794 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1795 " known how the state is changed, do not warn/insert NOPs\n"));
1797 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1798 " known how the state is changed, warn/insert NOPs (default)\n"
1799 " -mn and/or -my are required for this to have any effect\n"));
1801 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1806 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1812 extract_cmd (char * from
, char * to
, int limit
)
1816 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1818 *(to
+ size
) = *from
;
1829 md_atof (int type
, char * litP
, int * sizeP
)
1831 return ieee_md_atof (type
, litP
, sizeP
, false);
1837 struct msp430_opcode_s
* opcode
;
1838 msp430_hash
= str_htab_create ();
1840 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1841 str_hash_insert (msp430_hash
, opcode
->name
, opcode
, 0);
1843 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1844 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1846 /* Set linkrelax here to avoid fixups in most sections. */
1851 is_regname_end (char c
)
1853 return (c
== 0 || ! ISALNUM (c
));
1856 /* Returns the register number equivalent to the string T.
1857 Returns -1 if there is no such register.
1858 Skips a leading 'r' or 'R' character if there is one.
1859 Handles the register aliases PC and SP. */
1862 check_reg (char * t
)
1865 signed long int val
;
1867 if (t
== NULL
|| t
[0] == 0)
1870 if (*t
== 'r' || *t
== 'R')
1873 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1876 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1879 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1882 if (*t
== '0' && is_regname_end (t
[1]))
1885 val
= strtol (t
, & endt
, 0);
1887 if (val
< 1 || val
> 15)
1890 if (is_regname_end (*endt
))
1897 msp430_srcoperand (struct msp430_operand_s
* op
,
1901 bool allow_20bit_values
,
1902 bool constants_allowed
)
1907 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1913 /* Use all parts of the constant expression by default. */
1914 enum msp430_expp_e expp
= MSP_EXPP_ALL
;
1916 /* Check if there is:
1917 llo(x) - least significant 16 bits, x &= 0xffff
1918 lhi(x) - x = (x >> 16) & 0xffff,
1919 hlo(x) - x = (x >> 32) & 0xffff,
1920 hhi(x) - x = (x >> 48) & 0xffff
1921 The value _MUST_ be an immediate expression: #hlo(1231231231). */
1925 if (strncasecmp (h
, "#llo(", 5) == 0)
1929 expp
= MSP_EXPP_LLO
;
1931 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1935 expp
= MSP_EXPP_LHI
;
1937 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1941 expp
= MSP_EXPP_HLO
;
1943 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1947 expp
= MSP_EXPP_HHI
;
1949 else if (strncasecmp (h
, "#lo(", 4) == 0)
1955 else if (strncasecmp (h
, "#hi(", 4) == 0)
1962 op
->reg
= 0; /* Reg PC. */
1964 op
->ol
= 1; /* Immediate will follow an instruction. */
1965 __tl
= h
+ 1 + rval
;
1967 op
->vshift
= vshift
;
1970 end
= parse_exp (__tl
, &(op
->exp
));
1971 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1973 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1976 if (op
->exp
.X_op
== O_constant
)
1978 int x
= op
->exp
.X_add_number
;
1983 op
->exp
.X_add_number
= x
;
1985 else if (vshift
== 1)
1987 x
= (x
>> 16) & 0xffff;
1988 op
->exp
.X_add_number
= x
;
1991 else if (vshift
> 1)
1994 op
->exp
.X_add_number
= -1;
1996 op
->exp
.X_add_number
= 0; /* Nothing left. */
1997 x
= op
->exp
.X_add_number
;
2001 if (allow_20bit_values
)
2003 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
2005 as_bad (_("value 0x%x out of extended range."), x
);
2009 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
2011 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
2015 /* Now check constants. */
2016 /* Substitute register mode with a constant generator if applicable. */
2018 if (!allow_20bit_values
)
2019 x
= (short) x
; /* Extend sign. */
2021 if (! constants_allowed
)
2053 if (bin
== 0x1200 && ! target_is_430x ())
2055 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
2056 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2057 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
2058 /* No need to check silicon_errata_fixes - this fix is always implemented. */
2070 if (bin
== 0x1200 && ! target_is_430x ())
2072 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
2073 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2074 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
2085 else if (op
->exp
.X_op
== O_symbol
)
2088 as_bad (_("error: unsupported #foo() directive used on symbol"));
2091 else if (op
->exp
.X_op
== O_big
)
2097 op
->exp
.X_op
= O_constant
;
2098 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
2099 x
= op
->exp
.X_add_number
;
2105 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
2153 /* Redundant (yet) check. */
2154 else if (op
->exp
.X_op
== O_register
)
2156 (_("Registers cannot be used within immediate expression [%s]"), l
);
2158 as_bad (_("unknown operand %s"), l
);
2163 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2168 op
->reg
= 2; /* Reg 2 in absolute addr mode. */
2169 op
->am
= 1; /* Mode As == 01 bin. */
2170 op
->ol
= 1; /* Immediate value followed by instruction. */
2172 end
= parse_exp (__tl
, &(op
->exp
));
2173 if (end
!= NULL
&& *end
!= 0)
2175 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
2180 op
->expp
= MSP_EXPP_ALL
;
2181 if (op
->exp
.X_op
== O_constant
)
2183 int x
= op
->exp
.X_add_number
;
2185 if (allow_20bit_values
)
2187 if (x
> 0xfffff || x
< -(0x7ffff))
2189 as_bad (_("value 0x%x out of extended range."), x
);
2193 else if (x
> 65535 || x
< -32768)
2195 as_bad (_("value out of range: 0x%x"), x
);
2199 else if (op
->exp
.X_op
== O_symbol
)
2203 /* Redundant (yet) check. */
2204 if (op
->exp
.X_op
== O_register
)
2206 (_("Registers cannot be used within absolute expression [%s]"), l
);
2208 as_bad (_("unknown expression in operand %s"), l
);
2214 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2218 char *m
= strchr (l
, '+');
2222 as_bad (_("unknown addressing mode %s"), l
);
2228 if ((op
->reg
= check_reg (t
)) == -1)
2230 as_bad (_("Bad register name %s"), t
);
2238 /* PC cannot be used in indirect addressing. */
2239 if (target_is_430xv2 () && op
->reg
== 0)
2241 as_bad (_("cannot use indirect addressing with the PC"));
2248 /* Check if register indexed X(Rn). */
2251 char *h
= strrchr (l
, '(');
2252 char *m
= strrchr (l
, ')');
2261 as_bad (_("')' required"));
2269 /* Extract a register. */
2270 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2273 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2280 as_bad (_("r2 should not be used in indexed addressing mode"));
2284 /* Extract constant. */
2289 op
->expp
= MSP_EXPP_ALL
;
2290 end
= parse_exp (__tl
, &(op
->exp
));
2291 if (end
!= NULL
&& *end
!= 0)
2293 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2296 if (op
->exp
.X_op
== O_constant
)
2298 int x
= op
->exp
.X_add_number
;
2300 if (allow_20bit_values
)
2302 if (x
> 0xfffff || x
< - (0x7ffff))
2304 as_bad (_("value 0x%x out of extended range."), x
);
2308 else if (x
> 65535 || x
< -32768)
2310 as_bad (_("value out of range: 0x%x"), x
);
2322 if (op
->reg
== 1 && (x
& 1))
2324 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2325 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2326 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2327 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2330 else if (op
->exp
.X_op
== O_symbol
)
2334 /* Redundant (yet) check. */
2335 if (op
->exp
.X_op
== O_register
)
2337 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2339 as_bad (_("unknown expression in operand %s"), l
);
2347 /* Possibly register mode 'mov r1,r2'. */
2348 if ((op
->reg
= check_reg (l
)) != -1)
2356 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2358 op
->reg
= 0; /* PC relative... be careful. */
2359 /* An expression starting with a minus sign is a constant, not an address. */
2360 op
->am
= (*l
== '-' ? 3 : 1);
2363 op
->expp
= MSP_EXPP_ALL
;
2365 end
= parse_exp (__tl
, &(op
->exp
));
2366 if (end
!= NULL
&& * end
!= 0)
2368 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2376 msp430_dstoperand (struct msp430_operand_s
* op
,
2379 bool allow_20bit_values
,
2380 bool constants_allowed
)
2383 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2392 char *__tl
= (char *) "0";
2398 op
->expp
= MSP_EXPP_ALL
;
2399 (void) parse_exp (__tl
, &(op
->exp
));
2401 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2403 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2413 ("this addressing mode is not applicable for destination operand"));
2419 /* Attempt to encode a MOVA instruction with the given operands.
2420 Returns the length of the encoded instruction if successful
2421 or 0 upon failure. If the encoding fails, an error message
2422 will be returned if a pointer is provided. */
2425 try_encode_mova (bool imm_op
,
2427 struct msp430_operand_s
* op1
,
2428 struct msp430_operand_s
* op2
,
2429 const char ** error_message_return
)
2435 /* Only a restricted subset of the normal MSP430 addressing modes
2436 are supported here, so check for the ones that are allowed. */
2439 if (op1
->mode
== OP_EXP
)
2441 if (op2
->mode
!= OP_REG
)
2443 if (error_message_return
!= NULL
)
2444 * error_message_return
= _("expected register as second argument of %s");
2450 /* MOVA #imm20, Rdst. */
2451 bin
|= 0x80 | op2
->reg
;
2452 frag
= frag_more (4);
2453 where
= frag
- frag_now
->fr_literal
;
2454 if (op1
->exp
.X_op
== O_constant
)
2456 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2457 bfd_putl16 ((bfd_vma
) bin
, frag
);
2458 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2462 bfd_putl16 ((bfd_vma
) bin
, frag
);
2463 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), false,
2464 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2465 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2470 else if (op1
->am
== 1)
2472 /* MOVA z16(Rsrc), Rdst. */
2473 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2474 frag
= frag_more (4);
2475 where
= frag
- frag_now
->fr_literal
;
2476 bfd_putl16 ((bfd_vma
) bin
, frag
);
2477 if (op1
->exp
.X_op
== O_constant
)
2479 if (op1
->exp
.X_add_number
> 0xffff
2480 || op1
->exp
.X_add_number
< -(0x7fff))
2482 if (error_message_return
!= NULL
)
2483 * error_message_return
= _("index value too big for %s");
2486 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2490 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2491 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), false,
2493 BFD_RELOC_MSP430X_PCR16
:
2494 BFD_RELOC_MSP430X_ABS16
);
2499 if (error_message_return
!= NULL
)
2500 * error_message_return
= _("unexpected addressing mode for %s");
2503 else if (op1
->am
== 0)
2505 /* MOVA Rsrc, ... */
2506 if (op2
->mode
== OP_REG
)
2508 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2509 frag
= frag_more (2);
2510 where
= frag
- frag_now
->fr_literal
;
2511 bfd_putl16 ((bfd_vma
) bin
, frag
);
2514 else if (op2
->am
== 1)
2518 /* MOVA Rsrc, &abs20. */
2519 bin
|= 0x60 | (op1
->reg
<< 8);
2520 frag
= frag_more (4);
2521 where
= frag
- frag_now
->fr_literal
;
2522 if (op2
->exp
.X_op
== O_constant
)
2524 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2525 bfd_putl16 ((bfd_vma
) bin
, frag
);
2526 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2530 bfd_putl16 ((bfd_vma
) bin
, frag
);
2531 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2532 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), false,
2533 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2538 /* MOVA Rsrc, z16(Rdst). */
2539 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2540 frag
= frag_more (4);
2541 where
= frag
- frag_now
->fr_literal
;
2542 bfd_putl16 ((bfd_vma
) bin
, frag
);
2543 if (op2
->exp
.X_op
== O_constant
)
2545 if (op2
->exp
.X_add_number
> 0xffff
2546 || op2
->exp
.X_add_number
< -(0x7fff))
2548 if (error_message_return
!= NULL
)
2549 * error_message_return
= _("index value too big for %s");
2552 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2556 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2557 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), false,
2559 BFD_RELOC_MSP430X_PCR16
:
2560 BFD_RELOC_MSP430X_ABS16
);
2565 if (error_message_return
!= NULL
)
2566 * error_message_return
= _("unexpected addressing mode for %s");
2571 /* imm_op == false. */
2573 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2575 /* MOVA &abs20, Rdst. */
2576 if (op2
->mode
!= OP_REG
)
2578 if (error_message_return
!= NULL
)
2579 * error_message_return
= _("expected register as second argument of %s");
2583 if (op2
->reg
== 2 || op2
->reg
== 3)
2585 if (error_message_return
!= NULL
)
2586 * error_message_return
= _("constant generator destination register found in %s");
2590 bin
|= 0x20 | op2
->reg
;
2591 frag
= frag_more (4);
2592 where
= frag
- frag_now
->fr_literal
;
2593 if (op1
->exp
.X_op
== O_constant
)
2595 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2596 bfd_putl16 ((bfd_vma
) bin
, frag
);
2597 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2601 bfd_putl16 ((bfd_vma
) bin
, frag
);
2602 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2603 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), false,
2604 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2608 else if (op1
->mode
== OP_REG
)
2612 /* MOVA @Rsrc+, Rdst. */
2613 if (op2
->mode
!= OP_REG
)
2615 if (error_message_return
!= NULL
)
2616 * error_message_return
= _("expected register as second argument of %s");
2620 if (op2
->reg
== 2 || op2
->reg
== 3)
2622 if (error_message_return
!= NULL
)
2623 * error_message_return
= _("constant generator destination register found in %s");
2627 if (op1
->reg
== 2 || op1
->reg
== 3)
2629 if (error_message_return
!= NULL
)
2630 * error_message_return
= _("constant generator source register found in %s");
2634 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2635 frag
= frag_more (2);
2636 where
= frag
- frag_now
->fr_literal
;
2637 bfd_putl16 ((bfd_vma
) bin
, frag
);
2640 else if (op1
->am
== 2)
2642 /* MOVA @Rsrc,Rdst */
2643 if (op2
->mode
!= OP_REG
)
2645 if (error_message_return
!= NULL
)
2646 * error_message_return
= _("expected register as second argument of %s");
2650 if (op2
->reg
== 2 || op2
->reg
== 3)
2652 if (error_message_return
!= NULL
)
2653 * error_message_return
= _("constant generator destination register found in %s");
2657 if (op1
->reg
== 2 || op1
->reg
== 3)
2659 if (error_message_return
!= NULL
)
2660 * error_message_return
= _("constant generator source register found in %s");
2664 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2665 frag
= frag_more (2);
2666 where
= frag
- frag_now
->fr_literal
;
2667 bfd_putl16 ((bfd_vma
) bin
, frag
);
2672 if (error_message_return
!= NULL
)
2673 * error_message_return
= _("unexpected addressing mode for %s");
2678 #define NOP_CHECK_INTERRUPT (1 << 0)
2679 #define NOP_CHECK_CPU12 (1 << 1)
2680 #define NOP_CHECK_CPU19 (1 << 2)
2682 static signed int check_for_nop
= 0;
2684 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2686 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2687 For MOV insns, more sophisticated processing is needed to determine if they
2688 result in enabling/disabling interrupts. */
2689 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2690 || ((strcmp (OPCODE, "bic") == 0) \
2692 || ((strcmp (OPCODE, "clr") == 0) \
2695 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2696 || ((strcmp (OPCODE, "bis") == 0) \
2699 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2700 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2701 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2702 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2703 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2704 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2706 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2707 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2708 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2709 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2710 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2711 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2717 frag
= frag_more (2);
2718 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2719 dwarf2_emit_insn (2);
2722 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2725 warn_eint_nop (bool prev_insn_is_nop
, bool prev_insn_is_dint
)
2727 if (prev_insn_is_nop
2728 /* If the last insn was a DINT, we will have already warned that a NOP is
2729 required after it. */
2730 || prev_insn_is_dint
2731 /* 430 ISA does not require a NOP before EINT. */
2732 || (! target_is_430x ()))
2735 if (gen_interrupt_nops
)
2738 if (warn_interrupt_nops
)
2739 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2741 else if (warn_interrupt_nops
)
2742 as_warn (_(WARN_NOP_BEFORE_EINT
));
2745 /* Use when unsure what effect the insn will have on the interrupt status,
2746 to insert/warn about adding a NOP before the current insn. */
2749 warn_unsure_interrupt (bool prev_insn_is_nop
,
2750 bool prev_insn_is_dint
)
2752 if (prev_insn_is_nop
2753 /* If the last insn was a DINT, we will have already warned that a NOP is
2754 required after it. */
2755 || prev_insn_is_dint
2756 /* 430 ISA does not require a NOP before EINT or DINT. */
2757 || (! target_is_430x ()))
2760 if (gen_interrupt_nops
)
2763 if (warn_interrupt_nops
)
2764 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2766 else if (warn_interrupt_nops
)
2767 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2770 /* Parse instruction operands.
2771 Return binary opcode. */
2774 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2776 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2777 int insn_length
= 0;
2778 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2782 struct msp430_operand_s op1
, op2
;
2784 static short ZEROS
= 0;
2785 bool byte_op
, imm_op
;
2788 int extended
= 0x1800;
2789 bool extended_op
= false;
2791 const char * error_message
;
2792 static signed int repeat_count
= 0;
2793 static bool prev_insn_is_nop
= false;
2794 static bool prev_insn_is_dint
= false;
2795 static bool prev_insn_is_eint
= false;
2796 /* We might decide before the end of the function that the current insn is
2797 equivalent to DINT/EINT. */
2798 bool this_insn_is_dint
= false;
2799 bool this_insn_is_eint
= false;
2802 /* Opcode is the one from opcodes table
2803 line contains something like
2815 switch (TOLOWER (* line
))
2818 /* Byte operation. */
2819 bin
|= BYTE_OPERATION
;
2825 /* "Address" ops work on 20-bit values. */
2827 bin
|= BYTE_OPERATION
;
2832 /* Word operation - this is the default. */
2840 as_warn (_("no size modifier after period, .w assumed"));
2844 as_bad (_("unrecognised instruction size modifier .%c"),
2856 if (*line
&& ! ISSPACE (*line
))
2858 as_bad (_("junk found after instruction: %s.%s"),
2859 opcode
->name
, line
);
2863 /* Catch the case where the programmer has used a ".a" size modifier on an
2864 instruction that does not support it. Look for an alternative extended
2865 instruction that has the same name without the period. Eg: "add.a"
2866 becomes "adda". Although this not an officially supported way of
2867 specifying instruction aliases other MSP430 assemblers allow it. So we
2868 support it for compatibility purposes. */
2869 if (addr_op
&& opcode
->fmt
>= 0)
2871 const char * old_name
= opcode
->name
;
2874 sprintf (real_name
, "%sa", old_name
);
2875 opcode
= str_hash_find (msp430_hash
, real_name
);
2878 as_bad (_("instruction %s.a does not exist"), old_name
);
2881 #if 0 /* Enable for debugging. */
2882 as_warn ("treating %s.a as %s", old_name
, real_name
);
2885 bin
= opcode
->bin_opcode
;
2888 if (opcode
->fmt
!= -1
2889 && opcode
->insn_opnumb
2890 && (!*line
|| *line
== '\n'))
2892 as_bad (ngettext ("instruction %s requires %d operand",
2893 "instruction %s requires %d operands",
2894 opcode
->insn_opnumb
),
2895 opcode
->name
, opcode
->insn_opnumb
);
2899 memset (l1
, 0, sizeof (l1
));
2900 memset (l2
, 0, sizeof (l2
));
2901 memset (&op1
, 0, sizeof (op1
));
2902 memset (&op2
, 0, sizeof (op2
));
2906 if ((fmt
= opcode
->fmt
) < 0)
2908 if (! target_is_430x ())
2910 as_bad (_("instruction %s requires MSP430X mcu"),
2921 /* If requested set the extended instruction repeat count. */
2924 if (repeat_count
> 0)
2925 extended
|= (repeat_count
- 1);
2927 extended
|= (1 << 7) | (- repeat_count
);
2930 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2935 /* The previous instruction set this flag if it wants to check if this insn
2939 if (! is_opcode ("nop"))
2943 switch (check_for_nop
& - check_for_nop
)
2945 case NOP_CHECK_INTERRUPT
:
2946 /* NOP_CHECK_INTERRUPT rules:
2947 1. 430 and 430x ISA require a NOP after DINT.
2948 2. Only the 430x ISA requires NOP before EINT (this has
2949 been dealt with in the previous call to this function).
2950 3. Only the 430x ISA requires NOP after every EINT.
2952 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2954 if (prev_insn_is_dint
)
2956 if (gen_interrupt_nops
)
2959 if (warn_interrupt_nops
)
2960 as_warn (_(INSERT_NOP_AFTER_DINT
));
2963 as_warn (_(WARN_NOP_AFTER_DINT
));
2965 else if (prev_insn_is_eint
)
2967 if (gen_interrupt_nops
)
2970 if (warn_interrupt_nops
)
2971 as_warn (_(INSERT_NOP_AFTER_EINT
));
2974 as_warn (_(WARN_NOP_AFTER_EINT
));
2976 /* If we get here it's because the last instruction was
2977 determined to either disable or enable interrupts, but
2978 we're not sure which.
2979 We have no information yet about what effect the
2980 current instruction has on interrupts, that has to be
2982 The last insn may have required a NOP after it, so we
2983 deal with that now. */
2986 if (gen_interrupt_nops
)
2989 if (warn_interrupt_nops
)
2990 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2993 /* warn_unsure_interrupt was called on the previous
2995 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
3000 case NOP_CHECK_CPU12
:
3001 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
3002 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
3004 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
3008 case NOP_CHECK_CPU19
:
3009 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
3010 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
3012 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
3017 as_bad (_("internal error: unknown nop check state"));
3020 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
3022 while (check_for_nop
);
3031 switch (opcode
->insn_opnumb
)
3034 if (is_opcode ("eint"))
3035 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3037 /* Set/clear bits instructions. */
3041 extended
|= BYTE_OPERATION
;
3043 /* Emit the extension word. */
3045 frag
= frag_more (2);
3046 bfd_putl16 (extended
, frag
);
3050 frag
= frag_more (2);
3051 bfd_putl16 ((bfd_vma
) bin
, frag
);
3052 dwarf2_emit_insn (insn_length
);
3056 /* Something which works with destination operand. */
3057 line
= extract_operand (line
, l1
, sizeof (l1
));
3058 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, true);
3062 bin
|= (op1
.reg
| (op1
.am
<< 7));
3064 /* If the PC is the destination... */
3065 if (op1
.am
== 0 && op1
.reg
== 0
3066 /* ... and the opcode alters the SR. */
3067 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3068 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3070 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3071 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3072 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3073 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3076 /* If the status register is the destination... */
3077 if (op1
.am
== 0 && op1
.reg
== 2
3078 /* ... and the opcode alters the SR. */
3079 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
3080 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
3081 || is_opcode ("sbc") || is_opcode ("sxt")
3082 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
3083 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
3084 || is_opcode ("sbcx")
3087 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3088 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3089 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3090 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3093 /* Compute the entire instruction length, in bytes. */
3094 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3095 insn_length
+= op_length
;
3096 frag
= frag_more (op_length
);
3097 where
= frag
- frag_now
->fr_literal
;
3102 extended
|= BYTE_OPERATION
;
3104 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3106 as_bad (_("repeat instruction used with non-register mode instruction"));
3110 if (op1
.mode
== OP_EXP
)
3112 if (op1
.exp
.X_op
== O_constant
)
3113 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3115 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3116 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3117 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3119 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3120 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3123 /* Emit the extension word. */
3124 bfd_putl16 (extended
, frag
);
3129 bfd_putl16 ((bfd_vma
) bin
, frag
);
3133 if (op1
.mode
== OP_EXP
)
3135 if (op1
.exp
.X_op
== O_constant
)
3137 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3141 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3146 fix_new_exp (frag_now
, where
, 2,
3147 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3149 fix_new_exp (frag_now
, where
, 2,
3150 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3155 dwarf2_emit_insn (insn_length
);
3159 /* Shift instruction. */
3160 line
= extract_operand (line
, l1
, sizeof (l1
));
3161 strncpy (l2
, l1
, sizeof (l2
));
3162 l2
[sizeof (l2
) - 1] = '\0';
3163 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, true);
3164 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, true);
3167 break; /* An error occurred. All warnings were done before. */
3169 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
3170 frag
= frag_more (insn_length
);
3171 where
= frag
- frag_now
->fr_literal
;
3173 if (target_is_430xv2 ()
3174 && op1
.mode
== OP_REG
3176 && (is_opcode ("rlax")
3177 || is_opcode ("rlcx")
3178 || is_opcode ("rla")
3179 || is_opcode ("rlc")))
3181 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3185 /* If the status register is the destination... */
3186 if (op1
.am
== 0 && op1
.reg
== 2
3187 /* ... and the opcode alters the SR. */
3188 && (is_opcode ("rla") || is_opcode ("rlc")
3189 || is_opcode ("rlax") || is_opcode ("rlcx")
3190 || is_opcode ("sxt") || is_opcode ("sxtx")
3191 || is_opcode ("swpb")
3194 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3195 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3196 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3197 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3203 extended
|= BYTE_OPERATION
;
3205 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3207 as_bad (_("repeat instruction used with non-register mode instruction"));
3211 if (op1
.mode
== OP_EXP
)
3213 if (op1
.exp
.X_op
== O_constant
)
3214 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3216 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3217 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3218 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3220 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3221 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3224 if (op2
.mode
== OP_EXP
)
3226 if (op2
.exp
.X_op
== O_constant
)
3227 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3229 else if (op1
.mode
== OP_EXP
)
3230 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), false,
3231 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3232 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3234 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), false,
3235 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3236 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3239 /* Emit the extension word. */
3240 bfd_putl16 (extended
, frag
);
3245 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3246 bfd_putl16 ((bfd_vma
) bin
, frag
);
3250 if (op1
.mode
== OP_EXP
)
3252 if (op1
.exp
.X_op
== O_constant
)
3254 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3258 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3262 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3263 fix_new_exp (frag_now
, where
, 2,
3264 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3266 fix_new_exp (frag_now
, where
, 2,
3267 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3274 if (op2
.mode
== OP_EXP
)
3276 if (op2
.exp
.X_op
== O_constant
)
3278 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3282 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3286 if (op2
.reg
) /* Not PC relative. */
3287 fix_new_exp (frag_now
, where
, 2,
3288 &(op2
.exp
), false, CHECK_RELOC_MSP430 (op2
));
3290 fix_new_exp (frag_now
, where
, 2,
3291 &(op2
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3296 dwarf2_emit_insn (insn_length
);
3300 /* Branch instruction => mov dst, r0. */
3303 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3307 line
= extract_operand (line
, l1
, sizeof (l1
));
3308 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, false);
3314 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3315 op_length
= 2 + 2 * op1
.ol
;
3316 frag
= frag_more (op_length
);
3317 where
= frag
- frag_now
->fr_literal
;
3318 bfd_putl16 ((bfd_vma
) bin
, frag
);
3320 if (op1
.mode
== OP_EXP
)
3322 if (op1
.exp
.X_op
== O_constant
)
3324 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3330 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3332 if (op1
.reg
|| op1
.am
== 3)
3333 fix_new_exp (frag_now
, where
, 2,
3334 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3336 fix_new_exp (frag_now
, where
, 2,
3337 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3341 dwarf2_emit_insn (insn_length
+ op_length
);
3345 /* CALLA instructions. */
3346 fix_emitted
= false;
3348 line
= extract_operand (line
, l1
, sizeof (l1
));
3351 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3352 extended_op
, false);
3358 op_length
= 2 + 2 * op1
.ol
;
3359 frag
= frag_more (op_length
);
3360 where
= frag
- frag_now
->fr_literal
;
3368 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3369 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3372 else if (op1
.am
== 1)
3378 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3379 BFD_RELOC_MSP430X_PCR20_CALL
);
3383 bin
|= 0x50 | op1
.reg
;
3385 else if (op1
.am
== 0)
3386 bin
|= 0x40 | op1
.reg
;
3388 else if (op1
.am
== 1)
3392 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3393 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3396 else if (op1
.am
== 2)
3397 bin
|= 0x60 | op1
.reg
;
3398 else if (op1
.am
== 3)
3399 bin
|= 0x70 | op1
.reg
;
3401 bfd_putl16 ((bfd_vma
) bin
, frag
);
3403 if (op1
.mode
== OP_EXP
)
3407 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3411 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3414 fix_new_exp (frag_now
, where
+ 2, 2,
3415 &(op1
.exp
), false, BFD_RELOC_16
);
3418 dwarf2_emit_insn (insn_length
+ op_length
);
3426 /* [POP|PUSH]M[.A] #N, Rd */
3427 line
= extract_operand (line
, l1
, sizeof (l1
));
3428 line
= extract_operand (line
, l2
, sizeof (l2
));
3432 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3435 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3436 if (end
!= NULL
&& *end
!= 0)
3438 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3441 if (op1
.exp
.X_op
!= O_constant
)
3443 as_bad (_("expected constant expression as first argument of %s"),
3448 if ((reg
= check_reg (l2
)) == -1)
3450 as_bad (_("expected register as second argument of %s"),
3456 frag
= frag_more (op_length
);
3457 where
= frag
- frag_now
->fr_literal
;
3458 bin
= opcode
->bin_opcode
;
3461 n
= op1
.exp
.X_add_number
;
3462 bin
|= (n
- 1) << 4;
3463 if (is_opcode ("pushm"))
3467 if (reg
- n
+ 1 < 0)
3469 as_bad (_("Too many registers popped"));
3473 /* CPU21 errata: cannot use POPM to restore the SR register. */
3474 if (target_is_430xv2 ()
3475 && (reg
- n
+ 1 < 3)
3477 && is_opcode ("popm"))
3479 as_bad (_("Cannot use POPM to restore the SR register"));
3483 bin
|= (reg
- n
+ 1);
3486 bfd_putl16 ((bfd_vma
) bin
, frag
);
3487 dwarf2_emit_insn (op_length
);
3496 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3497 if (extended
& 0xff)
3499 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3503 line
= extract_operand (line
, l1
, sizeof (l1
));
3504 line
= extract_operand (line
, l2
, sizeof (l2
));
3508 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3511 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3512 if (end
!= NULL
&& *end
!= 0)
3514 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3517 if (op1
.exp
.X_op
!= O_constant
)
3519 as_bad (_("expected constant expression as first argument of %s"),
3523 n
= op1
.exp
.X_add_number
;
3526 as_bad (_("expected first argument of %s to be in the range 1-4"),
3531 if ((reg
= check_reg (l2
)) == -1)
3533 as_bad (_("expected register as second argument of %s"),
3538 if (target_is_430xv2 () && reg
== 0)
3540 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3545 frag
= frag_more (op_length
);
3546 where
= frag
- frag_now
->fr_literal
;
3548 bin
= opcode
->bin_opcode
;
3551 bin
|= (n
- 1) << 10;
3554 bfd_putl16 ((bfd_vma
) bin
, frag
);
3555 dwarf2_emit_insn (op_length
);
3561 bool need_reloc
= false;
3565 /* ADDA, CMPA and SUBA address instructions. */
3566 if (extended
& 0xff)
3568 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3572 line
= extract_operand (line
, l1
, sizeof (l1
));
3573 line
= extract_operand (line
, l2
, sizeof (l2
));
3575 bin
= opcode
->bin_opcode
;
3579 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3580 if (end
!= NULL
&& *end
!= 0)
3582 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3586 if (op1
.exp
.X_op
== O_constant
)
3588 n
= op1
.exp
.X_add_number
;
3589 if (n
> 0xfffff || n
< - (0x7ffff))
3591 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3596 bin
|= ((n
>> 16) & 0xf) << 8;
3608 if ((n
= check_reg (l1
)) == -1)
3610 as_bad (_("expected register name or constant as first argument of %s"),
3615 bin
|= (n
<< 8) | (1 << 6);
3619 if ((reg
= check_reg (l2
)) == -1)
3621 as_bad (_("expected register as second argument of %s"),
3626 frag
= frag_more (op_length
);
3627 where
= frag
- frag_now
->fr_literal
;
3630 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), false,
3631 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3633 bfd_putl16 ((bfd_vma
) bin
, frag
);
3635 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3636 dwarf2_emit_insn (op_length
);
3640 case 9: /* MOVA, BRA, RETA. */
3642 bin
= opcode
->bin_opcode
;
3644 if (is_opcode ("reta"))
3646 /* The RETA instruction does not take any arguments.
3647 The implicit first argument is @SP+.
3648 The implicit second argument is PC. */
3658 line
= extract_operand (line
, l1
, sizeof (l1
));
3659 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3660 &imm_op
, extended_op
, false);
3662 if (is_opcode ("bra"))
3664 /* This is the BRA synthetic instruction.
3665 The second argument is always PC. */
3671 line
= extract_operand (line
, l2
, sizeof (l2
));
3672 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3677 break; /* Error occurred. All warnings were done before. */
3680 /* Only a restricted subset of the normal MSP430 addressing modes
3681 are supported here, so check for the ones that are allowed. */
3682 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3683 & error_message
)) == 0)
3685 as_bad (error_message
, opcode
->name
);
3688 dwarf2_emit_insn (op_length
);
3692 line
= extract_operand (line
, l1
, sizeof l1
);
3693 /* The RPT instruction only accepted immediates and registers. */
3696 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3697 if (end
!= NULL
&& *end
!= 0)
3699 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3702 if (op1
.exp
.X_op
!= O_constant
)
3704 as_bad (_("expected constant value as argument to RPT"));
3707 if (op1
.exp
.X_add_number
< 1
3708 || op1
.exp
.X_add_number
> (1 << 4))
3710 as_bad (_("expected constant in the range 2..16"));
3714 /* We silently accept and ignore a repeat count of 1. */
3715 if (op1
.exp
.X_add_number
> 1)
3716 repeat_count
= op1
.exp
.X_add_number
;
3722 if ((reg
= check_reg (l1
)) != -1)
3725 as_warn (_("PC used as an argument to RPT"));
3727 repeat_count
= - reg
;
3731 as_bad (_("expected constant or register name as argument to RPT insn"));
3738 as_bad (_("Illegal emulated instruction"));
3743 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3744 From f5 ref man 6.3.3:
3745 The 16-bit Status Register (SR, also called R2), used as a source or
3746 destination register, can only be used in register mode addressed
3747 with word instructions. */
3749 case 1: /* Format 1, double operand. */
3750 line
= extract_operand (line
, l1
, sizeof (l1
));
3751 line
= extract_operand (line
, l2
, sizeof (l2
));
3752 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, true);
3753 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, true);
3756 break; /* Error occurred. All warnings were done before. */
3759 && is_opcode ("movx")
3761 && msp430_enable_relax
)
3763 /* This is the MOVX.A instruction. See if we can convert
3764 it into the MOVA instruction instead. This saves 2 bytes. */
3765 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3768 dwarf2_emit_insn (op_length
);
3773 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3775 /* If the PC is the destination... */
3776 if (op2
.am
== 0 && op2
.reg
== 0
3777 /* ... and the opcode alters the SR. */
3778 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3779 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3781 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3782 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3783 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3784 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3787 /* If the status register is the destination... */
3788 if (op2
.am
== 0 && op2
.reg
== 2
3789 /* ... and the opcode alters the SR. */
3790 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3791 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3792 || is_opcode ("xor")
3793 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3794 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3795 || is_opcode ("xorx")
3798 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3799 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3800 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3801 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3804 /* Chain these checks for SR manipulations so we can warn if they are not
3806 if (((is_opcode ("bis") && bin
== 0xd032)
3807 || (is_opcode ("mov") && bin
== 0x4032)
3808 || (is_opcode ("xor") && bin
== 0xe032))
3809 && op1
.mode
== OP_EXP
3810 && op1
.exp
.X_op
== O_constant
3811 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3812 check_for_nop
|= NOP_CHECK_CPU19
;
3813 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3815 /* Any MOV with the SR as the destination either enables or disables
3817 if (op1
.mode
== OP_EXP
3818 && op1
.exp
.X_op
== O_constant
)
3820 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3822 /* The GIE bit is being set. */
3823 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3824 this_insn_is_eint
= true;
3827 /* The GIE bit is being cleared. */
3828 this_insn_is_dint
= true;
3830 /* If an immediate value which is covered by the constant generator
3831 is the src, then op1 will have been changed to either R2 or R3 by
3833 The only constants covered by CG1 and CG2, which have bit 3 set
3834 and therefore would enable interrupts when writing to the SR, are
3835 R2 with addresing mode 0b11 and R3 with 0b11.
3836 The addressing mode is in bits 5:4 of the binary opcode. */
3837 else if (op1
.mode
== OP_REG
3838 && (op1
.reg
== 2 || op1
.reg
== 3)
3839 && (bin
& 0x30) == 0x30)
3841 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3842 this_insn_is_eint
= true;
3844 /* Any other use of the constant generator with destination R2, will
3845 disable interrupts. */
3846 else if (op1
.mode
== OP_REG
3847 && (op1
.reg
== 2 || op1
.reg
== 3))
3848 this_insn_is_dint
= true;
3849 else if (do_unknown_interrupt_nops
)
3851 /* FIXME: Couldn't work out whether the insn is enabling or
3852 disabling interrupts, so for safety need to treat it as both
3854 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3855 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3858 else if (is_eint (opcode
->name
, bin
))
3859 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3860 else if ((bin
& 0x32) == 0x32)
3862 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3863 * an interrupt state change if a write happens. */
3864 /* FIXME: How strict to be here? */
3868 /* Compute the entire length of the instruction in bytes. */
3869 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3870 + 2 /* The opcode */
3871 + (2 * op1
.ol
) /* The first operand. */
3872 + (2 * op2
.ol
); /* The second operand. */
3874 insn_length
+= op_length
;
3875 frag
= frag_more (op_length
);
3876 where
= frag
- frag_now
->fr_literal
;
3881 extended
|= BYTE_OPERATION
;
3883 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3885 as_bad (_("repeat instruction used with non-register mode instruction"));
3889 /* If necessary, emit a reloc to update the extension word. */
3890 if (op1
.mode
== OP_EXP
)
3892 if (op1
.exp
.X_op
== O_constant
)
3893 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3895 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3896 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3897 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3899 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
3900 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3903 if (op2
.mode
== OP_EXP
)
3905 if (op2
.exp
.X_op
== O_constant
)
3906 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3908 else if (op1
.mode
== OP_EXP
)
3909 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), false,
3910 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3911 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3914 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), false,
3915 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3916 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3919 /* Emit the extension word. */
3920 bfd_putl16 (extended
, frag
);
3925 bfd_putl16 ((bfd_vma
) bin
, frag
);
3929 if (op1
.mode
== OP_EXP
)
3931 if (op1
.exp
.X_op
== O_constant
)
3933 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3937 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3941 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3942 fix_new_exp (frag_now
, where
, 2,
3943 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
3945 fix_new_exp (frag_now
, where
, 2,
3946 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3954 if (op2
.mode
== OP_EXP
)
3956 if (op2
.exp
.X_op
== O_constant
)
3958 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3962 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3966 if (op2
.reg
) /* Not PC relative. */
3967 fix_new_exp (frag_now
, where
, 2,
3968 &(op2
.exp
), false, CHECK_RELOC_MSP430 (op2
));
3970 fix_new_exp (frag_now
, where
, 2,
3971 &(op2
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
3976 dwarf2_emit_insn (insn_length
);
3978 /* If the PC is the destination... */
3979 if (op2
.am
== 0 && op2
.reg
== 0
3980 /* ... but the opcode does not alter the destination. */
3981 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3982 check_for_nop
|= NOP_CHECK_CPU12
;
3985 case 2: /* Single-operand mostly instr. */
3986 if (opcode
->insn_opnumb
== 0)
3988 /* reti instruction. */
3990 frag
= frag_more (2);
3991 bfd_putl16 ((bfd_vma
) bin
, frag
);
3992 dwarf2_emit_insn (insn_length
);
3996 line
= extract_operand (line
, l1
, sizeof (l1
));
3997 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3998 &imm_op
, extended_op
, true);
4000 break; /* Error in operand. */
4002 if (target_is_430xv2 ()
4003 && op1
.mode
== OP_REG
4005 && (is_opcode ("rrax")
4006 || is_opcode ("rrcx")
4007 || is_opcode ("rra")
4008 || is_opcode ("rrc")))
4010 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
4014 /* If the status register is the destination... */
4015 if (op1
.am
== 0 && op1
.reg
== 2
4016 /* ... and the opcode alters the SR. */
4017 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
4019 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
4020 as_bad (_("CPU13: SR is destination of SR altering instruction"));
4021 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
4022 as_warn (_("CPU13: SR is destination of SR altering instruction"));
4025 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
4026 frag
= frag_more (insn_length
);
4027 where
= frag
- frag_now
->fr_literal
;
4031 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
4033 /* These two instructions use a special
4034 encoding of the A/L and B/W bits. */
4035 bin
&= ~ BYTE_OPERATION
;
4039 as_bad (_("%s instruction does not accept a .b suffix"),
4044 extended
|= BYTE_OPERATION
;
4047 extended
|= BYTE_OPERATION
;
4049 if (is_opcode ("rrux"))
4050 extended
|= IGNORE_CARRY_BIT
;
4052 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
4054 as_bad (_("repeat instruction used with non-register mode instruction"));
4058 if (op1
.mode
== OP_EXP
)
4060 if (op1
.exp
.X_op
== O_constant
)
4061 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
4063 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4064 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
4065 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
4067 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), false,
4068 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
4071 /* Emit the extension word. */
4072 bfd_putl16 (extended
, frag
);
4077 bin
|= op1
.reg
| (op1
.am
<< 4);
4078 bfd_putl16 ((bfd_vma
) bin
, frag
);
4082 if (op1
.mode
== OP_EXP
)
4084 if (op1
.exp
.X_op
== O_constant
)
4086 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
4090 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
4094 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4095 fix_new_exp (frag_now
, where
, 2,
4096 &(op1
.exp
), false, CHECK_RELOC_MSP430 (op1
));
4098 fix_new_exp (frag_now
, where
, 2,
4099 &(op1
.exp
), true, CHECK_RELOC_MSP430_PCREL
);
4104 dwarf2_emit_insn (insn_length
);
4107 case 3: /* Conditional jumps instructions. */
4108 line
= extract_operand (line
, l1
, sizeof (l1
));
4109 /* l1 is a label. */
4118 end
= parse_exp (m
, &exp
);
4119 if (end
!= NULL
&& *end
!= 0)
4121 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4125 /* In order to handle something like:
4129 jz 4 ; skip next 4 bytes
4132 nop ; will jump here if r5 positive or zero
4134 jCOND -n ;assumes jump n bytes backward:
4144 jCOND $n ; jump from PC in either direction. */
4146 if (exp
.X_op
== O_constant
)
4148 int x
= exp
.X_add_number
;
4152 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
4156 if ((*l1
== '$' && x
> 0) || x
< 0)
4161 if (x
> 512 || x
< -511)
4163 as_bad (_("Wrong displacement %d"), x
<< 1);
4168 frag
= frag_more (2); /* Instr size is 1 word. */
4171 bfd_putl16 ((bfd_vma
) bin
, frag
);
4173 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4176 frag
= frag_more (2); /* Instr size is 1 word. */
4177 where
= frag
- frag_now
->fr_literal
;
4178 fix_new_exp (frag_now
, where
, 2,
4179 &exp
, true, BFD_RELOC_MSP430_10_PCREL
);
4181 bfd_putl16 ((bfd_vma
) bin
, frag
);
4183 else if (*l1
== '$')
4185 as_bad (_("instruction requires label sans '$'"));
4189 ("instruction requires label or value in range -511:512"));
4190 dwarf2_emit_insn (insn_length
);
4195 as_bad (_("instruction requires label"));
4200 case 4: /* Extended jumps. */
4201 if (!msp430_enable_polys
)
4203 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4207 line
= extract_operand (line
, l1
, sizeof (l1
));
4213 /* Ignore absolute addressing. make it PC relative anyway. */
4214 if (*m
== '#' || *m
== '$')
4217 end
= parse_exp (m
, & exp
);
4218 if (end
!= NULL
&& *end
!= 0)
4220 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4223 if (exp
.X_op
== O_symbol
)
4225 /* Relaxation required. */
4226 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4228 if (target_is_430x ())
4229 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4231 /* The parameter to dwarf2_emit_insn is actually the offset to
4232 the start of the insn from the fix piece of instruction that
4233 was emitted. Since next fragments may have variable size we
4234 tie debug info to the beginning of the instruction. */
4236 frag
= frag_more (8);
4237 dwarf2_emit_insn (0);
4238 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4239 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4241 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4243 0, /* Offset is zero if jump dist less than 1K. */
4249 as_bad (_("instruction requires label"));
4252 case 5: /* Emulated extended branches. */
4253 if (!msp430_enable_polys
)
4255 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4258 line
= extract_operand (line
, l1
, sizeof (l1
));
4264 /* Ignore absolute addressing. make it PC relative anyway. */
4265 if (*m
== '#' || *m
== '$')
4268 end
= parse_exp (m
, & exp
);
4269 if (end
!= NULL
&& *end
!= 0)
4271 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4274 if (exp
.X_op
== O_symbol
)
4276 /* Relaxation required. */
4277 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4279 if (target_is_430x ())
4280 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4283 frag
= frag_more (8);
4284 dwarf2_emit_insn (0);
4285 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4286 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4288 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4289 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4291 0, /* Offset is zero if jump dist less than 1K. */
4297 as_bad (_("instruction requires label"));
4301 as_bad (_("Illegal instruction or not implemented opcode."));
4304 if (is_opcode ("nop"))
4306 prev_insn_is_nop
= true;
4307 prev_insn_is_dint
= false;
4308 prev_insn_is_eint
= false;
4310 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4312 prev_insn_is_dint
= true;
4313 prev_insn_is_eint
= false;
4314 prev_insn_is_nop
= false;
4315 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4317 /* NOP is not needed after EINT for 430 ISA. */
4318 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4320 prev_insn_is_eint
= true;
4321 prev_insn_is_nop
= false;
4322 prev_insn_is_dint
= false;
4323 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4327 prev_insn_is_nop
= false;
4328 prev_insn_is_dint
= false;
4329 prev_insn_is_eint
= false;
4332 input_line_pointer
= line
;
4337 md_assemble (char * str
)
4339 struct msp430_opcode_s
* opcode
;
4343 str
= skip_space (str
); /* Skip leading spaces. */
4344 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4348 char a
= TOLOWER (cmd
[i
]);
4355 as_bad (_("can't find opcode"));
4359 opcode
= (struct msp430_opcode_s
*) str_hash_find (msp430_hash
, cmd
);
4363 as_bad (_("unknown opcode `%s'"), cmd
);
4368 char *__t
= input_line_pointer
;
4370 msp430_operands (opcode
, str
);
4371 input_line_pointer
= __t
;
4375 /* GAS will call this function for each section at the end of the assembly,
4376 to permit the CPU backend to adjust the alignment of a section. */
4379 md_section_align (asection
* seg
, valueT addr
)
4381 int align
= bfd_section_alignment (seg
);
4383 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4386 /* If you define this macro, it should return the offset between the
4387 address of a PC relative fixup and the position from which the PC
4388 relative adjustment should be made. On many processors, the base
4389 of a PC relative instruction is the next instruction, so this
4390 macro would return the length of an instruction. */
4393 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4395 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4396 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4397 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4400 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4403 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4404 Now it handles the situation when relocations
4405 have to be passed to linker. */
4407 msp430_force_relocation_local (fixS
*fixp
)
4409 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4413 if (msp430_enable_polys
4414 && !msp430_enable_relax
)
4421 /* GAS will call this for each fixup. It should store the correct
4422 value in the object file. */
4424 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4426 unsigned char * where
;
4430 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4435 else if (fixp
->fx_pcrel
)
4437 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4439 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4441 /* FIXME: We can appear here only in case if we perform a pc
4442 relative jump to the label which is i) global, ii) locally
4443 defined or this is a jump to an absolute symbol.
4444 If this is an absolute symbol -- everything is OK.
4445 If this is a global label, we've got a symbol value defined
4447 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4448 from this section start
4449 2. *valuep will contain the real offset from jump insn to the
4451 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4452 will be incorrect. Therefore remove s_get_value. */
4453 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4461 value
= fixp
->fx_offset
;
4463 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4465 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4467 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4473 fixp
->fx_no_overflow
= 1;
4475 /* If polymorphs are enabled and relax disabled.
4476 do not kill any relocs and pass them to linker. */
4477 if (msp430_enable_polys
4478 && !msp430_enable_relax
)
4481 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4482 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4489 /* Fetch the instruction, insert the fully resolved operand
4490 value, and stuff the instruction back again. */
4491 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4493 insn
= bfd_getl16 (where
);
4495 switch (fixp
->fx_r_type
)
4497 case BFD_RELOC_MSP430_10_PCREL
:
4499 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4500 _("odd address operand: %ld"), value
);
4502 /* Jumps are in words. */
4504 --value
; /* Correct PC. */
4506 if (value
< -512 || value
> 511)
4507 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4508 _("operand out of range: %ld"), value
);
4510 value
&= 0x3ff; /* get rid of extended sign */
4511 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4514 case BFD_RELOC_MSP430X_PCR16
:
4515 case BFD_RELOC_MSP430_RL_PCREL
:
4516 case BFD_RELOC_MSP430_16_PCREL
:
4518 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4519 _("odd address operand: %ld"), value
);
4522 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4523 /* Nothing to be corrected here. */
4524 if (value
< -32768 || value
> 65536)
4525 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4526 _("operand out of range: %ld"), value
);
4529 case BFD_RELOC_MSP430X_ABS16
:
4530 case BFD_RELOC_MSP430_16
:
4532 case BFD_RELOC_MSP430_16_BYTE
:
4533 value
&= 0xffff; /* Get rid of extended sign. */
4534 bfd_putl16 ((bfd_vma
) value
, where
);
4537 case BFD_RELOC_MSP430_ABS_HI16
:
4539 value
&= 0xffff; /* Get rid of extended sign. */
4540 bfd_putl16 ((bfd_vma
) value
, where
);
4544 bfd_putl32 ((bfd_vma
) value
, where
);
4547 case BFD_RELOC_MSP430_ABS8
:
4549 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4552 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4553 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4554 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4556 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4559 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4560 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4562 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4565 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4566 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4568 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4571 case BFD_RELOC_MSP430X_PCR20_CALL
:
4572 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4574 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4577 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4578 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4579 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4581 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4584 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4585 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4587 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4590 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4591 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4593 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4597 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4598 fixp
->fx_line
, fixp
->fx_r_type
);
4604 fixp
->fx_addnumber
= value
;
4609 S_IS_GAS_LOCAL (symbolS
* s
)
4616 name
= S_GET_NAME (s
);
4617 len
= strlen (name
) - 1;
4619 return name
[len
] == 1 || name
[len
] == 2;
4622 /* GAS will call this to generate a reloc, passing the resulting reloc
4623 to `bfd_install_relocation'. This currently works poorly, as
4624 `bfd_install_relocation' often does the wrong thing, and instances of
4625 `tc_gen_reloc' have been written to work around the problems, which
4626 in turns makes it difficult to fix `bfd_install_relocation'. */
4628 /* If while processing a fixup, a reloc really needs to be created
4629 then it is done here. */
4632 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4634 static arelent
* no_relocs
= NULL
;
4635 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4638 reloc
= XNEW (arelent
);
4639 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4640 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4642 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4644 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4645 _("reloc %d not supported by object file format"),
4646 (int) fixp
->fx_r_type
);
4655 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4657 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4658 fixp
->fx_subsy
= NULL
;
4661 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4663 asection
*asec
, *ssec
;
4665 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4666 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4668 /* If we have a difference between two different, non-absolute symbols
4669 we must generate two relocs (one for each symbol) and allow the
4670 linker to resolve them - relaxation may change the distances between
4671 symbols, even local symbols defined in the same section.
4673 Unfortunately we cannot do this with assembler generated local labels
4674 because there can be multiple incarnations of the same label, with
4675 exactly the same name, in any given section and the linker will have
4676 no way to identify the correct one. Instead we just have to hope
4677 that no relaxation will occur between the local label and the other
4678 symbol in the expression.
4680 Similarly we have to compute differences between symbols in the .eh_frame
4681 section as the linker is not smart enough to apply relocations there
4682 before attempting to process it. */
4683 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4684 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4685 && strcmp (ssec
->name
, ".eh_frame") != 0
4686 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4687 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4689 arelent
* reloc2
= XNEW (arelent
);
4694 reloc2
->address
= reloc
->address
;
4695 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4696 BFD_RELOC_MSP430_SYM_DIFF
);
4697 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4699 if (ssec
== absolute_section
)
4700 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4703 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4704 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4707 reloc
->addend
= fixp
->fx_offset
;
4708 if (asec
== absolute_section
)
4710 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4711 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4715 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4716 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4725 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4727 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4728 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4730 switch (fixp
->fx_r_type
)
4733 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4737 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4741 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4745 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4750 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4761 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4762 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4764 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4765 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4767 md_number_to_chars (fixpos
, amount
, 2);
4772 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4773 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4774 reloc
->addend
= fixp
->fx_offset
;
4776 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4777 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4778 reloc
->address
= fixp
->fx_offset
;
4785 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4786 asection
* segment_type ATTRIBUTE_UNUSED
)
4788 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4790 /* This is a jump -> pcrel mode. Nothing to do much here.
4791 Return value == 2. */
4793 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4795 else if (fragP
->fr_symbol
)
4797 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4798 an absolute segment, we don't know a displacement until we link
4799 object files. So it will always be long. This also applies to
4800 labels in a subsegment of current. Liker may relax it to short
4801 jump later. Return value == 8. */
4803 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4807 /* We know the abs value. may be it is a jump to fixed address.
4808 Impossible in our case, cause all constants already handled. */
4810 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4813 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4817 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4818 asection
* sec ATTRIBUTE_UNUSED
,
4824 struct rcodes_s
* cc
= NULL
;
4825 struct hcodes_s
* hc
= NULL
;
4827 switch (fragP
->fr_subtype
)
4829 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4830 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4831 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4832 /* We do not have to convert anything here.
4833 Just apply a fix. */
4834 rela
= BFD_RELOC_MSP430_10_PCREL
;
4837 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4838 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4839 /* Convert uncond branch jmp lab -> br lab. */
4840 if (target_is_430x ())
4841 cc
= msp430x_rcodes
+ 7;
4843 cc
= msp430_rcodes
+ 7;
4844 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4845 bfd_putl16 (cc
->lop0
, where
);
4846 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4850 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4851 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4853 /* Other simple branches. */
4854 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4857 /* Find actual instruction. */
4858 if (target_is_430x ())
4860 for (i
= 0; i
< 7 && !cc
; i
++)
4861 if (msp430x_rcodes
[i
].sop
== insn
)
4862 cc
= msp430x_rcodes
+ i
;
4866 for (i
= 0; i
< 7 && !cc
; i
++)
4867 if (msp430_rcodes
[i
].sop
== insn
)
4868 cc
= & msp430_rcodes
[i
];
4871 if (!cc
|| !cc
->name
)
4872 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4873 __func__
, (long) insn
);
4874 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4875 bfd_putl16 (cc
->lop0
, where
);
4876 bfd_putl16 (cc
->lop1
, where
+ 2);
4877 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4882 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4883 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4884 if (target_is_430x ())
4885 cc
= msp430x_rcodes
+ 6;
4887 cc
= msp430_rcodes
+ 6;
4888 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4889 bfd_putl16 (cc
->lop0
, where
);
4890 bfd_putl16 (cc
->lop1
, where
+ 2);
4891 bfd_putl16 (cc
->lop2
, where
+ 4);
4892 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4896 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4898 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4901 if (target_is_430x ())
4903 for (i
= 0; i
< 4 && !hc
; i
++)
4904 if (msp430x_hcodes
[i
].op1
== insn
)
4905 hc
= msp430x_hcodes
+ i
;
4909 for (i
= 0; i
< 4 && !hc
; i
++)
4910 if (msp430_hcodes
[i
].op1
== insn
)
4911 hc
= &msp430_hcodes
[i
];
4913 if (!hc
|| !hc
->name
)
4914 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4915 __func__
, (long) insn
);
4916 rela
= BFD_RELOC_MSP430_10_PCREL
;
4917 /* Apply a fix for a first label if necessary.
4918 another fix will be applied to the next word of insn anyway. */
4920 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4921 fragP
->fr_offset
, true, rela
);
4927 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4928 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4930 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4933 if (target_is_430x ())
4935 for (i
= 0; i
< 4 && !hc
; i
++)
4936 if (msp430x_hcodes
[i
].op1
== insn
)
4937 hc
= msp430x_hcodes
+ i
;
4941 for (i
= 0; i
< 4 && !hc
; i
++)
4942 if (msp430_hcodes
[i
].op1
== insn
)
4943 hc
= & msp430_hcodes
[i
];
4945 if (!hc
|| !hc
->name
)
4946 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4947 __func__
, (long) insn
);
4948 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4949 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4950 bfd_putl16 (hc
->lop0
, where
);
4951 bfd_putl16 (hc
->lop1
, where
+ 2);
4952 bfd_putl16 (hc
->lop2
, where
+ 4);
4958 as_fatal (_("internal inconsistency problem in %s: %lx"),
4959 __func__
, (long) fragP
->fr_subtype
);
4963 /* Now apply fix. */
4964 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4965 fragP
->fr_offset
, true, rela
);
4966 /* Just fixed 2 bytes. */
4970 /* Relax fragment. Mostly stolen from hc11 and mcore
4971 which arches I think I know. */
4974 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4975 long stretch ATTRIBUTE_UNUSED
)
4980 const relax_typeS
*this_type
;
4981 const relax_typeS
*start_type
;
4982 relax_substateT next_state
;
4983 relax_substateT this_state
;
4984 const relax_typeS
*table
= md_relax_table
;
4986 /* Nothing to be done if the frag has already max size. */
4987 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4988 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4991 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4993 symbolP
= fragP
->fr_symbol
;
4994 if (symbol_resolved_p (symbolP
))
4995 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4997 /* We know the offset. calculate a distance. */
4998 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
5001 if (!msp430_enable_relax
)
5003 /* Relaxation is not enabled. So, make all jump as long ones
5004 by setting 'aim' to quite high value. */
5008 this_state
= fragP
->fr_subtype
;
5009 start_type
= this_type
= table
+ this_state
;
5013 /* Look backwards. */
5014 for (next_state
= this_type
->rlx_more
; next_state
;)
5015 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
5019 /* Grow to next state. */
5020 this_state
= next_state
;
5021 this_type
= table
+ this_state
;
5022 next_state
= this_type
->rlx_more
;
5027 /* Look forwards. */
5028 for (next_state
= this_type
->rlx_more
; next_state
;)
5029 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
5033 /* Grow to next state. */
5034 this_state
= next_state
;
5035 this_type
= table
+ this_state
;
5036 next_state
= this_type
->rlx_more
;
5040 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5042 fragP
->fr_subtype
= this_state
;
5046 /* Return FALSE if the fixup in fixp should be left alone and not
5047 adjusted. We return FALSE here so that linker relaxation will
5051 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
5053 /* If the symbol is in a non-code section then it should be OK. */
5055 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
5061 /* Scan uleb128 subtraction expressions and insert fixups for them.
5062 e.g., .uleb128 .L1 - .L0
5063 Because relaxation may change the value of the subtraction, we
5064 must resolve them at link-time. */
5067 msp430_insert_uleb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
5068 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
5070 segment_info_type
*seginfo
= seg_info (sec
);
5073 subseg_set (sec
, 0);
5075 for (fragP
= seginfo
->frchainP
->frch_root
;
5076 fragP
; fragP
= fragP
->fr_next
)
5078 expressionS
*exp
, *exp_dup
;
5080 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_symbol
== NULL
)
5083 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
5085 if (exp
->X_op
!= O_subtract
)
5088 /* FIXME: Skip for .sleb128. */
5089 if (fragP
->fr_subtype
!= 0)
5092 exp_dup
= xmemdup (exp
, sizeof (*exp
), sizeof (*exp
));
5093 exp_dup
->X_op
= O_symbol
;
5094 exp_dup
->X_op_symbol
= NULL
;
5096 /* Emit the SUB relocation first, since the SET relocation will write out
5098 exp_dup
->X_add_symbol
= exp
->X_op_symbol
;
5099 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
5100 exp_dup
, 0, BFD_RELOC_MSP430_SUB_ULEB128
);
5102 exp_dup
->X_add_symbol
= exp
->X_add_symbol
;
5103 /* Insert relocations to resolve the subtraction at link-time. */
5104 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
5105 exp_dup
, 0, BFD_RELOC_MSP430_SET_ULEB128
);
5110 /* Called after all assembly has been done. */
5112 msp430_md_finish (void)
5116 if (gen_interrupt_nops
)
5119 if (warn_interrupt_nops
)
5120 as_warn (INSERT_NOP_AT_EOF
);
5122 else if (warn_interrupt_nops
)
5123 as_warn (_(WARN_NOP_AT_EOF
));
5126 /* Insert relocations for uleb128 directives, so the values can be recomputed
5128 bfd_map_over_sections (stdoutput
, msp430_insert_uleb128_fixes
, NULL
);
5130 /* We have already emitted an error if any of the following attributes
5131 disagree with the attributes in the input assembly file. See
5132 msp430_object_attribute. */
5133 if (!bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
5135 ? OFBA_MSPABI_Val_ISA_MSP430X
5136 : OFBA_MSPABI_Val_ISA_MSP430
)
5137 || !bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
5139 ? OFBA_MSPABI_Val_Code_Model_LARGE
5140 : OFBA_MSPABI_Val_Code_Model_SMALL
)
5141 || !bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
5143 ? OFBA_MSPABI_Val_Code_Model_LARGE
5144 : OFBA_MSPABI_Val_Code_Model_SMALL
)
5145 /* The data region GNU attribute is ignored for the small memory model. */
5147 && !bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_GNU
,
5148 Tag_GNU_MSP430_Data_Region
,
5149 lower_data_region_only
5150 ? Val_GNU_MSP430_Data_Region_Lower
5151 : Val_GNU_MSP430_Data_Region_Any
)))
5152 as_fatal (_("error adding attribute: %s"),
5153 bfd_errmsg (bfd_get_error ()));
5156 /* Returns FALSE if there is a msp430 specific reason why the
5157 subtraction of two same-section symbols cannot be computed by
5161 msp430_allow_local_subtract (expressionS
* left
,
5162 expressionS
* right
,
5165 /* If the symbols are not in a code section then they are OK. */
5166 if ((section
->flags
& SEC_CODE
) == 0)
5169 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
5172 if (left
->X_add_symbol
== right
->X_add_symbol
)
5175 /* We have to assume that there may be instructions between the
5176 two symbols and that relaxation may increase the distance between