1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002, 2003, 2004, 2005, 2006 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 2, 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
28 #include "opcode/msp430.h"
29 #include "safe-ctype.h"
30 #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' wiys thin +-1024 bytes range then linker
59 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
62 The workaround is the following:
63 1. Declare global var enable_polymorphs which set to 1 via option -mP.
64 2. Declare global var enable_relax which set to 1 via option -mQ.
66 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
67 do not delete any relocs and leave them for linker.
69 If relax is enabled, relax at assembly time and kill relocs as necessary.
72 int msp430_enable_relax
;
73 int msp430_enable_polys
;
75 /* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
86 lt < jl jge +4; br lab
87 ltu < jlo lhs +4; br lab
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
99 'u' means unsigned compares
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
109 int index
; /* Corresponding insn_opnumb. */
110 int sop
; /* Opcode if jump length is short. */
111 long lpos
; /* Label position. */
112 long lop0
; /* Opcode 1 _word_ (16 bits). */
113 long lop1
; /* Opcode second word. */
114 long lop2
; /* Opcode third word. */
117 #define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
120 static struct rcodes_s msp430_rcodes
[] =
122 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
135 /* More difficult than above and they have format 5.
138 =================================================================
139 gt > jeq +2; jge label jeq +6; jl +4; br label
140 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
141 leu <= jeq label; jlo label jeq +2; jhs +4; br label
142 le <= jeq label; jl label jeq +2; jge +4; br label
143 ================================================================= */
148 int index
; /* Corresponding insn_opnumb. */
149 int tlab
; /* Number of labels in short mode. */
150 int op0
; /* Opcode for first word of short jump. */
151 int op1
; /* Opcode for second word of short jump. */
152 int lop0
; /* Opcodes for long jump mode. */
157 static struct hcodes_s msp430_hcodes
[] =
159 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
160 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
161 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
162 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
166 const char comment_chars
[] = ";";
167 const char line_comment_chars
[] = "#";
168 const char line_separator_chars
[] = "|";
169 const char EXP_CHARS
[] = "eE";
170 const char FLT_CHARS
[] = "dD";
172 /* Handle long expressions. */
173 extern LITTLENUM_TYPE generic_bignum
[];
175 static struct hash_control
*msp430_hash
;
178 #define STATE_UNCOND_BRANCH 1 /* jump */
179 #define STATE_NOOV_BRANCH 3 /* bltn */
180 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
181 #define STATE_EMUL_BRANCH 4
190 #define STATE_BITS10 1 /* wild guess. short jump */
191 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
192 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
194 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
195 #define RELAX_STATE(s) ((s) & 3)
196 #define RELAX_LEN(s) ((s) >> 2)
197 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
199 relax_typeS md_relax_table
[] =
207 /* Unconditional jump. */
209 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
210 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
211 {1, 1, CUBL
, 0}, /* state undef */
213 /* Simple branches. */
215 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
216 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
219 /* blt no overflow branch. */
221 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
222 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
225 /* Emulated branches. */
227 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
228 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
233 #define MAX_OP_LEN 256
242 #define MSP430_ISA_11 11
243 #define MSP430_ISA_110 110
244 #define MSP430_ISA_12 12
245 #define MSP430_ISA_13 13
246 #define MSP430_ISA_14 14
247 #define MSP430_ISA_15 15
248 #define MSP430_ISA_16 16
249 #define MSP430_ISA_21 21
250 #define MSP430_ISA_31 31
251 #define MSP430_ISA_32 32
252 #define MSP430_ISA_33 33
253 #define MSP430_ISA_41 41
254 #define MSP430_ISA_42 42
255 #define MSP430_ISA_43 43
256 #define MSP430_ISA_44 44
258 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
259 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
261 static struct mcu_type_s mcu_types
[] =
263 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
264 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
265 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
266 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
267 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
268 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
269 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
270 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
271 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
273 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
274 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
275 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
276 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
278 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
279 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
280 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
281 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
282 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
283 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
284 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
286 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
287 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
288 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
289 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
290 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
291 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
292 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
293 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
294 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
296 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
297 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
298 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
299 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
301 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
302 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
303 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
304 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
305 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
306 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
307 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
308 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
309 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
311 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
312 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
313 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
314 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
316 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
317 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
318 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
320 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
321 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
322 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
324 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
325 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
326 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
328 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
329 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
330 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
331 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
332 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
333 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
339 static struct mcu_type_s default_mcu
=
340 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
342 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
344 /* Profiling capability:
345 It is a performance hit to use gcc's profiling approach for this tiny target.
346 Even more -- jtag hardware facility does not perform any profiling functions.
347 However we've got gdb's built-in simulator where we can do anything.
348 Therefore my suggestion is:
350 We define new section ".profiler" which holds all profiling information.
351 We define new pseudo operation .profiler which will instruct assembler to
352 add new profile entry to the object file. Profile should take place at the
357 .profiler flags,function_to_profile [, cycle_corrector, extra]
359 where 'flags' is a combination of the following chars:
362 i - function is in Init section
363 f - function is in Fini section
365 c - libC standard call
366 d - stack value Demand (saved at run-time in simulator)
367 I - Interrupt service routine
372 j - long Jump/ sjlj unwind
373 a - an Arbitrary code fragment
374 t - exTra parameter saved (constant value like frame size)
375 '""' optional: "sil" == sil
377 function_to_profile - function's address
378 cycle_corrector - a value which should be added to the cycle
379 counter, zero if omitted
380 extra - some extra parameter, zero if omitted.
383 ------------------------------
387 .LFrameOffset_fxx=0x08
388 .profiler "scdP", fxx ; function entry.
389 ; we also demand stack value to be displayed
394 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
395 ; (this is a prologue end)
396 ; note, that spare var filled with the farme size
399 .profiler cdE,fxx ; check stack
404 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
405 ret ; cause 'ret' insn takes 3 cycles
406 -------------------------------
408 This profiling approach does not produce any overhead and
410 So, even profiled code can be uploaded to the MCU. */
411 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
412 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
413 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
414 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
415 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
416 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
417 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
418 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
419 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
420 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
421 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
422 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
423 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
424 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
425 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
426 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
439 for (; x
; x
= x
>> 1)
446 /* Parse ordinary expression. */
449 parse_exp (char * s
, expressionS
* op
)
451 input_line_pointer
= s
;
453 if (op
->X_op
== O_absent
)
454 as_bad (_("missing operand"));
455 return input_line_pointer
;
459 /* Delete spaces from s: X ( r 1 2) => X(r12). */
462 del_spaces (char * s
)
470 while (ISSPACE (*m
) && *m
)
472 memmove (s
, m
, strlen (m
) + 1);
480 skip_space (char * s
)
487 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
490 extract_operand (char * from
, char * to
, int limit
)
494 /* Drop leading whitespace. */
495 from
= skip_space (from
);
497 while (size
< limit
&& *from
)
499 *(to
+ size
) = *from
;
500 if (*from
== ',' || *from
== ';' || *from
== '\n')
515 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
532 s
= input_line_pointer
;
533 end
= input_line_pointer
;
535 while (*end
&& *end
!= '\n')
538 while (*s
&& *s
!= '\n')
549 as_bad (_(".profiler pseudo requires at least two operands."));
550 input_line_pointer
= end
;
554 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
563 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
566 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
569 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
572 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
575 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
578 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
581 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
584 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
587 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
590 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
593 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
596 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
599 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
602 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
605 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
608 as_warn (_("unknown profiling flag - ignored."));
615 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
616 | MSP430_PROFILER_FLAG_EXIT
))
617 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
618 | MSP430_PROFILER_FLAG_PROLEND
619 | MSP430_PROFILER_FLAG_EPISTART
620 | MSP430_PROFILER_FLAG_EPIEND
))
621 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
622 | MSP430_PROFILER_FLAG_FINISECT
))))
624 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
625 input_line_pointer
= end
;
629 /* Generate temp symbol which denotes current location. */
630 if (now_seg
== absolute_section
) /* Paranoja ? */
632 exp1
.X_op
= O_constant
;
633 exp1
.X_add_number
= abs_section_offset
;
634 as_warn (_("profiling in absolute section? Hm..."));
638 exp1
.X_op
= O_symbol
;
639 exp1
.X_add_symbol
= symbol_temp_new_now ();
640 exp1
.X_add_number
= 0;
643 /* Generate a symbol which holds flags value. */
644 exp
.X_op
= O_constant
;
645 exp
.X_add_number
= p_flags
;
647 /* Save current section. */
651 /* Now go to .profiler section. */
652 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
655 emit_expr (& exp
, 2);
657 /* Save label value. */
658 emit_expr (& exp1
, 2);
662 /* Now get profiling info. */
663 halt
= extract_operand (input_line_pointer
, str
, 1024);
664 /* Process like ".word xxx" directive. */
665 parse_exp (str
, & exp
);
666 emit_expr (& exp
, 2);
667 input_line_pointer
= halt
;
670 /* Fill the rest with zeros. */
671 exp
.X_op
= O_constant
;
672 exp
.X_add_number
= 0;
674 emit_expr (& exp
, 2);
676 /* Return to current section. */
677 subseg_set (seg
, subseg
);
681 extract_word (char * from
, char * to
, int limit
)
687 /* Drop leading whitespace. */
688 from
= skip_space (from
);
691 /* Find the op code end. */
692 for (op_start
= op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
694 to
[size
++] = *op_end
++;
695 if (size
+ 1 >= limit
)
703 #define OPTION_MMCU 'm'
704 #define OPTION_RELAX 'Q'
705 #define OPTION_POLYMORPHS 'P'
708 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
710 char *str
= (char *) alloca (32); /* 32 for good measure. */
712 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
714 md_parse_option (OPTION_MMCU
, str
);
715 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
719 show_mcu_list (FILE * stream
)
723 fprintf (stream
, _("Known MCU names:\n"));
725 for (i
= 0; mcu_types
[i
].name
; i
++)
726 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
728 fprintf (stream
, "\n");
732 md_parse_option (int c
, char * arg
)
739 for (i
= 0; mcu_types
[i
].name
; ++i
)
740 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
743 if (!mcu_types
[i
].name
)
745 show_mcu_list (stderr
);
746 as_fatal (_("unknown MCU: %s\n"), arg
);
749 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
750 msp430_mcu
= &mcu_types
[i
];
752 as_fatal (_("redefinition of mcu type %s' to %s'"),
753 msp430_mcu
->name
, mcu_types
[i
].name
);
758 msp430_enable_relax
= 1;
762 case OPTION_POLYMORPHS
:
763 msp430_enable_polys
= 1;
772 const pseudo_typeS md_pseudo_table
[] =
774 {"arch", msp430_set_arch
, 0},
775 {"profiler", msp430_profiler
, 0},
779 const char *md_shortopts
= "m:";
781 struct option md_longopts
[] =
783 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
784 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
785 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
786 {NULL
, no_argument
, NULL
, 0}
789 size_t md_longopts_size
= sizeof (md_longopts
);
792 md_show_usage (FILE * stream
)
795 _("MSP430 options:\n"
796 " -mmcu=[msp430-name] select microcontroller type\n"
797 " msp430x110 msp430x112\n"
798 " msp430x1101 msp430x1111\n"
799 " msp430x1121 msp430x1122 msp430x1132\n"
800 " msp430x122 msp430x123\n"
801 " msp430x1222 msp430x1232\n"
802 " msp430x133 msp430x135\n"
803 " msp430x1331 msp430x1351\n"
804 " msp430x147 msp430x148 msp430x149\n"
805 " msp430x155 msp430x156 msp430x157\n"
806 " msp430x167 msp430x168 msp430x169\n"
807 " msp430x1610 msp430x1611 msp430x1612\n"
808 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
809 " msp430x323 msp430x325\n"
810 " msp430x336 msp430x337\n"
811 " msp430x412 msp430x413 msp430x415 msp430x417\n"
812 " msp430xE423 msp430xE425 msp430E427\n"
813 " msp430xW423 msp430xW425 msp430W427\n"
814 " msp430xG437 msp430xG438 msp430G439\n"
815 " msp430x435 msp430x436 msp430x437\n"
816 " msp430x447 msp430x448 msp430x449\n"));
818 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
819 " -mP - enable polymorph instructions\n"));
821 show_mcu_list (stream
);
825 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
831 extract_cmd (char * from
, char * to
, int limit
)
835 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
837 *(to
+ size
) = *from
;
847 /* Turn a string in input_line_pointer into a floating point constant
848 of type TYPE, and store the appropriate bytes in *LITP. The number
849 of LITTLENUMS emitted is stored in *SIZEP. An error message is
850 returned, or NULL on OK. */
853 md_atof (int type
, char * litP
, int * sizeP
)
856 LITTLENUM_TYPE words
[4];
857 LITTLENUM_TYPE
*wordP
;
870 return _("bad call to md_atof");
873 t
= atof_ieee (input_line_pointer
, type
, words
);
875 input_line_pointer
= t
;
877 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
879 /* This loop outputs the LITTLENUMs in REVERSE order. */
880 for (wordP
= words
+ prec
- 1; prec
--;)
882 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
883 litP
+= sizeof (LITTLENUM_TYPE
);
892 struct msp430_opcode_s
* opcode
;
893 msp430_hash
= hash_new ();
895 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
896 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
898 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
904 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
906 if (strlen (t
) > 2 && *(t
+ 2) != '+')
911 if ((*t
< '0' || *t
> '9') && *t
!= '+')
924 msp430_srcoperand (struct msp430_operand_s
* op
,
925 char * l
, int bin
, int * imm_op
)
929 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
936 /* Check if there is:
937 llo(x) - least significant 16 bits, x &= 0xffff
938 lhi(x) - x = (x >> 16) & 0xffff,
939 hlo(x) - x = (x >> 32) & 0xffff,
940 hhi(x) - x = (x >> 48) & 0xffff
941 The value _MUST_ be constant expression: #hlo(1231231231). */
945 if (strncasecmp (h
, "#llo(", 5) == 0)
950 else if (strncasecmp (h
, "#lhi(", 5) == 0)
955 else if (strncasecmp (h
, "#hlo(", 5) == 0)
960 else if (strncasecmp (h
, "#hhi(", 5) == 0)
965 else if (strncasecmp (h
, "#lo(", 4) == 0)
970 else if (strncasecmp (h
, "#hi(", 4) == 0)
976 op
->reg
= 0; /* Reg PC. */
978 op
->ol
= 1; /* Immediate will follow an instruction. */
982 parse_exp (__tl
, &(op
->exp
));
983 if (op
->exp
.X_op
== O_constant
)
985 int x
= op
->exp
.X_add_number
;
990 op
->exp
.X_add_number
= x
;
992 else if (vshift
== 1)
994 x
= (x
>> 16) & 0xffff;
995 op
->exp
.X_add_number
= x
;
1000 op
->exp
.X_add_number
= -1;
1002 op
->exp
.X_add_number
= 0; /* Nothing left. */
1003 x
= op
->exp
.X_add_number
;
1006 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1008 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1012 /* Now check constants. */
1013 /* Substitute register mode with a constant generator if applicable. */
1015 x
= (short) x
; /* Extend sign. */
1047 #ifdef PUSH_1X_WORKAROUND
1050 /* Remove warning as confusing.
1051 as_warn(_("Hardware push bug workaround")); */
1064 #ifdef PUSH_1X_WORKAROUND
1067 /* Remove warning as confusing.
1068 as_warn(_("Hardware push bug workaround")); */
1080 else if (op
->exp
.X_op
== O_symbol
)
1084 else if (op
->exp
.X_op
== O_big
)
1089 op
->exp
.X_op
= O_constant
;
1090 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1091 x
= op
->exp
.X_add_number
;
1096 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1144 /* Redudant (yet) check. */
1145 else if (op
->exp
.X_op
== O_register
)
1147 (_("Registers cannot be used within immediate expression [%s]"), l
);
1149 as_bad (_("unknown operand %s"), l
);
1154 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1159 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1160 op
->am
= 1; /* mode As == 01 bin. */
1161 op
->ol
= 1; /* Immediate value followed by instruction. */
1163 parse_exp (__tl
, &(op
->exp
));
1165 if (op
->exp
.X_op
== O_constant
)
1167 int x
= op
->exp
.X_add_number
;
1169 if (x
> 65535 || x
< -32768)
1171 as_bad (_("value out of range: %d"), x
);
1175 else if (op
->exp
.X_op
== O_symbol
)
1179 /* Redudant (yet) check. */
1180 if (op
->exp
.X_op
== O_register
)
1182 (_("Registers cannot be used within absolute expression [%s]"), l
);
1184 as_bad (_("unknown expression in operand %s"), l
);
1190 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1194 char *m
= strchr (l
, '+');
1198 as_bad (_("unknown addressing mode %s"), l
);
1203 if (*t
!= 'r' && *t
!= 'R')
1205 as_bad (_("unknown addressing mode %s"), l
);
1209 t
++; /* Points to the reg value. */
1213 as_bad (_("Bad register name r%s"), t
);
1221 *m
= 0; /* strip '+' */
1223 if (op
->reg
< 0 || op
->reg
> 15)
1225 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1232 /* Check if register indexed X(Rn). */
1235 char *h
= strrchr (l
, '(');
1236 char *m
= strrchr (l
, ')');
1245 as_bad (_("')' required"));
1252 /* Extract a register. */
1253 t
++; /* Advance pointer. */
1255 if (*t
!= 'r' && *t
!= 'R')
1258 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1265 if (op
->reg
> 9 || op
->reg
< 0)
1267 as_bad (_("unknown operator (r%s substituded as a register name"),
1274 op
->reg
= op
->reg
* 10;
1275 op
->reg
+= *t
- '0';
1279 as_bad (_("unknown operator %s"), l
);
1284 as_bad (_("r2 should not be used in indexed addressing mode"));
1288 if (*(t
+ 1) != ')')
1290 as_bad (_("unknown operator %s"), l
);
1295 /* Extract constant. */
1299 parse_exp (__tl
, &(op
->exp
));
1300 if (op
->exp
.X_op
== O_constant
)
1302 int x
= op
->exp
.X_add_number
;
1304 if (x
> 65535 || x
< -32768)
1306 as_bad (_("value out of range: %d"), x
);
1318 else if (op
->exp
.X_op
== O_symbol
)
1322 /* Redudant (yet) check. */
1323 if (op
->exp
.X_op
== O_register
)
1325 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1327 as_bad (_("unknown expression in operand %s"), l
);
1335 /* Register mode 'mov r1,r2'. */
1340 /* Operand should be a register. */
1341 if (*t
== 'r' || *t
== 'R')
1343 int x
= atoi (t
+ 1);
1345 if (check_reg (t
+ 1))
1348 if (x
< 0 || x
> 15)
1349 break; /* Symbolic mode. */
1360 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1364 op
->reg
= 0; /* PC relative... be careful. */
1368 parse_exp (__tl
, &(op
->exp
));
1374 as_bad (_("unknown addressing mode for operand %s"), l
);
1380 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1383 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1395 parse_exp (__tl
, &(op
->exp
));
1397 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1399 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1409 ("this addressing mode is not applicable for destination operand"));
1416 /* Parse instruction operands.
1417 Return binary opcode. */
1420 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1422 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1424 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1427 struct msp430_operand_s op1
, op2
;
1429 static short ZEROS
= 0;
1430 int byte_op
, imm_op
;
1432 /* Opcode is the one from opcodes table
1433 line contains something like
1438 /* Check if byte or word operation. */
1439 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1441 bin
|= BYTE_OPERATION
;
1448 while (! ISSPACE (*line
) && *line
)
1451 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1453 as_bad (_("instruction %s requires %d operand(s)"),
1454 opcode
->name
, opcode
->insn_opnumb
);
1458 memset (l1
, 0, sizeof (l1
));
1459 memset (l2
, 0, sizeof (l2
));
1460 memset (&op1
, 0, sizeof (op1
));
1461 memset (&op2
, 0, sizeof (op2
));
1465 switch (opcode
->fmt
)
1467 case 0: /* Emulated. */
1468 switch (opcode
->insn_opnumb
)
1471 /* Set/clear bits instructions. */
1473 frag
= frag_more (__is
);
1474 bfd_putl16 ((bfd_vma
) bin
, frag
);
1475 dwarf2_emit_insn (__is
);
1478 /* Something which works with destination operand. */
1479 line
= extract_operand (line
, l1
, sizeof (l1
));
1480 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1484 bin
|= (op1
.reg
| (op1
.am
<< 7));
1486 frag
= frag_more (2 * __is
);
1487 where
= frag
- frag_now
->fr_literal
;
1488 bfd_putl16 ((bfd_vma
) bin
, frag
);
1489 dwarf2_emit_insn (2 * __is
);
1491 if (op1
.mode
== OP_EXP
)
1494 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1497 fix_new_exp (frag_now
, where
, 2,
1498 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1500 fix_new_exp (frag_now
, where
, 2,
1501 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1507 /* Shift instruction. */
1508 line
= extract_operand (line
, l1
, sizeof (l1
));
1509 strncpy (l2
, l1
, sizeof (l2
));
1510 l2
[sizeof (l2
) - 1] = '\0';
1511 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1512 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1515 break; /* An error occurred. All warnings were done before. */
1517 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1519 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1520 frag
= frag_more (2 * __is
);
1521 where
= frag
- frag_now
->fr_literal
;
1522 bfd_putl16 ((bfd_vma
) bin
, frag
);
1523 dwarf2_emit_insn (2 * __is
);
1525 if (op1
.mode
== OP_EXP
)
1527 where
+= 2; /* Advance 'where' as we do not know _where_. */
1528 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1530 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1531 fix_new_exp (frag_now
, where
, 2,
1532 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1534 fix_new_exp (frag_now
, where
, 2,
1535 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1538 if (op2
.mode
== OP_EXP
)
1541 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1543 if (op2
.reg
) /* Not PC relative. */
1544 fix_new_exp (frag_now
, where
+ 2, 2,
1545 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1547 fix_new_exp (frag_now
, where
+ 2, 2,
1548 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1553 /* Branch instruction => mov dst, r0. */
1554 line
= extract_operand (line
, l1
, sizeof (l1
));
1556 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1563 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1565 frag
= frag_more (2 * __is
);
1566 where
= frag
- frag_now
->fr_literal
;
1567 bfd_putl16 ((bfd_vma
) bin
, frag
);
1568 dwarf2_emit_insn (2 * __is
);
1570 if (op1
.mode
== OP_EXP
)
1573 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1575 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1576 fix_new_exp (frag_now
, where
, 2,
1577 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1579 fix_new_exp (frag_now
, where
, 2,
1580 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1586 case 1: /* Format 1, double operand. */
1587 line
= extract_operand (line
, l1
, sizeof (l1
));
1588 line
= extract_operand (line
, l2
, sizeof (l2
));
1589 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1590 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1593 break; /* Error occurred. All warnings were done before. */
1595 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1597 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1598 frag
= frag_more (2 * __is
);
1599 where
= frag
- frag_now
->fr_literal
;
1600 bfd_putl16 ((bfd_vma
) bin
, frag
);
1601 dwarf2_emit_insn (2 * __is
);
1603 if (op1
.mode
== OP_EXP
)
1605 where
+= 2; /* Advance where as we do not know _where_. */
1606 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1608 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1609 fix_new_exp (frag_now
, where
, 2,
1610 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1612 fix_new_exp (frag_now
, where
, 2,
1613 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1616 if (op2
.mode
== OP_EXP
)
1619 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1621 if (op2
.reg
) /* Not PC relative. */
1622 fix_new_exp (frag_now
, where
+ 2, 2,
1623 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1625 fix_new_exp (frag_now
, where
+ 2, 2,
1626 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1630 case 2: /* Single-operand mostly instr. */
1631 if (opcode
->insn_opnumb
== 0)
1633 /* reti instruction. */
1634 frag
= frag_more (2);
1635 bfd_putl16 ((bfd_vma
) bin
, frag
);
1636 dwarf2_emit_insn (2);
1640 line
= extract_operand (line
, l1
, sizeof (l1
));
1641 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1643 break; /* Error in operand. */
1645 bin
|= op1
.reg
| (op1
.am
<< 4);
1647 frag
= frag_more (2 * __is
);
1648 where
= frag
- frag_now
->fr_literal
;
1649 bfd_putl16 ((bfd_vma
) bin
, frag
);
1650 dwarf2_emit_insn (2 * __is
);
1652 if (op1
.mode
== OP_EXP
)
1654 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1656 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1657 fix_new_exp (frag_now
, where
+ 2, 2,
1658 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1660 fix_new_exp (frag_now
, where
+ 2, 2,
1661 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1665 case 3: /* Conditional jumps instructions. */
1666 line
= extract_operand (line
, l1
, sizeof (l1
));
1667 /* l1 is a label. */
1676 parse_exp (m
, &exp
);
1677 frag
= frag_more (2); /* Instr size is 1 word. */
1679 /* In order to handle something like:
1683 jz 4 ; skip next 4 bytes
1686 nop ; will jump here if r5 positive or zero
1688 jCOND -n ;assumes jump n bytes backward:
1698 jCOND $n ; jump from PC in either direction. */
1700 if (exp
.X_op
== O_constant
)
1702 int x
= exp
.X_add_number
;
1706 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1710 if ((*l1
== '$' && x
> 0) || x
< 0)
1715 if (x
> 512 || x
< -511)
1717 as_bad (_("Wrong displacement %d"), x
<< 1);
1722 bfd_putl16 ((bfd_vma
) bin
, frag
);
1724 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1726 where
= frag
- frag_now
->fr_literal
;
1727 fix_new_exp (frag_now
, where
, 2,
1728 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1730 bfd_putl16 ((bfd_vma
) bin
, frag
);
1732 else if (*l1
== '$')
1734 as_bad (_("instruction requires label sans '$'"));
1739 ("instruction requires label or value in range -511:512"));
1741 dwarf2_emit_insn (2 * __is
);
1746 as_bad (_("instruction requires label"));
1751 case 4: /* Extended jumps. */
1752 if (!msp430_enable_polys
)
1754 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1758 line
= extract_operand (line
, l1
, sizeof (l1
));
1764 /* Ignore absolute addressing. make it PC relative anyway. */
1765 if (*m
== '#' || *m
== '$')
1768 parse_exp (m
, & exp
);
1769 if (exp
.X_op
== O_symbol
)
1771 /* Relaxation required. */
1772 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1774 /* The parameter to dwarf2_emit_insn is actually the offset to the start
1775 of the insn from the fix piece of instruction that was emitted.
1776 Since next fragments may have variable size we tie debug info
1777 to the beginning of the instruction. */
1778 frag
= frag_more (8);
1779 dwarf2_emit_insn (0);
1780 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1781 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1782 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1784 0, /* Offset is zero if jump dist less than 1K. */
1790 as_bad (_("instruction requires label"));
1793 case 5: /* Emulated extended branches. */
1794 if (!msp430_enable_polys
)
1796 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1799 line
= extract_operand (line
, l1
, sizeof (l1
));
1805 /* Ignore absolute addressing. make it PC relative anyway. */
1806 if (*m
== '#' || *m
== '$')
1809 parse_exp (m
, & exp
);
1810 if (exp
.X_op
== O_symbol
)
1812 /* Relaxation required. */
1813 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1815 frag
= frag_more (8);
1816 dwarf2_emit_insn (0);
1817 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1818 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1820 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1821 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1823 0, /* Offset is zero if jump dist less than 1K. */
1829 as_bad (_("instruction requires label"));
1833 as_bad (_("Ilegal instruction or not implmented opcode."));
1836 input_line_pointer
= line
;
1841 md_assemble (char * str
)
1843 struct msp430_opcode_s
* opcode
;
1847 str
= skip_space (str
); /* Skip leading spaces. */
1848 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1850 while (cmd
[i
] && i
< sizeof (cmd
))
1852 char a
= TOLOWER (cmd
[i
]);
1859 as_bad (_("can't find opcode "));
1863 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1867 as_bad (_("unknown opcode `%s'"), cmd
);
1872 char *__t
= input_line_pointer
;
1874 msp430_operands (opcode
, str
);
1875 input_line_pointer
= __t
;
1879 /* GAS will call this function for each section at the end of the assembly,
1880 to permit the CPU backend to adjust the alignment of a section. */
1883 md_section_align (asection
* seg
, valueT addr
)
1885 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1887 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1890 /* If you define this macro, it should return the offset between the
1891 address of a PC relative fixup and the position from which the PC
1892 relative adjustment should be made. On many processors, the base
1893 of a PC relative instruction is the next instruction, so this
1894 macro would return the length of an instruction. */
1897 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1899 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1900 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1901 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1904 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1907 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1908 Now it handles the situation when relocations
1909 have to be passed to linker. */
1911 msp430_force_relocation_local(fixS
*fixp
)
1913 if (msp430_enable_polys
1914 && !msp430_enable_relax
)
1917 return (!fixp
->fx_pcrel
1919 || generic_force_reloc(fixp
));
1923 /* GAS will call this for each fixup. It should store the correct
1924 value in the object file. */
1926 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1928 unsigned char * where
;
1932 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1937 else if (fixp
->fx_pcrel
)
1939 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1941 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1943 /* FIXME: We can appear here only in case if we perform a pc
1944 relative jump to the label which is i) global, ii) locally
1945 defined or this is a jump to an absolute symbol.
1946 If this is an absolute symbol -- everything is OK.
1947 If this is a global label, we've got a symbol value defined
1949 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1950 from this section start
1951 2. *valuep will contain the real offset from jump insn to the
1953 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1954 will be incorrect. Therefore remove s_get_value. */
1955 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1963 value
= fixp
->fx_offset
;
1965 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1967 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1969 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1974 /* We don't actually support subtracting a symbol. */
1975 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1976 _("expression too complex"));
1981 fixp
->fx_no_overflow
= 1;
1983 /* if polymorphs are enabled and relax disabled.
1984 do not kill any relocs and pass them to linker. */
1985 if (msp430_enable_polys
1986 && !msp430_enable_relax
)
1988 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
1989 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
1990 fixp
->fx_done
= 1; /* it is ok to kill 'abs' reloc */
1997 /* Fetch the instruction, insert the fully resolved operand
1998 value, and stuff the instruction back again. */
2000 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2002 insn
= bfd_getl16 (where
);
2004 switch (fixp
->fx_r_type
)
2006 case BFD_RELOC_MSP430_10_PCREL
:
2008 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2009 _("odd address operand: %ld"), value
);
2011 /* Jumps are in words. */
2013 --value
; /* Correct PC. */
2015 if (value
< -512 || value
> 511)
2016 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2017 _("operand out of range: %ld"), value
);
2019 value
&= 0x3ff; /* get rid of extended sign */
2020 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
2023 case BFD_RELOC_MSP430_RL_PCREL
:
2024 case BFD_RELOC_MSP430_16_PCREL
:
2026 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2027 _("odd address operand: %ld"), value
);
2029 /* Nothing to be corrected here. */
2030 if (value
< -32768 || value
> 65536)
2031 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2032 _("operand out of range: %ld"), value
);
2034 value
&= 0xffff; /* Get rid of extended sign. */
2035 bfd_putl16 ((bfd_vma
) value
, where
);
2038 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
2039 /* Nothing to be corrected here. */
2040 if (value
< -32768 || value
> 65536)
2041 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2042 _("operand out of range: %ld"), value
);
2044 value
&= 0xffff; /* Get rid of extended sign. */
2045 bfd_putl16 ((bfd_vma
) value
, where
);
2049 bfd_putl16 ((bfd_vma
) value
, where
);
2052 case BFD_RELOC_MSP430_16
:
2054 case BFD_RELOC_MSP430_16_BYTE
:
2056 bfd_putl16 ((bfd_vma
) value
, where
);
2060 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2061 fixp
->fx_line
, fixp
->fx_r_type
);
2067 fixp
->fx_addnumber
= value
;
2071 /* GAS will call this to generate a reloc, passing the resulting reloc
2072 to `bfd_install_relocation'. This currently works poorly, as
2073 `bfd_install_relocation' often does the wrong thing, and instances of
2074 `tc_gen_reloc' have been written to work around the problems, which
2075 in turns makes it difficult to fix `bfd_install_relocation'. */
2077 /* If while processing a fixup, a reloc really needs to be created
2078 then it is done here. */
2081 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
2085 reloc
= xmalloc (sizeof (arelent
));
2087 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2088 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2090 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2091 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2092 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2094 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2095 _("reloc %d not supported by object file format"),
2096 (int) fixp
->fx_r_type
);
2100 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
2101 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2102 reloc
->address
= fixp
->fx_offset
;
2104 reloc
->addend
= fixp
->fx_offset
;
2110 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2111 asection
* segment_type ATTRIBUTE_UNUSED
)
2113 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2115 /* This is a jump -> pcrel mode. Nothing to do much here.
2116 Return value == 2. */
2118 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2120 else if (fragP
->fr_symbol
)
2122 /* Its got a segment, but its not ours. Even if fr_symbol is in
2123 an absolute segment, we dont know a displacement until we link
2124 object files. So it will always be long. This also applies to
2125 labels in a subsegment of current. Liker may relax it to short
2126 jump later. Return value == 8. */
2128 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2132 /* We know the abs value. may be it is a jump to fixed address.
2133 Impossible in our case, cause all constants already handeled. */
2135 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2138 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2142 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2143 asection
* sec ATTRIBUTE_UNUSED
,
2149 struct rcodes_s
* cc
= NULL
;
2150 struct hcodes_s
* hc
= NULL
;
2152 switch (fragP
->fr_subtype
)
2154 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2155 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2156 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2157 /* We do not have to convert anything here.
2158 Just apply a fix. */
2159 rela
= BFD_RELOC_MSP430_10_PCREL
;
2162 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2163 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2164 /* Convert uncond branch jmp lab -> br lab. */
2165 cc
= & msp430_rcodes
[7];
2166 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2167 bfd_putl16 (cc
->lop0
, where
);
2168 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2172 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2173 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2175 /* Other simple branches. */
2176 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2179 /* Find actual instruction. */
2180 for (i
= 0; i
< 7 && !cc
; i
++)
2181 if (msp430_rcodes
[i
].sop
== insn
)
2182 cc
= & msp430_rcodes
[i
];
2183 if (!cc
|| !cc
->name
)
2184 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2185 __FUNCTION__
, (long) insn
);
2186 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2187 bfd_putl16 (cc
->lop0
, where
);
2188 bfd_putl16 (cc
->lop1
, where
+ 2);
2189 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2194 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2195 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2196 cc
= & msp430_rcodes
[6];
2197 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2198 bfd_putl16 (cc
->lop0
, where
);
2199 bfd_putl16 (cc
->lop1
, where
+ 2);
2200 bfd_putl16 (cc
->lop2
, where
+ 4);
2201 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2205 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2207 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2210 for (i
= 0; i
< 4 && !hc
; i
++)
2211 if (msp430_hcodes
[i
].op1
== insn
)
2212 hc
= &msp430_hcodes
[i
];
2213 if (!hc
|| !hc
->name
)
2214 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2215 __FUNCTION__
, (long) insn
);
2216 rela
= BFD_RELOC_MSP430_10_PCREL
;
2217 /* Apply a fix for a first label if necessary.
2218 another fix will be applied to the next word of insn anyway. */
2220 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2221 fragP
->fr_offset
, TRUE
, rela
);
2227 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2228 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2230 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2233 for (i
= 0; i
< 4 && !hc
; i
++)
2234 if (msp430_hcodes
[i
].op1
== insn
)
2235 hc
= & msp430_hcodes
[i
];
2236 if (!hc
|| !hc
->name
)
2237 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2238 __FUNCTION__
, (long) insn
);
2239 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2240 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2241 bfd_putl16 (hc
->lop0
, where
);
2242 bfd_putl16 (hc
->lop1
, where
+ 2);
2243 bfd_putl16 (hc
->lop2
, where
+ 4);
2249 as_fatal (_("internal inconsistency problem in %s: %lx"),
2250 __FUNCTION__
, (long) fragP
->fr_subtype
);
2254 /* Now apply fix. */
2255 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2256 fragP
->fr_offset
, TRUE
, rela
);
2257 /* Just fixed 2 bytes. */
2261 /* Relax fragment. Mostly stolen from hc11 and mcore
2262 which arches I think I know. */
2265 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2266 long stretch ATTRIBUTE_UNUSED
)
2271 const relax_typeS
*this_type
;
2272 const relax_typeS
*start_type
;
2273 relax_substateT next_state
;
2274 relax_substateT this_state
;
2275 const relax_typeS
*table
= md_relax_table
;
2277 /* Nothing to be done if the frag has already max size. */
2278 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2279 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2282 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2284 symbolP
= fragP
->fr_symbol
;
2285 if (symbol_resolved_p (symbolP
))
2286 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2288 /* We know the offset. calculate a distance. */
2289 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2292 if (!msp430_enable_relax
)
2294 /* Relaxation is not enabled. So, make all jump as long ones
2295 by setting 'aim' to quite high value. */
2299 this_state
= fragP
->fr_subtype
;
2300 start_type
= this_type
= table
+ this_state
;
2304 /* Look backwards. */
2305 for (next_state
= this_type
->rlx_more
; next_state
;)
2306 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
2310 /* Grow to next state. */
2311 this_state
= next_state
;
2312 this_type
= table
+ this_state
;
2313 next_state
= this_type
->rlx_more
;
2318 /* Look forwards. */
2319 for (next_state
= this_type
->rlx_more
; next_state
;)
2320 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
2324 /* Grow to next state. */
2325 this_state
= next_state
;
2326 this_type
= table
+ this_state
;
2327 next_state
= this_type
->rlx_more
;
2331 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2333 fragP
->fr_subtype
= this_state
;