1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 #include "opcode/msp430.h"
27 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
29 #include "elf/msp430.h"
30 #include "libiberty.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
106 int index
; /* Corresponding insn_opnumb. */
107 int sop
; /* Opcode if jump length is short. */
108 long lpos
; /* Label position. */
109 long lop0
; /* Opcode 1 _word_ (16 bits). */
110 long lop1
; /* Opcode second word. */
111 long lop2
; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes
[] =
119 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
131 #define MSP430_RLC(n,i,sop,o1) \
132 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
134 static struct rcodes_s msp430x_rcodes
[] =
136 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
137 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
138 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
139 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
140 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
141 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
142 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
143 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
148 /* More difficult than above and they have format 5.
151 =================================================================
152 gt > jeq +2; jge label jeq +6; jl +4; br label
153 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
154 leu <= jeq label; jlo label jeq +2; jhs +4; br label
155 le <= jeq label; jl label jeq +2; jge +4; br label
156 ================================================================= */
161 int index
; /* Corresponding insn_opnumb. */
162 int tlab
; /* Number of labels in short mode. */
163 int op0
; /* Opcode for first word of short jump. */
164 int op1
; /* Opcode for second word of short jump. */
165 int lop0
; /* Opcodes for long jump mode. */
170 static struct hcodes_s msp430_hcodes
[] =
172 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
173 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
174 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
175 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 static struct hcodes_s msp430x_hcodes
[] =
181 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
182 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
183 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
184 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 const char comment_chars
[] = ";";
189 const char line_comment_chars
[] = "#";
190 const char line_separator_chars
[] = "{";
191 const char EXP_CHARS
[] = "eE";
192 const char FLT_CHARS
[] = "dD";
194 /* Handle long expressions. */
195 extern LITTLENUM_TYPE generic_bignum
[];
197 static htab_t msp430_hash
;
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
212 #define STATE_BITS10 1 /* Wild guess. short jump. */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */
214 #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table
[] =
229 /* Unconditional jump. */
231 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
232 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
233 {1, 1, CUBL
, 0}, /* state undef */
235 /* Simple branches. */
237 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
238 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
241 /* blt no overflow branch. */
243 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
244 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
247 /* Emulated branches. */
249 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
250 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
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, for 430 (!extended_op) instructions
280 For the 430X we generate a 430 relocation only for the case where part of an
281 expression is being extracted (e.g. #hi(EXP), #lo(EXP). Otherwise generate
283 For the 430 we generate a relocation without assembler range checking
284 if we are handling an immediate value or a byte-width instruction. */
286 #undef CHECK_RELOC_MSP430
287 #define CHECK_RELOC_MSP430(OP) \
289 ? ((OP).expp == MSP_EXPP_ALL \
290 ? BFD_RELOC_MSP430X_ABS16 \
291 : ((OP).vshift == 1 \
292 ? BFD_RELOC_MSP430_ABS_HI16 : BFD_RELOC_16)) \
293 : ((imm_op || byte_op) \
294 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
296 /* Generate a 16-bit pc-relative relocation.
297 For the 430X we generate a relocation without linker range checking.
298 For the 430 we generate a relocation without assembler range checking
299 if we are handling an immediate value or a byte-width instruction. */
300 #undef CHECK_RELOC_MSP430_PCREL
301 #define CHECK_RELOC_MSP430_PCREL \
303 ? BFD_RELOC_MSP430X_PCR16 \
304 : (imm_op || byte_op) \
305 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
307 /* Profiling capability:
308 It is a performance hit to use gcc's profiling approach for this tiny target.
309 Even more -- jtag hardware facility does not perform any profiling functions.
310 However we've got gdb's built-in simulator where we can do anything.
311 Therefore my suggestion is:
313 We define new section ".profiler" which holds all profiling information.
314 We define new pseudo operation .profiler which will instruct assembler to
315 add new profile entry to the object file. Profile should take place at the
320 .profiler flags,function_to_profile [, cycle_corrector, extra]
322 where 'flags' is a combination of the following chars:
325 i - function is in Init section
326 f - function is in Fini section
328 c - libC standard call
329 d - stack value Demand (saved at run-time in simulator)
330 I - Interrupt service routine
335 j - long Jump/ sjlj unwind
336 a - an Arbitrary code fragment
337 t - exTra parameter saved (constant value like frame size)
338 '""' optional: "sil" == sil
340 function_to_profile - function's address
341 cycle_corrector - a value which should be added to the cycle
342 counter, zero if omitted
343 extra - some extra parameter, zero if omitted.
346 ------------------------------
350 .LFrameOffset_fxx=0x08
351 .profiler "scdP", fxx ; function entry.
352 ; we also demand stack value to be displayed
357 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
358 ; (this is a prologue end)
359 ; note, that spare var filled with the frame size
362 .profiler cdE,fxx ; check stack
367 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
368 ret ; cause 'ret' insn takes 3 cycles
369 -------------------------------
371 This profiling approach does not produce any overhead and
373 So, even profiled code can be uploaded to the MCU. */
374 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
375 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
376 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
377 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
378 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
379 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
380 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
381 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
382 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
383 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
384 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
385 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
386 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
387 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
388 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
389 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
402 for (; x
; x
= x
>> 1)
409 /* Parse ordinary expression. */
412 parse_exp (char * s
, expressionS
* op
)
414 input_line_pointer
= s
;
416 if (op
->X_op
== O_absent
)
417 as_bad (_("missing operand"));
419 /* 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);
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_DATA_REGION 'r'
689 static bfd_boolean upper_data_region_in_use
= FALSE
;
690 /* The default is to use the lower region only. */
691 static bfd_boolean lower_data_region_only
= TRUE
;
695 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
696 OPTION_SILICON_ERRATA_WARN
,
699 static unsigned int silicon_errata_fix
= 0;
700 static unsigned int silicon_errata_warn
= 0;
701 #define SILICON_ERRATA_CPU4 (1 << 0)
702 #define SILICON_ERRATA_CPU8 (1 << 1)
703 #define SILICON_ERRATA_CPU11 (1 << 2)
704 #define SILICON_ERRATA_CPU12 (1 << 3)
705 #define SILICON_ERRATA_CPU13 (1 << 4)
706 #define SILICON_ERRATA_CPU19 (1 << 5)
709 msp430_set_arch (int option
)
711 char str
[32]; /* 32 for good measure. */
713 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
715 md_parse_option (option
, str
);
716 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
717 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
720 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
721 Keep these two structures in sync.
722 The data in this structure has been extracted from version 1.194 of the
723 devices.csv file released by TI in September 2016. */
725 struct msp430_mcu_data
728 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
729 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
733 { "cc430f5123",2,8 },
734 { "cc430f5125",2,8 },
735 { "cc430f5133",2,8 },
736 { "cc430f5135",2,8 },
737 { "cc430f5137",2,8 },
738 { "cc430f5143",2,8 },
739 { "cc430f5145",2,8 },
740 { "cc430f5147",2,8 },
741 { "cc430f6125",2,8 },
742 { "cc430f6126",2,8 },
743 { "cc430f6127",2,8 },
744 { "cc430f6135",2,8 },
745 { "cc430f6137",2,8 },
746 { "cc430f6143",2,8 },
747 { "cc430f6145",2,8 },
748 { "cc430f6147",2,8 },
749 { "msp430afe221",0,2 },
750 { "msp430afe222",0,2 },
751 { "msp430afe223",0,2 },
752 { "msp430afe231",0,2 },
753 { "msp430afe232",0,2 },
754 { "msp430afe233",0,2 },
755 { "msp430afe251",0,2 },
756 { "msp430afe252",0,2 },
757 { "msp430afe253",0,2 },
758 { "msp430bt5190",2,8 },
759 { "msp430c091",0,0 },
760 { "msp430c092",0,0 },
761 { "msp430c111",0,0 },
762 { "msp430c1111",0,0 },
763 { "msp430c112",0,0 },
764 { "msp430c1121",0,0 },
765 { "msp430c1331",0,0 },
766 { "msp430c1351",0,0 },
767 { "msp430c311s",0,0 },
768 { "msp430c312",0,0 },
769 { "msp430c313",0,0 },
770 { "msp430c314",0,0 },
771 { "msp430c315",0,0 },
772 { "msp430c323",0,0 },
773 { "msp430c325",0,0 },
774 { "msp430c336",0,1 },
775 { "msp430c337",0,1 },
776 { "msp430c412",0,0 },
777 { "msp430c413",0,0 },
778 { "msp430cg4616",1,1 },
779 { "msp430cg4617",1,1 },
780 { "msp430cg4618",1,1 },
781 { "msp430cg4619",1,1 },
782 { "msp430e112",0,0 },
783 { "msp430e313",0,0 },
784 { "msp430e315",0,0 },
785 { "msp430e325",0,0 },
786 { "msp430e337",0,1 },
787 { "msp430f110",0,0 },
788 { "msp430f1101",0,0 },
789 { "msp430f1101a",0,0 },
790 { "msp430f1111",0,0 },
791 { "msp430f1111a",0,0 },
792 { "msp430f112",0,0 },
793 { "msp430f1121",0,0 },
794 { "msp430f1121a",0,0 },
795 { "msp430f1122",0,0 },
796 { "msp430f1132",0,0 },
797 { "msp430f122",0,0 },
798 { "msp430f1222",0,0 },
799 { "msp430f123",0,0 },
800 { "msp430f1232",0,0 },
801 { "msp430f133",0,0 },
802 { "msp430f135",0,0 },
803 { "msp430f147",0,1 },
804 { "msp430f1471",0,1 },
805 { "msp430f148",0,1 },
806 { "msp430f1481",0,1 },
807 { "msp430f149",0,1 },
808 { "msp430f1491",0,1 },
809 { "msp430f155",0,0 },
810 { "msp430f156",0,0 },
811 { "msp430f157",0,0 },
812 { "msp430f1610",0,1 },
813 { "msp430f1611",0,1 },
814 { "msp430f1612",0,1 },
815 { "msp430f167",0,1 },
816 { "msp430f168",0,1 },
817 { "msp430f169",0,1 },
818 { "msp430f2001",0,0 },
819 { "msp430f2002",0,0 },
820 { "msp430f2003",0,0 },
821 { "msp430f2011",0,0 },
822 { "msp430f2012",0,0 },
823 { "msp430f2013",0,0 },
824 { "msp430f2101",0,0 },
825 { "msp430f2111",0,0 },
826 { "msp430f2112",0,0 },
827 { "msp430f2121",0,0 },
828 { "msp430f2122",0,0 },
829 { "msp430f2131",0,0 },
830 { "msp430f2132",0,0 },
831 { "msp430f2232",0,0 },
832 { "msp430f2234",0,0 },
833 { "msp430f2252",0,0 },
834 { "msp430f2254",0,0 },
835 { "msp430f2272",0,0 },
836 { "msp430f2274",0,0 },
837 { "msp430f233",0,2 },
838 { "msp430f2330",0,2 },
839 { "msp430f235",0,2 },
840 { "msp430f2350",0,2 },
841 { "msp430f2370",0,2 },
842 { "msp430f2410",0,2 },
843 { "msp430f2416",1,2 },
844 { "msp430f2417",1,2 },
845 { "msp430f2418",1,2 },
846 { "msp430f2419",1,2 },
847 { "msp430f247",0,2 },
848 { "msp430f2471",0,2 },
849 { "msp430f248",0,2 },
850 { "msp430f2481",0,2 },
851 { "msp430f249",0,2 },
852 { "msp430f2491",0,2 },
853 { "msp430f2616",1,2 },
854 { "msp430f2617",1,2 },
855 { "msp430f2618",1,2 },
856 { "msp430f2619",1,2 },
857 { "msp430f412",0,0 },
858 { "msp430f413",0,0 },
859 { "msp430f4132",0,0 },
860 { "msp430f415",0,0 },
861 { "msp430f4152",0,0 },
862 { "msp430f417",0,0 },
863 { "msp430f423",0,1 },
864 { "msp430f423a",0,1 },
865 { "msp430f425",0,1 },
866 { "msp430f4250",0,0 },
867 { "msp430f425a",0,1 },
868 { "msp430f4260",0,0 },
869 { "msp430f427",0,1 },
870 { "msp430f4270",0,0 },
871 { "msp430f427a",0,1 },
872 { "msp430f435",0,0 },
873 { "msp430f4351",0,0 },
874 { "msp430f436",0,0 },
875 { "msp430f4361",0,0 },
876 { "msp430f437",0,0 },
877 { "msp430f4371",0,0 },
878 { "msp430f438",0,0 },
879 { "msp430f439",0,0 },
880 { "msp430f447",0,1 },
881 { "msp430f448",0,1 },
882 { "msp430f4481",0,1 },
883 { "msp430f449",0,1 },
884 { "msp430f4491",0,1 },
885 { "msp430f4616",1,1 },
886 { "msp430f46161",1,1 },
887 { "msp430f4617",1,1 },
888 { "msp430f46171",1,1 },
889 { "msp430f4618",1,1 },
890 { "msp430f46181",1,1 },
891 { "msp430f4619",1,1 },
892 { "msp430f46191",1,1 },
893 { "msp430f47126",1,4 },
894 { "msp430f47127",1,4 },
895 { "msp430f47163",1,4 },
896 { "msp430f47166",1,4 },
897 { "msp430f47167",1,4 },
898 { "msp430f47173",1,4 },
899 { "msp430f47176",1,4 },
900 { "msp430f47177",1,4 },
901 { "msp430f47183",1,4 },
902 { "msp430f47186",1,4 },
903 { "msp430f47187",1,4 },
904 { "msp430f47193",1,4 },
905 { "msp430f47196",1,4 },
906 { "msp430f47197",1,4 },
907 { "msp430f477",0,0 },
908 { "msp430f478",0,0 },
909 { "msp430f4783",0,4 },
910 { "msp430f4784",0,4 },
911 { "msp430f479",0,0 },
912 { "msp430f4793",0,4 },
913 { "msp430f4794",0,4 },
914 { "msp430f5131",2,8 },
915 { "msp430f5132",2,8 },
916 { "msp430f5151",2,8 },
917 { "msp430f5152",2,8 },
918 { "msp430f5171",2,8 },
919 { "msp430f5172",2,8 },
920 { "msp430f5212",2,8 },
921 { "msp430f5213",2,8 },
922 { "msp430f5214",2,8 },
923 { "msp430f5217",2,8 },
924 { "msp430f5218",2,8 },
925 { "msp430f5219",2,8 },
926 { "msp430f5222",2,8 },
927 { "msp430f5223",2,8 },
928 { "msp430f5224",2,8 },
929 { "msp430f5227",2,8 },
930 { "msp430f5228",2,8 },
931 { "msp430f5229",2,8 },
932 { "msp430f5232",2,8 },
933 { "msp430f5234",2,8 },
934 { "msp430f5237",2,8 },
935 { "msp430f5239",2,8 },
936 { "msp430f5242",2,8 },
937 { "msp430f5244",2,8 },
938 { "msp430f5247",2,8 },
939 { "msp430f5249",2,8 },
940 { "msp430f5252",2,8 },
941 { "msp430f5253",2,8 },
942 { "msp430f5254",2,8 },
943 { "msp430f5255",2,8 },
944 { "msp430f5256",2,8 },
945 { "msp430f5257",2,8 },
946 { "msp430f5258",2,8 },
947 { "msp430f5259",2,8 },
948 { "msp430f5304",2,8 },
949 { "msp430f5308",2,8 },
950 { "msp430f5309",2,8 },
951 { "msp430f5310",2,8 },
952 { "msp430f5324",2,8 },
953 { "msp430f5325",2,8 },
954 { "msp430f5326",2,8 },
955 { "msp430f5327",2,8 },
956 { "msp430f5328",2,8 },
957 { "msp430f5329",2,8 },
958 { "msp430f5333",2,8 },
959 { "msp430f5335",2,8 },
960 { "msp430f5336",2,8 },
961 { "msp430f5338",2,8 },
962 { "msp430f5340",2,8 },
963 { "msp430f5341",2,8 },
964 { "msp430f5342",2,8 },
965 { "msp430f5358",2,8 },
966 { "msp430f5359",2,8 },
967 { "msp430f5418",2,8 },
968 { "msp430f5418a",2,8 },
969 { "msp430f5419",2,8 },
970 { "msp430f5419a",2,8 },
971 { "msp430f5435",2,8 },
972 { "msp430f5435a",2,8 },
973 { "msp430f5436",2,8 },
974 { "msp430f5436a",2,8 },
975 { "msp430f5437",2,8 },
976 { "msp430f5437a",2,8 },
977 { "msp430f5438",2,8 },
978 { "msp430f5438a",2,8 },
979 { "msp430f5500",2,8 },
980 { "msp430f5501",2,8 },
981 { "msp430f5502",2,8 },
982 { "msp430f5503",2,8 },
983 { "msp430f5504",2,8 },
984 { "msp430f5505",2,8 },
985 { "msp430f5506",2,8 },
986 { "msp430f5507",2,8 },
987 { "msp430f5508",2,8 },
988 { "msp430f5509",2,8 },
989 { "msp430f5510",2,8 },
990 { "msp430f5513",2,8 },
991 { "msp430f5514",2,8 },
992 { "msp430f5515",2,8 },
993 { "msp430f5517",2,8 },
994 { "msp430f5519",2,8 },
995 { "msp430f5521",2,8 },
996 { "msp430f5522",2,8 },
997 { "msp430f5524",2,8 },
998 { "msp430f5525",2,8 },
999 { "msp430f5526",2,8 },
1000 { "msp430f5527",2,8 },
1001 { "msp430f5528",2,8 },
1002 { "msp430f5529",2,8 },
1003 { "msp430f5630",2,8 },
1004 { "msp430f5631",2,8 },
1005 { "msp430f5632",2,8 },
1006 { "msp430f5633",2,8 },
1007 { "msp430f5634",2,8 },
1008 { "msp430f5635",2,8 },
1009 { "msp430f5636",2,8 },
1010 { "msp430f5637",2,8 },
1011 { "msp430f5638",2,8 },
1012 { "msp430f5658",2,8 },
1013 { "msp430f5659",2,8 },
1014 { "msp430f5xx_6xxgeneric",2,8 },
1015 { "msp430f6433",2,8 },
1016 { "msp430f6435",2,8 },
1017 { "msp430f6436",2,8 },
1018 { "msp430f6438",2,8 },
1019 { "msp430f6458",2,8 },
1020 { "msp430f6459",2,8 },
1021 { "msp430f6630",2,8 },
1022 { "msp430f6631",2,8 },
1023 { "msp430f6632",2,8 },
1024 { "msp430f6633",2,8 },
1025 { "msp430f6634",2,8 },
1026 { "msp430f6635",2,8 },
1027 { "msp430f6636",2,8 },
1028 { "msp430f6637",2,8 },
1029 { "msp430f6638",2,8 },
1030 { "msp430f6658",2,8 },
1031 { "msp430f6659",2,8 },
1032 { "msp430f6720",2,8 },
1033 { "msp430f6720a",2,8 },
1034 { "msp430f6721",2,8 },
1035 { "msp430f6721a",2,8 },
1036 { "msp430f6723",2,8 },
1037 { "msp430f6723a",2,8 },
1038 { "msp430f6724",2,8 },
1039 { "msp430f6724a",2,8 },
1040 { "msp430f6725",2,8 },
1041 { "msp430f6725a",2,8 },
1042 { "msp430f6726",2,8 },
1043 { "msp430f6726a",2,8 },
1044 { "msp430f6730",2,8 },
1045 { "msp430f6730a",2,8 },
1046 { "msp430f6731",2,8 },
1047 { "msp430f6731a",2,8 },
1048 { "msp430f6733",2,8 },
1049 { "msp430f6733a",2,8 },
1050 { "msp430f6734",2,8 },
1051 { "msp430f6734a",2,8 },
1052 { "msp430f6735",2,8 },
1053 { "msp430f6735a",2,8 },
1054 { "msp430f6736",2,8 },
1055 { "msp430f6736a",2,8 },
1056 { "msp430f6745",2,8 },
1057 { "msp430f67451",2,8 },
1058 { "msp430f67451a",2,8 },
1059 { "msp430f6745a",2,8 },
1060 { "msp430f6746",2,8 },
1061 { "msp430f67461",2,8 },
1062 { "msp430f67461a",2,8 },
1063 { "msp430f6746a",2,8 },
1064 { "msp430f6747",2,8 },
1065 { "msp430f67471",2,8 },
1066 { "msp430f67471a",2,8 },
1067 { "msp430f6747a",2,8 },
1068 { "msp430f6748",2,8 },
1069 { "msp430f67481",2,8 },
1070 { "msp430f67481a",2,8 },
1071 { "msp430f6748a",2,8 },
1072 { "msp430f6749",2,8 },
1073 { "msp430f67491",2,8 },
1074 { "msp430f67491a",2,8 },
1075 { "msp430f6749a",2,8 },
1076 { "msp430f67621",2,8 },
1077 { "msp430f67621a",2,8 },
1078 { "msp430f67641",2,8 },
1079 { "msp430f67641a",2,8 },
1080 { "msp430f6765",2,8 },
1081 { "msp430f67651",2,8 },
1082 { "msp430f67651a",2,8 },
1083 { "msp430f6765a",2,8 },
1084 { "msp430f6766",2,8 },
1085 { "msp430f67661",2,8 },
1086 { "msp430f67661a",2,8 },
1087 { "msp430f6766a",2,8 },
1088 { "msp430f6767",2,8 },
1089 { "msp430f67671",2,8 },
1090 { "msp430f67671a",2,8 },
1091 { "msp430f6767a",2,8 },
1092 { "msp430f6768",2,8 },
1093 { "msp430f67681",2,8 },
1094 { "msp430f67681a",2,8 },
1095 { "msp430f6768a",2,8 },
1096 { "msp430f6769",2,8 },
1097 { "msp430f67691",2,8 },
1098 { "msp430f67691a",2,8 },
1099 { "msp430f6769a",2,8 },
1100 { "msp430f6775",2,8 },
1101 { "msp430f67751",2,8 },
1102 { "msp430f67751a",2,8 },
1103 { "msp430f6775a",2,8 },
1104 { "msp430f6776",2,8 },
1105 { "msp430f67761",2,8 },
1106 { "msp430f67761a",2,8 },
1107 { "msp430f6776a",2,8 },
1108 { "msp430f6777",2,8 },
1109 { "msp430f67771",2,8 },
1110 { "msp430f67771a",2,8 },
1111 { "msp430f6777a",2,8 },
1112 { "msp430f6778",2,8 },
1113 { "msp430f67781",2,8 },
1114 { "msp430f67781a",2,8 },
1115 { "msp430f6778a",2,8 },
1116 { "msp430f6779",2,8 },
1117 { "msp430f67791",2,8 },
1118 { "msp430f67791a",2,8 },
1119 { "msp430f6779a",2,8 },
1120 { "msp430fe423",0,0 },
1121 { "msp430fe4232",0,0 },
1122 { "msp430fe423a",0,0 },
1123 { "msp430fe4242",0,0 },
1124 { "msp430fe425",0,0 },
1125 { "msp430fe4252",0,0 },
1126 { "msp430fe425a",0,0 },
1127 { "msp430fe427",0,0 },
1128 { "msp430fe4272",0,0 },
1129 { "msp430fe427a",0,0 },
1130 { "msp430fg4250",0,0 },
1131 { "msp430fg4260",0,0 },
1132 { "msp430fg4270",0,0 },
1133 { "msp430fg437",0,0 },
1134 { "msp430fg438",0,0 },
1135 { "msp430fg439",0,0 },
1136 { "msp430fg4616",1,1 },
1137 { "msp430fg4617",1,1 },
1138 { "msp430fg4618",1,1 },
1139 { "msp430fg4619",1,1 },
1140 { "msp430fg477",0,0 },
1141 { "msp430fg478",0,0 },
1142 { "msp430fg479",0,0 },
1143 { "msp430fg6425",2,8 },
1144 { "msp430fg6426",2,8 },
1145 { "msp430fg6625",2,8 },
1146 { "msp430fg6626",2,8 },
1147 { "msp430fr2032",2,0 },
1148 { "msp430fr2033",2,0 },
1149 { "msp430fr2110",2,0 },
1150 { "msp430fr2111",2,0 },
1151 { "msp430fr2310",2,0 },
1152 { "msp430fr2311",2,0 },
1153 { "msp430fr2433",2,8 },
1154 { "msp430fr2532",2,8 },
1155 { "msp430fr2533",2,8 },
1156 { "msp430fr2632",2,8 },
1157 { "msp430fr2633",2,8 },
1158 { "msp430fr2xx_4xxgeneric",2,8 },
1159 { "msp430fr4131",2,0 },
1160 { "msp430fr4132",2,0 },
1161 { "msp430fr4133",2,0 },
1162 { "msp430fr5720",2,8 },
1163 { "msp430fr5721",2,8 },
1164 { "msp430fr5722",2,8 },
1165 { "msp430fr5723",2,8 },
1166 { "msp430fr5724",2,8 },
1167 { "msp430fr5725",2,8 },
1168 { "msp430fr5726",2,8 },
1169 { "msp430fr5727",2,8 },
1170 { "msp430fr5728",2,8 },
1171 { "msp430fr5729",2,8 },
1172 { "msp430fr5730",2,8 },
1173 { "msp430fr5731",2,8 },
1174 { "msp430fr5732",2,8 },
1175 { "msp430fr5733",2,8 },
1176 { "msp430fr5734",2,8 },
1177 { "msp430fr5735",2,8 },
1178 { "msp430fr5736",2,8 },
1179 { "msp430fr5737",2,8 },
1180 { "msp430fr5738",2,8 },
1181 { "msp430fr5739",2,8 },
1182 { "msp430fr57xxgeneric",2,8 },
1183 { "msp430fr5847",2,8 },
1184 { "msp430fr58471",2,8 },
1185 { "msp430fr5848",2,8 },
1186 { "msp430fr5849",2,8 },
1187 { "msp430fr5857",2,8 },
1188 { "msp430fr5858",2,8 },
1189 { "msp430fr5859",2,8 },
1190 { "msp430fr5867",2,8 },
1191 { "msp430fr58671",2,8 },
1192 { "msp430fr5868",2,8 },
1193 { "msp430fr5869",2,8 },
1194 { "msp430fr5870",2,8 },
1195 { "msp430fr5872",2,8 },
1196 { "msp430fr58721",2,8 },
1197 { "msp430fr5887",2,8 },
1198 { "msp430fr5888",2,8 },
1199 { "msp430fr5889",2,8 },
1200 { "msp430fr58891",2,8 },
1201 { "msp430fr5922",2,8 },
1202 { "msp430fr59221",2,8 },
1203 { "msp430fr5947",2,8 },
1204 { "msp430fr59471",2,8 },
1205 { "msp430fr5948",2,8 },
1206 { "msp430fr5949",2,8 },
1207 { "msp430fr5957",2,8 },
1208 { "msp430fr5958",2,8 },
1209 { "msp430fr5959",2,8 },
1210 { "msp430fr5962",2,8 },
1211 { "msp430fr5964",2,8 },
1212 { "msp430fr5967",2,8 },
1213 { "msp430fr5968",2,8 },
1214 { "msp430fr5969",2,8 },
1215 { "msp430fr59691",2,8 },
1216 { "msp430fr5970",2,8 },
1217 { "msp430fr5972",2,8 },
1218 { "msp430fr59721",2,8 },
1219 { "msp430fr5986",2,8 },
1220 { "msp430fr5987",2,8 },
1221 { "msp430fr5988",2,8 },
1222 { "msp430fr5989",2,8 },
1223 { "msp430fr59891",2,8 },
1224 { "msp430fr5992",2,8 },
1225 { "msp430fr5994",2,8 },
1226 { "msp430fr59941",2,8 },
1227 { "msp430fr5xx_6xxgeneric",2,8 },
1228 { "msp430fr6820",2,8 },
1229 { "msp430fr6822",2,8 },
1230 { "msp430fr68221",2,8 },
1231 { "msp430fr6870",2,8 },
1232 { "msp430fr6872",2,8 },
1233 { "msp430fr68721",2,8 },
1234 { "msp430fr6877",2,8 },
1235 { "msp430fr6879",2,8 },
1236 { "msp430fr68791",2,8 },
1237 { "msp430fr6887",2,8 },
1238 { "msp430fr6888",2,8 },
1239 { "msp430fr6889",2,8 },
1240 { "msp430fr68891",2,8 },
1241 { "msp430fr6920",2,8 },
1242 { "msp430fr6922",2,8 },
1243 { "msp430fr69221",2,8 },
1244 { "msp430fr6927",2,8 },
1245 { "msp430fr69271",2,8 },
1246 { "msp430fr6928",2,8 },
1247 { "msp430fr6970",2,8 },
1248 { "msp430fr6972",2,8 },
1249 { "msp430fr69721",2,8 },
1250 { "msp430fr6977",2,8 },
1251 { "msp430fr6979",2,8 },
1252 { "msp430fr69791",2,8 },
1253 { "msp430fr6987",2,8 },
1254 { "msp430fr6988",2,8 },
1255 { "msp430fr6989",2,8 },
1256 { "msp430fr69891",2,8 },
1257 { "msp430fw423",0,0 },
1258 { "msp430fw425",0,0 },
1259 { "msp430fw427",0,0 },
1260 { "msp430fw428",0,0 },
1261 { "msp430fw429",0,0 },
1262 { "msp430g2001",0,0 },
1263 { "msp430g2101",0,0 },
1264 { "msp430g2102",0,0 },
1265 { "msp430g2111",0,0 },
1266 { "msp430g2112",0,0 },
1267 { "msp430g2113",0,0 },
1268 { "msp430g2121",0,0 },
1269 { "msp430g2131",0,0 },
1270 { "msp430g2132",0,0 },
1271 { "msp430g2152",0,0 },
1272 { "msp430g2153",0,0 },
1273 { "msp430g2201",0,0 },
1274 { "msp430g2202",0,0 },
1275 { "msp430g2203",0,0 },
1276 { "msp430g2210",0,0 },
1277 { "msp430g2211",0,0 },
1278 { "msp430g2212",0,0 },
1279 { "msp430g2213",0,0 },
1280 { "msp430g2221",0,0 },
1281 { "msp430g2230",0,0 },
1282 { "msp430g2231",0,0 },
1283 { "msp430g2232",0,0 },
1284 { "msp430g2233",0,0 },
1285 { "msp430g2252",0,0 },
1286 { "msp430g2253",0,0 },
1287 { "msp430g2302",0,0 },
1288 { "msp430g2303",0,0 },
1289 { "msp430g2312",0,0 },
1290 { "msp430g2313",0,0 },
1291 { "msp430g2332",0,0 },
1292 { "msp430g2333",0,0 },
1293 { "msp430g2352",0,0 },
1294 { "msp430g2353",0,0 },
1295 { "msp430g2402",0,0 },
1296 { "msp430g2403",0,0 },
1297 { "msp430g2412",0,0 },
1298 { "msp430g2413",0,0 },
1299 { "msp430g2432",0,0 },
1300 { "msp430g2433",0,0 },
1301 { "msp430g2444",0,0 },
1302 { "msp430g2452",0,0 },
1303 { "msp430g2453",0,0 },
1304 { "msp430g2513",0,0 },
1305 { "msp430g2533",0,0 },
1306 { "msp430g2544",0,0 },
1307 { "msp430g2553",0,0 },
1308 { "msp430g2744",0,0 },
1309 { "msp430g2755",0,0 },
1310 { "msp430g2855",0,0 },
1311 { "msp430g2955",0,0 },
1312 { "msp430i2020",0,2 },
1313 { "msp430i2021",0,2 },
1314 { "msp430i2030",0,2 },
1315 { "msp430i2031",0,2 },
1316 { "msp430i2040",0,2 },
1317 { "msp430i2041",0,2 },
1318 { "msp430i2xxgeneric",0,2 },
1319 { "msp430l092",0,0 },
1320 { "msp430p112",0,0 },
1321 { "msp430p313",0,0 },
1322 { "msp430p315",0,0 },
1323 { "msp430p315s",0,0 },
1324 { "msp430p325",0,0 },
1325 { "msp430p337",0,1 },
1326 { "msp430sl5438a",2,8 },
1327 { "msp430tch5e",0,0 },
1328 { "msp430xgeneric",2,8 },
1329 { "rf430f5144",2,8 },
1330 { "rf430f5155",2,8 },
1331 { "rf430f5175",2,8 },
1332 { "rf430frl152h",0,0 },
1333 { "rf430frl152h_rom",0,0 },
1334 { "rf430frl153h",0,0 },
1335 { "rf430frl153h_rom",0,0 },
1336 { "rf430frl154h",0,0 },
1337 { "rf430frl154h_rom",0,0 }
1341 md_parse_option (int c
, const char * arg
)
1345 case OPTION_SILICON_ERRATA
:
1346 case OPTION_SILICON_ERRATA_WARN
:
1352 unsigned int length
;
1353 unsigned int bitfield
;
1356 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1357 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1358 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1359 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1360 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1361 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1366 for (i
= ARRAY_SIZE (erratas
); i
--;)
1367 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1369 if (c
== OPTION_SILICON_ERRATA
)
1370 silicon_errata_fix
|= erratas
[i
].bitfield
;
1372 silicon_errata_warn
|= erratas
[i
].bitfield
;
1373 arg
+= erratas
[i
].length
;
1378 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1384 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1394 as_fatal (_("MCU option requires a name\n"));
1396 if (strcasecmp ("msp430", arg
) == 0)
1397 selected_isa
= MSP_ISA_430
;
1398 else if (strcasecmp ("msp430xv2", arg
) == 0)
1399 selected_isa
= MSP_ISA_430Xv2
;
1400 else if (strcasecmp ("msp430x", arg
) == 0)
1401 selected_isa
= MSP_ISA_430X
;
1406 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1407 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1409 switch (msp430_mcu_data
[i
].revision
)
1411 case 0: selected_isa
= MSP_ISA_430
; break;
1412 case 1: selected_isa
= MSP_ISA_430X
; break;
1413 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1418 /* It is not an error if we do not match the MCU name. */
1422 if (strcmp (arg
, "430") == 0
1423 || strcasecmp (arg
, "msp430") == 0)
1424 selected_isa
= MSP_ISA_430
;
1425 else if (strcasecmp (arg
, "430x") == 0
1426 || strcasecmp (arg
, "msp430x") == 0)
1427 selected_isa
= MSP_ISA_430X
;
1428 else if (strcasecmp (arg
, "430xv2") == 0
1429 || strcasecmp (arg
, "msp430xv2") == 0)
1430 selected_isa
= MSP_ISA_430Xv2
;
1432 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1436 msp430_enable_relax
= 1;
1439 case OPTION_POLYMORPHS
:
1440 msp430_enable_polys
= 1;
1447 case OPTION_NO_INTR_NOPS
:
1448 gen_interrupt_nops
= FALSE
;
1450 case OPTION_INTR_NOPS
:
1451 gen_interrupt_nops
= TRUE
;
1454 case OPTION_WARN_INTR_NOPS
:
1455 warn_interrupt_nops
= TRUE
;
1457 case OPTION_NO_WARN_INTR_NOPS
:
1458 warn_interrupt_nops
= FALSE
;
1461 case OPTION_UNKNOWN_INTR_NOPS
:
1462 do_unknown_interrupt_nops
= TRUE
;
1464 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1465 do_unknown_interrupt_nops
= FALSE
;
1468 case OPTION_DATA_REGION
:
1469 if (strcmp (arg
, "upper") == 0
1470 || strcmp (arg
, "either") == 0)
1471 upper_data_region_in_use
= TRUE
;
1472 if (strcmp (arg
, "upper") == 0
1473 || strcmp (arg
, "either") == 0
1474 /* With data-region=none, the compiler has generated code assuming
1475 data could be in the upper region, but nothing has been explicitly
1477 || strcmp (arg
, "none") == 0)
1478 lower_data_region_only
= FALSE
;
1485 /* The intention here is to have the mere presence of these sections
1486 cause the object to have a reference to a well-known symbol. This
1487 reference pulls in the bits of the runtime (crt0) that initialize
1488 these sections. Thus, for example, the startup code to call
1489 memset() to initialize .bss will only be linked in when there is a
1490 non-empty .bss section. Otherwise, the call would exist but have a
1491 zero length parameter, which is a waste of memory and cycles.
1493 The code which initializes these sections should have a global
1494 label for these symbols, and should be marked with KEEP() in the
1498 msp430_make_init_symbols (const char * name
)
1500 if (strncmp (name
, ".bss", 4) == 0
1501 || strncmp (name
, ".lower.bss", 10) == 0
1502 || strncmp (name
, ".either.bss", 11) == 0
1503 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1504 (void) symbol_find_or_make ("__crt0_init_bss");
1506 if (strncmp (name
, ".data", 5) == 0
1507 || strncmp (name
, ".lower.data", 11) == 0
1508 || strncmp (name
, ".either.data", 12) == 0
1509 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1510 (void) symbol_find_or_make ("__crt0_movedata");
1511 /* Note - data assigned to the .either.data section may end up being
1512 placed in the .upper.data section if the .lower.data section is
1513 full. Hence the need to define the crt0 symbol.
1514 The linker may create upper or either data sections, even when none exist
1515 at the moment, so use the value of the data-region flag to determine if
1516 the symbol is needed. */
1517 if (strncmp (name
, ".either.data", 12) == 0
1518 || strncmp (name
, ".upper.data", 11) == 0
1519 || upper_data_region_in_use
)
1520 (void) symbol_find_or_make ("__crt0_move_highdata");
1522 /* See note about .either.data above. */
1523 if (strncmp (name
, ".upper.bss", 10) == 0
1524 || strncmp (name
, ".either.bss", 11) == 0
1525 || upper_data_region_in_use
)
1526 (void) symbol_find_or_make ("__crt0_init_highbss");
1528 /* The following symbols are for the crt0 functions that run through
1529 the different .*_array sections and call the functions placed there.
1530 - init_array stores global static C++ constructors to run before main.
1531 - preinit_array is not expected to ever be used for MSP430.
1532 GCC only places initialization functions for runtime "sanitizers"
1533 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1534 - fini_array stores global static C++ destructors to run after calling
1535 exit() or returning from main.
1536 __crt0_run_array is required to actually call the functions in the above
1538 if (strncmp (name
, ".init_array", 11) == 0)
1540 (void) symbol_find_or_make ("__crt0_run_init_array");
1541 (void) symbol_find_or_make ("__crt0_run_array");
1543 else if (strncmp (name
, ".preinit_array", 14) == 0)
1545 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1546 (void) symbol_find_or_make ("__crt0_run_array");
1548 else if (strncmp (name
, ".fini_array", 11) == 0)
1550 (void) symbol_find_or_make ("__crt0_run_fini_array");
1551 (void) symbol_find_or_make ("__crt0_run_array");
1556 msp430_section (int arg
)
1558 char * saved_ilp
= input_line_pointer
;
1559 const char * name
= obj_elf_section_name ();
1561 msp430_make_init_symbols (name
);
1563 input_line_pointer
= saved_ilp
;
1564 obj_elf_section (arg
);
1568 msp430_frob_section (asection
*sec
)
1570 const char *name
= sec
->name
;
1575 msp430_make_init_symbols (name
);
1579 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1581 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1584 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1585 (void) symbol_find_or_make ("__crt0_init_bss");
1589 msp430_comm (int needs_align
)
1591 s_comm_internal (needs_align
, elf_common_parse
);
1592 (void) symbol_find_or_make ("__crt0_init_bss");
1596 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1598 char sym_name
[1024];
1599 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1601 (void) symbol_find_or_make (sym_name
);
1604 /* Handle a .mspabi_attribute or .gnu_attribute directive.
1605 attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute.
1606 This is only used for validating the attributes in the assembly file against
1607 the options gas has been invoked with. If the attributes and options are
1608 compatible then we add the attributes to the assembly file in
1611 msp430_object_attribute (int attr_type
)
1613 char tag_name_s
[32];
1614 char tag_value_s
[32];
1615 int tag_name
, tag_value
;
1616 /* First operand is the tag name, second is the tag value e.g.
1617 ".mspabi_attribute 4, 2". */
1618 input_line_pointer
= extract_operand (input_line_pointer
, tag_name_s
, 32);
1619 input_line_pointer
= extract_operand (input_line_pointer
, tag_value_s
, 32);
1620 tag_name
= atoi (tag_name_s
);
1621 tag_value
= atoi (tag_value_s
);
1622 /* If the attribute directive is present, the tag_value should never be set
1624 if (tag_name
== 0 || tag_value
== 0)
1625 as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"),
1626 tag_name_s
, tag_value_s
, (attr_type
? ".gnu_attribute"
1627 : ".mspabi_attribute"));
1628 else if (attr_type
== 0)
1629 /* Handle .mspabi_attribute. */
1632 case OFBA_MSPABI_Tag_ISA
:
1635 case OFBA_MSPABI_Val_ISA_MSP430
:
1636 if (target_is_430x ())
1637 as_bad (_("file was compiled for the 430 ISA but the %s ISA is "
1638 "selected"), (target_is_430xv2 () ? "430X" : "430Xv2"));
1640 case OFBA_MSPABI_Val_ISA_MSP430X
:
1641 if (!target_is_430x ())
1642 as_bad (_("file was compiled for the 430X ISA but the 430 ISA is "
1646 as_bad (_("unknown MSPABI build attribute value '%d' for "
1647 "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"),
1648 tag_value
, OFBA_MSPABI_Tag_ISA
);
1652 case OFBA_MSPABI_Tag_Code_Model
:
1654 case OFBA_MSPABI_Tag_Data_Model
:
1655 /* FIXME: Might we want to set the memory model to large if the assembly
1656 file has the large model attribute, but -ml has not been passed? */
1659 case OFBA_MSPABI_Val_Code_Model_SMALL
:
1661 as_bad (_("file was compiled for the small memory model, but the "
1662 "large memory model is selected"));
1664 case OFBA_MSPABI_Val_Code_Model_LARGE
:
1666 as_bad (_("file was compiled for the large memory model, "
1667 "but the small memory model is selected"));
1670 as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) "
1671 "in .mspabi_attribute directive"), tag_value
,
1672 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1673 ? "OFBA_MSPABI_Tag_Code_Model"
1674 : "OFBA_MSPABI_Tag_Data_Model"),
1675 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1676 ? OFBA_MSPABI_Tag_Code_Model
1677 : OFBA_MSPABI_Tag_Data_Model
));
1682 as_bad (_("unknown MSPABI build attribute tag '%d' in "
1683 ".mspabi_attribute directive"), tag_name
);
1686 else if (attr_type
== 1)
1687 /* Handle .gnu_attribute. */
1690 case Tag_GNU_MSP430_Data_Region
:
1691 /* This attribute is only applicable in the large memory model. */
1696 case Val_GNU_MSP430_Data_Region_Lower
:
1697 if (!lower_data_region_only
)
1698 as_bad (_("file was compiled assuming all data will be in the "
1699 "lower memory region, but the upper region is in use"));
1701 case Val_GNU_MSP430_Data_Region_Any
:
1702 if (lower_data_region_only
)
1703 as_bad (_("file was compiled assuming data could be in the upper "
1704 "memory region, but the lower data region is "
1705 "exclusively in use"));
1708 as_bad (_("unknown GNU build attribute value '%d' for "
1709 "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute "
1710 "directive"), tag_value
, Tag_GNU_MSP430_Data_Region
);
1714 as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"),
1718 const pseudo_typeS md_pseudo_table
[] =
1720 {"arch", msp430_set_arch
, OPTION_MMCU
},
1721 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1722 {"profiler", msp430_profiler
, 0},
1723 {"section", msp430_section
, 0},
1724 {"section.s", msp430_section
, 0},
1725 {"sect", msp430_section
, 0},
1726 {"sect.s", msp430_section
, 0},
1727 {"pushsection", msp430_section
, 1},
1728 {"refsym", msp430_refsym
, 0},
1729 {"comm", msp430_comm
, 0},
1730 {"lcomm", msp430_lcomm
, 0},
1731 {"mspabi_attribute", msp430_object_attribute
, 0},
1732 {"gnu_attribute", msp430_object_attribute
, 1},
1736 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1738 struct option md_longopts
[] =
1740 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1741 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1742 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1743 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1744 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1745 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1746 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1747 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1748 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1749 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1750 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1751 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1752 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1753 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1754 {NULL
, no_argument
, NULL
, 0}
1757 size_t md_longopts_size
= sizeof (md_longopts
);
1760 md_show_usage (FILE * stream
)
1763 _("MSP430 options:\n"
1764 " -mmcu=<msp430-name> - select microcontroller type\n"
1765 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1767 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1768 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1769 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1771 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1772 " -mP - enable polymorph instructions\n"));
1774 _(" -ml - enable large code model\n"));
1776 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1778 _(" -mn - insert a NOP after changing interrupts\n"));
1780 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1782 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1784 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1785 " known how the state is changed, do not warn/insert NOPs\n"));
1787 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1788 " known how the state is changed, warn/insert NOPs (default)\n"
1789 " -mn and/or -my are required for this to have any effect\n"));
1791 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1796 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1802 extract_cmd (char * from
, char * to
, int limit
)
1806 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1808 *(to
+ size
) = *from
;
1819 md_atof (int type
, char * litP
, int * sizeP
)
1821 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1827 struct msp430_opcode_s
* opcode
;
1828 msp430_hash
= str_htab_create ();
1830 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1831 str_hash_insert (msp430_hash
, opcode
->name
, opcode
, 0);
1833 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1834 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1836 /* Set linkrelax here to avoid fixups in most sections. */
1840 static inline bfd_boolean
1841 is_regname_end (char c
)
1843 return (c
== 0 || ! ISALNUM (c
));
1846 /* Returns the register number equivalent to the string T.
1847 Returns -1 if there is no such register.
1848 Skips a leading 'r' or 'R' character if there is one.
1849 Handles the register aliases PC and SP. */
1852 check_reg (char * t
)
1855 signed long int val
;
1857 if (t
== NULL
|| t
[0] == 0)
1860 if (*t
== 'r' || *t
== 'R')
1863 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1866 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1869 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1872 if (*t
== '0' && is_regname_end (t
[1]))
1875 val
= strtol (t
, & endt
, 0);
1877 if (val
< 1 || val
> 15)
1880 if (is_regname_end (*endt
))
1887 msp430_srcoperand (struct msp430_operand_s
* op
,
1890 bfd_boolean
* imm_op
,
1891 bfd_boolean allow_20bit_values
,
1892 bfd_boolean constants_allowed
)
1897 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1903 /* Use all parts of the constant expression by default. */
1904 enum msp430_expp_e expp
= MSP_EXPP_ALL
;
1906 /* Check if there is:
1907 llo(x) - least significant 16 bits, x &= 0xffff
1908 lhi(x) - x = (x >> 16) & 0xffff,
1909 hlo(x) - x = (x >> 32) & 0xffff,
1910 hhi(x) - x = (x >> 48) & 0xffff
1911 The value _MUST_ be an immediate expression: #hlo(1231231231). */
1915 if (strncasecmp (h
, "#llo(", 5) == 0)
1919 expp
= MSP_EXPP_LLO
;
1921 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1925 expp
= MSP_EXPP_LHI
;
1927 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1931 expp
= MSP_EXPP_HLO
;
1933 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1937 expp
= MSP_EXPP_HHI
;
1939 else if (strncasecmp (h
, "#lo(", 4) == 0)
1945 else if (strncasecmp (h
, "#hi(", 4) == 0)
1952 op
->reg
= 0; /* Reg PC. */
1954 op
->ol
= 1; /* Immediate will follow an instruction. */
1955 __tl
= h
+ 1 + rval
;
1957 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 op
->expp
= MSP_EXPP_ALL
;
2171 if (op
->exp
.X_op
== O_constant
)
2173 int x
= op
->exp
.X_add_number
;
2175 if (allow_20bit_values
)
2177 if (x
> 0xfffff || x
< -(0x7ffff))
2179 as_bad (_("value 0x%x out of extended range."), x
);
2183 else if (x
> 65535 || x
< -32768)
2185 as_bad (_("value out of range: 0x%x"), x
);
2189 else if (op
->exp
.X_op
== O_symbol
)
2193 /* Redundant (yet) check. */
2194 if (op
->exp
.X_op
== O_register
)
2196 (_("Registers cannot be used within absolute expression [%s]"), l
);
2198 as_bad (_("unknown expression in operand %s"), l
);
2204 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2208 char *m
= strchr (l
, '+');
2212 as_bad (_("unknown addressing mode %s"), l
);
2218 if ((op
->reg
= check_reg (t
)) == -1)
2220 as_bad (_("Bad register name %s"), t
);
2228 /* PC cannot be used in indirect addressing. */
2229 if (target_is_430xv2 () && op
->reg
== 0)
2231 as_bad (_("cannot use indirect addressing with the PC"));
2238 /* Check if register indexed X(Rn). */
2241 char *h
= strrchr (l
, '(');
2242 char *m
= strrchr (l
, ')');
2251 as_bad (_("')' required"));
2259 /* Extract a register. */
2260 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2263 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2270 as_bad (_("r2 should not be used in indexed addressing mode"));
2274 /* Extract constant. */
2279 op
->expp
= MSP_EXPP_ALL
;
2280 end
= parse_exp (__tl
, &(op
->exp
));
2281 if (end
!= NULL
&& *end
!= 0)
2283 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2286 if (op
->exp
.X_op
== O_constant
)
2288 int x
= op
->exp
.X_add_number
;
2290 if (allow_20bit_values
)
2292 if (x
> 0xfffff || x
< - (0x7ffff))
2294 as_bad (_("value 0x%x out of extended range."), x
);
2298 else if (x
> 65535 || x
< -32768)
2300 as_bad (_("value out of range: 0x%x"), x
);
2312 if (op
->reg
== 1 && (x
& 1))
2314 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2315 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2316 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2317 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2320 else if (op
->exp
.X_op
== O_symbol
)
2324 /* Redundant (yet) check. */
2325 if (op
->exp
.X_op
== O_register
)
2327 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2329 as_bad (_("unknown expression in operand %s"), l
);
2337 /* Possibly register mode 'mov r1,r2'. */
2338 if ((op
->reg
= check_reg (l
)) != -1)
2346 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2348 op
->reg
= 0; /* PC relative... be careful. */
2349 /* An expression starting with a minus sign is a constant, not an address. */
2350 op
->am
= (*l
== '-' ? 3 : 1);
2353 op
->expp
= MSP_EXPP_ALL
;
2355 end
= parse_exp (__tl
, &(op
->exp
));
2356 if (end
!= NULL
&& * end
!= 0)
2358 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2366 msp430_dstoperand (struct msp430_operand_s
* op
,
2369 bfd_boolean allow_20bit_values
,
2370 bfd_boolean constants_allowed
)
2373 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2382 char *__tl
= (char *) "0";
2388 op
->expp
= MSP_EXPP_ALL
;
2389 (void) parse_exp (__tl
, &(op
->exp
));
2391 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2393 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2403 ("this addressing mode is not applicable for destination operand"));
2409 /* Attempt to encode a MOVA instruction with the given operands.
2410 Returns the length of the encoded instruction if successful
2411 or 0 upon failure. If the encoding fails, an error message
2412 will be returned if a pointer is provided. */
2415 try_encode_mova (bfd_boolean imm_op
,
2417 struct msp430_operand_s
* op1
,
2418 struct msp430_operand_s
* op2
,
2419 const char ** error_message_return
)
2425 /* Only a restricted subset of the normal MSP430 addressing modes
2426 are supported here, so check for the ones that are allowed. */
2429 if (op1
->mode
== OP_EXP
)
2431 if (op2
->mode
!= OP_REG
)
2433 if (error_message_return
!= NULL
)
2434 * error_message_return
= _("expected register as second argument of %s");
2440 /* MOVA #imm20, Rdst. */
2441 bin
|= 0x80 | op2
->reg
;
2442 frag
= frag_more (4);
2443 where
= frag
- frag_now
->fr_literal
;
2444 if (op1
->exp
.X_op
== O_constant
)
2446 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2447 bfd_putl16 ((bfd_vma
) bin
, frag
);
2448 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2452 bfd_putl16 ((bfd_vma
) bin
, frag
);
2453 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2454 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2455 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2460 else if (op1
->am
== 1)
2462 /* MOVA z16(Rsrc), Rdst. */
2463 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2464 frag
= frag_more (4);
2465 where
= frag
- frag_now
->fr_literal
;
2466 bfd_putl16 ((bfd_vma
) bin
, frag
);
2467 if (op1
->exp
.X_op
== O_constant
)
2469 if (op1
->exp
.X_add_number
> 0xffff
2470 || op1
->exp
.X_add_number
< -(0x7fff))
2472 if (error_message_return
!= NULL
)
2473 * error_message_return
= _("index value too big for %s");
2476 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2480 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2481 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2483 BFD_RELOC_MSP430X_PCR16
:
2484 BFD_RELOC_MSP430X_ABS16
);
2489 if (error_message_return
!= NULL
)
2490 * error_message_return
= _("unexpected addressing mode for %s");
2493 else if (op1
->am
== 0)
2495 /* MOVA Rsrc, ... */
2496 if (op2
->mode
== OP_REG
)
2498 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2499 frag
= frag_more (2);
2500 where
= frag
- frag_now
->fr_literal
;
2501 bfd_putl16 ((bfd_vma
) bin
, frag
);
2504 else if (op2
->am
== 1)
2508 /* MOVA Rsrc, &abs20. */
2509 bin
|= 0x60 | (op1
->reg
<< 8);
2510 frag
= frag_more (4);
2511 where
= frag
- frag_now
->fr_literal
;
2512 if (op2
->exp
.X_op
== O_constant
)
2514 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2515 bfd_putl16 ((bfd_vma
) bin
, frag
);
2516 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2520 bfd_putl16 ((bfd_vma
) bin
, frag
);
2521 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2522 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2523 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2528 /* MOVA Rsrc, z16(Rdst). */
2529 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2530 frag
= frag_more (4);
2531 where
= frag
- frag_now
->fr_literal
;
2532 bfd_putl16 ((bfd_vma
) bin
, frag
);
2533 if (op2
->exp
.X_op
== O_constant
)
2535 if (op2
->exp
.X_add_number
> 0xffff
2536 || op2
->exp
.X_add_number
< -(0x7fff))
2538 if (error_message_return
!= NULL
)
2539 * error_message_return
= _("index value too big for %s");
2542 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2546 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2547 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2549 BFD_RELOC_MSP430X_PCR16
:
2550 BFD_RELOC_MSP430X_ABS16
);
2555 if (error_message_return
!= NULL
)
2556 * error_message_return
= _("unexpected addressing mode for %s");
2561 /* imm_op == FALSE. */
2563 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2565 /* MOVA &abs20, Rdst. */
2566 if (op2
->mode
!= OP_REG
)
2568 if (error_message_return
!= NULL
)
2569 * error_message_return
= _("expected register as second argument of %s");
2573 if (op2
->reg
== 2 || op2
->reg
== 3)
2575 if (error_message_return
!= NULL
)
2576 * error_message_return
= _("constant generator destination register found in %s");
2580 bin
|= 0x20 | op2
->reg
;
2581 frag
= frag_more (4);
2582 where
= frag
- frag_now
->fr_literal
;
2583 if (op1
->exp
.X_op
== O_constant
)
2585 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2586 bfd_putl16 ((bfd_vma
) bin
, frag
);
2587 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2591 bfd_putl16 ((bfd_vma
) bin
, frag
);
2592 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2593 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2594 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2598 else if (op1
->mode
== OP_REG
)
2602 /* MOVA @Rsrc+, Rdst. */
2603 if (op2
->mode
!= OP_REG
)
2605 if (error_message_return
!= NULL
)
2606 * error_message_return
= _("expected register as second argument of %s");
2610 if (op2
->reg
== 2 || op2
->reg
== 3)
2612 if (error_message_return
!= NULL
)
2613 * error_message_return
= _("constant generator destination register found in %s");
2617 if (op1
->reg
== 2 || op1
->reg
== 3)
2619 if (error_message_return
!= NULL
)
2620 * error_message_return
= _("constant generator source register found in %s");
2624 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2625 frag
= frag_more (2);
2626 where
= frag
- frag_now
->fr_literal
;
2627 bfd_putl16 ((bfd_vma
) bin
, frag
);
2630 else if (op1
->am
== 2)
2632 /* MOVA @Rsrc,Rdst */
2633 if (op2
->mode
!= OP_REG
)
2635 if (error_message_return
!= NULL
)
2636 * error_message_return
= _("expected register as second argument of %s");
2640 if (op2
->reg
== 2 || op2
->reg
== 3)
2642 if (error_message_return
!= NULL
)
2643 * error_message_return
= _("constant generator destination register found in %s");
2647 if (op1
->reg
== 2 || op1
->reg
== 3)
2649 if (error_message_return
!= NULL
)
2650 * error_message_return
= _("constant generator source register found in %s");
2654 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2655 frag
= frag_more (2);
2656 where
= frag
- frag_now
->fr_literal
;
2657 bfd_putl16 ((bfd_vma
) bin
, frag
);
2662 if (error_message_return
!= NULL
)
2663 * error_message_return
= _("unexpected addressing mode for %s");
2668 #define NOP_CHECK_INTERRUPT (1 << 0)
2669 #define NOP_CHECK_CPU12 (1 << 1)
2670 #define NOP_CHECK_CPU19 (1 << 2)
2672 static signed int check_for_nop
= 0;
2674 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2676 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2677 For MOV insns, more sophisticated processing is needed to determine if they
2678 result in enabling/disabling interrupts. */
2679 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2680 || ((strcmp (OPCODE, "bic") == 0) \
2682 || ((strcmp (OPCODE, "clr") == 0) \
2685 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2686 || ((strcmp (OPCODE, "bis") == 0) \
2689 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2690 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2691 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2692 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2693 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2694 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2696 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2697 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2698 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2699 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2700 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2701 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2707 frag
= frag_more (2);
2708 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2709 dwarf2_emit_insn (2);
2712 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2715 warn_eint_nop (bfd_boolean prev_insn_is_nop
, bfd_boolean prev_insn_is_dint
)
2717 if (prev_insn_is_nop
2718 /* If the last insn was a DINT, we will have already warned that a NOP is
2719 required after it. */
2720 || prev_insn_is_dint
2721 /* 430 ISA does not require a NOP before EINT. */
2722 || (! target_is_430x ()))
2725 if (gen_interrupt_nops
)
2728 if (warn_interrupt_nops
)
2729 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2731 else if (warn_interrupt_nops
)
2732 as_warn (_(WARN_NOP_BEFORE_EINT
));
2735 /* Use when unsure what effect the insn will have on the interrupt status,
2736 to insert/warn about adding a NOP before the current insn. */
2739 warn_unsure_interrupt (bfd_boolean prev_insn_is_nop
,
2740 bfd_boolean prev_insn_is_dint
)
2742 if (prev_insn_is_nop
2743 /* If the last insn was a DINT, we will have already warned that a NOP is
2744 required after it. */
2745 || prev_insn_is_dint
2746 /* 430 ISA does not require a NOP before EINT or DINT. */
2747 || (! target_is_430x ()))
2750 if (gen_interrupt_nops
)
2753 if (warn_interrupt_nops
)
2754 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2756 else if (warn_interrupt_nops
)
2757 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2760 /* Parse instruction operands.
2761 Return binary opcode. */
2764 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2766 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2767 int insn_length
= 0;
2768 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2772 struct msp430_operand_s op1
, op2
;
2774 static short ZEROS
= 0;
2775 bfd_boolean byte_op
, imm_op
;
2778 int extended
= 0x1800;
2779 bfd_boolean extended_op
= FALSE
;
2780 bfd_boolean addr_op
;
2781 const char * error_message
;
2782 static signed int repeat_count
= 0;
2783 static bfd_boolean prev_insn_is_nop
= FALSE
;
2784 static bfd_boolean prev_insn_is_dint
= FALSE
;
2785 static bfd_boolean prev_insn_is_eint
= FALSE
;
2786 /* We might decide before the end of the function that the current insn is
2787 equivalent to DINT/EINT. */
2788 bfd_boolean this_insn_is_dint
= FALSE
;
2789 bfd_boolean this_insn_is_eint
= FALSE
;
2790 bfd_boolean fix_emitted
;
2792 /* Opcode is the one from opcodes table
2793 line contains something like
2802 bfd_boolean check
= FALSE
;
2805 switch (TOLOWER (* line
))
2808 /* Byte operation. */
2809 bin
|= BYTE_OPERATION
;
2815 /* "Address" ops work on 20-bit values. */
2817 bin
|= BYTE_OPERATION
;
2822 /* Word operation - this is the default. */
2830 as_warn (_("no size modifier after period, .w assumed"));
2834 as_bad (_("unrecognised instruction size modifier .%c"),
2846 if (*line
&& ! ISSPACE (*line
))
2848 as_bad (_("junk found after instruction: %s.%s"),
2849 opcode
->name
, line
);
2853 /* Catch the case where the programmer has used a ".a" size modifier on an
2854 instruction that does not support it. Look for an alternative extended
2855 instruction that has the same name without the period. Eg: "add.a"
2856 becomes "adda". Although this not an officially supported way of
2857 specifying instruction aliases other MSP430 assemblers allow it. So we
2858 support it for compatibility purposes. */
2859 if (addr_op
&& opcode
->fmt
>= 0)
2861 const char * old_name
= opcode
->name
;
2864 sprintf (real_name
, "%sa", old_name
);
2865 opcode
= str_hash_find (msp430_hash
, real_name
);
2868 as_bad (_("instruction %s.a does not exist"), old_name
);
2871 #if 0 /* Enable for debugging. */
2872 as_warn ("treating %s.a as %s", old_name
, real_name
);
2875 bin
= opcode
->bin_opcode
;
2878 if (opcode
->fmt
!= -1
2879 && opcode
->insn_opnumb
2880 && (!*line
|| *line
== '\n'))
2882 as_bad (ngettext ("instruction %s requires %d operand",
2883 "instruction %s requires %d operands",
2884 opcode
->insn_opnumb
),
2885 opcode
->name
, opcode
->insn_opnumb
);
2889 memset (l1
, 0, sizeof (l1
));
2890 memset (l2
, 0, sizeof (l2
));
2891 memset (&op1
, 0, sizeof (op1
));
2892 memset (&op2
, 0, sizeof (op2
));
2896 if ((fmt
= opcode
->fmt
) < 0)
2898 if (! target_is_430x ())
2900 as_bad (_("instruction %s requires MSP430X mcu"),
2911 /* If requested set the extended instruction repeat count. */
2914 if (repeat_count
> 0)
2915 extended
|= (repeat_count
- 1);
2917 extended
|= (1 << 7) | (- repeat_count
);
2920 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2925 /* The previous instruction set this flag if it wants to check if this insn
2929 if (! is_opcode ("nop"))
2933 switch (check_for_nop
& - check_for_nop
)
2935 case NOP_CHECK_INTERRUPT
:
2936 /* NOP_CHECK_INTERRUPT rules:
2937 1. 430 and 430x ISA require a NOP after DINT.
2938 2. Only the 430x ISA requires NOP before EINT (this has
2939 been dealt with in the previous call to this function).
2940 3. Only the 430x ISA requires NOP after every EINT.
2942 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2944 if (prev_insn_is_dint
)
2946 if (gen_interrupt_nops
)
2949 if (warn_interrupt_nops
)
2950 as_warn (_(INSERT_NOP_AFTER_DINT
));
2953 as_warn (_(WARN_NOP_AFTER_DINT
));
2955 else if (prev_insn_is_eint
)
2957 if (gen_interrupt_nops
)
2960 if (warn_interrupt_nops
)
2961 as_warn (_(INSERT_NOP_AFTER_EINT
));
2964 as_warn (_(WARN_NOP_AFTER_EINT
));
2966 /* If we get here it's because the last instruction was
2967 determined to either disable or enable interrupts, but
2968 we're not sure which.
2969 We have no information yet about what effect the
2970 current instruction has on interrupts, that has to be
2972 The last insn may have required a NOP after it, so we
2973 deal with that now. */
2976 if (gen_interrupt_nops
)
2979 if (warn_interrupt_nops
)
2980 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2983 /* warn_unsure_interrupt was called on the previous
2985 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
2990 case NOP_CHECK_CPU12
:
2991 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
2992 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2994 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
2998 case NOP_CHECK_CPU19
:
2999 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
3000 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
3002 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
3007 as_bad (_("internal error: unknown nop check state"));
3010 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
3012 while (check_for_nop
);
3021 switch (opcode
->insn_opnumb
)
3024 if (is_opcode ("eint"))
3025 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3027 /* Set/clear bits instructions. */
3031 extended
|= BYTE_OPERATION
;
3033 /* Emit the extension word. */
3035 frag
= frag_more (2);
3036 bfd_putl16 (extended
, frag
);
3040 frag
= frag_more (2);
3041 bfd_putl16 ((bfd_vma
) bin
, frag
);
3042 dwarf2_emit_insn (insn_length
);
3046 /* Something which works with destination operand. */
3047 line
= extract_operand (line
, l1
, sizeof (l1
));
3048 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
3052 bin
|= (op1
.reg
| (op1
.am
<< 7));
3054 /* If the PC is the destination... */
3055 if (op1
.am
== 0 && op1
.reg
== 0
3056 /* ... and the opcode alters the SR. */
3057 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3058 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3060 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3061 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3062 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3063 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3066 /* If the status register is the destination... */
3067 if (op1
.am
== 0 && op1
.reg
== 2
3068 /* ... and the opcode alters the SR. */
3069 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
3070 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
3071 || is_opcode ("sbc") || is_opcode ("sxt")
3072 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
3073 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
3074 || is_opcode ("sbcx")
3077 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3078 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3079 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3080 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3083 /* Compute the entire instruction length, in bytes. */
3084 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3085 insn_length
+= op_length
;
3086 frag
= frag_more (op_length
);
3087 where
= frag
- frag_now
->fr_literal
;
3092 extended
|= BYTE_OPERATION
;
3094 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3096 as_bad (_("repeat instruction used with non-register mode instruction"));
3100 if (op1
.mode
== OP_EXP
)
3102 if (op1
.exp
.X_op
== O_constant
)
3103 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3105 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3106 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3107 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3109 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3110 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3113 /* Emit the extension word. */
3114 bfd_putl16 (extended
, frag
);
3119 bfd_putl16 ((bfd_vma
) bin
, frag
);
3123 if (op1
.mode
== OP_EXP
)
3125 if (op1
.exp
.X_op
== O_constant
)
3127 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3131 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3136 fix_new_exp (frag_now
, where
, 2,
3137 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3139 fix_new_exp (frag_now
, where
, 2,
3140 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3145 dwarf2_emit_insn (insn_length
);
3149 /* Shift instruction. */
3150 line
= extract_operand (line
, l1
, sizeof (l1
));
3151 strncpy (l2
, l1
, sizeof (l2
));
3152 l2
[sizeof (l2
) - 1] = '\0';
3153 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3154 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3157 break; /* An error occurred. All warnings were done before. */
3159 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
3160 frag
= frag_more (insn_length
);
3161 where
= frag
- frag_now
->fr_literal
;
3163 if (target_is_430xv2 ()
3164 && op1
.mode
== OP_REG
3166 && (is_opcode ("rlax")
3167 || is_opcode ("rlcx")
3168 || is_opcode ("rla")
3169 || is_opcode ("rlc")))
3171 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3175 /* If the status register is the destination... */
3176 if (op1
.am
== 0 && op1
.reg
== 2
3177 /* ... and the opcode alters the SR. */
3178 && (is_opcode ("rla") || is_opcode ("rlc")
3179 || is_opcode ("rlax") || is_opcode ("rlcx")
3180 || is_opcode ("sxt") || is_opcode ("sxtx")
3181 || is_opcode ("swpb")
3184 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3185 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3186 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3187 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3193 extended
|= BYTE_OPERATION
;
3195 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3197 as_bad (_("repeat instruction used with non-register mode instruction"));
3201 if (op1
.mode
== OP_EXP
)
3203 if (op1
.exp
.X_op
== O_constant
)
3204 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3206 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3207 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3208 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3210 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3211 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3214 if (op2
.mode
== OP_EXP
)
3216 if (op2
.exp
.X_op
== O_constant
)
3217 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3219 else if (op1
.mode
== OP_EXP
)
3220 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3221 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3222 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3224 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3225 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3226 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3229 /* Emit the extension word. */
3230 bfd_putl16 (extended
, frag
);
3235 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3236 bfd_putl16 ((bfd_vma
) bin
, frag
);
3240 if (op1
.mode
== OP_EXP
)
3242 if (op1
.exp
.X_op
== O_constant
)
3244 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3248 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3252 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3253 fix_new_exp (frag_now
, where
, 2,
3254 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3256 fix_new_exp (frag_now
, where
, 2,
3257 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3264 if (op2
.mode
== OP_EXP
)
3266 if (op2
.exp
.X_op
== O_constant
)
3268 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3272 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3276 if (op2
.reg
) /* Not PC relative. */
3277 fix_new_exp (frag_now
, where
, 2,
3278 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3280 fix_new_exp (frag_now
, where
, 2,
3281 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3286 dwarf2_emit_insn (insn_length
);
3290 /* Branch instruction => mov dst, r0. */
3293 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3297 line
= extract_operand (line
, l1
, sizeof (l1
));
3298 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3304 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3305 op_length
= 2 + 2 * op1
.ol
;
3306 frag
= frag_more (op_length
);
3307 where
= frag
- frag_now
->fr_literal
;
3308 bfd_putl16 ((bfd_vma
) bin
, frag
);
3310 if (op1
.mode
== OP_EXP
)
3312 if (op1
.exp
.X_op
== O_constant
)
3314 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3320 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3322 if (op1
.reg
|| op1
.am
== 3)
3323 fix_new_exp (frag_now
, where
, 2,
3324 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3326 fix_new_exp (frag_now
, where
, 2,
3327 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3331 dwarf2_emit_insn (insn_length
+ op_length
);
3335 /* CALLA instructions. */
3336 fix_emitted
= FALSE
;
3338 line
= extract_operand (line
, l1
, sizeof (l1
));
3341 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3342 extended_op
, FALSE
);
3348 op_length
= 2 + 2 * op1
.ol
;
3349 frag
= frag_more (op_length
);
3350 where
= frag
- frag_now
->fr_literal
;
3358 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3359 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3362 else if (op1
.am
== 1)
3368 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3369 BFD_RELOC_MSP430X_PCR20_CALL
);
3373 bin
|= 0x50 | op1
.reg
;
3375 else if (op1
.am
== 0)
3376 bin
|= 0x40 | op1
.reg
;
3378 else if (op1
.am
== 1)
3382 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3383 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3386 else if (op1
.am
== 2)
3387 bin
|= 0x60 | op1
.reg
;
3388 else if (op1
.am
== 3)
3389 bin
|= 0x70 | op1
.reg
;
3391 bfd_putl16 ((bfd_vma
) bin
, frag
);
3393 if (op1
.mode
== OP_EXP
)
3397 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3401 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3404 fix_new_exp (frag_now
, where
+ 2, 2,
3405 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3408 dwarf2_emit_insn (insn_length
+ op_length
);
3416 /* [POP|PUSH]M[.A] #N, Rd */
3417 line
= extract_operand (line
, l1
, sizeof (l1
));
3418 line
= extract_operand (line
, l2
, sizeof (l2
));
3422 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3425 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3426 if (end
!= NULL
&& *end
!= 0)
3428 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3431 if (op1
.exp
.X_op
!= O_constant
)
3433 as_bad (_("expected constant expression as first argument of %s"),
3438 if ((reg
= check_reg (l2
)) == -1)
3440 as_bad (_("expected register as second argument of %s"),
3446 frag
= frag_more (op_length
);
3447 where
= frag
- frag_now
->fr_literal
;
3448 bin
= opcode
->bin_opcode
;
3451 n
= op1
.exp
.X_add_number
;
3452 bin
|= (n
- 1) << 4;
3453 if (is_opcode ("pushm"))
3457 if (reg
- n
+ 1 < 0)
3459 as_bad (_("Too many registers popped"));
3463 /* CPU21 errata: cannot use POPM to restore the SR register. */
3464 if (target_is_430xv2 ()
3465 && (reg
- n
+ 1 < 3)
3467 && is_opcode ("popm"))
3469 as_bad (_("Cannot use POPM to restore the SR register"));
3473 bin
|= (reg
- n
+ 1);
3476 bfd_putl16 ((bfd_vma
) bin
, frag
);
3477 dwarf2_emit_insn (op_length
);
3486 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3487 if (extended
& 0xff)
3489 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3493 line
= extract_operand (line
, l1
, sizeof (l1
));
3494 line
= extract_operand (line
, l2
, sizeof (l2
));
3498 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3501 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3502 if (end
!= NULL
&& *end
!= 0)
3504 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3507 if (op1
.exp
.X_op
!= O_constant
)
3509 as_bad (_("expected constant expression as first argument of %s"),
3513 n
= op1
.exp
.X_add_number
;
3516 as_bad (_("expected first argument of %s to be in the range 1-4"),
3521 if ((reg
= check_reg (l2
)) == -1)
3523 as_bad (_("expected register as second argument of %s"),
3528 if (target_is_430xv2 () && reg
== 0)
3530 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3535 frag
= frag_more (op_length
);
3536 where
= frag
- frag_now
->fr_literal
;
3538 bin
= opcode
->bin_opcode
;
3541 bin
|= (n
- 1) << 10;
3544 bfd_putl16 ((bfd_vma
) bin
, frag
);
3545 dwarf2_emit_insn (op_length
);
3551 bfd_boolean need_reloc
= FALSE
;
3555 /* ADDA, CMPA and SUBA address instructions. */
3556 if (extended
& 0xff)
3558 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3562 line
= extract_operand (line
, l1
, sizeof (l1
));
3563 line
= extract_operand (line
, l2
, sizeof (l2
));
3565 bin
= opcode
->bin_opcode
;
3569 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3570 if (end
!= NULL
&& *end
!= 0)
3572 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3576 if (op1
.exp
.X_op
== O_constant
)
3578 n
= op1
.exp
.X_add_number
;
3579 if (n
> 0xfffff || n
< - (0x7ffff))
3581 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3586 bin
|= ((n
>> 16) & 0xf) << 8;
3598 if ((n
= check_reg (l1
)) == -1)
3600 as_bad (_("expected register name or constant as first argument of %s"),
3605 bin
|= (n
<< 8) | (1 << 6);
3609 if ((reg
= check_reg (l2
)) == -1)
3611 as_bad (_("expected register as second argument of %s"),
3616 frag
= frag_more (op_length
);
3617 where
= frag
- frag_now
->fr_literal
;
3620 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3621 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3623 bfd_putl16 ((bfd_vma
) bin
, frag
);
3625 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3626 dwarf2_emit_insn (op_length
);
3630 case 9: /* MOVA, BRA, RETA. */
3632 bin
= opcode
->bin_opcode
;
3634 if (is_opcode ("reta"))
3636 /* The RETA instruction does not take any arguments.
3637 The implicit first argument is @SP+.
3638 The implicit second argument is PC. */
3648 line
= extract_operand (line
, l1
, sizeof (l1
));
3649 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3650 &imm_op
, extended_op
, FALSE
);
3652 if (is_opcode ("bra"))
3654 /* This is the BRA synthetic instruction.
3655 The second argument is always PC. */
3661 line
= extract_operand (line
, l2
, sizeof (l2
));
3662 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3667 break; /* Error occurred. All warnings were done before. */
3670 /* Only a restricted subset of the normal MSP430 addressing modes
3671 are supported here, so check for the ones that are allowed. */
3672 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3673 & error_message
)) == 0)
3675 as_bad (error_message
, opcode
->name
);
3678 dwarf2_emit_insn (op_length
);
3682 line
= extract_operand (line
, l1
, sizeof l1
);
3683 /* The RPT instruction only accepted immediates and registers. */
3686 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3687 if (end
!= NULL
&& *end
!= 0)
3689 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3692 if (op1
.exp
.X_op
!= O_constant
)
3694 as_bad (_("expected constant value as argument to RPT"));
3697 if (op1
.exp
.X_add_number
< 1
3698 || op1
.exp
.X_add_number
> (1 << 4))
3700 as_bad (_("expected constant in the range 2..16"));
3704 /* We silently accept and ignore a repeat count of 1. */
3705 if (op1
.exp
.X_add_number
> 1)
3706 repeat_count
= op1
.exp
.X_add_number
;
3712 if ((reg
= check_reg (l1
)) != -1)
3715 as_warn (_("PC used as an argument to RPT"));
3717 repeat_count
= - reg
;
3721 as_bad (_("expected constant or register name as argument to RPT insn"));
3728 as_bad (_("Illegal emulated instruction"));
3733 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3734 From f5 ref man 6.3.3:
3735 The 16-bit Status Register (SR, also called R2), used as a source or
3736 destination register, can only be used in register mode addressed
3737 with word instructions. */
3739 case 1: /* Format 1, double operand. */
3740 line
= extract_operand (line
, l1
, sizeof (l1
));
3741 line
= extract_operand (line
, l2
, sizeof (l2
));
3742 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3743 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3746 break; /* Error occurred. All warnings were done before. */
3749 && is_opcode ("movx")
3751 && msp430_enable_relax
)
3753 /* This is the MOVX.A instruction. See if we can convert
3754 it into the MOVA instruction instead. This saves 2 bytes. */
3755 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3758 dwarf2_emit_insn (op_length
);
3763 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3765 /* If the PC is the destination... */
3766 if (op2
.am
== 0 && op2
.reg
== 0
3767 /* ... and the opcode alters the SR. */
3768 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3769 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3771 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3772 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3773 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3774 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3777 /* If the status register is the destination... */
3778 if (op2
.am
== 0 && op2
.reg
== 2
3779 /* ... and the opcode alters the SR. */
3780 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3781 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3782 || is_opcode ("xor")
3783 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3784 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3785 || is_opcode ("xorx")
3788 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3789 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3790 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3791 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3794 /* Chain these checks for SR manipulations so we can warn if they are not
3796 if (((is_opcode ("bis") && bin
== 0xd032)
3797 || (is_opcode ("mov") && bin
== 0x4032)
3798 || (is_opcode ("xor") && bin
== 0xe032))
3799 && op1
.mode
== OP_EXP
3800 && op1
.exp
.X_op
== O_constant
3801 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3802 check_for_nop
|= NOP_CHECK_CPU19
;
3803 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3805 /* Any MOV with the SR as the destination either enables or disables
3807 if (op1
.mode
== OP_EXP
3808 && op1
.exp
.X_op
== O_constant
)
3810 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3812 /* The GIE bit is being set. */
3813 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3814 this_insn_is_eint
= TRUE
;
3817 /* The GIE bit is being cleared. */
3818 this_insn_is_dint
= TRUE
;
3820 /* If an immediate value which is covered by the constant generator
3821 is the src, then op1 will have been changed to either R2 or R3 by
3823 The only constants covered by CG1 and CG2, which have bit 3 set
3824 and therefore would enable interrupts when writing to the SR, are
3825 R2 with addresing mode 0b11 and R3 with 0b11.
3826 The addressing mode is in bits 5:4 of the binary opcode. */
3827 else if (op1
.mode
== OP_REG
3828 && (op1
.reg
== 2 || op1
.reg
== 3)
3829 && (bin
& 0x30) == 0x30)
3831 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3832 this_insn_is_eint
= TRUE
;
3834 /* Any other use of the constant generator with destination R2, will
3835 disable interrupts. */
3836 else if (op1
.mode
== OP_REG
3837 && (op1
.reg
== 2 || op1
.reg
== 3))
3838 this_insn_is_dint
= TRUE
;
3839 else if (do_unknown_interrupt_nops
)
3841 /* FIXME: Couldn't work out whether the insn is enabling or
3842 disabling interrupts, so for safety need to treat it as both
3844 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3845 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3848 else if (is_eint (opcode
->name
, bin
))
3849 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3850 else if ((bin
& 0x32) == 0x32)
3852 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3853 * an interrupt state change if a write happens. */
3854 /* FIXME: How strict to be here? */
3858 /* Compute the entire length of the instruction in bytes. */
3859 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3860 + 2 /* The opcode */
3861 + (2 * op1
.ol
) /* The first operand. */
3862 + (2 * op2
.ol
); /* The second operand. */
3864 insn_length
+= op_length
;
3865 frag
= frag_more (op_length
);
3866 where
= frag
- frag_now
->fr_literal
;
3871 extended
|= BYTE_OPERATION
;
3873 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3875 as_bad (_("repeat instruction used with non-register mode instruction"));
3879 /* If necessary, emit a reloc to update the extension word. */
3880 if (op1
.mode
== OP_EXP
)
3882 if (op1
.exp
.X_op
== O_constant
)
3883 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3885 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3886 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3887 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3889 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3890 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3893 if (op2
.mode
== OP_EXP
)
3895 if (op2
.exp
.X_op
== O_constant
)
3896 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3898 else if (op1
.mode
== OP_EXP
)
3899 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3900 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3901 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3904 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3905 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3906 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3909 /* Emit the extension word. */
3910 bfd_putl16 (extended
, frag
);
3915 bfd_putl16 ((bfd_vma
) bin
, frag
);
3919 if (op1
.mode
== OP_EXP
)
3921 if (op1
.exp
.X_op
== O_constant
)
3923 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3927 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3931 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3932 fix_new_exp (frag_now
, where
, 2,
3933 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3935 fix_new_exp (frag_now
, where
, 2,
3936 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3944 if (op2
.mode
== OP_EXP
)
3946 if (op2
.exp
.X_op
== O_constant
)
3948 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3952 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3956 if (op2
.reg
) /* Not PC relative. */
3957 fix_new_exp (frag_now
, where
, 2,
3958 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3960 fix_new_exp (frag_now
, where
, 2,
3961 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3966 dwarf2_emit_insn (insn_length
);
3968 /* If the PC is the destination... */
3969 if (op2
.am
== 0 && op2
.reg
== 0
3970 /* ... but the opcode does not alter the destination. */
3971 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3972 check_for_nop
|= NOP_CHECK_CPU12
;
3975 case 2: /* Single-operand mostly instr. */
3976 if (opcode
->insn_opnumb
== 0)
3978 /* reti instruction. */
3980 frag
= frag_more (2);
3981 bfd_putl16 ((bfd_vma
) bin
, frag
);
3982 dwarf2_emit_insn (insn_length
);
3986 line
= extract_operand (line
, l1
, sizeof (l1
));
3987 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3988 &imm_op
, extended_op
, TRUE
);
3990 break; /* Error in operand. */
3992 if (target_is_430xv2 ()
3993 && op1
.mode
== OP_REG
3995 && (is_opcode ("rrax")
3996 || is_opcode ("rrcx")
3997 || is_opcode ("rra")
3998 || is_opcode ("rrc")))
4000 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
4004 /* If the status register is the destination... */
4005 if (op1
.am
== 0 && op1
.reg
== 2
4006 /* ... and the opcode alters the SR. */
4007 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
4009 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
4010 as_bad (_("CPU13: SR is destination of SR altering instruction"));
4011 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
4012 as_warn (_("CPU13: SR is destination of SR altering instruction"));
4015 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
4016 frag
= frag_more (insn_length
);
4017 where
= frag
- frag_now
->fr_literal
;
4021 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
4023 /* These two instructions use a special
4024 encoding of the A/L and B/W bits. */
4025 bin
&= ~ BYTE_OPERATION
;
4029 as_bad (_("%s instruction does not accept a .b suffix"),
4034 extended
|= BYTE_OPERATION
;
4037 extended
|= BYTE_OPERATION
;
4039 if (is_opcode ("rrux"))
4040 extended
|= IGNORE_CARRY_BIT
;
4042 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
4044 as_bad (_("repeat instruction used with non-register mode instruction"));
4048 if (op1
.mode
== OP_EXP
)
4050 if (op1
.exp
.X_op
== O_constant
)
4051 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
4053 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4054 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4055 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
4057 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4058 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
4061 /* Emit the extension word. */
4062 bfd_putl16 (extended
, frag
);
4067 bin
|= op1
.reg
| (op1
.am
<< 4);
4068 bfd_putl16 ((bfd_vma
) bin
, frag
);
4072 if (op1
.mode
== OP_EXP
)
4074 if (op1
.exp
.X_op
== O_constant
)
4076 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
4080 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
4084 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4085 fix_new_exp (frag_now
, where
, 2,
4086 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
4088 fix_new_exp (frag_now
, where
, 2,
4089 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
4094 dwarf2_emit_insn (insn_length
);
4097 case 3: /* Conditional jumps instructions. */
4098 line
= extract_operand (line
, l1
, sizeof (l1
));
4099 /* l1 is a label. */
4108 end
= parse_exp (m
, &exp
);
4109 if (end
!= NULL
&& *end
!= 0)
4111 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4115 /* In order to handle something like:
4119 jz 4 ; skip next 4 bytes
4122 nop ; will jump here if r5 positive or zero
4124 jCOND -n ;assumes jump n bytes backward:
4134 jCOND $n ; jump from PC in either direction. */
4136 if (exp
.X_op
== O_constant
)
4138 int x
= exp
.X_add_number
;
4142 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
4146 if ((*l1
== '$' && x
> 0) || x
< 0)
4151 if (x
> 512 || x
< -511)
4153 as_bad (_("Wrong displacement %d"), x
<< 1);
4158 frag
= frag_more (2); /* Instr size is 1 word. */
4161 bfd_putl16 ((bfd_vma
) bin
, frag
);
4163 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4166 frag
= frag_more (2); /* Instr size is 1 word. */
4167 where
= frag
- frag_now
->fr_literal
;
4168 fix_new_exp (frag_now
, where
, 2,
4169 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
4171 bfd_putl16 ((bfd_vma
) bin
, frag
);
4173 else if (*l1
== '$')
4175 as_bad (_("instruction requires label sans '$'"));
4179 ("instruction requires label or value in range -511:512"));
4180 dwarf2_emit_insn (insn_length
);
4185 as_bad (_("instruction requires label"));
4190 case 4: /* Extended jumps. */
4191 if (!msp430_enable_polys
)
4193 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4197 line
= extract_operand (line
, l1
, sizeof (l1
));
4203 /* Ignore absolute addressing. make it PC relative anyway. */
4204 if (*m
== '#' || *m
== '$')
4207 end
= parse_exp (m
, & exp
);
4208 if (end
!= NULL
&& *end
!= 0)
4210 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4213 if (exp
.X_op
== O_symbol
)
4215 /* Relaxation required. */
4216 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4218 if (target_is_430x ())
4219 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4221 /* The parameter to dwarf2_emit_insn is actually the offset to
4222 the start of the insn from the fix piece of instruction that
4223 was emitted. Since next fragments may have variable size we
4224 tie debug info to the beginning of the instruction. */
4226 frag
= frag_more (8);
4227 dwarf2_emit_insn (0);
4228 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4229 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4231 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4233 0, /* Offset is zero if jump dist less than 1K. */
4239 as_bad (_("instruction requires label"));
4242 case 5: /* Emulated extended branches. */
4243 if (!msp430_enable_polys
)
4245 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4248 line
= extract_operand (line
, l1
, sizeof (l1
));
4254 /* Ignore absolute addressing. make it PC relative anyway. */
4255 if (*m
== '#' || *m
== '$')
4258 end
= parse_exp (m
, & exp
);
4259 if (end
!= NULL
&& *end
!= 0)
4261 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4264 if (exp
.X_op
== O_symbol
)
4266 /* Relaxation required. */
4267 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4269 if (target_is_430x ())
4270 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4273 frag
= frag_more (8);
4274 dwarf2_emit_insn (0);
4275 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4276 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4278 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4279 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4281 0, /* Offset is zero if jump dist less than 1K. */
4287 as_bad (_("instruction requires label"));
4291 as_bad (_("Illegal instruction or not implemented opcode."));
4294 if (is_opcode ("nop"))
4296 prev_insn_is_nop
= TRUE
;
4297 prev_insn_is_dint
= FALSE
;
4298 prev_insn_is_eint
= FALSE
;
4300 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4302 prev_insn_is_dint
= TRUE
;
4303 prev_insn_is_eint
= FALSE
;
4304 prev_insn_is_nop
= FALSE
;
4305 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4307 /* NOP is not needed after EINT for 430 ISA. */
4308 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4310 prev_insn_is_eint
= TRUE
;
4311 prev_insn_is_nop
= FALSE
;
4312 prev_insn_is_dint
= FALSE
;
4313 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4317 prev_insn_is_nop
= FALSE
;
4318 prev_insn_is_dint
= FALSE
;
4319 prev_insn_is_eint
= FALSE
;
4322 input_line_pointer
= line
;
4327 md_assemble (char * str
)
4329 struct msp430_opcode_s
* opcode
;
4333 str
= skip_space (str
); /* Skip leading spaces. */
4334 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4338 char a
= TOLOWER (cmd
[i
]);
4345 as_bad (_("can't find opcode"));
4349 opcode
= (struct msp430_opcode_s
*) str_hash_find (msp430_hash
, cmd
);
4353 as_bad (_("unknown opcode `%s'"), cmd
);
4358 char *__t
= input_line_pointer
;
4360 msp430_operands (opcode
, str
);
4361 input_line_pointer
= __t
;
4365 /* GAS will call this function for each section at the end of the assembly,
4366 to permit the CPU backend to adjust the alignment of a section. */
4369 md_section_align (asection
* seg
, valueT addr
)
4371 int align
= bfd_section_alignment (seg
);
4373 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4376 /* If you define this macro, it should return the offset between the
4377 address of a PC relative fixup and the position from which the PC
4378 relative adjustment should be made. On many processors, the base
4379 of a PC relative instruction is the next instruction, so this
4380 macro would return the length of an instruction. */
4383 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4385 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4386 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4387 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4390 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4393 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4394 Now it handles the situation when relocations
4395 have to be passed to linker. */
4397 msp430_force_relocation_local (fixS
*fixp
)
4399 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4403 if (msp430_enable_polys
4404 && !msp430_enable_relax
)
4411 /* GAS will call this for each fixup. It should store the correct
4412 value in the object file. */
4414 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4416 unsigned char * where
;
4420 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4425 else if (fixp
->fx_pcrel
)
4427 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4429 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4431 /* FIXME: We can appear here only in case if we perform a pc
4432 relative jump to the label which is i) global, ii) locally
4433 defined or this is a jump to an absolute symbol.
4434 If this is an absolute symbol -- everything is OK.
4435 If this is a global label, we've got a symbol value defined
4437 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4438 from this section start
4439 2. *valuep will contain the real offset from jump insn to the
4441 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4442 will be incorrect. Therefore remove s_get_value. */
4443 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4451 value
= fixp
->fx_offset
;
4453 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4455 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4457 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4463 fixp
->fx_no_overflow
= 1;
4465 /* If polymorphs are enabled and relax disabled.
4466 do not kill any relocs and pass them to linker. */
4467 if (msp430_enable_polys
4468 && !msp430_enable_relax
)
4471 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4472 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4479 /* Fetch the instruction, insert the fully resolved operand
4480 value, and stuff the instruction back again. */
4481 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4483 insn
= bfd_getl16 (where
);
4485 switch (fixp
->fx_r_type
)
4487 case BFD_RELOC_MSP430_10_PCREL
:
4489 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4490 _("odd address operand: %ld"), value
);
4492 /* Jumps are in words. */
4494 --value
; /* Correct PC. */
4496 if (value
< -512 || value
> 511)
4497 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4498 _("operand out of range: %ld"), value
);
4500 value
&= 0x3ff; /* get rid of extended sign */
4501 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4504 case BFD_RELOC_MSP430X_PCR16
:
4505 case BFD_RELOC_MSP430_RL_PCREL
:
4506 case BFD_RELOC_MSP430_16_PCREL
:
4508 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4509 _("odd address operand: %ld"), value
);
4512 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4513 /* Nothing to be corrected here. */
4514 if (value
< -32768 || value
> 65536)
4515 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4516 _("operand out of range: %ld"), value
);
4519 case BFD_RELOC_MSP430X_ABS16
:
4520 case BFD_RELOC_MSP430_16
:
4522 case BFD_RELOC_MSP430_16_BYTE
:
4523 value
&= 0xffff; /* Get rid of extended sign. */
4524 bfd_putl16 ((bfd_vma
) value
, where
);
4527 case BFD_RELOC_MSP430_ABS_HI16
:
4529 value
&= 0xffff; /* Get rid of extended sign. */
4530 bfd_putl16 ((bfd_vma
) value
, where
);
4534 bfd_putl16 ((bfd_vma
) value
, where
);
4537 case BFD_RELOC_MSP430_ABS8
:
4539 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4542 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4543 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4544 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4546 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4549 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4550 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4552 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4555 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4556 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4558 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4561 case BFD_RELOC_MSP430X_PCR20_CALL
:
4562 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4564 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4567 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4568 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4569 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4571 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4574 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4575 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4577 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4580 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4581 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4583 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4587 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4588 fixp
->fx_line
, fixp
->fx_r_type
);
4594 fixp
->fx_addnumber
= value
;
4599 S_IS_GAS_LOCAL (symbolS
* s
)
4606 name
= S_GET_NAME (s
);
4607 len
= strlen (name
) - 1;
4609 return name
[len
] == 1 || name
[len
] == 2;
4612 /* GAS will call this to generate a reloc, passing the resulting reloc
4613 to `bfd_install_relocation'. This currently works poorly, as
4614 `bfd_install_relocation' often does the wrong thing, and instances of
4615 `tc_gen_reloc' have been written to work around the problems, which
4616 in turns makes it difficult to fix `bfd_install_relocation'. */
4618 /* If while processing a fixup, a reloc really needs to be created
4619 then it is done here. */
4622 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4624 static arelent
* no_relocs
= NULL
;
4625 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4628 reloc
= XNEW (arelent
);
4629 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4630 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4632 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4634 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4635 _("reloc %d not supported by object file format"),
4636 (int) fixp
->fx_r_type
);
4645 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4647 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4648 fixp
->fx_subsy
= NULL
;
4651 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4653 asection
*asec
, *ssec
;
4655 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4656 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4658 /* If we have a difference between two different, non-absolute symbols
4659 we must generate two relocs (one for each symbol) and allow the
4660 linker to resolve them - relaxation may change the distances between
4661 symbols, even local symbols defined in the same section.
4663 Unfortunately we cannot do this with assembler generated local labels
4664 because there can be multiple incarnations of the same label, with
4665 exactly the same name, in any given section and the linker will have
4666 no way to identify the correct one. Instead we just have to hope
4667 that no relaxation will occur between the local label and the other
4668 symbol in the expression.
4670 Similarly we have to compute differences between symbols in the .eh_frame
4671 section as the linker is not smart enough to apply relocations there
4672 before attempting to process it. */
4673 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4674 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4675 && strcmp (ssec
->name
, ".eh_frame") != 0
4676 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4677 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4679 arelent
* reloc2
= XNEW (arelent
);
4684 reloc2
->address
= reloc
->address
;
4685 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4686 BFD_RELOC_MSP430_SYM_DIFF
);
4687 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4689 if (ssec
== absolute_section
)
4690 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4693 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4694 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4697 reloc
->addend
= fixp
->fx_offset
;
4698 if (asec
== absolute_section
)
4700 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4701 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4705 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4706 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4715 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4717 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4718 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4720 switch (fixp
->fx_r_type
)
4723 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4727 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4731 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4735 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4740 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4751 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4752 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4754 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4755 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4757 md_number_to_chars (fixpos
, amount
, 2);
4762 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4763 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4764 reloc
->addend
= fixp
->fx_offset
;
4766 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4767 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4768 reloc
->address
= fixp
->fx_offset
;
4775 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4776 asection
* segment_type ATTRIBUTE_UNUSED
)
4778 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4780 /* This is a jump -> pcrel mode. Nothing to do much here.
4781 Return value == 2. */
4783 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4785 else if (fragP
->fr_symbol
)
4787 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4788 an absolute segment, we don't know a displacement until we link
4789 object files. So it will always be long. This also applies to
4790 labels in a subsegment of current. Liker may relax it to short
4791 jump later. Return value == 8. */
4793 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4797 /* We know the abs value. may be it is a jump to fixed address.
4798 Impossible in our case, cause all constants already handled. */
4800 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4803 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4807 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4808 asection
* sec ATTRIBUTE_UNUSED
,
4814 struct rcodes_s
* cc
= NULL
;
4815 struct hcodes_s
* hc
= NULL
;
4817 switch (fragP
->fr_subtype
)
4819 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4820 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4821 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4822 /* We do not have to convert anything here.
4823 Just apply a fix. */
4824 rela
= BFD_RELOC_MSP430_10_PCREL
;
4827 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4828 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4829 /* Convert uncond branch jmp lab -> br lab. */
4830 if (target_is_430x ())
4831 cc
= msp430x_rcodes
+ 7;
4833 cc
= msp430_rcodes
+ 7;
4834 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4835 bfd_putl16 (cc
->lop0
, where
);
4836 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4840 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4841 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4843 /* Other simple branches. */
4844 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4847 /* Find actual instruction. */
4848 if (target_is_430x ())
4850 for (i
= 0; i
< 7 && !cc
; i
++)
4851 if (msp430x_rcodes
[i
].sop
== insn
)
4852 cc
= msp430x_rcodes
+ i
;
4856 for (i
= 0; i
< 7 && !cc
; i
++)
4857 if (msp430_rcodes
[i
].sop
== insn
)
4858 cc
= & msp430_rcodes
[i
];
4861 if (!cc
|| !cc
->name
)
4862 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4863 __FUNCTION__
, (long) insn
);
4864 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4865 bfd_putl16 (cc
->lop0
, where
);
4866 bfd_putl16 (cc
->lop1
, where
+ 2);
4867 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4872 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4873 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4874 if (target_is_430x ())
4875 cc
= msp430x_rcodes
+ 6;
4877 cc
= msp430_rcodes
+ 6;
4878 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4879 bfd_putl16 (cc
->lop0
, where
);
4880 bfd_putl16 (cc
->lop1
, where
+ 2);
4881 bfd_putl16 (cc
->lop2
, where
+ 4);
4882 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4886 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4888 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4891 if (target_is_430x ())
4893 for (i
= 0; i
< 4 && !hc
; i
++)
4894 if (msp430x_hcodes
[i
].op1
== insn
)
4895 hc
= msp430x_hcodes
+ i
;
4899 for (i
= 0; i
< 4 && !hc
; i
++)
4900 if (msp430_hcodes
[i
].op1
== insn
)
4901 hc
= &msp430_hcodes
[i
];
4903 if (!hc
|| !hc
->name
)
4904 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4905 __FUNCTION__
, (long) insn
);
4906 rela
= BFD_RELOC_MSP430_10_PCREL
;
4907 /* Apply a fix for a first label if necessary.
4908 another fix will be applied to the next word of insn anyway. */
4910 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4911 fragP
->fr_offset
, TRUE
, rela
);
4917 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4918 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4920 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4923 if (target_is_430x ())
4925 for (i
= 0; i
< 4 && !hc
; i
++)
4926 if (msp430x_hcodes
[i
].op1
== insn
)
4927 hc
= msp430x_hcodes
+ i
;
4931 for (i
= 0; i
< 4 && !hc
; i
++)
4932 if (msp430_hcodes
[i
].op1
== insn
)
4933 hc
= & msp430_hcodes
[i
];
4935 if (!hc
|| !hc
->name
)
4936 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4937 __FUNCTION__
, (long) insn
);
4938 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4939 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4940 bfd_putl16 (hc
->lop0
, where
);
4941 bfd_putl16 (hc
->lop1
, where
+ 2);
4942 bfd_putl16 (hc
->lop2
, where
+ 4);
4948 as_fatal (_("internal inconsistency problem in %s: %lx"),
4949 __FUNCTION__
, (long) fragP
->fr_subtype
);
4953 /* Now apply fix. */
4954 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4955 fragP
->fr_offset
, TRUE
, rela
);
4956 /* Just fixed 2 bytes. */
4960 /* Relax fragment. Mostly stolen from hc11 and mcore
4961 which arches I think I know. */
4964 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4965 long stretch ATTRIBUTE_UNUSED
)
4970 const relax_typeS
*this_type
;
4971 const relax_typeS
*start_type
;
4972 relax_substateT next_state
;
4973 relax_substateT this_state
;
4974 const relax_typeS
*table
= md_relax_table
;
4976 /* Nothing to be done if the frag has already max size. */
4977 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4978 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4981 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4983 symbolP
= fragP
->fr_symbol
;
4984 if (symbol_resolved_p (symbolP
))
4985 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4987 /* We know the offset. calculate a distance. */
4988 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4991 if (!msp430_enable_relax
)
4993 /* Relaxation is not enabled. So, make all jump as long ones
4994 by setting 'aim' to quite high value. */
4998 this_state
= fragP
->fr_subtype
;
4999 start_type
= this_type
= table
+ this_state
;
5003 /* Look backwards. */
5004 for (next_state
= this_type
->rlx_more
; next_state
;)
5005 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
5009 /* Grow to next state. */
5010 this_state
= next_state
;
5011 this_type
= table
+ this_state
;
5012 next_state
= this_type
->rlx_more
;
5017 /* Look forwards. */
5018 for (next_state
= this_type
->rlx_more
; next_state
;)
5019 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
5023 /* Grow to next state. */
5024 this_state
= next_state
;
5025 this_type
= table
+ this_state
;
5026 next_state
= this_type
->rlx_more
;
5030 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5032 fragP
->fr_subtype
= this_state
;
5036 /* Return FALSE if the fixup in fixp should be left alone and not
5037 adjusted. We return FALSE here so that linker relaxation will
5041 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
5043 /* If the symbol is in a non-code section then it should be OK. */
5045 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
5051 /* Set the contents of the .MSP430.attributes and .GNU.attributes sections. */
5054 msp430_md_end (void)
5058 if (gen_interrupt_nops
)
5061 if (warn_interrupt_nops
)
5062 as_warn (INSERT_NOP_AT_EOF
);
5064 else if (warn_interrupt_nops
)
5065 as_warn (_(WARN_NOP_AT_EOF
));
5068 /* We have already emitted an error if any of the following attributes
5069 disagree with the attributes in the input assembly file. See
5070 msp430_object_attribute. */
5071 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
5072 target_is_430x () ? OFBA_MSPABI_Val_ISA_MSP430X
5073 : OFBA_MSPABI_Val_ISA_MSP430
);
5075 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
5076 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5077 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5079 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
5080 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5081 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5083 /* The data region GNU attribute is ignored for the small memory model. */
5085 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_GNU
,
5086 Tag_GNU_MSP430_Data_Region
, lower_data_region_only
5087 ? Val_GNU_MSP430_Data_Region_Lower
5088 : Val_GNU_MSP430_Data_Region_Any
);
5091 /* Returns FALSE if there is a msp430 specific reason why the
5092 subtraction of two same-section symbols cannot be computed by
5096 msp430_allow_local_subtract (expressionS
* left
,
5097 expressionS
* right
,
5100 /* If the symbols are not in a code section then they are OK. */
5101 if ((section
->flags
& SEC_CODE
) == 0)
5104 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
5107 if (left
->X_add_symbol
== right
->X_add_symbol
)
5110 /* We have to assume that there may be instructions between the
5111 two symbols and that relaxation may increase the distance between