1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2015 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. */
25 #define PUSH_1X_WORKAROUND
27 #include "opcode/msp430.h"
28 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
30 #include "elf/msp430.h"
31 #include "libiberty.h"
33 /* We will disable polymorphs by default because it is dangerous.
34 The potential problem here is the following: assume we got the
39 jump subroutine ; external symbol
44 In case of assembly time relaxation we'll get:
45 0: jmp .l1 <.text +0x08> (reloc deleted)
52 If the 'subroutine' is within +-1024 bytes range then linker
59 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
61 The workaround is the following:
62 1. Declare global var enable_polymorphs which set to 1 via option -mp.
63 2. Declare global var enable_relax which set to 1 via option -mQ.
65 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
66 do not delete any relocs and leave them for linker.
68 If relax is enabled, relax at assembly time and kill relocs as necessary. */
70 int msp430_enable_relax
;
71 int msp430_enable_polys
;
73 /* Set linkrelax here to avoid fixups in most sections. */
76 /* GCC uses the some condition codes which we'll
77 implement as new polymorph instructions.
79 COND EXPL SHORT JUMP LONG JUMP
80 ===============================================
81 eq == jeq jne +4; br lab
82 ne != jne jeq +4; br lab
84 ltn honours no-overflow flag
85 ltn < jn jn +2; jmp +4; br lab
87 lt < jl jge +4; br lab
88 ltu < jlo lhs +4; br lab
94 ge >= jge jl +4; br lab
95 geu >= jhs jlo +4; br lab
96 ===============================================
98 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
99 beq,bne,blt,bltn,bltu,bge,bgeu
100 'u' means unsigned compares
102 Also, we add 'jump' instruction:
103 jump UNCOND -> jmp br lab
105 They will have fmt == 4, and insn_opnumb == number of instruction. */
110 int index
; /* Corresponding insn_opnumb. */
111 int sop
; /* Opcode if jump length is short. */
112 long lpos
; /* Label position. */
113 long lop0
; /* Opcode 1 _word_ (16 bits). */
114 long lop1
; /* Opcode second word. */
115 long lop2
; /* Opcode third word. */
118 #define MSP430_RLC(n,i,sop,o1) \
119 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
121 static struct rcodes_s msp430_rcodes
[] =
123 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
124 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
125 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
126 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
127 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
128 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
129 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
130 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
135 #define MSP430_RLC(n,i,sop,o1) \
136 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
138 static struct rcodes_s msp430x_rcodes
[] =
140 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
141 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
142 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
143 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
144 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
145 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
146 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
147 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
152 /* More difficult than above and they have format 5.
155 =================================================================
156 gt > jeq +2; jge label jeq +6; jl +4; br label
157 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
158 leu <= jeq label; jlo label jeq +2; jhs +4; br label
159 le <= jeq label; jl label jeq +2; jge +4; br label
160 ================================================================= */
165 int index
; /* Corresponding insn_opnumb. */
166 int tlab
; /* Number of labels in short mode. */
167 int op0
; /* Opcode for first word of short jump. */
168 int op1
; /* Opcode for second word of short jump. */
169 int lop0
; /* Opcodes for long jump mode. */
174 static struct hcodes_s msp430_hcodes
[] =
176 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
177 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
178 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
179 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
183 static struct hcodes_s msp430x_hcodes
[] =
185 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
186 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
187 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
188 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
192 const char comment_chars
[] = ";";
193 const char line_comment_chars
[] = "#";
194 const char line_separator_chars
[] = "{";
195 const char EXP_CHARS
[] = "eE";
196 const char FLT_CHARS
[] = "dD";
198 /* Handle long expressions. */
199 extern LITTLENUM_TYPE generic_bignum
[];
201 static struct hash_control
*msp430_hash
;
204 #define STATE_UNCOND_BRANCH 1 /* jump */
205 #define STATE_NOOV_BRANCH 3 /* bltn */
206 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
207 #define STATE_EMUL_BRANCH 4
216 #define STATE_BITS10 1 /* wild guess. short jump */
217 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
218 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
220 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
221 #define RELAX_STATE(s) ((s) & 3)
222 #define RELAX_LEN(s) ((s) >> 2)
223 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
225 relax_typeS md_relax_table
[] =
233 /* Unconditional jump. */
235 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
236 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
237 {1, 1, CUBL
, 0}, /* state undef */
239 /* Simple branches. */
241 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
242 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
245 /* blt no overflow branch. */
247 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
248 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
251 /* Emulated branches. */
253 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
254 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
259 #define MAX_OP_LEN 4096
268 static enum msp_isa selected_isa
= MSP_ISA_430Xv2
;
270 static inline bfd_boolean
271 target_is_430x (void)
273 return selected_isa
>= MSP_ISA_430X
;
276 static inline bfd_boolean
277 target_is_430xv2 (void)
279 return selected_isa
== MSP_ISA_430Xv2
;
282 /* Generate an absolute 16-bit relocation.
283 For the 430X we generate a relocation without linker range checking
284 if the value is being used in an extended (ie 20-bit) instruction,
285 otherwise if have a shifted expression we use a HI reloc.
286 For the 430 we generate a relocation without assembler range checking
287 if we are handling an immediate value or a byte-width instruction. */
289 #undef CHECK_RELOC_MSP430
290 #define CHECK_RELOC_MSP430(OP) \
294 : ((OP).vshift == 1) \
295 ? BFD_RELOC_MSP430_ABS_HI16 \
296 : BFD_RELOC_MSP430X_ABS16) \
297 : ((imm_op || byte_op) \
298 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
300 /* Generate a 16-bit pc-relative relocation.
301 For the 430X we generate a relocation without linkwer range checking.
302 For the 430 we generate a relocation without assembler range checking
303 if we are handling an immediate value or a byte-width instruction. */
304 #undef CHECK_RELOC_MSP430_PCREL
305 #define CHECK_RELOC_MSP430_PCREL \
307 ? BFD_RELOC_MSP430X_PCR16 \
308 : (imm_op || byte_op) \
309 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
311 /* Profiling capability:
312 It is a performance hit to use gcc's profiling approach for this tiny target.
313 Even more -- jtag hardware facility does not perform any profiling functions.
314 However we've got gdb's built-in simulator where we can do anything.
315 Therefore my suggestion is:
317 We define new section ".profiler" which holds all profiling information.
318 We define new pseudo operation .profiler which will instruct assembler to
319 add new profile entry to the object file. Profile should take place at the
324 .profiler flags,function_to_profile [, cycle_corrector, extra]
326 where 'flags' is a combination of the following chars:
329 i - function is in Init section
330 f - function is in Fini section
332 c - libC standard call
333 d - stack value Demand (saved at run-time in simulator)
334 I - Interrupt service routine
339 j - long Jump/ sjlj unwind
340 a - an Arbitrary code fragment
341 t - exTra parameter saved (constant value like frame size)
342 '""' optional: "sil" == sil
344 function_to_profile - function's address
345 cycle_corrector - a value which should be added to the cycle
346 counter, zero if omitted
347 extra - some extra parameter, zero if omitted.
350 ------------------------------
354 .LFrameOffset_fxx=0x08
355 .profiler "scdP", fxx ; function entry.
356 ; we also demand stack value to be displayed
361 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
362 ; (this is a prologue end)
363 ; note, that spare var filled with the frame size
366 .profiler cdE,fxx ; check stack
371 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
372 ret ; cause 'ret' insn takes 3 cycles
373 -------------------------------
375 This profiling approach does not produce any overhead and
377 So, even profiled code can be uploaded to the MCU. */
378 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
379 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
380 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
381 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
382 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
383 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
384 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
385 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
386 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
387 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
388 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
389 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
390 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
391 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
392 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
393 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
406 for (; x
; x
= x
>> 1)
413 /* Parse ordinary expression. */
416 parse_exp (char * s
, expressionS
* op
)
418 input_line_pointer
= s
;
420 if (op
->X_op
== O_absent
)
421 as_bad (_("missing operand"));
422 return input_line_pointer
;
426 /* Delete spaces from s: X ( r 1 2) => X(r12). */
429 del_spaces (char * s
)
437 while (ISSPACE (*m
) && *m
)
439 memmove (s
, m
, strlen (m
) + 1);
447 skip_space (char * s
)
454 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
457 extract_operand (char * from
, char * to
, int limit
)
461 /* Drop leading whitespace. */
462 from
= skip_space (from
);
464 while (size
< limit
&& *from
)
466 *(to
+ size
) = *from
;
467 if (*from
== ',' || *from
== ';' || *from
== '\n')
482 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
499 s
= input_line_pointer
;
500 end
= input_line_pointer
;
502 while (*end
&& *end
!= '\n')
505 while (*s
&& *s
!= '\n')
516 as_bad (_(".profiler pseudo requires at least two operands."));
517 input_line_pointer
= end
;
521 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
530 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
533 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
536 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
539 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
542 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
545 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
548 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
551 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
554 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
557 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
560 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
563 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
566 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
569 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
572 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
575 as_warn (_("unknown profiling flag - ignored."));
582 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
583 | MSP430_PROFILER_FLAG_EXIT
))
584 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
585 | MSP430_PROFILER_FLAG_PROLEND
586 | MSP430_PROFILER_FLAG_EPISTART
587 | MSP430_PROFILER_FLAG_EPIEND
))
588 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
589 | MSP430_PROFILER_FLAG_FINISECT
))))
591 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
592 input_line_pointer
= end
;
596 /* Generate temp symbol which denotes current location. */
597 if (now_seg
== absolute_section
) /* Paranoia ? */
599 exp1
.X_op
= O_constant
;
600 exp1
.X_add_number
= abs_section_offset
;
601 as_warn (_("profiling in absolute section?"));
605 exp1
.X_op
= O_symbol
;
606 exp1
.X_add_symbol
= symbol_temp_new_now ();
607 exp1
.X_add_number
= 0;
610 /* Generate a symbol which holds flags value. */
611 exp
.X_op
= O_constant
;
612 exp
.X_add_number
= p_flags
;
614 /* Save current section. */
618 /* Now go to .profiler section. */
619 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
622 emit_expr (& exp
, 2);
624 /* Save label value. */
625 emit_expr (& exp1
, 2);
629 /* Now get profiling info. */
630 halt
= extract_operand (input_line_pointer
, str
, 1024);
631 /* Process like ".word xxx" directive. */
632 parse_exp (str
, & exp
);
633 emit_expr (& exp
, 2);
634 input_line_pointer
= halt
;
637 /* Fill the rest with zeros. */
638 exp
.X_op
= O_constant
;
639 exp
.X_add_number
= 0;
641 emit_expr (& exp
, 2);
643 /* Return to current section. */
644 subseg_set (seg
, subseg
);
648 extract_word (char * from
, char * to
, int limit
)
653 /* Drop leading whitespace. */
654 from
= skip_space (from
);
657 /* Find the op code end. */
658 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
660 to
[size
++] = *op_end
++;
661 if (size
+ 1 >= limit
)
669 #define OPTION_MMCU 'm'
670 #define OPTION_RELAX 'Q'
671 #define OPTION_POLYMORPHS 'P'
672 #define OPTION_LARGE 'l'
673 static bfd_boolean large_model
= FALSE
;
674 #define OPTION_NO_INTR_NOPS 'N'
675 #define OPTION_INTR_NOPS 'n'
676 static bfd_boolean gen_interrupt_nops
= FALSE
;
677 #define OPTION_WARN_INTR_NOPS 'y'
678 #define OPTION_NO_WARN_INTR_NOPS 'Y'
679 static bfd_boolean warn_interrupt_nops
= TRUE
;
680 #define OPTION_MCPU 'c'
681 #define OPTION_MOVE_DATA 'd'
682 static bfd_boolean move_data
= FALSE
;
685 msp430_set_arch (int option
)
687 char *str
= (char *) alloca (32); /* 32 for good measure. */
689 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
691 md_parse_option (option
, str
);
692 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
693 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
696 /* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
697 Keep these two structures in sync.
698 The data in this structure has been extracted from the devices.csv file
699 released by TI, updated as of 8 October 2015. */
701 struct msp430_mcu_data
704 unsigned int revision
; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
705 unsigned int hwmpy
; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
709 { "cc430f5123",2,8 },
710 { "cc430f5125",2,8 },
711 { "cc430f5133",2,8 },
712 { "cc430f5135",2,8 },
713 { "cc430f5137",2,8 },
714 { "cc430f5143",2,8 },
715 { "cc430f5145",2,8 },
716 { "cc430f5147",2,8 },
717 { "cc430f6125",2,8 },
718 { "cc430f6126",2,8 },
719 { "cc430f6127",2,8 },
720 { "cc430f6135",2,8 },
721 { "cc430f6137",2,8 },
722 { "cc430f6143",2,8 },
723 { "cc430f6145",2,8 },
724 { "cc430f6147",2,8 },
725 { "msp430afe221",0,2 },
726 { "msp430afe222",0,2 },
727 { "msp430afe223",0,2 },
728 { "msp430afe231",0,2 },
729 { "msp430afe232",0,2 },
730 { "msp430afe233",0,2 },
731 { "msp430afe251",0,2 },
732 { "msp430afe252",0,2 },
733 { "msp430afe253",0,2 },
734 { "msp430bt5190",2,8 },
735 { "msp430c091",0,0 },
736 { "msp430c092",0,0 },
737 { "msp430c111",0,0 },
738 { "msp430c1111",0,0 },
739 { "msp430c112",0,0 },
740 { "msp430c1121",0,0 },
741 { "msp430c1331",0,0 },
742 { "msp430c1351",0,0 },
743 { "msp430c311s",0,0 },
744 { "msp430c312",0,0 },
745 { "msp430c313",0,0 },
746 { "msp430c314",0,0 },
747 { "msp430c315",0,0 },
748 { "msp430c323",0,0 },
749 { "msp430c325",0,0 },
750 { "msp430c336",0,1 },
751 { "msp430c337",0,1 },
752 { "msp430c412",0,0 },
753 { "msp430c413",0,0 },
754 { "msp430cg4616",1,1 },
755 { "msp430cg4617",1,1 },
756 { "msp430cg4618",1,1 },
757 { "msp430cg4619",1,1 },
758 { "msp430e112",0,0 },
759 { "msp430e313",0,0 },
760 { "msp430e315",0,0 },
761 { "msp430e325",0,0 },
762 { "msp430e337",0,1 },
763 { "msp430f110",0,0 },
764 { "msp430f1101",0,0 },
765 { "msp430f1101a",0,0 },
766 { "msp430f1111",0,0 },
767 { "msp430f1111a",0,0 },
768 { "msp430f112",0,0 },
769 { "msp430f1121",0,0 },
770 { "msp430f1121a",0,0 },
771 { "msp430f1122",0,0 },
772 { "msp430f1132",0,0 },
773 { "msp430f122",0,0 },
774 { "msp430f1222",0,0 },
775 { "msp430f123",0,0 },
776 { "msp430f1232",0,0 },
777 { "msp430f133",0,0 },
778 { "msp430f135",0,0 },
779 { "msp430f147",0,1 },
780 { "msp430f1471",0,1 },
781 { "msp430f148",0,1 },
782 { "msp430f1481",0,1 },
783 { "msp430f149",0,1 },
784 { "msp430f1491",0,1 },
785 { "msp430f155",0,0 },
786 { "msp430f156",0,0 },
787 { "msp430f157",0,0 },
788 { "msp430f1610",0,1 },
789 { "msp430f1611",0,1 },
790 { "msp430f1612",0,1 },
791 { "msp430f167",0,1 },
792 { "msp430f168",0,1 },
793 { "msp430f169",0,1 },
794 { "msp430f2001",0,0 },
795 { "msp430f2002",0,0 },
796 { "msp430f2003",0,0 },
797 { "msp430f2011",0,0 },
798 { "msp430f2012",0,0 },
799 { "msp430f2013",0,0 },
800 { "msp430f2101",0,0 },
801 { "msp430f2111",0,0 },
802 { "msp430f2112",0,0 },
803 { "msp430f2121",0,0 },
804 { "msp430f2122",0,0 },
805 { "msp430f2131",0,0 },
806 { "msp430f2132",0,0 },
807 { "msp430f2232",0,0 },
808 { "msp430f2234",0,0 },
809 { "msp430f2252",0,0 },
810 { "msp430f2254",0,0 },
811 { "msp430f2272",0,0 },
812 { "msp430f2274",0,0 },
813 { "msp430f233",0,2 },
814 { "msp430f2330",0,2 },
815 { "msp430f235",0,2 },
816 { "msp430f2350",0,2 },
817 { "msp430f2370",0,2 },
818 { "msp430f2410",0,2 },
819 { "msp430f2416",1,2 },
820 { "msp430f2417",1,2 },
821 { "msp430f2418",1,2 },
822 { "msp430f2419",1,2 },
823 { "msp430f247",0,2 },
824 { "msp430f2471",0,2 },
825 { "msp430f248",0,2 },
826 { "msp430f2481",0,2 },
827 { "msp430f249",0,2 },
828 { "msp430f2491",0,2 },
829 { "msp430f2616",1,2 },
830 { "msp430f2617",1,2 },
831 { "msp430f2618",1,2 },
832 { "msp430f2619",1,2 },
833 { "msp430f412",0,0 },
834 { "msp430f413",0,0 },
835 { "msp430f4132",0,0 },
836 { "msp430f415",0,0 },
837 { "msp430f4152",0,0 },
838 { "msp430f417",0,0 },
839 { "msp430f423",0,1 },
840 { "msp430f423a",0,1 },
841 { "msp430f425",0,1 },
842 { "msp430f4250",0,0 },
843 { "msp430f425a",0,1 },
844 { "msp430f4260",0,0 },
845 { "msp430f427",0,1 },
846 { "msp430f4270",0,0 },
847 { "msp430f427a",0,1 },
848 { "msp430f435",0,0 },
849 { "msp430f4351",0,0 },
850 { "msp430f436",0,0 },
851 { "msp430f4361",0,0 },
852 { "msp430f437",0,0 },
853 { "msp430f4371",0,0 },
854 { "msp430f438",0,0 },
855 { "msp430f439",0,0 },
856 { "msp430f447",0,1 },
857 { "msp430f448",0,1 },
858 { "msp430f4481",0,1 },
859 { "msp430f449",0,1 },
860 { "msp430f4491",0,1 },
861 { "msp430f4616",1,1 },
862 { "msp430f46161",1,1 },
863 { "msp430f4617",1,1 },
864 { "msp430f46171",1,1 },
865 { "msp430f4618",1,1 },
866 { "msp430f46181",1,1 },
867 { "msp430f4619",1,1 },
868 { "msp430f46191",1,1 },
869 { "msp430f47126",1,4 },
870 { "msp430f47127",1,4 },
871 { "msp430f47163",1,4 },
872 { "msp430f47166",1,4 },
873 { "msp430f47167",1,4 },
874 { "msp430f47173",1,4 },
875 { "msp430f47176",1,4 },
876 { "msp430f47177",1,4 },
877 { "msp430f47183",1,4 },
878 { "msp430f47186",1,4 },
879 { "msp430f47187",1,4 },
880 { "msp430f47193",1,4 },
881 { "msp430f47196",1,4 },
882 { "msp430f47197",1,4 },
883 { "msp430f477",0,0 },
884 { "msp430f478",0,0 },
885 { "msp430f4783",0,4 },
886 { "msp430f4784",0,4 },
887 { "msp430f479",0,0 },
888 { "msp430f4793",0,4 },
889 { "msp430f4794",0,4 },
890 { "msp430f5131",2,8 },
891 { "msp430f5132",2,8 },
892 { "msp430f5151",2,8 },
893 { "msp430f5152",2,8 },
894 { "msp430f5171",2,8 },
895 { "msp430f5172",2,8 },
896 { "msp430f5212",2,8 },
897 { "msp430f5213",2,8 },
898 { "msp430f5214",2,8 },
899 { "msp430f5217",2,8 },
900 { "msp430f5218",2,8 },
901 { "msp430f5219",2,8 },
902 { "msp430f5222",2,8 },
903 { "msp430f5223",2,8 },
904 { "msp430f5224",2,8 },
905 { "msp430f5227",2,8 },
906 { "msp430f5228",2,8 },
907 { "msp430f5229",2,8 },
908 { "msp430f5232",2,8 },
909 { "msp430f5234",2,8 },
910 { "msp430f5237",2,8 },
911 { "msp430f5239",2,8 },
912 { "msp430f5242",2,8 },
913 { "msp430f5244",2,8 },
914 { "msp430f5247",2,8 },
915 { "msp430f5249",2,8 },
916 { "msp430f5252",2,8 },
917 { "msp430f5253",2,8 },
918 { "msp430f5254",2,8 },
919 { "msp430f5255",2,8 },
920 { "msp430f5256",2,8 },
921 { "msp430f5257",2,8 },
922 { "msp430f5258",2,8 },
923 { "msp430f5259",2,8 },
924 { "msp430f5304",2,8 },
925 { "msp430f5308",2,8 },
926 { "msp430f5309",2,8 },
927 { "msp430f5310",2,8 },
928 { "msp430f5324",2,8 },
929 { "msp430f5325",2,8 },
930 { "msp430f5326",2,8 },
931 { "msp430f5327",2,8 },
932 { "msp430f5328",2,8 },
933 { "msp430f5329",2,8 },
934 { "msp430f5333",2,8 },
935 { "msp430f5335",2,8 },
936 { "msp430f5336",2,8 },
937 { "msp430f5338",2,8 },
938 { "msp430f5340",2,8 },
939 { "msp430f5341",2,8 },
940 { "msp430f5342",2,8 },
941 { "msp430f5358",2,8 },
942 { "msp430f5359",2,8 },
943 { "msp430f5418",2,8 },
944 { "msp430f5418a",2,8 },
945 { "msp430f5419",2,8 },
946 { "msp430f5419a",2,8 },
947 { "msp430f5435",2,8 },
948 { "msp430f5435a",2,8 },
949 { "msp430f5436",2,8 },
950 { "msp430f5436a",2,8 },
951 { "msp430f5437",2,8 },
952 { "msp430f5437a",2,8 },
953 { "msp430f5438",2,8 },
954 { "msp430f5438a",2,8 },
955 { "msp430f5500",2,8 },
956 { "msp430f5501",2,8 },
957 { "msp430f5502",2,8 },
958 { "msp430f5503",2,8 },
959 { "msp430f5504",2,8 },
960 { "msp430f5505",2,8 },
961 { "msp430f5506",2,8 },
962 { "msp430f5507",2,8 },
963 { "msp430f5508",2,8 },
964 { "msp430f5509",2,8 },
965 { "msp430f5510",2,8 },
966 { "msp430f5513",2,8 },
967 { "msp430f5514",2,8 },
968 { "msp430f5515",2,8 },
969 { "msp430f5517",2,8 },
970 { "msp430f5519",2,8 },
971 { "msp430f5521",2,8 },
972 { "msp430f5522",2,8 },
973 { "msp430f5524",2,8 },
974 { "msp430f5525",2,8 },
975 { "msp430f5526",2,8 },
976 { "msp430f5527",2,8 },
977 { "msp430f5528",2,8 },
978 { "msp430f5529",2,8 },
979 { "msp430f5630",2,8 },
980 { "msp430f5631",2,8 },
981 { "msp430f5632",2,8 },
982 { "msp430f5633",2,8 },
983 { "msp430f5634",2,8 },
984 { "msp430f5635",2,8 },
985 { "msp430f5636",2,8 },
986 { "msp430f5637",2,8 },
987 { "msp430f5638",2,8 },
988 { "msp430f5658",2,8 },
989 { "msp430f5659",2,8 },
990 { "msp430f5xx_6xxgeneric",2,8 },
991 { "msp430f6433",2,8 },
992 { "msp430f6435",2,8 },
993 { "msp430f6436",2,8 },
994 { "msp430f6438",2,8 },
995 { "msp430f6458",2,8 },
996 { "msp430f6459",2,8 },
997 { "msp430f6630",2,8 },
998 { "msp430f6631",2,8 },
999 { "msp430f6632",2,8 },
1000 { "msp430f6633",2,8 },
1001 { "msp430f6634",2,8 },
1002 { "msp430f6635",2,8 },
1003 { "msp430f6636",2,8 },
1004 { "msp430f6637",2,8 },
1005 { "msp430f6638",2,8 },
1006 { "msp430f6658",2,8 },
1007 { "msp430f6659",2,8 },
1008 { "msp430f6720",2,8 },
1009 { "msp430f6720a",2,8 },
1010 { "msp430f6721",2,8 },
1011 { "msp430f6721a",2,8 },
1012 { "msp430f6723",2,8 },
1013 { "msp430f6723a",2,8 },
1014 { "msp430f6724",2,8 },
1015 { "msp430f6724a",2,8 },
1016 { "msp430f6725",2,8 },
1017 { "msp430f6725a",2,8 },
1018 { "msp430f6726",2,8 },
1019 { "msp430f6726a",2,8 },
1020 { "msp430f6730",2,8 },
1021 { "msp430f6730a",2,8 },
1022 { "msp430f6731",2,8 },
1023 { "msp430f6731a",2,8 },
1024 { "msp430f6733",2,8 },
1025 { "msp430f6733a",2,8 },
1026 { "msp430f6734",2,8 },
1027 { "msp430f6734a",2,8 },
1028 { "msp430f6735",2,8 },
1029 { "msp430f6735a",2,8 },
1030 { "msp430f6736",2,8 },
1031 { "msp430f6736a",2,8 },
1032 { "msp430f6745",2,8 },
1033 { "msp430f67451",2,8 },
1034 { "msp430f67451a",2,8 },
1035 { "msp430f6745a",2,8 },
1036 { "msp430f6746",2,8 },
1037 { "msp430f67461",2,8 },
1038 { "msp430f67461a",2,8 },
1039 { "msp430f6746a",2,8 },
1040 { "msp430f6747",2,8 },
1041 { "msp430f67471",2,8 },
1042 { "msp430f67471a",2,8 },
1043 { "msp430f6747a",2,8 },
1044 { "msp430f6748",2,8 },
1045 { "msp430f67481",2,8 },
1046 { "msp430f67481a",2,8 },
1047 { "msp430f6748a",2,8 },
1048 { "msp430f6749",2,8 },
1049 { "msp430f67491",2,8 },
1050 { "msp430f67491a",2,8 },
1051 { "msp430f6749a",2,8 },
1052 { "msp430f67621",2,8 },
1053 { "msp430f67621a",2,8 },
1054 { "msp430f67641",2,8 },
1055 { "msp430f67641a",2,8 },
1056 { "msp430f6765",2,8 },
1057 { "msp430f67651",2,8 },
1058 { "msp430f67651a",2,8 },
1059 { "msp430f6765a",2,8 },
1060 { "msp430f6766",2,8 },
1061 { "msp430f67661",2,8 },
1062 { "msp430f67661a",2,8 },
1063 { "msp430f6766a",2,8 },
1064 { "msp430f6767",2,8 },
1065 { "msp430f67671",2,8 },
1066 { "msp430f67671a",2,8 },
1067 { "msp430f6767a",2,8 },
1068 { "msp430f6768",2,8 },
1069 { "msp430f67681",2,8 },
1070 { "msp430f67681a",2,8 },
1071 { "msp430f6768a",2,8 },
1072 { "msp430f6769",2,8 },
1073 { "msp430f67691",2,8 },
1074 { "msp430f67691a",2,8 },
1075 { "msp430f6769a",2,8 },
1076 { "msp430f6775",2,8 },
1077 { "msp430f67751",2,8 },
1078 { "msp430f67751a",2,8 },
1079 { "msp430f6775a",2,8 },
1080 { "msp430f6776",2,8 },
1081 { "msp430f67761",2,8 },
1082 { "msp430f67761a",2,8 },
1083 { "msp430f6776a",2,8 },
1084 { "msp430f6777",2,8 },
1085 { "msp430f67771",2,8 },
1086 { "msp430f67771a",2,8 },
1087 { "msp430f6777a",2,8 },
1088 { "msp430f6778",2,8 },
1089 { "msp430f67781",2,8 },
1090 { "msp430f67781a",2,8 },
1091 { "msp430f6778a",2,8 },
1092 { "msp430f6779",2,8 },
1093 { "msp430f67791",2,8 },
1094 { "msp430f67791a",2,8 },
1095 { "msp430f6779a",2,8 },
1096 { "msp430fe423",0,0 },
1097 { "msp430fe4232",0,0 },
1098 { "msp430fe423a",0,0 },
1099 { "msp430fe4242",0,0 },
1100 { "msp430fe425",0,0 },
1101 { "msp430fe4252",0,0 },
1102 { "msp430fe425a",0,0 },
1103 { "msp430fe427",0,0 },
1104 { "msp430fe4272",0,0 },
1105 { "msp430fe427a",0,0 },
1106 { "msp430fg4250",0,0 },
1107 { "msp430fg4260",0,0 },
1108 { "msp430fg4270",0,0 },
1109 { "msp430fg437",0,0 },
1110 { "msp430fg438",0,0 },
1111 { "msp430fg439",0,0 },
1112 { "msp430fg4616",1,1 },
1113 { "msp430fg4617",1,1 },
1114 { "msp430fg4618",1,1 },
1115 { "msp430fg4619",1,1 },
1116 { "msp430fg477",0,0 },
1117 { "msp430fg478",0,0 },
1118 { "msp430fg479",0,0 },
1119 { "msp430fg6425",2,8 },
1120 { "msp430fg6426",2,8 },
1121 { "msp430fg6625",2,8 },
1122 { "msp430fg6626",2,8 },
1123 { "msp430fr2032",2,0 },
1124 { "msp430fr2033",2,0 },
1125 { "msp430fr2433",2,8 },
1126 { "msp430fr2xx_4xxgeneric",2,8 },
1127 { "msp430fr4131",2,0 },
1128 { "msp430fr4132",2,0 },
1129 { "msp430fr4133",2,0 },
1130 { "msp430fr5720",2,8 },
1131 { "msp430fr5721",2,8 },
1132 { "msp430fr5722",2,8 },
1133 { "msp430fr5723",2,8 },
1134 { "msp430fr5724",2,8 },
1135 { "msp430fr5725",2,8 },
1136 { "msp430fr5726",2,8 },
1137 { "msp430fr5727",2,8 },
1138 { "msp430fr5728",2,8 },
1139 { "msp430fr5729",2,8 },
1140 { "msp430fr5730",2,8 },
1141 { "msp430fr5731",2,8 },
1142 { "msp430fr5732",2,8 },
1143 { "msp430fr5733",2,8 },
1144 { "msp430fr5734",2,8 },
1145 { "msp430fr5735",2,8 },
1146 { "msp430fr5736",2,8 },
1147 { "msp430fr5737",2,8 },
1148 { "msp430fr5738",2,8 },
1149 { "msp430fr5739",2,8 },
1150 { "msp430fr57xxgeneric",2,8 },
1151 { "msp430fr5847",2,8 },
1152 { "msp430fr58471",2,8 },
1153 { "msp430fr5848",2,8 },
1154 { "msp430fr5849",2,8 },
1155 { "msp430fr5857",2,8 },
1156 { "msp430fr5858",2,8 },
1157 { "msp430fr5859",2,8 },
1158 { "msp430fr5867",2,8 },
1159 { "msp430fr58671",2,8 },
1160 { "msp430fr5868",2,8 },
1161 { "msp430fr5869",2,8 },
1162 { "msp430fr5870",2,8 },
1163 { "msp430fr5872",2,8 },
1164 { "msp430fr58721",2,8 },
1165 { "msp430fr5887",2,8 },
1166 { "msp430fr5888",2,8 },
1167 { "msp430fr5889",2,8 },
1168 { "msp430fr58891",2,8 },
1169 { "msp430fr5922",2,8 },
1170 { "msp430fr59221",2,8 },
1171 { "msp430fr5947",2,8 },
1172 { "msp430fr59471",2,8 },
1173 { "msp430fr5948",2,8 },
1174 { "msp430fr5949",2,8 },
1175 { "msp430fr5957",2,8 },
1176 { "msp430fr5958",2,8 },
1177 { "msp430fr5959",2,8 },
1178 { "msp430fr5967",2,8 },
1179 { "msp430fr5968",2,8 },
1180 { "msp430fr5969",2,8 },
1181 { "msp430fr59691",2,8 },
1182 { "msp430fr5970",2,8 },
1183 { "msp430fr5972",2,8 },
1184 { "msp430fr59721",2,8 },
1185 { "msp430fr5986",2,8 },
1186 { "msp430fr5987",2,8 },
1187 { "msp430fr5988",2,8 },
1188 { "msp430fr5989",2,8 },
1189 { "msp430fr59891",2,8 },
1190 { "msp430fr5xx_6xxgeneric",2,8 },
1191 { "msp430fr6820",2,8 },
1192 { "msp430fr6822",2,8 },
1193 { "msp430fr68221",2,8 },
1194 { "msp430fr6870",2,8 },
1195 { "msp430fr6872",2,8 },
1196 { "msp430fr68721",2,8 },
1197 { "msp430fr6877",2,8 },
1198 { "msp430fr6879",2,8 },
1199 { "msp430fr68791",2,8 },
1200 { "msp430fr6887",2,8 },
1201 { "msp430fr6888",2,8 },
1202 { "msp430fr6889",2,8 },
1203 { "msp430fr68891",2,8 },
1204 { "msp430fr6920",2,8 },
1205 { "msp430fr6922",2,8 },
1206 { "msp430fr69221",2,8 },
1207 { "msp430fr6927",2,8 },
1208 { "msp430fr69271",2,8 },
1209 { "msp430fr6928",2,8 },
1210 { "msp430fr6970",2,8 },
1211 { "msp430fr6972",2,8 },
1212 { "msp430fr69721",2,8 },
1213 { "msp430fr6977",2,8 },
1214 { "msp430fr6979",2,8 },
1215 { "msp430fr69791",2,8 },
1216 { "msp430fr6987",2,8 },
1217 { "msp430fr6988",2,8 },
1218 { "msp430fr6989",2,8 },
1219 { "msp430fr69891",2,8 },
1220 { "msp430fw423",0,0 },
1221 { "msp430fw425",0,0 },
1222 { "msp430fw427",0,0 },
1223 { "msp430fw428",0,0 },
1224 { "msp430fw429",0,0 },
1225 { "msp430g2001",0,0 },
1226 { "msp430g2101",0,0 },
1227 { "msp430g2102",0,0 },
1228 { "msp430g2111",0,0 },
1229 { "msp430g2112",0,0 },
1230 { "msp430g2113",0,0 },
1231 { "msp430g2121",0,0 },
1232 { "msp430g2131",0,0 },
1233 { "msp430g2132",0,0 },
1234 { "msp430g2152",0,0 },
1235 { "msp430g2153",0,0 },
1236 { "msp430g2201",0,0 },
1237 { "msp430g2202",0,0 },
1238 { "msp430g2203",0,0 },
1239 { "msp430g2210",0,0 },
1240 { "msp430g2211",0,0 },
1241 { "msp430g2212",0,0 },
1242 { "msp430g2213",0,0 },
1243 { "msp430g2221",0,0 },
1244 { "msp430g2230",0,0 },
1245 { "msp430g2231",0,0 },
1246 { "msp430g2232",0,0 },
1247 { "msp430g2233",0,0 },
1248 { "msp430g2252",0,0 },
1249 { "msp430g2253",0,0 },
1250 { "msp430g2302",0,0 },
1251 { "msp430g2303",0,0 },
1252 { "msp430g2312",0,0 },
1253 { "msp430g2313",0,0 },
1254 { "msp430g2332",0,0 },
1255 { "msp430g2333",0,0 },
1256 { "msp430g2352",0,0 },
1257 { "msp430g2353",0,0 },
1258 { "msp430g2402",0,0 },
1259 { "msp430g2403",0,0 },
1260 { "msp430g2412",0,0 },
1261 { "msp430g2413",0,0 },
1262 { "msp430g2432",0,0 },
1263 { "msp430g2433",0,0 },
1264 { "msp430g2444",0,0 },
1265 { "msp430g2452",0,0 },
1266 { "msp430g2453",0,0 },
1267 { "msp430g2513",0,0 },
1268 { "msp430g2533",0,0 },
1269 { "msp430g2544",0,0 },
1270 { "msp430g2553",0,0 },
1271 { "msp430g2744",0,0 },
1272 { "msp430g2755",0,0 },
1273 { "msp430g2855",0,0 },
1274 { "msp430g2955",0,0 },
1275 { "msp430i2020",0,2 },
1276 { "msp430i2021",0,2 },
1277 { "msp430i2030",0,2 },
1278 { "msp430i2031",0,2 },
1279 { "msp430i2040",0,2 },
1280 { "msp430i2041",0,2 },
1281 { "msp430i2xxgeneric",0,2 },
1282 { "msp430l092",0,0 },
1283 { "msp430p112",0,0 },
1284 { "msp430p313",0,0 },
1285 { "msp430p315",0,0 },
1286 { "msp430p315s",0,0 },
1287 { "msp430p325",0,0 },
1288 { "msp430p337",0,1 },
1289 { "msp430sl5438a",2,8 },
1290 { "msp430tch5e",0,0 },
1291 { "msp430xgeneric",2,8 },
1292 { "rf430f5144",2,8 },
1293 { "rf430f5155",2,8 },
1294 { "rf430f5175",2,8 },
1295 { "rf430frl152h",0,0 },
1296 { "rf430frl152h_rom",0,0 },
1297 { "rf430frl153h",0,0 },
1298 { "rf430frl153h_rom",0,0 },
1299 { "rf430frl154h",0,0 },
1300 { "rf430frl154h_rom",0,0 }
1304 md_parse_option (int c
, char * arg
)
1310 as_fatal (_("MCU option requires a name\n"));
1312 if (strcasecmp ("msp430", arg
) == 0)
1313 selected_isa
= MSP_ISA_430
;
1314 else if (strcasecmp ("msp430xv2", arg
) == 0)
1315 selected_isa
= MSP_ISA_430Xv2
;
1316 else if (strcasecmp ("msp430x", arg
) == 0)
1317 selected_isa
= MSP_ISA_430X
;
1322 for (i
= ARRAY_SIZE (msp430_mcu_data
); i
--;)
1323 if (strcasecmp (msp430_mcu_data
[i
].name
, arg
) == 0)
1325 switch (msp430_mcu_data
[i
].revision
)
1327 case 0: selected_isa
= MSP_ISA_430
; break;
1328 case 1: selected_isa
= MSP_ISA_430X
; break;
1329 case 2: selected_isa
= MSP_ISA_430Xv2
; break;
1334 /* It is not an error if we do not match the MCU name. */
1338 if (strcmp (arg
, "430") == 0
1339 || strcasecmp (arg
, "msp430") == 0)
1340 selected_isa
= MSP_ISA_430
;
1341 else if (strcasecmp (arg
, "430x") == 0
1342 || strcasecmp (arg
, "msp430x") == 0)
1343 selected_isa
= MSP_ISA_430X
;
1344 else if (strcasecmp (arg
, "430xv2") == 0
1345 || strcasecmp (arg
, "msp430xv2") == 0)
1346 selected_isa
= MSP_ISA_430Xv2
;
1348 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1352 msp430_enable_relax
= 1;
1355 case OPTION_POLYMORPHS
:
1356 msp430_enable_polys
= 1;
1363 case OPTION_NO_INTR_NOPS
:
1364 gen_interrupt_nops
= FALSE
;
1366 case OPTION_INTR_NOPS
:
1367 gen_interrupt_nops
= TRUE
;
1370 case OPTION_WARN_INTR_NOPS
:
1371 warn_interrupt_nops
= TRUE
;
1373 case OPTION_NO_WARN_INTR_NOPS
:
1374 warn_interrupt_nops
= FALSE
;
1377 case OPTION_MOVE_DATA
:
1385 /* The intention here is to have the mere presence of these sections
1386 cause the object to have a reference to a well-known symbol. This
1387 reference pulls in the bits of the runtime (crt0) that initialize
1388 these sections. Thus, for example, the startup code to call
1389 memset() to initialize .bss will only be linked in when there is a
1390 non-empty .bss section. Otherwise, the call would exist but have a
1391 zero length parameter, which is a waste of memory and cycles.
1393 The code which initializes these sections should have a global
1394 label for these symbols, and should be marked with KEEP() in the
1398 msp430_make_init_symbols (const char * name
)
1400 if (strncmp (name
, ".bss", 4) == 0
1401 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1402 (void) symbol_find_or_make ("__crt0_init_bss");
1404 if (strncmp (name
, ".data", 5) == 0
1405 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0)
1406 (void) symbol_find_or_make ("__crt0_movedata");
1408 /* Note - data assigned to the .either.data section may end up being
1409 placed in the .upper.data section if the .lower.data section is
1410 full. Hence the need to define the crt0 symbol. */
1411 if (strncmp (name
, ".either.data", 12) == 0
1412 || strncmp (name
, ".upper.data", 11) == 0)
1413 (void) symbol_find_or_make ("__crt0_move_highdata");
1415 /* See note about .either.data above. */
1416 if (strncmp (name
, ".upper.bss", 10) == 0
1417 || strncmp (name
, ".either.bss", 11) == 0)
1418 (void) symbol_find_or_make ("__crt0_init_highbss");
1422 msp430_section (int arg
)
1424 char * saved_ilp
= input_line_pointer
;
1425 char * name
= obj_elf_section_name ();
1427 msp430_make_init_symbols (name
);
1429 input_line_pointer
= saved_ilp
;
1430 obj_elf_section (arg
);
1434 msp430_frob_section (asection
*sec
)
1436 const char *name
= sec
->name
;
1441 msp430_make_init_symbols (name
);
1445 msp430_lcomm (int ignore ATTRIBUTE_UNUSED
)
1447 symbolS
*symbolP
= s_comm_internal (0, s_lcomm_internal
);
1450 symbol_get_bfdsym (symbolP
)->flags
|= BSF_OBJECT
;
1451 (void) symbol_find_or_make ("__crt0_init_bss");
1455 msp430_comm (int needs_align
)
1457 s_comm_internal (needs_align
, elf_common_parse
);
1458 (void) symbol_find_or_make ("__crt0_init_bss");
1462 msp430_refsym (int arg ATTRIBUTE_UNUSED
)
1464 char sym_name
[1024];
1465 input_line_pointer
= extract_word (input_line_pointer
, sym_name
, 1024);
1467 (void) symbol_find_or_make (sym_name
);
1470 const pseudo_typeS md_pseudo_table
[] =
1472 {"arch", msp430_set_arch
, OPTION_MMCU
},
1473 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1474 {"profiler", msp430_profiler
, 0},
1475 {"section", msp430_section
, 0},
1476 {"section.s", msp430_section
, 0},
1477 {"sect", msp430_section
, 0},
1478 {"sect.s", msp430_section
, 0},
1479 {"pushsection", msp430_section
, 1},
1480 {"refsym", msp430_refsym
, 0},
1481 {"comm", msp430_comm
, 0},
1482 {"lcomm", msp430_lcomm
, 0},
1486 const char *md_shortopts
= "mm:,mP,mQ,ml,mN,mn,my,mY";
1488 struct option md_longopts
[] =
1490 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1491 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1492 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1493 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1494 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1495 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1496 {"mn", no_argument
, NULL
, OPTION_INTR_NOPS
},
1497 {"mY", no_argument
, NULL
, OPTION_NO_WARN_INTR_NOPS
},
1498 {"my", no_argument
, NULL
, OPTION_WARN_INTR_NOPS
},
1499 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1500 {NULL
, no_argument
, NULL
, 0}
1503 size_t md_longopts_size
= sizeof (md_longopts
);
1506 md_show_usage (FILE * stream
)
1509 _("MSP430 options:\n"
1510 " -mmcu=<msp430-name> - select microcontroller type\n"
1511 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1513 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1514 " -mP - enable polymorph instructions\n"));
1516 _(" -ml - enable large code model\n"));
1518 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1520 _(" -mn - insert a NOP after changing interrupts\n"));
1522 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1524 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1526 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1530 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1536 extract_cmd (char * from
, char * to
, int limit
)
1540 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1542 *(to
+ size
) = *from
;
1553 md_atof (int type
, char * litP
, int * sizeP
)
1555 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1561 struct msp430_opcode_s
* opcode
;
1562 msp430_hash
= hash_new ();
1564 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1565 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1567 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1568 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1571 /* Returns the register number equivalent to the string T.
1572 Returns -1 if there is no such register.
1573 Skips a leading 'r' or 'R' character if there is one.
1574 Handles the register aliases PC and SP. */
1577 check_reg (char * t
)
1584 if (*t
== 'r' || *t
== 'R')
1587 if (strncasecmp (t
, "pc", 2) == 0)
1590 if (strncasecmp (t
, "sp", 2) == 0)
1593 if (strncasecmp (t
, "sr", 2) == 0)
1601 if (val
< 1 || val
> 15)
1608 msp430_srcoperand (struct msp430_operand_s
* op
,
1611 bfd_boolean
* imm_op
,
1612 bfd_boolean allow_20bit_values
,
1613 bfd_boolean constants_allowed
)
1617 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1624 /* Check if there is:
1625 llo(x) - least significant 16 bits, x &= 0xffff
1626 lhi(x) - x = (x >> 16) & 0xffff,
1627 hlo(x) - x = (x >> 32) & 0xffff,
1628 hhi(x) - x = (x >> 48) & 0xffff
1629 The value _MUST_ be constant expression: #hlo(1231231231). */
1633 if (strncasecmp (h
, "#llo(", 5) == 0)
1638 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1643 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1648 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1653 else if (strncasecmp (h
, "#lo(", 4) == 0)
1658 else if (strncasecmp (h
, "#hi(", 4) == 0)
1664 op
->reg
= 0; /* Reg PC. */
1666 op
->ol
= 1; /* Immediate will follow an instruction. */
1667 __tl
= h
+ 1 + rval
;
1669 op
->vshift
= vshift
;
1671 parse_exp (__tl
, &(op
->exp
));
1672 if (op
->exp
.X_op
== O_constant
)
1674 int x
= op
->exp
.X_add_number
;
1679 op
->exp
.X_add_number
= x
;
1681 else if (vshift
== 1)
1683 x
= (x
>> 16) & 0xffff;
1684 op
->exp
.X_add_number
= x
;
1687 else if (vshift
> 1)
1690 op
->exp
.X_add_number
= -1;
1692 op
->exp
.X_add_number
= 0; /* Nothing left. */
1693 x
= op
->exp
.X_add_number
;
1697 if (allow_20bit_values
)
1699 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< -524288)
1701 as_bad (_("value 0x%x out of extended range."), x
);
1705 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1707 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1711 /* Now check constants. */
1712 /* Substitute register mode with a constant generator if applicable. */
1714 if (!allow_20bit_values
)
1715 x
= (short) x
; /* Extend sign. */
1717 if (! constants_allowed
)
1749 #ifdef PUSH_1X_WORKAROUND
1752 /* Remove warning as confusing.
1753 as_warn (_("Hardware push bug workaround")); */
1766 #ifdef PUSH_1X_WORKAROUND
1769 /* Remove warning as confusing.
1770 as_warn (_("Hardware push bug workaround")); */
1782 else if (op
->exp
.X_op
== O_symbol
)
1785 as_bad (_("error: unsupported #foo() directive used on symbol"));
1788 else if (op
->exp
.X_op
== O_big
)
1794 op
->exp
.X_op
= O_constant
;
1795 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1796 x
= op
->exp
.X_add_number
;
1802 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1850 /* Redundant (yet) check. */
1851 else if (op
->exp
.X_op
== O_register
)
1853 (_("Registers cannot be used within immediate expression [%s]"), l
);
1855 as_bad (_("unknown operand %s"), l
);
1860 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1865 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1866 op
->am
= 1; /* mode As == 01 bin. */
1867 op
->ol
= 1; /* Immediate value followed by instruction. */
1869 parse_exp (__tl
, &(op
->exp
));
1872 if (op
->exp
.X_op
== O_constant
)
1874 int x
= op
->exp
.X_add_number
;
1876 if (allow_20bit_values
)
1878 if (x
> 0xfffff || x
< -(0x7ffff))
1880 as_bad (_("value 0x%x out of extended range."), x
);
1884 else if (x
> 65535 || x
< -32768)
1886 as_bad (_("value out of range: 0x%x"), x
);
1890 else if (op
->exp
.X_op
== O_symbol
)
1894 /* Redundant (yet) check. */
1895 if (op
->exp
.X_op
== O_register
)
1897 (_("Registers cannot be used within absolute expression [%s]"), l
);
1899 as_bad (_("unknown expression in operand %s"), l
);
1905 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1909 char *m
= strchr (l
, '+');
1913 as_bad (_("unknown addressing mode %s"), l
);
1919 if ((op
->reg
= check_reg (t
)) == -1)
1921 as_bad (_("Bad register name %s"), t
);
1929 /* PC cannot be used in indirect addressing. */
1930 if (target_is_430xv2 () && op
->reg
== 0)
1932 as_bad (_("cannot use indirect addressing with the PC"));
1939 /* Check if register indexed X(Rn). */
1942 char *h
= strrchr (l
, '(');
1943 char *m
= strrchr (l
, ')');
1952 as_bad (_("')' required"));
1960 /* Extract a register. */
1961 if ((op
->reg
= check_reg (t
+ 1)) == -1)
1964 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1971 as_bad (_("r2 should not be used in indexed addressing mode"));
1975 /* Extract constant. */
1980 parse_exp (__tl
, &(op
->exp
));
1981 if (op
->exp
.X_op
== O_constant
)
1983 int x
= op
->exp
.X_add_number
;
1985 if (allow_20bit_values
)
1987 if (x
> 0xfffff || x
< - (0x7ffff))
1989 as_bad (_("value 0x%x out of extended range."), x
);
1993 else if (x
> 65535 || x
< -32768)
1995 as_bad (_("value out of range: 0x%x"), x
);
2007 else if (op
->exp
.X_op
== O_symbol
)
2011 /* Redundant (yet) check. */
2012 if (op
->exp
.X_op
== O_register
)
2014 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
2016 as_bad (_("unknown expression in operand %s"), l
);
2024 /* Possibly register mode 'mov r1,r2'. */
2025 if ((op
->reg
= check_reg (l
)) != -1)
2033 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2037 op
->reg
= 0; /* PC relative... be careful. */
2038 /* An expression starting with a minus sign is a constant, not an address. */
2039 op
->am
= (*l
== '-' ? 3 : 1);
2043 parse_exp (__tl
, &(op
->exp
));
2049 as_bad (_("unknown addressing mode for operand %s"), l
);
2055 msp430_dstoperand (struct msp430_operand_s
* op
,
2058 bfd_boolean allow_20bit_values
,
2059 bfd_boolean constants_allowed
)
2062 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
2077 parse_exp (__tl
, &(op
->exp
));
2079 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
2081 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2091 ("this addressing mode is not applicable for destination operand"));
2097 /* Attempt to encode a MOVA instruction with the given operands.
2098 Returns the length of the encoded instruction if successful
2099 or 0 upon failure. If the encoding fails, an error message
2100 will be returned if a pointer is provided. */
2103 try_encode_mova (bfd_boolean imm_op
,
2105 struct msp430_operand_s
* op1
,
2106 struct msp430_operand_s
* op2
,
2107 const char ** error_message_return
)
2113 /* Only a restricted subset of the normal MSP430 addressing modes
2114 are supported here, so check for the ones that are allowed. */
2117 if (op1
->mode
== OP_EXP
)
2119 if (op2
->mode
!= OP_REG
)
2121 if (error_message_return
!= NULL
)
2122 * error_message_return
= _("expected register as second argument of %s");
2128 /* MOVA #imm20, Rdst. */
2129 bin
|= 0x80 | op2
->reg
;
2130 frag
= frag_more (4);
2131 where
= frag
- frag_now
->fr_literal
;
2132 if (op1
->exp
.X_op
== O_constant
)
2134 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2135 bfd_putl16 ((bfd_vma
) bin
, frag
);
2136 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2140 bfd_putl16 ((bfd_vma
) bin
, frag
);
2141 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2142 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2143 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2148 else if (op1
->am
== 1)
2150 /* MOVA z16(Rsrc), Rdst. */
2151 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
2152 frag
= frag_more (4);
2153 where
= frag
- frag_now
->fr_literal
;
2154 bfd_putl16 ((bfd_vma
) bin
, frag
);
2155 if (op1
->exp
.X_op
== O_constant
)
2157 if (op1
->exp
.X_add_number
> 0xffff
2158 || op1
->exp
.X_add_number
< -(0x7fff))
2160 if (error_message_return
!= NULL
)
2161 * error_message_return
= _("index value too big for %s");
2164 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2168 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2169 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
2171 BFD_RELOC_MSP430X_PCR16
:
2172 BFD_RELOC_MSP430X_ABS16
);
2177 if (error_message_return
!= NULL
)
2178 * error_message_return
= _("unexpected addressing mode for %s");
2181 else if (op1
->am
== 0)
2183 /* MOVA Rsrc, ... */
2184 if (op2
->mode
== OP_REG
)
2186 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
2187 frag
= frag_more (2);
2188 where
= frag
- frag_now
->fr_literal
;
2189 bfd_putl16 ((bfd_vma
) bin
, frag
);
2192 else if (op2
->am
== 1)
2196 /* MOVA Rsrc, &abs20. */
2197 bin
|= 0x60 | (op1
->reg
<< 8);
2198 frag
= frag_more (4);
2199 where
= frag
- frag_now
->fr_literal
;
2200 if (op2
->exp
.X_op
== O_constant
)
2202 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
2203 bfd_putl16 ((bfd_vma
) bin
, frag
);
2204 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2208 bfd_putl16 ((bfd_vma
) bin
, frag
);
2209 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2210 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
2211 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2216 /* MOVA Rsrc, z16(Rdst). */
2217 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
2218 frag
= frag_more (4);
2219 where
= frag
- frag_now
->fr_literal
;
2220 bfd_putl16 ((bfd_vma
) bin
, frag
);
2221 if (op2
->exp
.X_op
== O_constant
)
2223 if (op2
->exp
.X_add_number
> 0xffff
2224 || op2
->exp
.X_add_number
< -(0x7fff))
2226 if (error_message_return
!= NULL
)
2227 * error_message_return
= _("index value too big for %s");
2230 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
2234 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2235 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
2237 BFD_RELOC_MSP430X_PCR16
:
2238 BFD_RELOC_MSP430X_ABS16
);
2243 if (error_message_return
!= NULL
)
2244 * error_message_return
= _("unexpected addressing mode for %s");
2249 /* imm_op == FALSE. */
2251 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2253 /* MOVA &abs20, Rdst. */
2254 if (op2
->mode
!= OP_REG
)
2256 if (error_message_return
!= NULL
)
2257 * error_message_return
= _("expected register as second argument of %s");
2261 if (op2
->reg
== 2 || op2
->reg
== 3)
2263 if (error_message_return
!= NULL
)
2264 * error_message_return
= _("constant generator destination register found in %s");
2268 bin
|= 0x20 | op2
->reg
;
2269 frag
= frag_more (4);
2270 where
= frag
- frag_now
->fr_literal
;
2271 if (op1
->exp
.X_op
== O_constant
)
2273 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2274 bfd_putl16 ((bfd_vma
) bin
, frag
);
2275 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2279 bfd_putl16 ((bfd_vma
) bin
, frag
);
2280 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2281 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2282 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2286 else if (op1
->mode
== OP_REG
)
2290 /* MOVA @Rsrc+, Rdst. */
2291 if (op2
->mode
!= OP_REG
)
2293 if (error_message_return
!= NULL
)
2294 * error_message_return
= _("expected register as second argument of %s");
2298 if (op2
->reg
== 2 || op2
->reg
== 3)
2300 if (error_message_return
!= NULL
)
2301 * error_message_return
= _("constant generator destination register found in %s");
2305 if (op1
->reg
== 2 || op1
->reg
== 3)
2307 if (error_message_return
!= NULL
)
2308 * error_message_return
= _("constant generator source register found in %s");
2312 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2313 frag
= frag_more (2);
2314 where
= frag
- frag_now
->fr_literal
;
2315 bfd_putl16 ((bfd_vma
) bin
, frag
);
2318 else if (op1
->am
== 2)
2320 /* MOVA @Rsrc,Rdst */
2321 if (op2
->mode
!= OP_REG
)
2323 if (error_message_return
!= NULL
)
2324 * error_message_return
= _("expected register as second argument of %s");
2328 if (op2
->reg
== 2 || op2
->reg
== 3)
2330 if (error_message_return
!= NULL
)
2331 * error_message_return
= _("constant generator destination register found in %s");
2335 if (op1
->reg
== 2 || op1
->reg
== 3)
2337 if (error_message_return
!= NULL
)
2338 * error_message_return
= _("constant generator source register found in %s");
2342 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2343 frag
= frag_more (2);
2344 where
= frag
- frag_now
->fr_literal
;
2345 bfd_putl16 ((bfd_vma
) bin
, frag
);
2350 if (error_message_return
!= NULL
)
2351 * error_message_return
= _("unexpected addressing mode for %s");
2356 static bfd_boolean check_for_nop
= FALSE
;
2358 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2360 /* Parse instruction operands.
2361 Return binary opcode. */
2364 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2366 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2367 int insn_length
= 0;
2368 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2371 struct msp430_operand_s op1
, op2
;
2373 static short ZEROS
= 0;
2374 bfd_boolean byte_op
, imm_op
;
2377 int extended
= 0x1800;
2378 bfd_boolean extended_op
= FALSE
;
2379 bfd_boolean addr_op
;
2380 const char * error_message
;
2381 static signed int repeat_count
= 0;
2382 bfd_boolean fix_emitted
;
2383 bfd_boolean nop_check_needed
= FALSE
;
2385 /* Opcode is the one from opcodes table
2386 line contains something like
2395 bfd_boolean check
= FALSE
;
2398 switch (TOLOWER (* line
))
2401 /* Byte operation. */
2402 bin
|= BYTE_OPERATION
;
2408 /* "Address" ops work on 20-bit values. */
2410 bin
|= BYTE_OPERATION
;
2415 /* Word operation - this is the default. */
2423 as_warn (_("no size modifier after period, .w assumed"));
2427 as_bad (_("unrecognised instruction size modifier .%c"),
2439 if (*line
&& ! ISSPACE (*line
))
2441 as_bad (_("junk found after instruction: %s.%s"),
2442 opcode
->name
, line
);
2446 /* Catch the case where the programmer has used a ".a" size modifier on an
2447 instruction that does not support it. Look for an alternative extended
2448 instruction that has the same name without the period. Eg: "add.a"
2449 becomes "adda". Although this not an officially supported way of
2450 specifing instruction aliases other MSP430 assemblers allow it. So we
2451 support it for compatibility purposes. */
2452 if (addr_op
&& opcode
->fmt
>= 0)
2454 char * old_name
= opcode
->name
;
2457 sprintf (real_name
, "%sa", old_name
);
2458 opcode
= hash_find (msp430_hash
, real_name
);
2461 as_bad (_("instruction %s.a does not exist"), old_name
);
2464 #if 0 /* Enable for debugging. */
2465 as_warn ("treating %s.a as %s", old_name
, real_name
);
2468 bin
= opcode
->bin_opcode
;
2471 if (opcode
->fmt
!= -1
2472 && opcode
->insn_opnumb
2473 && (!*line
|| *line
== '\n'))
2475 as_bad (_("instruction %s requires %d operand(s)"),
2476 opcode
->name
, opcode
->insn_opnumb
);
2480 memset (l1
, 0, sizeof (l1
));
2481 memset (l2
, 0, sizeof (l2
));
2482 memset (&op1
, 0, sizeof (op1
));
2483 memset (&op2
, 0, sizeof (op2
));
2487 if ((fmt
= opcode
->fmt
) < 0)
2489 if (! target_is_430x ())
2491 as_bad (_("instruction %s requires MSP430X mcu"),
2502 /* If requested set the extended instruction repeat count. */
2505 if (repeat_count
> 0)
2506 extended
|= (repeat_count
- 1);
2508 extended
|= (1 << 7) | (- repeat_count
);
2511 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2516 if (check_for_nop
&& is_opcode ("nop"))
2517 check_for_nop
= FALSE
;
2521 case 0: /* Emulated. */
2522 switch (opcode
->insn_opnumb
)
2525 if (is_opcode ("eint") || is_opcode ("dint"))
2529 if (warn_interrupt_nops
)
2531 if (gen_interrupt_nops
)
2532 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2534 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2537 if (gen_interrupt_nops
)
2539 /* Emit a NOP between interrupt enable/disable.
2540 See 1.3.4.1 of the MSP430x5xx User Guide. */
2542 frag
= frag_more (2);
2543 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2547 nop_check_needed
= TRUE
;
2550 /* Set/clear bits instructions. */
2554 extended
|= BYTE_OPERATION
;
2556 /* Emit the extension word. */
2558 frag
= frag_more (2);
2559 bfd_putl16 (extended
, frag
);
2563 frag
= frag_more (2);
2564 bfd_putl16 ((bfd_vma
) bin
, frag
);
2565 dwarf2_emit_insn (insn_length
);
2569 /* Something which works with destination operand. */
2570 line
= extract_operand (line
, l1
, sizeof (l1
));
2571 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2575 bin
|= (op1
.reg
| (op1
.am
<< 7));
2577 if (is_opcode ("clr") && bin
== 0x4302 /* CLR R2*/)
2581 if (warn_interrupt_nops
)
2583 if (gen_interrupt_nops
)
2584 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2586 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2589 if (gen_interrupt_nops
)
2591 /* Emit a NOP between interrupt enable/disable.
2592 See 1.3.4.1 of the MSP430x5xx User Guide. */
2594 frag
= frag_more (2);
2595 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2599 nop_check_needed
= TRUE
;
2602 /* Compute the entire instruction length, in bytes. */
2603 op_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2604 insn_length
+= op_length
;
2605 frag
= frag_more (op_length
);
2606 where
= frag
- frag_now
->fr_literal
;
2611 extended
|= BYTE_OPERATION
;
2613 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2615 as_bad (_("repeat instruction used with non-register mode instruction"));
2619 if (op1
.mode
== OP_EXP
)
2621 if (op1
.exp
.X_op
== O_constant
)
2622 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2624 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2625 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2626 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2628 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2629 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2632 /* Emit the extension word. */
2633 bfd_putl16 (extended
, frag
);
2638 bfd_putl16 ((bfd_vma
) bin
, frag
);
2642 if (op1
.mode
== OP_EXP
)
2644 if (op1
.exp
.X_op
== O_constant
)
2646 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2650 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2655 fix_new_exp (frag_now
, where
, 2,
2656 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2658 fix_new_exp (frag_now
, where
, 2,
2659 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2664 dwarf2_emit_insn (insn_length
);
2668 /* Shift instruction. */
2669 line
= extract_operand (line
, l1
, sizeof (l1
));
2670 strncpy (l2
, l1
, sizeof (l2
));
2671 l2
[sizeof (l2
) - 1] = '\0';
2672 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2673 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2676 break; /* An error occurred. All warnings were done before. */
2678 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2679 frag
= frag_more (insn_length
);
2680 where
= frag
- frag_now
->fr_literal
;
2682 if (target_is_430xv2 ()
2683 && op1
.mode
== OP_REG
2685 && (is_opcode ("rlax")
2686 || is_opcode ("rlcx")
2687 || is_opcode ("rla")
2688 || is_opcode ("rlc")))
2690 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2697 extended
|= BYTE_OPERATION
;
2699 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2701 as_bad (_("repeat instruction used with non-register mode instruction"));
2705 if (op1
.mode
== OP_EXP
)
2707 if (op1
.exp
.X_op
== O_constant
)
2708 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2710 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2711 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2712 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2714 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2715 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2718 if (op2
.mode
== OP_EXP
)
2720 if (op2
.exp
.X_op
== O_constant
)
2721 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2723 else if (op1
.mode
== OP_EXP
)
2724 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2725 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2726 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2728 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2729 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2730 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2733 /* Emit the extension word. */
2734 bfd_putl16 (extended
, frag
);
2739 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2740 bfd_putl16 ((bfd_vma
) bin
, frag
);
2744 if (op1
.mode
== OP_EXP
)
2746 if (op1
.exp
.X_op
== O_constant
)
2748 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2752 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2756 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
2757 fix_new_exp (frag_now
, where
, 2,
2758 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2760 fix_new_exp (frag_now
, where
, 2,
2761 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2768 if (op2
.mode
== OP_EXP
)
2770 if (op2
.exp
.X_op
== O_constant
)
2772 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2776 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2780 if (op2
.reg
) /* Not PC relative. */
2781 fix_new_exp (frag_now
, where
, 2,
2782 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
2784 fix_new_exp (frag_now
, where
, 2,
2785 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2790 dwarf2_emit_insn (insn_length
);
2794 /* Branch instruction => mov dst, r0. */
2797 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2801 line
= extract_operand (line
, l1
, sizeof (l1
));
2802 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2808 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2809 op_length
= 2 + 2 * op1
.ol
;
2810 frag
= frag_more (op_length
);
2811 where
= frag
- frag_now
->fr_literal
;
2812 bfd_putl16 ((bfd_vma
) bin
, frag
);
2814 if (op1
.mode
== OP_EXP
)
2816 if (op1
.exp
.X_op
== O_constant
)
2818 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2824 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2826 if (op1
.reg
|| op1
.am
== 3)
2827 fix_new_exp (frag_now
, where
, 2,
2828 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
2830 fix_new_exp (frag_now
, where
, 2,
2831 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2835 dwarf2_emit_insn (insn_length
+ op_length
);
2839 /* CALLA instructions. */
2840 fix_emitted
= FALSE
;
2842 line
= extract_operand (line
, l1
, sizeof (l1
));
2845 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
2846 extended_op
, FALSE
);
2852 op_length
= 2 + 2 * op1
.ol
;
2853 frag
= frag_more (op_length
);
2854 where
= frag
- frag_now
->fr_literal
;
2862 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2863 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2866 else if (op1
.am
== 1)
2872 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2873 BFD_RELOC_MSP430X_PCR20_CALL
);
2877 bin
|= 0x50 | op1
.reg
;
2879 else if (op1
.am
== 0)
2880 bin
|= 0x40 | op1
.reg
;
2882 else if (op1
.am
== 1)
2886 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2887 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2890 else if (op1
.am
== 2)
2891 bin
|= 0x60 | op1
.reg
;
2892 else if (op1
.am
== 3)
2893 bin
|= 0x70 | op1
.reg
;
2895 bfd_putl16 ((bfd_vma
) bin
, frag
);
2897 if (op1
.mode
== OP_EXP
)
2901 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
2905 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2908 fix_new_exp (frag_now
, where
+ 2, 2,
2909 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
2912 dwarf2_emit_insn (insn_length
+ op_length
);
2920 /* [POP|PUSH]M[.A] #N, Rd */
2921 line
= extract_operand (line
, l1
, sizeof (l1
));
2922 line
= extract_operand (line
, l2
, sizeof (l2
));
2926 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
2929 parse_exp (l1
+ 1, &(op1
.exp
));
2930 if (op1
.exp
.X_op
!= O_constant
)
2932 as_bad (_("expected constant expression for first argument of %s"),
2937 if ((reg
= check_reg (l2
)) == -1)
2939 as_bad (_("expected register as second argument of %s"),
2945 frag
= frag_more (op_length
);
2946 where
= frag
- frag_now
->fr_literal
;
2947 bin
= opcode
->bin_opcode
;
2950 n
= op1
.exp
.X_add_number
;
2951 bin
|= (n
- 1) << 4;
2952 if (is_opcode ("pushm"))
2956 if (reg
- n
+ 1 < 0)
2958 as_bad (_("Too many registers popped"));
2962 /* CPU21 errata: cannot use POPM to restore the SR register. */
2963 if (target_is_430xv2 ()
2964 && (reg
- n
+ 1 < 3)
2966 && is_opcode ("popm"))
2968 as_bad (_("Cannot use POPM to restore the SR register"));
2972 bin
|= (reg
- n
+ 1);
2975 bfd_putl16 ((bfd_vma
) bin
, frag
);
2976 dwarf2_emit_insn (op_length
);
2985 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2986 if (extended
& 0xff)
2988 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2992 line
= extract_operand (line
, l1
, sizeof (l1
));
2993 line
= extract_operand (line
, l2
, sizeof (l2
));
2997 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
3000 parse_exp (l1
+ 1, &(op1
.exp
));
3001 if (op1
.exp
.X_op
!= O_constant
)
3003 as_bad (_("expected constant expression for first argument of %s"),
3007 n
= op1
.exp
.X_add_number
;
3010 as_bad (_("expected first argument of %s to be in the range 1-4"),
3015 if ((reg
= check_reg (l2
)) == -1)
3017 as_bad (_("expected register as second argument of %s"),
3022 if (target_is_430xv2 () && reg
== 0)
3024 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3029 frag
= frag_more (op_length
);
3030 where
= frag
- frag_now
->fr_literal
;
3032 bin
= opcode
->bin_opcode
;
3035 bin
|= (n
- 1) << 10;
3038 bfd_putl16 ((bfd_vma
) bin
, frag
);
3039 dwarf2_emit_insn (op_length
);
3047 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
3048 if (extended
& 0xff)
3050 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3054 line
= extract_operand (line
, l1
, sizeof (l1
));
3055 if ((reg
= check_reg (l1
)) == -1)
3057 as_bad (_("expected register as argument of %s"),
3062 if (target_is_430xv2 () && reg
== 0)
3064 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3070 /* Tricky - there is no single instruction that will do this.
3071 Encode as: RRA.B rN { BIC.B #0x80, rN */
3073 frag
= frag_more (op_length
);
3074 where
= frag
- frag_now
->fr_literal
;
3076 bfd_putl16 ((bfd_vma
) bin
, frag
);
3077 dwarf2_emit_insn (2);
3079 bfd_putl16 ((bfd_vma
) bin
, frag
+ 2);
3081 bfd_putl16 ((bfd_vma
) bin
, frag
+ 4);
3082 dwarf2_emit_insn (4);
3086 /* Encode as RRUM[.A] rN. */
3087 bin
= opcode
->bin_opcode
;
3092 frag
= frag_more (op_length
);
3093 where
= frag
- frag_now
->fr_literal
;
3094 bfd_putl16 ((bfd_vma
) bin
, frag
);
3095 dwarf2_emit_insn (op_length
);
3102 bfd_boolean need_reloc
= FALSE
;
3106 /* ADDA, CMPA and SUBA address instructions. */
3107 if (extended
& 0xff)
3109 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
3113 line
= extract_operand (line
, l1
, sizeof (l1
));
3114 line
= extract_operand (line
, l2
, sizeof (l2
));
3116 bin
= opcode
->bin_opcode
;
3120 parse_exp (l1
+ 1, &(op1
.exp
));
3122 if (op1
.exp
.X_op
== O_constant
)
3124 n
= op1
.exp
.X_add_number
;
3125 if (n
> 0xfffff || n
< - (0x7ffff))
3127 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3132 bin
|= ((n
>> 16) & 0xf) << 8;
3144 if ((n
= check_reg (l1
)) == -1)
3146 as_bad (_("expected register name or constant as first argument of %s"),
3151 bin
|= (n
<< 8) | (1 << 6);
3155 if ((reg
= check_reg (l2
)) == -1)
3157 as_bad (_("expected register as second argument of %s"),
3162 frag
= frag_more (op_length
);
3163 where
= frag
- frag_now
->fr_literal
;
3166 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
3167 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
3169 bfd_putl16 ((bfd_vma
) bin
, frag
);
3171 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
3172 dwarf2_emit_insn (op_length
);
3176 case 9: /* MOVA, BRA, RETA. */
3178 bin
= opcode
->bin_opcode
;
3180 if (is_opcode ("reta"))
3182 /* The RETA instruction does not take any arguments.
3183 The implicit first argument is @SP+.
3184 The implicit second argument is PC. */
3194 line
= extract_operand (line
, l1
, sizeof (l1
));
3195 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3196 &imm_op
, extended_op
, FALSE
);
3198 if (is_opcode ("bra"))
3200 /* This is the BRA synthetic instruction.
3201 The second argument is always PC. */
3207 line
= extract_operand (line
, l2
, sizeof (l2
));
3208 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
3213 break; /* Error occurred. All warnings were done before. */
3216 /* Only a restricted subset of the normal MSP430 addressing modes
3217 are supported here, so check for the ones that are allowed. */
3218 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
3219 & error_message
)) == 0)
3221 as_bad (error_message
, opcode
->name
);
3224 dwarf2_emit_insn (op_length
);
3228 line
= extract_operand (line
, l1
, sizeof l1
);
3229 /* The RPT instruction only accepted immediates and registers. */
3232 parse_exp (l1
+ 1, &(op1
.exp
));
3233 if (op1
.exp
.X_op
!= O_constant
)
3235 as_bad (_("expected constant value as argument to RPT"));
3238 if (op1
.exp
.X_add_number
< 1
3239 || op1
.exp
.X_add_number
> (1 << 4))
3241 as_bad (_("expected constant in the range 2..16"));
3245 /* We silently accept and ignore a repeat count of 1. */
3246 if (op1
.exp
.X_add_number
> 1)
3247 repeat_count
= op1
.exp
.X_add_number
;
3253 if ((reg
= check_reg (l1
)) != -1)
3256 as_warn (_("PC used as an argument to RPT"));
3258 repeat_count
= - reg
;
3262 as_bad (_("expected constant or register name as argument to RPT insn"));
3269 as_bad (_("Illegal emulated instruction "));
3274 case 1: /* Format 1, double operand. */
3275 line
= extract_operand (line
, l1
, sizeof (l1
));
3276 line
= extract_operand (line
, l2
, sizeof (l2
));
3277 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
3278 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
3281 break; /* Error occurred. All warnings were done before. */
3284 && is_opcode ("movx")
3286 && msp430_enable_relax
)
3288 /* This is the MOVX.A instruction. See if we can convert
3289 it into the MOVA instruction instead. This saves 2 bytes. */
3290 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
3293 dwarf2_emit_insn (op_length
);
3298 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3300 if ( (is_opcode ("bic") && bin
== 0xc232)
3301 || (is_opcode ("bis") && bin
== 0xd232)
3302 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2))
3306 if (warn_interrupt_nops
)
3308 if (gen_interrupt_nops
)
3309 as_warn (_("NOP inserted between two instructions that change interrupt state"));
3311 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
3314 if (gen_interrupt_nops
)
3316 /* Emit a NOP between interrupt enable/disable.
3317 See 1.3.4.1 of the MSP430x5xx User Guide. */
3319 frag
= frag_more (2);
3320 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
3324 nop_check_needed
= TRUE
;
3327 /* Compute the entire length of the instruction in bytes. */
3328 op_length
= (extended_op
? 2 : 0) /* The extension word. */
3329 + 2 /* The opcode */
3330 + (2 * op1
.ol
) /* The first operand. */
3331 + (2 * op2
.ol
); /* The second operand. */
3333 insn_length
+= op_length
;
3334 frag
= frag_more (op_length
);
3335 where
= frag
- frag_now
->fr_literal
;
3340 extended
|= BYTE_OPERATION
;
3342 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
3344 as_bad (_("repeat instruction used with non-register mode instruction"));
3348 /* If necessary, emit a reloc to update the extension word. */
3349 if (op1
.mode
== OP_EXP
)
3351 if (op1
.exp
.X_op
== O_constant
)
3352 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3354 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3355 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3356 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3358 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3359 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3362 if (op2
.mode
== OP_EXP
)
3364 if (op2
.exp
.X_op
== O_constant
)
3365 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3367 else if (op1
.mode
== OP_EXP
)
3368 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3369 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3370 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3373 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3374 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3375 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3378 /* Emit the extension word. */
3379 bfd_putl16 (extended
, frag
);
3384 bfd_putl16 ((bfd_vma
) bin
, frag
);
3388 if (op1
.mode
== OP_EXP
)
3390 if (op1
.exp
.X_op
== O_constant
)
3392 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3396 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3400 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3401 fix_new_exp (frag_now
, where
, 2,
3402 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3404 fix_new_exp (frag_now
, where
, 2,
3405 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3413 if (op2
.mode
== OP_EXP
)
3415 if (op2
.exp
.X_op
== O_constant
)
3417 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3421 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3425 if (op2
.reg
) /* Not PC relative. */
3426 fix_new_exp (frag_now
, where
, 2,
3427 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430 (op2
));
3429 fix_new_exp (frag_now
, where
, 2,
3430 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3435 dwarf2_emit_insn (insn_length
);
3438 case 2: /* Single-operand mostly instr. */
3439 if (opcode
->insn_opnumb
== 0)
3441 /* reti instruction. */
3443 frag
= frag_more (2);
3444 bfd_putl16 ((bfd_vma
) bin
, frag
);
3445 dwarf2_emit_insn (insn_length
);
3449 line
= extract_operand (line
, l1
, sizeof (l1
));
3450 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3451 &imm_op
, extended_op
, TRUE
);
3453 break; /* Error in operand. */
3455 if (target_is_430xv2 ()
3456 && op1
.mode
== OP_REG
3458 && (is_opcode ("rrax")
3459 || is_opcode ("rrcx")
3460 || is_opcode ("rra")
3461 || is_opcode ("rrc")))
3463 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3467 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3468 frag
= frag_more (insn_length
);
3469 where
= frag
- frag_now
->fr_literal
;
3473 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3475 /* These two instructions use a special
3476 encoding of the A/L and B/W bits. */
3477 bin
&= ~ BYTE_OPERATION
;
3481 as_bad (_("%s instruction does not accept a .b suffix"),
3486 extended
|= BYTE_OPERATION
;
3489 extended
|= BYTE_OPERATION
;
3491 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3493 as_bad (_("repeat instruction used with non-register mode instruction"));
3497 if (op1
.mode
== OP_EXP
)
3499 if (op1
.exp
.X_op
== O_constant
)
3500 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3502 else if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3503 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3504 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3506 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3507 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3510 /* Emit the extension word. */
3511 bfd_putl16 (extended
, frag
);
3516 bin
|= op1
.reg
| (op1
.am
<< 4);
3517 bfd_putl16 ((bfd_vma
) bin
, frag
);
3521 if (op1
.mode
== OP_EXP
)
3523 if (op1
.exp
.X_op
== O_constant
)
3525 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3529 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3533 if (op1
.reg
|| op1
.am
== 3) /* Not PC relative. */
3534 fix_new_exp (frag_now
, where
, 2,
3535 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430 (op1
));
3537 fix_new_exp (frag_now
, where
, 2,
3538 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3543 dwarf2_emit_insn (insn_length
);
3546 case 3: /* Conditional jumps instructions. */
3547 line
= extract_operand (line
, l1
, sizeof (l1
));
3548 /* l1 is a label. */
3557 parse_exp (m
, &exp
);
3559 /* In order to handle something like:
3563 jz 4 ; skip next 4 bytes
3566 nop ; will jump here if r5 positive or zero
3568 jCOND -n ;assumes jump n bytes backward:
3578 jCOND $n ; jump from PC in either direction. */
3580 if (exp
.X_op
== O_constant
)
3582 int x
= exp
.X_add_number
;
3586 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3590 if ((*l1
== '$' && x
> 0) || x
< 0)
3595 if (x
> 512 || x
< -511)
3597 as_bad (_("Wrong displacement %d"), x
<< 1);
3602 frag
= frag_more (2); /* Instr size is 1 word. */
3605 bfd_putl16 ((bfd_vma
) bin
, frag
);
3607 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3610 frag
= frag_more (2); /* Instr size is 1 word. */
3611 where
= frag
- frag_now
->fr_literal
;
3612 fix_new_exp (frag_now
, where
, 2,
3613 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3615 bfd_putl16 ((bfd_vma
) bin
, frag
);
3617 else if (*l1
== '$')
3619 as_bad (_("instruction requires label sans '$'"));
3623 ("instruction requires label or value in range -511:512"));
3624 dwarf2_emit_insn (insn_length
);
3629 as_bad (_("instruction requires label"));
3634 case 4: /* Extended jumps. */
3635 if (!msp430_enable_polys
)
3637 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3641 line
= extract_operand (line
, l1
, sizeof (l1
));
3647 /* Ignore absolute addressing. make it PC relative anyway. */
3648 if (*m
== '#' || *m
== '$')
3651 parse_exp (m
, & exp
);
3652 if (exp
.X_op
== O_symbol
)
3654 /* Relaxation required. */
3655 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3657 if (target_is_430x ())
3658 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3660 /* The parameter to dwarf2_emit_insn is actually the offset to
3661 the start of the insn from the fix piece of instruction that
3662 was emitted. Since next fragments may have variable size we
3663 tie debug info to the beginning of the instruction. */
3665 frag
= frag_more (8);
3666 dwarf2_emit_insn (0);
3667 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3668 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3670 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3672 0, /* Offset is zero if jump dist less than 1K. */
3678 as_bad (_("instruction requires label"));
3681 case 5: /* Emulated extended branches. */
3682 if (!msp430_enable_polys
)
3684 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3687 line
= extract_operand (line
, l1
, sizeof (l1
));
3693 /* Ignore absolute addressing. make it PC relative anyway. */
3694 if (*m
== '#' || *m
== '$')
3697 parse_exp (m
, & exp
);
3698 if (exp
.X_op
== O_symbol
)
3700 /* Relaxation required. */
3701 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3703 if (target_is_430x ())
3704 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3707 frag
= frag_more (8);
3708 dwarf2_emit_insn (0);
3709 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3710 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3712 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3713 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3715 0, /* Offset is zero if jump dist less than 1K. */
3721 as_bad (_("instruction requires label"));
3725 as_bad (_("Illegal instruction or not implemented opcode."));
3728 input_line_pointer
= line
;
3729 check_for_nop
= nop_check_needed
;
3734 md_assemble (char * str
)
3736 struct msp430_opcode_s
* opcode
;
3740 str
= skip_space (str
); /* Skip leading spaces. */
3741 str
= extract_cmd (str
, cmd
, sizeof (cmd
) - 1);
3745 char a
= TOLOWER (cmd
[i
]);
3752 as_bad (_("can't find opcode "));
3756 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3760 as_bad (_("unknown opcode `%s'"), cmd
);
3765 char *__t
= input_line_pointer
;
3767 msp430_operands (opcode
, str
);
3768 input_line_pointer
= __t
;
3772 /* GAS will call this function for each section at the end of the assembly,
3773 to permit the CPU backend to adjust the alignment of a section. */
3776 md_section_align (asection
* seg
, valueT addr
)
3778 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3780 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
3783 /* If you define this macro, it should return the offset between the
3784 address of a PC relative fixup and the position from which the PC
3785 relative adjustment should be made. On many processors, the base
3786 of a PC relative instruction is the next instruction, so this
3787 macro would return the length of an instruction. */
3790 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3792 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3793 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3794 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3797 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3800 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3801 Now it handles the situation when relocations
3802 have to be passed to linker. */
3804 msp430_force_relocation_local (fixS
*fixp
)
3806 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3810 if (msp430_enable_polys
3811 && !msp430_enable_relax
)
3814 return (!fixp
->fx_pcrel
3815 || generic_force_reloc (fixp
));
3819 /* GAS will call this for each fixup. It should store the correct
3820 value in the object file. */
3822 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3824 unsigned char * where
;
3828 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3833 else if (fixp
->fx_pcrel
)
3835 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3837 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3839 /* FIXME: We can appear here only in case if we perform a pc
3840 relative jump to the label which is i) global, ii) locally
3841 defined or this is a jump to an absolute symbol.
3842 If this is an absolute symbol -- everything is OK.
3843 If this is a global label, we've got a symbol value defined
3845 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3846 from this section start
3847 2. *valuep will contain the real offset from jump insn to the
3849 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3850 will be incorrect. Therefore remove s_get_value. */
3851 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
3859 value
= fixp
->fx_offset
;
3861 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
3863 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3865 value
-= S_GET_VALUE (fixp
->fx_subsy
);
3871 fixp
->fx_no_overflow
= 1;
3873 /* If polymorphs are enabled and relax disabled.
3874 do not kill any relocs and pass them to linker. */
3875 if (msp430_enable_polys
3876 && !msp430_enable_relax
)
3879 || S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
3880 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
3887 /* Fetch the instruction, insert the fully resolved operand
3888 value, and stuff the instruction back again. */
3889 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
3891 insn
= bfd_getl16 (where
);
3893 switch (fixp
->fx_r_type
)
3895 case BFD_RELOC_MSP430_10_PCREL
:
3897 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3898 _("odd address operand: %ld"), value
);
3900 /* Jumps are in words. */
3902 --value
; /* Correct PC. */
3904 if (value
< -512 || value
> 511)
3905 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3906 _("operand out of range: %ld"), value
);
3908 value
&= 0x3ff; /* get rid of extended sign */
3909 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
3912 case BFD_RELOC_MSP430X_PCR16
:
3913 case BFD_RELOC_MSP430_RL_PCREL
:
3914 case BFD_RELOC_MSP430_16_PCREL
:
3916 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3917 _("odd address operand: %ld"), value
);
3920 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
3921 /* Nothing to be corrected here. */
3922 if (value
< -32768 || value
> 65536)
3923 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3924 _("operand out of range: %ld"), value
);
3927 case BFD_RELOC_MSP430X_ABS16
:
3928 case BFD_RELOC_MSP430_16
:
3930 case BFD_RELOC_MSP430_16_BYTE
:
3931 value
&= 0xffff; /* Get rid of extended sign. */
3932 bfd_putl16 ((bfd_vma
) value
, where
);
3935 case BFD_RELOC_MSP430_ABS_HI16
:
3937 value
&= 0xffff; /* Get rid of extended sign. */
3938 bfd_putl16 ((bfd_vma
) value
, where
);
3942 bfd_putl16 ((bfd_vma
) value
, where
);
3945 case BFD_RELOC_MSP430_ABS8
:
3947 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
3950 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
3951 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
3952 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3954 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
3957 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
3958 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3960 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
3963 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
3964 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3966 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3969 case BFD_RELOC_MSP430X_PCR20_CALL
:
3970 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3972 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3975 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
3976 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
3977 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3979 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3982 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
3983 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3985 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3988 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
3989 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3991 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3995 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3996 fixp
->fx_line
, fixp
->fx_r_type
);
4002 fixp
->fx_addnumber
= value
;
4007 S_IS_GAS_LOCAL (symbolS
* s
)
4014 name
= S_GET_NAME (s
);
4015 len
= strlen (name
) - 1;
4017 return name
[len
] == 1 || name
[len
] == 2;
4020 /* GAS will call this to generate a reloc, passing the resulting reloc
4021 to `bfd_install_relocation'. This currently works poorly, as
4022 `bfd_install_relocation' often does the wrong thing, and instances of
4023 `tc_gen_reloc' have been written to work around the problems, which
4024 in turns makes it difficult to fix `bfd_install_relocation'. */
4026 /* If while processing a fixup, a reloc really needs to be created
4027 then it is done here. */
4030 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
4032 static arelent
* no_relocs
= NULL
;
4033 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
4036 reloc
= xmalloc (sizeof (arelent
));
4037 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
4038 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
4040 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
4042 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
4043 _("reloc %d not supported by object file format"),
4044 (int) fixp
->fx_r_type
);
4053 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
4055 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
4056 fixp
->fx_subsy
= NULL
;
4059 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
4061 asection
*asec
, *ssec
;
4063 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
4064 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
4066 /* If we have a difference between two different, non-absolute symbols
4067 we must generate two relocs (one for each symbol) and allow the
4068 linker to resolve them - relaxation may change the distances between
4069 symbols, even local symbols defined in the same section.
4071 Unfortunately we cannot do this with assembler generated local labels
4072 because there can be multiple incarnations of the same label, with
4073 exactly the same name, in any given section and the linker will have
4074 no way to identify the correct one. Instead we just have to hope
4075 that no relaxtion will occur between the local label and the other
4076 symbol in the expression.
4078 Similarly we have to compute differences between symbols in the .eh_frame
4079 section as the linker is not smart enough to apply relocations there
4080 before attempting to process it. */
4081 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
4082 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
4083 && strcmp (ssec
->name
, ".eh_frame") != 0
4084 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
4085 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
4087 arelent
* reloc2
= xmalloc (sizeof * reloc
);
4092 reloc2
->address
= reloc
->address
;
4093 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
4094 BFD_RELOC_MSP430_SYM_DIFF
);
4095 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
4097 if (ssec
== absolute_section
)
4098 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4101 reloc2
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4102 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
4105 reloc
->addend
= fixp
->fx_offset
;
4106 if (asec
== absolute_section
)
4108 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
4109 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
4113 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4114 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4123 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4125 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
4126 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
4128 switch (fixp
->fx_r_type
)
4131 md_number_to_chars (fixpos
, reloc
->addend
, 1);
4135 md_number_to_chars (fixpos
, reloc
->addend
, 2);
4139 md_number_to_chars (fixpos
, reloc
->addend
, 3);
4143 md_number_to_chars (fixpos
, reloc
->addend
, 4);
4148 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
4159 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
4160 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
4162 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
4163 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
4165 md_number_to_chars (fixpos
, amount
, 2);
4170 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
4171 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
4172 reloc
->addend
= fixp
->fx_offset
;
4174 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4175 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
4176 reloc
->address
= fixp
->fx_offset
;
4183 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
4184 asection
* segment_type ATTRIBUTE_UNUSED
)
4186 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
4188 /* This is a jump -> pcrel mode. Nothing to do much here.
4189 Return value == 2. */
4191 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
4193 else if (fragP
->fr_symbol
)
4195 /* Its got a segment, but its not ours. Even if fr_symbol is in
4196 an absolute segment, we don't know a displacement until we link
4197 object files. So it will always be long. This also applies to
4198 labels in a subsegment of current. Liker may relax it to short
4199 jump later. Return value == 8. */
4201 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
4205 /* We know the abs value. may be it is a jump to fixed address.
4206 Impossible in our case, cause all constants already handled. */
4208 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
4211 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
4215 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
4216 asection
* sec ATTRIBUTE_UNUSED
,
4222 struct rcodes_s
* cc
= NULL
;
4223 struct hcodes_s
* hc
= NULL
;
4225 switch (fragP
->fr_subtype
)
4227 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
4228 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
4229 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
4230 /* We do not have to convert anything here.
4231 Just apply a fix. */
4232 rela
= BFD_RELOC_MSP430_10_PCREL
;
4235 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
4236 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
4237 /* Convert uncond branch jmp lab -> br lab. */
4238 if (target_is_430x ())
4239 cc
= msp430x_rcodes
+ 7;
4241 cc
= msp430_rcodes
+ 7;
4242 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4243 bfd_putl16 (cc
->lop0
, where
);
4244 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4248 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
4249 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
4251 /* Other simple branches. */
4252 int insn
= bfd_getl16 (fragP
->fr_opcode
);
4255 /* Find actual instruction. */
4256 if (target_is_430x ())
4258 for (i
= 0; i
< 7 && !cc
; i
++)
4259 if (msp430x_rcodes
[i
].sop
== insn
)
4260 cc
= msp430x_rcodes
+ i
;
4264 for (i
= 0; i
< 7 && !cc
; i
++)
4265 if (msp430_rcodes
[i
].sop
== insn
)
4266 cc
= & msp430_rcodes
[i
];
4269 if (!cc
|| !cc
->name
)
4270 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4271 __FUNCTION__
, (long) insn
);
4272 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4273 bfd_putl16 (cc
->lop0
, where
);
4274 bfd_putl16 (cc
->lop1
, where
+ 2);
4275 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4280 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
4281 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
4282 if (target_is_430x ())
4283 cc
= msp430x_rcodes
+ 6;
4285 cc
= msp430_rcodes
+ 6;
4286 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4287 bfd_putl16 (cc
->lop0
, where
);
4288 bfd_putl16 (cc
->lop1
, where
+ 2);
4289 bfd_putl16 (cc
->lop2
, where
+ 4);
4290 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4294 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
4296 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4299 if (target_is_430x ())
4301 for (i
= 0; i
< 4 && !hc
; i
++)
4302 if (msp430x_hcodes
[i
].op1
== insn
)
4303 hc
= msp430x_hcodes
+ i
;
4307 for (i
= 0; i
< 4 && !hc
; i
++)
4308 if (msp430_hcodes
[i
].op1
== insn
)
4309 hc
= &msp430_hcodes
[i
];
4311 if (!hc
|| !hc
->name
)
4312 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4313 __FUNCTION__
, (long) insn
);
4314 rela
= BFD_RELOC_MSP430_10_PCREL
;
4315 /* Apply a fix for a first label if necessary.
4316 another fix will be applied to the next word of insn anyway. */
4318 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4319 fragP
->fr_offset
, TRUE
, rela
);
4325 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
4326 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
4328 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
4331 if (target_is_430x ())
4333 for (i
= 0; i
< 4 && !hc
; i
++)
4334 if (msp430x_hcodes
[i
].op1
== insn
)
4335 hc
= msp430x_hcodes
+ i
;
4339 for (i
= 0; i
< 4 && !hc
; i
++)
4340 if (msp430_hcodes
[i
].op1
== insn
)
4341 hc
= & msp430_hcodes
[i
];
4343 if (!hc
|| !hc
->name
)
4344 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4345 __FUNCTION__
, (long) insn
);
4346 rela
= BFD_RELOC_MSP430_RL_PCREL
;
4347 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
4348 bfd_putl16 (hc
->lop0
, where
);
4349 bfd_putl16 (hc
->lop1
, where
+ 2);
4350 bfd_putl16 (hc
->lop2
, where
+ 4);
4356 as_fatal (_("internal inconsistency problem in %s: %lx"),
4357 __FUNCTION__
, (long) fragP
->fr_subtype
);
4361 /* Now apply fix. */
4362 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4363 fragP
->fr_offset
, TRUE
, rela
);
4364 /* Just fixed 2 bytes. */
4368 /* Relax fragment. Mostly stolen from hc11 and mcore
4369 which arches I think I know. */
4372 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4373 long stretch ATTRIBUTE_UNUSED
)
4378 const relax_typeS
*this_type
;
4379 const relax_typeS
*start_type
;
4380 relax_substateT next_state
;
4381 relax_substateT this_state
;
4382 const relax_typeS
*table
= md_relax_table
;
4384 /* Nothing to be done if the frag has already max size. */
4385 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4386 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4389 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4391 symbolP
= fragP
->fr_symbol
;
4392 if (symbol_resolved_p (symbolP
))
4393 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4395 /* We know the offset. calculate a distance. */
4396 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4399 if (!msp430_enable_relax
)
4401 /* Relaxation is not enabled. So, make all jump as long ones
4402 by setting 'aim' to quite high value. */
4406 this_state
= fragP
->fr_subtype
;
4407 start_type
= this_type
= table
+ this_state
;
4411 /* Look backwards. */
4412 for (next_state
= this_type
->rlx_more
; next_state
;)
4413 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4417 /* Grow to next state. */
4418 this_state
= next_state
;
4419 this_type
= table
+ this_state
;
4420 next_state
= this_type
->rlx_more
;
4425 /* Look forwards. */
4426 for (next_state
= this_type
->rlx_more
; next_state
;)
4427 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4431 /* Grow to next state. */
4432 this_state
= next_state
;
4433 this_type
= table
+ this_state
;
4434 next_state
= this_type
->rlx_more
;
4438 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4440 fragP
->fr_subtype
= this_state
;
4444 /* Return FALSE if the fixup in fixp should be left alone and not
4445 adjusted. We return FALSE here so that linker relaxation will
4449 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4451 /* If the symbol is in a non-code section then it should be OK. */
4453 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4459 /* Set the contents of the .MSP430.attributes section. */
4462 msp430_md_end (void)
4464 if (check_for_nop
== TRUE
&& warn_interrupt_nops
)
4465 as_warn ("assembly finished with the last instruction changing interrupt state - a NOP might be needed");
4467 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4468 target_is_430x () ? 2 : 1);
4470 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4471 large_model
? 2 : 1);
4473 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4474 large_model
? 2 : 1);
4477 /* Returns FALSE if there is a msp430 specific reason why the
4478 subtraction of two same-section symbols cannot be computed by
4482 msp430_allow_local_subtract (expressionS
* left
,
4483 expressionS
* right
,
4486 /* If the symbols are not in a code section then they are OK. */
4487 if ((section
->flags
& SEC_CODE
) == 0)
4490 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4493 if (left
->X_add_symbol
== right
->X_add_symbol
)
4496 /* We have to assume that there may be instructions between the
4497 two symbols and that relaxation may increase the distance between