1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
4 Free Software Foundation, Inc.
5 Contributed by Dmitry Diky <diwil@mail.ru>
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
26 #define PUSH_1X_WORKAROUND
28 #include "opcode/msp430.h"
29 #include "safe-ctype.h"
30 #include "dwarf2dbg.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* GCC uses the some condition codes which we'll
73 implement as new polymorph instructions.
75 COND EXPL SHORT JUMP LONG JUMP
76 ===============================================
77 eq == jeq jne +4; br lab
78 ne != jne jeq +4; br lab
80 ltn honours no-overflow flag
81 ltn < jn jn +2; jmp +4; br lab
83 lt < jl jge +4; br lab
84 ltu < jlo lhs +4; br lab
90 ge >= jge jl +4; br lab
91 geu >= jhs jlo +4; br lab
92 ===============================================
94 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
95 beq,bne,blt,bltn,bltu,bge,bgeu
96 'u' means unsigned compares
98 Also, we add 'jump' instruction:
99 jump UNCOND -> jmp br lab
101 They will have fmt == 4, and insn_opnumb == number of instruction. */
106 int index
; /* Corresponding insn_opnumb. */
107 int sop
; /* Opcode if jump length is short. */
108 long lpos
; /* Label position. */
109 long lop0
; /* Opcode 1 _word_ (16 bits). */
110 long lop1
; /* Opcode second word. */
111 long lop2
; /* Opcode third word. */
114 #define MSP430_RLC(n,i,sop,o1) \
115 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 static struct rcodes_s msp430_rcodes
[] =
119 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
120 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
121 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
122 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
123 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
124 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
125 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
126 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
132 /* More difficult than above and they have format 5.
135 =================================================================
136 gt > jeq +2; jge label jeq +6; jl +4; br label
137 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
138 leu <= jeq label; jlo label jeq +2; jhs +4; br label
139 le <= jeq label; jl label jeq +2; jge +4; br label
140 ================================================================= */
145 int index
; /* Corresponding insn_opnumb. */
146 int tlab
; /* Number of labels in short mode. */
147 int op0
; /* Opcode for first word of short jump. */
148 int op1
; /* Opcode for second word of short jump. */
149 int lop0
; /* Opcodes for long jump mode. */
154 static struct hcodes_s msp430_hcodes
[] =
156 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
157 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
158 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
159 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
163 const char comment_chars
[] = ";";
164 const char line_comment_chars
[] = "#";
165 const char line_separator_chars
[] = "{";
166 const char EXP_CHARS
[] = "eE";
167 const char FLT_CHARS
[] = "dD";
169 /* Handle long expressions. */
170 extern LITTLENUM_TYPE generic_bignum
[];
172 static struct hash_control
*msp430_hash
;
175 #define STATE_UNCOND_BRANCH 1 /* jump */
176 #define STATE_NOOV_BRANCH 3 /* bltn */
177 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
178 #define STATE_EMUL_BRANCH 4
187 #define STATE_BITS10 1 /* wild guess. short jump */
188 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
189 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
191 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
192 #define RELAX_STATE(s) ((s) & 3)
193 #define RELAX_LEN(s) ((s) >> 2)
194 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
196 relax_typeS md_relax_table
[] =
204 /* Unconditional jump. */
206 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
207 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
208 {1, 1, CUBL
, 0}, /* state undef */
210 /* Simple branches. */
212 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
213 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
216 /* blt no overflow branch. */
218 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
219 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
222 /* Emulated branches. */
224 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
225 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
230 #define MAX_OP_LEN 256
239 #define MSP430_ISA_11 11
240 #define MSP430_ISA_110 110
241 #define MSP430_ISA_12 12
242 #define MSP430_ISA_13 13
243 #define MSP430_ISA_14 14
244 #define MSP430_ISA_15 15
245 #define MSP430_ISA_16 16
246 #define MSP430_ISA_21 21
247 #define MSP430_ISA_31 31
248 #define MSP430_ISA_32 32
249 #define MSP430_ISA_33 33
250 #define MSP430_ISA_41 41
251 #define MSP430_ISA_42 42
252 #define MSP430_ISA_43 43
253 #define MSP430_ISA_44 44
255 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
256 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
258 static struct mcu_type_s mcu_types
[] =
260 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
261 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
262 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
263 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
264 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
265 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
266 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
267 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
268 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
270 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
271 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
272 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
273 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
275 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
276 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
277 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
278 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
279 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
280 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
281 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
283 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
284 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
285 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
286 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
287 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
288 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
289 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
290 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
291 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
293 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
294 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
295 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
296 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
298 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
299 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
300 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
301 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
302 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
303 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
304 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
305 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
306 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
308 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
309 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
310 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
311 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
313 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
314 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
315 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
317 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
318 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
319 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
321 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
322 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
323 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
325 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
326 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
327 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
328 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
329 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
330 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
336 static struct mcu_type_s default_mcu
=
337 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
339 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
341 /* Profiling capability:
342 It is a performance hit to use gcc's profiling approach for this tiny target.
343 Even more -- jtag hardware facility does not perform any profiling functions.
344 However we've got gdb's built-in simulator where we can do anything.
345 Therefore my suggestion is:
347 We define new section ".profiler" which holds all profiling information.
348 We define new pseudo operation .profiler which will instruct assembler to
349 add new profile entry to the object file. Profile should take place at the
354 .profiler flags,function_to_profile [, cycle_corrector, extra]
356 where 'flags' is a combination of the following chars:
359 i - function is in Init section
360 f - function is in Fini section
362 c - libC standard call
363 d - stack value Demand (saved at run-time in simulator)
364 I - Interrupt service routine
369 j - long Jump/ sjlj unwind
370 a - an Arbitrary code fragment
371 t - exTra parameter saved (constant value like frame size)
372 '""' optional: "sil" == sil
374 function_to_profile - function's address
375 cycle_corrector - a value which should be added to the cycle
376 counter, zero if omitted
377 extra - some extra parameter, zero if omitted.
380 ------------------------------
384 .LFrameOffset_fxx=0x08
385 .profiler "scdP", fxx ; function entry.
386 ; we also demand stack value to be displayed
391 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
392 ; (this is a prologue end)
393 ; note, that spare var filled with the frame size
396 .profiler cdE,fxx ; check stack
401 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
402 ret ; cause 'ret' insn takes 3 cycles
403 -------------------------------
405 This profiling approach does not produce any overhead and
407 So, even profiled code can be uploaded to the MCU. */
408 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
409 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
410 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
411 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
412 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
413 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
414 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
415 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
416 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
417 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
418 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
419 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
420 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
421 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
422 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
423 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
436 for (; x
; x
= x
>> 1)
443 /* Parse ordinary expression. */
446 parse_exp (char * s
, expressionS
* op
)
448 input_line_pointer
= s
;
450 if (op
->X_op
== O_absent
)
451 as_bad (_("missing operand"));
452 return input_line_pointer
;
456 /* Delete spaces from s: X ( r 1 2) => X(r12). */
459 del_spaces (char * s
)
467 while (ISSPACE (*m
) && *m
)
469 memmove (s
, m
, strlen (m
) + 1);
477 skip_space (char * s
)
484 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
487 extract_operand (char * from
, char * to
, int limit
)
491 /* Drop leading whitespace. */
492 from
= skip_space (from
);
494 while (size
< limit
&& *from
)
496 *(to
+ size
) = *from
;
497 if (*from
== ',' || *from
== ';' || *from
== '\n')
512 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
529 s
= input_line_pointer
;
530 end
= input_line_pointer
;
532 while (*end
&& *end
!= '\n')
535 while (*s
&& *s
!= '\n')
546 as_bad (_(".profiler pseudo requires at least two operands."));
547 input_line_pointer
= end
;
551 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
560 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
563 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
566 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
569 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
572 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
575 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
578 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
581 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
584 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
587 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
590 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
593 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
596 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
599 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
602 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
605 as_warn (_("unknown profiling flag - ignored."));
612 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
613 | MSP430_PROFILER_FLAG_EXIT
))
614 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
615 | MSP430_PROFILER_FLAG_PROLEND
616 | MSP430_PROFILER_FLAG_EPISTART
617 | MSP430_PROFILER_FLAG_EPIEND
))
618 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
619 | MSP430_PROFILER_FLAG_FINISECT
))))
621 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
622 input_line_pointer
= end
;
626 /* Generate temp symbol which denotes current location. */
627 if (now_seg
== absolute_section
) /* Paranoia ? */
629 exp1
.X_op
= O_constant
;
630 exp1
.X_add_number
= abs_section_offset
;
631 as_warn (_("profiling in absolute section?"));
635 exp1
.X_op
= O_symbol
;
636 exp1
.X_add_symbol
= symbol_temp_new_now ();
637 exp1
.X_add_number
= 0;
640 /* Generate a symbol which holds flags value. */
641 exp
.X_op
= O_constant
;
642 exp
.X_add_number
= p_flags
;
644 /* Save current section. */
648 /* Now go to .profiler section. */
649 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
652 emit_expr (& exp
, 2);
654 /* Save label value. */
655 emit_expr (& exp1
, 2);
659 /* Now get profiling info. */
660 halt
= extract_operand (input_line_pointer
, str
, 1024);
661 /* Process like ".word xxx" directive. */
662 parse_exp (str
, & exp
);
663 emit_expr (& exp
, 2);
664 input_line_pointer
= halt
;
667 /* Fill the rest with zeros. */
668 exp
.X_op
= O_constant
;
669 exp
.X_add_number
= 0;
671 emit_expr (& exp
, 2);
673 /* Return to current section. */
674 subseg_set (seg
, subseg
);
678 extract_word (char * from
, char * to
, int limit
)
683 /* Drop leading whitespace. */
684 from
= skip_space (from
);
687 /* Find the op code end. */
688 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
690 to
[size
++] = *op_end
++;
691 if (size
+ 1 >= limit
)
699 #define OPTION_MMCU 'm'
700 #define OPTION_RELAX 'Q'
701 #define OPTION_POLYMORPHS 'P'
704 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
706 char *str
= (char *) alloca (32); /* 32 for good measure. */
708 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
710 md_parse_option (OPTION_MMCU
, str
);
711 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
715 show_mcu_list (FILE * stream
)
719 fprintf (stream
, _("Known MCU names:\n"));
721 for (i
= 0; mcu_types
[i
].name
; i
++)
722 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
724 fprintf (stream
, "\n");
728 md_parse_option (int c
, char * arg
)
735 for (i
= 0; mcu_types
[i
].name
; ++i
)
736 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
739 if (!mcu_types
[i
].name
)
741 show_mcu_list (stderr
);
742 as_fatal (_("unknown MCU: %s\n"), arg
);
745 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
746 msp430_mcu
= &mcu_types
[i
];
748 as_fatal (_("redefinition of mcu type %s' to %s'"),
749 msp430_mcu
->name
, mcu_types
[i
].name
);
754 msp430_enable_relax
= 1;
758 case OPTION_POLYMORPHS
:
759 msp430_enable_polys
= 1;
768 const pseudo_typeS md_pseudo_table
[] =
770 {"arch", msp430_set_arch
, 0},
771 {"profiler", msp430_profiler
, 0},
775 const char *md_shortopts
= "m:";
777 struct option md_longopts
[] =
779 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
780 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
781 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
782 {NULL
, no_argument
, NULL
, 0}
785 size_t md_longopts_size
= sizeof (md_longopts
);
788 md_show_usage (FILE * stream
)
791 _("MSP430 options:\n"
792 " -mmcu=[msp430-name] select microcontroller type\n"
793 " msp430x110 msp430x112\n"
794 " msp430x1101 msp430x1111\n"
795 " msp430x1121 msp430x1122 msp430x1132\n"
796 " msp430x122 msp430x123\n"
797 " msp430x1222 msp430x1232\n"
798 " msp430x133 msp430x135\n"
799 " msp430x1331 msp430x1351\n"
800 " msp430x147 msp430x148 msp430x149\n"
801 " msp430x155 msp430x156 msp430x157\n"
802 " msp430x167 msp430x168 msp430x169\n"
803 " msp430x1610 msp430x1611 msp430x1612\n"
804 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
805 " msp430x323 msp430x325\n"
806 " msp430x336 msp430x337\n"
807 " msp430x412 msp430x413 msp430x415 msp430x417\n"
808 " msp430xE423 msp430xE425 msp430E427\n"
809 " msp430xW423 msp430xW425 msp430W427\n"
810 " msp430xG437 msp430xG438 msp430G439\n"
811 " msp430x435 msp430x436 msp430x437\n"
812 " msp430x447 msp430x448 msp430x449\n"));
814 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
815 " -mP - enable polymorph instructions\n"));
817 show_mcu_list (stream
);
821 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
827 extract_cmd (char * from
, char * to
, int limit
)
831 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
833 *(to
+ size
) = *from
;
844 md_atof (int type
, char * litP
, int * sizeP
)
846 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
852 struct msp430_opcode_s
* opcode
;
853 msp430_hash
= hash_new ();
855 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
856 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
858 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
864 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
866 if (strlen (t
) > 2 && *(t
+ 2) != '+')
871 if ((*t
< '0' || *t
> '9') && *t
!= '+')
884 msp430_srcoperand (struct msp430_operand_s
* op
,
885 char * l
, int bin
, int * imm_op
)
889 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
896 /* Check if there is:
897 llo(x) - least significant 16 bits, x &= 0xffff
898 lhi(x) - x = (x >> 16) & 0xffff,
899 hlo(x) - x = (x >> 32) & 0xffff,
900 hhi(x) - x = (x >> 48) & 0xffff
901 The value _MUST_ be constant expression: #hlo(1231231231). */
905 if (strncasecmp (h
, "#llo(", 5) == 0)
910 else if (strncasecmp (h
, "#lhi(", 5) == 0)
915 else if (strncasecmp (h
, "#hlo(", 5) == 0)
920 else if (strncasecmp (h
, "#hhi(", 5) == 0)
925 else if (strncasecmp (h
, "#lo(", 4) == 0)
930 else if (strncasecmp (h
, "#hi(", 4) == 0)
936 op
->reg
= 0; /* Reg PC. */
938 op
->ol
= 1; /* Immediate will follow an instruction. */
942 parse_exp (__tl
, &(op
->exp
));
943 if (op
->exp
.X_op
== O_constant
)
945 int x
= op
->exp
.X_add_number
;
950 op
->exp
.X_add_number
= x
;
952 else if (vshift
== 1)
954 x
= (x
>> 16) & 0xffff;
955 op
->exp
.X_add_number
= x
;
960 op
->exp
.X_add_number
= -1;
962 op
->exp
.X_add_number
= 0; /* Nothing left. */
963 x
= op
->exp
.X_add_number
;
966 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
968 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
972 /* Now check constants. */
973 /* Substitute register mode with a constant generator if applicable. */
975 x
= (short) x
; /* Extend sign. */
1007 #ifdef PUSH_1X_WORKAROUND
1010 /* Remove warning as confusing.
1011 as_warn (_("Hardware push bug workaround")); */
1024 #ifdef PUSH_1X_WORKAROUND
1027 /* Remove warning as confusing.
1028 as_warn (_("Hardware push bug workaround")); */
1040 else if (op
->exp
.X_op
== O_symbol
)
1044 else if (op
->exp
.X_op
== O_big
)
1049 op
->exp
.X_op
= O_constant
;
1050 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1051 x
= op
->exp
.X_add_number
;
1056 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1104 /* Redundant (yet) check. */
1105 else if (op
->exp
.X_op
== O_register
)
1107 (_("Registers cannot be used within immediate expression [%s]"), l
);
1109 as_bad (_("unknown operand %s"), l
);
1114 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1119 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1120 op
->am
= 1; /* mode As == 01 bin. */
1121 op
->ol
= 1; /* Immediate value followed by instruction. */
1123 parse_exp (__tl
, &(op
->exp
));
1125 if (op
->exp
.X_op
== O_constant
)
1127 int x
= op
->exp
.X_add_number
;
1129 if (x
> 65535 || x
< -32768)
1131 as_bad (_("value out of range: %d"), x
);
1135 else if (op
->exp
.X_op
== O_symbol
)
1139 /* Redundant (yet) check. */
1140 if (op
->exp
.X_op
== O_register
)
1142 (_("Registers cannot be used within absolute expression [%s]"), l
);
1144 as_bad (_("unknown expression in operand %s"), l
);
1150 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1154 char *m
= strchr (l
, '+');
1158 as_bad (_("unknown addressing mode %s"), l
);
1163 if (*t
!= 'r' && *t
!= 'R')
1165 as_bad (_("unknown addressing mode %s"), l
);
1169 t
++; /* Points to the reg value. */
1173 as_bad (_("Bad register name r%s"), t
);
1181 *m
= 0; /* strip '+' */
1183 if (op
->reg
< 0 || op
->reg
> 15)
1185 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1192 /* Check if register indexed X(Rn). */
1195 char *h
= strrchr (l
, '(');
1196 char *m
= strrchr (l
, ')');
1205 as_bad (_("')' required"));
1212 /* Extract a register. */
1213 t
++; /* Advance pointer. */
1215 if (*t
!= 'r' && *t
!= 'R')
1218 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1225 if (op
->reg
> 9 || op
->reg
< 0)
1227 as_bad (_("unknown operator (r%s substituted as a register name"),
1234 op
->reg
= op
->reg
* 10;
1235 op
->reg
+= *t
- '0';
1239 as_bad (_("unknown operator %s"), l
);
1244 as_bad (_("r2 should not be used in indexed addressing mode"));
1248 if (*(t
+ 1) != ')')
1250 as_bad (_("unknown operator %s"), l
);
1255 /* Extract constant. */
1259 parse_exp (__tl
, &(op
->exp
));
1260 if (op
->exp
.X_op
== O_constant
)
1262 int x
= op
->exp
.X_add_number
;
1264 if (x
> 65535 || x
< -32768)
1266 as_bad (_("value out of range: %d"), x
);
1278 else if (op
->exp
.X_op
== O_symbol
)
1282 /* Redundant (yet) check. */
1283 if (op
->exp
.X_op
== O_register
)
1285 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1287 as_bad (_("unknown expression in operand %s"), l
);
1295 /* Register mode 'mov r1,r2'. */
1300 /* Operand should be a register. */
1301 if (*t
== 'r' || *t
== 'R')
1303 int x
= atoi (t
+ 1);
1305 if (check_reg (t
+ 1))
1308 if (x
< 0 || x
> 15)
1309 break; /* Symbolic mode. */
1320 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1324 op
->reg
= 0; /* PC relative... be careful. */
1328 parse_exp (__tl
, &(op
->exp
));
1334 as_bad (_("unknown addressing mode for operand %s"), l
);
1340 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1343 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1355 parse_exp (__tl
, &(op
->exp
));
1357 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1359 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1369 ("this addressing mode is not applicable for destination operand"));
1376 /* Parse instruction operands.
1377 Return binary opcode. */
1380 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1382 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1384 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1387 struct msp430_operand_s op1
, op2
;
1389 static short ZEROS
= 0;
1390 int byte_op
, imm_op
;
1392 /* Opcode is the one from opcodes table
1393 line contains something like
1398 /* Check if byte or word operation. */
1399 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1401 bin
|= BYTE_OPERATION
;
1408 while (! ISSPACE (*line
) && *line
)
1411 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1413 as_bad (_("instruction %s requires %d operand(s)"),
1414 opcode
->name
, opcode
->insn_opnumb
);
1418 memset (l1
, 0, sizeof (l1
));
1419 memset (l2
, 0, sizeof (l2
));
1420 memset (&op1
, 0, sizeof (op1
));
1421 memset (&op2
, 0, sizeof (op2
));
1425 switch (opcode
->fmt
)
1427 case 0: /* Emulated. */
1428 switch (opcode
->insn_opnumb
)
1431 /* Set/clear bits instructions. */
1433 frag
= frag_more (__is
);
1434 bfd_putl16 ((bfd_vma
) bin
, frag
);
1435 dwarf2_emit_insn (__is
);
1438 /* Something which works with destination operand. */
1439 line
= extract_operand (line
, l1
, sizeof (l1
));
1440 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1444 bin
|= (op1
.reg
| (op1
.am
<< 7));
1446 frag
= frag_more (2 * __is
);
1447 where
= frag
- frag_now
->fr_literal
;
1448 bfd_putl16 ((bfd_vma
) bin
, frag
);
1449 dwarf2_emit_insn (2 * __is
);
1451 if (op1
.mode
== OP_EXP
)
1454 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1457 fix_new_exp (frag_now
, where
, 2,
1458 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1460 fix_new_exp (frag_now
, where
, 2,
1461 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1467 /* Shift instruction. */
1468 line
= extract_operand (line
, l1
, sizeof (l1
));
1469 strncpy (l2
, l1
, sizeof (l2
));
1470 l2
[sizeof (l2
) - 1] = '\0';
1471 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1472 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1475 break; /* An error occurred. All warnings were done before. */
1477 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1479 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1480 frag
= frag_more (2 * __is
);
1481 where
= frag
- frag_now
->fr_literal
;
1482 bfd_putl16 ((bfd_vma
) bin
, frag
);
1483 dwarf2_emit_insn (2 * __is
);
1485 if (op1
.mode
== OP_EXP
)
1487 where
+= 2; /* Advance 'where' as we do not know _where_. */
1488 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1490 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1491 fix_new_exp (frag_now
, where
, 2,
1492 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1494 fix_new_exp (frag_now
, where
, 2,
1495 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1498 if (op2
.mode
== OP_EXP
)
1501 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1503 if (op2
.reg
) /* Not PC relative. */
1504 fix_new_exp (frag_now
, where
+ 2, 2,
1505 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1507 fix_new_exp (frag_now
, where
+ 2, 2,
1508 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1513 /* Branch instruction => mov dst, r0. */
1514 line
= extract_operand (line
, l1
, sizeof (l1
));
1516 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1523 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1525 frag
= frag_more (2 * __is
);
1526 where
= frag
- frag_now
->fr_literal
;
1527 bfd_putl16 ((bfd_vma
) bin
, frag
);
1528 dwarf2_emit_insn (2 * __is
);
1530 if (op1
.mode
== OP_EXP
)
1533 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1535 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1536 fix_new_exp (frag_now
, where
, 2,
1537 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1539 fix_new_exp (frag_now
, where
, 2,
1540 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1546 case 1: /* Format 1, double operand. */
1547 line
= extract_operand (line
, l1
, sizeof (l1
));
1548 line
= extract_operand (line
, l2
, sizeof (l2
));
1549 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1550 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1553 break; /* Error occurred. All warnings were done before. */
1555 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1557 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1558 frag
= frag_more (2 * __is
);
1559 where
= frag
- frag_now
->fr_literal
;
1560 bfd_putl16 ((bfd_vma
) bin
, frag
);
1561 dwarf2_emit_insn (2 * __is
);
1563 if (op1
.mode
== OP_EXP
)
1565 where
+= 2; /* Advance where as we do not know _where_. */
1566 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1568 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1569 fix_new_exp (frag_now
, where
, 2,
1570 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1572 fix_new_exp (frag_now
, where
, 2,
1573 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1576 if (op2
.mode
== OP_EXP
)
1579 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1581 if (op2
.reg
) /* Not PC relative. */
1582 fix_new_exp (frag_now
, where
+ 2, 2,
1583 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1585 fix_new_exp (frag_now
, where
+ 2, 2,
1586 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1590 case 2: /* Single-operand mostly instr. */
1591 if (opcode
->insn_opnumb
== 0)
1593 /* reti instruction. */
1594 frag
= frag_more (2);
1595 bfd_putl16 ((bfd_vma
) bin
, frag
);
1596 dwarf2_emit_insn (2);
1600 line
= extract_operand (line
, l1
, sizeof (l1
));
1601 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1603 break; /* Error in operand. */
1605 bin
|= op1
.reg
| (op1
.am
<< 4);
1607 frag
= frag_more (2 * __is
);
1608 where
= frag
- frag_now
->fr_literal
;
1609 bfd_putl16 ((bfd_vma
) bin
, frag
);
1610 dwarf2_emit_insn (2 * __is
);
1612 if (op1
.mode
== OP_EXP
)
1614 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1616 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1617 fix_new_exp (frag_now
, where
+ 2, 2,
1618 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1620 fix_new_exp (frag_now
, where
+ 2, 2,
1621 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1625 case 3: /* Conditional jumps instructions. */
1626 line
= extract_operand (line
, l1
, sizeof (l1
));
1627 /* l1 is a label. */
1636 parse_exp (m
, &exp
);
1637 frag
= frag_more (2); /* Instr size is 1 word. */
1639 /* In order to handle something like:
1643 jz 4 ; skip next 4 bytes
1646 nop ; will jump here if r5 positive or zero
1648 jCOND -n ;assumes jump n bytes backward:
1658 jCOND $n ; jump from PC in either direction. */
1660 if (exp
.X_op
== O_constant
)
1662 int x
= exp
.X_add_number
;
1666 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1670 if ((*l1
== '$' && x
> 0) || x
< 0)
1675 if (x
> 512 || x
< -511)
1677 as_bad (_("Wrong displacement %d"), x
<< 1);
1682 bfd_putl16 ((bfd_vma
) bin
, frag
);
1684 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1686 where
= frag
- frag_now
->fr_literal
;
1687 fix_new_exp (frag_now
, where
, 2,
1688 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1690 bfd_putl16 ((bfd_vma
) bin
, frag
);
1692 else if (*l1
== '$')
1694 as_bad (_("instruction requires label sans '$'"));
1699 ("instruction requires label or value in range -511:512"));
1701 dwarf2_emit_insn (2 * __is
);
1706 as_bad (_("instruction requires label"));
1711 case 4: /* Extended jumps. */
1712 if (!msp430_enable_polys
)
1714 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1718 line
= extract_operand (line
, l1
, sizeof (l1
));
1724 /* Ignore absolute addressing. make it PC relative anyway. */
1725 if (*m
== '#' || *m
== '$')
1728 parse_exp (m
, & exp
);
1729 if (exp
.X_op
== O_symbol
)
1731 /* Relaxation required. */
1732 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1734 /* The parameter to dwarf2_emit_insn is actually the offset to the start
1735 of the insn from the fix piece of instruction that was emitted.
1736 Since next fragments may have variable size we tie debug info
1737 to the beginning of the instruction. */
1738 frag
= frag_more (8);
1739 dwarf2_emit_insn (0);
1740 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1741 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1742 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1744 0, /* Offset is zero if jump dist less than 1K. */
1750 as_bad (_("instruction requires label"));
1753 case 5: /* Emulated extended branches. */
1754 if (!msp430_enable_polys
)
1756 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1759 line
= extract_operand (line
, l1
, sizeof (l1
));
1765 /* Ignore absolute addressing. make it PC relative anyway. */
1766 if (*m
== '#' || *m
== '$')
1769 parse_exp (m
, & exp
);
1770 if (exp
.X_op
== O_symbol
)
1772 /* Relaxation required. */
1773 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1775 frag
= frag_more (8);
1776 dwarf2_emit_insn (0);
1777 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1778 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1780 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1781 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1783 0, /* Offset is zero if jump dist less than 1K. */
1789 as_bad (_("instruction requires label"));
1793 as_bad (_("Illegal instruction or not implemented opcode."));
1796 input_line_pointer
= line
;
1801 md_assemble (char * str
)
1803 struct msp430_opcode_s
* opcode
;
1807 str
= skip_space (str
); /* Skip leading spaces. */
1808 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1810 while (cmd
[i
] && i
< sizeof (cmd
))
1812 char a
= TOLOWER (cmd
[i
]);
1819 as_bad (_("can't find opcode "));
1823 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1827 as_bad (_("unknown opcode `%s'"), cmd
);
1832 char *__t
= input_line_pointer
;
1834 msp430_operands (opcode
, str
);
1835 input_line_pointer
= __t
;
1839 /* GAS will call this function for each section at the end of the assembly,
1840 to permit the CPU backend to adjust the alignment of a section. */
1843 md_section_align (asection
* seg
, valueT addr
)
1845 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1847 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1850 /* If you define this macro, it should return the offset between the
1851 address of a PC relative fixup and the position from which the PC
1852 relative adjustment should be made. On many processors, the base
1853 of a PC relative instruction is the next instruction, so this
1854 macro would return the length of an instruction. */
1857 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1859 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1860 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1861 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1864 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1867 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1868 Now it handles the situation when relocations
1869 have to be passed to linker. */
1871 msp430_force_relocation_local(fixS
*fixp
)
1873 if (msp430_enable_polys
1874 && !msp430_enable_relax
)
1877 return (!fixp
->fx_pcrel
1878 || generic_force_reloc(fixp
));
1882 /* GAS will call this for each fixup. It should store the correct
1883 value in the object file. */
1885 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1887 unsigned char * where
;
1891 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1896 else if (fixp
->fx_pcrel
)
1898 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1900 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1902 /* FIXME: We can appear here only in case if we perform a pc
1903 relative jump to the label which is i) global, ii) locally
1904 defined or this is a jump to an absolute symbol.
1905 If this is an absolute symbol -- everything is OK.
1906 If this is a global label, we've got a symbol value defined
1908 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1909 from this section start
1910 2. *valuep will contain the real offset from jump insn to the
1912 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1913 will be incorrect. Therefore remove s_get_value. */
1914 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1922 value
= fixp
->fx_offset
;
1924 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1926 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1928 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1933 /* We don't actually support subtracting a symbol. */
1934 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1935 _("expression too complex"));
1940 fixp
->fx_no_overflow
= 1;
1942 /* if polymorphs are enabled and relax disabled.
1943 do not kill any relocs and pass them to linker. */
1944 if (msp430_enable_polys
1945 && !msp430_enable_relax
)
1947 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
1948 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
1949 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
1956 /* Fetch the instruction, insert the fully resolved operand
1957 value, and stuff the instruction back again. */
1959 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
1961 insn
= bfd_getl16 (where
);
1963 switch (fixp
->fx_r_type
)
1965 case BFD_RELOC_MSP430_10_PCREL
:
1967 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1968 _("odd address operand: %ld"), value
);
1970 /* Jumps are in words. */
1972 --value
; /* Correct PC. */
1974 if (value
< -512 || value
> 511)
1975 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1976 _("operand out of range: %ld"), value
);
1978 value
&= 0x3ff; /* get rid of extended sign */
1979 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
1982 case BFD_RELOC_MSP430_RL_PCREL
:
1983 case BFD_RELOC_MSP430_16_PCREL
:
1985 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1986 _("odd address operand: %ld"), value
);
1988 /* Nothing to be corrected here. */
1989 if (value
< -32768 || value
> 65536)
1990 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1991 _("operand out of range: %ld"), value
);
1993 value
&= 0xffff; /* Get rid of extended sign. */
1994 bfd_putl16 ((bfd_vma
) value
, where
);
1997 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
1998 /* Nothing to be corrected here. */
1999 if (value
< -32768 || value
> 65536)
2000 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2001 _("operand out of range: %ld"), value
);
2003 value
&= 0xffff; /* Get rid of extended sign. */
2004 bfd_putl16 ((bfd_vma
) value
, where
);
2008 bfd_putl16 ((bfd_vma
) value
, where
);
2011 case BFD_RELOC_MSP430_16
:
2013 case BFD_RELOC_MSP430_16_BYTE
:
2015 bfd_putl16 ((bfd_vma
) value
, where
);
2019 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2020 fixp
->fx_line
, fixp
->fx_r_type
);
2026 fixp
->fx_addnumber
= value
;
2030 /* GAS will call this to generate a reloc, passing the resulting reloc
2031 to `bfd_install_relocation'. This currently works poorly, as
2032 `bfd_install_relocation' often does the wrong thing, and instances of
2033 `tc_gen_reloc' have been written to work around the problems, which
2034 in turns makes it difficult to fix `bfd_install_relocation'. */
2036 /* If while processing a fixup, a reloc really needs to be created
2037 then it is done here. */
2040 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
2044 reloc
= xmalloc (sizeof (arelent
));
2046 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2047 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2049 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2050 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2051 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2053 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2054 _("reloc %d not supported by object file format"),
2055 (int) fixp
->fx_r_type
);
2059 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
2060 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2061 reloc
->address
= fixp
->fx_offset
;
2063 reloc
->addend
= fixp
->fx_offset
;
2069 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2070 asection
* segment_type ATTRIBUTE_UNUSED
)
2072 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2074 /* This is a jump -> pcrel mode. Nothing to do much here.
2075 Return value == 2. */
2077 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2079 else if (fragP
->fr_symbol
)
2081 /* Its got a segment, but its not ours. Even if fr_symbol is in
2082 an absolute segment, we don't know a displacement until we link
2083 object files. So it will always be long. This also applies to
2084 labels in a subsegment of current. Liker may relax it to short
2085 jump later. Return value == 8. */
2087 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2091 /* We know the abs value. may be it is a jump to fixed address.
2092 Impossible in our case, cause all constants already handled. */
2094 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2097 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2101 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2102 asection
* sec ATTRIBUTE_UNUSED
,
2108 struct rcodes_s
* cc
= NULL
;
2109 struct hcodes_s
* hc
= NULL
;
2111 switch (fragP
->fr_subtype
)
2113 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2114 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2115 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2116 /* We do not have to convert anything here.
2117 Just apply a fix. */
2118 rela
= BFD_RELOC_MSP430_10_PCREL
;
2121 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2122 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2123 /* Convert uncond branch jmp lab -> br lab. */
2124 cc
= & msp430_rcodes
[7];
2125 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2126 bfd_putl16 (cc
->lop0
, where
);
2127 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2131 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2132 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2134 /* Other simple branches. */
2135 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2138 /* Find actual instruction. */
2139 for (i
= 0; i
< 7 && !cc
; i
++)
2140 if (msp430_rcodes
[i
].sop
== insn
)
2141 cc
= & msp430_rcodes
[i
];
2142 if (!cc
|| !cc
->name
)
2143 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2144 __FUNCTION__
, (long) insn
);
2145 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2146 bfd_putl16 (cc
->lop0
, where
);
2147 bfd_putl16 (cc
->lop1
, where
+ 2);
2148 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2153 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2154 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2155 cc
= & msp430_rcodes
[6];
2156 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2157 bfd_putl16 (cc
->lop0
, where
);
2158 bfd_putl16 (cc
->lop1
, where
+ 2);
2159 bfd_putl16 (cc
->lop2
, where
+ 4);
2160 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2164 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2166 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2169 for (i
= 0; i
< 4 && !hc
; i
++)
2170 if (msp430_hcodes
[i
].op1
== insn
)
2171 hc
= &msp430_hcodes
[i
];
2172 if (!hc
|| !hc
->name
)
2173 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2174 __FUNCTION__
, (long) insn
);
2175 rela
= BFD_RELOC_MSP430_10_PCREL
;
2176 /* Apply a fix for a first label if necessary.
2177 another fix will be applied to the next word of insn anyway. */
2179 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2180 fragP
->fr_offset
, TRUE
, rela
);
2186 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2187 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2189 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2192 for (i
= 0; i
< 4 && !hc
; i
++)
2193 if (msp430_hcodes
[i
].op1
== insn
)
2194 hc
= & msp430_hcodes
[i
];
2195 if (!hc
|| !hc
->name
)
2196 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2197 __FUNCTION__
, (long) insn
);
2198 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2199 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2200 bfd_putl16 (hc
->lop0
, where
);
2201 bfd_putl16 (hc
->lop1
, where
+ 2);
2202 bfd_putl16 (hc
->lop2
, where
+ 4);
2208 as_fatal (_("internal inconsistency problem in %s: %lx"),
2209 __FUNCTION__
, (long) fragP
->fr_subtype
);
2213 /* Now apply fix. */
2214 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2215 fragP
->fr_offset
, TRUE
, rela
);
2216 /* Just fixed 2 bytes. */
2220 /* Relax fragment. Mostly stolen from hc11 and mcore
2221 which arches I think I know. */
2224 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2225 long stretch ATTRIBUTE_UNUSED
)
2230 const relax_typeS
*this_type
;
2231 const relax_typeS
*start_type
;
2232 relax_substateT next_state
;
2233 relax_substateT this_state
;
2234 const relax_typeS
*table
= md_relax_table
;
2236 /* Nothing to be done if the frag has already max size. */
2237 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2238 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2241 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2243 symbolP
= fragP
->fr_symbol
;
2244 if (symbol_resolved_p (symbolP
))
2245 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2247 /* We know the offset. calculate a distance. */
2248 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2251 if (!msp430_enable_relax
)
2253 /* Relaxation is not enabled. So, make all jump as long ones
2254 by setting 'aim' to quite high value. */
2258 this_state
= fragP
->fr_subtype
;
2259 start_type
= this_type
= table
+ this_state
;
2263 /* Look backwards. */
2264 for (next_state
= this_type
->rlx_more
; next_state
;)
2265 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
2269 /* Grow to next state. */
2270 this_state
= next_state
;
2271 this_type
= table
+ this_state
;
2272 next_state
= this_type
->rlx_more
;
2277 /* Look forwards. */
2278 for (next_state
= this_type
->rlx_more
; next_state
;)
2279 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
2283 /* Grow to next state. */
2284 this_state
= next_state
;
2285 this_type
= table
+ this_state
;
2286 next_state
= this_type
->rlx_more
;
2290 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2292 fragP
->fr_subtype
= this_state
;