1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2019 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
106 int index
; /* Corresponding insn_opnumb. */
107 int sop
; /* Opcode if jump length is short. */
108 long lpos
; /* Label position. */
109 long lop0
; /* Opcode 1 _word_ (16 bits). */
110 long lop1
; /* Opcode second word. */
111 long lop2
; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes
[] =
119 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
131 #define MSP430_RLC(n,i,sop,o1) \
132 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
134 static struct rcodes_s msp430x_rcodes
[] =
136 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
137 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
138 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
139 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
140 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
141 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
142 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
143 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
148 /* More difficult than above and they have format 5.
151 =================================================================
152 gt > jeq +2; jge label jeq +6; jl +4; br label
153 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
154 leu <= jeq label; jlo label jeq +2; jhs +4; br label
155 le <= jeq label; jl label jeq +2; jge +4; br label
156 ================================================================= */
161 int index
; /* Corresponding insn_opnumb. */
162 int tlab
; /* Number of labels in short mode. */
163 int op0
; /* Opcode for first word of short jump. */
164 int op1
; /* Opcode for second word of short jump. */
165 int lop0
; /* Opcodes for long jump mode. */
170 static struct hcodes_s msp430_hcodes
[] =
172 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
173 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
174 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
175 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 static struct hcodes_s msp430x_hcodes
[] =
181 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
182 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
183 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
184 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 const char comment_chars
[] = ";";
189 const char line_comment_chars
[] = "#";
190 const char line_separator_chars
[] = "{";
191 const char EXP_CHARS
[] = "eE";
192 const char FLT_CHARS
[] = "dD";
194 /* Handle long expressions. */
195 extern LITTLENUM_TYPE generic_bignum
[];
197 static struct hash_control
*msp430_hash
;
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
212 #define STATE_BITS10 1 /* Wild guess. short jump. */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */
214 #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table
[] =
229 /* Unconditional jump. */
231 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
232 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
233 {1, 1, CUBL
, 0}, /* state undef */
235 /* Simple branches. */
237 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
238 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
241 /* blt no overflow branch. */
243 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
244 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
247 /* Emulated branches. */
249 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
250 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
266 static inline bfd_boolean
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
272 static inline bfd_boolean
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation.
279 For the 430X we generate a relocation without linker range checking
280 if the value is being used in an extended (ie 20-bit) instruction,
281 otherwise if have a shifted expression we use a HI reloc.
282 For the 430 we generate a relocation without assembler range checking
283 if we are handling an immediate value or a byte-width instruction. */
285 #undef CHECK_RELOC_MSP430
286 #define CHECK_RELOC_MSP430(OP) \
290 : ((OP).vshift == 1) \
291 ? BFD_RELOC_MSP430_ABS_HI16 \
292 : BFD_RELOC_MSP430X_ABS16) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
303 ? BFD_RELOC_MSP430X_PCR16 \
304 : (imm_op || byte_op) \
305 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
307 /* Profiling capability:
308 It is a performance hit to use gcc's profiling approach for this tiny target.
309 Even more -- jtag hardware facility does not perform any profiling functions.
310 However we've got gdb's built-in simulator where we can do anything.
311 Therefore my suggestion is:
313 We define new section ".profiler" which holds all profiling information.
314 We define new pseudo operation .profiler which will instruct assembler to
315 add new profile entry to the object file. Profile should take place at the
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
325 i - function is in Init section
326 f - function is in Fini section
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
335 j - long Jump/ sjlj unwind
336 a - an Arbitrary code fragment
337 t - exTra parameter saved (constant value like frame size)
338 '""' optional: "sil" == sil
340 function_to_profile - function's address
341 cycle_corrector - a value which should be added to the cycle
342 counter, zero if omitted
343 extra - some extra parameter, zero if omitted.
346 ------------------------------
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
357 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
358 ; (this is a prologue end)
359 ; note, that spare var filled with the frame size
362 .profiler cdE,fxx ; check stack
367 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
368 ret ; cause 'ret' insn takes 3 cycles
369 -------------------------------
371 This profiling approach does not produce any overhead and
373 So, even profiled code can be uploaded to the MCU. */
374 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
375 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
376 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
377 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
378 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
379 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
380 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
381 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
382 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
383 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
384 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
385 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
386 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
387 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
388 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
389 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
402 for (; x
; x
= x
>> 1)
409 /* Parse ordinary expression. */
412 parse_exp (char * s
, expressionS
* op
)
414 input_line_pointer
= s
;
416 if (op
->X_op
== O_absent
)
417 as_bad (_("missing operand"));
419 /* Our caller is likely to check that the entire expression was parsed.
420 If we have found a hex constant with an 'h' suffix, ilp will be left
421 pointing at the 'h', so skip it here. */
422 if (input_line_pointer
!= NULL
423 && op
->X_op
== O_constant
424 && (*input_line_pointer
== 'h' || *input_line_pointer
== 'H'))
425 ++ input_line_pointer
;
426 return input_line_pointer
;
430 /* Delete spaces from s: X ( r 1 2) => X(r12). */
433 del_spaces (char * s
)
441 while (ISSPACE (*m
) && *m
)
443 memmove (s
, m
, strlen (m
) + 1);
451 skip_space (char * s
)
458 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
461 extract_operand (char * from
, char * to
, int limit
)
465 /* Drop leading whitespace. */
466 from
= skip_space (from
);
468 while (size
< limit
&& *from
)
470 *(to
+ size
) = *from
;
471 if (*from
== ',' || *from
== ';' || *from
== '\n')
486 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
503 s
= input_line_pointer
;
504 end
= input_line_pointer
;
506 while (*end
&& *end
!= '\n')
509 while (*s
&& *s
!= '\n')
520 as_bad (_(".profiler pseudo requires at least two operands."));
521 input_line_pointer
= end
;
525 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
534 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
537 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
540 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
543 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
546 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
549 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
552 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
555 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
558 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
561 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
564 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
567 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
570 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
573 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
576 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
579 as_warn (_("unknown profiling flag - ignored."));
586 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
587 | MSP430_PROFILER_FLAG_EXIT
))
588 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
589 | MSP430_PROFILER_FLAG_PROLEND
590 | MSP430_PROFILER_FLAG_EPISTART
591 | MSP430_PROFILER_FLAG_EPIEND
))
592 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
593 | MSP430_PROFILER_FLAG_FINISECT
))))
595 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
596 input_line_pointer
= end
;
600 /* Generate temp symbol which denotes current location. */
601 if (now_seg
== absolute_section
) /* Paranoia ? */
603 exp1
.X_op
= O_constant
;
604 exp1
.X_add_number
= abs_section_offset
;
605 as_warn (_("profiling in absolute section?"));
609 exp1
.X_op
= O_symbol
;
610 exp1
.X_add_symbol
= symbol_temp_new_now ();
611 exp1
.X_add_number
= 0;
614 /* Generate a symbol which holds flags value. */
615 exp
.X_op
= O_constant
;
616 exp
.X_add_number
= p_flags
;
618 /* Save current section. */
622 /* Now go to .profiler section. */
623 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0, 0);
626 emit_expr (& exp
, 2);
628 /* Save label value. */
629 emit_expr (& exp1
, 2);
633 /* Now get profiling info. */
634 halt
= extract_operand (input_line_pointer
, str
, 1024);
635 /* Process like ".word xxx" directive. */
636 (void) parse_exp (str
, & exp
);
637 emit_expr (& exp
, 2);
638 input_line_pointer
= halt
;
641 /* Fill the rest with zeros. */
642 exp
.X_op
= O_constant
;
643 exp
.X_add_number
= 0;
645 emit_expr (& exp
, 2);
647 /* Return to current section. */
648 subseg_set (seg
, subseg
);
652 extract_word (char * from
, char * to
, int limit
)
657 /* Drop leading whitespace. */
658 from
= skip_space (from
);
661 /* Find the op code end. */
662 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
664 to
[size
++] = *op_end
++;
665 if (size
+ 1 >= limit
)
673 #define OPTION_MMCU 'm'
674 #define OPTION_RELAX 'Q'
675 #define OPTION_POLYMORPHS 'P'
676 #define OPTION_LARGE 'l'
677 static bfd_boolean large_model
= FALSE
;
678 #define OPTION_NO_INTR_NOPS 'N'
679 #define OPTION_INTR_NOPS 'n'
680 static bfd_boolean gen_interrupt_nops
= FALSE
;
681 #define OPTION_WARN_INTR_NOPS 'y'
682 #define OPTION_NO_WARN_INTR_NOPS 'Y'
683 static bfd_boolean warn_interrupt_nops
= TRUE
;
684 #define OPTION_UNKNOWN_INTR_NOPS 'u'
685 #define OPTION_NO_UNKNOWN_INTR_NOPS 'U'
686 static bfd_boolean do_unknown_interrupt_nops
= TRUE
;
687 #define OPTION_MCPU 'c'
688 #define OPTION_MOVE_DATA 'd'
689 static bfd_boolean move_data
= FALSE
;
690 #define OPTION_DATA_REGION 'r'
691 static bfd_boolean upper_data_region_in_use
= FALSE
;
692 /* The default is to use the lower region only. */
693 static bfd_boolean lower_data_region_only
= TRUE
;
697 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
698 OPTION_SILICON_ERRATA_WARN
,
701 static unsigned int silicon_errata_fix
= 0;
702 static unsigned int silicon_errata_warn
= 0;
703 #define SILICON_ERRATA_CPU4 (1 << 0)
704 #define SILICON_ERRATA_CPU8 (1 << 1)
705 #define SILICON_ERRATA_CPU11 (1 << 2)
706 #define SILICON_ERRATA_CPU12 (1 << 3)
707 #define SILICON_ERRATA_CPU13 (1 << 4)
708 #define SILICON_ERRATA_CPU19 (1 << 5)
711 msp430_set_arch (int option
)
713 char str
[32]; /* 32 for good measure. */
715 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
717 md_parse_option (option
, str
);
718 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
719 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
722 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
723 Keep these two structures in sync.
724 The data in this structure has been extracted from version 1.194 of the
725 devices.csv file released by TI in September 2016. */
727 struct msp430_mcu_data
730 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
731 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
735 { "cc430f5123",2,8 },
736 { "cc430f5125",2,8 },
737 { "cc430f5133",2,8 },
738 { "cc430f5135",2,8 },
739 { "cc430f5137",2,8 },
740 { "cc430f5143",2,8 },
741 { "cc430f5145",2,8 },
742 { "cc430f5147",2,8 },
743 { "cc430f6125",2,8 },
744 { "cc430f6126",2,8 },
745 { "cc430f6127",2,8 },
746 { "cc430f6135",2,8 },
747 { "cc430f6137",2,8 },
748 { "cc430f6143",2,8 },
749 { "cc430f6145",2,8 },
750 { "cc430f6147",2,8 },
751 { "msp430afe221",0,2 },
752 { "msp430afe222",0,2 },
753 { "msp430afe223",0,2 },
754 { "msp430afe231",0,2 },
755 { "msp430afe232",0,2 },
756 { "msp430afe233",0,2 },
757 { "msp430afe251",0,2 },
758 { "msp430afe252",0,2 },
759 { "msp430afe253",0,2 },
760 { "msp430bt5190",2,8 },
761 { "msp430c091",0,0 },
762 { "msp430c092",0,0 },
763 { "msp430c111",0,0 },
764 { "msp430c1111",0,0 },
765 { "msp430c112",0,0 },
766 { "msp430c1121",0,0 },
767 { "msp430c1331",0,0 },
768 { "msp430c1351",0,0 },
769 { "msp430c311s",0,0 },
770 { "msp430c312",0,0 },
771 { "msp430c313",0,0 },
772 { "msp430c314",0,0 },
773 { "msp430c315",0,0 },
774 { "msp430c323",0,0 },
775 { "msp430c325",0,0 },
776 { "msp430c336",0,1 },
777 { "msp430c337",0,1 },
778 { "msp430c412",0,0 },
779 { "msp430c413",0,0 },
780 { "msp430cg4616",1,1 },
781 { "msp430cg4617",1,1 },
782 { "msp430cg4618",1,1 },
783 { "msp430cg4619",1,1 },
784 { "msp430e112",0,0 },
785 { "msp430e313",0,0 },
786 { "msp430e315",0,0 },
787 { "msp430e325",0,0 },
788 { "msp430e337",0,1 },
789 { "msp430f110",0,0 },
790 { "msp430f1101",0,0 },
791 { "msp430f1101a",0,0 },
792 { "msp430f1111",0,0 },
793 { "msp430f1111a",0,0 },
794 { "msp430f112",0,0 },
795 { "msp430f1121",0,0 },
796 { "msp430f1121a",0,0 },
797 { "msp430f1122",0,0 },
798 { "msp430f1132",0,0 },
799 { "msp430f122",0,0 },
800 { "msp430f1222",0,0 },
801 { "msp430f123",0,0 },
802 { "msp430f1232",0,0 },
803 { "msp430f133",0,0 },
804 { "msp430f135",0,0 },
805 { "msp430f147",0,1 },
806 { "msp430f1471",0,1 },
807 { "msp430f148",0,1 },
808 { "msp430f1481",0,1 },
809 { "msp430f149",0,1 },
810 { "msp430f1491",0,1 },
811 { "msp430f155",0,0 },
812 { "msp430f156",0,0 },
813 { "msp430f157",0,0 },
814 { "msp430f1610",0,1 },
815 { "msp430f1611",0,1 },
816 { "msp430f1612",0,1 },
817 { "msp430f167",0,1 },
818 { "msp430f168",0,1 },
819 { "msp430f169",0,1 },
820 { "msp430f2001",0,0 },
821 { "msp430f2002",0,0 },
822 { "msp430f2003",0,0 },
823 { "msp430f2011",0,0 },
824 { "msp430f2012",0,0 },
825 { "msp430f2013",0,0 },
826 { "msp430f2101",0,0 },
827 { "msp430f2111",0,0 },
828 { "msp430f2112",0,0 },
829 { "msp430f2121",0,0 },
830 { "msp430f2122",0,0 },
831 { "msp430f2131",0,0 },
832 { "msp430f2132",0,0 },
833 { "msp430f2232",0,0 },
834 { "msp430f2234",0,0 },
835 { "msp430f2252",0,0 },
836 { "msp430f2254",0,0 },
837 { "msp430f2272",0,0 },
838 { "msp430f2274",0,0 },
839 { "msp430f233",0,2 },
840 { "msp430f2330",0,2 },
841 { "msp430f235",0,2 },
842 { "msp430f2350",0,2 },
843 { "msp430f2370",0,2 },
844 { "msp430f2410",0,2 },
845 { "msp430f2416",1,2 },
846 { "msp430f2417",1,2 },
847 { "msp430f2418",1,2 },
848 { "msp430f2419",1,2 },
849 { "msp430f247",0,2 },
850 { "msp430f2471",0,2 },
851 { "msp430f248",0,2 },
852 { "msp430f2481",0,2 },
853 { "msp430f249",0,2 },
854 { "msp430f2491",0,2 },
855 { "msp430f2616",1,2 },
856 { "msp430f2617",1,2 },
857 { "msp430f2618",1,2 },
858 { "msp430f2619",1,2 },
859 { "msp430f412",0,0 },
860 { "msp430f413",0,0 },
861 { "msp430f4132",0,0 },
862 { "msp430f415",0,0 },
863 { "msp430f4152",0,0 },
864 { "msp430f417",0,0 },
865 { "msp430f423",0,1 },
866 { "msp430f423a",0,1 },
867 { "msp430f425",0,1 },
868 { "msp430f4250",0,0 },
869 { "msp430f425a",0,1 },
870 { "msp430f4260",0,0 },
871 { "msp430f427",0,1 },
872 { "msp430f4270",0,0 },
873 { "msp430f427a",0,1 },
874 { "msp430f435",0,0 },
875 { "msp430f4351",0,0 },
876 { "msp430f436",0,0 },
877 { "msp430f4361",0,0 },
878 { "msp430f437",0,0 },
879 { "msp430f4371",0,0 },
880 { "msp430f438",0,0 },
881 { "msp430f439",0,0 },
882 { "msp430f447",0,1 },
883 { "msp430f448",0,1 },
884 { "msp430f4481",0,1 },
885 { "msp430f449",0,1 },
886 { "msp430f4491",0,1 },
887 { "msp430f4616",1,1 },
888 { "msp430f46161",1,1 },
889 { "msp430f4617",1,1 },
890 { "msp430f46171",1,1 },
891 { "msp430f4618",1,1 },
892 { "msp430f46181",1,1 },
893 { "msp430f4619",1,1 },
894 { "msp430f46191",1,1 },
895 { "msp430f47126",1,4 },
896 { "msp430f47127",1,4 },
897 { "msp430f47163",1,4 },
898 { "msp430f47166",1,4 },
899 { "msp430f47167",1,4 },
900 { "msp430f47173",1,4 },
901 { "msp430f47176",1,4 },
902 { "msp430f47177",1,4 },
903 { "msp430f47183",1,4 },
904 { "msp430f47186",1,4 },
905 { "msp430f47187",1,4 },
906 { "msp430f47193",1,4 },
907 { "msp430f47196",1,4 },
908 { "msp430f47197",1,4 },
909 { "msp430f477",0,0 },
910 { "msp430f478",0,0 },
911 { "msp430f4783",0,4 },
912 { "msp430f4784",0,4 },
913 { "msp430f479",0,0 },
914 { "msp430f4793",0,4 },
915 { "msp430f4794",0,4 },
916 { "msp430f5131",2,8 },
917 { "msp430f5132",2,8 },
918 { "msp430f5151",2,8 },
919 { "msp430f5152",2,8 },
920 { "msp430f5171",2,8 },
921 { "msp430f5172",2,8 },
922 { "msp430f5212",2,8 },
923 { "msp430f5213",2,8 },
924 { "msp430f5214",2,8 },
925 { "msp430f5217",2,8 },
926 { "msp430f5218",2,8 },
927 { "msp430f5219",2,8 },
928 { "msp430f5222",2,8 },
929 { "msp430f5223",2,8 },
930 { "msp430f5224",2,8 },
931 { "msp430f5227",2,8 },
932 { "msp430f5228",2,8 },
933 { "msp430f5229",2,8 },
934 { "msp430f5232",2,8 },
935 { "msp430f5234",2,8 },
936 { "msp430f5237",2,8 },
937 { "msp430f5239",2,8 },
938 { "msp430f5242",2,8 },
939 { "msp430f5244",2,8 },
940 { "msp430f5247",2,8 },
941 { "msp430f5249",2,8 },
942 { "msp430f5252",2,8 },
943 { "msp430f5253",2,8 },
944 { "msp430f5254",2,8 },
945 { "msp430f5255",2,8 },
946 { "msp430f5256",2,8 },
947 { "msp430f5257",2,8 },
948 { "msp430f5258",2,8 },
949 { "msp430f5259",2,8 },
950 { "msp430f5304",2,8 },
951 { "msp430f5308",2,8 },
952 { "msp430f5309",2,8 },
953 { "msp430f5310",2,8 },
954 { "msp430f5324",2,8 },
955 { "msp430f5325",2,8 },
956 { "msp430f5326",2,8 },
957 { "msp430f5327",2,8 },
958 { "msp430f5328",2,8 },
959 { "msp430f5329",2,8 },
960 { "msp430f5333",2,8 },
961 { "msp430f5335",2,8 },
962 { "msp430f5336",2,8 },
963 { "msp430f5338",2,8 },
964 { "msp430f5340",2,8 },
965 { "msp430f5341",2,8 },
966 { "msp430f5342",2,8 },
967 { "msp430f5358",2,8 },
968 { "msp430f5359",2,8 },
969 { "msp430f5418",2,8 },
970 { "msp430f5418a",2,8 },
971 { "msp430f5419",2,8 },
972 { "msp430f5419a",2,8 },
973 { "msp430f5435",2,8 },
974 { "msp430f5435a",2,8 },
975 { "msp430f5436",2,8 },
976 { "msp430f5436a",2,8 },
977 { "msp430f5437",2,8 },
978 { "msp430f5437a",2,8 },
979 { "msp430f5438",2,8 },
980 { "msp430f5438a",2,8 },
981 { "msp430f5500",2,8 },
982 { "msp430f5501",2,8 },
983 { "msp430f5502",2,8 },
984 { "msp430f5503",2,8 },
985 { "msp430f5504",2,8 },
986 { "msp430f5505",2,8 },
987 { "msp430f5506",2,8 },
988 { "msp430f5507",2,8 },
989 { "msp430f5508",2,8 },
990 { "msp430f5509",2,8 },
991 { "msp430f5510",2,8 },
992 { "msp430f5513",2,8 },
993 { "msp430f5514",2,8 },
994 { "msp430f5515",2,8 },
995 { "msp430f5517",2,8 },
996 { "msp430f5519",2,8 },
997 { "msp430f5521",2,8 },
998 { "msp430f5522",2,8 },
999 { "msp430f5524",2,8 },
1000 { "msp430f5525",2,8 },
1001 { "msp430f5526",2,8 },
1002 { "msp430f5527",2,8 },
1003 { "msp430f5528",2,8 },
1004 { "msp430f5529",2,8 },
1005 { "msp430f5630",2,8 },
1006 { "msp430f5631",2,8 },
1007 { "msp430f5632",2,8 },
1008 { "msp430f5633",2,8 },
1009 { "msp430f5634",2,8 },
1010 { "msp430f5635",2,8 },
1011 { "msp430f5636",2,8 },
1012 { "msp430f5637",2,8 },
1013 { "msp430f5638",2,8 },
1014 { "msp430f5658",2,8 },
1015 { "msp430f5659",2,8 },
1016 { "msp430f5xx_6xxgeneric",2,8 },
1017 { "msp430f6433",2,8 },
1018 { "msp430f6435",2,8 },
1019 { "msp430f6436",2,8 },
1020 { "msp430f6438",2,8 },
1021 { "msp430f6458",2,8 },
1022 { "msp430f6459",2,8 },
1023 { "msp430f6630",2,8 },
1024 { "msp430f6631",2,8 },
1025 { "msp430f6632",2,8 },
1026 { "msp430f6633",2,8 },
1027 { "msp430f6634",2,8 },
1028 { "msp430f6635",2,8 },
1029 { "msp430f6636",2,8 },
1030 { "msp430f6637",2,8 },
1031 { "msp430f6638",2,8 },
1032 { "msp430f6658",2,8 },
1033 { "msp430f6659",2,8 },
1034 { "msp430f6720",2,8 },
1035 { "msp430f6720a",2,8 },
1036 { "msp430f6721",2,8 },
1037 { "msp430f6721a",2,8 },
1038 { "msp430f6723",2,8 },
1039 { "msp430f6723a",2,8 },
1040 { "msp430f6724",2,8 },
1041 { "msp430f6724a",2,8 },
1042 { "msp430f6725",2,8 },
1043 { "msp430f6725a",2,8 },
1044 { "msp430f6726",2,8 },
1045 { "msp430f6726a",2,8 },
1046 { "msp430f6730",2,8 },
1047 { "msp430f6730a",2,8 },
1048 { "msp430f6731",2,8 },
1049 { "msp430f6731a",2,8 },
1050 { "msp430f6733",2,8 },
1051 { "msp430f6733a",2,8 },
1052 { "msp430f6734",2,8 },
1053 { "msp430f6734a",2,8 },
1054 { "msp430f6735",2,8 },
1055 { "msp430f6735a",2,8 },
1056 { "msp430f6736",2,8 },
1057 { "msp430f6736a",2,8 },
1058 { "msp430f6745",2,8 },
1059 { "msp430f67451",2,8 },
1060 { "msp430f67451a",2,8 },
1061 { "msp430f6745a",2,8 },
1062 { "msp430f6746",2,8 },
1063 { "msp430f67461",2,8 },
1064 { "msp430f67461a",2,8 },
1065 { "msp430f6746a",2,8 },
1066 { "msp430f6747",2,8 },
1067 { "msp430f67471",2,8 },
1068 { "msp430f67471a",2,8 },
1069 { "msp430f6747a",2,8 },
1070 { "msp430f6748",2,8 },
1071 { "msp430f67481",2,8 },
1072 { "msp430f67481a",2,8 },
1073 { "msp430f6748a",2,8 },
1074 { "msp430f6749",2,8 },
1075 { "msp430f67491",2,8 },
1076 { "msp430f67491a",2,8 },
1077 { "msp430f6749a",2,8 },
1078 { "msp430f67621",2,8 },
1079 { "msp430f67621a",2,8 },
1080 { "msp430f67641",2,8 },
1081 { "msp430f67641a",2,8 },
1082 { "msp430f6765",2,8 },
1083 { "msp430f67651",2,8 },
1084 { "msp430f67651a",2,8 },
1085 { "msp430f6765a",2,8 },
1086 { "msp430f6766",2,8 },
1087 { "msp430f67661",2,8 },
1088 { "msp430f67661a",2,8 },
1089 { "msp430f6766a",2,8 },
1090 { "msp430f6767",2,8 },
1091 { "msp430f67671",2,8 },
1092 { "msp430f67671a",2,8 },
1093 { "msp430f6767a",2,8 },
1094 { "msp430f6768",2,8 },
1095 { "msp430f67681",2,8 },
1096 { "msp430f67681a",2,8 },
1097 { "msp430f6768a",2,8 },
1098 { "msp430f6769",2,8 },
1099 { "msp430f67691",2,8 },
1100 { "msp430f67691a",2,8 },
1101 { "msp430f6769a",2,8 },
1102 { "msp430f6775",2,8 },
1103 { "msp430f67751",2,8 },
1104 { "msp430f67751a",2,8 },
1105 { "msp430f6775a",2,8 },
1106 { "msp430f6776",2,8 },
1107 { "msp430f67761",2,8 },
1108 { "msp430f67761a",2,8 },
1109 { "msp430f6776a",2,8 },
1110 { "msp430f6777",2,8 },
1111 { "msp430f67771",2,8 },
1112 { "msp430f67771a",2,8 },
1113 { "msp430f6777a",2,8 },
1114 { "msp430f6778",2,8 },
1115 { "msp430f67781",2,8 },
1116 { "msp430f67781a",2,8 },
1117 { "msp430f6778a",2,8 },
1118 { "msp430f6779",2,8 },
1119 { "msp430f67791",2,8 },
1120 { "msp430f67791a",2,8 },
1121 { "msp430f6779a",2,8 },
1122 { "msp430fe423",0,0 },
1123 { "msp430fe4232",0,0 },
1124 { "msp430fe423a",0,0 },
1125 { "msp430fe4242",0,0 },
1126 { "msp430fe425",0,0 },
1127 { "msp430fe4252",0,0 },
1128 { "msp430fe425a",0,0 },
1129 { "msp430fe427",0,0 },
1130 { "msp430fe4272",0,0 },
1131 { "msp430fe427a",0,0 },
1132 { "msp430fg4250",0,0 },
1133 { "msp430fg4260",0,0 },
1134 { "msp430fg4270",0,0 },
1135 { "msp430fg437",0,0 },
1136 { "msp430fg438",0,0 },
1137 { "msp430fg439",0,0 },
1138 { "msp430fg4616",1,1 },
1139 { "msp430fg4617",1,1 },
1140 { "msp430fg4618",1,1 },
1141 { "msp430fg4619",1,1 },
1142 { "msp430fg477",0,0 },
1143 { "msp430fg478",0,0 },
1144 { "msp430fg479",0,0 },
1145 { "msp430fg6425",2,8 },
1146 { "msp430fg6426",2,8 },
1147 { "msp430fg6625",2,8 },
1148 { "msp430fg6626",2,8 },
1149 { "msp430fr2032",2,0 },
1150 { "msp430fr2033",2,0 },
1151 { "msp430fr2110",2,0 },
1152 { "msp430fr2111",2,0 },
1153 { "msp430fr2310",2,0 },
1154 { "msp430fr2311",2,0 },
1155 { "msp430fr2433",2,8 },
1156 { "msp430fr2532",2,8 },
1157 { "msp430fr2533",2,8 },
1158 { "msp430fr2632",2,8 },
1159 { "msp430fr2633",2,8 },
1160 { "msp430fr2xx_4xxgeneric",2,8 },
1161 { "msp430fr4131",2,0 },
1162 { "msp430fr4132",2,0 },
1163 { "msp430fr4133",2,0 },
1164 { "msp430fr5720",2,8 },
1165 { "msp430fr5721",2,8 },
1166 { "msp430fr5722",2,8 },
1167 { "msp430fr5723",2,8 },
1168 { "msp430fr5724",2,8 },
1169 { "msp430fr5725",2,8 },
1170 { "msp430fr5726",2,8 },
1171 { "msp430fr5727",2,8 },
1172 { "msp430fr5728",2,8 },
1173 { "msp430fr5729",2,8 },
1174 { "msp430fr5730",2,8 },
1175 { "msp430fr5731",2,8 },
1176 { "msp430fr5732",2,8 },
1177 { "msp430fr5733",2,8 },
1178 { "msp430fr5734",2,8 },
1179 { "msp430fr5735",2,8 },
1180 { "msp430fr5736",2,8 },
1181 { "msp430fr5737",2,8 },
1182 { "msp430fr5738",2,8 },
1183 { "msp430fr5739",2,8 },
1184 { "msp430fr57xxgeneric",2,8 },
1185 { "msp430fr5847",2,8 },
1186 { "msp430fr58471",2,8 },
1187 { "msp430fr5848",2,8 },
1188 { "msp430fr5849",2,8 },
1189 { "msp430fr5857",2,8 },
1190 { "msp430fr5858",2,8 },
1191 { "msp430fr5859",2,8 },
1192 { "msp430fr5867",2,8 },
1193 { "msp430fr58671",2,8 },
1194 { "msp430fr5868",2,8 },
1195 { "msp430fr5869",2,8 },
1196 { "msp430fr5870",2,8 },
1197 { "msp430fr5872",2,8 },
1198 { "msp430fr58721",2,8 },
1199 { "msp430fr5887",2,8 },
1200 { "msp430fr5888",2,8 },
1201 { "msp430fr5889",2,8 },
1202 { "msp430fr58891",2,8 },
1203 { "msp430fr5922",2,8 },
1204 { "msp430fr59221",2,8 },
1205 { "msp430fr5947",2,8 },
1206 { "msp430fr59471",2,8 },
1207 { "msp430fr5948",2,8 },
1208 { "msp430fr5949",2,8 },
1209 { "msp430fr5957",2,8 },
1210 { "msp430fr5958",2,8 },
1211 { "msp430fr5959",2,8 },
1212 { "msp430fr5962",2,8 },
1213 { "msp430fr5964",2,8 },
1214 { "msp430fr5967",2,8 },
1215 { "msp430fr5968",2,8 },
1216 { "msp430fr5969",2,8 },
1217 { "msp430fr59691",2,8 },
1218 { "msp430fr5970",2,8 },
1219 { "msp430fr5972",2,8 },
1220 { "msp430fr59721",2,8 },
1221 { "msp430fr5986",2,8 },
1222 { "msp430fr5987",2,8 },
1223 { "msp430fr5988",2,8 },
1224 { "msp430fr5989",2,8 },
1225 { "msp430fr59891",2,8 },
1226 { "msp430fr5992",2,8 },
1227 { "msp430fr5994",2,8 },
1228 { "msp430fr59941",2,8 },
1229 { "msp430fr5xx_6xxgeneric",2,8 },
1230 { "msp430fr6820",2,8 },
1231 { "msp430fr6822",2,8 },
1232 { "msp430fr68221",2,8 },
1233 { "msp430fr6870",2,8 },
1234 { "msp430fr6872",2,8 },
1235 { "msp430fr68721",2,8 },
1236 { "msp430fr6877",2,8 },
1237 { "msp430fr6879",2,8 },
1238 { "msp430fr68791",2,8 },
1239 { "msp430fr6887",2,8 },
1240 { "msp430fr6888",2,8 },
1241 { "msp430fr6889",2,8 },
1242 { "msp430fr68891",2,8 },
1243 { "msp430fr6920",2,8 },
1244 { "msp430fr6922",2,8 },
1245 { "msp430fr69221",2,8 },
1246 { "msp430fr6927",2,8 },
1247 { "msp430fr69271",2,8 },
1248 { "msp430fr6928",2,8 },
1249 { "msp430fr6970",2,8 },
1250 { "msp430fr6972",2,8 },
1251 { "msp430fr69721",2,8 },
1252 { "msp430fr6977",2,8 },
1253 { "msp430fr6979",2,8 },
1254 { "msp430fr69791",2,8 },
1255 { "msp430fr6987",2,8 },
1256 { "msp430fr6988",2,8 },
1257 { "msp430fr6989",2,8 },
1258 { "msp430fr69891",2,8 },
1259 { "msp430fw423",0,0 },
1260 { "msp430fw425",0,0 },
1261 { "msp430fw427",0,0 },
1262 { "msp430fw428",0,0 },
1263 { "msp430fw429",0,0 },
1264 { "msp430g2001",0,0 },
1265 { "msp430g2101",0,0 },
1266 { "msp430g2102",0,0 },
1267 { "msp430g2111",0,0 },
1268 { "msp430g2112",0,0 },
1269 { "msp430g2113",0,0 },
1270 { "msp430g2121",0,0 },
1271 { "msp430g2131",0,0 },
1272 { "msp430g2132",0,0 },
1273 { "msp430g2152",0,0 },
1274 { "msp430g2153",0,0 },
1275 { "msp430g2201",0,0 },
1276 { "msp430g2202",0,0 },
1277 { "msp430g2203",0,0 },
1278 { "msp430g2210",0,0 },
1279 { "msp430g2211",0,0 },
1280 { "msp430g2212",0,0 },
1281 { "msp430g2213",0,0 },
1282 { "msp430g2221",0,0 },
1283 { "msp430g2230",0,0 },
1284 { "msp430g2231",0,0 },
1285 { "msp430g2232",0,0 },
1286 { "msp430g2233",0,0 },
1287 { "msp430g2252",0,0 },
1288 { "msp430g2253",0,0 },
1289 { "msp430g2302",0,0 },
1290 { "msp430g2303",0,0 },
1291 { "msp430g2312",0,0 },
1292 { "msp430g2313",0,0 },
1293 { "msp430g2332",0,0 },
1294 { "msp430g2333",0,0 },
1295 { "msp430g2352",0,0 },
1296 { "msp430g2353",0,0 },
1297 { "msp430g2402",0,0 },
1298 { "msp430g2403",0,0 },
1299 { "msp430g2412",0,0 },
1300 { "msp430g2413",0,0 },
1301 { "msp430g2432",0,0 },
1302 { "msp430g2433",0,0 },
1303 { "msp430g2444",0,0 },
1304 { "msp430g2452",0,0 },
1305 { "msp430g2453",0,0 },
1306 { "msp430g2513",0,0 },
1307 { "msp430g2533",0,0 },
1308 { "msp430g2544",0,0 },
1309 { "msp430g2553",0,0 },
1310 { "msp430g2744",0,0 },
1311 { "msp430g2755",0,0 },
1312 { "msp430g2855",0,0 },
1313 { "msp430g2955",0,0 },
1314 { "msp430i2020",0,2 },
1315 { "msp430i2021",0,2 },
1316 { "msp430i2030",0,2 },
1317 { "msp430i2031",0,2 },
1318 { "msp430i2040",0,2 },
1319 { "msp430i2041",0,2 },
1320 { "msp430i2xxgeneric",0,2 },
1321 { "msp430l092",0,0 },
1322 { "msp430p112",0,0 },
1323 { "msp430p313",0,0 },
1324 { "msp430p315",0,0 },
1325 { "msp430p315s",0,0 },
1326 { "msp430p325",0,0 },
1327 { "msp430p337",0,1 },
1328 { "msp430sl5438a",2,8 },
1329 { "msp430tch5e",0,0 },
1330 { "msp430xgeneric",2,8 },
1331 { "rf430f5144",2,8 },
1332 { "rf430f5155",2,8 },
1333 { "rf430f5175",2,8 },
1334 { "rf430frl152h",0,0 },
1335 { "rf430frl152h_rom",0,0 },
1336 { "rf430frl153h",0,0 },
1337 { "rf430frl153h_rom",0,0 },
1338 { "rf430frl154h",0,0 },
1339 { "rf430frl154h_rom",0,0 }
1343 md_parse_option (int c
, const char * arg
)
1347 case OPTION_SILICON_ERRATA
:
1348 case OPTION_SILICON_ERRATA_WARN
:
1354 unsigned int length
;
1355 unsigned int bitfield
;
1358 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1359 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1360 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1361 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1362 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1363 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1368 for (i
= ARRAY_SIZE (erratas
); i
--;)
1369 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1371 if (c
== OPTION_SILICON_ERRATA
)
1372 silicon_errata_fix
|= erratas
[i
].bitfield
;
1374 silicon_errata_warn
|= erratas
[i
].bitfield
;
1375 arg
+= erratas
[i
].length
;
1380 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1386 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1396 as_fatal (_("MCU option requires a name\n"));
1398 if (strcasecmp ("msp430", arg
) == 0)
1399 selected_isa
= MSP_ISA_430
;
1400 else if (strcasecmp ("msp430xv2", arg
) == 0)
1401 selected_isa
= MSP_ISA_430Xv2
;
1402 else if (strcasecmp ("msp430x", arg
) == 0)
1403 selected_isa
= MSP_ISA_430X
;
1408 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1409 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1411 switch (msp430_mcu_data
[i
].revision
)
1413 case 0: selected_isa
= MSP_ISA_430
; break;
1414 case 1: selected_isa
= MSP_ISA_430X
; break;
1415 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1420 /* It is not an error if we do not match the MCU name. */
1424 if (strcmp (arg
, "430") == 0
1425 || strcasecmp (arg
, "msp430") == 0)
1426 selected_isa
= MSP_ISA_430
;
1427 else if (strcasecmp (arg
, "430x") == 0
1428 || strcasecmp (arg
, "msp430x") == 0)
1429 selected_isa
= MSP_ISA_430X
;
1430 else if (strcasecmp (arg
, "430xv2") == 0
1431 || strcasecmp (arg
, "msp430xv2") == 0)
1432 selected_isa
= MSP_ISA_430Xv2
;
1434 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1438 msp430_enable_relax
= 1;
1441 case OPTION_POLYMORPHS
:
1442 msp430_enable_polys
= 1;
1449 case OPTION_NO_INTR_NOPS
:
1450 gen_interrupt_nops
= FALSE
;
1452 case OPTION_INTR_NOPS
:
1453 gen_interrupt_nops
= TRUE
;
1456 case OPTION_WARN_INTR_NOPS
:
1457 warn_interrupt_nops
= TRUE
;
1459 case OPTION_NO_WARN_INTR_NOPS
:
1460 warn_interrupt_nops
= FALSE
;
1463 case OPTION_UNKNOWN_INTR_NOPS
:
1464 do_unknown_interrupt_nops
= TRUE
;
1466 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1467 do_unknown_interrupt_nops
= FALSE
;
1470 case OPTION_MOVE_DATA
:
1474 case OPTION_DATA_REGION
:
1475 if (strcmp (arg
, "upper") == 0
1476 || strcmp (arg
, "either") == 0)
1477 upper_data_region_in_use
= TRUE
;
1478 if (strcmp (arg
, "upper") == 0
1479 || strcmp (arg
, "either") == 0
1480 /* With data-region=none, the compiler has generated code assuming
1481 data could be in the upper region, but nothing has been explicitly
1483 || strcmp (arg
, "none") == 0)
1484 lower_data_region_only
= FALSE
;
1491 /* The intention here is to have the mere presence of these sections
1492 cause the object to have a reference to a well-known symbol. This
1493 reference pulls in the bits of the runtime (crt0) that initialize
1494 these sections. Thus, for example, the startup code to call
1495 memset() to initialize .bss will only be linked in when there is a
1496 non-empty .bss section. Otherwise, the call would exist but have a
1497 zero length parameter, which is a waste of memory and cycles.
1499 The code which initializes these sections should have a global
1500 label for these symbols, and should be marked with KEEP() in the
1504 msp430_make_init_symbols (const char * name
)
1506 if (strncmp (name
, ".bss", 4) == 0
1507 || strncmp (name
, ".lower.bss", 10) == 0
1508 || strncmp (name
, ".either.bss", 11) == 0
1509 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1510 (void) symbol_find_or_make ("__crt0_init_bss");
1512 if (strncmp (name
, ".data", 5) == 0
1513 || strncmp (name
, ".lower.data", 11) == 0
1514 || strncmp (name
, ".either.data", 12) == 0
1515 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1516 (void) symbol_find_or_make ("__crt0_movedata");
1517 /* Note - data assigned to the .either.data section may end up being
1518 placed in the .upper.data section if the .lower.data section is
1519 full. Hence the need to define the crt0 symbol.
1520 The linker may create upper or either data sections, even when none exist
1521 at the moment, so use the value of the data-region flag to determine if
1522 the symbol is needed. */
1523 if (strncmp (name
, ".either.data", 12) == 0
1524 || strncmp (name
, ".upper.data", 11) == 0
1525 || upper_data_region_in_use
)
1526 (void) symbol_find_or_make ("__crt0_move_highdata");
1528 /* See note about .either.data above. */
1529 if (strncmp (name
, ".upper.bss", 10) == 0
1530 || strncmp (name
, ".either.bss", 11) == 0
1531 || upper_data_region_in_use
)
1532 (void) symbol_find_or_make ("__crt0_init_highbss");
1534 /* The following symbols are for the crt0 functions that run through
1535 the different .*_array sections and call the functions placed there.
1536 - init_array stores global static C++ constructors to run before main.
1537 - preinit_array is not expected to ever be used for MSP430.
1538 GCC only places initialization functions for runtime "sanitizers"
1539 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1540 - fini_array stores global static C++ destructors to run after calling
1541 exit() or returning from main.
1542 __crt0_run_array is required to actually call the functions in the above
1544 if (strncmp (name
, ".init_array", 11) == 0)
1546 (void) symbol_find_or_make ("__crt0_run_init_array");
1547 (void) symbol_find_or_make ("__crt0_run_array");
1549 else if (strncmp (name
, ".preinit_array", 14) == 0)
1551 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1552 (void) symbol_find_or_make ("__crt0_run_array");
1554 else if (strncmp (name
, ".fini_array", 11) == 0)
1556 (void) symbol_find_or_make ("__crt0_run_fini_array");
1557 (void) symbol_find_or_make ("__crt0_run_array");
1562 msp430_section (int arg
)
1564 char * saved_ilp
= input_line_pointer
;
1565 const char * name
= obj_elf_section_name ();
1567 msp430_make_init_symbols (name
);
1569 input_line_pointer
= saved_ilp
;
1570 obj_elf_section (arg
);
1574 msp430_frob_section (asection
*sec
)
1576 const char *name
= sec
->name
;
1581 msp430_make_init_symbols (name
);
1585 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1587 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1590 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1591 (void) symbol_find_or_make ("__crt0_init_bss");
1595 msp430_comm (int needs_align
)
1597 s_comm_internal (needs_align
, elf_common_parse
);
1598 (void) symbol_find_or_make ("__crt0_init_bss");
1602 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1604 char sym_name
[1024];
1605 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1607 (void) symbol_find_or_make (sym_name
);
1610 /* Handle a .mspabi_attribute or .gnu_attribute directive.
1611 attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute.
1612 This is only used for validating the attributes in the assembly file against
1613 the options gas has been invoked with. If the attributes and options are
1614 compatible then we add the attributes to the assembly file in
1617 msp430_object_attribute (int attr_type
)
1619 char tag_name_s
[32];
1620 char tag_value_s
[32];
1621 int tag_name
, tag_value
;
1622 /* First operand is the tag name, second is the tag value e.g.
1623 ".mspabi_attribute 4, 2". */
1624 input_line_pointer
= extract_operand (input_line_pointer
, tag_name_s
, 32);
1625 input_line_pointer
= extract_operand (input_line_pointer
, tag_value_s
, 32);
1626 tag_name
= atoi (tag_name_s
);
1627 tag_value
= atoi (tag_value_s
);
1628 /* If the attribute directive is present, the tag_value should never be set
1630 if (tag_name
== 0 || tag_value
== 0)
1631 as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"),
1632 tag_name_s
, tag_value_s
, (attr_type
? ".gnu_attribute"
1633 : ".mspabi_attribute"));
1634 else if (attr_type
== 0)
1635 /* Handle .mspabi_attribute. */
1638 case OFBA_MSPABI_Tag_ISA
:
1641 case OFBA_MSPABI_Val_ISA_MSP430
:
1642 if (target_is_430x ())
1643 as_bad (_("file was compiled for the 430 ISA but the %s ISA is "
1644 "selected"), (target_is_430xv2 () ? "430X" : "430Xv2"));
1646 case OFBA_MSPABI_Val_ISA_MSP430X
:
1647 if (!target_is_430x ())
1648 as_bad (_("file was compiled for the 430X ISA but the 430 ISA is "
1652 as_bad (_("unknown MSPABI build attribute value '%d' for "
1653 "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"),
1654 tag_value
, OFBA_MSPABI_Tag_ISA
);
1658 case OFBA_MSPABI_Tag_Code_Model
:
1660 case OFBA_MSPABI_Tag_Data_Model
:
1661 /* FIXME: Might we want to set the memory model to large if the assembly
1662 file has the large model attribute, but -ml has not been passed? */
1665 case OFBA_MSPABI_Val_Code_Model_SMALL
:
1667 as_bad (_("file was compiled for the small memory model, but the "
1668 "large memory model is selected"));
1670 case OFBA_MSPABI_Val_Code_Model_LARGE
:
1672 as_bad (_("file was compiled for the large memory model, "
1673 "but the small memory model is selected"));
1676 as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) "
1677 "in .mspabi_attribute directive"), tag_value
,
1678 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1679 ? "OFBA_MSPABI_Tag_Code_Model"
1680 : "OFBA_MSPABI_Tag_Data_Model"),
1681 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1682 ? OFBA_MSPABI_Tag_Code_Model
1683 : OFBA_MSPABI_Tag_Data_Model
));
1688 as_bad (_("unknown MSPABI build attribute tag '%d' in "
1689 ".mspabi_attribute directive"), tag_name
);
1692 else if (attr_type
== 1)
1693 /* Handle .gnu_attribute. */
1696 case Tag_GNU_MSP430_Data_Region
:
1697 /* This attribute is only applicable in the large memory model. */
1702 case Val_GNU_MSP430_Data_Region_Lower
:
1703 if (!lower_data_region_only
)
1704 as_bad (_("file was compiled assuming all data will be in the "
1705 "lower memory region, but the upper region is in use"));
1707 case Val_GNU_MSP430_Data_Region_Any
:
1708 if (lower_data_region_only
)
1709 as_bad (_("file was compiled assuming data could be in the upper "
1710 "memory region, but the lower data region is "
1711 "exclusively in use"));
1714 as_bad (_("unknown GNU build attribute value '%d' for "
1715 "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute "
1716 "directive"), tag_value
, Tag_GNU_MSP430_Data_Region
);
1720 as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"),
1724 const pseudo_typeS md_pseudo_table
[] =
1726 {"arch", msp430_set_arch
, OPTION_MMCU
},
1727 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1728 {"profiler", msp430_profiler
, 0},
1729 {"section", msp430_section
, 0},
1730 {"section.s", msp430_section
, 0},
1731 {"sect", msp430_section
, 0},
1732 {"sect.s", msp430_section
, 0},
1733 {"pushsection", msp430_section
, 1},
1734 {"refsym", msp430_refsym
, 0},
1735 {"comm", msp430_comm
, 0},
1736 {"lcomm", msp430_lcomm
, 0},
1737 {"mspabi_attribute", msp430_object_attribute
, 0},
1738 {"gnu_attribute", msp430_object_attribute
, 1},
1742 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1744 struct option md_longopts
[] =
1746 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1747 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1748 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1749 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1750 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1751 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1752 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1753 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1754 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1755 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1756 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1757 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1758 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1759 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1760 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1761 {NULL
, no_argument
, NULL
, 0}
1764 size_t md_longopts_size
= sizeof (md_longopts
);
1767 md_show_usage (FILE * stream
)
1770 _("MSP430 options:\n"
1771 " -mmcu=<msp430-name> - select microcontroller type\n"
1772 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1774 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1775 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1776 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1778 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1779 " -mP - enable polymorph instructions\n"));
1781 _(" -ml - enable large code model\n"));
1783 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1785 _(" -mn - insert a NOP after changing interrupts\n"));
1787 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1789 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1791 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1792 " known how the state is changed, do not warn/insert NOPs\n"));
1794 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1795 " known how the state is changed, warn/insert NOPs (default)\n"
1796 " -mn and/or -my are required for this to have any effect\n"));
1798 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1800 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1805 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1811 extract_cmd (char * from
, char * to
, int limit
)
1815 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1817 *(to
+ size
) = *from
;
1828 md_atof (int type
, char * litP
, int * sizeP
)
1830 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1836 struct msp430_opcode_s
* opcode
;
1837 msp430_hash
= hash_new ();
1839 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1840 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1842 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1843 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1845 /* Set linkrelax here to avoid fixups in most sections. */
1849 static inline bfd_boolean
1850 is_regname_end (char c
)
1852 return (c
== 0 || ! ISALNUM (c
));
1855 /* Returns the register number equivalent to the string T.
1856 Returns -1 if there is no such register.
1857 Skips a leading 'r' or 'R' character if there is one.
1858 Handles the register aliases PC and SP. */
1861 check_reg (char * t
)
1864 signed long int val
;
1866 if (t
== NULL
|| t
[0] == 0)
1869 if (*t
== 'r' || *t
== 'R')
1872 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1875 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1878 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1881 if (*t
== '0' && is_regname_end (t
[1]))
1884 val
= strtol (t
, & endt
, 0);
1886 if (val
< 1 || val
> 15)
1889 if (is_regname_end (*endt
))
1896 msp430_srcoperand (struct msp430_operand_s
* op
,
1899 bfd_boolean
* imm_op
,
1900 bfd_boolean allow_20bit_values
,
1901 bfd_boolean constants_allowed
)
1906 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1913 /* Check if there is:
1914 llo(x) - least significant 16 bits, x &= 0xffff
1915 lhi(x) - x = (x >> 16) & 0xffff,
1916 hlo(x) - x = (x >> 32) & 0xffff,
1917 hhi(x) - x = (x >> 48) & 0xffff
1918 The value _MUST_ be constant expression: #hlo(1231231231). */
1922 if (strncasecmp (h
, "#llo(", 5) == 0)
1927 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1932 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1937 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1942 else if (strncasecmp (h
, "#lo(", 4) == 0)
1947 else if (strncasecmp (h
, "#hi(", 4) == 0)
1953 op
->reg
= 0; /* Reg PC. */
1955 op
->ol
= 1; /* Immediate will follow an instruction. */
1956 __tl
= h
+ 1 + rval
;
1958 op
->vshift
= vshift
;
1960 end
= parse_exp (__tl
, &(op
->exp
));
1961 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1963 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1966 if (op
->exp
.X_op
== O_constant
)
1968 int x
= op
->exp
.X_add_number
;
1973 op
->exp
.X_add_number
= x
;
1975 else if (vshift
== 1)
1977 x
= (x
>> 16) & 0xffff;
1978 op
->exp
.X_add_number
= x
;
1981 else if (vshift
> 1)
1984 op
->exp
.X_add_number
= -1;
1986 op
->exp
.X_add_number
= 0; /* Nothing left. */
1987 x
= op
->exp
.X_add_number
;
1991 if (allow_20bit_values
)
1993 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1995 as_bad (_("value 0x%x out of extended range."), x
);
1999 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
2001 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
2005 /* Now check constants. */
2006 /* Substitute register mode with a constant generator if applicable. */
2008 if (!allow_20bit_values
)
2009 x
= (short) x
; /* Extend sign. */
2011 if (! constants_allowed
)
2043 if (bin
== 0x1200 && ! target_is_430x ())
2045 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
2046 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2047 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
2048 /* No need to check silicon_errata_fixes - this fix is always implemented. */
2060 if (bin
== 0x1200 && ! target_is_430x ())
2062 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
2063 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2064 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
2075 else if (op
->exp
.X_op
== O_symbol
)
2078 as_bad (_("error: unsupported #foo() directive used on symbol"));
2081 else if (op
->exp
.X_op
== O_big
)
2087 op
->exp
.X_op
= O_constant
;
2088 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
2089 x
= op
->exp
.X_add_number
;
2095 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
2143 /* Redundant (yet) check. */
2144 else if (op
->exp
.X_op
== O_register
)
2146 (_("Registers cannot be used within immediate expression [%s]"), l
);
2148 as_bad (_("unknown operand %s"), l
);
2153 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2158 op
->reg
= 2; /* Reg 2 in absolute addr mode. */
2159 op
->am
= 1; /* Mode As == 01 bin. */
2160 op
->ol
= 1; /* Immediate value followed by instruction. */
2162 end
= parse_exp (__tl
, &(op
->exp
));
2163 if (end
!= NULL
&& *end
!= 0)
2165 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
2170 if (op
->exp
.X_op
== O_constant
)
2172 int x
= op
->exp
.X_add_number
;
2174 if (allow_20bit_values
)
2176 if (x
> 0xfffff || x
< -(0x7ffff))
2178 as_bad (_("value 0x%x out of extended range."), x
);
2182 else if (x
> 65535 || x
< -32768)
2184 as_bad (_("value out of range: 0x%x"), x
);
2188 else if (op
->exp
.X_op
== O_symbol
)
2192 /* Redundant (yet) check. */
2193 if (op
->exp
.X_op
== O_register
)
2195 (_("Registers cannot be used within absolute expression [%s]"), l
);
2197 as_bad (_("unknown expression in operand %s"), l
);
2203 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2207 char *m
= strchr (l
, '+');
2211 as_bad (_("unknown addressing mode %s"), l
);
2217 if ((op
->reg
= check_reg (t
)) == -1)
2219 as_bad (_("Bad register name %s"), t
);
2227 /* PC cannot be used in indirect addressing. */
2228 if (target_is_430xv2 () && op
->reg
== 0)
2230 as_bad (_("cannot use indirect addressing with the PC"));
2237 /* Check if register indexed X(Rn). */
2240 char *h
= strrchr (l
, '(');
2241 char *m
= strrchr (l
, ')');
2250 as_bad (_("')' required"));
2258 /* Extract a register. */
2259 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2262 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2269 as_bad (_("r2 should not be used in indexed addressing mode"));
2273 /* Extract constant. */
2278 end
= parse_exp (__tl
, &(op
->exp
));
2279 if (end
!= NULL
&& *end
!= 0)
2281 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2284 if (op
->exp
.X_op
== O_constant
)
2286 int x
= op
->exp
.X_add_number
;
2288 if (allow_20bit_values
)
2290 if (x
> 0xfffff || x
< - (0x7ffff))
2292 as_bad (_("value 0x%x out of extended range."), x
);
2296 else if (x
> 65535 || x
< -32768)
2298 as_bad (_("value out of range: 0x%x"), x
);
2310 if (op
->reg
== 1 && (x
& 1))
2312 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2313 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2314 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2315 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2318 else if (op
->exp
.X_op
== O_symbol
)
2322 /* Redundant (yet) check. */
2323 if (op
->exp
.X_op
== O_register
)
2325 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2327 as_bad (_("unknown expression in operand %s"), l
);
2335 /* Possibly register mode 'mov r1,r2'. */
2336 if ((op
->reg
= check_reg (l
)) != -1)
2344 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2346 op
->reg
= 0; /* PC relative... be careful. */
2347 /* An expression starting with a minus sign is a constant, not an address. */
2348 op
->am
= (*l
== '-' ? 3 : 1);
2352 end
= parse_exp (__tl
, &(op
->exp
));
2353 if (end
!= NULL
&& * end
!= 0)
2355 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2363 msp430_dstoperand (struct msp430_operand_s
* op
,
2366 bfd_boolean allow_20bit_values
,
2367 bfd_boolean constants_allowed
)
2370 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2379 char *__tl
= (char *) "0";
2385 (void) parse_exp (__tl
, &(op
->exp
));
2387 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2389 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2399 ("this addressing mode is not applicable for destination operand"));
2405 /* Attempt to encode a MOVA instruction with the given operands.
2406 Returns the length of the encoded instruction if successful
2407 or 0 upon failure. If the encoding fails, an error message
2408 will be returned if a pointer is provided. */
2411 try_encode_mova (bfd_boolean imm_op
,
2413 struct msp430_operand_s
* op1
,
2414 struct msp430_operand_s
* op2
,
2415 const char ** error_message_return
)
2421 /* Only a restricted subset of the normal MSP430 addressing modes
2422 are supported here, so check for the ones that are allowed. */
2425 if (op1
->mode
== OP_EXP
)
2427 if (op2
->mode
!= OP_REG
)
2429 if (error_message_return
!= NULL
)
2430 * error_message_return
= _("expected register as second argument of %s");
2436 /* MOVA #imm20, Rdst. */
2437 bin
|= 0x80 | op2
->reg
;
2438 frag
= frag_more (4);
2439 where
= frag
- frag_now
->fr_literal
;
2440 if (op1
->exp
.X_op
== O_constant
)
2442 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2443 bfd_putl16 ((bfd_vma
) bin
, frag
);
2444 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2448 bfd_putl16 ((bfd_vma
) bin
, frag
);
2449 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2450 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2451 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2456 else if (op1
->am
== 1)
2458 /* MOVA z16(Rsrc), Rdst. */
2459 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2460 frag
= frag_more (4);
2461 where
= frag
- frag_now
->fr_literal
;
2462 bfd_putl16 ((bfd_vma
) bin
, frag
);
2463 if (op1
->exp
.X_op
== O_constant
)
2465 if (op1
->exp
.X_add_number
> 0xffff
2466 || op1
->exp
.X_add_number
< -(0x7fff))
2468 if (error_message_return
!= NULL
)
2469 * error_message_return
= _("index value too big for %s");
2472 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2476 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2477 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2479 BFD_RELOC_MSP430X_PCR16
:
2480 BFD_RELOC_MSP430X_ABS16
);
2485 if (error_message_return
!= NULL
)
2486 * error_message_return
= _("unexpected addressing mode for %s");
2489 else if (op1
->am
== 0)
2491 /* MOVA Rsrc, ... */
2492 if (op2
->mode
== OP_REG
)
2494 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2495 frag
= frag_more (2);
2496 where
= frag
- frag_now
->fr_literal
;
2497 bfd_putl16 ((bfd_vma
) bin
, frag
);
2500 else if (op2
->am
== 1)
2504 /* MOVA Rsrc, &abs20. */
2505 bin
|= 0x60 | (op1
->reg
<< 8);
2506 frag
= frag_more (4);
2507 where
= frag
- frag_now
->fr_literal
;
2508 if (op2
->exp
.X_op
== O_constant
)
2510 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2511 bfd_putl16 ((bfd_vma
) bin
, frag
);
2512 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2516 bfd_putl16 ((bfd_vma
) bin
, frag
);
2517 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2518 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2519 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2524 /* MOVA Rsrc, z16(Rdst). */
2525 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2526 frag
= frag_more (4);
2527 where
= frag
- frag_now
->fr_literal
;
2528 bfd_putl16 ((bfd_vma
) bin
, frag
);
2529 if (op2
->exp
.X_op
== O_constant
)
2531 if (op2
->exp
.X_add_number
> 0xffff
2532 || op2
->exp
.X_add_number
< -(0x7fff))
2534 if (error_message_return
!= NULL
)
2535 * error_message_return
= _("index value too big for %s");
2538 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2542 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2543 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2545 BFD_RELOC_MSP430X_PCR16
:
2546 BFD_RELOC_MSP430X_ABS16
);
2551 if (error_message_return
!= NULL
)
2552 * error_message_return
= _("unexpected addressing mode for %s");
2557 /* imm_op == FALSE. */
2559 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2561 /* MOVA &abs20, Rdst. */
2562 if (op2
->mode
!= OP_REG
)
2564 if (error_message_return
!= NULL
)
2565 * error_message_return
= _("expected register as second argument of %s");
2569 if (op2
->reg
== 2 || op2
->reg
== 3)
2571 if (error_message_return
!= NULL
)
2572 * error_message_return
= _("constant generator destination register found in %s");
2576 bin
|= 0x20 | op2
->reg
;
2577 frag
= frag_more (4);
2578 where
= frag
- frag_now
->fr_literal
;
2579 if (op1
->exp
.X_op
== O_constant
)
2581 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2582 bfd_putl16 ((bfd_vma
) bin
, frag
);
2583 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2587 bfd_putl16 ((bfd_vma
) bin
, frag
);
2588 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2589 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2590 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2594 else if (op1
->mode
== OP_REG
)
2598 /* MOVA @Rsrc+, Rdst. */
2599 if (op2
->mode
!= OP_REG
)
2601 if (error_message_return
!= NULL
)
2602 * error_message_return
= _("expected register as second argument of %s");
2606 if (op2
->reg
== 2 || op2
->reg
== 3)
2608 if (error_message_return
!= NULL
)
2609 * error_message_return
= _("constant generator destination register found in %s");
2613 if (op1
->reg
== 2 || op1
->reg
== 3)
2615 if (error_message_return
!= NULL
)
2616 * error_message_return
= _("constant generator source register found in %s");
2620 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2621 frag
= frag_more (2);
2622 where
= frag
- frag_now
->fr_literal
;
2623 bfd_putl16 ((bfd_vma
) bin
, frag
);
2626 else if (op1
->am
== 2)
2628 /* MOVA @Rsrc,Rdst */
2629 if (op2
->mode
!= OP_REG
)
2631 if (error_message_return
!= NULL
)
2632 * error_message_return
= _("expected register as second argument of %s");
2636 if (op2
->reg
== 2 || op2
->reg
== 3)
2638 if (error_message_return
!= NULL
)
2639 * error_message_return
= _("constant generator destination register found in %s");
2643 if (op1
->reg
== 2 || op1
->reg
== 3)
2645 if (error_message_return
!= NULL
)
2646 * error_message_return
= _("constant generator source register found in %s");
2650 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2651 frag
= frag_more (2);
2652 where
= frag
- frag_now
->fr_literal
;
2653 bfd_putl16 ((bfd_vma
) bin
, frag
);
2658 if (error_message_return
!= NULL
)
2659 * error_message_return
= _("unexpected addressing mode for %s");
2664 #define NOP_CHECK_INTERRUPT (1 << 0)
2665 #define NOP_CHECK_CPU12 (1 << 1)
2666 #define NOP_CHECK_CPU19 (1 << 2)
2668 static signed int check_for_nop
= 0;
2670 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2672 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2673 For MOV insns, more sophisticated processing is needed to determine if they
2674 result in enabling/disabling interrupts. */
2675 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2676 || ((strcmp (OPCODE, "bic") == 0) \
2678 || ((strcmp (OPCODE, "clr") == 0) \
2681 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2682 || ((strcmp (OPCODE, "bis") == 0) \
2685 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2686 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2687 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2688 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2689 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2690 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2692 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2693 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2694 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2695 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2696 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2697 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2703 frag
= frag_more (2);
2704 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2705 dwarf2_emit_insn (2);
2708 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2711 warn_eint_nop (bfd_boolean prev_insn_is_nop
, bfd_boolean prev_insn_is_dint
)
2713 if (prev_insn_is_nop
2714 /* If the last insn was a DINT, we will have already warned that a NOP is
2715 required after it. */
2716 || prev_insn_is_dint
2717 /* 430 ISA does not require a NOP before EINT. */
2718 || (! target_is_430x ()))
2721 if (gen_interrupt_nops
)
2724 if (warn_interrupt_nops
)
2725 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2727 else if (warn_interrupt_nops
)
2728 as_warn (_(WARN_NOP_BEFORE_EINT
));
2731 /* Use when unsure what effect the insn will have on the interrupt status,
2732 to insert/warn about adding a NOP before the current insn. */
2735 warn_unsure_interrupt (bfd_boolean prev_insn_is_nop
,
2736 bfd_boolean prev_insn_is_dint
)
2738 if (prev_insn_is_nop
2739 /* If the last insn was a DINT, we will have already warned that a NOP is
2740 required after it. */
2741 || prev_insn_is_dint
2742 /* 430 ISA does not require a NOP before EINT or DINT. */
2743 || (! target_is_430x ()))
2746 if (gen_interrupt_nops
)
2749 if (warn_interrupt_nops
)
2750 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2752 else if (warn_interrupt_nops
)
2753 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2756 /* Parse instruction operands.
2757 Return binary opcode. */
2760 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2762 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2763 int insn_length
= 0;
2764 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2768 struct msp430_operand_s op1
, op2
;
2770 static short ZEROS
= 0;
2771 bfd_boolean byte_op
, imm_op
;
2774 int extended
= 0x1800;
2775 bfd_boolean extended_op
= FALSE
;
2776 bfd_boolean addr_op
;
2777 const char * error_message
;
2778 static signed int repeat_count
= 0;
2779 static bfd_boolean prev_insn_is_nop
= FALSE
;
2780 static bfd_boolean prev_insn_is_dint
= FALSE
;
2781 static bfd_boolean prev_insn_is_eint
= FALSE
;
2782 /* We might decide before the end of the function that the current insn is
2783 equivalent to DINT/EINT. */
2784 bfd_boolean this_insn_is_dint
= FALSE
;
2785 bfd_boolean this_insn_is_eint
= FALSE
;
2786 bfd_boolean fix_emitted
;
2788 /* Opcode is the one from opcodes table
2789 line contains something like
2798 bfd_boolean check
= FALSE
;
2801 switch (TOLOWER (* line
))
2804 /* Byte operation. */
2805 bin
|= BYTE_OPERATION
;
2811 /* "Address" ops work on 20-bit values. */
2813 bin
|= BYTE_OPERATION
;
2818 /* Word operation - this is the default. */
2826 as_warn (_("no size modifier after period, .w assumed"));
2830 as_bad (_("unrecognised instruction size modifier .%c"),
2842 if (*line
&& ! ISSPACE (*line
))
2844 as_bad (_("junk found after instruction: %s.%s"),
2845 opcode
->name
, line
);
2849 /* Catch the case where the programmer has used a ".a" size modifier on an
2850 instruction that does not support it. Look for an alternative extended
2851 instruction that has the same name without the period. Eg: "add.a"
2852 becomes "adda". Although this not an officially supported way of
2853 specifying instruction aliases other MSP430 assemblers allow it. So we
2854 support it for compatibility purposes. */
2855 if (addr_op
&& opcode
->fmt
>= 0)
2857 const char * old_name
= opcode
->name
;
2860 sprintf (real_name
, "%sa", old_name
);
2861 opcode
= hash_find (msp430_hash
, real_name
);
2864 as_bad (_("instruction %s.a does not exist"), old_name
);
2867 #if 0 /* Enable for debugging. */
2868 as_warn ("treating %s.a as %s", old_name
, real_name
);
2871 bin
= opcode
->bin_opcode
;
2874 if (opcode
->fmt
!= -1
2875 && opcode
->insn_opnumb
2876 && (!*line
|| *line
== '\n'))
2878 as_bad (ngettext ("instruction %s requires %d operand",
2879 "instruction %s requires %d operands",
2880 opcode
->insn_opnumb
),
2881 opcode
->name
, opcode
->insn_opnumb
);
2885 memset (l1
, 0, sizeof (l1
));
2886 memset (l2
, 0, sizeof (l2
));
2887 memset (&op1
, 0, sizeof (op1
));
2888 memset (&op2
, 0, sizeof (op2
));
2892 if ((fmt
= opcode
->fmt
) < 0)
2894 if (! target_is_430x ())
2896 as_bad (_("instruction %s requires MSP430X mcu"),
2907 /* If requested set the extended instruction repeat count. */
2910 if (repeat_count
> 0)
2911 extended
|= (repeat_count
- 1);
2913 extended
|= (1 << 7) | (- repeat_count
);
2916 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2921 /* The previous instruction set this flag if it wants to check if this insn
2925 if (! is_opcode ("nop"))
2929 switch (check_for_nop
& - check_for_nop
)
2931 case NOP_CHECK_INTERRUPT
:
2932 /* NOP_CHECK_INTERRUPT rules:
2933 1. 430 and 430x ISA require a NOP after DINT.
2934 2. Only the 430x ISA requires NOP before EINT (this has
2935 been dealt with in the previous call to this function).
2936 3. Only the 430x ISA requires NOP after every EINT.
2938 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2940 if (prev_insn_is_dint
)
2942 if (gen_interrupt_nops
)
2945 if (warn_interrupt_nops
)
2946 as_warn (_(INSERT_NOP_AFTER_DINT
));
2949 as_warn (_(WARN_NOP_AFTER_DINT
));
2951 else if (prev_insn_is_eint
)
2953 if (gen_interrupt_nops
)
2956 if (warn_interrupt_nops
)
2957 as_warn (_(INSERT_NOP_AFTER_EINT
));
2960 as_warn (_(WARN_NOP_AFTER_EINT
));
2962 /* If we get here it's because the last instruction was
2963 determined to either disable or enable interrupts, but
2964 we're not sure which.
2965 We have no information yet about what effect the
2966 current instruction has on interrupts, that has to be
2968 The last insn may have required a NOP after it, so we
2969 deal with that now. */
2972 if (gen_interrupt_nops
)
2975 if (warn_interrupt_nops
)
2976 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2979 /* warn_unsure_interrupt was called on the previous
2981 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
2986 case NOP_CHECK_CPU12
:
2987 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2988 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2990 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2994 case NOP_CHECK_CPU19
:
2995 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
2996 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
2998 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
3003 as_bad (_("internal error: unknown nop check state"));
3006 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
3008 while (check_for_nop
);
3017 switch (opcode
->insn_opnumb
)
3020 if (is_opcode ("eint"))
3021 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3023 /* Set/clear bits instructions. */
3027 extended
|= BYTE_OPERATION
;
3029 /* Emit the extension word. */
3031 frag
= frag_more (2);
3032 bfd_putl16 (extended
, frag
);
3036 frag
= frag_more (2);
3037 bfd_putl16 ((bfd_vma
) bin
, frag
);
3038 dwarf2_emit_insn (insn_length
);
3042 /* Something which works with destination operand. */
3043 line
= extract_operand (line
, l1
, sizeof (l1
));
3044 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
3048 bin
|= (op1
.reg
| (op1
.am
<< 7));
3050 /* If the PC is the destination... */
3051 if (op1
.am
== 0 && op1
.reg
== 0
3052 /* ... and the opcode alters the SR. */
3053 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3054 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3056 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3057 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3058 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3059 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3062 /* If the status register is the destination... */
3063 if (op1
.am
== 0 && op1
.reg
== 2
3064 /* ... and the opcode alters the SR. */
3065 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
3066 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
3067 || is_opcode ("sbc") || is_opcode ("sxt")
3068 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
3069 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
3070 || is_opcode ("sbcx")
3073 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3074 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3075 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3076 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3079 /* Compute the entire instruction length, in bytes. */
3080 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3081 insn_length
+= op_length
;
3082 frag
= frag_more (op_length
);
3083 where
= frag
- frag_now
->fr_literal
;
3088 extended
|= BYTE_OPERATION
;
3090 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3092 as_bad (_("repeat instruction used with non-register mode instruction"));
3096 if (op1
.mode
== OP_EXP
)
3098 if (op1
.exp
.X_op
== O_constant
)
3099 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3101 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3102 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3103 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3105 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3106 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3109 /* Emit the extension word. */
3110 bfd_putl16 (extended
, frag
);
3115 bfd_putl16 ((bfd_vma
) bin
, frag
);
3119 if (op1
.mode
== OP_EXP
)
3121 if (op1
.exp
.X_op
== O_constant
)
3123 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3127 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3132 fix_new_exp (frag_now
, where
, 2,
3133 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3135 fix_new_exp (frag_now
, where
, 2,
3136 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3141 dwarf2_emit_insn (insn_length
);
3145 /* Shift instruction. */
3146 line
= extract_operand (line
, l1
, sizeof (l1
));
3147 strncpy (l2
, l1
, sizeof (l2
));
3148 l2
[sizeof (l2
) - 1] = '\0';
3149 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3150 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3153 break; /* An error occurred. All warnings were done before. */
3155 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
3156 frag
= frag_more (insn_length
);
3157 where
= frag
- frag_now
->fr_literal
;
3159 if (target_is_430xv2 ()
3160 && op1
.mode
== OP_REG
3162 && (is_opcode ("rlax")
3163 || is_opcode ("rlcx")
3164 || is_opcode ("rla")
3165 || is_opcode ("rlc")))
3167 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3171 /* If the status register is the destination... */
3172 if (op1
.am
== 0 && op1
.reg
== 2
3173 /* ... and the opcode alters the SR. */
3174 && (is_opcode ("rla") || is_opcode ("rlc")
3175 || is_opcode ("rlax") || is_opcode ("rlcx")
3176 || is_opcode ("sxt") || is_opcode ("sxtx")
3177 || is_opcode ("swpb")
3180 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3181 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3182 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3183 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3189 extended
|= BYTE_OPERATION
;
3191 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3193 as_bad (_("repeat instruction used with non-register mode instruction"));
3197 if (op1
.mode
== OP_EXP
)
3199 if (op1
.exp
.X_op
== O_constant
)
3200 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3202 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3203 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3204 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3206 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3207 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3210 if (op2
.mode
== OP_EXP
)
3212 if (op2
.exp
.X_op
== O_constant
)
3213 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3215 else if (op1
.mode
== OP_EXP
)
3216 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3217 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3218 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3220 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3221 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3222 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3225 /* Emit the extension word. */
3226 bfd_putl16 (extended
, frag
);
3231 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3232 bfd_putl16 ((bfd_vma
) bin
, frag
);
3236 if (op1
.mode
== OP_EXP
)
3238 if (op1
.exp
.X_op
== O_constant
)
3240 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3244 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3248 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3249 fix_new_exp (frag_now
, where
, 2,
3250 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3252 fix_new_exp (frag_now
, where
, 2,
3253 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3260 if (op2
.mode
== OP_EXP
)
3262 if (op2
.exp
.X_op
== O_constant
)
3264 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3268 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3272 if (op2
.reg
) /* Not PC relative. */
3273 fix_new_exp (frag_now
, where
, 2,
3274 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3276 fix_new_exp (frag_now
, where
, 2,
3277 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3282 dwarf2_emit_insn (insn_length
);
3286 /* Branch instruction => mov dst, r0. */
3289 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3293 line
= extract_operand (line
, l1
, sizeof (l1
));
3294 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3300 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3301 op_length
= 2 + 2 * op1
.ol
;
3302 frag
= frag_more (op_length
);
3303 where
= frag
- frag_now
->fr_literal
;
3304 bfd_putl16 ((bfd_vma
) bin
, frag
);
3306 if (op1
.mode
== OP_EXP
)
3308 if (op1
.exp
.X_op
== O_constant
)
3310 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3316 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3318 if (op1
.reg
|| op1
.am
== 3)
3319 fix_new_exp (frag_now
, where
, 2,
3320 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3322 fix_new_exp (frag_now
, where
, 2,
3323 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3327 dwarf2_emit_insn (insn_length
+ op_length
);
3331 /* CALLA instructions. */
3332 fix_emitted
= FALSE
;
3334 line
= extract_operand (line
, l1
, sizeof (l1
));
3337 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3338 extended_op
, FALSE
);
3344 op_length
= 2 + 2 * op1
.ol
;
3345 frag
= frag_more (op_length
);
3346 where
= frag
- frag_now
->fr_literal
;
3354 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3355 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3358 else if (op1
.am
== 1)
3364 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3365 BFD_RELOC_MSP430X_PCR20_CALL
);
3369 bin
|= 0x50 | op1
.reg
;
3371 else if (op1
.am
== 0)
3372 bin
|= 0x40 | op1
.reg
;
3374 else if (op1
.am
== 1)
3378 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3379 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3382 else if (op1
.am
== 2)
3383 bin
|= 0x60 | op1
.reg
;
3384 else if (op1
.am
== 3)
3385 bin
|= 0x70 | op1
.reg
;
3387 bfd_putl16 ((bfd_vma
) bin
, frag
);
3389 if (op1
.mode
== OP_EXP
)
3393 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3397 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3400 fix_new_exp (frag_now
, where
+ 2, 2,
3401 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3404 dwarf2_emit_insn (insn_length
+ op_length
);
3412 /* [POP|PUSH]M[.A] #N, Rd */
3413 line
= extract_operand (line
, l1
, sizeof (l1
));
3414 line
= extract_operand (line
, l2
, sizeof (l2
));
3418 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3421 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3422 if (end
!= NULL
&& *end
!= 0)
3424 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3427 if (op1
.exp
.X_op
!= O_constant
)
3429 as_bad (_("expected constant expression as first argument of %s"),
3434 if ((reg
= check_reg (l2
)) == -1)
3436 as_bad (_("expected register as second argument of %s"),
3442 frag
= frag_more (op_length
);
3443 where
= frag
- frag_now
->fr_literal
;
3444 bin
= opcode
->bin_opcode
;
3447 n
= op1
.exp
.X_add_number
;
3448 bin
|= (n
- 1) << 4;
3449 if (is_opcode ("pushm"))
3453 if (reg
- n
+ 1 < 0)
3455 as_bad (_("Too many registers popped"));
3459 /* CPU21 errata: cannot use POPM to restore the SR register. */
3460 if (target_is_430xv2 ()
3461 && (reg
- n
+ 1 < 3)
3463 && is_opcode ("popm"))
3465 as_bad (_("Cannot use POPM to restore the SR register"));
3469 bin
|= (reg
- n
+ 1);
3472 bfd_putl16 ((bfd_vma
) bin
, frag
);
3473 dwarf2_emit_insn (op_length
);
3482 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3483 if (extended
& 0xff)
3485 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3489 line
= extract_operand (line
, l1
, sizeof (l1
));
3490 line
= extract_operand (line
, l2
, sizeof (l2
));
3494 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3497 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3498 if (end
!= NULL
&& *end
!= 0)
3500 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3503 if (op1
.exp
.X_op
!= O_constant
)
3505 as_bad (_("expected constant expression as first argument of %s"),
3509 n
= op1
.exp
.X_add_number
;
3512 as_bad (_("expected first argument of %s to be in the range 1-4"),
3517 if ((reg
= check_reg (l2
)) == -1)
3519 as_bad (_("expected register as second argument of %s"),
3524 if (target_is_430xv2 () && reg
== 0)
3526 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3531 frag
= frag_more (op_length
);
3532 where
= frag
- frag_now
->fr_literal
;
3534 bin
= opcode
->bin_opcode
;
3537 bin
|= (n
- 1) << 10;
3540 bfd_putl16 ((bfd_vma
) bin
, frag
);
3541 dwarf2_emit_insn (op_length
);
3547 bfd_boolean need_reloc
= FALSE
;
3551 /* ADDA, CMPA and SUBA address instructions. */
3552 if (extended
& 0xff)
3554 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3558 line
= extract_operand (line
, l1
, sizeof (l1
));
3559 line
= extract_operand (line
, l2
, sizeof (l2
));
3561 bin
= opcode
->bin_opcode
;
3565 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3566 if (end
!= NULL
&& *end
!= 0)
3568 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3572 if (op1
.exp
.X_op
== O_constant
)
3574 n
= op1
.exp
.X_add_number
;
3575 if (n
> 0xfffff || n
< - (0x7ffff))
3577 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3582 bin
|= ((n
>> 16) & 0xf) << 8;
3594 if ((n
= check_reg (l1
)) == -1)
3596 as_bad (_("expected register name or constant as first argument of %s"),
3601 bin
|= (n
<< 8) | (1 << 6);
3605 if ((reg
= check_reg (l2
)) == -1)
3607 as_bad (_("expected register as second argument of %s"),
3612 frag
= frag_more (op_length
);
3613 where
= frag
- frag_now
->fr_literal
;
3616 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3617 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3619 bfd_putl16 ((bfd_vma
) bin
, frag
);
3621 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3622 dwarf2_emit_insn (op_length
);
3626 case 9: /* MOVA, BRA, RETA. */
3628 bin
= opcode
->bin_opcode
;
3630 if (is_opcode ("reta"))
3632 /* The RETA instruction does not take any arguments.
3633 The implicit first argument is @SP+.
3634 The implicit second argument is PC. */
3644 line
= extract_operand (line
, l1
, sizeof (l1
));
3645 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3646 &imm_op
, extended_op
, FALSE
);
3648 if (is_opcode ("bra"))
3650 /* This is the BRA synthetic instruction.
3651 The second argument is always PC. */
3657 line
= extract_operand (line
, l2
, sizeof (l2
));
3658 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3663 break; /* Error occurred. All warnings were done before. */
3666 /* Only a restricted subset of the normal MSP430 addressing modes
3667 are supported here, so check for the ones that are allowed. */
3668 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3669 & error_message
)) == 0)
3671 as_bad (error_message
, opcode
->name
);
3674 dwarf2_emit_insn (op_length
);
3678 line
= extract_operand (line
, l1
, sizeof l1
);
3679 /* The RPT instruction only accepted immediates and registers. */
3682 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3683 if (end
!= NULL
&& *end
!= 0)
3685 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3688 if (op1
.exp
.X_op
!= O_constant
)
3690 as_bad (_("expected constant value as argument to RPT"));
3693 if (op1
.exp
.X_add_number
< 1
3694 || op1
.exp
.X_add_number
> (1 << 4))
3696 as_bad (_("expected constant in the range 2..16"));
3700 /* We silently accept and ignore a repeat count of 1. */
3701 if (op1
.exp
.X_add_number
> 1)
3702 repeat_count
= op1
.exp
.X_add_number
;
3708 if ((reg
= check_reg (l1
)) != -1)
3711 as_warn (_("PC used as an argument to RPT"));
3713 repeat_count
= - reg
;
3717 as_bad (_("expected constant or register name as argument to RPT insn"));
3724 as_bad (_("Illegal emulated instruction"));
3729 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3730 From f5 ref man 6.3.3:
3731 The 16-bit Status Register (SR, also called R2), used as a source or
3732 destination register, can only be used in register mode addressed
3733 with word instructions. */
3735 case 1: /* Format 1, double operand. */
3736 line
= extract_operand (line
, l1
, sizeof (l1
));
3737 line
= extract_operand (line
, l2
, sizeof (l2
));
3738 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3739 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3742 break; /* Error occurred. All warnings were done before. */
3745 && is_opcode ("movx")
3747 && msp430_enable_relax
)
3749 /* This is the MOVX.A instruction. See if we can convert
3750 it into the MOVA instruction instead. This saves 2 bytes. */
3751 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3754 dwarf2_emit_insn (op_length
);
3759 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3761 /* If the PC is the destination... */
3762 if (op2
.am
== 0 && op2
.reg
== 0
3763 /* ... and the opcode alters the SR. */
3764 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3765 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3767 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3768 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3769 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3770 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3773 /* If the status register is the destination... */
3774 if (op2
.am
== 0 && op2
.reg
== 2
3775 /* ... and the opcode alters the SR. */
3776 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3777 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3778 || is_opcode ("xor")
3779 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3780 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3781 || is_opcode ("xorx")
3784 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3785 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3786 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3787 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3790 /* Chain these checks for SR manipulations so we can warn if they are not
3792 if (((is_opcode ("bis") && bin
== 0xd032)
3793 || (is_opcode ("mov") && bin
== 0x4032)
3794 || (is_opcode ("xor") && bin
== 0xe032))
3795 && op1
.mode
== OP_EXP
3796 && op1
.exp
.X_op
== O_constant
3797 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3798 check_for_nop
|= NOP_CHECK_CPU19
;
3799 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3801 /* Any MOV with the SR as the destination either enables or disables
3803 if (op1
.mode
== OP_EXP
3804 && op1
.exp
.X_op
== O_constant
)
3806 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3808 /* The GIE bit is being set. */
3809 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3810 this_insn_is_eint
= TRUE
;
3813 /* The GIE bit is being cleared. */
3814 this_insn_is_dint
= TRUE
;
3816 /* If an immediate value which is covered by the constant generator
3817 is the src, then op1 will have been changed to either R2 or R3 by
3819 The only constants covered by CG1 and CG2, which have bit 3 set
3820 and therefore would enable interrupts when writing to the SR, are
3821 R2 with addresing mode 0b11 and R3 with 0b11.
3822 The addressing mode is in bits 5:4 of the binary opcode. */
3823 else if (op1
.mode
== OP_REG
3824 && (op1
.reg
== 2 || op1
.reg
== 3)
3825 && (bin
& 0x30) == 0x30)
3827 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3828 this_insn_is_eint
= TRUE
;
3830 /* Any other use of the constant generator with destination R2, will
3831 disable interrupts. */
3832 else if (op1
.mode
== OP_REG
3833 && (op1
.reg
== 2 || op1
.reg
== 3))
3834 this_insn_is_dint
= TRUE
;
3835 else if (do_unknown_interrupt_nops
)
3837 /* FIXME: Couldn't work out whether the insn is enabling or
3838 disabling interrupts, so for safety need to treat it as both
3840 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3841 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3844 else if (is_eint (opcode
->name
, bin
))
3845 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3846 else if ((bin
& 0x32) == 0x32)
3848 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3849 * an interrupt state change if a write happens. */
3850 /* FIXME: How strict to be here? */
3854 /* Compute the entire length of the instruction in bytes. */
3855 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3856 + 2 /* The opcode */
3857 + (2 * op1
.ol
) /* The first operand. */
3858 + (2 * op2
.ol
); /* The second operand. */
3860 insn_length
+= op_length
;
3861 frag
= frag_more (op_length
);
3862 where
= frag
- frag_now
->fr_literal
;
3867 extended
|= BYTE_OPERATION
;
3869 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3871 as_bad (_("repeat instruction used with non-register mode instruction"));
3875 /* If necessary, emit a reloc to update the extension word. */
3876 if (op1
.mode
== OP_EXP
)
3878 if (op1
.exp
.X_op
== O_constant
)
3879 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3881 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3882 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3883 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3885 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3886 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3889 if (op2
.mode
== OP_EXP
)
3891 if (op2
.exp
.X_op
== O_constant
)
3892 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3894 else if (op1
.mode
== OP_EXP
)
3895 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3896 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3897 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3900 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3901 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3902 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3905 /* Emit the extension word. */
3906 bfd_putl16 (extended
, frag
);
3911 bfd_putl16 ((bfd_vma
) bin
, frag
);
3915 if (op1
.mode
== OP_EXP
)
3917 if (op1
.exp
.X_op
== O_constant
)
3919 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3923 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3927 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3928 fix_new_exp (frag_now
, where
, 2,
3929 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3931 fix_new_exp (frag_now
, where
, 2,
3932 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3940 if (op2
.mode
== OP_EXP
)
3942 if (op2
.exp
.X_op
== O_constant
)
3944 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3948 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3952 if (op2
.reg
) /* Not PC relative. */
3953 fix_new_exp (frag_now
, where
, 2,
3954 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3956 fix_new_exp (frag_now
, where
, 2,
3957 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3962 dwarf2_emit_insn (insn_length
);
3964 /* If the PC is the destination... */
3965 if (op2
.am
== 0 && op2
.reg
== 0
3966 /* ... but the opcode does not alter the destination. */
3967 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3968 check_for_nop
|= NOP_CHECK_CPU12
;
3971 case 2: /* Single-operand mostly instr. */
3972 if (opcode
->insn_opnumb
== 0)
3974 /* reti instruction. */
3976 frag
= frag_more (2);
3977 bfd_putl16 ((bfd_vma
) bin
, frag
);
3978 dwarf2_emit_insn (insn_length
);
3982 line
= extract_operand (line
, l1
, sizeof (l1
));
3983 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3984 &imm_op
, extended_op
, TRUE
);
3986 break; /* Error in operand. */
3988 if (target_is_430xv2 ()
3989 && op1
.mode
== OP_REG
3991 && (is_opcode ("rrax")
3992 || is_opcode ("rrcx")
3993 || is_opcode ("rra")
3994 || is_opcode ("rrc")))
3996 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
4000 /* If the status register is the destination... */
4001 if (op1
.am
== 0 && op1
.reg
== 2
4002 /* ... and the opcode alters the SR. */
4003 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
4005 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
4006 as_bad (_("CPU13: SR is destination of SR altering instruction"));
4007 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
4008 as_warn (_("CPU13: SR is destination of SR altering instruction"));
4011 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
4012 frag
= frag_more (insn_length
);
4013 where
= frag
- frag_now
->fr_literal
;
4017 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
4019 /* These two instructions use a special
4020 encoding of the A/L and B/W bits. */
4021 bin
&= ~ BYTE_OPERATION
;
4025 as_bad (_("%s instruction does not accept a .b suffix"),
4030 extended
|= BYTE_OPERATION
;
4033 extended
|= BYTE_OPERATION
;
4035 if (is_opcode ("rrux"))
4036 extended
|= IGNORE_CARRY_BIT
;
4038 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
4040 as_bad (_("repeat instruction used with non-register mode instruction"));
4044 if (op1
.mode
== OP_EXP
)
4046 if (op1
.exp
.X_op
== O_constant
)
4047 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
4049 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4050 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4051 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
4053 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4054 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
4057 /* Emit the extension word. */
4058 bfd_putl16 (extended
, frag
);
4063 bin
|= op1
.reg
| (op1
.am
<< 4);
4064 bfd_putl16 ((bfd_vma
) bin
, frag
);
4068 if (op1
.mode
== OP_EXP
)
4070 if (op1
.exp
.X_op
== O_constant
)
4072 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
4076 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
4080 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4081 fix_new_exp (frag_now
, where
, 2,
4082 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
4084 fix_new_exp (frag_now
, where
, 2,
4085 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
4090 dwarf2_emit_insn (insn_length
);
4093 case 3: /* Conditional jumps instructions. */
4094 line
= extract_operand (line
, l1
, sizeof (l1
));
4095 /* l1 is a label. */
4104 end
= parse_exp (m
, &exp
);
4105 if (end
!= NULL
&& *end
!= 0)
4107 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4111 /* In order to handle something like:
4115 jz 4 ; skip next 4 bytes
4118 nop ; will jump here if r5 positive or zero
4120 jCOND -n ;assumes jump n bytes backward:
4130 jCOND $n ; jump from PC in either direction. */
4132 if (exp
.X_op
== O_constant
)
4134 int x
= exp
.X_add_number
;
4138 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
4142 if ((*l1
== '$' && x
> 0) || x
< 0)
4147 if (x
> 512 || x
< -511)
4149 as_bad (_("Wrong displacement %d"), x
<< 1);
4154 frag
= frag_more (2); /* Instr size is 1 word. */
4157 bfd_putl16 ((bfd_vma
) bin
, frag
);
4159 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4162 frag
= frag_more (2); /* Instr size is 1 word. */
4163 where
= frag
- frag_now
->fr_literal
;
4164 fix_new_exp (frag_now
, where
, 2,
4165 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
4167 bfd_putl16 ((bfd_vma
) bin
, frag
);
4169 else if (*l1
== '$')
4171 as_bad (_("instruction requires label sans '$'"));
4175 ("instruction requires label or value in range -511:512"));
4176 dwarf2_emit_insn (insn_length
);
4181 as_bad (_("instruction requires label"));
4186 case 4: /* Extended jumps. */
4187 if (!msp430_enable_polys
)
4189 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4193 line
= extract_operand (line
, l1
, sizeof (l1
));
4199 /* Ignore absolute addressing. make it PC relative anyway. */
4200 if (*m
== '#' || *m
== '$')
4203 end
= parse_exp (m
, & exp
);
4204 if (end
!= NULL
&& *end
!= 0)
4206 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4209 if (exp
.X_op
== O_symbol
)
4211 /* Relaxation required. */
4212 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4214 if (target_is_430x ())
4215 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4217 /* The parameter to dwarf2_emit_insn is actually the offset to
4218 the start of the insn from the fix piece of instruction that
4219 was emitted. Since next fragments may have variable size we
4220 tie debug info to the beginning of the instruction. */
4222 frag
= frag_more (8);
4223 dwarf2_emit_insn (0);
4224 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4225 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4227 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4229 0, /* Offset is zero if jump dist less than 1K. */
4235 as_bad (_("instruction requires label"));
4238 case 5: /* Emulated extended branches. */
4239 if (!msp430_enable_polys
)
4241 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4244 line
= extract_operand (line
, l1
, sizeof (l1
));
4250 /* Ignore absolute addressing. make it PC relative anyway. */
4251 if (*m
== '#' || *m
== '$')
4254 end
= parse_exp (m
, & exp
);
4255 if (end
!= NULL
&& *end
!= 0)
4257 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4260 if (exp
.X_op
== O_symbol
)
4262 /* Relaxation required. */
4263 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4265 if (target_is_430x ())
4266 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4269 frag
= frag_more (8);
4270 dwarf2_emit_insn (0);
4271 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4272 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4274 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4275 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4277 0, /* Offset is zero if jump dist less than 1K. */
4283 as_bad (_("instruction requires label"));
4287 as_bad (_("Illegal instruction or not implemented opcode."));
4290 if (is_opcode ("nop"))
4292 prev_insn_is_nop
= TRUE
;
4293 prev_insn_is_dint
= FALSE
;
4294 prev_insn_is_eint
= FALSE
;
4296 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4298 prev_insn_is_dint
= TRUE
;
4299 prev_insn_is_eint
= FALSE
;
4300 prev_insn_is_nop
= FALSE
;
4301 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4303 /* NOP is not needed after EINT for 430 ISA. */
4304 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4306 prev_insn_is_eint
= TRUE
;
4307 prev_insn_is_nop
= FALSE
;
4308 prev_insn_is_dint
= FALSE
;
4309 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4313 prev_insn_is_nop
= FALSE
;
4314 prev_insn_is_dint
= FALSE
;
4315 prev_insn_is_eint
= FALSE
;
4318 input_line_pointer
= line
;
4323 md_assemble (char * str
)
4325 struct msp430_opcode_s
* opcode
;
4329 str
= skip_space (str
); /* Skip leading spaces. */
4330 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4334 char a
= TOLOWER (cmd
[i
]);
4341 as_bad (_("can't find opcode"));
4345 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
4349 as_bad (_("unknown opcode `%s'"), cmd
);
4354 char *__t
= input_line_pointer
;
4356 msp430_operands (opcode
, str
);
4357 input_line_pointer
= __t
;
4361 /* GAS will call this function for each section at the end of the assembly,
4362 to permit the CPU backend to adjust the alignment of a section. */
4365 md_section_align (asection
* seg
, valueT addr
)
4367 int align
= bfd_section_alignment (seg
);
4369 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4372 /* If you define this macro, it should return the offset between the
4373 address of a PC relative fixup and the position from which the PC
4374 relative adjustment should be made. On many processors, the base
4375 of a PC relative instruction is the next instruction, so this
4376 macro would return the length of an instruction. */
4379 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4381 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4382 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4383 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4386 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4389 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4390 Now it handles the situation when relocations
4391 have to be passed to linker. */
4393 msp430_force_relocation_local (fixS
*fixp
)
4395 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4399 if (msp430_enable_polys
4400 && !msp430_enable_relax
)
4407 /* GAS will call this for each fixup. It should store the correct
4408 value in the object file. */
4410 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4412 unsigned char * where
;
4416 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4421 else if (fixp
->fx_pcrel
)
4423 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4425 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4427 /* FIXME: We can appear here only in case if we perform a pc
4428 relative jump to the label which is i) global, ii) locally
4429 defined or this is a jump to an absolute symbol.
4430 If this is an absolute symbol -- everything is OK.
4431 If this is a global label, we've got a symbol value defined
4433 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4434 from this section start
4435 2. *valuep will contain the real offset from jump insn to the
4437 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4438 will be incorrect. Therefore remove s_get_value. */
4439 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4447 value
= fixp
->fx_offset
;
4449 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4451 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4453 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4459 fixp
->fx_no_overflow
= 1;
4461 /* If polymorphs are enabled and relax disabled.
4462 do not kill any relocs and pass them to linker. */
4463 if (msp430_enable_polys
4464 && !msp430_enable_relax
)
4467 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4468 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4475 /* Fetch the instruction, insert the fully resolved operand
4476 value, and stuff the instruction back again. */
4477 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4479 insn
= bfd_getl16 (where
);
4481 switch (fixp
->fx_r_type
)
4483 case BFD_RELOC_MSP430_10_PCREL
:
4485 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4486 _("odd address operand: %ld"), value
);
4488 /* Jumps are in words. */
4490 --value
; /* Correct PC. */
4492 if (value
< -512 || value
> 511)
4493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4494 _("operand out of range: %ld"), value
);
4496 value
&= 0x3ff; /* get rid of extended sign */
4497 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4500 case BFD_RELOC_MSP430X_PCR16
:
4501 case BFD_RELOC_MSP430_RL_PCREL
:
4502 case BFD_RELOC_MSP430_16_PCREL
:
4504 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4505 _("odd address operand: %ld"), value
);
4508 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4509 /* Nothing to be corrected here. */
4510 if (value
< -32768 || value
> 65536)
4511 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4512 _("operand out of range: %ld"), value
);
4515 case BFD_RELOC_MSP430X_ABS16
:
4516 case BFD_RELOC_MSP430_16
:
4518 case BFD_RELOC_MSP430_16_BYTE
:
4519 value
&= 0xffff; /* Get rid of extended sign. */
4520 bfd_putl16 ((bfd_vma
) value
, where
);
4523 case BFD_RELOC_MSP430_ABS_HI16
:
4525 value
&= 0xffff; /* Get rid of extended sign. */
4526 bfd_putl16 ((bfd_vma
) value
, where
);
4530 bfd_putl16 ((bfd_vma
) value
, where
);
4533 case BFD_RELOC_MSP430_ABS8
:
4535 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4538 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4539 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4540 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4542 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4545 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4546 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4548 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4551 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4552 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4554 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4557 case BFD_RELOC_MSP430X_PCR20_CALL
:
4558 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4560 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4563 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4564 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4565 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4567 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4570 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4571 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4573 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4576 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4577 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4579 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4583 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4584 fixp
->fx_line
, fixp
->fx_r_type
);
4590 fixp
->fx_addnumber
= value
;
4595 S_IS_GAS_LOCAL (symbolS
* s
)
4602 name
= S_GET_NAME (s
);
4603 len
= strlen (name
) - 1;
4605 return name
[len
] == 1 || name
[len
] == 2;
4608 /* GAS will call this to generate a reloc, passing the resulting reloc
4609 to `bfd_install_relocation'. This currently works poorly, as
4610 `bfd_install_relocation' often does the wrong thing, and instances of
4611 `tc_gen_reloc' have been written to work around the problems, which
4612 in turns makes it difficult to fix `bfd_install_relocation'. */
4614 /* If while processing a fixup, a reloc really needs to be created
4615 then it is done here. */
4618 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4620 static arelent
* no_relocs
= NULL
;
4621 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4624 reloc
= XNEW (arelent
);
4625 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4626 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4628 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4630 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4631 _("reloc %d not supported by object file format"),
4632 (int) fixp
->fx_r_type
);
4641 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4643 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4644 fixp
->fx_subsy
= NULL
;
4647 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4649 asection
*asec
, *ssec
;
4651 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4652 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4654 /* If we have a difference between two different, non-absolute symbols
4655 we must generate two relocs (one for each symbol) and allow the
4656 linker to resolve them - relaxation may change the distances between
4657 symbols, even local symbols defined in the same section.
4659 Unfortunately we cannot do this with assembler generated local labels
4660 because there can be multiple incarnations of the same label, with
4661 exactly the same name, in any given section and the linker will have
4662 no way to identify the correct one. Instead we just have to hope
4663 that no relaxation will occur between the local label and the other
4664 symbol in the expression.
4666 Similarly we have to compute differences between symbols in the .eh_frame
4667 section as the linker is not smart enough to apply relocations there
4668 before attempting to process it. */
4669 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4670 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4671 && strcmp (ssec
->name
, ".eh_frame") != 0
4672 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4673 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4675 arelent
* reloc2
= XNEW (arelent
);
4680 reloc2
->address
= reloc
->address
;
4681 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4682 BFD_RELOC_MSP430_SYM_DIFF
);
4683 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4685 if (ssec
== absolute_section
)
4686 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4689 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4690 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4693 reloc
->addend
= fixp
->fx_offset
;
4694 if (asec
== absolute_section
)
4696 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4697 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4701 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4702 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4711 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4713 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4714 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4716 switch (fixp
->fx_r_type
)
4719 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4723 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4727 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4731 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4736 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4747 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4748 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4750 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4751 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4753 md_number_to_chars (fixpos
, amount
, 2);
4758 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4759 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4760 reloc
->addend
= fixp
->fx_offset
;
4762 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4763 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4764 reloc
->address
= fixp
->fx_offset
;
4771 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4772 asection
* segment_type ATTRIBUTE_UNUSED
)
4774 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4776 /* This is a jump -> pcrel mode. Nothing to do much here.
4777 Return value == 2. */
4779 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4781 else if (fragP
->fr_symbol
)
4783 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4784 an absolute segment, we don't know a displacement until we link
4785 object files. So it will always be long. This also applies to
4786 labels in a subsegment of current. Liker may relax it to short
4787 jump later. Return value == 8. */
4789 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4793 /* We know the abs value. may be it is a jump to fixed address.
4794 Impossible in our case, cause all constants already handled. */
4796 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4799 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4803 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4804 asection
* sec ATTRIBUTE_UNUSED
,
4810 struct rcodes_s
* cc
= NULL
;
4811 struct hcodes_s
* hc
= NULL
;
4813 switch (fragP
->fr_subtype
)
4815 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4816 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4817 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4818 /* We do not have to convert anything here.
4819 Just apply a fix. */
4820 rela
= BFD_RELOC_MSP430_10_PCREL
;
4823 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4824 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4825 /* Convert uncond branch jmp lab -> br lab. */
4826 if (target_is_430x ())
4827 cc
= msp430x_rcodes
+ 7;
4829 cc
= msp430_rcodes
+ 7;
4830 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4831 bfd_putl16 (cc
->lop0
, where
);
4832 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4836 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4837 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4839 /* Other simple branches. */
4840 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4843 /* Find actual instruction. */
4844 if (target_is_430x ())
4846 for (i
= 0; i
< 7 && !cc
; i
++)
4847 if (msp430x_rcodes
[i
].sop
== insn
)
4848 cc
= msp430x_rcodes
+ i
;
4852 for (i
= 0; i
< 7 && !cc
; i
++)
4853 if (msp430_rcodes
[i
].sop
== insn
)
4854 cc
= & msp430_rcodes
[i
];
4857 if (!cc
|| !cc
->name
)
4858 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4859 __FUNCTION__
, (long) insn
);
4860 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4861 bfd_putl16 (cc
->lop0
, where
);
4862 bfd_putl16 (cc
->lop1
, where
+ 2);
4863 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4868 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4869 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4870 if (target_is_430x ())
4871 cc
= msp430x_rcodes
+ 6;
4873 cc
= msp430_rcodes
+ 6;
4874 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4875 bfd_putl16 (cc
->lop0
, where
);
4876 bfd_putl16 (cc
->lop1
, where
+ 2);
4877 bfd_putl16 (cc
->lop2
, where
+ 4);
4878 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4882 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4884 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4887 if (target_is_430x ())
4889 for (i
= 0; i
< 4 && !hc
; i
++)
4890 if (msp430x_hcodes
[i
].op1
== insn
)
4891 hc
= msp430x_hcodes
+ i
;
4895 for (i
= 0; i
< 4 && !hc
; i
++)
4896 if (msp430_hcodes
[i
].op1
== insn
)
4897 hc
= &msp430_hcodes
[i
];
4899 if (!hc
|| !hc
->name
)
4900 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4901 __FUNCTION__
, (long) insn
);
4902 rela
= BFD_RELOC_MSP430_10_PCREL
;
4903 /* Apply a fix for a first label if necessary.
4904 another fix will be applied to the next word of insn anyway. */
4906 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4907 fragP
->fr_offset
, TRUE
, rela
);
4913 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4914 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4916 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4919 if (target_is_430x ())
4921 for (i
= 0; i
< 4 && !hc
; i
++)
4922 if (msp430x_hcodes
[i
].op1
== insn
)
4923 hc
= msp430x_hcodes
+ i
;
4927 for (i
= 0; i
< 4 && !hc
; i
++)
4928 if (msp430_hcodes
[i
].op1
== insn
)
4929 hc
= & msp430_hcodes
[i
];
4931 if (!hc
|| !hc
->name
)
4932 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4933 __FUNCTION__
, (long) insn
);
4934 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4935 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4936 bfd_putl16 (hc
->lop0
, where
);
4937 bfd_putl16 (hc
->lop1
, where
+ 2);
4938 bfd_putl16 (hc
->lop2
, where
+ 4);
4944 as_fatal (_("internal inconsistency problem in %s: %lx"),
4945 __FUNCTION__
, (long) fragP
->fr_subtype
);
4949 /* Now apply fix. */
4950 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4951 fragP
->fr_offset
, TRUE
, rela
);
4952 /* Just fixed 2 bytes. */
4956 /* Relax fragment. Mostly stolen from hc11 and mcore
4957 which arches I think I know. */
4960 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4961 long stretch ATTRIBUTE_UNUSED
)
4966 const relax_typeS
*this_type
;
4967 const relax_typeS
*start_type
;
4968 relax_substateT next_state
;
4969 relax_substateT this_state
;
4970 const relax_typeS
*table
= md_relax_table
;
4972 /* Nothing to be done if the frag has already max size. */
4973 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4974 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4977 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4979 symbolP
= fragP
->fr_symbol
;
4980 if (symbol_resolved_p (symbolP
))
4981 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4983 /* We know the offset. calculate a distance. */
4984 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4987 if (!msp430_enable_relax
)
4989 /* Relaxation is not enabled. So, make all jump as long ones
4990 by setting 'aim' to quite high value. */
4994 this_state
= fragP
->fr_subtype
;
4995 start_type
= this_type
= table
+ this_state
;
4999 /* Look backwards. */
5000 for (next_state
= this_type
->rlx_more
; next_state
;)
5001 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
5005 /* Grow to next state. */
5006 this_state
= next_state
;
5007 this_type
= table
+ this_state
;
5008 next_state
= this_type
->rlx_more
;
5013 /* Look forwards. */
5014 for (next_state
= this_type
->rlx_more
; next_state
;)
5015 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
5019 /* Grow to next state. */
5020 this_state
= next_state
;
5021 this_type
= table
+ this_state
;
5022 next_state
= this_type
->rlx_more
;
5026 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5028 fragP
->fr_subtype
= this_state
;
5032 /* Return FALSE if the fixup in fixp should be left alone and not
5033 adjusted. We return FALSE here so that linker relaxation will
5037 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
5039 /* If the symbol is in a non-code section then it should be OK. */
5041 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
5047 /* Set the contents of the .MSP430.attributes and .GNU.attributes sections. */
5050 msp430_md_end (void)
5054 if (gen_interrupt_nops
)
5057 if (warn_interrupt_nops
)
5058 as_warn (INSERT_NOP_AT_EOF
);
5060 else if (warn_interrupt_nops
)
5061 as_warn (_(WARN_NOP_AT_EOF
));
5064 /* We have already emitted an error if any of the following attributes
5065 disagree with the attributes in the input assembly file. See
5066 msp430_object_attribute. */
5067 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
5068 target_is_430x () ? OFBA_MSPABI_Val_ISA_MSP430X
5069 : OFBA_MSPABI_Val_ISA_MSP430
);
5071 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
5072 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5073 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5075 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
5076 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5077 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5079 /* The data region GNU attribute is ignored for the small memory model. */
5081 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_GNU
,
5082 Tag_GNU_MSP430_Data_Region
, lower_data_region_only
5083 ? Val_GNU_MSP430_Data_Region_Lower
5084 : Val_GNU_MSP430_Data_Region_Any
);
5087 /* Returns FALSE if there is a msp430 specific reason why the
5088 subtraction of two same-section symbols cannot be computed by
5092 msp430_allow_local_subtract (expressionS
* left
,
5093 expressionS
* right
,
5096 /* If the symbols are not in a code section then they are OK. */
5097 if ((section
->flags
& SEC_CODE
) == 0)
5100 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
5103 if (left
->X_add_symbol
== right
->X_add_symbol
)
5106 /* We have to assume that there may be instructions between the
5107 two symbols and that relaxation may increase the distance between