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"
34 /* GCC uses the some condition codes which we'll
35 implement as new polymorph instructions.
37 COND EXPL SHORT JUMP LONG JUMP
38 ===============================================
39 eq == jeq jne +4; br lab
40 ne != jne jeq +4; br lab
42 ltn honours no-overflow flag
43 ltn < jn jn +2; jmp +4; br lab
45 lt < jl jge +4; br lab
46 ltu < jlo lhs +4; br lab
52 ge >= jge jl +4; br lab
53 geu >= jhs jlo +4; br lab
54 ===============================================
56 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
57 beq,bne,blt,bltn,bltu,bge,bgeu
58 'u' means unsigned compares
60 Also, we add 'jump' instruction:
61 jump UNCOND -> jmp br lab
63 They will have fmt == 4, and insn_opnumb == number of instruction. */
68 int index
; /* Corresponding insn_opnumb. */
69 int sop
; /* Opcode if jump length is short. */
70 long lpos
; /* Label position. */
71 long lop0
; /* Opcode 1 _word_ (16 bits). */
72 long lop1
; /* Opcode second word. */
73 long lop2
; /* Opcode third word. */
76 #define MSP430_RLC(n,i,sop,o1) \
77 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
79 static struct rcodes_s msp430_rcodes
[] =
81 MSP430_RLC (beq
, 0, 0x2400, 0x2000),
82 MSP430_RLC (bne
, 1, 0x2000, 0x2400),
83 MSP430_RLC (blt
, 2, 0x3800, 0x3400),
84 MSP430_RLC (bltu
, 3, 0x2800, 0x2c00),
85 MSP430_RLC (bge
, 4, 0x3400, 0x3800),
86 MSP430_RLC (bgeu
, 5, 0x2c00, 0x2800),
87 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
88 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
94 /* More difficult than above and they have format 5.
97 =================================================================
98 gt > jeq +2; jge label jeq +6; jl +4; br label
99 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
100 leu <= jeq label; jlo label jeq +2; jhs +4; br label
101 le <= jeq label; jl label jeq +2; jge +4; br label
102 ================================================================= */
107 int index
; /* Corresponding insn_opnumb. */
108 int tlab
; /* Number of labels in short mode. */
109 int op0
; /* Opcode for first word of short jump. */
110 int op1
; /* Opcode for second word of short jump. */
111 int lop0
; /* Opcodes for long jump mode. */
116 static struct hcodes_s msp430_hcodes
[] =
118 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
119 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
120 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
121 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
125 const char comment_chars
[] = ";";
126 const char line_comment_chars
[] = "#";
127 const char line_separator_chars
[] = "";
128 const char EXP_CHARS
[] = "eE";
129 const char FLT_CHARS
[] = "dD";
131 /* Handle long expressions. */
132 extern LITTLENUM_TYPE generic_bignum
[];
134 static struct hash_control
*msp430_hash
;
137 #define STATE_UNCOND_BRANCH 1 /* jump */
138 #define STATE_NOOV_BRANCH 3 /* bltn */
139 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
140 #define STATE_EMUL_BRANCH 4
149 #define STATE_BITS10 1 /* wild guess. short jump */
150 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
151 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
153 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
154 #define RELAX_STATE(s) ((s) & 3)
155 #define RELAX_LEN(s) ((s) >> 2)
156 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
158 relax_typeS md_relax_table
[] =
166 /* Unconditional jump. */
168 {1024, -1024, CNRL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
169 {0, 0, CUBL
, RELAX_NEXT (STATE_UNCOND_BRANCH
, STATE_WORD
)}, /* state word */
170 {1, 1, CUBL
, 0}, /* state undef */
172 /* Simple branches. */
174 {1024, -1024, CNRL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
175 {0, 0, CSBL
, RELAX_NEXT (STATE_SIMPLE_BRANCH
, STATE_WORD
)}, /* state word */
178 /* blt no overflow branch. */
180 {1024, -1024, CNRL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
181 {0, 0, CNOL
, RELAX_NEXT (STATE_NOOV_BRANCH
, STATE_WORD
)}, /* state word */
184 /* Emulated branches. */
186 {1020, -1020, CEBL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_BITS10
)}, /* state 10 bits displ */
187 {0, 0, CNOL
, RELAX_NEXT (STATE_EMUL_BRANCH
, STATE_WORD
)}, /* state word */
192 #define MAX_OP_LEN 256
201 #define MSP430_ISA_11 11
202 #define MSP430_ISA_110 110
203 #define MSP430_ISA_12 12
204 #define MSP430_ISA_13 13
205 #define MSP430_ISA_14 14
206 #define MSP430_ISA_15 15
207 #define MSP430_ISA_16 16
208 #define MSP430_ISA_21 21
209 #define MSP430_ISA_31 31
210 #define MSP430_ISA_32 32
211 #define MSP430_ISA_33 33
212 #define MSP430_ISA_41 41
213 #define MSP430_ISA_42 42
214 #define MSP430_ISA_43 43
215 #define MSP430_ISA_44 44
217 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
218 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
220 static struct mcu_type_s mcu_types
[] =
222 {"msp1", MSP430_ISA_11
, bfd_mach_msp11
},
223 {"msp2", MSP430_ISA_14
, bfd_mach_msp14
},
224 {"msp430x110", MSP430_ISA_11
, bfd_mach_msp11
},
225 {"msp430x112", MSP430_ISA_11
, bfd_mach_msp11
},
226 {"msp430x1101", MSP430_ISA_110
, bfd_mach_msp110
},
227 {"msp430x1111", MSP430_ISA_110
, bfd_mach_msp110
},
228 {"msp430x1121", MSP430_ISA_110
, bfd_mach_msp110
},
229 {"msp430x1122", MSP430_ISA_11
, bfd_mach_msp110
},
230 {"msp430x1132", MSP430_ISA_11
, bfd_mach_msp110
},
232 {"msp430x122", MSP430_ISA_12
, bfd_mach_msp12
},
233 {"msp430x123", MSP430_ISA_12
, bfd_mach_msp12
},
234 {"msp430x1222", MSP430_ISA_12
, bfd_mach_msp12
},
235 {"msp430x1232", MSP430_ISA_12
, bfd_mach_msp12
},
237 {"msp430x133", MSP430_ISA_13
, bfd_mach_msp13
},
238 {"msp430x135", MSP430_ISA_13
, bfd_mach_msp13
},
239 {"msp430x1331", MSP430_ISA_13
, bfd_mach_msp13
},
240 {"msp430x1351", MSP430_ISA_13
, bfd_mach_msp13
},
241 {"msp430x147", MSP430_ISA_14
, bfd_mach_msp14
},
242 {"msp430x148", MSP430_ISA_14
, bfd_mach_msp14
},
243 {"msp430x149", MSP430_ISA_14
, bfd_mach_msp14
},
245 {"msp430x155", MSP430_ISA_15
, bfd_mach_msp15
},
246 {"msp430x156", MSP430_ISA_15
, bfd_mach_msp15
},
247 {"msp430x157", MSP430_ISA_15
, bfd_mach_msp15
},
248 {"msp430x167", MSP430_ISA_16
, bfd_mach_msp16
},
249 {"msp430x168", MSP430_ISA_16
, bfd_mach_msp16
},
250 {"msp430x169", MSP430_ISA_16
, bfd_mach_msp16
},
251 {"msp430x1610", MSP430_ISA_16
, bfd_mach_msp16
},
252 {"msp430x1611", MSP430_ISA_16
, bfd_mach_msp16
},
253 {"msp430x1612", MSP430_ISA_16
, bfd_mach_msp16
},
255 {"msp430x2101", MSP430_ISA_21
, bfd_mach_msp21
},
256 {"msp430x2111", MSP430_ISA_21
, bfd_mach_msp21
},
257 {"msp430x2121", MSP430_ISA_21
, bfd_mach_msp21
},
258 {"msp430x2131", MSP430_ISA_21
, bfd_mach_msp21
},
260 {"msp430x311", MSP430_ISA_31
, bfd_mach_msp31
},
261 {"msp430x312", MSP430_ISA_31
, bfd_mach_msp31
},
262 {"msp430x313", MSP430_ISA_31
, bfd_mach_msp31
},
263 {"msp430x314", MSP430_ISA_31
, bfd_mach_msp31
},
264 {"msp430x315", MSP430_ISA_31
, bfd_mach_msp31
},
265 {"msp430x323", MSP430_ISA_32
, bfd_mach_msp32
},
266 {"msp430x325", MSP430_ISA_32
, bfd_mach_msp32
},
267 {"msp430x336", MSP430_ISA_33
, bfd_mach_msp33
},
268 {"msp430x337", MSP430_ISA_33
, bfd_mach_msp33
},
270 {"msp430x412", MSP430_ISA_41
, bfd_mach_msp41
},
271 {"msp430x413", MSP430_ISA_41
, bfd_mach_msp41
},
272 {"msp430x415", MSP430_ISA_41
, bfd_mach_msp41
},
273 {"msp430x417", MSP430_ISA_41
, bfd_mach_msp41
},
275 {"msp430xE423", MSP430_ISA_42
, bfd_mach_msp42
},
276 {"msp430xE425", MSP430_ISA_42
, bfd_mach_msp42
},
277 {"msp430xE427", MSP430_ISA_42
, bfd_mach_msp42
},
279 {"msp430xW423", MSP430_ISA_42
, bfd_mach_msp42
},
280 {"msp430xW425", MSP430_ISA_42
, bfd_mach_msp42
},
281 {"msp430xW427", MSP430_ISA_42
, bfd_mach_msp42
},
283 {"msp430xG437", MSP430_ISA_43
, bfd_mach_msp43
},
284 {"msp430xG438", MSP430_ISA_43
, bfd_mach_msp43
},
285 {"msp430xG439", MSP430_ISA_43
, bfd_mach_msp43
},
287 {"msp430x435", MSP430_ISA_43
, bfd_mach_msp43
},
288 {"msp430x436", MSP430_ISA_43
, bfd_mach_msp43
},
289 {"msp430x437", MSP430_ISA_43
, bfd_mach_msp43
},
290 {"msp430x447", MSP430_ISA_44
, bfd_mach_msp44
},
291 {"msp430x448", MSP430_ISA_44
, bfd_mach_msp44
},
292 {"msp430x449", MSP430_ISA_44
, bfd_mach_msp44
},
298 static struct mcu_type_s default_mcu
=
299 { "msp430x11", MSP430_ISA_11
, bfd_mach_msp11
};
301 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
303 /* Profiling capability:
304 It is a performance hit to use gcc's profiling approach for this tiny target.
305 Even more -- jtag hardware facility does not perform any profiling functions.
306 However we've got gdb's built-in simulator where we can do anything.
307 Therefore my suggestion is:
309 We define new section ".profiler" which holds all profiling information.
310 We define new pseudo operation .profiler which will instruct assembler to
311 add new profile entry to the object file. Profile should take place at the
316 .profiler flags,function_to_profile [, cycle_corrector, extra]
318 where 'flags' is a combination of the following chars:
321 i - function is in Init section
322 f - function is in Fini section
324 c - libC standard call
325 d - stack value Demand (saved at run-time in simulator)
326 I - Interrupt service routine
331 j - long Jump/ sjlj unwind
332 a - an Arbitrary code fragment
333 t - exTra parameter saved (constant value like frame size)
334 '""' optional: "sil" == sil
336 function_to_profile - function's address
337 cycle_corrector - a value which should be added to the cycle
338 counter, zero if omitted
339 extra - some extra parameter, zero if omitted.
342 ------------------------------
346 .LFrameOffset_fxx=0x08
347 .profiler "scdP", fxx ; function entry.
348 ; we also demand stack value to be displayed
353 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
354 ; (this is a prologue end)
355 ; note, that spare var filled with the farme size
358 .profiler cdE,fxx ; check stack
363 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
364 ret ; cause 'ret' insn takes 3 cycles
365 -------------------------------
367 This profiling approach does not produce any overhead and
369 So, even profiled code can be uploaded to the MCU. */
370 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
371 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
372 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
373 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
374 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
375 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
376 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
377 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
378 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
379 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
380 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
381 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
382 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
383 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
384 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
385 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
398 for (; x
; x
= x
>> 1)
405 /* Parse ordinary expression. */
408 parse_exp (char * s
, expressionS
* op
)
410 input_line_pointer
= s
;
412 if (op
->X_op
== O_absent
)
413 as_bad (_("missing operand"));
414 return input_line_pointer
;
418 /* Delete spaces from s: X ( r 1 2) => X(r12). */
421 del_spaces (char * s
)
429 while (ISSPACE (*m
) && *m
)
431 memmove (s
, m
, strlen (m
) + 1);
439 skip_space (char * s
)
446 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
449 extract_operand (char * from
, char * to
, int limit
)
453 /* Drop leading whitespace. */
454 from
= skip_space (from
);
456 while (size
< limit
&& *from
)
458 *(to
+ size
) = *from
;
459 if (*from
== ',' || *from
== ';' || *from
== '\n')
474 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
491 s
= input_line_pointer
;
492 end
= input_line_pointer
;
494 while (*end
&& *end
!= '\n')
497 while (*s
&& *s
!= '\n')
508 as_bad (_(".profiler pseudo requires at least two operands."));
509 input_line_pointer
= end
;
513 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
522 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
525 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
528 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
531 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
534 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
537 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
540 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
543 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
546 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
549 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
552 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
555 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
558 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
561 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
564 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
567 as_warn (_("unknown profiling flag - ignored."));
574 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
575 | MSP430_PROFILER_FLAG_EXIT
))
576 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
577 | MSP430_PROFILER_FLAG_PROLEND
578 | MSP430_PROFILER_FLAG_EPISTART
579 | MSP430_PROFILER_FLAG_EPIEND
))
580 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
581 | MSP430_PROFILER_FLAG_FINISECT
))))
583 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
584 input_line_pointer
= end
;
588 /* Generate temp symbol which denotes current location. */
589 if (now_seg
== absolute_section
) /* Paranoja ? */
591 exp1
.X_op
= O_constant
;
592 exp1
.X_add_number
= abs_section_offset
;
593 as_warn (_("profiling in absolute section? Hm..."));
597 exp1
.X_op
= O_symbol
;
598 exp1
.X_add_symbol
= symbol_temp_new_now ();
599 exp1
.X_add_number
= 0;
602 /* Generate a symbol which holds flags value. */
603 exp
.X_op
= O_constant
;
604 exp
.X_add_number
= p_flags
;
606 /* Save current section. */
610 /* Now go to .profiler section. */
611 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
614 emit_expr (& exp
, 2);
616 /* Save label value. */
617 emit_expr (& exp1
, 2);
621 /* Now get profiling info. */
622 halt
= extract_operand (input_line_pointer
, str
, 1024);
623 /* Process like ".word xxx" directive. */
624 parse_exp (str
, & exp
);
625 emit_expr (& exp
, 2);
626 input_line_pointer
= halt
;
629 /* Fill the rest with zeros. */
630 exp
.X_op
= O_constant
;
631 exp
.X_add_number
= 0;
633 emit_expr (& exp
, 2);
635 /* Return to current section. */
636 subseg_set (seg
, subseg
);
640 extract_word (char * from
, char * to
, int limit
)
646 /* Drop leading whitespace. */
647 from
= skip_space (from
);
650 /* Find the op code end. */
651 for (op_start
= op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
653 to
[size
++] = *op_end
++;
654 if (size
+ 1 >= limit
)
662 #define OPTION_MMCU 'm'
665 msp430_set_arch (int dummy ATTRIBUTE_UNUSED
)
667 char *str
= (char *) alloca (32); /* 32 for good measure. */
669 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
671 md_parse_option (OPTION_MMCU
, str
);
672 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
676 show_mcu_list (FILE * stream
)
680 fprintf (stream
, _("Known MCU names:\n"));
682 for (i
= 0; mcu_types
[i
].name
; i
++)
683 fprintf (stream
, _("\t %s\n"), mcu_types
[i
].name
);
685 fprintf (stream
, "\n");
689 md_parse_option (int c
, char * arg
)
696 for (i
= 0; mcu_types
[i
].name
; ++i
)
697 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
700 if (!mcu_types
[i
].name
)
702 show_mcu_list (stderr
);
703 as_fatal (_("unknown MCU: %s\n"), arg
);
706 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->mach
== mcu_types
[i
].mach
)
707 msp430_mcu
= &mcu_types
[i
];
709 as_fatal (_("redefinition of mcu type %s' to %s'"),
710 msp430_mcu
->name
, mcu_types
[i
].name
);
718 const pseudo_typeS md_pseudo_table
[] =
720 {"arch", msp430_set_arch
, 0},
721 {"profiler", msp430_profiler
, 0},
725 const char *md_shortopts
= "m:";
727 struct option md_longopts
[] =
729 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
730 {NULL
, no_argument
, NULL
, 0}
733 size_t md_longopts_size
= sizeof (md_longopts
);
736 md_show_usage (FILE * stream
)
739 _("MSP430 options:\n"
740 " -mmcu=[msp430-name] select microcontroller type\n"
741 " msp430x110 msp430x112\n"
742 " msp430x1101 msp430x1111\n"
743 " msp430x1121 msp430x1122 msp430x1132\n"
744 " msp430x122 msp430x123\n"
745 " msp430x1222 msp430x1232\n"
746 " msp430x133 msp430x135\n"
747 " msp430x1331 msp430x1351\n"
748 " msp430x147 msp430x148 msp430x149\n"
749 " msp430x155 msp430x156 msp430x157\n"
750 " msp430x167 msp430x168 msp430x169\n"
751 " msp430x1610 msp430x1611 msp430x1612\n"
752 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
753 " msp430x323 msp430x325\n"
754 " msp430x336 msp430x337\n"
755 " msp430x412 msp430x413 msp430x415 msp430x417\n"
756 " msp430xE423 msp430xE425 msp430E427\n"
757 " msp430xW423 msp430xW425 msp430W427\n"
758 " msp430xG437 msp430xG438 msp430G439\n"
759 " msp430x435 msp430x436 msp430x437\n"
760 " msp430x447 msp430x448 msp430x449\n"));
762 show_mcu_list (stream
);
766 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
772 extract_cmd (char * from
, char * to
, int limit
)
776 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
778 *(to
+ size
) = *from
;
788 /* Turn a string in input_line_pointer into a floating point constant
789 of type TYPE, and store the appropriate bytes in *LITP. The number
790 of LITTLENUMS emitted is stored in *SIZEP. An error message is
791 returned, or NULL on OK. */
794 md_atof (int type
, char * litP
, int * sizeP
)
797 LITTLENUM_TYPE words
[4];
798 LITTLENUM_TYPE
*wordP
;
811 return _("bad call to md_atof");
814 t
= atof_ieee (input_line_pointer
, type
, words
);
816 input_line_pointer
= t
;
818 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
820 /* This loop outputs the LITTLENUMs in REVERSE order. */
821 for (wordP
= words
+ prec
- 1; prec
--;)
823 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
824 litP
+= sizeof (LITTLENUM_TYPE
);
833 struct msp430_opcode_s
* opcode
;
834 msp430_hash
= hash_new ();
836 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
837 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
839 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, msp430_mcu
->mach
);
845 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
847 if (strlen (t
) > 2 && *(t
+ 2) != '+')
852 if ((*t
< '0' || *t
> '9') && *t
!= '+')
865 msp430_srcoperand (struct msp430_operand_s
* op
,
866 char * l
, int bin
, int * imm_op
)
870 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
877 /* Check if there is:
878 llo(x) - least significant 16 bits, x &= 0xffff
879 lhi(x) - x = (x >> 16) & 0xffff,
880 hlo(x) - x = (x >> 32) & 0xffff,
881 hhi(x) - x = (x >> 48) & 0xffff
882 The value _MUST_ be constant expression: #hlo(1231231231). */
886 if (strncasecmp (h
, "#llo(", 5) == 0)
891 else if (strncasecmp (h
, "#lhi(", 5) == 0)
896 else if (strncasecmp (h
, "#hlo(", 5) == 0)
901 else if (strncasecmp (h
, "#hhi(", 5) == 0)
906 else if (strncasecmp (h
, "#lo(", 4) == 0)
911 else if (strncasecmp (h
, "#hi(", 4) == 0)
917 op
->reg
= 0; /* Reg PC. */
919 op
->ol
= 1; /* Immediate will follow an instruction. */
923 parse_exp (__tl
, &(op
->exp
));
924 if (op
->exp
.X_op
== O_constant
)
926 int x
= op
->exp
.X_add_number
;
931 op
->exp
.X_add_number
= x
;
933 else if (vshift
== 1)
935 x
= (x
>> 16) & 0xffff;
936 op
->exp
.X_add_number
= x
;
941 op
->exp
.X_add_number
= -1;
943 op
->exp
.X_add_number
= 0; /* Nothing left. */
944 x
= op
->exp
.X_add_number
;
947 if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
949 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
953 /* Now check constants. */
954 /* Substitute register mode with a constant generator if applicable. */
956 x
= (short) x
; /* Extend sign. */
988 #ifdef PUSH_1X_WORKAROUND
991 /* Remove warning as confusing.
992 as_warn(_("Hardware push bug workaround")); */
1005 #ifdef PUSH_1X_WORKAROUND
1008 /* Remove warning as confusing.
1009 as_warn(_("Hardware push bug workaround")); */
1021 else if (op
->exp
.X_op
== O_symbol
)
1025 else if (op
->exp
.X_op
== O_big
)
1030 op
->exp
.X_op
= O_constant
;
1031 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1032 x
= op
->exp
.X_add_number
;
1037 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1085 /* Redudant (yet) check. */
1086 else if (op
->exp
.X_op
== O_register
)
1088 (_("Registers cannot be used within immediate expression [%s]"), l
);
1090 as_bad (_("unknown operand %s"), l
);
1095 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1100 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1101 op
->am
= 1; /* mode As == 01 bin. */
1102 op
->ol
= 1; /* Immediate value followed by instruction. */
1104 parse_exp (__tl
, &(op
->exp
));
1106 if (op
->exp
.X_op
== O_constant
)
1108 int x
= op
->exp
.X_add_number
;
1110 if (x
> 65535 || x
< -32768)
1112 as_bad (_("value out of range: %d"), x
);
1116 else if (op
->exp
.X_op
== O_symbol
)
1120 /* Redudant (yet) check. */
1121 if (op
->exp
.X_op
== O_register
)
1123 (_("Registers cannot be used within absolute expression [%s]"), l
);
1125 as_bad (_("unknown expression in operand %s"), l
);
1131 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1135 char *m
= strchr (l
, '+');
1139 as_bad (_("unknown addressing mode %s"), l
);
1144 if (*t
!= 'r' && *t
!= 'R')
1146 as_bad (_("unknown addressing mode %s"), l
);
1150 t
++; /* Points to the reg value. */
1154 as_bad (_("Bad register name r%s"), t
);
1162 *m
= 0; /* strip '+' */
1164 if (op
->reg
< 0 || op
->reg
> 15)
1166 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1173 /* Check if register indexed X(Rn). */
1176 char *h
= strrchr (l
, '(');
1177 char *m
= strrchr (l
, ')');
1186 as_bad (_("')' required"));
1193 /* Extract a register. */
1194 t
++; /* Advance pointer. */
1196 if (*t
!= 'r' && *t
!= 'R')
1199 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1206 if (op
->reg
> 9 || op
->reg
< 0)
1208 as_bad (_("unknown operator (r%s substituded as a register name"),
1215 op
->reg
= op
->reg
* 10;
1216 op
->reg
+= *t
- '0';
1220 as_bad (_("unknown operator %s"), l
);
1225 as_bad (_("r2 should not be used in indexed addressing mode"));
1229 if (*(t
+ 1) != ')')
1231 as_bad (_("unknown operator %s"), l
);
1236 /* Extract constant. */
1240 parse_exp (__tl
, &(op
->exp
));
1241 if (op
->exp
.X_op
== O_constant
)
1243 int x
= op
->exp
.X_add_number
;
1245 if (x
> 65535 || x
< -32768)
1247 as_bad (_("value out of range: %d"), x
);
1259 else if (op
->exp
.X_op
== O_symbol
)
1263 /* Redudant (yet) check. */
1264 if (op
->exp
.X_op
== O_register
)
1266 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1268 as_bad (_("unknown expression in operand %s"), l
);
1276 /* Register mode 'mov r1,r2'. */
1281 /* Operand should be a register. */
1282 if (*t
== 'r' || *t
== 'R')
1284 int x
= atoi (t
+ 1);
1286 if (check_reg (t
+ 1))
1289 if (x
< 0 || x
> 15)
1290 break; /* Symbolic mode. */
1301 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1305 op
->reg
= 0; /* PC relative... be careful. */
1309 parse_exp (__tl
, &(op
->exp
));
1315 as_bad (_("unknown addressing mode for operand %s"), l
);
1321 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1324 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
1336 parse_exp (__tl
, &(op
->exp
));
1338 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1340 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1350 ("this addressing mode is not applicable for destination operand"));
1357 /* Parse instruction operands.
1358 Return binary opcode. */
1361 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1363 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1365 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1368 struct msp430_operand_s op1
, op2
;
1370 static short ZEROS
= 0;
1371 int byte_op
, imm_op
;
1373 /* Opcode is the one from opcodes table
1374 line contains something like
1379 /* Check if byte or word operation. */
1380 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1382 bin
|= BYTE_OPERATION
;
1389 while (! ISSPACE (*line
) && *line
)
1392 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1394 as_bad (_("instruction %s requires %d operand(s)"),
1395 opcode
->name
, opcode
->insn_opnumb
);
1399 memset (l1
, 0, sizeof (l1
));
1400 memset (l2
, 0, sizeof (l2
));
1401 memset (&op1
, 0, sizeof (op1
));
1402 memset (&op2
, 0, sizeof (op2
));
1406 switch (opcode
->fmt
)
1408 case 0: /* Emulated. */
1409 switch (opcode
->insn_opnumb
)
1412 /* Set/clear bits instructions. */
1414 frag
= frag_more (__is
);
1415 bfd_putl16 ((bfd_vma
) bin
, frag
);
1418 /* Something which works with destination operand. */
1419 line
= extract_operand (line
, l1
, sizeof (l1
));
1420 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1424 bin
|= (op1
.reg
| (op1
.am
<< 7));
1426 frag
= frag_more (2 * __is
);
1427 where
= frag
- frag_now
->fr_literal
;
1428 bfd_putl16 ((bfd_vma
) bin
, frag
);
1430 if (op1
.mode
== OP_EXP
)
1433 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1436 fix_new_exp (frag_now
, where
, 2,
1437 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1439 fix_new_exp (frag_now
, where
, 2,
1440 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1446 /* Shift instruction. */
1447 line
= extract_operand (line
, l1
, sizeof (l1
));
1448 strncpy (l2
, l1
, sizeof (l2
));
1449 l2
[sizeof (l2
) - 1] = '\0';
1450 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1451 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1454 break; /* An error occurred. All warnings were done before. */
1456 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1458 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1459 frag
= frag_more (2 * __is
);
1460 where
= frag
- frag_now
->fr_literal
;
1461 bfd_putl16 ((bfd_vma
) bin
, frag
);
1463 if (op1
.mode
== OP_EXP
)
1465 where
+= 2; /* Advance 'where' as we do not know _where_. */
1466 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1468 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1469 fix_new_exp (frag_now
, where
, 2,
1470 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1472 fix_new_exp (frag_now
, where
, 2,
1473 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1476 if (op2
.mode
== OP_EXP
)
1479 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1481 if (op2
.reg
) /* Not PC relative. */
1482 fix_new_exp (frag_now
, where
+ 2, 2,
1483 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1485 fix_new_exp (frag_now
, where
+ 2, 2,
1486 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1491 /* Branch instruction => mov dst, r0. */
1492 line
= extract_operand (line
, l1
, sizeof (l1
));
1494 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1501 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
1503 frag
= frag_more (2 * __is
);
1504 where
= frag
- frag_now
->fr_literal
;
1505 bfd_putl16 ((bfd_vma
) bin
, frag
);
1507 if (op1
.mode
== OP_EXP
)
1510 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1512 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
1513 fix_new_exp (frag_now
, where
, 2,
1514 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1516 fix_new_exp (frag_now
, where
, 2,
1517 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1523 case 1: /* Format 1, double operand. */
1524 line
= extract_operand (line
, l1
, sizeof (l1
));
1525 line
= extract_operand (line
, l2
, sizeof (l2
));
1526 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1527 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
);
1530 break; /* Error occurred. All warnings were done before. */
1532 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
1534 __is
= 1 + op1
.ol
+ op2
.ol
; /* insn size in words. */
1535 frag
= frag_more (2 * __is
);
1536 where
= frag
- frag_now
->fr_literal
;
1537 bfd_putl16 ((bfd_vma
) bin
, frag
);
1539 if (op1
.mode
== OP_EXP
)
1541 where
+= 2; /* Advance where as we do not know _where_. */
1542 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1544 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1545 fix_new_exp (frag_now
, where
, 2,
1546 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1548 fix_new_exp (frag_now
, where
, 2,
1549 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1552 if (op2
.mode
== OP_EXP
)
1555 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2 + ((__is
== 3) ? 2 : 0));
1557 if (op2
.reg
) /* Not PC relative. */
1558 fix_new_exp (frag_now
, where
+ 2, 2,
1559 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1561 fix_new_exp (frag_now
, where
+ 2, 2,
1562 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1566 case 2: /* Single-operand mostly instr. */
1567 if (opcode
->insn_opnumb
== 0)
1569 /* reti instruction. */
1570 frag
= frag_more (2);
1571 bfd_putl16 ((bfd_vma
) bin
, frag
);
1575 line
= extract_operand (line
, l1
, sizeof (l1
));
1576 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1578 break; /* Error in operand. */
1580 bin
|= op1
.reg
| (op1
.am
<< 4);
1582 frag
= frag_more (2 * __is
);
1583 where
= frag
- frag_now
->fr_literal
;
1584 bfd_putl16 ((bfd_vma
) bin
, frag
);
1586 if (op1
.mode
== OP_EXP
)
1588 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1590 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
1591 fix_new_exp (frag_now
, where
+ 2, 2,
1592 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1594 fix_new_exp (frag_now
, where
+ 2, 2,
1595 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1599 case 3: /* Conditional jumps instructions. */
1600 line
= extract_operand (line
, l1
, sizeof (l1
));
1601 /* l1 is a label. */
1610 parse_exp (m
, &exp
);
1611 frag
= frag_more (2); /* Instr size is 1 word. */
1613 /* In order to handle something like:
1617 jz 4 ; skip next 4 bytes
1620 nop ; will jump here if r5 positive or zero
1622 jCOND -n ;assumes jump n bytes backward:
1632 jCOND $n ; jump from PC in either direction. */
1634 if (exp
.X_op
== O_constant
)
1636 int x
= exp
.X_add_number
;
1640 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1644 if ((*l1
== '$' && x
> 0) || x
< 0)
1649 if (x
> 512 || x
< -511)
1651 as_bad (_("Wrong displacement %d"), x
<< 1);
1656 bfd_putl16 ((bfd_vma
) bin
, frag
);
1658 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
1660 where
= frag
- frag_now
->fr_literal
;
1661 fix_new_exp (frag_now
, where
, 2,
1662 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
1664 bfd_putl16 ((bfd_vma
) bin
, frag
);
1666 else if (*l1
== '$')
1668 as_bad (_("instruction requires label sans '$'"));
1674 ("instruction requires label or value in range -511:512"));
1680 as_bad (_("instruction requires label"));
1685 case 4: /* Extended jumps. */
1686 line
= extract_operand (line
, l1
, sizeof (l1
));
1692 /* Ignore absolute addressing. make it PC relative anyway. */
1693 if (*m
== '#' || *m
== '$')
1696 parse_exp (m
, & exp
);
1697 if (exp
.X_op
== O_symbol
)
1699 /* Relaxation required. */
1700 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
1702 frag
= frag_more (8);
1703 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
1704 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1705 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
), /* Wild guess. */
1707 0, /* Offset is zero if jump dist less than 1K. */
1713 as_bad (_("instruction requires label"));
1716 case 5: /* Emulated extended branches. */
1717 line
= extract_operand (line
, l1
, sizeof (l1
));
1723 /* Ignore absolute addressing. make it PC relative anyway. */
1724 if (*m
== '#' || *m
== '$')
1727 parse_exp (m
, & exp
);
1728 if (exp
.X_op
== O_symbol
)
1730 /* Relaxation required. */
1731 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
1733 frag
= frag_more (8);
1734 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
1735 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
1736 frag
= frag_variant (rs_machine_dependent
, 8, 2,
1737 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
1739 0, /* Offset is zero if jump dist less than 1K. */
1745 as_bad (_("instruction requires label"));
1749 as_bad (_("Ilegal instruction or not implmented opcode."));
1752 input_line_pointer
= line
;
1757 md_assemble (char * str
)
1759 struct msp430_opcode_s
* opcode
;
1763 str
= skip_space (str
); /* Skip leading spaces. */
1764 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
1766 while (cmd
[i
] && i
< sizeof (cmd
))
1768 char a
= TOLOWER (cmd
[i
]);
1775 as_bad (_("can't find opcode "));
1779 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1783 as_bad (_("unknown opcode `%s'"), cmd
);
1788 char *__t
= input_line_pointer
;
1790 msp430_operands (opcode
, str
);
1791 input_line_pointer
= __t
;
1795 /* GAS will call this function for each section at the end of the assembly,
1796 to permit the CPU backend to adjust the alignment of a section. */
1799 md_section_align (asection
* seg
, valueT addr
)
1801 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1803 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
1806 /* If you define this macro, it should return the offset between the
1807 address of a PC relative fixup and the position from which the PC
1808 relative adjustment should be made. On many processors, the base
1809 of a PC relative instruction is the next instruction, so this
1810 macro would return the length of an instruction. */
1813 md_pcrel_from_section (fixS
* fixp
, segT sec
)
1815 if (fixp
->fx_addsy
!= (symbolS
*) NULL
1816 && (!S_IS_DEFINED (fixp
->fx_addsy
)
1817 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
1820 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1823 /* GAS will call this for each fixup. It should store the correct
1824 value in the object file. */
1827 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
1829 unsigned char * where
;
1833 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
1838 else if (fixp
->fx_pcrel
)
1840 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
1842 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
1844 /* FIXME: We can appear here only in case if we perform a pc
1845 relative jump to the label which is i) global, ii) locally
1846 defined or this is a jump to an absolute symbol.
1847 If this is an absolute symbol -- everything is OK.
1848 If this is a global label, we've got a symbol value defined
1850 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1851 from this section start
1852 2. *valuep will contain the real offset from jump insn to the
1854 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1855 will be incorrect. Therefore remove s_get_value. */
1856 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
1864 value
= fixp
->fx_offset
;
1866 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
1868 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1870 value
-= S_GET_VALUE (fixp
->fx_subsy
);
1875 /* We don't actually support subtracting a symbol. */
1876 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1877 _("expression too complex"));
1882 switch (fixp
->fx_r_type
)
1885 fixp
->fx_no_overflow
= 1;
1887 case BFD_RELOC_MSP430_10_PCREL
:
1893 /* Fetch the instruction, insert the fully resolved operand
1894 value, and stuff the instruction back again. */
1896 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
1898 insn
= bfd_getl16 (where
);
1900 switch (fixp
->fx_r_type
)
1902 case BFD_RELOC_MSP430_10_PCREL
:
1904 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1905 _("odd address operand: %ld"), value
);
1907 /* Jumps are in words. */
1909 --value
; /* Correct PC. */
1911 if (value
< -512 || value
> 511)
1912 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1913 _("operand out of range: %ld"), value
);
1915 value
&= 0x3ff; /* get rid of extended sign */
1916 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
1919 case BFD_RELOC_MSP430_RL_PCREL
:
1920 case BFD_RELOC_MSP430_16_PCREL
:
1922 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1923 _("odd address operand: %ld"), value
);
1925 /* Nothing to be corrected here. */
1926 if (value
< -32768 || value
> 65536)
1927 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1928 _("operand out of range: %ld"), value
);
1930 value
&= 0xffff; /* Get rid of extended sign. */
1931 bfd_putl16 ((bfd_vma
) value
, where
);
1934 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
1935 /* Nothing to be corrected here. */
1936 if (value
< -32768 || value
> 65536)
1937 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1938 _("operand out of range: %ld"), value
);
1940 value
&= 0xffff; /* Get rid of extended sign. */
1941 bfd_putl16 ((bfd_vma
) value
, where
);
1945 bfd_putl16 ((bfd_vma
) value
, where
);
1948 case BFD_RELOC_MSP430_16
:
1950 case BFD_RELOC_MSP430_16_BYTE
:
1952 bfd_putl16 ((bfd_vma
) value
, where
);
1956 as_fatal (_("line %d: unknown relocation type: 0x%x"),
1957 fixp
->fx_line
, fixp
->fx_r_type
);
1963 fixp
->fx_addnumber
= value
;
1967 /* A `BFD_ASSEMBLER' GAS will call this to generate a reloc. GAS
1968 will pass the resulting reloc to `bfd_install_relocation'. This
1969 currently works poorly, as `bfd_install_relocation' often does the
1970 wrong thing, and instances of `tc_gen_reloc' have been written to
1971 work around the problems, which in turns makes it difficult to fix
1972 `bfd_install_relocation'. */
1974 /* If while processing a fixup, a reloc really needs to be created
1975 then it is done here. */
1978 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
1982 reloc
= xmalloc (sizeof (arelent
));
1984 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
1985 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1987 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1988 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1989 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1991 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1992 _("reloc %d not supported by object file format"),
1993 (int) fixp
->fx_r_type
);
1997 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
1998 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
1999 reloc
->address
= fixp
->fx_offset
;
2001 reloc
->addend
= fixp
->fx_offset
;
2007 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
2008 asection
* segment_type ATTRIBUTE_UNUSED
)
2010 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
2012 /* This is a jump -> pcrel mode. Nothing to do much here.
2013 Return value == 2. */
2015 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
2017 else if (fragP
->fr_symbol
)
2019 /* Its got a segment, but its not ours. Even if fr_symbol is in
2020 an absolute segment, we dont know a displacement until we link
2021 object files. So it will always be long. This also applies to
2022 labels in a subsegment of current. Liker may relax it to short
2023 jump later. Return value == 8. */
2025 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
2029 /* We know the abs value. may be it is a jump to fixed address.
2030 Impossible in our case, cause all constants already handeled. */
2032 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
2035 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
2039 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
2040 asection
* sec ATTRIBUTE_UNUSED
,
2046 struct rcodes_s
* cc
= NULL
;
2047 struct hcodes_s
* hc
= NULL
;
2049 switch (fragP
->fr_subtype
)
2051 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
2052 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
2053 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
2054 /* We do not have to convert anything here.
2055 Just apply a fix. */
2056 rela
= BFD_RELOC_MSP430_10_PCREL
;
2059 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
2060 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
2061 /* Convert uncond branch jmp lab -> br lab. */
2062 cc
= & msp430_rcodes
[7];
2063 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2064 bfd_putl16 (cc
->lop0
, where
);
2065 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2069 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
2070 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
2072 /* Other simple branches. */
2073 int insn
= bfd_getl16 (fragP
->fr_opcode
);
2076 /* Find actual instruction. */
2077 for (i
= 0; i
< 7 && !cc
; i
++)
2078 if (msp430_rcodes
[i
].sop
== insn
)
2079 cc
= & msp430_rcodes
[i
];
2080 if (!cc
|| !cc
->name
)
2081 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2082 __FUNCTION__
, (long) insn
);
2083 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2084 bfd_putl16 (cc
->lop0
, where
);
2085 bfd_putl16 (cc
->lop1
, where
+ 2);
2086 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2091 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
2092 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
2093 cc
= & msp430_rcodes
[6];
2094 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2095 bfd_putl16 (cc
->lop0
, where
);
2096 bfd_putl16 (cc
->lop1
, where
+ 2);
2097 bfd_putl16 (cc
->lop2
, where
+ 4);
2098 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2102 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2104 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2107 for (i
= 0; i
< 4 && !hc
; i
++)
2108 if (msp430_hcodes
[i
].op1
== insn
)
2109 hc
= &msp430_hcodes
[i
];
2110 if (!hc
|| !hc
->name
)
2111 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2112 __FUNCTION__
, (long) insn
);
2113 rela
= BFD_RELOC_MSP430_10_PCREL
;
2114 /* Apply a fix for a first label if necessary.
2115 another fix will be applied to the next word of insn anyway. */
2117 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2118 fragP
->fr_offset
, TRUE
, rela
);
2124 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
2125 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
2127 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
2130 for (i
= 0; i
< 4 && !hc
; i
++)
2131 if (msp430_hcodes
[i
].op1
== insn
)
2132 hc
= & msp430_hcodes
[i
];
2133 if (!hc
|| !hc
->name
)
2134 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2135 __FUNCTION__
, (long) insn
);
2136 rela
= BFD_RELOC_MSP430_RL_PCREL
;
2137 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
2138 bfd_putl16 (hc
->lop0
, where
);
2139 bfd_putl16 (hc
->lop1
, where
+ 2);
2140 bfd_putl16 (hc
->lop2
, where
+ 4);
2146 as_fatal (_("internal inconsistency problem in %s: %lx"),
2147 __FUNCTION__
, (long) fragP
->fr_subtype
);
2151 /* Now apply fix. */
2152 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2153 fragP
->fr_offset
, TRUE
, rela
);
2154 /* Just fixed 2 bytes. */
2158 /* Relax fragment. Mostly stolen from hc11 and mcore
2159 which arches I think I know. */
2162 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2163 long stretch ATTRIBUTE_UNUSED
)
2168 const relax_typeS
*this_type
;
2169 const relax_typeS
*start_type
;
2170 relax_substateT next_state
;
2171 relax_substateT this_state
;
2172 const relax_typeS
*table
= md_relax_table
;
2174 /* Nothing to be done if the frag has already max size. */
2175 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
2176 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
2179 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
2181 symbolP
= fragP
->fr_symbol
;
2182 if (symbol_resolved_p (symbolP
))
2183 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2185 /* We know the offset. calculate a distance. */
2186 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
2189 this_state
= fragP
->fr_subtype
;
2190 start_type
= this_type
= table
+ this_state
;
2194 /* Look backwards. */
2195 for (next_state
= this_type
->rlx_more
; next_state
;)
2196 if (aim
>= this_type
->rlx_backward
)
2200 /* Grow to next state. */
2201 this_state
= next_state
;
2202 this_type
= table
+ this_state
;
2203 next_state
= this_type
->rlx_more
;
2208 /* Look forwards. */
2209 for (next_state
= this_type
->rlx_more
; next_state
;)
2210 if (aim
<= this_type
->rlx_forward
)
2214 /* Grow to next state. */
2215 this_state
= next_state
;
2216 this_type
= table
+ this_state
;
2217 next_state
= this_type
->rlx_more
;
2221 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
2223 fragP
->fr_subtype
= this_state
;