1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
5 Contributed by Dmitry Diky <diwil@mail.ru>
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
26 #define PUSH_1X_WORKAROUND
29 #include "opcode/msp430.h"
30 #include "safe-ctype.h"
31 #include "dwarf2dbg.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 /* GCC uses the some condition codes which we'll
74 implement as new polymorph instructions.
76 COND EXPL SHORT JUMP LONG JUMP
77 ===============================================
78 eq == jeq jne +4; br lab
79 ne != jne jeq +4; br lab
81 ltn honours no-overflow flag
82 ltn < jn jn +2; jmp +4; br lab
84 lt < jl jge +4; br lab
85 ltu < jlo lhs +4; br lab
91 ge >= jge jl +4; br lab
92 geu >= jhs jlo +4; br lab
93 ===============================================
95 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
96 beq,bne,blt,bltn,bltu,bge,bgeu
97 'u' means unsigned compares
99 Also, we add 'jump' instruction:
100 jump UNCOND -> jmp br lab
102 They will have fmt == 4, and insn_opnumb == number of instruction. */
107 int index
; /* Corresponding insn_opnumb. */
108 int sop
; /* Opcode if jump length is short. */
109 long lpos
; /* Label position. */
110 long lop0
; /* Opcode 1 _word_ (16 bits). */
111 long lop1
; /* Opcode second word. */
112 long lop2
; /* Opcode third word. */
115 #define MSP430_RLC(n,i,sop,o1) \
116 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
118 static struct rcodes_s msp430_rcodes
[] =
120 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
121 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
122 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
123 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
124 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
125 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
126 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
127 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
133 /* More difficult than above and they have format 5.
136 =================================================================
137 gt > jeq +2; jge label jeq +6; jl +4; br label
138 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
139 leu <= jeq label; jlo label jeq +2; jhs +4; br label
140 le <= jeq label; jl label jeq +2; jge +4; br label
141 ================================================================= */
146 int index
; /* Corresponding insn_opnumb. */
147 int tlab
; /* Number of labels in short mode. */
148 int op0
; /* Opcode for first word of short jump. */
149 int op1
; /* Opcode for second word of short jump. */
150 int lop0
; /* Opcodes for long jump mode. */
155 static struct hcodes_s msp430_hcodes
[] =
157 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
158 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
159 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
160 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
164 const char comment_chars
[] = ";";
165 const char line_comment_chars
[] = "#";
166 const char line_separator_chars
[] = "{";
167 const char EXP_CHARS
[] = "eE";
168 const char FLT_CHARS
[] = "dD";
170 /* Handle long expressions. */
171 extern LITTLENUM_TYPE generic_bignum
[];
173 static struct hash_control
*msp430_hash
;
176 #define STATE_UNCOND_BRANCH 1 /* jump */
177 #define STATE_NOOV_BRANCH 3 /* bltn */
178 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
179 #define STATE_EMUL_BRANCH 4
188 #define STATE_BITS10 1 /* wild guess. short jump */
189 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
190 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
192 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
193 #define RELAX_STATE(s) ((s) & 3)
194 #define RELAX_LEN(s) ((s) >> 2)
195 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
197 relax_typeS md_relax_table
[] =
205 /* Unconditional jump. */
207 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
208 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
209 {1, 1, CUBL
, 0}, /* state undef */
211 /* Simple branches. */
213 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
214 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
217 /* blt no overflow branch. */
219 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
220 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
223 /* Emulated branches. */
225 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
226 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
231 #define MAX_OP_LEN 256
240 #define MSP430_ISA_11 11
241 #define MSP430_ISA_110 110
242 #define MSP430_ISA_12 12
243 #define MSP430_ISA_13 13
244 #define MSP430_ISA_14 14
245 #define MSP430_ISA_15 15
246 #define MSP430_ISA_16 16
247 #define MSP430_ISA_21 21
248 #define MSP430_ISA_31 31
249 #define MSP430_ISA_32 32
250 #define MSP430_ISA_33 33
251 #define MSP430_ISA_41 41
252 #define MSP430_ISA_42 42
253 #define MSP430_ISA_43 43
254 #define MSP430_ISA_44 44
256 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
257 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
259 static struct mcu_type_s mcu_types
[] =
261 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
262 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
263 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
264 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
265 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
266 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
267 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
268 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
269 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
271 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
272 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
273 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
274 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
276 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
277 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
278 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
279 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
280 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
281 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
282 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
284 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
285 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
286 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
287 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
288 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
289 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
290 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
291 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
292 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
294 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
295 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
296 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
297 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
299 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
300 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
301 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
302 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
303 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
304 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
305 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
306 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
307 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
309 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
310 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
311 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
312 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
314 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
315 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
316 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
318 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
319 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
320 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
322 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
323 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
324 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
326 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
327 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
328 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
329 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
330 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
331 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
337 static struct mcu_type_s default_mcu
=
338 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
340 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
342 /* Profiling capability:
343 It is a performance hit to use gcc's profiling approach for this tiny target.
344 Even more -- jtag hardware facility does not perform any profiling functions.
345 However we've got gdb's built-in simulator where we can do anything.
346 Therefore my suggestion is:
348 We define new section ".profiler" which holds all profiling information.
349 We define new pseudo operation .profiler which will instruct assembler to
350 add new profile entry to the object file. Profile should take place at the
355 .profiler flags,function_to_profile [, cycle_corrector, extra]
357 where 'flags' is a combination of the following chars:
360 i - function is in Init section
361 f - function is in Fini section
363 c - libC standard call
364 d - stack value Demand (saved at run-time in simulator)
365 I - Interrupt service routine
370 j - long Jump/ sjlj unwind
371 a - an Arbitrary code fragment
372 t - exTra parameter saved (constant value like frame size)
373 '""' optional: "sil" == sil
375 function_to_profile - function's address
376 cycle_corrector - a value which should be added to the cycle
377 counter, zero if omitted
378 extra - some extra parameter, zero if omitted.
381 ------------------------------
385 .LFrameOffset_fxx=0x08
386 .profiler "scdP", fxx ; function entry.
387 ; we also demand stack value to be displayed
392 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
393 ; (this is a prologue end)
394 ; note, that spare var filled with the frame size
397 .profiler cdE,fxx ; check stack
402 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
403 ret ; cause 'ret' insn takes 3 cycles
404 -------------------------------
406 This profiling approach does not produce any overhead and
408 So, even profiled code can be uploaded to the MCU. */
409 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
410 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
411 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
412 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
413 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
414 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
415 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
416 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
417 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
418 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
419 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
420 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
421 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
422 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
423 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
424 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
437 for (; x
; x
= x
>> 1)
444 /* Parse ordinary expression. */
447 parse_exp (char * s
, expressionS
* op
)
449 input_line_pointer
= s
;
451 if (op
->X_op
== O_absent
)
452 as_bad (_("missing operand"));
453 return input_line_pointer
;
457 /* Delete spaces from s: X ( r 1 2) => X(r12). */
460 del_spaces (char * s
)
468 while (ISSPACE (*m
) && *m
)
470 memmove (s
, m
, strlen (m
) + 1);
478 skip_space (char * s
)
485 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
488 extract_operand (char * from
, char * to
, int limit
)
492 /* Drop leading whitespace. */
493 from
= skip_space (from
);
495 while (size
< limit
&& *from
)
497 *(to
+ size
) = *from
;
498 if (*from
== ',' || *from
== ';' || *from
== '\n')
513 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
530 s
= input_line_pointer
;
531 end
= input_line_pointer
;
533 while (*end
&& *end
!= '\n')
536 while (*s
&& *s
!= '\n')
547 as_bad (_(".profiler pseudo requires at least two operands."));
548 input_line_pointer
= end
;
552 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
561 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
564 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
567 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
570 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
573 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
576 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
579 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
582 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
585 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
588 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
591 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
594 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
597 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
600 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
603 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
606 as_warn (_("unknown profiling flag - ignored."));
613 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
614 | MSP430_PROFILER_FLAG_EXIT
))
615 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
616 | MSP430_PROFILER_FLAG_PROLEND
617 | MSP430_PROFILER_FLAG_EPISTART
618 | MSP430_PROFILER_FLAG_EPIEND
))
619 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
620 | MSP430_PROFILER_FLAG_FINISECT
))))
622 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
623 input_line_pointer
= end
;
627 /* Generate temp symbol which denotes current location. */
628 if (now_seg
== absolute_section
) /* Paranoia ? */
630 exp1
.X_op
= O_constant
;
631 exp1
.X_add_number
= abs_section_offset
;
632 as_warn (_("profiling in absolute section?"));
636 exp1
.X_op
= O_symbol
;
637 exp1
.X_add_symbol
= symbol_temp_new_now ();
638 exp1
.X_add_number
= 0;
641 /* Generate a symbol which holds flags value. */
642 exp
.X_op
= O_constant
;
643 exp
.X_add_number
= p_flags
;
645 /* Save current section. */
649 /* Now go to .profiler section. */
650 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
653 emit_expr (& exp
, 2);
655 /* Save label value. */
656 emit_expr (& exp1
, 2);
660 /* Now get profiling info. */
661 halt
= extract_operand (input_line_pointer
, str
, 1024);
662 /* Process like ".word xxx" directive. */
663 parse_exp (str
, & exp
);
664 emit_expr (& exp
, 2);
665 input_line_pointer
= halt
;
668 /* Fill the rest with zeros. */
669 exp
.X_op
= O_constant
;
670 exp
.X_add_number
= 0;
672 emit_expr (& exp
, 2);
674 /* Return to current section. */
675 subseg_set (seg
, subseg
);
679 extract_word (char * from
, char * to
, int limit
)
685 /* Drop leading whitespace. */
686 from
= skip_space (from
);
689 /* Find the op code end. */
690 for (op_start
= op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
692 to
[size
++] = *op_end
++;
693 if (size
+ 1 >= limit
)
701 #define OPTION_MMCU 'm'
702 #define OPTION_RELAX 'Q'
703 #define OPTION_POLYMORPHS 'P'
706 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
708 char *str
= (char *) alloca (32); /* 32 for good measure. */
710 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
712 md_parse_option (OPTION_MMCU
, str
);
713 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
717 show_mcu_list (FILE * stream
)
721 fprintf (stream
, _("Known MCU names:\n"));
723 for (i
= 0; mcu_types
[i
].name
; i
++)
724 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
726 fprintf (stream
, "\n");
730 md_parse_option (int c
, char * arg
)
737 for (i
= 0; mcu_types
[i
].name
; ++i
)
738 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
741 if (!mcu_types
[i
].name
)
743 show_mcu_list (stderr
);
744 as_fatal (_("unknown MCU: %s\n"), arg
);
747 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
748 msp430_mcu
= &mcu_types
[i
];
750 as_fatal (_("redefinition of mcu type %s' to %s'"),
751 msp430_mcu
->name
, mcu_types
[i
].name
);
756 msp430_enable_relax
= 1;
760 case OPTION_POLYMORPHS
:
761 msp430_enable_polys
= 1;
770 const pseudo_typeS md_pseudo_table
[] =
772 {"arch", msp430_set_arch
, 0},
773 {"profiler", msp430_profiler
, 0},
777 const char *md_shortopts
= "m:";
779 struct option md_longopts
[] =
781 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
782 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
783 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
784 {NULL
, no_argument
, NULL
, 0}
787 size_t md_longopts_size
= sizeof (md_longopts
);
790 md_show_usage (FILE * stream
)
793 _("MSP430 options:\n"
794 " -mmcu=[msp430-name] select microcontroller type\n"
795 " msp430x110 msp430x112\n"
796 " msp430x1101 msp430x1111\n"
797 " msp430x1121 msp430x1122 msp430x1132\n"
798 " msp430x122 msp430x123\n"
799 " msp430x1222 msp430x1232\n"
800 " msp430x133 msp430x135\n"
801 " msp430x1331 msp430x1351\n"
802 " msp430x147 msp430x148 msp430x149\n"
803 " msp430x155 msp430x156 msp430x157\n"
804 " msp430x167 msp430x168 msp430x169\n"
805 " msp430x1610 msp430x1611 msp430x1612\n"
806 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
807 " msp430x323 msp430x325\n"
808 " msp430x336 msp430x337\n"
809 " msp430x412 msp430x413 msp430x415 msp430x417\n"
810 " msp430xE423 msp430xE425 msp430E427\n"
811 " msp430xW423 msp430xW425 msp430W427\n"
812 " msp430xG437 msp430xG438 msp430G439\n"
813 " msp430x435 msp430x436 msp430x437\n"
814 " msp430x447 msp430x448 msp430x449\n"));
816 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
817 " -mP - enable polymorph instructions\n"));
819 show_mcu_list (stream
);
823 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
829 extract_cmd (char * from
, char * to
, int limit
)
833 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
835 *(to
+ size
) = *from
;
845 /* Turn a string in input_line_pointer into a floating point constant
846 of type TYPE, and store the appropriate bytes in *LITP. The number
847 of LITTLENUMS emitted is stored in *SIZEP. An error message is
848 returned, or NULL on OK. */
851 md_atof (int type
, char * litP
, int * sizeP
)
854 LITTLENUM_TYPE words
[4];
855 LITTLENUM_TYPE
*wordP
;
868 return _("bad call to md_atof");
871 t
= atof_ieee (input_line_pointer
, type
, words
);
873 input_line_pointer
= t
;
875 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
877 /* This loop outputs the LITTLENUMs in REVERSE order. */
878 for (wordP
= words
+ prec
- 1; prec
--;)
880 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
881 litP
+= sizeof (LITTLENUM_TYPE
);
890 struct msp430_opcode_s
* opcode
;
891 msp430_hash
= hash_new ();
893 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
894 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
896 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
902 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
904 if (strlen (t
) > 2 && *(t
+ 2) != '+')
909 if ((*t
< '0' || *t
> '9') && *t
!= '+')
922 msp430_srcoperand (struct msp430_operand_s
* op
,
923 char * l
, int bin
, int * imm_op
)
927 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
934 /* Check if there is:
935 llo(x) - least significant 16 bits, x &= 0xffff
936 lhi(x) - x = (x >> 16) & 0xffff,
937 hlo(x) - x = (x >> 32) & 0xffff,
938 hhi(x) - x = (x >> 48) & 0xffff
939 The value _MUST_ be constant expression: #hlo(1231231231). */
943 if (strncasecmp (h
, "#llo(", 5) == 0)
948 else if (strncasecmp (h
, "#lhi(", 5) == 0)
953 else if (strncasecmp (h
, "#hlo(", 5) == 0)
958 else if (strncasecmp (h
, "#hhi(", 5) == 0)
963 else if (strncasecmp (h
, "#lo(", 4) == 0)
968 else if (strncasecmp (h
, "#hi(", 4) == 0)
974 op
->reg
= 0; /* Reg PC. */
976 op
->ol
= 1; /* Immediate will follow an instruction. */
980 parse_exp (__tl
, &(op
->exp
));
981 if (op
->exp
.X_op
== O_constant
)
983 int x
= op
->exp
.X_add_number
;
988 op
->exp
.X_add_number
= x
;
990 else if (vshift
== 1)
992 x
= (x
>> 16) & 0xffff;
993 op
->exp
.X_add_number
= x
;
998 op
->exp
.X_add_number
= -1;
1000 op
->exp
.X_add_number
= 0; /* Nothing left. */
1001 x
= op
->exp
.X_add_number
;
1004 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1006 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1010 /* Now check constants. */
1011 /* Substitute register mode with a constant generator if applicable. */
1013 x
= (short) x
; /* Extend sign. */
1045 #ifdef PUSH_1X_WORKAROUND
1048 /* Remove warning as confusing.
1049 as_warn(_("Hardware push bug workaround")); */
1062 #ifdef PUSH_1X_WORKAROUND
1065 /* Remove warning as confusing.
1066 as_warn(_("Hardware push bug workaround")); */
1078 else if (op
->exp
.X_op
== O_symbol
)
1082 else if (op
->exp
.X_op
== O_big
)
1087 op
->exp
.X_op
= O_constant
;
1088 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1089 x
= op
->exp
.X_add_number
;
1094 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1142 /* Redundant (yet) check. */
1143 else if (op
->exp
.X_op
== O_register
)
1145 (_("Registers cannot be used within immediate expression [%s]"), l
);
1147 as_bad (_("unknown operand %s"), l
);
1152 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1157 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1158 op
->am
= 1; /* mode As == 01 bin. */
1159 op
->ol
= 1; /* Immediate value followed by instruction. */
1161 parse_exp (__tl
, &(op
->exp
));
1163 if (op
->exp
.X_op
== O_constant
)
1165 int x
= op
->exp
.X_add_number
;
1167 if (x
> 65535 || x
< -32768)
1169 as_bad (_("value out of range: %d"), x
);
1173 else if (op
->exp
.X_op
== O_symbol
)
1177 /* Redundant (yet) check. */
1178 if (op
->exp
.X_op
== O_register
)
1180 (_("Registers cannot be used within absolute expression [%s]"), l
);
1182 as_bad (_("unknown expression in operand %s"), l
);
1188 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1192 char *m
= strchr (l
, '+');
1196 as_bad (_("unknown addressing mode %s"), l
);
1201 if (*t
!= 'r' && *t
!= 'R')
1203 as_bad (_("unknown addressing mode %s"), l
);
1207 t
++; /* Points to the reg value. */
1211 as_bad (_("Bad register name r%s"), t
);
1219 *m
= 0; /* strip '+' */
1221 if (op
->reg
< 0 || op
->reg
> 15)
1223 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1230 /* Check if register indexed X(Rn). */
1233 char *h
= strrchr (l
, '(');
1234 char *m
= strrchr (l
, ')');
1243 as_bad (_("')' required"));
1250 /* Extract a register. */
1251 t
++; /* Advance pointer. */
1253 if (*t
!= 'r' && *t
!= 'R')
1256 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1263 if (op
->reg
> 9 || op
->reg
< 0)
1265 as_bad (_("unknown operator (r%s substituted as a register name"),
1272 op
->reg
= op
->reg
* 10;
1273 op
->reg
+= *t
- '0';
1277 as_bad (_("unknown operator %s"), l
);
1282 as_bad (_("r2 should not be used in indexed addressing mode"));
1286 if (*(t
+ 1) != ')')
1288 as_bad (_("unknown operator %s"), l
);
1293 /* Extract constant. */
1297 parse_exp (__tl
, &(op
->exp
));
1298 if (op
->exp
.X_op
== O_constant
)
1300 int x
= op
->exp
.X_add_number
;
1302 if (x
> 65535 || x
< -32768)
1304 as_bad (_("value out of range: %d"), x
);
1316 else if (op
->exp
.X_op
== O_symbol
)
1320 /* Redundant (yet) check. */
1321 if (op
->exp
.X_op
== O_register
)
1323 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1325 as_bad (_("unknown expression in operand %s"), l
);
1333 /* Register mode 'mov r1,r2'. */
1338 /* Operand should be a register. */
1339 if (*t
== 'r' || *t
== 'R')
1341 int x
= atoi (t
+ 1);
1343 if (check_reg (t
+ 1))
1346 if (x
< 0 || x
> 15)
1347 break; /* Symbolic mode. */
1358 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1362 op
->reg
= 0; /* PC relative... be careful. */
1366 parse_exp (__tl
, &(op
->exp
));
1372 as_bad (_("unknown addressing mode for operand %s"), l
);
1378 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1381 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1393 parse_exp (__tl
, &(op
->exp
));
1395 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1397 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1407 ("this addressing mode is not applicable for destination operand"));
1414 /* Parse instruction operands.
1415 Return binary opcode. */
1418 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1420 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1422 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1425 struct msp430_operand_s op1
, op2
;
1427 static short ZEROS
= 0;
1428 int byte_op
, imm_op
;
1430 /* Opcode is the one from opcodes table
1431 line contains something like
1436 /* Check if byte or word operation. */
1437 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1439 bin
|= BYTE_OPERATION
;
1446 while (! ISSPACE (*line
) && *line
)
1449 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1451 as_bad (_("instruction %s requires %d operand(s)"),
1452 opcode
->name
, opcode
->insn_opnumb
);
1456 memset (l1
, 0, sizeof (l1
));
1457 memset (l2
, 0, sizeof (l2
));
1458 memset (&op1
, 0, sizeof (op1
));
1459 memset (&op2
, 0, sizeof (op2
));
1463 switch (opcode
->fmt
)
1465 case 0: /* Emulated. */
1466 switch (opcode
->insn_opnumb
)
1469 /* Set/clear bits instructions. */
1471 frag
= frag_more (__is
);
1472 bfd_putl16 ((bfd_vma
) bin
, frag
);
1473 dwarf2_emit_insn (__is
);
1476 /* Something which works with destination operand. */
1477 line
= extract_operand (line
, l1
, sizeof (l1
));
1478 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1482 bin
|= (op1
.reg
| (op1
.am
<< 7));
1484 frag
= frag_more (2 * __is
);
1485 where
= frag
- frag_now
->fr_literal
;
1486 bfd_putl16 ((bfd_vma
) bin
, frag
);
1487 dwarf2_emit_insn (2 * __is
);
1489 if (op1
.mode
== OP_EXP
)
1492 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1495 fix_new_exp (frag_now
, where
, 2,
1496 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1498 fix_new_exp (frag_now
, where
, 2,
1499 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1505 /* Shift instruction. */
1506 line
= extract_operand (line
, l1
, sizeof (l1
));
1507 strncpy (l2
, l1
, sizeof (l2
));
1508 l2
[sizeof (l2
) - 1] = '\0';
1509 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1510 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1513 break; /* An error occurred. All warnings were done before. */
1515 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1517 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1518 frag
= frag_more (2 * __is
);
1519 where
= frag
- frag_now
->fr_literal
;
1520 bfd_putl16 ((bfd_vma
) bin
, frag
);
1521 dwarf2_emit_insn (2 * __is
);
1523 if (op1
.mode
== OP_EXP
)
1525 where
+= 2; /* Advance 'where' as we do not know _where_. */
1526 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1528 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1529 fix_new_exp (frag_now
, where
, 2,
1530 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1532 fix_new_exp (frag_now
, where
, 2,
1533 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1536 if (op2
.mode
== OP_EXP
)
1539 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1541 if (op2
.reg
) /* Not PC relative. */
1542 fix_new_exp (frag_now
, where
+ 2, 2,
1543 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1545 fix_new_exp (frag_now
, where
+ 2, 2,
1546 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1551 /* Branch instruction => mov dst, r0. */
1552 line
= extract_operand (line
, l1
, sizeof (l1
));
1554 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1561 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1563 frag
= frag_more (2 * __is
);
1564 where
= frag
- frag_now
->fr_literal
;
1565 bfd_putl16 ((bfd_vma
) bin
, frag
);
1566 dwarf2_emit_insn (2 * __is
);
1568 if (op1
.mode
== OP_EXP
)
1571 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1573 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1574 fix_new_exp (frag_now
, where
, 2,
1575 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1577 fix_new_exp (frag_now
, where
, 2,
1578 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1584 case 1: /* Format 1, double operand. */
1585 line
= extract_operand (line
, l1
, sizeof (l1
));
1586 line
= extract_operand (line
, l2
, sizeof (l2
));
1587 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1588 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1591 break; /* Error occurred. All warnings were done before. */
1593 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1595 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1596 frag
= frag_more (2 * __is
);
1597 where
= frag
- frag_now
->fr_literal
;
1598 bfd_putl16 ((bfd_vma
) bin
, frag
);
1599 dwarf2_emit_insn (2 * __is
);
1601 if (op1
.mode
== OP_EXP
)
1603 where
+= 2; /* Advance where as we do not know _where_. */
1604 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1606 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1607 fix_new_exp (frag_now
, where
, 2,
1608 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1610 fix_new_exp (frag_now
, where
, 2,
1611 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1614 if (op2
.mode
== OP_EXP
)
1617 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1619 if (op2
.reg
) /* Not PC relative. */
1620 fix_new_exp (frag_now
, where
+ 2, 2,
1621 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1623 fix_new_exp (frag_now
, where
+ 2, 2,
1624 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1628 case 2: /* Single-operand mostly instr. */
1629 if (opcode
->insn_opnumb
== 0)
1631 /* reti instruction. */
1632 frag
= frag_more (2);
1633 bfd_putl16 ((bfd_vma
) bin
, frag
);
1634 dwarf2_emit_insn (2);
1638 line
= extract_operand (line
, l1
, sizeof (l1
));
1639 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1641 break; /* Error in operand. */
1643 bin
|= op1
.reg
| (op1
.am
<< 4);
1645 frag
= frag_more (2 * __is
);
1646 where
= frag
- frag_now
->fr_literal
;
1647 bfd_putl16 ((bfd_vma
) bin
, frag
);
1648 dwarf2_emit_insn (2 * __is
);
1650 if (op1
.mode
== OP_EXP
)
1652 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1654 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1655 fix_new_exp (frag_now
, where
+ 2, 2,
1656 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1658 fix_new_exp (frag_now
, where
+ 2, 2,
1659 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1663 case 3: /* Conditional jumps instructions. */
1664 line
= extract_operand (line
, l1
, sizeof (l1
));
1665 /* l1 is a label. */
1674 parse_exp (m
, &exp
);
1675 frag
= frag_more (2); /* Instr size is 1 word. */
1677 /* In order to handle something like:
1681 jz 4 ; skip next 4 bytes
1684 nop ; will jump here if r5 positive or zero
1686 jCOND -n ;assumes jump n bytes backward:
1696 jCOND $n ; jump from PC in either direction. */
1698 if (exp
.X_op
== O_constant
)
1700 int x
= exp
.X_add_number
;
1704 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1708 if ((*l1
== '$' && x
> 0) || x
< 0)
1713 if (x
> 512 || x
< -511)
1715 as_bad (_("Wrong displacement %d"), x
<< 1);
1720 bfd_putl16 ((bfd_vma
) bin
, frag
);
1722 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1724 where
= frag
- frag_now
->fr_literal
;
1725 fix_new_exp (frag_now
, where
, 2,
1726 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1728 bfd_putl16 ((bfd_vma
) bin
, frag
);
1730 else if (*l1
== '$')
1732 as_bad (_("instruction requires label sans '$'"));
1737 ("instruction requires label or value in range -511:512"));
1739 dwarf2_emit_insn (2 * __is
);
1744 as_bad (_("instruction requires label"));
1749 case 4: /* Extended jumps. */
1750 if (!msp430_enable_polys
)
1752 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1756 line
= extract_operand (line
, l1
, sizeof (l1
));
1762 /* Ignore absolute addressing. make it PC relative anyway. */
1763 if (*m
== '#' || *m
== '$')
1766 parse_exp (m
, & exp
);
1767 if (exp
.X_op
== O_symbol
)
1769 /* Relaxation required. */
1770 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1772 /* The parameter to dwarf2_emit_insn is actually the offset to the start
1773 of the insn from the fix piece of instruction that was emitted.
1774 Since next fragments may have variable size we tie debug info
1775 to the beginning of the instruction. */
1776 frag
= frag_more (8);
1777 dwarf2_emit_insn (0);
1778 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1779 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1780 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1782 0, /* Offset is zero if jump dist less than 1K. */
1788 as_bad (_("instruction requires label"));
1791 case 5: /* Emulated extended branches. */
1792 if (!msp430_enable_polys
)
1794 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1797 line
= extract_operand (line
, l1
, sizeof (l1
));
1803 /* Ignore absolute addressing. make it PC relative anyway. */
1804 if (*m
== '#' || *m
== '$')
1807 parse_exp (m
, & exp
);
1808 if (exp
.X_op
== O_symbol
)
1810 /* Relaxation required. */
1811 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1813 frag
= frag_more (8);
1814 dwarf2_emit_insn (0);
1815 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1816 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1818 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1819 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1821 0, /* Offset is zero if jump dist less than 1K. */
1827 as_bad (_("instruction requires label"));
1831 as_bad (_("Illegal instruction or not implemented opcode."));
1834 input_line_pointer
= line
;
1839 md_assemble (char * str
)
1841 struct msp430_opcode_s
* opcode
;
1845 str
= skip_space (str
); /* Skip leading spaces. */
1846 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1848 while (cmd
[i
] && i
< sizeof (cmd
))
1850 char a
= TOLOWER (cmd
[i
]);
1857 as_bad (_("can't find opcode "));
1861 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1865 as_bad (_("unknown opcode `%s'"), cmd
);
1870 char *__t
= input_line_pointer
;
1872 msp430_operands (opcode
, str
);
1873 input_line_pointer
= __t
;
1877 /* GAS will call this function for each section at the end of the assembly,
1878 to permit the CPU backend to adjust the alignment of a section. */
1881 md_section_align (asection
* seg
, valueT addr
)
1883 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1885 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1888 /* If you define this macro, it should return the offset between the
1889 address of a PC relative fixup and the position from which the PC
1890 relative adjustment should be made. On many processors, the base
1891 of a PC relative instruction is the next instruction, so this
1892 macro would return the length of an instruction. */
1895 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1897 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1898 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1899 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1902 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1905 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1906 Now it handles the situation when relocations
1907 have to be passed to linker. */
1909 msp430_force_relocation_local(fixS
*fixp
)
1911 if (msp430_enable_polys
1912 && !msp430_enable_relax
)
1915 return (!fixp
->fx_pcrel
1916 || generic_force_reloc(fixp
));
1920 /* GAS will call this for each fixup. It should store the correct
1921 value in the object file. */
1923 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1925 unsigned char * where
;
1929 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1934 else if (fixp
->fx_pcrel
)
1936 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1938 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1940 /* FIXME: We can appear here only in case if we perform a pc
1941 relative jump to the label which is i) global, ii) locally
1942 defined or this is a jump to an absolute symbol.
1943 If this is an absolute symbol -- everything is OK.
1944 If this is a global label, we've got a symbol value defined
1946 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1947 from this section start
1948 2. *valuep will contain the real offset from jump insn to the
1950 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1951 will be incorrect. Therefore remove s_get_value. */
1952 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1960 value
= fixp
->fx_offset
;
1962 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1964 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1966 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1971 /* We don't actually support subtracting a symbol. */
1972 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1973 _("expression too complex"));
1978 fixp
->fx_no_overflow
= 1;
1980 /* if polymorphs are enabled and relax disabled.
1981 do not kill any relocs and pass them to linker. */
1982 if (msp430_enable_polys
1983 && !msp430_enable_relax
)
1985 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
1986 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
1987 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
1994 /* Fetch the instruction, insert the fully resolved operand
1995 value, and stuff the instruction back again. */
1997 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
1999 insn
= bfd_getl16 (where
);
2001 switch (fixp
->fx_r_type
)
2003 case BFD_RELOC_MSP430_10_PCREL
:
2005 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2006 _("odd address operand: %ld"), value
);
2008 /* Jumps are in words. */
2010 --value
; /* Correct PC. */
2012 if (value
< -512 || value
> 511)
2013 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2014 _("operand out of range: %ld"), value
);
2016 value
&= 0x3ff; /* get rid of extended sign */
2017 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
2020 case BFD_RELOC_MSP430_RL_PCREL
:
2021 case BFD_RELOC_MSP430_16_PCREL
:
2023 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2024 _("odd address operand: %ld"), value
);
2026 /* Nothing to be corrected here. */
2027 if (value
< -32768 || value
> 65536)
2028 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2029 _("operand out of range: %ld"), value
);
2031 value
&= 0xffff; /* Get rid of extended sign. */
2032 bfd_putl16 ((bfd_vma
) value
, where
);
2035 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
2036 /* Nothing to be corrected here. */
2037 if (value
< -32768 || value
> 65536)
2038 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2039 _("operand out of range: %ld"), value
);
2041 value
&= 0xffff; /* Get rid of extended sign. */
2042 bfd_putl16 ((bfd_vma
) value
, where
);
2046 bfd_putl16 ((bfd_vma
) value
, where
);
2049 case BFD_RELOC_MSP430_16
:
2051 case BFD_RELOC_MSP430_16_BYTE
:
2053 bfd_putl16 ((bfd_vma
) value
, where
);
2057 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2058 fixp
->fx_line
, fixp
->fx_r_type
);
2064 fixp
->fx_addnumber
= value
;
2068 /* GAS will call this to generate a reloc, passing the resulting reloc
2069 to `bfd_install_relocation'. This currently works poorly, as
2070 `bfd_install_relocation' often does the wrong thing, and instances of
2071 `tc_gen_reloc' have been written to work around the problems, which
2072 in turns makes it difficult to fix `bfd_install_relocation'. */
2074 /* If while processing a fixup, a reloc really needs to be created
2075 then it is done here. */
2078 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
2082 reloc
= xmalloc (sizeof (arelent
));
2084 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2085 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2087 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2088 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2089 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2091 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2092 _("reloc %d not supported by object file format"),
2093 (int) fixp
->fx_r_type
);
2097 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
2098 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2099 reloc
->address
= fixp
->fx_offset
;
2101 reloc
->addend
= fixp
->fx_offset
;
2107 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2108 asection
* segment_type ATTRIBUTE_UNUSED
)
2110 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2112 /* This is a jump -> pcrel mode. Nothing to do much here.
2113 Return value == 2. */
2115 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2117 else if (fragP
->fr_symbol
)
2119 /* Its got a segment, but its not ours. Even if fr_symbol is in
2120 an absolute segment, we don't know a displacement until we link
2121 object files. So it will always be long. This also applies to
2122 labels in a subsegment of current. Liker may relax it to short
2123 jump later. Return value == 8. */
2125 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2129 /* We know the abs value. may be it is a jump to fixed address.
2130 Impossible in our case, cause all constants already handled. */
2132 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2135 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2139 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2140 asection
* sec ATTRIBUTE_UNUSED
,
2146 struct rcodes_s
* cc
= NULL
;
2147 struct hcodes_s
* hc
= NULL
;
2149 switch (fragP
->fr_subtype
)
2151 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2152 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2153 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2154 /* We do not have to convert anything here.
2155 Just apply a fix. */
2156 rela
= BFD_RELOC_MSP430_10_PCREL
;
2159 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2160 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2161 /* Convert uncond branch jmp lab -> br lab. */
2162 cc
= & msp430_rcodes
[7];
2163 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2164 bfd_putl16 (cc
->lop0
, where
);
2165 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2169 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2170 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2172 /* Other simple branches. */
2173 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2176 /* Find actual instruction. */
2177 for (i
= 0; i
< 7 && !cc
; i
++)
2178 if (msp430_rcodes
[i
].sop
== insn
)
2179 cc
= & msp430_rcodes
[i
];
2180 if (!cc
|| !cc
->name
)
2181 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2182 __FUNCTION__
, (long) insn
);
2183 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2184 bfd_putl16 (cc
->lop0
, where
);
2185 bfd_putl16 (cc
->lop1
, where
+ 2);
2186 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2191 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2192 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2193 cc
= & msp430_rcodes
[6];
2194 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2195 bfd_putl16 (cc
->lop0
, where
);
2196 bfd_putl16 (cc
->lop1
, where
+ 2);
2197 bfd_putl16 (cc
->lop2
, where
+ 4);
2198 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2202 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2204 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2207 for (i
= 0; i
< 4 && !hc
; i
++)
2208 if (msp430_hcodes
[i
].op1
== insn
)
2209 hc
= &msp430_hcodes
[i
];
2210 if (!hc
|| !hc
->name
)
2211 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2212 __FUNCTION__
, (long) insn
);
2213 rela
= BFD_RELOC_MSP430_10_PCREL
;
2214 /* Apply a fix for a first label if necessary.
2215 another fix will be applied to the next word of insn anyway. */
2217 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2218 fragP
->fr_offset
, TRUE
, rela
);
2224 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2225 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2227 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2230 for (i
= 0; i
< 4 && !hc
; i
++)
2231 if (msp430_hcodes
[i
].op1
== insn
)
2232 hc
= & msp430_hcodes
[i
];
2233 if (!hc
|| !hc
->name
)
2234 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2235 __FUNCTION__
, (long) insn
);
2236 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2237 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2238 bfd_putl16 (hc
->lop0
, where
);
2239 bfd_putl16 (hc
->lop1
, where
+ 2);
2240 bfd_putl16 (hc
->lop2
, where
+ 4);
2246 as_fatal (_("internal inconsistency problem in %s: %lx"),
2247 __FUNCTION__
, (long) fragP
->fr_subtype
);
2251 /* Now apply fix. */
2252 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2253 fragP
->fr_offset
, TRUE
, rela
);
2254 /* Just fixed 2 bytes. */
2258 /* Relax fragment. Mostly stolen from hc11 and mcore
2259 which arches I think I know. */
2262 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2263 long stretch ATTRIBUTE_UNUSED
)
2268 const relax_typeS
*this_type
;
2269 const relax_typeS
*start_type
;
2270 relax_substateT next_state
;
2271 relax_substateT this_state
;
2272 const relax_typeS
*table
= md_relax_table
;
2274 /* Nothing to be done if the frag has already max size. */
2275 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2276 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2279 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2281 symbolP
= fragP
->fr_symbol
;
2282 if (symbol_resolved_p (symbolP
))
2283 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2285 /* We know the offset. calculate a distance. */
2286 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2289 if (!msp430_enable_relax
)
2291 /* Relaxation is not enabled. So, make all jump as long ones
2292 by setting 'aim' to quite high value. */
2296 this_state
= fragP
->fr_subtype
;
2297 start_type
= this_type
= table
+ this_state
;
2301 /* Look backwards. */
2302 for (next_state
= this_type
->rlx_more
; next_state
;)
2303 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
2307 /* Grow to next state. */
2308 this_state
= next_state
;
2309 this_type
= table
+ this_state
;
2310 next_state
= this_type
->rlx_more
;
2315 /* Look forwards. */
2316 for (next_state
= this_type
->rlx_more
; next_state
;)
2317 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
2321 /* Grow to next state. */
2322 this_state
= next_state
;
2323 this_type
= table
+ this_state
;
2324 next_state
= this_type
->rlx_more
;
2328 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2330 fragP
->fr_subtype
= this_state
;