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 struct hash_control
*msp430_hash
;
200 #define STATE_UNCOND_BRANCH 1 /* jump */
201 #define STATE_NOOV_BRANCH 3 /* bltn */
202 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
203 #define STATE_EMUL_BRANCH 4
212 #define STATE_BITS10 1 /* Wild guess. short jump. */
213 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more. */
214 #define STATE_UNDEF 3 /* Cannot handle this yet. convert to word mode. */
216 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
217 #define RELAX_STATE(s) ((s) & 3)
218 #define RELAX_LEN(s) ((s) >> 2)
219 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
221 relax_typeS md_relax_table
[] =
229 /* Unconditional jump. */
231 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
232 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
233 {1, 1, CUBL
, 0}, /* state undef */
235 /* Simple branches. */
237 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
238 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
241 /* blt no overflow branch. */
243 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
244 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
247 /* Emulated branches. */
249 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
250 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
255 #define MAX_OP_LEN 4096
264 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
266 static inline bfd_boolean
267 target_is_430x (void)
269 return selected_isa
>= MSP_ISA_430X
;
272 static inline bfd_boolean
273 target_is_430xv2 (void)
275 return selected_isa
== MSP_ISA_430Xv2
;
278 /* Generate an absolute 16-bit relocation, 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_MOVE_DATA 'd'
689 static bfd_boolean move_data
= FALSE
;
690 #define OPTION_DATA_REGION 'r'
691 static bfd_boolean upper_data_region_in_use
= FALSE
;
692 /* The default is to use the lower region only. */
693 static bfd_boolean lower_data_region_only
= TRUE
;
697 OPTION_SILICON_ERRATA
= OPTION_MD_BASE
,
698 OPTION_SILICON_ERRATA_WARN
,
701 static unsigned int silicon_errata_fix
= 0;
702 static unsigned int silicon_errata_warn
= 0;
703 #define SILICON_ERRATA_CPU4 (1 << 0)
704 #define SILICON_ERRATA_CPU8 (1 << 1)
705 #define SILICON_ERRATA_CPU11 (1 << 2)
706 #define SILICON_ERRATA_CPU12 (1 << 3)
707 #define SILICON_ERRATA_CPU13 (1 << 4)
708 #define SILICON_ERRATA_CPU19 (1 << 5)
711 msp430_set_arch (int option
)
713 char str
[32]; /* 32 for good measure. */
715 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
717 md_parse_option (option
, str
);
718 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
719 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
722 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
723 Keep these two structures in sync.
724 The data in this structure has been extracted from version 1.194 of the
725 devices.csv file released by TI in September 2016. */
727 struct msp430_mcu_data
730 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
731 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
735 { "cc430f5123",2,8 },
736 { "cc430f5125",2,8 },
737 { "cc430f5133",2,8 },
738 { "cc430f5135",2,8 },
739 { "cc430f5137",2,8 },
740 { "cc430f5143",2,8 },
741 { "cc430f5145",2,8 },
742 { "cc430f5147",2,8 },
743 { "cc430f6125",2,8 },
744 { "cc430f6126",2,8 },
745 { "cc430f6127",2,8 },
746 { "cc430f6135",2,8 },
747 { "cc430f6137",2,8 },
748 { "cc430f6143",2,8 },
749 { "cc430f6145",2,8 },
750 { "cc430f6147",2,8 },
751 { "msp430afe221",0,2 },
752 { "msp430afe222",0,2 },
753 { "msp430afe223",0,2 },
754 { "msp430afe231",0,2 },
755 { "msp430afe232",0,2 },
756 { "msp430afe233",0,2 },
757 { "msp430afe251",0,2 },
758 { "msp430afe252",0,2 },
759 { "msp430afe253",0,2 },
760 { "msp430bt5190",2,8 },
761 { "msp430c091",0,0 },
762 { "msp430c092",0,0 },
763 { "msp430c111",0,0 },
764 { "msp430c1111",0,0 },
765 { "msp430c112",0,0 },
766 { "msp430c1121",0,0 },
767 { "msp430c1331",0,0 },
768 { "msp430c1351",0,0 },
769 { "msp430c311s",0,0 },
770 { "msp430c312",0,0 },
771 { "msp430c313",0,0 },
772 { "msp430c314",0,0 },
773 { "msp430c315",0,0 },
774 { "msp430c323",0,0 },
775 { "msp430c325",0,0 },
776 { "msp430c336",0,1 },
777 { "msp430c337",0,1 },
778 { "msp430c412",0,0 },
779 { "msp430c413",0,0 },
780 { "msp430cg4616",1,1 },
781 { "msp430cg4617",1,1 },
782 { "msp430cg4618",1,1 },
783 { "msp430cg4619",1,1 },
784 { "msp430e112",0,0 },
785 { "msp430e313",0,0 },
786 { "msp430e315",0,0 },
787 { "msp430e325",0,0 },
788 { "msp430e337",0,1 },
789 { "msp430f110",0,0 },
790 { "msp430f1101",0,0 },
791 { "msp430f1101a",0,0 },
792 { "msp430f1111",0,0 },
793 { "msp430f1111a",0,0 },
794 { "msp430f112",0,0 },
795 { "msp430f1121",0,0 },
796 { "msp430f1121a",0,0 },
797 { "msp430f1122",0,0 },
798 { "msp430f1132",0,0 },
799 { "msp430f122",0,0 },
800 { "msp430f1222",0,0 },
801 { "msp430f123",0,0 },
802 { "msp430f1232",0,0 },
803 { "msp430f133",0,0 },
804 { "msp430f135",0,0 },
805 { "msp430f147",0,1 },
806 { "msp430f1471",0,1 },
807 { "msp430f148",0,1 },
808 { "msp430f1481",0,1 },
809 { "msp430f149",0,1 },
810 { "msp430f1491",0,1 },
811 { "msp430f155",0,0 },
812 { "msp430f156",0,0 },
813 { "msp430f157",0,0 },
814 { "msp430f1610",0,1 },
815 { "msp430f1611",0,1 },
816 { "msp430f1612",0,1 },
817 { "msp430f167",0,1 },
818 { "msp430f168",0,1 },
819 { "msp430f169",0,1 },
820 { "msp430f2001",0,0 },
821 { "msp430f2002",0,0 },
822 { "msp430f2003",0,0 },
823 { "msp430f2011",0,0 },
824 { "msp430f2012",0,0 },
825 { "msp430f2013",0,0 },
826 { "msp430f2101",0,0 },
827 { "msp430f2111",0,0 },
828 { "msp430f2112",0,0 },
829 { "msp430f2121",0,0 },
830 { "msp430f2122",0,0 },
831 { "msp430f2131",0,0 },
832 { "msp430f2132",0,0 },
833 { "msp430f2232",0,0 },
834 { "msp430f2234",0,0 },
835 { "msp430f2252",0,0 },
836 { "msp430f2254",0,0 },
837 { "msp430f2272",0,0 },
838 { "msp430f2274",0,0 },
839 { "msp430f233",0,2 },
840 { "msp430f2330",0,2 },
841 { "msp430f235",0,2 },
842 { "msp430f2350",0,2 },
843 { "msp430f2370",0,2 },
844 { "msp430f2410",0,2 },
845 { "msp430f2416",1,2 },
846 { "msp430f2417",1,2 },
847 { "msp430f2418",1,2 },
848 { "msp430f2419",1,2 },
849 { "msp430f247",0,2 },
850 { "msp430f2471",0,2 },
851 { "msp430f248",0,2 },
852 { "msp430f2481",0,2 },
853 { "msp430f249",0,2 },
854 { "msp430f2491",0,2 },
855 { "msp430f2616",1,2 },
856 { "msp430f2617",1,2 },
857 { "msp430f2618",1,2 },
858 { "msp430f2619",1,2 },
859 { "msp430f412",0,0 },
860 { "msp430f413",0,0 },
861 { "msp430f4132",0,0 },
862 { "msp430f415",0,0 },
863 { "msp430f4152",0,0 },
864 { "msp430f417",0,0 },
865 { "msp430f423",0,1 },
866 { "msp430f423a",0,1 },
867 { "msp430f425",0,1 },
868 { "msp430f4250",0,0 },
869 { "msp430f425a",0,1 },
870 { "msp430f4260",0,0 },
871 { "msp430f427",0,1 },
872 { "msp430f4270",0,0 },
873 { "msp430f427a",0,1 },
874 { "msp430f435",0,0 },
875 { "msp430f4351",0,0 },
876 { "msp430f436",0,0 },
877 { "msp430f4361",0,0 },
878 { "msp430f437",0,0 },
879 { "msp430f4371",0,0 },
880 { "msp430f438",0,0 },
881 { "msp430f439",0,0 },
882 { "msp430f447",0,1 },
883 { "msp430f448",0,1 },
884 { "msp430f4481",0,1 },
885 { "msp430f449",0,1 },
886 { "msp430f4491",0,1 },
887 { "msp430f4616",1,1 },
888 { "msp430f46161",1,1 },
889 { "msp430f4617",1,1 },
890 { "msp430f46171",1,1 },
891 { "msp430f4618",1,1 },
892 { "msp430f46181",1,1 },
893 { "msp430f4619",1,1 },
894 { "msp430f46191",1,1 },
895 { "msp430f47126",1,4 },
896 { "msp430f47127",1,4 },
897 { "msp430f47163",1,4 },
898 { "msp430f47166",1,4 },
899 { "msp430f47167",1,4 },
900 { "msp430f47173",1,4 },
901 { "msp430f47176",1,4 },
902 { "msp430f47177",1,4 },
903 { "msp430f47183",1,4 },
904 { "msp430f47186",1,4 },
905 { "msp430f47187",1,4 },
906 { "msp430f47193",1,4 },
907 { "msp430f47196",1,4 },
908 { "msp430f47197",1,4 },
909 { "msp430f477",0,0 },
910 { "msp430f478",0,0 },
911 { "msp430f4783",0,4 },
912 { "msp430f4784",0,4 },
913 { "msp430f479",0,0 },
914 { "msp430f4793",0,4 },
915 { "msp430f4794",0,4 },
916 { "msp430f5131",2,8 },
917 { "msp430f5132",2,8 },
918 { "msp430f5151",2,8 },
919 { "msp430f5152",2,8 },
920 { "msp430f5171",2,8 },
921 { "msp430f5172",2,8 },
922 { "msp430f5212",2,8 },
923 { "msp430f5213",2,8 },
924 { "msp430f5214",2,8 },
925 { "msp430f5217",2,8 },
926 { "msp430f5218",2,8 },
927 { "msp430f5219",2,8 },
928 { "msp430f5222",2,8 },
929 { "msp430f5223",2,8 },
930 { "msp430f5224",2,8 },
931 { "msp430f5227",2,8 },
932 { "msp430f5228",2,8 },
933 { "msp430f5229",2,8 },
934 { "msp430f5232",2,8 },
935 { "msp430f5234",2,8 },
936 { "msp430f5237",2,8 },
937 { "msp430f5239",2,8 },
938 { "msp430f5242",2,8 },
939 { "msp430f5244",2,8 },
940 { "msp430f5247",2,8 },
941 { "msp430f5249",2,8 },
942 { "msp430f5252",2,8 },
943 { "msp430f5253",2,8 },
944 { "msp430f5254",2,8 },
945 { "msp430f5255",2,8 },
946 { "msp430f5256",2,8 },
947 { "msp430f5257",2,8 },
948 { "msp430f5258",2,8 },
949 { "msp430f5259",2,8 },
950 { "msp430f5304",2,8 },
951 { "msp430f5308",2,8 },
952 { "msp430f5309",2,8 },
953 { "msp430f5310",2,8 },
954 { "msp430f5324",2,8 },
955 { "msp430f5325",2,8 },
956 { "msp430f5326",2,8 },
957 { "msp430f5327",2,8 },
958 { "msp430f5328",2,8 },
959 { "msp430f5329",2,8 },
960 { "msp430f5333",2,8 },
961 { "msp430f5335",2,8 },
962 { "msp430f5336",2,8 },
963 { "msp430f5338",2,8 },
964 { "msp430f5340",2,8 },
965 { "msp430f5341",2,8 },
966 { "msp430f5342",2,8 },
967 { "msp430f5358",2,8 },
968 { "msp430f5359",2,8 },
969 { "msp430f5418",2,8 },
970 { "msp430f5418a",2,8 },
971 { "msp430f5419",2,8 },
972 { "msp430f5419a",2,8 },
973 { "msp430f5435",2,8 },
974 { "msp430f5435a",2,8 },
975 { "msp430f5436",2,8 },
976 { "msp430f5436a",2,8 },
977 { "msp430f5437",2,8 },
978 { "msp430f5437a",2,8 },
979 { "msp430f5438",2,8 },
980 { "msp430f5438a",2,8 },
981 { "msp430f5500",2,8 },
982 { "msp430f5501",2,8 },
983 { "msp430f5502",2,8 },
984 { "msp430f5503",2,8 },
985 { "msp430f5504",2,8 },
986 { "msp430f5505",2,8 },
987 { "msp430f5506",2,8 },
988 { "msp430f5507",2,8 },
989 { "msp430f5508",2,8 },
990 { "msp430f5509",2,8 },
991 { "msp430f5510",2,8 },
992 { "msp430f5513",2,8 },
993 { "msp430f5514",2,8 },
994 { "msp430f5515",2,8 },
995 { "msp430f5517",2,8 },
996 { "msp430f5519",2,8 },
997 { "msp430f5521",2,8 },
998 { "msp430f5522",2,8 },
999 { "msp430f5524",2,8 },
1000 { "msp430f5525",2,8 },
1001 { "msp430f5526",2,8 },
1002 { "msp430f5527",2,8 },
1003 { "msp430f5528",2,8 },
1004 { "msp430f5529",2,8 },
1005 { "msp430f5630",2,8 },
1006 { "msp430f5631",2,8 },
1007 { "msp430f5632",2,8 },
1008 { "msp430f5633",2,8 },
1009 { "msp430f5634",2,8 },
1010 { "msp430f5635",2,8 },
1011 { "msp430f5636",2,8 },
1012 { "msp430f5637",2,8 },
1013 { "msp430f5638",2,8 },
1014 { "msp430f5658",2,8 },
1015 { "msp430f5659",2,8 },
1016 { "msp430f5xx_6xxgeneric",2,8 },
1017 { "msp430f6433",2,8 },
1018 { "msp430f6435",2,8 },
1019 { "msp430f6436",2,8 },
1020 { "msp430f6438",2,8 },
1021 { "msp430f6458",2,8 },
1022 { "msp430f6459",2,8 },
1023 { "msp430f6630",2,8 },
1024 { "msp430f6631",2,8 },
1025 { "msp430f6632",2,8 },
1026 { "msp430f6633",2,8 },
1027 { "msp430f6634",2,8 },
1028 { "msp430f6635",2,8 },
1029 { "msp430f6636",2,8 },
1030 { "msp430f6637",2,8 },
1031 { "msp430f6638",2,8 },
1032 { "msp430f6658",2,8 },
1033 { "msp430f6659",2,8 },
1034 { "msp430f6720",2,8 },
1035 { "msp430f6720a",2,8 },
1036 { "msp430f6721",2,8 },
1037 { "msp430f6721a",2,8 },
1038 { "msp430f6723",2,8 },
1039 { "msp430f6723a",2,8 },
1040 { "msp430f6724",2,8 },
1041 { "msp430f6724a",2,8 },
1042 { "msp430f6725",2,8 },
1043 { "msp430f6725a",2,8 },
1044 { "msp430f6726",2,8 },
1045 { "msp430f6726a",2,8 },
1046 { "msp430f6730",2,8 },
1047 { "msp430f6730a",2,8 },
1048 { "msp430f6731",2,8 },
1049 { "msp430f6731a",2,8 },
1050 { "msp430f6733",2,8 },
1051 { "msp430f6733a",2,8 },
1052 { "msp430f6734",2,8 },
1053 { "msp430f6734a",2,8 },
1054 { "msp430f6735",2,8 },
1055 { "msp430f6735a",2,8 },
1056 { "msp430f6736",2,8 },
1057 { "msp430f6736a",2,8 },
1058 { "msp430f6745",2,8 },
1059 { "msp430f67451",2,8 },
1060 { "msp430f67451a",2,8 },
1061 { "msp430f6745a",2,8 },
1062 { "msp430f6746",2,8 },
1063 { "msp430f67461",2,8 },
1064 { "msp430f67461a",2,8 },
1065 { "msp430f6746a",2,8 },
1066 { "msp430f6747",2,8 },
1067 { "msp430f67471",2,8 },
1068 { "msp430f67471a",2,8 },
1069 { "msp430f6747a",2,8 },
1070 { "msp430f6748",2,8 },
1071 { "msp430f67481",2,8 },
1072 { "msp430f67481a",2,8 },
1073 { "msp430f6748a",2,8 },
1074 { "msp430f6749",2,8 },
1075 { "msp430f67491",2,8 },
1076 { "msp430f67491a",2,8 },
1077 { "msp430f6749a",2,8 },
1078 { "msp430f67621",2,8 },
1079 { "msp430f67621a",2,8 },
1080 { "msp430f67641",2,8 },
1081 { "msp430f67641a",2,8 },
1082 { "msp430f6765",2,8 },
1083 { "msp430f67651",2,8 },
1084 { "msp430f67651a",2,8 },
1085 { "msp430f6765a",2,8 },
1086 { "msp430f6766",2,8 },
1087 { "msp430f67661",2,8 },
1088 { "msp430f67661a",2,8 },
1089 { "msp430f6766a",2,8 },
1090 { "msp430f6767",2,8 },
1091 { "msp430f67671",2,8 },
1092 { "msp430f67671a",2,8 },
1093 { "msp430f6767a",2,8 },
1094 { "msp430f6768",2,8 },
1095 { "msp430f67681",2,8 },
1096 { "msp430f67681a",2,8 },
1097 { "msp430f6768a",2,8 },
1098 { "msp430f6769",2,8 },
1099 { "msp430f67691",2,8 },
1100 { "msp430f67691a",2,8 },
1101 { "msp430f6769a",2,8 },
1102 { "msp430f6775",2,8 },
1103 { "msp430f67751",2,8 },
1104 { "msp430f67751a",2,8 },
1105 { "msp430f6775a",2,8 },
1106 { "msp430f6776",2,8 },
1107 { "msp430f67761",2,8 },
1108 { "msp430f67761a",2,8 },
1109 { "msp430f6776a",2,8 },
1110 { "msp430f6777",2,8 },
1111 { "msp430f67771",2,8 },
1112 { "msp430f67771a",2,8 },
1113 { "msp430f6777a",2,8 },
1114 { "msp430f6778",2,8 },
1115 { "msp430f67781",2,8 },
1116 { "msp430f67781a",2,8 },
1117 { "msp430f6778a",2,8 },
1118 { "msp430f6779",2,8 },
1119 { "msp430f67791",2,8 },
1120 { "msp430f67791a",2,8 },
1121 { "msp430f6779a",2,8 },
1122 { "msp430fe423",0,0 },
1123 { "msp430fe4232",0,0 },
1124 { "msp430fe423a",0,0 },
1125 { "msp430fe4242",0,0 },
1126 { "msp430fe425",0,0 },
1127 { "msp430fe4252",0,0 },
1128 { "msp430fe425a",0,0 },
1129 { "msp430fe427",0,0 },
1130 { "msp430fe4272",0,0 },
1131 { "msp430fe427a",0,0 },
1132 { "msp430fg4250",0,0 },
1133 { "msp430fg4260",0,0 },
1134 { "msp430fg4270",0,0 },
1135 { "msp430fg437",0,0 },
1136 { "msp430fg438",0,0 },
1137 { "msp430fg439",0,0 },
1138 { "msp430fg4616",1,1 },
1139 { "msp430fg4617",1,1 },
1140 { "msp430fg4618",1,1 },
1141 { "msp430fg4619",1,1 },
1142 { "msp430fg477",0,0 },
1143 { "msp430fg478",0,0 },
1144 { "msp430fg479",0,0 },
1145 { "msp430fg6425",2,8 },
1146 { "msp430fg6426",2,8 },
1147 { "msp430fg6625",2,8 },
1148 { "msp430fg6626",2,8 },
1149 { "msp430fr2032",2,0 },
1150 { "msp430fr2033",2,0 },
1151 { "msp430fr2110",2,0 },
1152 { "msp430fr2111",2,0 },
1153 { "msp430fr2310",2,0 },
1154 { "msp430fr2311",2,0 },
1155 { "msp430fr2433",2,8 },
1156 { "msp430fr2532",2,8 },
1157 { "msp430fr2533",2,8 },
1158 { "msp430fr2632",2,8 },
1159 { "msp430fr2633",2,8 },
1160 { "msp430fr2xx_4xxgeneric",2,8 },
1161 { "msp430fr4131",2,0 },
1162 { "msp430fr4132",2,0 },
1163 { "msp430fr4133",2,0 },
1164 { "msp430fr5720",2,8 },
1165 { "msp430fr5721",2,8 },
1166 { "msp430fr5722",2,8 },
1167 { "msp430fr5723",2,8 },
1168 { "msp430fr5724",2,8 },
1169 { "msp430fr5725",2,8 },
1170 { "msp430fr5726",2,8 },
1171 { "msp430fr5727",2,8 },
1172 { "msp430fr5728",2,8 },
1173 { "msp430fr5729",2,8 },
1174 { "msp430fr5730",2,8 },
1175 { "msp430fr5731",2,8 },
1176 { "msp430fr5732",2,8 },
1177 { "msp430fr5733",2,8 },
1178 { "msp430fr5734",2,8 },
1179 { "msp430fr5735",2,8 },
1180 { "msp430fr5736",2,8 },
1181 { "msp430fr5737",2,8 },
1182 { "msp430fr5738",2,8 },
1183 { "msp430fr5739",2,8 },
1184 { "msp430fr57xxgeneric",2,8 },
1185 { "msp430fr5847",2,8 },
1186 { "msp430fr58471",2,8 },
1187 { "msp430fr5848",2,8 },
1188 { "msp430fr5849",2,8 },
1189 { "msp430fr5857",2,8 },
1190 { "msp430fr5858",2,8 },
1191 { "msp430fr5859",2,8 },
1192 { "msp430fr5867",2,8 },
1193 { "msp430fr58671",2,8 },
1194 { "msp430fr5868",2,8 },
1195 { "msp430fr5869",2,8 },
1196 { "msp430fr5870",2,8 },
1197 { "msp430fr5872",2,8 },
1198 { "msp430fr58721",2,8 },
1199 { "msp430fr5887",2,8 },
1200 { "msp430fr5888",2,8 },
1201 { "msp430fr5889",2,8 },
1202 { "msp430fr58891",2,8 },
1203 { "msp430fr5922",2,8 },
1204 { "msp430fr59221",2,8 },
1205 { "msp430fr5947",2,8 },
1206 { "msp430fr59471",2,8 },
1207 { "msp430fr5948",2,8 },
1208 { "msp430fr5949",2,8 },
1209 { "msp430fr5957",2,8 },
1210 { "msp430fr5958",2,8 },
1211 { "msp430fr5959",2,8 },
1212 { "msp430fr5962",2,8 },
1213 { "msp430fr5964",2,8 },
1214 { "msp430fr5967",2,8 },
1215 { "msp430fr5968",2,8 },
1216 { "msp430fr5969",2,8 },
1217 { "msp430fr59691",2,8 },
1218 { "msp430fr5970",2,8 },
1219 { "msp430fr5972",2,8 },
1220 { "msp430fr59721",2,8 },
1221 { "msp430fr5986",2,8 },
1222 { "msp430fr5987",2,8 },
1223 { "msp430fr5988",2,8 },
1224 { "msp430fr5989",2,8 },
1225 { "msp430fr59891",2,8 },
1226 { "msp430fr5992",2,8 },
1227 { "msp430fr5994",2,8 },
1228 { "msp430fr59941",2,8 },
1229 { "msp430fr5xx_6xxgeneric",2,8 },
1230 { "msp430fr6820",2,8 },
1231 { "msp430fr6822",2,8 },
1232 { "msp430fr68221",2,8 },
1233 { "msp430fr6870",2,8 },
1234 { "msp430fr6872",2,8 },
1235 { "msp430fr68721",2,8 },
1236 { "msp430fr6877",2,8 },
1237 { "msp430fr6879",2,8 },
1238 { "msp430fr68791",2,8 },
1239 { "msp430fr6887",2,8 },
1240 { "msp430fr6888",2,8 },
1241 { "msp430fr6889",2,8 },
1242 { "msp430fr68891",2,8 },
1243 { "msp430fr6920",2,8 },
1244 { "msp430fr6922",2,8 },
1245 { "msp430fr69221",2,8 },
1246 { "msp430fr6927",2,8 },
1247 { "msp430fr69271",2,8 },
1248 { "msp430fr6928",2,8 },
1249 { "msp430fr6970",2,8 },
1250 { "msp430fr6972",2,8 },
1251 { "msp430fr69721",2,8 },
1252 { "msp430fr6977",2,8 },
1253 { "msp430fr6979",2,8 },
1254 { "msp430fr69791",2,8 },
1255 { "msp430fr6987",2,8 },
1256 { "msp430fr6988",2,8 },
1257 { "msp430fr6989",2,8 },
1258 { "msp430fr69891",2,8 },
1259 { "msp430fw423",0,0 },
1260 { "msp430fw425",0,0 },
1261 { "msp430fw427",0,0 },
1262 { "msp430fw428",0,0 },
1263 { "msp430fw429",0,0 },
1264 { "msp430g2001",0,0 },
1265 { "msp430g2101",0,0 },
1266 { "msp430g2102",0,0 },
1267 { "msp430g2111",0,0 },
1268 { "msp430g2112",0,0 },
1269 { "msp430g2113",0,0 },
1270 { "msp430g2121",0,0 },
1271 { "msp430g2131",0,0 },
1272 { "msp430g2132",0,0 },
1273 { "msp430g2152",0,0 },
1274 { "msp430g2153",0,0 },
1275 { "msp430g2201",0,0 },
1276 { "msp430g2202",0,0 },
1277 { "msp430g2203",0,0 },
1278 { "msp430g2210",0,0 },
1279 { "msp430g2211",0,0 },
1280 { "msp430g2212",0,0 },
1281 { "msp430g2213",0,0 },
1282 { "msp430g2221",0,0 },
1283 { "msp430g2230",0,0 },
1284 { "msp430g2231",0,0 },
1285 { "msp430g2232",0,0 },
1286 { "msp430g2233",0,0 },
1287 { "msp430g2252",0,0 },
1288 { "msp430g2253",0,0 },
1289 { "msp430g2302",0,0 },
1290 { "msp430g2303",0,0 },
1291 { "msp430g2312",0,0 },
1292 { "msp430g2313",0,0 },
1293 { "msp430g2332",0,0 },
1294 { "msp430g2333",0,0 },
1295 { "msp430g2352",0,0 },
1296 { "msp430g2353",0,0 },
1297 { "msp430g2402",0,0 },
1298 { "msp430g2403",0,0 },
1299 { "msp430g2412",0,0 },
1300 { "msp430g2413",0,0 },
1301 { "msp430g2432",0,0 },
1302 { "msp430g2433",0,0 },
1303 { "msp430g2444",0,0 },
1304 { "msp430g2452",0,0 },
1305 { "msp430g2453",0,0 },
1306 { "msp430g2513",0,0 },
1307 { "msp430g2533",0,0 },
1308 { "msp430g2544",0,0 },
1309 { "msp430g2553",0,0 },
1310 { "msp430g2744",0,0 },
1311 { "msp430g2755",0,0 },
1312 { "msp430g2855",0,0 },
1313 { "msp430g2955",0,0 },
1314 { "msp430i2020",0,2 },
1315 { "msp430i2021",0,2 },
1316 { "msp430i2030",0,2 },
1317 { "msp430i2031",0,2 },
1318 { "msp430i2040",0,2 },
1319 { "msp430i2041",0,2 },
1320 { "msp430i2xxgeneric",0,2 },
1321 { "msp430l092",0,0 },
1322 { "msp430p112",0,0 },
1323 { "msp430p313",0,0 },
1324 { "msp430p315",0,0 },
1325 { "msp430p315s",0,0 },
1326 { "msp430p325",0,0 },
1327 { "msp430p337",0,1 },
1328 { "msp430sl5438a",2,8 },
1329 { "msp430tch5e",0,0 },
1330 { "msp430xgeneric",2,8 },
1331 { "rf430f5144",2,8 },
1332 { "rf430f5155",2,8 },
1333 { "rf430f5175",2,8 },
1334 { "rf430frl152h",0,0 },
1335 { "rf430frl152h_rom",0,0 },
1336 { "rf430frl153h",0,0 },
1337 { "rf430frl153h_rom",0,0 },
1338 { "rf430frl154h",0,0 },
1339 { "rf430frl154h_rom",0,0 }
1343 md_parse_option (int c
, const char * arg
)
1347 case OPTION_SILICON_ERRATA
:
1348 case OPTION_SILICON_ERRATA_WARN
:
1354 unsigned int length
;
1355 unsigned int bitfield
;
1358 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4
},
1359 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8
},
1360 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11
},
1361 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12
},
1362 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13
},
1363 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19
},
1368 for (i
= ARRAY_SIZE (erratas
); i
--;)
1369 if (strncasecmp (arg
, erratas
[i
].name
, erratas
[i
].length
) == 0)
1371 if (c
== OPTION_SILICON_ERRATA
)
1372 silicon_errata_fix
|= erratas
[i
].bitfield
;
1374 silicon_errata_warn
|= erratas
[i
].bitfield
;
1375 arg
+= erratas
[i
].length
;
1380 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg
);
1386 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg
);
1396 as_fatal (_("MCU option requires a name\n"));
1398 if (strcasecmp ("msp430", arg
) == 0)
1399 selected_isa
= MSP_ISA_430
;
1400 else if (strcasecmp ("msp430xv2", arg
) == 0)
1401 selected_isa
= MSP_ISA_430Xv2
;
1402 else if (strcasecmp ("msp430x", arg
) == 0)
1403 selected_isa
= MSP_ISA_430X
;
1408 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1409 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1411 switch (msp430_mcu_data
[i
].revision
)
1413 case 0: selected_isa
= MSP_ISA_430
; break;
1414 case 1: selected_isa
= MSP_ISA_430X
; break;
1415 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1420 /* It is not an error if we do not match the MCU name. */
1424 if (strcmp (arg
, "430") == 0
1425 || strcasecmp (arg
, "msp430") == 0)
1426 selected_isa
= MSP_ISA_430
;
1427 else if (strcasecmp (arg
, "430x") == 0
1428 || strcasecmp (arg
, "msp430x") == 0)
1429 selected_isa
= MSP_ISA_430X
;
1430 else if (strcasecmp (arg
, "430xv2") == 0
1431 || strcasecmp (arg
, "msp430xv2") == 0)
1432 selected_isa
= MSP_ISA_430Xv2
;
1434 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1438 msp430_enable_relax
= 1;
1441 case OPTION_POLYMORPHS
:
1442 msp430_enable_polys
= 1;
1449 case OPTION_NO_INTR_NOPS
:
1450 gen_interrupt_nops
= FALSE
;
1452 case OPTION_INTR_NOPS
:
1453 gen_interrupt_nops
= TRUE
;
1456 case OPTION_WARN_INTR_NOPS
:
1457 warn_interrupt_nops
= TRUE
;
1459 case OPTION_NO_WARN_INTR_NOPS
:
1460 warn_interrupt_nops
= FALSE
;
1463 case OPTION_UNKNOWN_INTR_NOPS
:
1464 do_unknown_interrupt_nops
= TRUE
;
1466 case OPTION_NO_UNKNOWN_INTR_NOPS
:
1467 do_unknown_interrupt_nops
= FALSE
;
1470 case OPTION_MOVE_DATA
:
1474 case OPTION_DATA_REGION
:
1475 if (strcmp (arg
, "upper") == 0
1476 || strcmp (arg
, "either") == 0)
1477 upper_data_region_in_use
= TRUE
;
1478 if (strcmp (arg
, "upper") == 0
1479 || strcmp (arg
, "either") == 0
1480 /* With data-region=none, the compiler has generated code assuming
1481 data could be in the upper region, but nothing has been explicitly
1483 || strcmp (arg
, "none") == 0)
1484 lower_data_region_only
= FALSE
;
1491 /* The intention here is to have the mere presence of these sections
1492 cause the object to have a reference to a well-known symbol. This
1493 reference pulls in the bits of the runtime (crt0) that initialize
1494 these sections. Thus, for example, the startup code to call
1495 memset() to initialize .bss will only be linked in when there is a
1496 non-empty .bss section. Otherwise, the call would exist but have a
1497 zero length parameter, which is a waste of memory and cycles.
1499 The code which initializes these sections should have a global
1500 label for these symbols, and should be marked with KEEP() in the
1504 msp430_make_init_symbols (const char * name
)
1506 if (strncmp (name
, ".bss", 4) == 0
1507 || strncmp (name
, ".lower.bss", 10) == 0
1508 || strncmp (name
, ".either.bss", 11) == 0
1509 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1510 (void) symbol_find_or_make ("__crt0_init_bss");
1512 if (strncmp (name
, ".data", 5) == 0
1513 || strncmp (name
, ".lower.data", 11) == 0
1514 || strncmp (name
, ".either.data", 12) == 0
1515 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1516 (void) symbol_find_or_make ("__crt0_movedata");
1517 /* Note - data assigned to the .either.data section may end up being
1518 placed in the .upper.data section if the .lower.data section is
1519 full. Hence the need to define the crt0 symbol.
1520 The linker may create upper or either data sections, even when none exist
1521 at the moment, so use the value of the data-region flag to determine if
1522 the symbol is needed. */
1523 if (strncmp (name
, ".either.data", 12) == 0
1524 || strncmp (name
, ".upper.data", 11) == 0
1525 || upper_data_region_in_use
)
1526 (void) symbol_find_or_make ("__crt0_move_highdata");
1528 /* See note about .either.data above. */
1529 if (strncmp (name
, ".upper.bss", 10) == 0
1530 || strncmp (name
, ".either.bss", 11) == 0
1531 || upper_data_region_in_use
)
1532 (void) symbol_find_or_make ("__crt0_init_highbss");
1534 /* The following symbols are for the crt0 functions that run through
1535 the different .*_array sections and call the functions placed there.
1536 - init_array stores global static C++ constructors to run before main.
1537 - preinit_array is not expected to ever be used for MSP430.
1538 GCC only places initialization functions for runtime "sanitizers"
1539 (i.e. {a,l,t,u}san) and "virtual table verification" in preinit_array.
1540 - fini_array stores global static C++ destructors to run after calling
1541 exit() or returning from main.
1542 __crt0_run_array is required to actually call the functions in the above
1544 if (strncmp (name
, ".init_array", 11) == 0)
1546 (void) symbol_find_or_make ("__crt0_run_init_array");
1547 (void) symbol_find_or_make ("__crt0_run_array");
1549 else if (strncmp (name
, ".preinit_array", 14) == 0)
1551 (void) symbol_find_or_make ("__crt0_run_preinit_array");
1552 (void) symbol_find_or_make ("__crt0_run_array");
1554 else if (strncmp (name
, ".fini_array", 11) == 0)
1556 (void) symbol_find_or_make ("__crt0_run_fini_array");
1557 (void) symbol_find_or_make ("__crt0_run_array");
1562 msp430_section (int arg
)
1564 char * saved_ilp
= input_line_pointer
;
1565 const char * name
= obj_elf_section_name ();
1567 msp430_make_init_symbols (name
);
1569 input_line_pointer
= saved_ilp
;
1570 obj_elf_section (arg
);
1574 msp430_frob_section (asection
*sec
)
1576 const char *name
= sec
->name
;
1581 msp430_make_init_symbols (name
);
1585 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1587 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1590 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1591 (void) symbol_find_or_make ("__crt0_init_bss");
1595 msp430_comm (int needs_align
)
1597 s_comm_internal (needs_align
, elf_common_parse
);
1598 (void) symbol_find_or_make ("__crt0_init_bss");
1602 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1604 char sym_name
[1024];
1605 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1607 (void) symbol_find_or_make (sym_name
);
1610 /* Handle a .mspabi_attribute or .gnu_attribute directive.
1611 attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute.
1612 This is only used for validating the attributes in the assembly file against
1613 the options gas has been invoked with. If the attributes and options are
1614 compatible then we add the attributes to the assembly file in
1617 msp430_object_attribute (int attr_type
)
1619 char tag_name_s
[32];
1620 char tag_value_s
[32];
1621 int tag_name
, tag_value
;
1622 /* First operand is the tag name, second is the tag value e.g.
1623 ".mspabi_attribute 4, 2". */
1624 input_line_pointer
= extract_operand (input_line_pointer
, tag_name_s
, 32);
1625 input_line_pointer
= extract_operand (input_line_pointer
, tag_value_s
, 32);
1626 tag_name
= atoi (tag_name_s
);
1627 tag_value
= atoi (tag_value_s
);
1628 /* If the attribute directive is present, the tag_value should never be set
1630 if (tag_name
== 0 || tag_value
== 0)
1631 as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"),
1632 tag_name_s
, tag_value_s
, (attr_type
? ".gnu_attribute"
1633 : ".mspabi_attribute"));
1634 else if (attr_type
== 0)
1635 /* Handle .mspabi_attribute. */
1638 case OFBA_MSPABI_Tag_ISA
:
1641 case OFBA_MSPABI_Val_ISA_MSP430
:
1642 if (target_is_430x ())
1643 as_bad (_("file was compiled for the 430 ISA but the %s ISA is "
1644 "selected"), (target_is_430xv2 () ? "430X" : "430Xv2"));
1646 case OFBA_MSPABI_Val_ISA_MSP430X
:
1647 if (!target_is_430x ())
1648 as_bad (_("file was compiled for the 430X ISA but the 430 ISA is "
1652 as_bad (_("unknown MSPABI build attribute value '%d' for "
1653 "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"),
1654 tag_value
, OFBA_MSPABI_Tag_ISA
);
1658 case OFBA_MSPABI_Tag_Code_Model
:
1660 case OFBA_MSPABI_Tag_Data_Model
:
1661 /* FIXME: Might we want to set the memory model to large if the assembly
1662 file has the large model attribute, but -ml has not been passed? */
1665 case OFBA_MSPABI_Val_Code_Model_SMALL
:
1667 as_bad (_("file was compiled for the small memory model, but the "
1668 "large memory model is selected"));
1670 case OFBA_MSPABI_Val_Code_Model_LARGE
:
1672 as_bad (_("file was compiled for the large memory model, "
1673 "but the small memory model is selected"));
1676 as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) "
1677 "in .mspabi_attribute directive"), tag_value
,
1678 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1679 ? "OFBA_MSPABI_Tag_Code_Model"
1680 : "OFBA_MSPABI_Tag_Data_Model"),
1681 (tag_name
== OFBA_MSPABI_Tag_Code_Model
1682 ? OFBA_MSPABI_Tag_Code_Model
1683 : OFBA_MSPABI_Tag_Data_Model
));
1688 as_bad (_("unknown MSPABI build attribute tag '%d' in "
1689 ".mspabi_attribute directive"), tag_name
);
1692 else if (attr_type
== 1)
1693 /* Handle .gnu_attribute. */
1696 case Tag_GNU_MSP430_Data_Region
:
1697 /* This attribute is only applicable in the large memory model. */
1702 case Val_GNU_MSP430_Data_Region_Lower
:
1703 if (!lower_data_region_only
)
1704 as_bad (_("file was compiled assuming all data will be in the "
1705 "lower memory region, but the upper region is in use"));
1707 case Val_GNU_MSP430_Data_Region_Any
:
1708 if (lower_data_region_only
)
1709 as_bad (_("file was compiled assuming data could be in the upper "
1710 "memory region, but the lower data region is "
1711 "exclusively in use"));
1714 as_bad (_("unknown GNU build attribute value '%d' for "
1715 "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute "
1716 "directive"), tag_value
, Tag_GNU_MSP430_Data_Region
);
1720 as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"),
1724 const pseudo_typeS md_pseudo_table
[] =
1726 {"arch", msp430_set_arch
, OPTION_MMCU
},
1727 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1728 {"profiler", msp430_profiler
, 0},
1729 {"section", msp430_section
, 0},
1730 {"section.s", msp430_section
, 0},
1731 {"sect", msp430_section
, 0},
1732 {"sect.s", msp430_section
, 0},
1733 {"pushsection", msp430_section
, 1},
1734 {"refsym", msp430_refsym
, 0},
1735 {"comm", msp430_comm
, 0},
1736 {"lcomm", msp430_lcomm
, 0},
1737 {"mspabi_attribute", msp430_object_attribute
, 0},
1738 {"gnu_attribute", msp430_object_attribute
, 1},
1742 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY,mu,mU";
1744 struct option md_longopts
[] =
1746 {"msilicon-errata", required_argument
, NULL
, OPTION_SILICON_ERRATA
},
1747 {"msilicon-errata-warn", required_argument
, NULL
, OPTION_SILICON_ERRATA_WARN
},
1748 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1749 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1750 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1751 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1752 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1753 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1754 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1755 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1756 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1757 {"mu", no_argument
, NULL
, OPTION_UNKNOWN_INTR_NOPS
},
1758 {"mU", no_argument
, NULL
, OPTION_NO_UNKNOWN_INTR_NOPS
},
1759 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1760 {"mdata-region", required_argument
, NULL
, OPTION_DATA_REGION
},
1761 {NULL
, no_argument
, NULL
, 0}
1764 size_t md_longopts_size
= sizeof (md_longopts
);
1767 md_show_usage (FILE * stream
)
1770 _("MSP430 options:\n"
1771 " -mmcu=<msp430-name> - select microcontroller type\n"
1772 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1774 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1775 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
1776 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
1778 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1779 " -mP - enable polymorph instructions\n"));
1781 _(" -ml - enable large code model\n"));
1783 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1785 _(" -mn - insert a NOP after changing interrupts\n"));
1787 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1789 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1791 _(" -mU - for an instruction which changes interrupt state, but where it is not\n"
1792 " known how the state is changed, do not warn/insert NOPs\n"));
1794 _(" -mu - for an instruction which changes interrupt state, but where it is not\n"
1795 " known how the state is changed, warn/insert NOPs (default)\n"
1796 " -mn and/or -my are required for this to have any effect\n"));
1798 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1800 _(" -mdata-region={none|lower|upper|either} - select region data will be\n"
1805 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1811 extract_cmd (char * from
, char * to
, int limit
)
1815 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1817 *(to
+ size
) = *from
;
1828 md_atof (int type
, char * litP
, int * sizeP
)
1830 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1836 struct msp430_opcode_s
* opcode
;
1837 msp430_hash
= hash_new ();
1839 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1840 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1842 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1843 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1845 /* Set linkrelax here to avoid fixups in most sections. */
1849 static inline bfd_boolean
1850 is_regname_end (char c
)
1852 return (c
== 0 || ! ISALNUM (c
));
1855 /* Returns the register number equivalent to the string T.
1856 Returns -1 if there is no such register.
1857 Skips a leading 'r' or 'R' character if there is one.
1858 Handles the register aliases PC and SP. */
1861 check_reg (char * t
)
1864 signed long int val
;
1866 if (t
== NULL
|| t
[0] == 0)
1869 if (*t
== 'r' || *t
== 'R')
1872 if (strncasecmp (t
, "pc", 2) == 0 && is_regname_end (t
[2]))
1875 if (strncasecmp (t
, "sp", 2) == 0 && is_regname_end (t
[2]))
1878 if (strncasecmp (t
, "sr", 2) == 0 && is_regname_end (t
[2]))
1881 if (*t
== '0' && is_regname_end (t
[1]))
1884 val
= strtol (t
, & endt
, 0);
1886 if (val
< 1 || val
> 15)
1889 if (is_regname_end (*endt
))
1896 msp430_srcoperand (struct msp430_operand_s
* op
,
1899 bfd_boolean
* imm_op
,
1900 bfd_boolean allow_20bit_values
,
1901 bfd_boolean constants_allowed
)
1906 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1912 /* Use all parts of the constant expression by default. */
1913 enum msp430_expp_e expp
= MSP_EXPP_ALL
;
1915 /* Check if there is:
1916 llo(x) - least significant 16 bits, x &= 0xffff
1917 lhi(x) - x = (x >> 16) & 0xffff,
1918 hlo(x) - x = (x >> 32) & 0xffff,
1919 hhi(x) - x = (x >> 48) & 0xffff
1920 The value _MUST_ be an immediate expression: #hlo(1231231231). */
1924 if (strncasecmp (h
, "#llo(", 5) == 0)
1928 expp
= MSP_EXPP_LLO
;
1930 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1934 expp
= MSP_EXPP_LHI
;
1936 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1940 expp
= MSP_EXPP_HLO
;
1942 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1946 expp
= MSP_EXPP_HHI
;
1948 else if (strncasecmp (h
, "#lo(", 4) == 0)
1954 else if (strncasecmp (h
, "#hi(", 4) == 0)
1961 op
->reg
= 0; /* Reg PC. */
1963 op
->ol
= 1; /* Immediate will follow an instruction. */
1964 __tl
= h
+ 1 + rval
;
1966 op
->vshift
= vshift
;
1969 end
= parse_exp (__tl
, &(op
->exp
));
1970 if (end
!= NULL
&& *end
!= 0 && *end
!= ')' )
1972 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end
, l
);
1975 if (op
->exp
.X_op
== O_constant
)
1977 int x
= op
->exp
.X_add_number
;
1982 op
->exp
.X_add_number
= x
;
1984 else if (vshift
== 1)
1986 x
= (x
>> 16) & 0xffff;
1987 op
->exp
.X_add_number
= x
;
1990 else if (vshift
> 1)
1993 op
->exp
.X_add_number
= -1;
1995 op
->exp
.X_add_number
= 0; /* Nothing left. */
1996 x
= op
->exp
.X_add_number
;
2000 if (allow_20bit_values
)
2002 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
2004 as_bad (_("value 0x%x out of extended range."), x
);
2008 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
2010 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
2014 /* Now check constants. */
2015 /* Substitute register mode with a constant generator if applicable. */
2017 if (!allow_20bit_values
)
2018 x
= (short) x
; /* Extend sign. */
2020 if (! constants_allowed
)
2052 if (bin
== 0x1200 && ! target_is_430x ())
2054 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
2055 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2056 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
2057 /* No need to check silicon_errata_fixes - this fix is always implemented. */
2069 if (bin
== 0x1200 && ! target_is_430x ())
2071 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
2072 if (silicon_errata_warn
& SILICON_ERRATA_CPU4
)
2073 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
2084 else if (op
->exp
.X_op
== O_symbol
)
2087 as_bad (_("error: unsupported #foo() directive used on symbol"));
2090 else if (op
->exp
.X_op
== O_big
)
2096 op
->exp
.X_op
= O_constant
;
2097 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
2098 x
= op
->exp
.X_add_number
;
2104 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
2152 /* Redundant (yet) check. */
2153 else if (op
->exp
.X_op
== O_register
)
2155 (_("Registers cannot be used within immediate expression [%s]"), l
);
2157 as_bad (_("unknown operand %s"), l
);
2162 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
2167 op
->reg
= 2; /* Reg 2 in absolute addr mode. */
2168 op
->am
= 1; /* Mode As == 01 bin. */
2169 op
->ol
= 1; /* Immediate value followed by instruction. */
2171 end
= parse_exp (__tl
, &(op
->exp
));
2172 if (end
!= NULL
&& *end
!= 0)
2174 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end
, l
);
2179 op
->expp
= MSP_EXPP_ALL
;
2180 if (op
->exp
.X_op
== O_constant
)
2182 int x
= op
->exp
.X_add_number
;
2184 if (allow_20bit_values
)
2186 if (x
> 0xfffff || x
< -(0x7ffff))
2188 as_bad (_("value 0x%x out of extended range."), x
);
2192 else if (x
> 65535 || x
< -32768)
2194 as_bad (_("value out of range: 0x%x"), x
);
2198 else if (op
->exp
.X_op
== O_symbol
)
2202 /* Redundant (yet) check. */
2203 if (op
->exp
.X_op
== O_register
)
2205 (_("Registers cannot be used within absolute expression [%s]"), l
);
2207 as_bad (_("unknown expression in operand %s"), l
);
2213 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2217 char *m
= strchr (l
, '+');
2221 as_bad (_("unknown addressing mode %s"), l
);
2227 if ((op
->reg
= check_reg (t
)) == -1)
2229 as_bad (_("Bad register name %s"), t
);
2237 /* PC cannot be used in indirect addressing. */
2238 if (target_is_430xv2 () && op
->reg
== 0)
2240 as_bad (_("cannot use indirect addressing with the PC"));
2247 /* Check if register indexed X(Rn). */
2250 char *h
= strrchr (l
, '(');
2251 char *m
= strrchr (l
, ')');
2260 as_bad (_("')' required"));
2268 /* Extract a register. */
2269 if ((op
->reg
= check_reg (t
+ 1)) == -1)
2272 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2279 as_bad (_("r2 should not be used in indexed addressing mode"));
2283 /* Extract constant. */
2288 op
->expp
= MSP_EXPP_ALL
;
2289 end
= parse_exp (__tl
, &(op
->exp
));
2290 if (end
!= NULL
&& *end
!= 0)
2292 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2295 if (op
->exp
.X_op
== O_constant
)
2297 int x
= op
->exp
.X_add_number
;
2299 if (allow_20bit_values
)
2301 if (x
> 0xfffff || x
< - (0x7ffff))
2303 as_bad (_("value 0x%x out of extended range."), x
);
2307 else if (x
> 65535 || x
< -32768)
2309 as_bad (_("value out of range: 0x%x"), x
);
2321 if (op
->reg
== 1 && (x
& 1))
2323 if (silicon_errata_fix
& SILICON_ERRATA_CPU8
)
2324 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2325 else if (silicon_errata_warn
& SILICON_ERRATA_CPU8
)
2326 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2329 else if (op
->exp
.X_op
== O_symbol
)
2333 /* Redundant (yet) check. */
2334 if (op
->exp
.X_op
== O_register
)
2336 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2338 as_bad (_("unknown expression in operand %s"), l
);
2346 /* Possibly register mode 'mov r1,r2'. */
2347 if ((op
->reg
= check_reg (l
)) != -1)
2355 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2357 op
->reg
= 0; /* PC relative... be careful. */
2358 /* An expression starting with a minus sign is a constant, not an address. */
2359 op
->am
= (*l
== '-' ? 3 : 1);
2362 op
->expp
= MSP_EXPP_ALL
;
2364 end
= parse_exp (__tl
, &(op
->exp
));
2365 if (end
!= NULL
&& * end
!= 0)
2367 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l
);
2375 msp430_dstoperand (struct msp430_operand_s
* op
,
2378 bfd_boolean allow_20bit_values
,
2379 bfd_boolean constants_allowed
)
2382 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2391 char *__tl
= (char *) "0";
2397 op
->expp
= MSP_EXPP_ALL
;
2398 (void) parse_exp (__tl
, &(op
->exp
));
2400 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2402 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2412 ("this addressing mode is not applicable for destination operand"));
2418 /* Attempt to encode a MOVA instruction with the given operands.
2419 Returns the length of the encoded instruction if successful
2420 or 0 upon failure. If the encoding fails, an error message
2421 will be returned if a pointer is provided. */
2424 try_encode_mova (bfd_boolean imm_op
,
2426 struct msp430_operand_s
* op1
,
2427 struct msp430_operand_s
* op2
,
2428 const char ** error_message_return
)
2434 /* Only a restricted subset of the normal MSP430 addressing modes
2435 are supported here, so check for the ones that are allowed. */
2438 if (op1
->mode
== OP_EXP
)
2440 if (op2
->mode
!= OP_REG
)
2442 if (error_message_return
!= NULL
)
2443 * error_message_return
= _("expected register as second argument of %s");
2449 /* MOVA #imm20, Rdst. */
2450 bin
|= 0x80 | op2
->reg
;
2451 frag
= frag_more (4);
2452 where
= frag
- frag_now
->fr_literal
;
2453 if (op1
->exp
.X_op
== O_constant
)
2455 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2456 bfd_putl16 ((bfd_vma
) bin
, frag
);
2457 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2461 bfd_putl16 ((bfd_vma
) bin
, frag
);
2462 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2463 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2464 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2469 else if (op1
->am
== 1)
2471 /* MOVA z16(Rsrc), Rdst. */
2472 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2473 frag
= frag_more (4);
2474 where
= frag
- frag_now
->fr_literal
;
2475 bfd_putl16 ((bfd_vma
) bin
, frag
);
2476 if (op1
->exp
.X_op
== O_constant
)
2478 if (op1
->exp
.X_add_number
> 0xffff
2479 || op1
->exp
.X_add_number
< -(0x7fff))
2481 if (error_message_return
!= NULL
)
2482 * error_message_return
= _("index value too big for %s");
2485 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2489 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2490 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2492 BFD_RELOC_MSP430X_PCR16
:
2493 BFD_RELOC_MSP430X_ABS16
);
2498 if (error_message_return
!= NULL
)
2499 * error_message_return
= _("unexpected addressing mode for %s");
2502 else if (op1
->am
== 0)
2504 /* MOVA Rsrc, ... */
2505 if (op2
->mode
== OP_REG
)
2507 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2508 frag
= frag_more (2);
2509 where
= frag
- frag_now
->fr_literal
;
2510 bfd_putl16 ((bfd_vma
) bin
, frag
);
2513 else if (op2
->am
== 1)
2517 /* MOVA Rsrc, &abs20. */
2518 bin
|= 0x60 | (op1
->reg
<< 8);
2519 frag
= frag_more (4);
2520 where
= frag
- frag_now
->fr_literal
;
2521 if (op2
->exp
.X_op
== O_constant
)
2523 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2524 bfd_putl16 ((bfd_vma
) bin
, frag
);
2525 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2529 bfd_putl16 ((bfd_vma
) bin
, frag
);
2530 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2531 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2532 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2537 /* MOVA Rsrc, z16(Rdst). */
2538 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2539 frag
= frag_more (4);
2540 where
= frag
- frag_now
->fr_literal
;
2541 bfd_putl16 ((bfd_vma
) bin
, frag
);
2542 if (op2
->exp
.X_op
== O_constant
)
2544 if (op2
->exp
.X_add_number
> 0xffff
2545 || op2
->exp
.X_add_number
< -(0x7fff))
2547 if (error_message_return
!= NULL
)
2548 * error_message_return
= _("index value too big for %s");
2551 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2555 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2556 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2558 BFD_RELOC_MSP430X_PCR16
:
2559 BFD_RELOC_MSP430X_ABS16
);
2564 if (error_message_return
!= NULL
)
2565 * error_message_return
= _("unexpected addressing mode for %s");
2570 /* imm_op == FALSE. */
2572 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2574 /* MOVA &abs20, Rdst. */
2575 if (op2
->mode
!= OP_REG
)
2577 if (error_message_return
!= NULL
)
2578 * error_message_return
= _("expected register as second argument of %s");
2582 if (op2
->reg
== 2 || op2
->reg
== 3)
2584 if (error_message_return
!= NULL
)
2585 * error_message_return
= _("constant generator destination register found in %s");
2589 bin
|= 0x20 | op2
->reg
;
2590 frag
= frag_more (4);
2591 where
= frag
- frag_now
->fr_literal
;
2592 if (op1
->exp
.X_op
== O_constant
)
2594 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2595 bfd_putl16 ((bfd_vma
) bin
, frag
);
2596 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2600 bfd_putl16 ((bfd_vma
) bin
, frag
);
2601 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2602 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2603 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2607 else if (op1
->mode
== OP_REG
)
2611 /* MOVA @Rsrc+, Rdst. */
2612 if (op2
->mode
!= OP_REG
)
2614 if (error_message_return
!= NULL
)
2615 * error_message_return
= _("expected register as second argument of %s");
2619 if (op2
->reg
== 2 || op2
->reg
== 3)
2621 if (error_message_return
!= NULL
)
2622 * error_message_return
= _("constant generator destination register found in %s");
2626 if (op1
->reg
== 2 || op1
->reg
== 3)
2628 if (error_message_return
!= NULL
)
2629 * error_message_return
= _("constant generator source register found in %s");
2633 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2634 frag
= frag_more (2);
2635 where
= frag
- frag_now
->fr_literal
;
2636 bfd_putl16 ((bfd_vma
) bin
, frag
);
2639 else if (op1
->am
== 2)
2641 /* MOVA @Rsrc,Rdst */
2642 if (op2
->mode
!= OP_REG
)
2644 if (error_message_return
!= NULL
)
2645 * error_message_return
= _("expected register as second argument of %s");
2649 if (op2
->reg
== 2 || op2
->reg
== 3)
2651 if (error_message_return
!= NULL
)
2652 * error_message_return
= _("constant generator destination register found in %s");
2656 if (op1
->reg
== 2 || op1
->reg
== 3)
2658 if (error_message_return
!= NULL
)
2659 * error_message_return
= _("constant generator source register found in %s");
2663 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2664 frag
= frag_more (2);
2665 where
= frag
- frag_now
->fr_literal
;
2666 bfd_putl16 ((bfd_vma
) bin
, frag
);
2671 if (error_message_return
!= NULL
)
2672 * error_message_return
= _("unexpected addressing mode for %s");
2677 #define NOP_CHECK_INTERRUPT (1 << 0)
2678 #define NOP_CHECK_CPU12 (1 << 1)
2679 #define NOP_CHECK_CPU19 (1 << 2)
2681 static signed int check_for_nop
= 0;
2683 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2685 /* is_{e,d}int only check the explicit enabling/disabling of interrupts.
2686 For MOV insns, more sophisticated processing is needed to determine if they
2687 result in enabling/disabling interrupts. */
2688 #define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \
2689 || ((strcmp (OPCODE, "bic") == 0) \
2691 || ((strcmp (OPCODE, "clr") == 0) \
2694 #define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \
2695 || ((strcmp (OPCODE, "bis") == 0) \
2698 const char * const INSERT_NOP_BEFORE_EINT
= "NOP inserted here, before an interrupt enable instruction";
2699 const char * const INSERT_NOP_AFTER_DINT
= "NOP inserted here, after an interrupt disable instruction";
2700 const char * const INSERT_NOP_AFTER_EINT
= "NOP inserted here, after an interrupt enable instruction";
2701 const char * const INSERT_NOP_BEFORE_UNKNOWN
= "NOP inserted here, before this interrupt state change";
2702 const char * const INSERT_NOP_AFTER_UNKNOWN
="NOP inserted here, after the instruction that changed interrupt state";
2703 const char * const INSERT_NOP_AT_EOF
= "NOP inserted after the interrupt state change at the end of the file";
2705 const char * const WARN_NOP_BEFORE_EINT
= "a NOP might be needed here, before an interrupt enable instruction";
2706 const char * const WARN_NOP_AFTER_DINT
= "a NOP might be needed here, after an interrupt disable instruction";
2707 const char * const WARN_NOP_AFTER_EINT
= "a NOP might be needed here, after an interrupt enable instruction";
2708 const char * const WARN_NOP_BEFORE_UNKNOWN
= "a NOP might be needed here, before this interrupt state change";
2709 const char * const WARN_NOP_AFTER_UNKNOWN
= "a NOP might also be needed here, after the instruction that changed interrupt state";
2710 const char * const WARN_NOP_AT_EOF
= "a NOP might be needed after the interrupt state change at the end of the file";
2716 frag
= frag_more (2);
2717 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2718 dwarf2_emit_insn (2);
2721 /* Insert/inform about adding a NOP if this insn enables interrupts. */
2724 warn_eint_nop (bfd_boolean prev_insn_is_nop
, bfd_boolean prev_insn_is_dint
)
2726 if (prev_insn_is_nop
2727 /* If the last insn was a DINT, we will have already warned that a NOP is
2728 required after it. */
2729 || prev_insn_is_dint
2730 /* 430 ISA does not require a NOP before EINT. */
2731 || (! target_is_430x ()))
2734 if (gen_interrupt_nops
)
2737 if (warn_interrupt_nops
)
2738 as_warn (_(INSERT_NOP_BEFORE_EINT
));
2740 else if (warn_interrupt_nops
)
2741 as_warn (_(WARN_NOP_BEFORE_EINT
));
2744 /* Use when unsure what effect the insn will have on the interrupt status,
2745 to insert/warn about adding a NOP before the current insn. */
2748 warn_unsure_interrupt (bfd_boolean prev_insn_is_nop
,
2749 bfd_boolean prev_insn_is_dint
)
2751 if (prev_insn_is_nop
2752 /* If the last insn was a DINT, we will have already warned that a NOP is
2753 required after it. */
2754 || prev_insn_is_dint
2755 /* 430 ISA does not require a NOP before EINT or DINT. */
2756 || (! target_is_430x ()))
2759 if (gen_interrupt_nops
)
2762 if (warn_interrupt_nops
)
2763 as_warn (_(INSERT_NOP_BEFORE_UNKNOWN
));
2765 else if (warn_interrupt_nops
)
2766 as_warn (_(WARN_NOP_BEFORE_UNKNOWN
));
2769 /* Parse instruction operands.
2770 Return binary opcode. */
2773 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2775 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2776 int insn_length
= 0;
2777 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2781 struct msp430_operand_s op1
, op2
;
2783 static short ZEROS
= 0;
2784 bfd_boolean byte_op
, imm_op
;
2787 int extended
= 0x1800;
2788 bfd_boolean extended_op
= FALSE
;
2789 bfd_boolean addr_op
;
2790 const char * error_message
;
2791 static signed int repeat_count
= 0;
2792 static bfd_boolean prev_insn_is_nop
= FALSE
;
2793 static bfd_boolean prev_insn_is_dint
= FALSE
;
2794 static bfd_boolean prev_insn_is_eint
= FALSE
;
2795 /* We might decide before the end of the function that the current insn is
2796 equivalent to DINT/EINT. */
2797 bfd_boolean this_insn_is_dint
= FALSE
;
2798 bfd_boolean this_insn_is_eint
= FALSE
;
2799 bfd_boolean fix_emitted
;
2801 /* Opcode is the one from opcodes table
2802 line contains something like
2811 bfd_boolean check
= FALSE
;
2814 switch (TOLOWER (* line
))
2817 /* Byte operation. */
2818 bin
|= BYTE_OPERATION
;
2824 /* "Address" ops work on 20-bit values. */
2826 bin
|= BYTE_OPERATION
;
2831 /* Word operation - this is the default. */
2839 as_warn (_("no size modifier after period, .w assumed"));
2843 as_bad (_("unrecognised instruction size modifier .%c"),
2855 if (*line
&& ! ISSPACE (*line
))
2857 as_bad (_("junk found after instruction: %s.%s"),
2858 opcode
->name
, line
);
2862 /* Catch the case where the programmer has used a ".a" size modifier on an
2863 instruction that does not support it. Look for an alternative extended
2864 instruction that has the same name without the period. Eg: "add.a"
2865 becomes "adda". Although this not an officially supported way of
2866 specifying instruction aliases other MSP430 assemblers allow it. So we
2867 support it for compatibility purposes. */
2868 if (addr_op
&& opcode
->fmt
>= 0)
2870 const char * old_name
= opcode
->name
;
2873 sprintf (real_name
, "%sa", old_name
);
2874 opcode
= hash_find (msp430_hash
, real_name
);
2877 as_bad (_("instruction %s.a does not exist"), old_name
);
2880 #if 0 /* Enable for debugging. */
2881 as_warn ("treating %s.a as %s", old_name
, real_name
);
2884 bin
= opcode
->bin_opcode
;
2887 if (opcode
->fmt
!= -1
2888 && opcode
->insn_opnumb
2889 && (!*line
|| *line
== '\n'))
2891 as_bad (ngettext ("instruction %s requires %d operand",
2892 "instruction %s requires %d operands",
2893 opcode
->insn_opnumb
),
2894 opcode
->name
, opcode
->insn_opnumb
);
2898 memset (l1
, 0, sizeof (l1
));
2899 memset (l2
, 0, sizeof (l2
));
2900 memset (&op1
, 0, sizeof (op1
));
2901 memset (&op2
, 0, sizeof (op2
));
2905 if ((fmt
= opcode
->fmt
) < 0)
2907 if (! target_is_430x ())
2909 as_bad (_("instruction %s requires MSP430X mcu"),
2920 /* If requested set the extended instruction repeat count. */
2923 if (repeat_count
> 0)
2924 extended
|= (repeat_count
- 1);
2926 extended
|= (1 << 7) | (- repeat_count
);
2929 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2934 /* The previous instruction set this flag if it wants to check if this insn
2938 if (! is_opcode ("nop"))
2942 switch (check_for_nop
& - check_for_nop
)
2944 case NOP_CHECK_INTERRUPT
:
2945 /* NOP_CHECK_INTERRUPT rules:
2946 1. 430 and 430x ISA require a NOP after DINT.
2947 2. Only the 430x ISA requires NOP before EINT (this has
2948 been dealt with in the previous call to this function).
2949 3. Only the 430x ISA requires NOP after every EINT.
2951 if (gen_interrupt_nops
|| warn_interrupt_nops
)
2953 if (prev_insn_is_dint
)
2955 if (gen_interrupt_nops
)
2958 if (warn_interrupt_nops
)
2959 as_warn (_(INSERT_NOP_AFTER_DINT
));
2962 as_warn (_(WARN_NOP_AFTER_DINT
));
2964 else if (prev_insn_is_eint
)
2966 if (gen_interrupt_nops
)
2969 if (warn_interrupt_nops
)
2970 as_warn (_(INSERT_NOP_AFTER_EINT
));
2973 as_warn (_(WARN_NOP_AFTER_EINT
));
2975 /* If we get here it's because the last instruction was
2976 determined to either disable or enable interrupts, but
2977 we're not sure which.
2978 We have no information yet about what effect the
2979 current instruction has on interrupts, that has to be
2981 The last insn may have required a NOP after it, so we
2982 deal with that now. */
2985 if (gen_interrupt_nops
)
2988 if (warn_interrupt_nops
)
2989 as_warn (_(INSERT_NOP_AFTER_UNKNOWN
));
2992 /* warn_unsure_interrupt was called on the previous
2994 as_warn (_(WARN_NOP_AFTER_UNKNOWN
));
2999 case NOP_CHECK_CPU12
:
3000 if (silicon_errata_warn
& SILICON_ERRATA_CPU12
)
3001 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
3003 if (silicon_errata_fix
& SILICON_ERRATA_CPU12
)
3007 case NOP_CHECK_CPU19
:
3008 if (silicon_errata_warn
& SILICON_ERRATA_CPU19
)
3009 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
3011 if (silicon_errata_fix
& SILICON_ERRATA_CPU19
)
3016 as_bad (_("internal error: unknown nop check state"));
3019 check_for_nop
&= ~ (check_for_nop
& - check_for_nop
);
3021 while (check_for_nop
);
3030 switch (opcode
->insn_opnumb
)
3033 if (is_opcode ("eint"))
3034 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3036 /* Set/clear bits instructions. */
3040 extended
|= BYTE_OPERATION
;
3042 /* Emit the extension word. */
3044 frag
= frag_more (2);
3045 bfd_putl16 (extended
, frag
);
3049 frag
= frag_more (2);
3050 bfd_putl16 ((bfd_vma
) bin
, frag
);
3051 dwarf2_emit_insn (insn_length
);
3055 /* Something which works with destination operand. */
3056 line
= extract_operand (line
, l1
, sizeof (l1
));
3057 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
3061 bin
|= (op1
.reg
| (op1
.am
<< 7));
3063 /* If the PC is the destination... */
3064 if (op1
.am
== 0 && op1
.reg
== 0
3065 /* ... and the opcode alters the SR. */
3066 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3067 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3069 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3070 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3071 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3072 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3075 /* If the status register is the destination... */
3076 if (op1
.am
== 0 && op1
.reg
== 2
3077 /* ... and the opcode alters the SR. */
3078 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
3079 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
3080 || is_opcode ("sbc") || is_opcode ("sxt")
3081 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
3082 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
3083 || is_opcode ("sbcx")
3086 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3087 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3088 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3089 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3092 /* Compute the entire instruction length, in bytes. */
3093 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3094 insn_length
+= op_length
;
3095 frag
= frag_more (op_length
);
3096 where
= frag
- frag_now
->fr_literal
;
3101 extended
|= BYTE_OPERATION
;
3103 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3105 as_bad (_("repeat instruction used with non-register mode instruction"));
3109 if (op1
.mode
== OP_EXP
)
3111 if (op1
.exp
.X_op
== O_constant
)
3112 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3114 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3115 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3116 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3118 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3119 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3122 /* Emit the extension word. */
3123 bfd_putl16 (extended
, frag
);
3128 bfd_putl16 ((bfd_vma
) bin
, frag
);
3132 if (op1
.mode
== OP_EXP
)
3134 if (op1
.exp
.X_op
== O_constant
)
3136 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3140 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3145 fix_new_exp (frag_now
, where
, 2,
3146 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3148 fix_new_exp (frag_now
, where
, 2,
3149 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3154 dwarf2_emit_insn (insn_length
);
3158 /* Shift instruction. */
3159 line
= extract_operand (line
, l1
, sizeof (l1
));
3160 strncpy (l2
, l1
, sizeof (l2
));
3161 l2
[sizeof (l2
) - 1] = '\0';
3162 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3163 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3166 break; /* An error occurred. All warnings were done before. */
3168 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
3169 frag
= frag_more (insn_length
);
3170 where
= frag
- frag_now
->fr_literal
;
3172 if (target_is_430xv2 ()
3173 && op1
.mode
== OP_REG
3175 && (is_opcode ("rlax")
3176 || is_opcode ("rlcx")
3177 || is_opcode ("rla")
3178 || is_opcode ("rlc")))
3180 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3184 /* If the status register is the destination... */
3185 if (op1
.am
== 0 && op1
.reg
== 2
3186 /* ... and the opcode alters the SR. */
3187 && (is_opcode ("rla") || is_opcode ("rlc")
3188 || is_opcode ("rlax") || is_opcode ("rlcx")
3189 || is_opcode ("sxt") || is_opcode ("sxtx")
3190 || is_opcode ("swpb")
3193 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3194 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3195 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3196 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3202 extended
|= BYTE_OPERATION
;
3204 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3206 as_bad (_("repeat instruction used with non-register mode instruction"));
3210 if (op1
.mode
== OP_EXP
)
3212 if (op1
.exp
.X_op
== O_constant
)
3213 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3215 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3216 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3217 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3219 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3220 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3223 if (op2
.mode
== OP_EXP
)
3225 if (op2
.exp
.X_op
== O_constant
)
3226 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3228 else if (op1
.mode
== OP_EXP
)
3229 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3230 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3231 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3233 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3234 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3235 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3238 /* Emit the extension word. */
3239 bfd_putl16 (extended
, frag
);
3244 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3245 bfd_putl16 ((bfd_vma
) bin
, frag
);
3249 if (op1
.mode
== OP_EXP
)
3251 if (op1
.exp
.X_op
== O_constant
)
3253 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3257 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3261 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3262 fix_new_exp (frag_now
, where
, 2,
3263 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3265 fix_new_exp (frag_now
, where
, 2,
3266 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3273 if (op2
.mode
== OP_EXP
)
3275 if (op2
.exp
.X_op
== O_constant
)
3277 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3281 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3285 if (op2
.reg
) /* Not PC relative. */
3286 fix_new_exp (frag_now
, where
, 2,
3287 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3289 fix_new_exp (frag_now
, where
, 2,
3290 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3295 dwarf2_emit_insn (insn_length
);
3299 /* Branch instruction => mov dst, r0. */
3302 as_bad ("Internal error: state 0/3 not coded for extended instructions");
3306 line
= extract_operand (line
, l1
, sizeof (l1
));
3307 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
3313 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
3314 op_length
= 2 + 2 * op1
.ol
;
3315 frag
= frag_more (op_length
);
3316 where
= frag
- frag_now
->fr_literal
;
3317 bfd_putl16 ((bfd_vma
) bin
, frag
);
3319 if (op1
.mode
== OP_EXP
)
3321 if (op1
.exp
.X_op
== O_constant
)
3323 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
3329 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3331 if (op1
.reg
|| op1
.am
== 3)
3332 fix_new_exp (frag_now
, where
, 2,
3333 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3335 fix_new_exp (frag_now
, where
, 2,
3336 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3340 dwarf2_emit_insn (insn_length
+ op_length
);
3344 /* CALLA instructions. */
3345 fix_emitted
= FALSE
;
3347 line
= extract_operand (line
, l1
, sizeof (l1
));
3350 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
3351 extended_op
, FALSE
);
3357 op_length
= 2 + 2 * op1
.ol
;
3358 frag
= frag_more (op_length
);
3359 where
= frag
- frag_now
->fr_literal
;
3367 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3368 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3371 else if (op1
.am
== 1)
3377 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3378 BFD_RELOC_MSP430X_PCR20_CALL
);
3382 bin
|= 0x50 | op1
.reg
;
3384 else if (op1
.am
== 0)
3385 bin
|= 0x40 | op1
.reg
;
3387 else if (op1
.am
== 1)
3391 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3392 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
3395 else if (op1
.am
== 2)
3396 bin
|= 0x60 | op1
.reg
;
3397 else if (op1
.am
== 3)
3398 bin
|= 0x70 | op1
.reg
;
3400 bfd_putl16 ((bfd_vma
) bin
, frag
);
3402 if (op1
.mode
== OP_EXP
)
3406 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
3410 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
3413 fix_new_exp (frag_now
, where
+ 2, 2,
3414 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
3417 dwarf2_emit_insn (insn_length
+ op_length
);
3425 /* [POP|PUSH]M[.A] #N, Rd */
3426 line
= extract_operand (line
, l1
, sizeof (l1
));
3427 line
= extract_operand (line
, l2
, sizeof (l2
));
3431 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3434 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3435 if (end
!= NULL
&& *end
!= 0)
3437 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end
, l1
);
3440 if (op1
.exp
.X_op
!= O_constant
)
3442 as_bad (_("expected constant expression as first argument of %s"),
3447 if ((reg
= check_reg (l2
)) == -1)
3449 as_bad (_("expected register as second argument of %s"),
3455 frag
= frag_more (op_length
);
3456 where
= frag
- frag_now
->fr_literal
;
3457 bin
= opcode
->bin_opcode
;
3460 n
= op1
.exp
.X_add_number
;
3461 bin
|= (n
- 1) << 4;
3462 if (is_opcode ("pushm"))
3466 if (reg
- n
+ 1 < 0)
3468 as_bad (_("Too many registers popped"));
3472 /* CPU21 errata: cannot use POPM to restore the SR register. */
3473 if (target_is_430xv2 ()
3474 && (reg
- n
+ 1 < 3)
3476 && is_opcode ("popm"))
3478 as_bad (_("Cannot use POPM to restore the SR register"));
3482 bin
|= (reg
- n
+ 1);
3485 bfd_putl16 ((bfd_vma
) bin
, frag
);
3486 dwarf2_emit_insn (op_length
);
3495 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3496 if (extended
& 0xff)
3498 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3502 line
= extract_operand (line
, l1
, sizeof (l1
));
3503 line
= extract_operand (line
, l2
, sizeof (l2
));
3507 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3510 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3511 if (end
!= NULL
&& *end
!= 0)
3513 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3516 if (op1
.exp
.X_op
!= O_constant
)
3518 as_bad (_("expected constant expression as first argument of %s"),
3522 n
= op1
.exp
.X_add_number
;
3525 as_bad (_("expected first argument of %s to be in the range 1-4"),
3530 if ((reg
= check_reg (l2
)) == -1)
3532 as_bad (_("expected register as second argument of %s"),
3537 if (target_is_430xv2 () && reg
== 0)
3539 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3544 frag
= frag_more (op_length
);
3545 where
= frag
- frag_now
->fr_literal
;
3547 bin
= opcode
->bin_opcode
;
3550 bin
|= (n
- 1) << 10;
3553 bfd_putl16 ((bfd_vma
) bin
, frag
);
3554 dwarf2_emit_insn (op_length
);
3560 bfd_boolean need_reloc
= FALSE
;
3564 /* ADDA, CMPA and SUBA address instructions. */
3565 if (extended
& 0xff)
3567 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3571 line
= extract_operand (line
, l1
, sizeof (l1
));
3572 line
= extract_operand (line
, l2
, sizeof (l2
));
3574 bin
= opcode
->bin_opcode
;
3578 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3579 if (end
!= NULL
&& *end
!= 0)
3581 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3585 if (op1
.exp
.X_op
== O_constant
)
3587 n
= op1
.exp
.X_add_number
;
3588 if (n
> 0xfffff || n
< - (0x7ffff))
3590 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3595 bin
|= ((n
>> 16) & 0xf) << 8;
3607 if ((n
= check_reg (l1
)) == -1)
3609 as_bad (_("expected register name or constant as first argument of %s"),
3614 bin
|= (n
<< 8) | (1 << 6);
3618 if ((reg
= check_reg (l2
)) == -1)
3620 as_bad (_("expected register as second argument of %s"),
3625 frag
= frag_more (op_length
);
3626 where
= frag
- frag_now
->fr_literal
;
3629 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3630 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3632 bfd_putl16 ((bfd_vma
) bin
, frag
);
3634 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3635 dwarf2_emit_insn (op_length
);
3639 case 9: /* MOVA, BRA, RETA. */
3641 bin
= opcode
->bin_opcode
;
3643 if (is_opcode ("reta"))
3645 /* The RETA instruction does not take any arguments.
3646 The implicit first argument is @SP+.
3647 The implicit second argument is PC. */
3657 line
= extract_operand (line
, l1
, sizeof (l1
));
3658 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3659 &imm_op
, extended_op
, FALSE
);
3661 if (is_opcode ("bra"))
3663 /* This is the BRA synthetic instruction.
3664 The second argument is always PC. */
3670 line
= extract_operand (line
, l2
, sizeof (l2
));
3671 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3676 break; /* Error occurred. All warnings were done before. */
3679 /* Only a restricted subset of the normal MSP430 addressing modes
3680 are supported here, so check for the ones that are allowed. */
3681 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3682 & error_message
)) == 0)
3684 as_bad (error_message
, opcode
->name
);
3687 dwarf2_emit_insn (op_length
);
3691 line
= extract_operand (line
, l1
, sizeof l1
);
3692 /* The RPT instruction only accepted immediates and registers. */
3695 end
= parse_exp (l1
+ 1, &(op1
.exp
));
3696 if (end
!= NULL
&& *end
!= 0)
3698 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
3701 if (op1
.exp
.X_op
!= O_constant
)
3703 as_bad (_("expected constant value as argument to RPT"));
3706 if (op1
.exp
.X_add_number
< 1
3707 || op1
.exp
.X_add_number
> (1 << 4))
3709 as_bad (_("expected constant in the range 2..16"));
3713 /* We silently accept and ignore a repeat count of 1. */
3714 if (op1
.exp
.X_add_number
> 1)
3715 repeat_count
= op1
.exp
.X_add_number
;
3721 if ((reg
= check_reg (l1
)) != -1)
3724 as_warn (_("PC used as an argument to RPT"));
3726 repeat_count
= - reg
;
3730 as_bad (_("expected constant or register name as argument to RPT insn"));
3737 as_bad (_("Illegal emulated instruction"));
3742 /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A.
3743 From f5 ref man 6.3.3:
3744 The 16-bit Status Register (SR, also called R2), used as a source or
3745 destination register, can only be used in register mode addressed
3746 with word instructions. */
3748 case 1: /* Format 1, double operand. */
3749 line
= extract_operand (line
, l1
, sizeof (l1
));
3750 line
= extract_operand (line
, l2
, sizeof (l2
));
3751 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3752 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3755 break; /* Error occurred. All warnings were done before. */
3758 && is_opcode ("movx")
3760 && msp430_enable_relax
)
3762 /* This is the MOVX.A instruction. See if we can convert
3763 it into the MOVA instruction instead. This saves 2 bytes. */
3764 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3767 dwarf2_emit_insn (op_length
);
3772 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3774 /* If the PC is the destination... */
3775 if (op2
.am
== 0 && op2
.reg
== 0
3776 /* ... and the opcode alters the SR. */
3777 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3778 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3780 if (silicon_errata_fix
& SILICON_ERRATA_CPU11
)
3781 as_bad (_("CPU11: PC is destination of SR altering instruction"));
3782 else if (silicon_errata_warn
& SILICON_ERRATA_CPU11
)
3783 as_warn (_("CPU11: PC is destination of SR altering instruction"));
3786 /* If the status register is the destination... */
3787 if (op2
.am
== 0 && op2
.reg
== 2
3788 /* ... and the opcode alters the SR. */
3789 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3790 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3791 || is_opcode ("xor")
3792 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3793 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3794 || is_opcode ("xorx")
3797 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
3798 as_bad (_("CPU13: SR is destination of SR altering instruction"));
3799 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
3800 as_warn (_("CPU13: SR is destination of SR altering instruction"));
3803 /* Chain these checks for SR manipulations so we can warn if they are not
3805 if (((is_opcode ("bis") && bin
== 0xd032)
3806 || (is_opcode ("mov") && bin
== 0x4032)
3807 || (is_opcode ("xor") && bin
== 0xe032))
3808 && op1
.mode
== OP_EXP
3809 && op1
.exp
.X_op
== O_constant
3810 && (op1
.exp
.X_add_number
& 0x10) == 0x10)
3811 check_for_nop
|= NOP_CHECK_CPU19
;
3812 else if ((is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3814 /* Any MOV with the SR as the destination either enables or disables
3816 if (op1
.mode
== OP_EXP
3817 && op1
.exp
.X_op
== O_constant
)
3819 if ((op1
.exp
.X_add_number
& 0x8) == 0x8)
3821 /* The GIE bit is being set. */
3822 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3823 this_insn_is_eint
= TRUE
;
3826 /* The GIE bit is being cleared. */
3827 this_insn_is_dint
= TRUE
;
3829 /* If an immediate value which is covered by the constant generator
3830 is the src, then op1 will have been changed to either R2 or R3 by
3832 The only constants covered by CG1 and CG2, which have bit 3 set
3833 and therefore would enable interrupts when writing to the SR, are
3834 R2 with addresing mode 0b11 and R3 with 0b11.
3835 The addressing mode is in bits 5:4 of the binary opcode. */
3836 else if (op1
.mode
== OP_REG
3837 && (op1
.reg
== 2 || op1
.reg
== 3)
3838 && (bin
& 0x30) == 0x30)
3840 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3841 this_insn_is_eint
= TRUE
;
3843 /* Any other use of the constant generator with destination R2, will
3844 disable interrupts. */
3845 else if (op1
.mode
== OP_REG
3846 && (op1
.reg
== 2 || op1
.reg
== 3))
3847 this_insn_is_dint
= TRUE
;
3848 else if (do_unknown_interrupt_nops
)
3850 /* FIXME: Couldn't work out whether the insn is enabling or
3851 disabling interrupts, so for safety need to treat it as both
3853 warn_unsure_interrupt (prev_insn_is_nop
, prev_insn_is_dint
);
3854 check_for_nop
|= NOP_CHECK_INTERRUPT
;
3857 else if (is_eint (opcode
->name
, bin
))
3858 warn_eint_nop (prev_insn_is_nop
, prev_insn_is_dint
);
3859 else if ((bin
& 0x32) == 0x32)
3861 /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in
3862 * an interrupt state change if a write happens. */
3863 /* FIXME: How strict to be here? */
3867 /* Compute the entire length of the instruction in bytes. */
3868 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3869 + 2 /* The opcode */
3870 + (2 * op1
.ol
) /* The first operand. */
3871 + (2 * op2
.ol
); /* The second operand. */
3873 insn_length
+= op_length
;
3874 frag
= frag_more (op_length
);
3875 where
= frag
- frag_now
->fr_literal
;
3880 extended
|= BYTE_OPERATION
;
3882 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3884 as_bad (_("repeat instruction used with non-register mode instruction"));
3888 /* If necessary, emit a reloc to update the extension word. */
3889 if (op1
.mode
== OP_EXP
)
3891 if (op1
.exp
.X_op
== O_constant
)
3892 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3894 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3895 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3896 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3898 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3899 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3902 if (op2
.mode
== OP_EXP
)
3904 if (op2
.exp
.X_op
== O_constant
)
3905 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3907 else if (op1
.mode
== OP_EXP
)
3908 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3909 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3910 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3913 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3914 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3915 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3918 /* Emit the extension word. */
3919 bfd_putl16 (extended
, frag
);
3924 bfd_putl16 ((bfd_vma
) bin
, frag
);
3928 if (op1
.mode
== OP_EXP
)
3930 if (op1
.exp
.X_op
== O_constant
)
3932 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3936 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3940 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3941 fix_new_exp (frag_now
, where
, 2,
3942 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3944 fix_new_exp (frag_now
, where
, 2,
3945 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3953 if (op2
.mode
== OP_EXP
)
3955 if (op2
.exp
.X_op
== O_constant
)
3957 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3961 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3965 if (op2
.reg
) /* Not PC relative. */
3966 fix_new_exp (frag_now
, where
, 2,
3967 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3969 fix_new_exp (frag_now
, where
, 2,
3970 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3975 dwarf2_emit_insn (insn_length
);
3977 /* If the PC is the destination... */
3978 if (op2
.am
== 0 && op2
.reg
== 0
3979 /* ... but the opcode does not alter the destination. */
3980 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3981 check_for_nop
|= NOP_CHECK_CPU12
;
3984 case 2: /* Single-operand mostly instr. */
3985 if (opcode
->insn_opnumb
== 0)
3987 /* reti instruction. */
3989 frag
= frag_more (2);
3990 bfd_putl16 ((bfd_vma
) bin
, frag
);
3991 dwarf2_emit_insn (insn_length
);
3995 line
= extract_operand (line
, l1
, sizeof (l1
));
3996 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3997 &imm_op
, extended_op
, TRUE
);
3999 break; /* Error in operand. */
4001 if (target_is_430xv2 ()
4002 && op1
.mode
== OP_REG
4004 && (is_opcode ("rrax")
4005 || is_opcode ("rrcx")
4006 || is_opcode ("rra")
4007 || is_opcode ("rrc")))
4009 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
4013 /* If the status register is the destination... */
4014 if (op1
.am
== 0 && op1
.reg
== 2
4015 /* ... and the opcode alters the SR. */
4016 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
4018 if (silicon_errata_fix
& SILICON_ERRATA_CPU13
)
4019 as_bad (_("CPU13: SR is destination of SR altering instruction"));
4020 else if (silicon_errata_warn
& SILICON_ERRATA_CPU13
)
4021 as_warn (_("CPU13: SR is destination of SR altering instruction"));
4024 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
4025 frag
= frag_more (insn_length
);
4026 where
= frag
- frag_now
->fr_literal
;
4030 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
4032 /* These two instructions use a special
4033 encoding of the A/L and B/W bits. */
4034 bin
&= ~ BYTE_OPERATION
;
4038 as_bad (_("%s instruction does not accept a .b suffix"),
4043 extended
|= BYTE_OPERATION
;
4046 extended
|= BYTE_OPERATION
;
4048 if (is_opcode ("rrux"))
4049 extended
|= IGNORE_CARRY_BIT
;
4051 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
4053 as_bad (_("repeat instruction used with non-register mode instruction"));
4057 if (op1
.mode
== OP_EXP
)
4059 if (op1
.exp
.X_op
== O_constant
)
4060 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
4062 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4063 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4064 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
4066 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
4067 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
4070 /* Emit the extension word. */
4071 bfd_putl16 (extended
, frag
);
4076 bin
|= op1
.reg
| (op1
.am
<< 4);
4077 bfd_putl16 ((bfd_vma
) bin
, frag
);
4081 if (op1
.mode
== OP_EXP
)
4083 if (op1
.exp
.X_op
== O_constant
)
4085 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
4089 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
4093 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
4094 fix_new_exp (frag_now
, where
, 2,
4095 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
4097 fix_new_exp (frag_now
, where
, 2,
4098 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
4103 dwarf2_emit_insn (insn_length
);
4106 case 3: /* Conditional jumps instructions. */
4107 line
= extract_operand (line
, l1
, sizeof (l1
));
4108 /* l1 is a label. */
4117 end
= parse_exp (m
, &exp
);
4118 if (end
!= NULL
&& *end
!= 0)
4120 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4124 /* In order to handle something like:
4128 jz 4 ; skip next 4 bytes
4131 nop ; will jump here if r5 positive or zero
4133 jCOND -n ;assumes jump n bytes backward:
4143 jCOND $n ; jump from PC in either direction. */
4145 if (exp
.X_op
== O_constant
)
4147 int x
= exp
.X_add_number
;
4151 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
4155 if ((*l1
== '$' && x
> 0) || x
< 0)
4160 if (x
> 512 || x
< -511)
4162 as_bad (_("Wrong displacement %d"), x
<< 1);
4167 frag
= frag_more (2); /* Instr size is 1 word. */
4170 bfd_putl16 ((bfd_vma
) bin
, frag
);
4172 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
4175 frag
= frag_more (2); /* Instr size is 1 word. */
4176 where
= frag
- frag_now
->fr_literal
;
4177 fix_new_exp (frag_now
, where
, 2,
4178 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
4180 bfd_putl16 ((bfd_vma
) bin
, frag
);
4182 else if (*l1
== '$')
4184 as_bad (_("instruction requires label sans '$'"));
4188 ("instruction requires label or value in range -511:512"));
4189 dwarf2_emit_insn (insn_length
);
4194 as_bad (_("instruction requires label"));
4199 case 4: /* Extended jumps. */
4200 if (!msp430_enable_polys
)
4202 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4206 line
= extract_operand (line
, l1
, sizeof (l1
));
4212 /* Ignore absolute addressing. make it PC relative anyway. */
4213 if (*m
== '#' || *m
== '$')
4216 end
= parse_exp (m
, & exp
);
4217 if (end
!= NULL
&& *end
!= 0)
4219 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4222 if (exp
.X_op
== O_symbol
)
4224 /* Relaxation required. */
4225 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
4227 if (target_is_430x ())
4228 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
4230 /* The parameter to dwarf2_emit_insn is actually the offset to
4231 the start of the insn from the fix piece of instruction that
4232 was emitted. Since next fragments may have variable size we
4233 tie debug info to the beginning of the instruction. */
4235 frag
= frag_more (8);
4236 dwarf2_emit_insn (0);
4237 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
4238 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4240 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
4242 0, /* Offset is zero if jump dist less than 1K. */
4248 as_bad (_("instruction requires label"));
4251 case 5: /* Emulated extended branches. */
4252 if (!msp430_enable_polys
)
4254 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
4257 line
= extract_operand (line
, l1
, sizeof (l1
));
4263 /* Ignore absolute addressing. make it PC relative anyway. */
4264 if (*m
== '#' || *m
== '$')
4267 end
= parse_exp (m
, & exp
);
4268 if (end
!= NULL
&& *end
!= 0)
4270 as_bad (_("extra characters '%s' at end of operand '%s'"), end
, l1
);
4273 if (exp
.X_op
== O_symbol
)
4275 /* Relaxation required. */
4276 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
4278 if (target_is_430x ())
4279 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
4282 frag
= frag_more (8);
4283 dwarf2_emit_insn (0);
4284 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
4285 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
4287 frag
= frag_variant (rs_machine_dependent
, 8, 2,
4288 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
4290 0, /* Offset is zero if jump dist less than 1K. */
4296 as_bad (_("instruction requires label"));
4300 as_bad (_("Illegal instruction or not implemented opcode."));
4303 if (is_opcode ("nop"))
4305 prev_insn_is_nop
= TRUE
;
4306 prev_insn_is_dint
= FALSE
;
4307 prev_insn_is_eint
= FALSE
;
4309 else if (this_insn_is_dint
|| is_dint (opcode
->name
, bin
))
4311 prev_insn_is_dint
= TRUE
;
4312 prev_insn_is_eint
= FALSE
;
4313 prev_insn_is_nop
= FALSE
;
4314 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4316 /* NOP is not needed after EINT for 430 ISA. */
4317 else if (target_is_430x () && (this_insn_is_eint
|| is_eint (opcode
->name
, bin
)))
4319 prev_insn_is_eint
= TRUE
;
4320 prev_insn_is_nop
= FALSE
;
4321 prev_insn_is_dint
= FALSE
;
4322 check_for_nop
|= NOP_CHECK_INTERRUPT
;
4326 prev_insn_is_nop
= FALSE
;
4327 prev_insn_is_dint
= FALSE
;
4328 prev_insn_is_eint
= FALSE
;
4331 input_line_pointer
= line
;
4336 md_assemble (char * str
)
4338 struct msp430_opcode_s
* opcode
;
4342 str
= skip_space (str
); /* Skip leading spaces. */
4343 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
4347 char a
= TOLOWER (cmd
[i
]);
4354 as_bad (_("can't find opcode"));
4358 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
4362 as_bad (_("unknown opcode `%s'"), cmd
);
4367 char *__t
= input_line_pointer
;
4369 msp430_operands (opcode
, str
);
4370 input_line_pointer
= __t
;
4374 /* GAS will call this function for each section at the end of the assembly,
4375 to permit the CPU backend to adjust the alignment of a section. */
4378 md_section_align (asection
* seg
, valueT addr
)
4380 int align
= bfd_section_alignment (seg
);
4382 return ((addr
+ (1 << align
) - 1) & -(1 << align
));
4385 /* If you define this macro, it should return the offset between the
4386 address of a PC relative fixup and the position from which the PC
4387 relative adjustment should be made. On many processors, the base
4388 of a PC relative instruction is the next instruction, so this
4389 macro would return the length of an instruction. */
4392 md_pcrel_from_section (fixS
* fixp
, segT sec
)
4394 if (fixp
->fx_addsy
!= (symbolS
*) NULL
4395 && (!S_IS_DEFINED (fixp
->fx_addsy
)
4396 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
4399 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4402 /* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
4403 Now it handles the situation when relocations
4404 have to be passed to linker. */
4406 msp430_force_relocation_local (fixS
*fixp
)
4408 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
4412 if (msp430_enable_polys
4413 && !msp430_enable_relax
)
4420 /* GAS will call this for each fixup. It should store the correct
4421 value in the object file. */
4423 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
4425 unsigned char * where
;
4429 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
4434 else if (fixp
->fx_pcrel
)
4436 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
4438 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
4440 /* FIXME: We can appear here only in case if we perform a pc
4441 relative jump to the label which is i) global, ii) locally
4442 defined or this is a jump to an absolute symbol.
4443 If this is an absolute symbol -- everything is OK.
4444 If this is a global label, we've got a symbol value defined
4446 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4447 from this section start
4448 2. *valuep will contain the real offset from jump insn to the
4450 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4451 will be incorrect. Therefore remove s_get_value. */
4452 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
4460 value
= fixp
->fx_offset
;
4462 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
4464 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4466 value
-= S_GET_VALUE (fixp
->fx_subsy
);
4472 fixp
->fx_no_overflow
= 1;
4474 /* If polymorphs are enabled and relax disabled.
4475 do not kill any relocs and pass them to linker. */
4476 if (msp430_enable_polys
4477 && !msp430_enable_relax
)
4480 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4481 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
4488 /* Fetch the instruction, insert the fully resolved operand
4489 value, and stuff the instruction back again. */
4490 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
4492 insn
= bfd_getl16 (where
);
4494 switch (fixp
->fx_r_type
)
4496 case BFD_RELOC_MSP430_10_PCREL
:
4498 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4499 _("odd address operand: %ld"), value
);
4501 /* Jumps are in words. */
4503 --value
; /* Correct PC. */
4505 if (value
< -512 || value
> 511)
4506 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4507 _("operand out of range: %ld"), value
);
4509 value
&= 0x3ff; /* get rid of extended sign */
4510 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
4513 case BFD_RELOC_MSP430X_PCR16
:
4514 case BFD_RELOC_MSP430_RL_PCREL
:
4515 case BFD_RELOC_MSP430_16_PCREL
:
4517 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4518 _("odd address operand: %ld"), value
);
4521 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
4522 /* Nothing to be corrected here. */
4523 if (value
< -32768 || value
> 65536)
4524 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4525 _("operand out of range: %ld"), value
);
4528 case BFD_RELOC_MSP430X_ABS16
:
4529 case BFD_RELOC_MSP430_16
:
4531 case BFD_RELOC_MSP430_16_BYTE
:
4532 value
&= 0xffff; /* Get rid of extended sign. */
4533 bfd_putl16 ((bfd_vma
) value
, where
);
4536 case BFD_RELOC_MSP430_ABS_HI16
:
4538 value
&= 0xffff; /* Get rid of extended sign. */
4539 bfd_putl16 ((bfd_vma
) value
, where
);
4543 bfd_putl16 ((bfd_vma
) value
, where
);
4546 case BFD_RELOC_MSP430_ABS8
:
4548 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
4551 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
4552 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
4553 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4555 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
4558 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
4559 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4561 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
4564 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
4565 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4567 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4570 case BFD_RELOC_MSP430X_PCR20_CALL
:
4571 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4573 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4576 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
4577 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
4578 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
4580 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4583 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
4584 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
4586 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4589 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
4590 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
4592 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
4596 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4597 fixp
->fx_line
, fixp
->fx_r_type
);
4603 fixp
->fx_addnumber
= value
;
4608 S_IS_GAS_LOCAL (symbolS
* s
)
4615 name
= S_GET_NAME (s
);
4616 len
= strlen (name
) - 1;
4618 return name
[len
] == 1 || name
[len
] == 2;
4621 /* GAS will call this to generate a reloc, passing the resulting reloc
4622 to `bfd_install_relocation'. This currently works poorly, as
4623 `bfd_install_relocation' often does the wrong thing, and instances of
4624 `tc_gen_reloc' have been written to work around the problems, which
4625 in turns makes it difficult to fix `bfd_install_relocation'. */
4627 /* If while processing a fixup, a reloc really needs to be created
4628 then it is done here. */
4631 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4633 static arelent
* no_relocs
= NULL
;
4634 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4637 reloc
= XNEW (arelent
);
4638 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4639 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4641 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4643 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4644 _("reloc %d not supported by object file format"),
4645 (int) fixp
->fx_r_type
);
4654 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4656 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4657 fixp
->fx_subsy
= NULL
;
4660 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4662 asection
*asec
, *ssec
;
4664 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4665 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4667 /* If we have a difference between two different, non-absolute symbols
4668 we must generate two relocs (one for each symbol) and allow the
4669 linker to resolve them - relaxation may change the distances between
4670 symbols, even local symbols defined in the same section.
4672 Unfortunately we cannot do this with assembler generated local labels
4673 because there can be multiple incarnations of the same label, with
4674 exactly the same name, in any given section and the linker will have
4675 no way to identify the correct one. Instead we just have to hope
4676 that no relaxation will occur between the local label and the other
4677 symbol in the expression.
4679 Similarly we have to compute differences between symbols in the .eh_frame
4680 section as the linker is not smart enough to apply relocations there
4681 before attempting to process it. */
4682 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4683 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4684 && strcmp (ssec
->name
, ".eh_frame") != 0
4685 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4686 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4688 arelent
* reloc2
= XNEW (arelent
);
4693 reloc2
->address
= reloc
->address
;
4694 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4695 BFD_RELOC_MSP430_SYM_DIFF
);
4696 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4698 if (ssec
== absolute_section
)
4699 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4702 reloc2
->sym_ptr_ptr
= XNEW (asymbol
*);
4703 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4706 reloc
->addend
= fixp
->fx_offset
;
4707 if (asec
== absolute_section
)
4709 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4710 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4714 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4715 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4724 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4726 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4727 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4729 switch (fixp
->fx_r_type
)
4732 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4736 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4740 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4744 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4749 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4760 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4761 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4763 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4764 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4766 md_number_to_chars (fixpos
, amount
, 2);
4771 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
4772 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4773 reloc
->addend
= fixp
->fx_offset
;
4775 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4776 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4777 reloc
->address
= fixp
->fx_offset
;
4784 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4785 asection
* segment_type ATTRIBUTE_UNUSED
)
4787 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4789 /* This is a jump -> pcrel mode. Nothing to do much here.
4790 Return value == 2. */
4792 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4794 else if (fragP
->fr_symbol
)
4796 /* It's got a segment, but it's not ours. Even if fr_symbol is in
4797 an absolute segment, we don't know a displacement until we link
4798 object files. So it will always be long. This also applies to
4799 labels in a subsegment of current. Liker may relax it to short
4800 jump later. Return value == 8. */
4802 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4806 /* We know the abs value. may be it is a jump to fixed address.
4807 Impossible in our case, cause all constants already handled. */
4809 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4812 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4816 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4817 asection
* sec ATTRIBUTE_UNUSED
,
4823 struct rcodes_s
* cc
= NULL
;
4824 struct hcodes_s
* hc
= NULL
;
4826 switch (fragP
->fr_subtype
)
4828 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4829 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4830 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4831 /* We do not have to convert anything here.
4832 Just apply a fix. */
4833 rela
= BFD_RELOC_MSP430_10_PCREL
;
4836 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4837 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4838 /* Convert uncond branch jmp lab -> br lab. */
4839 if (target_is_430x ())
4840 cc
= msp430x_rcodes
+ 7;
4842 cc
= msp430_rcodes
+ 7;
4843 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4844 bfd_putl16 (cc
->lop0
, where
);
4845 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4849 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4850 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4852 /* Other simple branches. */
4853 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4856 /* Find actual instruction. */
4857 if (target_is_430x ())
4859 for (i
= 0; i
< 7 && !cc
; i
++)
4860 if (msp430x_rcodes
[i
].sop
== insn
)
4861 cc
= msp430x_rcodes
+ i
;
4865 for (i
= 0; i
< 7 && !cc
; i
++)
4866 if (msp430_rcodes
[i
].sop
== insn
)
4867 cc
= & msp430_rcodes
[i
];
4870 if (!cc
|| !cc
->name
)
4871 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4872 __FUNCTION__
, (long) insn
);
4873 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4874 bfd_putl16 (cc
->lop0
, where
);
4875 bfd_putl16 (cc
->lop1
, where
+ 2);
4876 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4881 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4882 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4883 if (target_is_430x ())
4884 cc
= msp430x_rcodes
+ 6;
4886 cc
= msp430_rcodes
+ 6;
4887 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4888 bfd_putl16 (cc
->lop0
, where
);
4889 bfd_putl16 (cc
->lop1
, where
+ 2);
4890 bfd_putl16 (cc
->lop2
, where
+ 4);
4891 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4895 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4897 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4900 if (target_is_430x ())
4902 for (i
= 0; i
< 4 && !hc
; i
++)
4903 if (msp430x_hcodes
[i
].op1
== insn
)
4904 hc
= msp430x_hcodes
+ i
;
4908 for (i
= 0; i
< 4 && !hc
; i
++)
4909 if (msp430_hcodes
[i
].op1
== insn
)
4910 hc
= &msp430_hcodes
[i
];
4912 if (!hc
|| !hc
->name
)
4913 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4914 __FUNCTION__
, (long) insn
);
4915 rela
= BFD_RELOC_MSP430_10_PCREL
;
4916 /* Apply a fix for a first label if necessary.
4917 another fix will be applied to the next word of insn anyway. */
4919 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4920 fragP
->fr_offset
, TRUE
, rela
);
4926 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4927 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4929 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4932 if (target_is_430x ())
4934 for (i
= 0; i
< 4 && !hc
; i
++)
4935 if (msp430x_hcodes
[i
].op1
== insn
)
4936 hc
= msp430x_hcodes
+ i
;
4940 for (i
= 0; i
< 4 && !hc
; i
++)
4941 if (msp430_hcodes
[i
].op1
== insn
)
4942 hc
= & msp430_hcodes
[i
];
4944 if (!hc
|| !hc
->name
)
4945 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4946 __FUNCTION__
, (long) insn
);
4947 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4948 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4949 bfd_putl16 (hc
->lop0
, where
);
4950 bfd_putl16 (hc
->lop1
, where
+ 2);
4951 bfd_putl16 (hc
->lop2
, where
+ 4);
4957 as_fatal (_("internal inconsistency problem in %s: %lx"),
4958 __FUNCTION__
, (long) fragP
->fr_subtype
);
4962 /* Now apply fix. */
4963 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4964 fragP
->fr_offset
, TRUE
, rela
);
4965 /* Just fixed 2 bytes. */
4969 /* Relax fragment. Mostly stolen from hc11 and mcore
4970 which arches I think I know. */
4973 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4974 long stretch ATTRIBUTE_UNUSED
)
4979 const relax_typeS
*this_type
;
4980 const relax_typeS
*start_type
;
4981 relax_substateT next_state
;
4982 relax_substateT this_state
;
4983 const relax_typeS
*table
= md_relax_table
;
4985 /* Nothing to be done if the frag has already max size. */
4986 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4987 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4990 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4992 symbolP
= fragP
->fr_symbol
;
4993 if (symbol_resolved_p (symbolP
))
4994 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4996 /* We know the offset. calculate a distance. */
4997 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
5000 if (!msp430_enable_relax
)
5002 /* Relaxation is not enabled. So, make all jump as long ones
5003 by setting 'aim' to quite high value. */
5007 this_state
= fragP
->fr_subtype
;
5008 start_type
= this_type
= table
+ this_state
;
5012 /* Look backwards. */
5013 for (next_state
= this_type
->rlx_more
; next_state
;)
5014 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
5018 /* Grow to next state. */
5019 this_state
= next_state
;
5020 this_type
= table
+ this_state
;
5021 next_state
= this_type
->rlx_more
;
5026 /* Look forwards. */
5027 for (next_state
= this_type
->rlx_more
; next_state
;)
5028 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
5032 /* Grow to next state. */
5033 this_state
= next_state
;
5034 this_type
= table
+ this_state
;
5035 next_state
= this_type
->rlx_more
;
5039 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5041 fragP
->fr_subtype
= this_state
;
5045 /* Return FALSE if the fixup in fixp should be left alone and not
5046 adjusted. We return FALSE here so that linker relaxation will
5050 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
5052 /* If the symbol is in a non-code section then it should be OK. */
5054 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
5060 /* Set the contents of the .MSP430.attributes and .GNU.attributes sections. */
5063 msp430_md_end (void)
5067 if (gen_interrupt_nops
)
5070 if (warn_interrupt_nops
)
5071 as_warn (INSERT_NOP_AT_EOF
);
5073 else if (warn_interrupt_nops
)
5074 as_warn (_(WARN_NOP_AT_EOF
));
5077 /* We have already emitted an error if any of the following attributes
5078 disagree with the attributes in the input assembly file. See
5079 msp430_object_attribute. */
5080 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
5081 target_is_430x () ? OFBA_MSPABI_Val_ISA_MSP430X
5082 : OFBA_MSPABI_Val_ISA_MSP430
);
5084 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
5085 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5086 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5088 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
5089 large_model
? OFBA_MSPABI_Val_Code_Model_LARGE
5090 : OFBA_MSPABI_Val_Code_Model_SMALL
);
5092 /* The data region GNU attribute is ignored for the small memory model. */
5094 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_GNU
,
5095 Tag_GNU_MSP430_Data_Region
, lower_data_region_only
5096 ? Val_GNU_MSP430_Data_Region_Lower
5097 : Val_GNU_MSP430_Data_Region_Any
);
5100 /* Returns FALSE if there is a msp430 specific reason why the
5101 subtraction of two same-section symbols cannot be computed by
5105 msp430_allow_local_subtract (expressionS
* left
,
5106 expressionS
* right
,
5109 /* If the symbols are not in a code section then they are OK. */
5110 if ((section
->flags
& SEC_CODE
) == 0)
5113 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
5116 if (left
->X_add_symbol
== right
->X_add_symbol
)
5119 /* We have to assume that there may be instructions between the
5120 two symbols and that relaxation may increase the distance between