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"
35 We will disable polymorphs by default because it is dangerous.
36 The potencial problem here is the following: assume we got the
41 jump subroutine ; external symbol
46 In case of assembly time relaxation we'll get:
47 0: jmp .l1 <.text +0x08> (reloc deleted)
54 If the 'subroutine' wiys thin +-1024 bytes range then linker
61 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
64 The workaround is the following:
65 1. Declare global var enable_polymorphs which set to 1 via option -mP.
66 2. Declare global var enable_relax which set to 1 via option -mQ.
68 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
69 do not delete any relocs and leave them for linker.
71 If relax is enabled, relax at assembly time and kill relocs as necessary.
74 int msp430_enable_relax
;
75 int msp430_enable_polys
;
77 /* GCC uses the some condition codes which we'll
78 implement as new polymorph instructions.
80 COND EXPL SHORT JUMP LONG JUMP
81 ===============================================
82 eq == jeq jne +4; br lab
83 ne != jne jeq +4; br lab
85 ltn honours no-overflow flag
86 ltn < jn jn +2; jmp +4; br lab
88 lt < jl jge +4; br lab
89 ltu < jlo lhs +4; br lab
95 ge >= jge jl +4; br lab
96 geu >= jhs jlo +4; br lab
97 ===============================================
99 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
100 beq,bne,blt,bltn,bltu,bge,bgeu
101 'u' means unsigned compares
103 Also, we add 'jump' instruction:
104 jump UNCOND -> jmp br lab
106 They will have fmt == 4, and insn_opnumb == number of instruction. */
111 int index
; /* Corresponding insn_opnumb. */
112 int sop
; /* Opcode if jump length is short. */
113 long lpos
; /* Label position. */
114 long lop0
; /* Opcode 1 _word_ (16 bits). */
115 long lop1
; /* Opcode second word. */
116 long lop2
; /* Opcode third word. */
119 #define MSP430_RLC(n,i,sop,o1) \
120 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
122 static struct rcodes_s msp430_rcodes
[] =
124 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
125 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
126 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
127 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
128 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
129 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
130 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
131 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
137 /* More difficult than above and they have format 5.
140 =================================================================
141 gt > jeq +2; jge label jeq +6; jl +4; br label
142 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
143 leu <= jeq label; jlo label jeq +2; jhs +4; br label
144 le <= jeq label; jl label jeq +2; jge +4; br label
145 ================================================================= */
150 int index
; /* Corresponding insn_opnumb. */
151 int tlab
; /* Number of labels in short mode. */
152 int op0
; /* Opcode for first word of short jump. */
153 int op1
; /* Opcode for second word of short jump. */
154 int lop0
; /* Opcodes for long jump mode. */
159 static struct hcodes_s msp430_hcodes
[] =
161 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
162 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
163 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
164 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
168 const char comment_chars
[] = ";";
169 const char line_comment_chars
[] = "#";
170 const char line_separator_chars
[] = "";
171 const char EXP_CHARS
[] = "eE";
172 const char FLT_CHARS
[] = "dD";
174 /* Handle long expressions. */
175 extern LITTLENUM_TYPE generic_bignum
[];
177 static struct hash_control
*msp430_hash
;
180 #define STATE_UNCOND_BRANCH 1 /* jump */
181 #define STATE_NOOV_BRANCH 3 /* bltn */
182 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
183 #define STATE_EMUL_BRANCH 4
192 #define STATE_BITS10 1 /* wild guess. short jump */
193 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
194 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
196 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
197 #define RELAX_STATE(s) ((s) & 3)
198 #define RELAX_LEN(s) ((s) >> 2)
199 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
201 relax_typeS md_relax_table
[] =
209 /* Unconditional jump. */
211 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
212 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
213 {1, 1, CUBL
, 0}, /* state undef */
215 /* Simple branches. */
217 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
218 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
221 /* blt no overflow branch. */
223 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
224 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
227 /* Emulated branches. */
229 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
230 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
235 #define MAX_OP_LEN 256
244 #define MSP430_ISA_11 11
245 #define MSP430_ISA_110 110
246 #define MSP430_ISA_12 12
247 #define MSP430_ISA_13 13
248 #define MSP430_ISA_14 14
249 #define MSP430_ISA_15 15
250 #define MSP430_ISA_16 16
251 #define MSP430_ISA_21 21
252 #define MSP430_ISA_31 31
253 #define MSP430_ISA_32 32
254 #define MSP430_ISA_33 33
255 #define MSP430_ISA_41 41
256 #define MSP430_ISA_42 42
257 #define MSP430_ISA_43 43
258 #define MSP430_ISA_44 44
260 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
261 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
263 static struct mcu_type_s mcu_types
[] =
265 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
266 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
267 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
268 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
269 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
270 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
271 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
272 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
273 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
275 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
276 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
277 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
278 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
280 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
281 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
282 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
283 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
284 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
285 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
286 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
288 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
289 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
290 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
291 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
292 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
293 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
294 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
295 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
296 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
298 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
299 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
300 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
301 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
303 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
304 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
305 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
306 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
307 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
308 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
309 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
310 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
311 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
313 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
314 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
315 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
316 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
318 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
319 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
320 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
322 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
323 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
324 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
326 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
327 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
328 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
330 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
331 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
332 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
333 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
334 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
335 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
341 static struct mcu_type_s default_mcu
=
342 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
344 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
346 /* Profiling capability:
347 It is a performance hit to use gcc's profiling approach for this tiny target.
348 Even more -- jtag hardware facility does not perform any profiling functions.
349 However we've got gdb's built-in simulator where we can do anything.
350 Therefore my suggestion is:
352 We define new section ".profiler" which holds all profiling information.
353 We define new pseudo operation .profiler which will instruct assembler to
354 add new profile entry to the object file. Profile should take place at the
359 .profiler flags,function_to_profile [, cycle_corrector, extra]
361 where 'flags' is a combination of the following chars:
364 i - function is in Init section
365 f - function is in Fini section
367 c - libC standard call
368 d - stack value Demand (saved at run-time in simulator)
369 I - Interrupt service routine
374 j - long Jump/ sjlj unwind
375 a - an Arbitrary code fragment
376 t - exTra parameter saved (constant value like frame size)
377 '""' optional: "sil" == sil
379 function_to_profile - function's address
380 cycle_corrector - a value which should be added to the cycle
381 counter, zero if omitted
382 extra - some extra parameter, zero if omitted.
385 ------------------------------
389 .LFrameOffset_fxx=0x08
390 .profiler "scdP", fxx ; function entry.
391 ; we also demand stack value to be displayed
396 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
397 ; (this is a prologue end)
398 ; note, that spare var filled with the farme size
401 .profiler cdE,fxx ; check stack
406 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
407 ret ; cause 'ret' insn takes 3 cycles
408 -------------------------------
410 This profiling approach does not produce any overhead and
412 So, even profiled code can be uploaded to the MCU. */
413 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
414 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
415 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
416 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
417 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
418 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
419 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
420 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
421 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
422 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
423 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
424 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
425 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
426 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
427 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
428 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
441 for (; x
; x
= x
>> 1)
448 /* Parse ordinary expression. */
451 parse_exp (char * s
, expressionS
* op
)
453 input_line_pointer
= s
;
455 if (op
->X_op
== O_absent
)
456 as_bad (_("missing operand"));
457 return input_line_pointer
;
461 /* Delete spaces from s: X ( r 1 2) => X(r12). */
464 del_spaces (char * s
)
472 while (ISSPACE (*m
) && *m
)
474 memmove (s
, m
, strlen (m
) + 1);
482 skip_space (char * s
)
489 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
492 extract_operand (char * from
, char * to
, int limit
)
496 /* Drop leading whitespace. */
497 from
= skip_space (from
);
499 while (size
< limit
&& *from
)
501 *(to
+ size
) = *from
;
502 if (*from
== ',' || *from
== ';' || *from
== '\n')
517 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
534 s
= input_line_pointer
;
535 end
= input_line_pointer
;
537 while (*end
&& *end
!= '\n')
540 while (*s
&& *s
!= '\n')
551 as_bad (_(".profiler pseudo requires at least two operands."));
552 input_line_pointer
= end
;
556 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
565 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
568 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
571 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
574 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
577 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
580 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
583 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
586 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
589 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
592 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
595 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
598 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
601 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
604 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
607 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
610 as_warn (_("unknown profiling flag - ignored."));
617 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
618 | MSP430_PROFILER_FLAG_EXIT
))
619 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
620 | MSP430_PROFILER_FLAG_PROLEND
621 | MSP430_PROFILER_FLAG_EPISTART
622 | MSP430_PROFILER_FLAG_EPIEND
))
623 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
624 | MSP430_PROFILER_FLAG_FINISECT
))))
626 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
627 input_line_pointer
= end
;
631 /* Generate temp symbol which denotes current location. */
632 if (now_seg
== absolute_section
) /* Paranoja ? */
634 exp1
.X_op
= O_constant
;
635 exp1
.X_add_number
= abs_section_offset
;
636 as_warn (_("profiling in absolute section? Hm..."));
640 exp1
.X_op
= O_symbol
;
641 exp1
.X_add_symbol
= symbol_temp_new_now ();
642 exp1
.X_add_number
= 0;
645 /* Generate a symbol which holds flags value. */
646 exp
.X_op
= O_constant
;
647 exp
.X_add_number
= p_flags
;
649 /* Save current section. */
653 /* Now go to .profiler section. */
654 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
657 emit_expr (& exp
, 2);
659 /* Save label value. */
660 emit_expr (& exp1
, 2);
664 /* Now get profiling info. */
665 halt
= extract_operand (input_line_pointer
, str
, 1024);
666 /* Process like ".word xxx" directive. */
667 parse_exp (str
, & exp
);
668 emit_expr (& exp
, 2);
669 input_line_pointer
= halt
;
672 /* Fill the rest with zeros. */
673 exp
.X_op
= O_constant
;
674 exp
.X_add_number
= 0;
676 emit_expr (& exp
, 2);
678 /* Return to current section. */
679 subseg_set (seg
, subseg
);
683 extract_word (char * from
, char * to
, int limit
)
689 /* Drop leading whitespace. */
690 from
= skip_space (from
);
693 /* Find the op code end. */
694 for (op_start
= op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
696 to
[size
++] = *op_end
++;
697 if (size
+ 1 >= limit
)
705 #define OPTION_MMCU 'm'
706 #define OPTION_RELAX 'Q'
707 #define OPTION_POLYMORPHS 'P'
710 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
712 char *str
= (char *) alloca (32); /* 32 for good measure. */
714 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
716 md_parse_option (OPTION_MMCU
, str
);
717 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
721 show_mcu_list (FILE * stream
)
725 fprintf (stream
, _("Known MCU names:\n"));
727 for (i
= 0; mcu_types
[i
].name
; i
++)
728 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
730 fprintf (stream
, "\n");
734 md_parse_option (int c
, char * arg
)
741 for (i
= 0; mcu_types
[i
].name
; ++i
)
742 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
745 if (!mcu_types
[i
].name
)
747 show_mcu_list (stderr
);
748 as_fatal (_("unknown MCU: %s\n"), arg
);
751 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
752 msp430_mcu
= &mcu_types
[i
];
754 as_fatal (_("redefinition of mcu type %s' to %s'"),
755 msp430_mcu
->name
, mcu_types
[i
].name
);
760 msp430_enable_relax
= 1;
764 case OPTION_POLYMORPHS
:
765 msp430_enable_polys
= 1;
774 const pseudo_typeS md_pseudo_table
[] =
776 {"arch", msp430_set_arch
, 0},
777 {"profiler", msp430_profiler
, 0},
781 const char *md_shortopts
= "m:";
783 struct option md_longopts
[] =
785 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
786 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
787 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
788 {NULL
, no_argument
, NULL
, 0}
791 size_t md_longopts_size
= sizeof (md_longopts
);
794 md_show_usage (FILE * stream
)
797 _("MSP430 options:\n"
798 " -mmcu=[msp430-name] select microcontroller type\n"
799 " msp430x110 msp430x112\n"
800 " msp430x1101 msp430x1111\n"
801 " msp430x1121 msp430x1122 msp430x1132\n"
802 " msp430x122 msp430x123\n"
803 " msp430x1222 msp430x1232\n"
804 " msp430x133 msp430x135\n"
805 " msp430x1331 msp430x1351\n"
806 " msp430x147 msp430x148 msp430x149\n"
807 " msp430x155 msp430x156 msp430x157\n"
808 " msp430x167 msp430x168 msp430x169\n"
809 " msp430x1610 msp430x1611 msp430x1612\n"
810 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
811 " msp430x323 msp430x325\n"
812 " msp430x336 msp430x337\n"
813 " msp430x412 msp430x413 msp430x415 msp430x417\n"
814 " msp430xE423 msp430xE425 msp430E427\n"
815 " msp430xW423 msp430xW425 msp430W427\n"
816 " msp430xG437 msp430xG438 msp430G439\n"
817 " msp430x435 msp430x436 msp430x437\n"
818 " msp430x447 msp430x448 msp430x449\n"));
820 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
821 " -mP - enable polymorph instructions\n"));
823 show_mcu_list (stream
);
827 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
833 extract_cmd (char * from
, char * to
, int limit
)
837 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
839 *(to
+ size
) = *from
;
849 /* Turn a string in input_line_pointer into a floating point constant
850 of type TYPE, and store the appropriate bytes in *LITP. The number
851 of LITTLENUMS emitted is stored in *SIZEP. An error message is
852 returned, or NULL on OK. */
855 md_atof (int type
, char * litP
, int * sizeP
)
858 LITTLENUM_TYPE words
[4];
859 LITTLENUM_TYPE
*wordP
;
872 return _("bad call to md_atof");
875 t
= atof_ieee (input_line_pointer
, type
, words
);
877 input_line_pointer
= t
;
879 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
881 /* This loop outputs the LITTLENUMs in REVERSE order. */
882 for (wordP
= words
+ prec
- 1; prec
--;)
884 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
885 litP
+= sizeof (LITTLENUM_TYPE
);
894 struct msp430_opcode_s
* opcode
;
895 msp430_hash
= hash_new ();
897 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
898 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
900 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
906 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
908 if (strlen (t
) > 2 && *(t
+ 2) != '+')
913 if ((*t
< '0' || *t
> '9') && *t
!= '+')
926 msp430_srcoperand (struct msp430_operand_s
* op
,
927 char * l
, int bin
, int * imm_op
)
931 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
938 /* Check if there is:
939 llo(x) - least significant 16 bits, x &= 0xffff
940 lhi(x) - x = (x >> 16) & 0xffff,
941 hlo(x) - x = (x >> 32) & 0xffff,
942 hhi(x) - x = (x >> 48) & 0xffff
943 The value _MUST_ be constant expression: #hlo(1231231231). */
947 if (strncasecmp (h
, "#llo(", 5) == 0)
952 else if (strncasecmp (h
, "#lhi(", 5) == 0)
957 else if (strncasecmp (h
, "#hlo(", 5) == 0)
962 else if (strncasecmp (h
, "#hhi(", 5) == 0)
967 else if (strncasecmp (h
, "#lo(", 4) == 0)
972 else if (strncasecmp (h
, "#hi(", 4) == 0)
978 op
->reg
= 0; /* Reg PC. */
980 op
->ol
= 1; /* Immediate will follow an instruction. */
984 parse_exp (__tl
, &(op
->exp
));
985 if (op
->exp
.X_op
== O_constant
)
987 int x
= op
->exp
.X_add_number
;
992 op
->exp
.X_add_number
= x
;
994 else if (vshift
== 1)
996 x
= (x
>> 16) & 0xffff;
997 op
->exp
.X_add_number
= x
;
1002 op
->exp
.X_add_number
= -1;
1004 op
->exp
.X_add_number
= 0; /* Nothing left. */
1005 x
= op
->exp
.X_add_number
;
1008 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1010 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1014 /* Now check constants. */
1015 /* Substitute register mode with a constant generator if applicable. */
1017 x
= (short) x
; /* Extend sign. */
1049 #ifdef PUSH_1X_WORKAROUND
1052 /* Remove warning as confusing.
1053 as_warn(_("Hardware push bug workaround")); */
1066 #ifdef PUSH_1X_WORKAROUND
1069 /* Remove warning as confusing.
1070 as_warn(_("Hardware push bug workaround")); */
1082 else if (op
->exp
.X_op
== O_symbol
)
1086 else if (op
->exp
.X_op
== O_big
)
1091 op
->exp
.X_op
= O_constant
;
1092 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1093 x
= op
->exp
.X_add_number
;
1098 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1146 /* Redudant (yet) check. */
1147 else if (op
->exp
.X_op
== O_register
)
1149 (_("Registers cannot be used within immediate expression [%s]"), l
);
1151 as_bad (_("unknown operand %s"), l
);
1156 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1161 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1162 op
->am
= 1; /* mode As == 01 bin. */
1163 op
->ol
= 1; /* Immediate value followed by instruction. */
1165 parse_exp (__tl
, &(op
->exp
));
1167 if (op
->exp
.X_op
== O_constant
)
1169 int x
= op
->exp
.X_add_number
;
1171 if (x
> 65535 || x
< -32768)
1173 as_bad (_("value out of range: %d"), x
);
1177 else if (op
->exp
.X_op
== O_symbol
)
1181 /* Redudant (yet) check. */
1182 if (op
->exp
.X_op
== O_register
)
1184 (_("Registers cannot be used within absolute expression [%s]"), l
);
1186 as_bad (_("unknown expression in operand %s"), l
);
1192 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1196 char *m
= strchr (l
, '+');
1200 as_bad (_("unknown addressing mode %s"), l
);
1205 if (*t
!= 'r' && *t
!= 'R')
1207 as_bad (_("unknown addressing mode %s"), l
);
1211 t
++; /* Points to the reg value. */
1215 as_bad (_("Bad register name r%s"), t
);
1223 *m
= 0; /* strip '+' */
1225 if (op
->reg
< 0 || op
->reg
> 15)
1227 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1234 /* Check if register indexed X(Rn). */
1237 char *h
= strrchr (l
, '(');
1238 char *m
= strrchr (l
, ')');
1247 as_bad (_("')' required"));
1254 /* Extract a register. */
1255 t
++; /* Advance pointer. */
1257 if (*t
!= 'r' && *t
!= 'R')
1260 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1267 if (op
->reg
> 9 || op
->reg
< 0)
1269 as_bad (_("unknown operator (r%s substituded as a register name"),
1276 op
->reg
= op
->reg
* 10;
1277 op
->reg
+= *t
- '0';
1281 as_bad (_("unknown operator %s"), l
);
1286 as_bad (_("r2 should not be used in indexed addressing mode"));
1290 if (*(t
+ 1) != ')')
1292 as_bad (_("unknown operator %s"), l
);
1297 /* Extract constant. */
1301 parse_exp (__tl
, &(op
->exp
));
1302 if (op
->exp
.X_op
== O_constant
)
1304 int x
= op
->exp
.X_add_number
;
1306 if (x
> 65535 || x
< -32768)
1308 as_bad (_("value out of range: %d"), x
);
1320 else if (op
->exp
.X_op
== O_symbol
)
1324 /* Redudant (yet) check. */
1325 if (op
->exp
.X_op
== O_register
)
1327 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1329 as_bad (_("unknown expression in operand %s"), l
);
1337 /* Register mode 'mov r1,r2'. */
1342 /* Operand should be a register. */
1343 if (*t
== 'r' || *t
== 'R')
1345 int x
= atoi (t
+ 1);
1347 if (check_reg (t
+ 1))
1350 if (x
< 0 || x
> 15)
1351 break; /* Symbolic mode. */
1362 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1366 op
->reg
= 0; /* PC relative... be careful. */
1370 parse_exp (__tl
, &(op
->exp
));
1376 as_bad (_("unknown addressing mode for operand %s"), l
);
1382 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1385 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1397 parse_exp (__tl
, &(op
->exp
));
1399 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1401 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1411 ("this addressing mode is not applicable for destination operand"));
1418 /* Parse instruction operands.
1419 Return binary opcode. */
1422 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1424 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1426 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1429 struct msp430_operand_s op1
, op2
;
1431 static short ZEROS
= 0;
1432 int byte_op
, imm_op
;
1434 /* Opcode is the one from opcodes table
1435 line contains something like
1440 /* Check if byte or word operation. */
1441 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1443 bin
|= BYTE_OPERATION
;
1450 while (! ISSPACE (*line
) && *line
)
1453 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1455 as_bad (_("instruction %s requires %d operand(s)"),
1456 opcode
->name
, opcode
->insn_opnumb
);
1460 memset (l1
, 0, sizeof (l1
));
1461 memset (l2
, 0, sizeof (l2
));
1462 memset (&op1
, 0, sizeof (op1
));
1463 memset (&op2
, 0, sizeof (op2
));
1467 switch (opcode
->fmt
)
1469 case 0: /* Emulated. */
1470 switch (opcode
->insn_opnumb
)
1473 /* Set/clear bits instructions. */
1475 frag
= frag_more (__is
);
1476 bfd_putl16 ((bfd_vma
) bin
, frag
);
1479 /* Something which works with destination operand. */
1480 line
= extract_operand (line
, l1
, sizeof (l1
));
1481 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1485 bin
|= (op1
.reg
| (op1
.am
<< 7));
1487 frag
= frag_more (2 * __is
);
1488 where
= frag
- frag_now
->fr_literal
;
1489 bfd_putl16 ((bfd_vma
) bin
, frag
);
1491 if (op1
.mode
== OP_EXP
)
1494 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1497 fix_new_exp (frag_now
, where
, 2,
1498 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1500 fix_new_exp (frag_now
, where
, 2,
1501 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1507 /* Shift instruction. */
1508 line
= extract_operand (line
, l1
, sizeof (l1
));
1509 strncpy (l2
, l1
, sizeof (l2
));
1510 l2
[sizeof (l2
) - 1] = '\0';
1511 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1512 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1515 break; /* An error occurred. All warnings were done before. */
1517 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1519 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1520 frag
= frag_more (2 * __is
);
1521 where
= frag
- frag_now
->fr_literal
;
1522 bfd_putl16 ((bfd_vma
) bin
, frag
);
1524 if (op1
.mode
== OP_EXP
)
1526 where
+= 2; /* Advance 'where' as we do not know _where_. */
1527 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1529 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1530 fix_new_exp (frag_now
, where
, 2,
1531 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1533 fix_new_exp (frag_now
, where
, 2,
1534 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1537 if (op2
.mode
== OP_EXP
)
1540 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1542 if (op2
.reg
) /* Not PC relative. */
1543 fix_new_exp (frag_now
, where
+ 2, 2,
1544 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1546 fix_new_exp (frag_now
, where
+ 2, 2,
1547 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1552 /* Branch instruction => mov dst, r0. */
1553 line
= extract_operand (line
, l1
, sizeof (l1
));
1555 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1562 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1564 frag
= frag_more (2 * __is
);
1565 where
= frag
- frag_now
->fr_literal
;
1566 bfd_putl16 ((bfd_vma
) bin
, frag
);
1568 if (op1
.mode
== OP_EXP
)
1571 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1573 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1574 fix_new_exp (frag_now
, where
, 2,
1575 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1577 fix_new_exp (frag_now
, where
, 2,
1578 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1584 case 1: /* Format 1, double operand. */
1585 line
= extract_operand (line
, l1
, sizeof (l1
));
1586 line
= extract_operand (line
, l2
, sizeof (l2
));
1587 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1588 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1591 break; /* Error occurred. All warnings were done before. */
1593 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1595 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1596 frag
= frag_more (2 * __is
);
1597 where
= frag
- frag_now
->fr_literal
;
1598 bfd_putl16 ((bfd_vma
) bin
, frag
);
1600 if (op1
.mode
== OP_EXP
)
1602 where
+= 2; /* Advance where as we do not know _where_. */
1603 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1605 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1606 fix_new_exp (frag_now
, where
, 2,
1607 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1609 fix_new_exp (frag_now
, where
, 2,
1610 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1613 if (op2
.mode
== OP_EXP
)
1616 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1618 if (op2
.reg
) /* Not PC relative. */
1619 fix_new_exp (frag_now
, where
+ 2, 2,
1620 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1622 fix_new_exp (frag_now
, where
+ 2, 2,
1623 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1627 case 2: /* Single-operand mostly instr. */
1628 if (opcode
->insn_opnumb
== 0)
1630 /* reti instruction. */
1631 frag
= frag_more (2);
1632 bfd_putl16 ((bfd_vma
) bin
, frag
);
1636 line
= extract_operand (line
, l1
, sizeof (l1
));
1637 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1639 break; /* Error in operand. */
1641 bin
|= op1
.reg
| (op1
.am
<< 4);
1643 frag
= frag_more (2 * __is
);
1644 where
= frag
- frag_now
->fr_literal
;
1645 bfd_putl16 ((bfd_vma
) bin
, frag
);
1647 if (op1
.mode
== OP_EXP
)
1649 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1651 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1652 fix_new_exp (frag_now
, where
+ 2, 2,
1653 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1655 fix_new_exp (frag_now
, where
+ 2, 2,
1656 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1660 case 3: /* Conditional jumps instructions. */
1661 line
= extract_operand (line
, l1
, sizeof (l1
));
1662 /* l1 is a label. */
1671 parse_exp (m
, &exp
);
1672 frag
= frag_more (2); /* Instr size is 1 word. */
1674 /* In order to handle something like:
1678 jz 4 ; skip next 4 bytes
1681 nop ; will jump here if r5 positive or zero
1683 jCOND -n ;assumes jump n bytes backward:
1693 jCOND $n ; jump from PC in either direction. */
1695 if (exp
.X_op
== O_constant
)
1697 int x
= exp
.X_add_number
;
1701 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1705 if ((*l1
== '$' && x
> 0) || x
< 0)
1710 if (x
> 512 || x
< -511)
1712 as_bad (_("Wrong displacement %d"), x
<< 1);
1717 bfd_putl16 ((bfd_vma
) bin
, frag
);
1719 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1721 where
= frag
- frag_now
->fr_literal
;
1722 fix_new_exp (frag_now
, where
, 2,
1723 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1725 bfd_putl16 ((bfd_vma
) bin
, frag
);
1727 else if (*l1
== '$')
1729 as_bad (_("instruction requires label sans '$'"));
1735 ("instruction requires label or value in range -511:512"));
1741 as_bad (_("instruction requires label"));
1746 case 4: /* Extended jumps. */
1747 if (!msp430_enable_polys
)
1749 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1753 line
= extract_operand (line
, l1
, sizeof (l1
));
1759 /* Ignore absolute addressing. make it PC relative anyway. */
1760 if (*m
== '#' || *m
== '$')
1763 parse_exp (m
, & exp
);
1764 if (exp
.X_op
== O_symbol
)
1766 /* Relaxation required. */
1767 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1769 frag
= frag_more (8);
1770 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1771 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1772 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1774 0, /* Offset is zero if jump dist less than 1K. */
1780 as_bad (_("instruction requires label"));
1783 case 5: /* Emulated extended branches. */
1784 if (!msp430_enable_polys
)
1786 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1789 line
= extract_operand (line
, l1
, sizeof (l1
));
1795 /* Ignore absolute addressing. make it PC relative anyway. */
1796 if (*m
== '#' || *m
== '$')
1799 parse_exp (m
, & exp
);
1800 if (exp
.X_op
== O_symbol
)
1802 /* Relaxation required. */
1803 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1805 frag
= frag_more (8);
1806 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1807 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1808 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1809 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1811 0, /* Offset is zero if jump dist less than 1K. */
1817 as_bad (_("instruction requires label"));
1821 as_bad (_("Ilegal instruction or not implmented opcode."));
1824 input_line_pointer
= line
;
1829 md_assemble (char * str
)
1831 struct msp430_opcode_s
* opcode
;
1835 str
= skip_space (str
); /* Skip leading spaces. */
1836 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1838 while (cmd
[i
] && i
< sizeof (cmd
))
1840 char a
= TOLOWER (cmd
[i
]);
1847 as_bad (_("can't find opcode "));
1851 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1855 as_bad (_("unknown opcode `%s'"), cmd
);
1860 char *__t
= input_line_pointer
;
1862 msp430_operands (opcode
, str
);
1863 input_line_pointer
= __t
;
1867 /* GAS will call this function for each section at the end of the assembly,
1868 to permit the CPU backend to adjust the alignment of a section. */
1871 md_section_align (asection
* seg
, valueT addr
)
1873 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1875 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1878 /* If you define this macro, it should return the offset between the
1879 address of a PC relative fixup and the position from which the PC
1880 relative adjustment should be made. On many processors, the base
1881 of a PC relative instruction is the next instruction, so this
1882 macro would return the length of an instruction. */
1885 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1887 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1888 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1889 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1892 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1895 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1896 Now it handles the situation when relocations
1897 have to be passed to linker. */
1899 msp430_force_relocation_local(fixS
*fixp
)
1901 if (msp430_enable_polys
1902 && !msp430_enable_relax
)
1905 return (!fixp
->fx_pcrel
1907 || generic_force_reloc(fixp
));
1911 /* GAS will call this for each fixup. It should store the correct
1912 value in the object file. */
1914 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1916 unsigned char * where
;
1920 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1925 else if (fixp
->fx_pcrel
)
1927 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1929 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1931 /* FIXME: We can appear here only in case if we perform a pc
1932 relative jump to the label which is i) global, ii) locally
1933 defined or this is a jump to an absolute symbol.
1934 If this is an absolute symbol -- everything is OK.
1935 If this is a global label, we've got a symbol value defined
1937 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1938 from this section start
1939 2. *valuep will contain the real offset from jump insn to the
1941 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1942 will be incorrect. Therefore remove s_get_value. */
1943 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1951 value
= fixp
->fx_offset
;
1953 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1955 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1957 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1962 /* We don't actually support subtracting a symbol. */
1963 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1964 _("expression too complex"));
1969 fixp
->fx_no_overflow
= 1;
1971 /* if polymorphs are enabled and relax disabled.
1972 do not kill any relocs and pass them to linker. */
1973 if (msp430_enable_polys
1974 && !msp430_enable_relax
)
1976 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
1977 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
1978 fixp
->fx_done
= 1; /* it is ok to kill 'abs' reloc */
1985 /* Fetch the instruction, insert the fully resolved operand
1986 value, and stuff the instruction back again. */
1988 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
1990 insn
= bfd_getl16 (where
);
1992 switch (fixp
->fx_r_type
)
1994 case BFD_RELOC_MSP430_10_PCREL
:
1996 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1997 _("odd address operand: %ld"), value
);
1999 /* Jumps are in words. */
2001 --value
; /* Correct PC. */
2003 if (value
< -512 || value
> 511)
2004 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2005 _("operand out of range: %ld"), value
);
2007 value
&= 0x3ff; /* get rid of extended sign */
2008 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
2011 case BFD_RELOC_MSP430_RL_PCREL
:
2012 case BFD_RELOC_MSP430_16_PCREL
:
2014 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2015 _("odd address operand: %ld"), value
);
2017 /* Nothing to be corrected here. */
2018 if (value
< -32768 || value
> 65536)
2019 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2020 _("operand out of range: %ld"), value
);
2022 value
&= 0xffff; /* Get rid of extended sign. */
2023 bfd_putl16 ((bfd_vma
) value
, where
);
2026 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
2027 /* Nothing to be corrected here. */
2028 if (value
< -32768 || value
> 65536)
2029 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2030 _("operand out of range: %ld"), value
);
2032 value
&= 0xffff; /* Get rid of extended sign. */
2033 bfd_putl16 ((bfd_vma
) value
, where
);
2037 bfd_putl16 ((bfd_vma
) value
, where
);
2040 case BFD_RELOC_MSP430_16
:
2042 case BFD_RELOC_MSP430_16_BYTE
:
2044 bfd_putl16 ((bfd_vma
) value
, where
);
2048 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2049 fixp
->fx_line
, fixp
->fx_r_type
);
2055 fixp
->fx_addnumber
= value
;
2059 /* GAS will call this to generate a reloc, passing the resulting reloc
2060 to `bfd_install_relocation'. This currently works poorly, as
2061 `bfd_install_relocation' often does the wrong thing, and instances of
2062 `tc_gen_reloc' have been written to work around the problems, which
2063 in turns makes it difficult to fix `bfd_install_relocation'. */
2065 /* If while processing a fixup, a reloc really needs to be created
2066 then it is done here. */
2069 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
2073 reloc
= xmalloc (sizeof (arelent
));
2075 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
2076 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2078 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2079 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2080 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2082 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2083 _("reloc %d not supported by object file format"),
2084 (int) fixp
->fx_r_type
);
2088 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
2089 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
2090 reloc
->address
= fixp
->fx_offset
;
2092 reloc
->addend
= fixp
->fx_offset
;
2098 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2099 asection
* segment_type ATTRIBUTE_UNUSED
)
2101 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2103 /* This is a jump -> pcrel mode. Nothing to do much here.
2104 Return value == 2. */
2106 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2108 else if (fragP
->fr_symbol
)
2110 /* Its got a segment, but its not ours. Even if fr_symbol is in
2111 an absolute segment, we dont know a displacement until we link
2112 object files. So it will always be long. This also applies to
2113 labels in a subsegment of current. Liker may relax it to short
2114 jump later. Return value == 8. */
2116 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2120 /* We know the abs value. may be it is a jump to fixed address.
2121 Impossible in our case, cause all constants already handeled. */
2123 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2126 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2130 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2131 asection
* sec ATTRIBUTE_UNUSED
,
2137 struct rcodes_s
* cc
= NULL
;
2138 struct hcodes_s
* hc
= NULL
;
2140 switch (fragP
->fr_subtype
)
2142 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2143 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2144 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2145 /* We do not have to convert anything here.
2146 Just apply a fix. */
2147 rela
= BFD_RELOC_MSP430_10_PCREL
;
2150 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2151 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2152 /* Convert uncond branch jmp lab -> br lab. */
2153 cc
= & msp430_rcodes
[7];
2154 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2155 bfd_putl16 (cc
->lop0
, where
);
2156 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2160 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2161 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2163 /* Other simple branches. */
2164 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2167 /* Find actual instruction. */
2168 for (i
= 0; i
< 7 && !cc
; i
++)
2169 if (msp430_rcodes
[i
].sop
== insn
)
2170 cc
= & msp430_rcodes
[i
];
2171 if (!cc
|| !cc
->name
)
2172 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2173 __FUNCTION__
, (long) insn
);
2174 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2175 bfd_putl16 (cc
->lop0
, where
);
2176 bfd_putl16 (cc
->lop1
, where
+ 2);
2177 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2182 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2183 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2184 cc
= & msp430_rcodes
[6];
2185 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2186 bfd_putl16 (cc
->lop0
, where
);
2187 bfd_putl16 (cc
->lop1
, where
+ 2);
2188 bfd_putl16 (cc
->lop2
, where
+ 4);
2189 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2193 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2195 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2198 for (i
= 0; i
< 4 && !hc
; i
++)
2199 if (msp430_hcodes
[i
].op1
== insn
)
2200 hc
= &msp430_hcodes
[i
];
2201 if (!hc
|| !hc
->name
)
2202 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2203 __FUNCTION__
, (long) insn
);
2204 rela
= BFD_RELOC_MSP430_10_PCREL
;
2205 /* Apply a fix for a first label if necessary.
2206 another fix will be applied to the next word of insn anyway. */
2208 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2209 fragP
->fr_offset
, TRUE
, rela
);
2215 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2216 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2218 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2221 for (i
= 0; i
< 4 && !hc
; i
++)
2222 if (msp430_hcodes
[i
].op1
== insn
)
2223 hc
= & msp430_hcodes
[i
];
2224 if (!hc
|| !hc
->name
)
2225 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2226 __FUNCTION__
, (long) insn
);
2227 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2228 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2229 bfd_putl16 (hc
->lop0
, where
);
2230 bfd_putl16 (hc
->lop1
, where
+ 2);
2231 bfd_putl16 (hc
->lop2
, where
+ 4);
2237 as_fatal (_("internal inconsistency problem in %s: %lx"),
2238 __FUNCTION__
, (long) fragP
->fr_subtype
);
2242 /* Now apply fix. */
2243 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2244 fragP
->fr_offset
, TRUE
, rela
);
2245 /* Just fixed 2 bytes. */
2249 /* Relax fragment. Mostly stolen from hc11 and mcore
2250 which arches I think I know. */
2253 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2254 long stretch ATTRIBUTE_UNUSED
)
2259 const relax_typeS
*this_type
;
2260 const relax_typeS
*start_type
;
2261 relax_substateT next_state
;
2262 relax_substateT this_state
;
2263 const relax_typeS
*table
= md_relax_table
;
2265 /* Nothing to be done if the frag has already max size. */
2266 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2267 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2270 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2272 symbolP
= fragP
->fr_symbol
;
2273 if (symbol_resolved_p (symbolP
))
2274 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2276 /* We know the offset. calculate a distance. */
2277 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2280 if (!msp430_enable_relax
)
2282 /* Relaxation is not enabled. So, make all jump as long ones
2283 by setting 'aim' to quite high value. */
2287 this_state
= fragP
->fr_subtype
;
2288 start_type
= this_type
= table
+ this_state
;
2292 /* Look backwards. */
2293 for (next_state
= this_type
->rlx_more
; next_state
;)
2294 if (aim
>= this_type
->rlx_backward
)
2298 /* Grow to next state. */
2299 this_state
= next_state
;
2300 this_type
= table
+ this_state
;
2301 next_state
= this_type
->rlx_more
;
2306 /* Look forwards. */
2307 for (next_state
= this_type
->rlx_more
; next_state
;)
2308 if (aim
<= this_type
->rlx_forward
)
2312 /* Grow to next state. */
2313 this_state
= next_state
;
2314 this_type
= table
+ this_state
;
2315 next_state
= this_type
->rlx_more
;
2319 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2321 fragP
->fr_subtype
= this_state
;