1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002, 2003, 2004, 2005 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. */
28 #define PUSH_1X_WORKAROUND
31 #include "opcode/msp430.h"
32 #include "safe-ctype.h"
33 #include "dwarf2dbg.h"
36 We will disable polymorphs by default because it is dangerous.
37 The potencial problem here is the following: assume we got the
42 jump subroutine ; external symbol
47 In case of assembly time relaxation we'll get:
48 0: jmp .l1 <.text +0x08> (reloc deleted)
55 If the 'subroutine' wiys thin +-1024 bytes range then linker
62 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
65 The workaround is the following:
66 1. Declare global var enable_polymorphs which set to 1 via option -mP.
67 2. Declare global var enable_relax which set to 1 via option -mQ.
69 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
70 do not delete any relocs and leave them for linker.
72 If relax is enabled, relax at assembly time and kill relocs as necessary.
75 int msp430_enable_relax
;
76 int msp430_enable_polys
;
78 /* GCC uses the some condition codes which we'll
79 implement as new polymorph instructions.
81 COND EXPL SHORT JUMP LONG JUMP
82 ===============================================
83 eq == jeq jne +4; br lab
84 ne != jne jeq +4; br lab
86 ltn honours no-overflow flag
87 ltn < jn jn +2; jmp +4; br lab
89 lt < jl jge +4; br lab
90 ltu < jlo lhs +4; br lab
96 ge >= jge jl +4; br lab
97 geu >= jhs jlo +4; br lab
98 ===============================================
100 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
101 beq,bne,blt,bltn,bltu,bge,bgeu
102 'u' means unsigned compares
104 Also, we add 'jump' instruction:
105 jump UNCOND -> jmp br lab
107 They will have fmt == 4, and insn_opnumb == number of instruction. */
112 int index
; /* Corresponding insn_opnumb. */
113 int sop
; /* Opcode if jump length is short. */
114 long lpos
; /* Label position. */
115 long lop0
; /* Opcode 1 _word_ (16 bits). */
116 long lop1
; /* Opcode second word. */
117 long lop2
; /* Opcode third word. */
120 #define MSP430_RLC(n,i,sop,o1) \
121 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
123 static struct rcodes_s msp430_rcodes
[] =
125 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
126 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
127 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
128 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
129 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
130 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
131 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
132 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
138 /* More difficult than above and they have format 5.
141 =================================================================
142 gt > jeq +2; jge label jeq +6; jl +4; br label
143 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
144 leu <= jeq label; jlo label jeq +2; jhs +4; br label
145 le <= jeq label; jl label jeq +2; jge +4; br label
146 ================================================================= */
151 int index
; /* Corresponding insn_opnumb. */
152 int tlab
; /* Number of labels in short mode. */
153 int op0
; /* Opcode for first word of short jump. */
154 int op1
; /* Opcode for second word of short jump. */
155 int lop0
; /* Opcodes for long jump mode. */
160 static struct hcodes_s msp430_hcodes
[] =
162 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
163 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
164 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
165 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
169 const char comment_chars
[] = ";";
170 const char line_comment_chars
[] = "#";
171 const char line_separator_chars
[] = "";
172 const char EXP_CHARS
[] = "eE";
173 const char FLT_CHARS
[] = "dD";
175 /* Handle long expressions. */
176 extern LITTLENUM_TYPE generic_bignum
[];
178 static struct hash_control
*msp430_hash
;
181 #define STATE_UNCOND_BRANCH 1 /* jump */
182 #define STATE_NOOV_BRANCH 3 /* bltn */
183 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
184 #define STATE_EMUL_BRANCH 4
193 #define STATE_BITS10 1 /* wild guess. short jump */
194 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
195 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
197 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
198 #define RELAX_STATE(s) ((s) & 3)
199 #define RELAX_LEN(s) ((s) >> 2)
200 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
202 relax_typeS md_relax_table
[] =
210 /* Unconditional jump. */
212 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
213 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
214 {1, 1, CUBL
, 0}, /* state undef */
216 /* Simple branches. */
218 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
219 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
222 /* blt no overflow branch. */
224 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
225 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
228 /* Emulated branches. */
230 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
231 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
236 #define MAX_OP_LEN 256
245 #define MSP430_ISA_11 11
246 #define MSP430_ISA_110 110
247 #define MSP430_ISA_12 12
248 #define MSP430_ISA_13 13
249 #define MSP430_ISA_14 14
250 #define MSP430_ISA_15 15
251 #define MSP430_ISA_16 16
252 #define MSP430_ISA_21 21
253 #define MSP430_ISA_31 31
254 #define MSP430_ISA_32 32
255 #define MSP430_ISA_33 33
256 #define MSP430_ISA_41 41
257 #define MSP430_ISA_42 42
258 #define MSP430_ISA_43 43
259 #define MSP430_ISA_44 44
261 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
262 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
264 static struct mcu_type_s mcu_types
[] =
266 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
267 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
268 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
269 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
270 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
271 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
272 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
273 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
274 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
276 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
277 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
278 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
279 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
281 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
282 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
283 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
284 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
285 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
286 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
287 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
289 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
290 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
291 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
292 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
293 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
294 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
295 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
296 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
297 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
299 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
300 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
301 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
302 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
304 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
305 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
306 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
307 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
308 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
309 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
310 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
311 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
312 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
314 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
315 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
316 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
317 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
319 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
320 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
321 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
323 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
324 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
325 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
327 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
328 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
329 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
331 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
332 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
333 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
334 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
335 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
336 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
342 static struct mcu_type_s default_mcu
=
343 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
345 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
347 /* Profiling capability:
348 It is a performance hit to use gcc's profiling approach for this tiny target.
349 Even more -- jtag hardware facility does not perform any profiling functions.
350 However we've got gdb's built-in simulator where we can do anything.
351 Therefore my suggestion is:
353 We define new section ".profiler" which holds all profiling information.
354 We define new pseudo operation .profiler which will instruct assembler to
355 add new profile entry to the object file. Profile should take place at the
360 .profiler flags,function_to_profile [, cycle_corrector, extra]
362 where 'flags' is a combination of the following chars:
365 i - function is in Init section
366 f - function is in Fini section
368 c - libC standard call
369 d - stack value Demand (saved at run-time in simulator)
370 I - Interrupt service routine
375 j - long Jump/ sjlj unwind
376 a - an Arbitrary code fragment
377 t - exTra parameter saved (constant value like frame size)
378 '""' optional: "sil" == sil
380 function_to_profile - function's address
381 cycle_corrector - a value which should be added to the cycle
382 counter, zero if omitted
383 extra - some extra parameter, zero if omitted.
386 ------------------------------
390 .LFrameOffset_fxx=0x08
391 .profiler "scdP", fxx ; function entry.
392 ; we also demand stack value to be displayed
397 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
398 ; (this is a prologue end)
399 ; note, that spare var filled with the farme size
402 .profiler cdE,fxx ; check stack
407 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
408 ret ; cause 'ret' insn takes 3 cycles
409 -------------------------------
411 This profiling approach does not produce any overhead and
413 So, even profiled code can be uploaded to the MCU. */
414 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
415 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
416 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
417 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
418 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
419 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
420 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
421 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
422 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
423 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
424 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
425 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
426 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
427 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
428 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
429 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
442 for (; x
; x
= x
>> 1)
449 /* Parse ordinary expression. */
452 parse_exp (char * s
, expressionS
* op
)
454 input_line_pointer
= s
;
456 if (op
->X_op
== O_absent
)
457 as_bad (_("missing operand"));
458 return input_line_pointer
;
462 /* Delete spaces from s: X ( r 1 2) => X(r12). */
465 del_spaces (char * s
)
473 while (ISSPACE (*m
) && *m
)
475 memmove (s
, m
, strlen (m
) + 1);
483 skip_space (char * s
)
490 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
493 extract_operand (char * from
, char * to
, int limit
)
497 /* Drop leading whitespace. */
498 from
= skip_space (from
);
500 while (size
< limit
&& *from
)
502 *(to
+ size
) = *from
;
503 if (*from
== ',' || *from
== ';' || *from
== '\n')
518 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
535 s
= input_line_pointer
;
536 end
= input_line_pointer
;
538 while (*end
&& *end
!= '\n')
541 while (*s
&& *s
!= '\n')
552 as_bad (_(".profiler pseudo requires at least two operands."));
553 input_line_pointer
= end
;
557 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
566 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
569 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
572 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
575 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
578 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
581 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
584 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
587 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
590 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
593 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
596 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
599 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
602 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
605 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
608 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
611 as_warn (_("unknown profiling flag - ignored."));
618 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
619 | MSP430_PROFILER_FLAG_EXIT
))
620 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
621 | MSP430_PROFILER_FLAG_PROLEND
622 | MSP430_PROFILER_FLAG_EPISTART
623 | MSP430_PROFILER_FLAG_EPIEND
))
624 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
625 | MSP430_PROFILER_FLAG_FINISECT
))))
627 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
628 input_line_pointer
= end
;
632 /* Generate temp symbol which denotes current location. */
633 if (now_seg
== absolute_section
) /* Paranoja ? */
635 exp1
.X_op
= O_constant
;
636 exp1
.X_add_number
= abs_section_offset
;
637 as_warn (_("profiling in absolute section? Hm..."));
641 exp1
.X_op
= O_symbol
;
642 exp1
.X_add_symbol
= symbol_temp_new_now ();
643 exp1
.X_add_number
= 0;
646 /* Generate a symbol which holds flags value. */
647 exp
.X_op
= O_constant
;
648 exp
.X_add_number
= p_flags
;
650 /* Save current section. */
654 /* Now go to .profiler section. */
655 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
658 emit_expr (& exp
, 2);
660 /* Save label value. */
661 emit_expr (& exp1
, 2);
665 /* Now get profiling info. */
666 halt
= extract_operand (input_line_pointer
, str
, 1024);
667 /* Process like ".word xxx" directive. */
668 parse_exp (str
, & exp
);
669 emit_expr (& exp
, 2);
670 input_line_pointer
= halt
;
673 /* Fill the rest with zeros. */
674 exp
.X_op
= O_constant
;
675 exp
.X_add_number
= 0;
677 emit_expr (& exp
, 2);
679 /* Return to current section. */
680 subseg_set (seg
, subseg
);
684 extract_word (char * from
, char * to
, int limit
)
690 /* Drop leading whitespace. */
691 from
= skip_space (from
);
694 /* Find the op code end. */
695 for (op_start
= op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
697 to
[size
++] = *op_end
++;
698 if (size
+ 1 >= limit
)
706 #define OPTION_MMCU 'm'
707 #define OPTION_RELAX 'Q'
708 #define OPTION_POLYMORPHS 'P'
711 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
713 char *str
= (char *) alloca (32); /* 32 for good measure. */
715 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
717 md_parse_option (OPTION_MMCU
, str
);
718 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
722 show_mcu_list (FILE * stream
)
726 fprintf (stream
, _("Known MCU names:\n"));
728 for (i
= 0; mcu_types
[i
].name
; i
++)
729 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
731 fprintf (stream
, "\n");
735 md_parse_option (int c
, char * arg
)
742 for (i
= 0; mcu_types
[i
].name
; ++i
)
743 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
746 if (!mcu_types
[i
].name
)
748 show_mcu_list (stderr
);
749 as_fatal (_("unknown MCU: %s\n"), arg
);
752 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
753 msp430_mcu
= &mcu_types
[i
];
755 as_fatal (_("redefinition of mcu type %s' to %s'"),
756 msp430_mcu
->name
, mcu_types
[i
].name
);
761 msp430_enable_relax
= 1;
765 case OPTION_POLYMORPHS
:
766 msp430_enable_polys
= 1;
775 const pseudo_typeS md_pseudo_table
[] =
777 {"arch", msp430_set_arch
, 0},
778 {"profiler", msp430_profiler
, 0},
782 const char *md_shortopts
= "m:";
784 struct option md_longopts
[] =
786 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
787 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
788 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
789 {NULL
, no_argument
, NULL
, 0}
792 size_t md_longopts_size
= sizeof (md_longopts
);
795 md_show_usage (FILE * stream
)
798 _("MSP430 options:\n"
799 " -mmcu=[msp430-name] select microcontroller type\n"
800 " msp430x110 msp430x112\n"
801 " msp430x1101 msp430x1111\n"
802 " msp430x1121 msp430x1122 msp430x1132\n"
803 " msp430x122 msp430x123\n"
804 " msp430x1222 msp430x1232\n"
805 " msp430x133 msp430x135\n"
806 " msp430x1331 msp430x1351\n"
807 " msp430x147 msp430x148 msp430x149\n"
808 " msp430x155 msp430x156 msp430x157\n"
809 " msp430x167 msp430x168 msp430x169\n"
810 " msp430x1610 msp430x1611 msp430x1612\n"
811 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
812 " msp430x323 msp430x325\n"
813 " msp430x336 msp430x337\n"
814 " msp430x412 msp430x413 msp430x415 msp430x417\n"
815 " msp430xE423 msp430xE425 msp430E427\n"
816 " msp430xW423 msp430xW425 msp430W427\n"
817 " msp430xG437 msp430xG438 msp430G439\n"
818 " msp430x435 msp430x436 msp430x437\n"
819 " msp430x447 msp430x448 msp430x449\n"));
821 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
822 " -mP - enable polymorph instructions\n"));
824 show_mcu_list (stream
);
828 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
834 extract_cmd (char * from
, char * to
, int limit
)
838 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
840 *(to
+ size
) = *from
;
850 /* Turn a string in input_line_pointer into a floating point constant
851 of type TYPE, and store the appropriate bytes in *LITP. The number
852 of LITTLENUMS emitted is stored in *SIZEP. An error message is
853 returned, or NULL on OK. */
856 md_atof (int type
, char * litP
, int * sizeP
)
859 LITTLENUM_TYPE words
[4];
860 LITTLENUM_TYPE
*wordP
;
873 return _("bad call to md_atof");
876 t
= atof_ieee (input_line_pointer
, type
, words
);
878 input_line_pointer
= t
;
880 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
882 /* This loop outputs the LITTLENUMs in REVERSE order. */
883 for (wordP
= words
+ prec
- 1; prec
--;)
885 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
886 litP
+= sizeof (LITTLENUM_TYPE
);
895 struct msp430_opcode_s
* opcode
;
896 msp430_hash
= hash_new ();
898 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
899 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
901 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
907 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
909 if (strlen (t
) > 2 && *(t
+ 2) != '+')
914 if ((*t
< '0' || *t
> '9') && *t
!= '+')
927 msp430_srcoperand (struct msp430_operand_s
* op
,
928 char * l
, int bin
, int * imm_op
)
932 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
939 /* Check if there is:
940 llo(x) - least significant 16 bits, x &= 0xffff
941 lhi(x) - x = (x >> 16) & 0xffff,
942 hlo(x) - x = (x >> 32) & 0xffff,
943 hhi(x) - x = (x >> 48) & 0xffff
944 The value _MUST_ be constant expression: #hlo(1231231231). */
948 if (strncasecmp (h
, "#llo(", 5) == 0)
953 else if (strncasecmp (h
, "#lhi(", 5) == 0)
958 else if (strncasecmp (h
, "#hlo(", 5) == 0)
963 else if (strncasecmp (h
, "#hhi(", 5) == 0)
968 else if (strncasecmp (h
, "#lo(", 4) == 0)
973 else if (strncasecmp (h
, "#hi(", 4) == 0)
979 op
->reg
= 0; /* Reg PC. */
981 op
->ol
= 1; /* Immediate will follow an instruction. */
985 parse_exp (__tl
, &(op
->exp
));
986 if (op
->exp
.X_op
== O_constant
)
988 int x
= op
->exp
.X_add_number
;
993 op
->exp
.X_add_number
= x
;
995 else if (vshift
== 1)
997 x
= (x
>> 16) & 0xffff;
998 op
->exp
.X_add_number
= x
;
1000 else if (vshift
> 1)
1003 op
->exp
.X_add_number
= -1;
1005 op
->exp
.X_add_number
= 0; /* Nothing left. */
1006 x
= op
->exp
.X_add_number
;
1009 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1011 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1015 /* Now check constants. */
1016 /* Substitute register mode with a constant generator if applicable. */
1018 x
= (short) x
; /* Extend sign. */
1050 #ifdef PUSH_1X_WORKAROUND
1053 /* Remove warning as confusing.
1054 as_warn(_("Hardware push bug workaround")); */
1067 #ifdef PUSH_1X_WORKAROUND
1070 /* Remove warning as confusing.
1071 as_warn(_("Hardware push bug workaround")); */
1083 else if (op
->exp
.X_op
== O_symbol
)
1087 else if (op
->exp
.X_op
== O_big
)
1092 op
->exp
.X_op
= O_constant
;
1093 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1094 x
= op
->exp
.X_add_number
;
1099 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1147 /* Redudant (yet) check. */
1148 else if (op
->exp
.X_op
== O_register
)
1150 (_("Registers cannot be used within immediate expression [%s]"), l
);
1152 as_bad (_("unknown operand %s"), l
);
1157 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1162 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1163 op
->am
= 1; /* mode As == 01 bin. */
1164 op
->ol
= 1; /* Immediate value followed by instruction. */
1166 parse_exp (__tl
, &(op
->exp
));
1168 if (op
->exp
.X_op
== O_constant
)
1170 int x
= op
->exp
.X_add_number
;
1172 if (x
> 65535 || x
< -32768)
1174 as_bad (_("value out of range: %d"), x
);
1178 else if (op
->exp
.X_op
== O_symbol
)
1182 /* Redudant (yet) check. */
1183 if (op
->exp
.X_op
== O_register
)
1185 (_("Registers cannot be used within absolute expression [%s]"), l
);
1187 as_bad (_("unknown expression in operand %s"), l
);
1193 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1197 char *m
= strchr (l
, '+');
1201 as_bad (_("unknown addressing mode %s"), l
);
1206 if (*t
!= 'r' && *t
!= 'R')
1208 as_bad (_("unknown addressing mode %s"), l
);
1212 t
++; /* Points to the reg value. */
1216 as_bad (_("Bad register name r%s"), t
);
1224 *m
= 0; /* strip '+' */
1226 if (op
->reg
< 0 || op
->reg
> 15)
1228 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1235 /* Check if register indexed X(Rn). */
1238 char *h
= strrchr (l
, '(');
1239 char *m
= strrchr (l
, ')');
1248 as_bad (_("')' required"));
1255 /* Extract a register. */
1256 t
++; /* Advance pointer. */
1258 if (*t
!= 'r' && *t
!= 'R')
1261 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1268 if (op
->reg
> 9 || op
->reg
< 0)
1270 as_bad (_("unknown operator (r%s substituded as a register name"),
1277 op
->reg
= op
->reg
* 10;
1278 op
->reg
+= *t
- '0';
1282 as_bad (_("unknown operator %s"), l
);
1287 as_bad (_("r2 should not be used in indexed addressing mode"));
1291 if (*(t
+ 1) != ')')
1293 as_bad (_("unknown operator %s"), l
);
1298 /* Extract constant. */
1302 parse_exp (__tl
, &(op
->exp
));
1303 if (op
->exp
.X_op
== O_constant
)
1305 int x
= op
->exp
.X_add_number
;
1307 if (x
> 65535 || x
< -32768)
1309 as_bad (_("value out of range: %d"), x
);
1321 else if (op
->exp
.X_op
== O_symbol
)
1325 /* Redudant (yet) check. */
1326 if (op
->exp
.X_op
== O_register
)
1328 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1330 as_bad (_("unknown expression in operand %s"), l
);
1338 /* Register mode 'mov r1,r2'. */
1343 /* Operand should be a register. */
1344 if (*t
== 'r' || *t
== 'R')
1346 int x
= atoi (t
+ 1);
1348 if (check_reg (t
+ 1))
1351 if (x
< 0 || x
> 15)
1352 break; /* Symbolic mode. */
1363 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1367 op
->reg
= 0; /* PC relative... be careful. */
1371 parse_exp (__tl
, &(op
->exp
));
1377 as_bad (_("unknown addressing mode for operand %s"), l
);
1383 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1386 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1398 parse_exp (__tl
, &(op
->exp
));
1400 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1402 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1412 ("this addressing mode is not applicable for destination operand"));
1419 /* Parse instruction operands.
1420 Return binary opcode. */
1423 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1425 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1427 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1430 struct msp430_operand_s op1
, op2
;
1432 static short ZEROS
= 0;
1433 int byte_op
, imm_op
;
1435 /* Opcode is the one from opcodes table
1436 line contains something like
1441 /* Check if byte or word operation. */
1442 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1444 bin
|= BYTE_OPERATION
;
1451 while (! ISSPACE (*line
) && *line
)
1454 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1456 as_bad (_("instruction %s requires %d operand(s)"),
1457 opcode
->name
, opcode
->insn_opnumb
);
1461 memset (l1
, 0, sizeof (l1
));
1462 memset (l2
, 0, sizeof (l2
));
1463 memset (&op1
, 0, sizeof (op1
));
1464 memset (&op2
, 0, sizeof (op2
));
1468 switch (opcode
->fmt
)
1470 case 0: /* Emulated. */
1471 switch (opcode
->insn_opnumb
)
1474 /* Set/clear bits instructions. */
1476 frag
= frag_more (__is
);
1477 bfd_putl16 ((bfd_vma
) bin
, frag
);
1478 dwarf2_emit_insn (__is
);
1481 /* Something which works with destination operand. */
1482 line
= extract_operand (line
, l1
, sizeof (l1
));
1483 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1487 bin
|= (op1
.reg
| (op1
.am
<< 7));
1489 frag
= frag_more (2 * __is
);
1490 where
= frag
- frag_now
->fr_literal
;
1491 bfd_putl16 ((bfd_vma
) bin
, frag
);
1492 dwarf2_emit_insn (2 * __is
);
1494 if (op1
.mode
== OP_EXP
)
1497 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1500 fix_new_exp (frag_now
, where
, 2,
1501 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1503 fix_new_exp (frag_now
, where
, 2,
1504 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1510 /* Shift instruction. */
1511 line
= extract_operand (line
, l1
, sizeof (l1
));
1512 strncpy (l2
, l1
, sizeof (l2
));
1513 l2
[sizeof (l2
) - 1] = '\0';
1514 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1515 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1518 break; /* An error occurred. All warnings were done before. */
1520 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1522 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1523 frag
= frag_more (2 * __is
);
1524 where
= frag
- frag_now
->fr_literal
;
1525 bfd_putl16 ((bfd_vma
) bin
, frag
);
1526 dwarf2_emit_insn (2 * __is
);
1528 if (op1
.mode
== OP_EXP
)
1530 where
+= 2; /* Advance 'where' as we do not know _where_. */
1531 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1533 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1534 fix_new_exp (frag_now
, where
, 2,
1535 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1537 fix_new_exp (frag_now
, where
, 2,
1538 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1541 if (op2
.mode
== OP_EXP
)
1544 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1546 if (op2
.reg
) /* Not PC relative. */
1547 fix_new_exp (frag_now
, where
+ 2, 2,
1548 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1550 fix_new_exp (frag_now
, where
+ 2, 2,
1551 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1556 /* Branch instruction => mov dst, r0. */
1557 line
= extract_operand (line
, l1
, sizeof (l1
));
1559 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1566 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1568 frag
= frag_more (2 * __is
);
1569 where
= frag
- frag_now
->fr_literal
;
1570 bfd_putl16 ((bfd_vma
) bin
, frag
);
1571 dwarf2_emit_insn (2 * __is
);
1573 if (op1
.mode
== OP_EXP
)
1576 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1578 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1579 fix_new_exp (frag_now
, where
, 2,
1580 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1582 fix_new_exp (frag_now
, where
, 2,
1583 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1589 case 1: /* Format 1, double operand. */
1590 line
= extract_operand (line
, l1
, sizeof (l1
));
1591 line
= extract_operand (line
, l2
, sizeof (l2
));
1592 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1593 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1596 break; /* Error occurred. All warnings were done before. */
1598 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1600 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1601 frag
= frag_more (2 * __is
);
1602 where
= frag
- frag_now
->fr_literal
;
1603 bfd_putl16 ((bfd_vma
) bin
, frag
);
1604 dwarf2_emit_insn (2 * __is
);
1606 if (op1
.mode
== OP_EXP
)
1608 where
+= 2; /* Advance where as we do not know _where_. */
1609 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1611 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1612 fix_new_exp (frag_now
, where
, 2,
1613 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1615 fix_new_exp (frag_now
, where
, 2,
1616 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1619 if (op2
.mode
== OP_EXP
)
1622 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1624 if (op2
.reg
) /* Not PC relative. */
1625 fix_new_exp (frag_now
, where
+ 2, 2,
1626 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1628 fix_new_exp (frag_now
, where
+ 2, 2,
1629 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1633 case 2: /* Single-operand mostly instr. */
1634 if (opcode
->insn_opnumb
== 0)
1636 /* reti instruction. */
1637 frag
= frag_more (2);
1638 bfd_putl16 ((bfd_vma
) bin
, frag
);
1639 dwarf2_emit_insn (2);
1643 line
= extract_operand (line
, l1
, sizeof (l1
));
1644 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1646 break; /* Error in operand. */
1648 bin
|= op1
.reg
| (op1
.am
<< 4);
1650 frag
= frag_more (2 * __is
);
1651 where
= frag
- frag_now
->fr_literal
;
1652 bfd_putl16 ((bfd_vma
) bin
, frag
);
1653 dwarf2_emit_insn (2 * __is
);
1655 if (op1
.mode
== OP_EXP
)
1657 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1659 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1660 fix_new_exp (frag_now
, where
+ 2, 2,
1661 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1663 fix_new_exp (frag_now
, where
+ 2, 2,
1664 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1668 case 3: /* Conditional jumps instructions. */
1669 line
= extract_operand (line
, l1
, sizeof (l1
));
1670 /* l1 is a label. */
1679 parse_exp (m
, &exp
);
1680 frag
= frag_more (2); /* Instr size is 1 word. */
1682 /* In order to handle something like:
1686 jz 4 ; skip next 4 bytes
1689 nop ; will jump here if r5 positive or zero
1691 jCOND -n ;assumes jump n bytes backward:
1701 jCOND $n ; jump from PC in either direction. */
1703 if (exp
.X_op
== O_constant
)
1705 int x
= exp
.X_add_number
;
1709 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1713 if ((*l1
== '$' && x
> 0) || x
< 0)
1718 if (x
> 512 || x
< -511)
1720 as_bad (_("Wrong displacement %d"), x
<< 1);
1725 bfd_putl16 ((bfd_vma
) bin
, frag
);
1727 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1729 where
= frag
- frag_now
->fr_literal
;
1730 fix_new_exp (frag_now
, where
, 2,
1731 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1733 bfd_putl16 ((bfd_vma
) bin
, frag
);
1735 else if (*l1
== '$')
1737 as_bad (_("instruction requires label sans '$'"));
1742 ("instruction requires label or value in range -511:512"));
1744 dwarf2_emit_insn (2 * __is
);
1749 as_bad (_("instruction requires label"));
1754 case 4: /* Extended jumps. */
1755 if (!msp430_enable_polys
)
1757 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1761 line
= extract_operand (line
, l1
, sizeof (l1
));
1767 /* Ignore absolute addressing. make it PC relative anyway. */
1768 if (*m
== '#' || *m
== '$')
1771 parse_exp (m
, & exp
);
1772 if (exp
.X_op
== O_symbol
)
1774 /* Relaxation required. */
1775 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1777 /* The parameter to dwarf2_emit_insn is actually the offset to the start
1778 of the insn from the fix piece of instruction that was emitted.
1779 Since next fragments may have variable size we tie debug info
1780 to the beginning of the instruction. */
1781 frag
= frag_more (8);
1782 dwarf2_emit_insn (0);
1783 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1784 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1785 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1787 0, /* Offset is zero if jump dist less than 1K. */
1793 as_bad (_("instruction requires label"));
1796 case 5: /* Emulated extended branches. */
1797 if (!msp430_enable_polys
)
1799 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1802 line
= extract_operand (line
, l1
, sizeof (l1
));
1808 /* Ignore absolute addressing. make it PC relative anyway. */
1809 if (*m
== '#' || *m
== '$')
1812 parse_exp (m
, & exp
);
1813 if (exp
.X_op
== O_symbol
)
1815 /* Relaxation required. */
1816 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1818 frag
= frag_more (8);
1819 dwarf2_emit_insn (0);
1820 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1821 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1823 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1824 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1826 0, /* Offset is zero if jump dist less than 1K. */
1832 as_bad (_("instruction requires label"));
1836 as_bad (_("Ilegal instruction or not implmented opcode."));
1839 input_line_pointer
= line
;
1844 md_assemble (char * str
)
1846 struct msp430_opcode_s
* opcode
;
1850 str
= skip_space (str
); /* Skip leading spaces. */
1851 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1853 while (cmd
[i
] && i
< sizeof (cmd
))
1855 char a
= TOLOWER (cmd
[i
]);
1862 as_bad (_("can't find opcode "));
1866 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1870 as_bad (_("unknown opcode `%s'"), cmd
);
1875 char *__t
= input_line_pointer
;
1877 msp430_operands (opcode
, str
);
1878 input_line_pointer
= __t
;
1882 /* GAS will call this function for each section at the end of the assembly,
1883 to permit the CPU backend to adjust the alignment of a section. */
1886 md_section_align (asection
* seg
, valueT addr
)
1888 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1890 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1893 /* If you define this macro, it should return the offset between the
1894 address of a PC relative fixup and the position from which the PC
1895 relative adjustment should be made. On many processors, the base
1896 of a PC relative instruction is the next instruction, so this
1897 macro would return the length of an instruction. */
1900 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1902 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1903 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1904 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1907 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1910 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1911 Now it handles the situation when relocations
1912 have to be passed to linker. */
1914 msp430_force_relocation_local(fixS
*fixp
)
1916 if (msp430_enable_polys
1917 && !msp430_enable_relax
)
1920 return (!fixp
->fx_pcrel
1922 || generic_force_reloc(fixp
));
1926 /* GAS will call this for each fixup. It should store the correct
1927 value in the object file. */
1929 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1931 unsigned char * where
;
1935 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1940 else if (fixp
->fx_pcrel
)
1942 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1944 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1946 /* FIXME: We can appear here only in case if we perform a pc
1947 relative jump to the label which is i) global, ii) locally
1948 defined or this is a jump to an absolute symbol.
1949 If this is an absolute symbol -- everything is OK.
1950 If this is a global label, we've got a symbol value defined
1952 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1953 from this section start
1954 2. *valuep will contain the real offset from jump insn to the
1956 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1957 will be incorrect. Therefore remove s_get_value. */
1958 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1966 value
= fixp
->fx_offset
;
1968 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1970 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1972 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1977 /* We don't actually support subtracting a symbol. */
1978 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1979 _("expression too complex"));
1984 fixp
->fx_no_overflow
= 1;
1986 /* if polymorphs are enabled and relax disabled.
1987 do not kill any relocs and pass them to linker. */
1988 if (msp430_enable_polys
1989 && !msp430_enable_relax
)
1991 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
1992 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
1993 fixp
->fx_done
= 1; /* it is ok to kill 'abs' reloc */
2000 /* Fetch the instruction, insert the fully resolved operand
2001 value, and stuff the instruction back again. */
2003 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
2005 insn
= bfd_getl16 (where
);
2007 switch (fixp
->fx_r_type
)
2009 case BFD_RELOC_MSP430_10_PCREL
:
2011 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2012 _("odd address operand: %ld"), value
);
2014 /* Jumps are in words. */
2016 --value
; /* Correct PC. */
2018 if (value
< -512 || value
> 511)
2019 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2020 _("operand out of range: %ld"), value
);
2022 value
&= 0x3ff; /* get rid of extended sign */
2023 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
2026 case BFD_RELOC_MSP430_RL_PCREL
:
2027 case BFD_RELOC_MSP430_16_PCREL
:
2029 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2030 _("odd address operand: %ld"), value
);
2032 /* Nothing to be corrected here. */
2033 if (value
< -32768 || value
> 65536)
2034 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2035 _("operand out of range: %ld"), value
);
2037 value
&= 0xffff; /* Get rid of extended sign. */
2038 bfd_putl16 ((bfd_vma
) value
, where
);
2041 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
2042 /* Nothing to be corrected here. */
2043 if (value
< -32768 || value
> 65536)
2044 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2045 _("operand out of range: %ld"), value
);
2047 value
&= 0xffff; /* Get rid of extended sign. */
2048 bfd_putl16 ((bfd_vma
) value
, where
);
2052 bfd_putl16 ((bfd_vma
) value
, where
);
2055 case BFD_RELOC_MSP430_16
:
2057 case BFD_RELOC_MSP430_16_BYTE
:
2059 bfd_putl16 ((bfd_vma
) value
, where
);
2063 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2064 fixp
->fx_line
, fixp
->fx_r_type
);
2070 fixp
->fx_addnumber
= value
;
2074 /* GAS will call this to generate a reloc, passing the resulting reloc
2075 to `bfd_install_relocation'. This currently works poorly, as
2076 `bfd_install_relocation' often does the wrong thing, and instances of
2077 `tc_gen_reloc' have been written to work around the problems, which
2078 in turns makes it difficult to fix `bfd_install_relocation'. */
2080 /* If while processing a fixup, a reloc really needs to be created
2081 then it is done here. */
2084 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
2088 reloc
= xmalloc (sizeof (arelent
));
2090 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2091 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2093 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2094 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2095 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2097 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2098 _("reloc %d not supported by object file format"),
2099 (int) fixp
->fx_r_type
);
2103 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
2104 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2105 reloc
->address
= fixp
->fx_offset
;
2107 reloc
->addend
= fixp
->fx_offset
;
2113 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2114 asection
* segment_type ATTRIBUTE_UNUSED
)
2116 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2118 /* This is a jump -> pcrel mode. Nothing to do much here.
2119 Return value == 2. */
2121 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2123 else if (fragP
->fr_symbol
)
2125 /* Its got a segment, but its not ours. Even if fr_symbol is in
2126 an absolute segment, we dont know a displacement until we link
2127 object files. So it will always be long. This also applies to
2128 labels in a subsegment of current. Liker may relax it to short
2129 jump later. Return value == 8. */
2131 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2135 /* We know the abs value. may be it is a jump to fixed address.
2136 Impossible in our case, cause all constants already handeled. */
2138 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2141 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2145 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2146 asection
* sec ATTRIBUTE_UNUSED
,
2152 struct rcodes_s
* cc
= NULL
;
2153 struct hcodes_s
* hc
= NULL
;
2155 switch (fragP
->fr_subtype
)
2157 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2158 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2159 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2160 /* We do not have to convert anything here.
2161 Just apply a fix. */
2162 rela
= BFD_RELOC_MSP430_10_PCREL
;
2165 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2166 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2167 /* Convert uncond branch jmp lab -> br lab. */
2168 cc
= & msp430_rcodes
[7];
2169 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2170 bfd_putl16 (cc
->lop0
, where
);
2171 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2175 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2176 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2178 /* Other simple branches. */
2179 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2182 /* Find actual instruction. */
2183 for (i
= 0; i
< 7 && !cc
; i
++)
2184 if (msp430_rcodes
[i
].sop
== insn
)
2185 cc
= & msp430_rcodes
[i
];
2186 if (!cc
|| !cc
->name
)
2187 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2188 __FUNCTION__
, (long) insn
);
2189 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2190 bfd_putl16 (cc
->lop0
, where
);
2191 bfd_putl16 (cc
->lop1
, where
+ 2);
2192 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2197 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2198 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2199 cc
= & msp430_rcodes
[6];
2200 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2201 bfd_putl16 (cc
->lop0
, where
);
2202 bfd_putl16 (cc
->lop1
, where
+ 2);
2203 bfd_putl16 (cc
->lop2
, where
+ 4);
2204 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2208 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2210 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2213 for (i
= 0; i
< 4 && !hc
; i
++)
2214 if (msp430_hcodes
[i
].op1
== insn
)
2215 hc
= &msp430_hcodes
[i
];
2216 if (!hc
|| !hc
->name
)
2217 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2218 __FUNCTION__
, (long) insn
);
2219 rela
= BFD_RELOC_MSP430_10_PCREL
;
2220 /* Apply a fix for a first label if necessary.
2221 another fix will be applied to the next word of insn anyway. */
2223 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2224 fragP
->fr_offset
, TRUE
, rela
);
2230 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2231 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2233 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2236 for (i
= 0; i
< 4 && !hc
; i
++)
2237 if (msp430_hcodes
[i
].op1
== insn
)
2238 hc
= & msp430_hcodes
[i
];
2239 if (!hc
|| !hc
->name
)
2240 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2241 __FUNCTION__
, (long) insn
);
2242 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2243 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2244 bfd_putl16 (hc
->lop0
, where
);
2245 bfd_putl16 (hc
->lop1
, where
+ 2);
2246 bfd_putl16 (hc
->lop2
, where
+ 4);
2252 as_fatal (_("internal inconsistency problem in %s: %lx"),
2253 __FUNCTION__
, (long) fragP
->fr_subtype
);
2257 /* Now apply fix. */
2258 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2259 fragP
->fr_offset
, TRUE
, rela
);
2260 /* Just fixed 2 bytes. */
2264 /* Relax fragment. Mostly stolen from hc11 and mcore
2265 which arches I think I know. */
2268 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2269 long stretch ATTRIBUTE_UNUSED
)
2274 const relax_typeS
*this_type
;
2275 const relax_typeS
*start_type
;
2276 relax_substateT next_state
;
2277 relax_substateT this_state
;
2278 const relax_typeS
*table
= md_relax_table
;
2280 /* Nothing to be done if the frag has already max size. */
2281 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2282 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2285 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2287 symbolP
= fragP
->fr_symbol
;
2288 if (symbol_resolved_p (symbolP
))
2289 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2291 /* We know the offset. calculate a distance. */
2292 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2295 if (!msp430_enable_relax
)
2297 /* Relaxation is not enabled. So, make all jump as long ones
2298 by setting 'aim' to quite high value. */
2302 this_state
= fragP
->fr_subtype
;
2303 start_type
= this_type
= table
+ this_state
;
2307 /* Look backwards. */
2308 for (next_state
= this_type
->rlx_more
; next_state
;)
2309 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
2313 /* Grow to next state. */
2314 this_state
= next_state
;
2315 this_type
= table
+ this_state
;
2316 next_state
= this_type
->rlx_more
;
2321 /* Look forwards. */
2322 for (next_state
= this_type
->rlx_more
; next_state
;)
2323 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
2327 /* Grow to next state. */
2328 this_state
= next_state
;
2329 this_type
= table
+ this_state
;
2330 next_state
= this_type
->rlx_more
;
2334 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2336 fragP
->fr_subtype
= this_state
;