tc-msp430.c revision 1.1.1.2 1 1.1 skrll /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2 1.1 skrll
3 1.1.1.2 christos Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
4 1.1 skrll Free Software Foundation, Inc.
5 1.1 skrll Contributed by Dmitry Diky <diwil (at) mail.ru>
6 1.1 skrll
7 1.1 skrll This file is part of GAS, the GNU Assembler.
8 1.1 skrll
9 1.1 skrll GAS is free software; you can redistribute it and/or modify
10 1.1 skrll it under the terms of the GNU General Public License as published by
11 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
12 1.1 skrll any later version.
13 1.1 skrll
14 1.1 skrll GAS is distributed in the hope that it will be useful,
15 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
16 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 1.1 skrll GNU General Public License for more details.
18 1.1 skrll
19 1.1 skrll You should have received a copy of the GNU General Public License
20 1.1 skrll along with GAS; see the file COPYING. If not, write to
21 1.1 skrll the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 1.1 skrll Boston, MA 02110-1301, USA. */
23 1.1 skrll
24 1.1 skrll #include <limits.h>
25 1.1 skrll
26 1.1 skrll #define PUSH_1X_WORKAROUND
27 1.1 skrll #include "as.h"
28 1.1 skrll #include "subsegs.h"
29 1.1 skrll #include "opcode/msp430.h"
30 1.1 skrll #include "safe-ctype.h"
31 1.1 skrll #include "dwarf2dbg.h"
32 1.1 skrll
33 1.1 skrll /* We will disable polymorphs by default because it is dangerous.
34 1.1 skrll The potential problem here is the following: assume we got the
35 1.1 skrll following code:
36 1.1 skrll
37 1.1 skrll jump .l1
38 1.1 skrll nop
39 1.1 skrll jump subroutine ; external symbol
40 1.1 skrll .l1:
41 1.1 skrll nop
42 1.1 skrll ret
43 1.1 skrll
44 1.1 skrll In case of assembly time relaxation we'll get:
45 1.1 skrll 0: jmp .l1 <.text +0x08> (reloc deleted)
46 1.1 skrll 2: nop
47 1.1 skrll 4: br subroutine
48 1.1 skrll .l1:
49 1.1 skrll 8: nop
50 1.1 skrll 10: ret
51 1.1 skrll
52 1.1 skrll If the 'subroutine' is within +-1024 bytes range then linker
53 1.1 skrll will produce:
54 1.1 skrll 0: jmp .text +0x08
55 1.1 skrll 2: nop
56 1.1 skrll 4: jmp subroutine
57 1.1 skrll .l1:
58 1.1 skrll 6: nop
59 1.1 skrll 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 1.1 skrll
61 1.1 skrll The workaround is the following:
62 1.1 skrll 1. Declare global var enable_polymorphs which set to 1 via option -mp.
63 1.1 skrll 2. Declare global var enable_relax which set to 1 via option -mQ.
64 1.1 skrll
65 1.1 skrll If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
66 1.1 skrll do not delete any relocs and leave them for linker.
67 1.1 skrll
68 1.1 skrll If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 1.1 skrll
70 1.1 skrll int msp430_enable_relax;
71 1.1 skrll int msp430_enable_polys;
72 1.1 skrll
73 1.1 skrll /* GCC uses the some condition codes which we'll
74 1.1 skrll implement as new polymorph instructions.
75 1.1 skrll
76 1.1 skrll COND EXPL SHORT JUMP LONG JUMP
77 1.1 skrll ===============================================
78 1.1 skrll eq == jeq jne +4; br lab
79 1.1 skrll ne != jne jeq +4; br lab
80 1.1 skrll
81 1.1 skrll ltn honours no-overflow flag
82 1.1 skrll ltn < jn jn +2; jmp +4; br lab
83 1.1 skrll
84 1.1 skrll lt < jl jge +4; br lab
85 1.1 skrll ltu < jlo lhs +4; br lab
86 1.1 skrll le <= see below
87 1.1 skrll leu <= see below
88 1.1 skrll
89 1.1 skrll gt > see below
90 1.1 skrll gtu > see below
91 1.1 skrll ge >= jge jl +4; br lab
92 1.1 skrll geu >= jhs jlo +4; br lab
93 1.1 skrll ===============================================
94 1.1 skrll
95 1.1 skrll Therefore, new opcodes are (BranchEQ -> beq; and so on...)
96 1.1 skrll beq,bne,blt,bltn,bltu,bge,bgeu
97 1.1 skrll 'u' means unsigned compares
98 1.1 skrll
99 1.1 skrll Also, we add 'jump' instruction:
100 1.1 skrll jump UNCOND -> jmp br lab
101 1.1 skrll
102 1.1 skrll They will have fmt == 4, and insn_opnumb == number of instruction. */
103 1.1 skrll
104 1.1 skrll struct rcodes_s
105 1.1 skrll {
106 1.1 skrll char * name;
107 1.1 skrll int index; /* Corresponding insn_opnumb. */
108 1.1 skrll int sop; /* Opcode if jump length is short. */
109 1.1 skrll long lpos; /* Label position. */
110 1.1 skrll long lop0; /* Opcode 1 _word_ (16 bits). */
111 1.1 skrll long lop1; /* Opcode second word. */
112 1.1 skrll long lop2; /* Opcode third word. */
113 1.1 skrll };
114 1.1 skrll
115 1.1 skrll #define MSP430_RLC(n,i,sop,o1) \
116 1.1 skrll {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
117 1.1 skrll
118 1.1 skrll static struct rcodes_s msp430_rcodes[] =
119 1.1 skrll {
120 1.1 skrll MSP430_RLC (beq, 0, 0x2400, 0x2000),
121 1.1 skrll MSP430_RLC (bne, 1, 0x2000, 0x2400),
122 1.1 skrll MSP430_RLC (blt, 2, 0x3800, 0x3400),
123 1.1 skrll MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
124 1.1 skrll MSP430_RLC (bge, 4, 0x3400, 0x3800),
125 1.1 skrll MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
126 1.1 skrll {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
127 1.1 skrll {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
128 1.1 skrll {0,0,0,0,0,0,0}
129 1.1 skrll };
130 1.1 skrll #undef MSP430_RLC
131 1.1 skrll
132 1.1 skrll
133 1.1 skrll /* More difficult than above and they have format 5.
134 1.1 skrll
135 1.1 skrll COND EXPL SHORT LONG
136 1.1 skrll =================================================================
137 1.1 skrll gt > jeq +2; jge label jeq +6; jl +4; br label
138 1.1 skrll gtu > jeq +2; jhs label jeq +6; jlo +4; br label
139 1.1 skrll leu <= jeq label; jlo label jeq +2; jhs +4; br label
140 1.1 skrll le <= jeq label; jl label jeq +2; jge +4; br label
141 1.1 skrll ================================================================= */
142 1.1 skrll
143 1.1 skrll struct hcodes_s
144 1.1 skrll {
145 1.1 skrll char * name;
146 1.1 skrll int index; /* Corresponding insn_opnumb. */
147 1.1 skrll int tlab; /* Number of labels in short mode. */
148 1.1 skrll int op0; /* Opcode for first word of short jump. */
149 1.1 skrll int op1; /* Opcode for second word of short jump. */
150 1.1 skrll int lop0; /* Opcodes for long jump mode. */
151 1.1 skrll int lop1;
152 1.1 skrll int lop2;
153 1.1 skrll };
154 1.1 skrll
155 1.1 skrll static struct hcodes_s msp430_hcodes[] =
156 1.1 skrll {
157 1.1 skrll {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
158 1.1 skrll {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
159 1.1 skrll {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
160 1.1 skrll {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
161 1.1 skrll {0,0,0,0,0,0,0,0}
162 1.1 skrll };
163 1.1 skrll
164 1.1 skrll const char comment_chars[] = ";";
165 1.1 skrll const char line_comment_chars[] = "#";
166 1.1 skrll const char line_separator_chars[] = "{";
167 1.1 skrll const char EXP_CHARS[] = "eE";
168 1.1 skrll const char FLT_CHARS[] = "dD";
169 1.1 skrll
170 1.1 skrll /* Handle long expressions. */
171 1.1 skrll extern LITTLENUM_TYPE generic_bignum[];
172 1.1 skrll
173 1.1 skrll static struct hash_control *msp430_hash;
174 1.1 skrll
175 1.1 skrll /* Relaxations. */
176 1.1 skrll #define STATE_UNCOND_BRANCH 1 /* jump */
177 1.1 skrll #define STATE_NOOV_BRANCH 3 /* bltn */
178 1.1 skrll #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
179 1.1 skrll #define STATE_EMUL_BRANCH 4
180 1.1 skrll
181 1.1 skrll #define CNRL 2
182 1.1 skrll #define CUBL 4
183 1.1 skrll #define CNOL 8
184 1.1 skrll #define CSBL 6
185 1.1 skrll #define CEBL 4
186 1.1 skrll
187 1.1 skrll /* Length. */
188 1.1 skrll #define STATE_BITS10 1 /* wild guess. short jump */
189 1.1 skrll #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
190 1.1 skrll #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
191 1.1 skrll
192 1.1 skrll #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
193 1.1 skrll #define RELAX_STATE(s) ((s) & 3)
194 1.1 skrll #define RELAX_LEN(s) ((s) >> 2)
195 1.1 skrll #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
196 1.1 skrll
197 1.1 skrll relax_typeS md_relax_table[] =
198 1.1 skrll {
199 1.1 skrll /* Unused. */
200 1.1 skrll {1, 1, 0, 0},
201 1.1 skrll {1, 1, 0, 0},
202 1.1 skrll {1, 1, 0, 0},
203 1.1 skrll {1, 1, 0, 0},
204 1.1 skrll
205 1.1 skrll /* Unconditional jump. */
206 1.1 skrll {1, 1, 8, 5},
207 1.1 skrll {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
208 1.1 skrll {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
209 1.1 skrll {1, 1, CUBL, 0}, /* state undef */
210 1.1 skrll
211 1.1 skrll /* Simple branches. */
212 1.1 skrll {0, 0, 8, 9},
213 1.1 skrll {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
214 1.1 skrll {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
215 1.1 skrll {1, 1, CSBL, 0},
216 1.1 skrll
217 1.1 skrll /* blt no overflow branch. */
218 1.1 skrll {1, 1, 8, 13},
219 1.1 skrll {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
220 1.1 skrll {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
221 1.1 skrll {1, 1, CNOL, 0},
222 1.1 skrll
223 1.1 skrll /* Emulated branches. */
224 1.1 skrll {1, 1, 8, 17},
225 1.1 skrll {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
226 1.1 skrll {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
227 1.1 skrll {1, 1, CNOL, 0}
228 1.1 skrll };
229 1.1 skrll
230 1.1 skrll
231 1.1 skrll #define MAX_OP_LEN 256
232 1.1 skrll
233 1.1 skrll struct mcu_type_s
234 1.1 skrll {
235 1.1 skrll char * name;
236 1.1 skrll int isa;
237 1.1 skrll int mach;
238 1.1 skrll };
239 1.1 skrll
240 1.1 skrll #define MSP430_ISA_11 11
241 1.1 skrll #define MSP430_ISA_110 110
242 1.1 skrll #define MSP430_ISA_12 12
243 1.1 skrll #define MSP430_ISA_13 13
244 1.1 skrll #define MSP430_ISA_14 14
245 1.1 skrll #define MSP430_ISA_15 15
246 1.1 skrll #define MSP430_ISA_16 16
247 1.1 skrll #define MSP430_ISA_21 21
248 1.1 skrll #define MSP430_ISA_31 31
249 1.1 skrll #define MSP430_ISA_32 32
250 1.1 skrll #define MSP430_ISA_33 33
251 1.1 skrll #define MSP430_ISA_41 41
252 1.1 skrll #define MSP430_ISA_42 42
253 1.1 skrll #define MSP430_ISA_43 43
254 1.1 skrll #define MSP430_ISA_44 44
255 1.1 skrll
256 1.1 skrll #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
257 1.1 skrll #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
258 1.1 skrll
259 1.1 skrll static struct mcu_type_s mcu_types[] =
260 1.1 skrll {
261 1.1 skrll {"msp1", MSP430_ISA_11, bfd_mach_msp11},
262 1.1 skrll {"msp2", MSP430_ISA_14, bfd_mach_msp14},
263 1.1 skrll {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
264 1.1 skrll {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
265 1.1 skrll {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
266 1.1 skrll {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
267 1.1 skrll {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
268 1.1 skrll {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
269 1.1 skrll {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
270 1.1 skrll
271 1.1 skrll {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
272 1.1 skrll {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
273 1.1 skrll {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
274 1.1 skrll {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
275 1.1 skrll
276 1.1 skrll {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
277 1.1 skrll {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
278 1.1 skrll {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
279 1.1 skrll {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
280 1.1 skrll {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
281 1.1 skrll {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
282 1.1 skrll {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
283 1.1 skrll
284 1.1 skrll {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
285 1.1 skrll {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
286 1.1 skrll {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
287 1.1 skrll {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
288 1.1 skrll {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
289 1.1 skrll {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
290 1.1 skrll {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
291 1.1 skrll {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
292 1.1 skrll {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
293 1.1 skrll
294 1.1 skrll {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
295 1.1 skrll {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
296 1.1 skrll {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
297 1.1 skrll {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
298 1.1 skrll
299 1.1 skrll {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
300 1.1 skrll {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
301 1.1 skrll {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
302 1.1 skrll {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
303 1.1 skrll {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
304 1.1 skrll {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
305 1.1 skrll {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
306 1.1 skrll {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
307 1.1 skrll {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
308 1.1 skrll
309 1.1 skrll {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
310 1.1 skrll {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
311 1.1 skrll {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
312 1.1 skrll {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
313 1.1 skrll
314 1.1 skrll {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
315 1.1 skrll {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
316 1.1 skrll {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
317 1.1 skrll
318 1.1 skrll {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
319 1.1 skrll {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
320 1.1 skrll {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
321 1.1 skrll
322 1.1 skrll {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
323 1.1 skrll {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
324 1.1 skrll {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
325 1.1 skrll
326 1.1 skrll {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
327 1.1 skrll {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
328 1.1 skrll {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
329 1.1 skrll {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
330 1.1 skrll {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
331 1.1 skrll {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
332 1.1 skrll
333 1.1 skrll {NULL, 0, 0}
334 1.1 skrll };
335 1.1 skrll
336 1.1 skrll
337 1.1 skrll static struct mcu_type_s default_mcu =
338 1.1 skrll { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
339 1.1 skrll
340 1.1 skrll static struct mcu_type_s * msp430_mcu = & default_mcu;
341 1.1 skrll
342 1.1 skrll /* Profiling capability:
343 1.1 skrll It is a performance hit to use gcc's profiling approach for this tiny target.
344 1.1 skrll Even more -- jtag hardware facility does not perform any profiling functions.
345 1.1 skrll However we've got gdb's built-in simulator where we can do anything.
346 1.1 skrll Therefore my suggestion is:
347 1.1 skrll
348 1.1 skrll We define new section ".profiler" which holds all profiling information.
349 1.1 skrll We define new pseudo operation .profiler which will instruct assembler to
350 1.1 skrll add new profile entry to the object file. Profile should take place at the
351 1.1 skrll present address.
352 1.1 skrll
353 1.1 skrll Pseudo-op format:
354 1.1 skrll
355 1.1 skrll .profiler flags,function_to_profile [, cycle_corrector, extra]
356 1.1 skrll
357 1.1 skrll where 'flags' is a combination of the following chars:
358 1.1 skrll s - function Start
359 1.1 skrll x - function eXit
360 1.1 skrll i - function is in Init section
361 1.1 skrll f - function is in Fini section
362 1.1 skrll l - Library call
363 1.1 skrll c - libC standard call
364 1.1 skrll d - stack value Demand (saved at run-time in simulator)
365 1.1 skrll I - Interrupt service routine
366 1.1 skrll P - Prologue start
367 1.1 skrll p - Prologue end
368 1.1 skrll E - Epilogue start
369 1.1 skrll e - Epilogue end
370 1.1 skrll j - long Jump/ sjlj unwind
371 1.1 skrll a - an Arbitrary code fragment
372 1.1 skrll t - exTra parameter saved (constant value like frame size)
373 1.1 skrll '""' optional: "sil" == sil
374 1.1 skrll
375 1.1 skrll function_to_profile - function's address
376 1.1 skrll cycle_corrector - a value which should be added to the cycle
377 1.1 skrll counter, zero if omitted
378 1.1 skrll extra - some extra parameter, zero if omitted.
379 1.1 skrll
380 1.1 skrll For example:
381 1.1 skrll ------------------------------
382 1.1 skrll .global fxx
383 1.1 skrll .type fxx,@function
384 1.1 skrll fxx:
385 1.1 skrll .LFrameOffset_fxx=0x08
386 1.1 skrll .profiler "scdP", fxx ; function entry.
387 1.1 skrll ; we also demand stack value to be displayed
388 1.1 skrll push r11
389 1.1 skrll push r10
390 1.1 skrll push r9
391 1.1 skrll push r8
392 1.1 skrll .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
393 1.1 skrll ; (this is a prologue end)
394 1.1 skrll ; note, that spare var filled with the frame size
395 1.1 skrll mov r15,r8
396 1.1 skrll ....
397 1.1 skrll .profiler cdE,fxx ; check stack
398 1.1 skrll pop r8
399 1.1 skrll pop r9
400 1.1 skrll pop r10
401 1.1 skrll pop r11
402 1.1 skrll .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
403 1.1 skrll ret ; cause 'ret' insn takes 3 cycles
404 1.1 skrll -------------------------------
405 1.1 skrll
406 1.1 skrll This profiling approach does not produce any overhead and
407 1.1 skrll absolutely harmless.
408 1.1 skrll So, even profiled code can be uploaded to the MCU. */
409 1.1 skrll #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
410 1.1 skrll #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
411 1.1 skrll #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
412 1.1 skrll #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
413 1.1 skrll #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
414 1.1 skrll #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
415 1.1 skrll #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
416 1.1 skrll #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
417 1.1 skrll #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
418 1.1 skrll #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
419 1.1 skrll #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
420 1.1 skrll #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
421 1.1 skrll #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
422 1.1 skrll #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
423 1.1 skrll #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
424 1.1 skrll #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
425 1.1 skrll
426 1.1 skrll static int
427 1.1 skrll pow2value (int y)
428 1.1 skrll {
429 1.1 skrll int n = 0;
430 1.1 skrll unsigned int x;
431 1.1 skrll
432 1.1 skrll x = y;
433 1.1 skrll
434 1.1 skrll if (!x)
435 1.1 skrll return 1;
436 1.1 skrll
437 1.1 skrll for (; x; x = x >> 1)
438 1.1 skrll if (x & 1)
439 1.1 skrll n++;
440 1.1 skrll
441 1.1 skrll return n == 1;
442 1.1 skrll }
443 1.1 skrll
444 1.1 skrll /* Parse ordinary expression. */
445 1.1 skrll
446 1.1 skrll static char *
447 1.1 skrll parse_exp (char * s, expressionS * op)
448 1.1 skrll {
449 1.1 skrll input_line_pointer = s;
450 1.1 skrll expression (op);
451 1.1 skrll if (op->X_op == O_absent)
452 1.1 skrll as_bad (_("missing operand"));
453 1.1 skrll return input_line_pointer;
454 1.1 skrll }
455 1.1 skrll
456 1.1 skrll
457 1.1 skrll /* Delete spaces from s: X ( r 1 2) => X(r12). */
458 1.1 skrll
459 1.1 skrll static void
460 1.1 skrll del_spaces (char * s)
461 1.1 skrll {
462 1.1 skrll while (*s)
463 1.1 skrll {
464 1.1 skrll if (ISSPACE (*s))
465 1.1 skrll {
466 1.1 skrll char *m = s + 1;
467 1.1 skrll
468 1.1 skrll while (ISSPACE (*m) && *m)
469 1.1 skrll m++;
470 1.1 skrll memmove (s, m, strlen (m) + 1);
471 1.1 skrll }
472 1.1 skrll else
473 1.1 skrll s++;
474 1.1 skrll }
475 1.1 skrll }
476 1.1 skrll
477 1.1 skrll static inline char *
478 1.1 skrll skip_space (char * s)
479 1.1 skrll {
480 1.1 skrll while (ISSPACE (*s))
481 1.1 skrll ++s;
482 1.1 skrll return s;
483 1.1 skrll }
484 1.1 skrll
485 1.1 skrll /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
486 1.1 skrll
487 1.1 skrll static char *
488 1.1 skrll extract_operand (char * from, char * to, int limit)
489 1.1 skrll {
490 1.1 skrll int size = 0;
491 1.1 skrll
492 1.1 skrll /* Drop leading whitespace. */
493 1.1 skrll from = skip_space (from);
494 1.1 skrll
495 1.1 skrll while (size < limit && *from)
496 1.1 skrll {
497 1.1 skrll *(to + size) = *from;
498 1.1 skrll if (*from == ',' || *from == ';' || *from == '\n')
499 1.1 skrll break;
500 1.1 skrll from++;
501 1.1 skrll size++;
502 1.1 skrll }
503 1.1 skrll
504 1.1 skrll *(to + size) = 0;
505 1.1 skrll del_spaces (to);
506 1.1 skrll
507 1.1 skrll from++;
508 1.1 skrll
509 1.1 skrll return from;
510 1.1 skrll }
511 1.1 skrll
512 1.1 skrll static void
513 1.1 skrll msp430_profiler (int dummy ATTRIBUTE_UNUSED)
514 1.1 skrll {
515 1.1 skrll char buffer[1024];
516 1.1 skrll char f[32];
517 1.1 skrll char * str = buffer;
518 1.1 skrll char * flags = f;
519 1.1 skrll int p_flags = 0;
520 1.1 skrll char * halt;
521 1.1 skrll int ops = 0;
522 1.1 skrll int left;
523 1.1 skrll char * s;
524 1.1 skrll segT seg;
525 1.1 skrll int subseg;
526 1.1 skrll char * end = 0;
527 1.1 skrll expressionS exp;
528 1.1 skrll expressionS exp1;
529 1.1 skrll
530 1.1 skrll s = input_line_pointer;
531 1.1 skrll end = input_line_pointer;
532 1.1 skrll
533 1.1 skrll while (*end && *end != '\n')
534 1.1 skrll end++;
535 1.1 skrll
536 1.1 skrll while (*s && *s != '\n')
537 1.1 skrll {
538 1.1 skrll if (*s == ',')
539 1.1 skrll ops++;
540 1.1 skrll s++;
541 1.1 skrll }
542 1.1 skrll
543 1.1 skrll left = 3 - ops;
544 1.1 skrll
545 1.1 skrll if (ops < 1)
546 1.1 skrll {
547 1.1 skrll as_bad (_(".profiler pseudo requires at least two operands."));
548 1.1 skrll input_line_pointer = end;
549 1.1 skrll return;
550 1.1 skrll }
551 1.1 skrll
552 1.1 skrll input_line_pointer = extract_operand (input_line_pointer, flags, 32);
553 1.1 skrll
554 1.1 skrll while (*flags)
555 1.1 skrll {
556 1.1 skrll switch (*flags)
557 1.1 skrll {
558 1.1 skrll case '"':
559 1.1 skrll break;
560 1.1 skrll case 'a':
561 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
562 1.1 skrll break;
563 1.1 skrll case 'j':
564 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_JUMP;
565 1.1 skrll break;
566 1.1 skrll case 'P':
567 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
568 1.1 skrll break;
569 1.1 skrll case 'p':
570 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_PROLEND;
571 1.1 skrll break;
572 1.1 skrll case 'E':
573 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_EPISTART;
574 1.1 skrll break;
575 1.1 skrll case 'e':
576 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_EPIEND;
577 1.1 skrll break;
578 1.1 skrll case 's':
579 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_ENTRY;
580 1.1 skrll break;
581 1.1 skrll case 'x':
582 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_EXIT;
583 1.1 skrll break;
584 1.1 skrll case 'i':
585 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_INITSECT;
586 1.1 skrll break;
587 1.1 skrll case 'f':
588 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_FINISECT;
589 1.1 skrll break;
590 1.1 skrll case 'l':
591 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
592 1.1 skrll break;
593 1.1 skrll case 'c':
594 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_STDCALL;
595 1.1 skrll break;
596 1.1 skrll case 'd':
597 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
598 1.1 skrll break;
599 1.1 skrll case 'I':
600 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_ISR;
601 1.1 skrll break;
602 1.1 skrll case 't':
603 1.1 skrll p_flags |= MSP430_PROFILER_FLAG_EXTRA;
604 1.1 skrll break;
605 1.1 skrll default:
606 1.1 skrll as_warn (_("unknown profiling flag - ignored."));
607 1.1 skrll break;
608 1.1 skrll }
609 1.1 skrll flags++;
610 1.1 skrll }
611 1.1 skrll
612 1.1 skrll if (p_flags
613 1.1 skrll && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
614 1.1 skrll | MSP430_PROFILER_FLAG_EXIT))
615 1.1 skrll || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
616 1.1 skrll | MSP430_PROFILER_FLAG_PROLEND
617 1.1 skrll | MSP430_PROFILER_FLAG_EPISTART
618 1.1 skrll | MSP430_PROFILER_FLAG_EPIEND))
619 1.1 skrll || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
620 1.1 skrll | MSP430_PROFILER_FLAG_FINISECT))))
621 1.1 skrll {
622 1.1 skrll as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
623 1.1 skrll input_line_pointer = end;
624 1.1 skrll return;
625 1.1 skrll }
626 1.1 skrll
627 1.1 skrll /* Generate temp symbol which denotes current location. */
628 1.1 skrll if (now_seg == absolute_section) /* Paranoia ? */
629 1.1 skrll {
630 1.1 skrll exp1.X_op = O_constant;
631 1.1 skrll exp1.X_add_number = abs_section_offset;
632 1.1 skrll as_warn (_("profiling in absolute section?"));
633 1.1 skrll }
634 1.1 skrll else
635 1.1 skrll {
636 1.1 skrll exp1.X_op = O_symbol;
637 1.1 skrll exp1.X_add_symbol = symbol_temp_new_now ();
638 1.1 skrll exp1.X_add_number = 0;
639 1.1 skrll }
640 1.1 skrll
641 1.1 skrll /* Generate a symbol which holds flags value. */
642 1.1 skrll exp.X_op = O_constant;
643 1.1 skrll exp.X_add_number = p_flags;
644 1.1 skrll
645 1.1 skrll /* Save current section. */
646 1.1 skrll seg = now_seg;
647 1.1 skrll subseg = now_subseg;
648 1.1 skrll
649 1.1 skrll /* Now go to .profiler section. */
650 1.1 skrll obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
651 1.1 skrll
652 1.1 skrll /* Save flags. */
653 1.1 skrll emit_expr (& exp, 2);
654 1.1 skrll
655 1.1 skrll /* Save label value. */
656 1.1 skrll emit_expr (& exp1, 2);
657 1.1 skrll
658 1.1 skrll while (ops--)
659 1.1 skrll {
660 1.1 skrll /* Now get profiling info. */
661 1.1 skrll halt = extract_operand (input_line_pointer, str, 1024);
662 1.1 skrll /* Process like ".word xxx" directive. */
663 1.1 skrll parse_exp (str, & exp);
664 1.1 skrll emit_expr (& exp, 2);
665 1.1 skrll input_line_pointer = halt;
666 1.1 skrll }
667 1.1 skrll
668 1.1 skrll /* Fill the rest with zeros. */
669 1.1 skrll exp.X_op = O_constant;
670 1.1 skrll exp.X_add_number = 0;
671 1.1 skrll while (left--)
672 1.1 skrll emit_expr (& exp, 2);
673 1.1 skrll
674 1.1 skrll /* Return to current section. */
675 1.1 skrll subseg_set (seg, subseg);
676 1.1 skrll }
677 1.1 skrll
678 1.1 skrll static char *
679 1.1 skrll extract_word (char * from, char * to, int limit)
680 1.1 skrll {
681 1.1 skrll char *op_end;
682 1.1 skrll int size = 0;
683 1.1 skrll
684 1.1 skrll /* Drop leading whitespace. */
685 1.1 skrll from = skip_space (from);
686 1.1 skrll *to = 0;
687 1.1 skrll
688 1.1 skrll /* Find the op code end. */
689 1.1.1.2 christos for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
690 1.1 skrll {
691 1.1 skrll to[size++] = *op_end++;
692 1.1 skrll if (size + 1 >= limit)
693 1.1 skrll break;
694 1.1 skrll }
695 1.1 skrll
696 1.1 skrll to[size] = 0;
697 1.1 skrll return op_end;
698 1.1 skrll }
699 1.1 skrll
700 1.1 skrll #define OPTION_MMCU 'm'
701 1.1 skrll #define OPTION_RELAX 'Q'
702 1.1 skrll #define OPTION_POLYMORPHS 'P'
703 1.1 skrll
704 1.1 skrll static void
705 1.1 skrll msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
706 1.1 skrll {
707 1.1 skrll char *str = (char *) alloca (32); /* 32 for good measure. */
708 1.1 skrll
709 1.1 skrll input_line_pointer = extract_word (input_line_pointer, str, 32);
710 1.1 skrll
711 1.1 skrll md_parse_option (OPTION_MMCU, str);
712 1.1 skrll bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
713 1.1 skrll }
714 1.1 skrll
715 1.1 skrll static void
716 1.1 skrll show_mcu_list (FILE * stream)
717 1.1 skrll {
718 1.1 skrll int i;
719 1.1 skrll
720 1.1 skrll fprintf (stream, _("Known MCU names:\n"));
721 1.1 skrll
722 1.1 skrll for (i = 0; mcu_types[i].name; i++)
723 1.1 skrll fprintf (stream, _("\t %s\n"), mcu_types[i].name);
724 1.1 skrll
725 1.1 skrll fprintf (stream, "\n");
726 1.1 skrll }
727 1.1 skrll
728 1.1 skrll int
729 1.1 skrll md_parse_option (int c, char * arg)
730 1.1 skrll {
731 1.1 skrll int i;
732 1.1 skrll
733 1.1 skrll switch (c)
734 1.1 skrll {
735 1.1 skrll case OPTION_MMCU:
736 1.1 skrll for (i = 0; mcu_types[i].name; ++i)
737 1.1 skrll if (strcmp (mcu_types[i].name, arg) == 0)
738 1.1 skrll break;
739 1.1 skrll
740 1.1 skrll if (!mcu_types[i].name)
741 1.1 skrll {
742 1.1 skrll show_mcu_list (stderr);
743 1.1 skrll as_fatal (_("unknown MCU: %s\n"), arg);
744 1.1 skrll }
745 1.1 skrll
746 1.1 skrll if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
747 1.1 skrll msp430_mcu = &mcu_types[i];
748 1.1 skrll else
749 1.1 skrll as_fatal (_("redefinition of mcu type %s' to %s'"),
750 1.1 skrll msp430_mcu->name, mcu_types[i].name);
751 1.1 skrll return 1;
752 1.1 skrll break;
753 1.1 skrll
754 1.1 skrll case OPTION_RELAX:
755 1.1 skrll msp430_enable_relax = 1;
756 1.1 skrll return 1;
757 1.1 skrll break;
758 1.1 skrll
759 1.1 skrll case OPTION_POLYMORPHS:
760 1.1 skrll msp430_enable_polys = 1;
761 1.1 skrll return 1;
762 1.1 skrll break;
763 1.1 skrll }
764 1.1 skrll
765 1.1 skrll return 0;
766 1.1 skrll }
767 1.1 skrll
768 1.1 skrll
769 1.1 skrll const pseudo_typeS md_pseudo_table[] =
770 1.1 skrll {
771 1.1 skrll {"arch", msp430_set_arch, 0},
772 1.1 skrll {"profiler", msp430_profiler, 0},
773 1.1 skrll {NULL, NULL, 0}
774 1.1 skrll };
775 1.1 skrll
776 1.1 skrll const char *md_shortopts = "m:";
777 1.1 skrll
778 1.1 skrll struct option md_longopts[] =
779 1.1 skrll {
780 1.1 skrll {"mmcu", required_argument, NULL, OPTION_MMCU},
781 1.1 skrll {"mP", no_argument, NULL, OPTION_POLYMORPHS},
782 1.1 skrll {"mQ", no_argument, NULL, OPTION_RELAX},
783 1.1 skrll {NULL, no_argument, NULL, 0}
784 1.1 skrll };
785 1.1 skrll
786 1.1 skrll size_t md_longopts_size = sizeof (md_longopts);
787 1.1 skrll
788 1.1 skrll void
789 1.1 skrll md_show_usage (FILE * stream)
790 1.1 skrll {
791 1.1 skrll fprintf (stream,
792 1.1 skrll _("MSP430 options:\n"
793 1.1 skrll " -mmcu=[msp430-name] select microcontroller type\n"
794 1.1 skrll " msp430x110 msp430x112\n"
795 1.1 skrll " msp430x1101 msp430x1111\n"
796 1.1 skrll " msp430x1121 msp430x1122 msp430x1132\n"
797 1.1 skrll " msp430x122 msp430x123\n"
798 1.1 skrll " msp430x1222 msp430x1232\n"
799 1.1 skrll " msp430x133 msp430x135\n"
800 1.1 skrll " msp430x1331 msp430x1351\n"
801 1.1 skrll " msp430x147 msp430x148 msp430x149\n"
802 1.1 skrll " msp430x155 msp430x156 msp430x157\n"
803 1.1 skrll " msp430x167 msp430x168 msp430x169\n"
804 1.1 skrll " msp430x1610 msp430x1611 msp430x1612\n"
805 1.1 skrll " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
806 1.1 skrll " msp430x323 msp430x325\n"
807 1.1 skrll " msp430x336 msp430x337\n"
808 1.1 skrll " msp430x412 msp430x413 msp430x415 msp430x417\n"
809 1.1 skrll " msp430xE423 msp430xE425 msp430E427\n"
810 1.1 skrll " msp430xW423 msp430xW425 msp430W427\n"
811 1.1 skrll " msp430xG437 msp430xG438 msp430G439\n"
812 1.1 skrll " msp430x435 msp430x436 msp430x437\n"
813 1.1 skrll " msp430x447 msp430x448 msp430x449\n"));
814 1.1 skrll fprintf (stream,
815 1.1 skrll _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
816 1.1 skrll " -mP - enable polymorph instructions\n"));
817 1.1 skrll
818 1.1 skrll show_mcu_list (stream);
819 1.1 skrll }
820 1.1 skrll
821 1.1 skrll symbolS *
822 1.1 skrll md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
823 1.1 skrll {
824 1.1 skrll return 0;
825 1.1 skrll }
826 1.1 skrll
827 1.1 skrll static char *
828 1.1 skrll extract_cmd (char * from, char * to, int limit)
829 1.1 skrll {
830 1.1 skrll int size = 0;
831 1.1 skrll
832 1.1 skrll while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
833 1.1 skrll {
834 1.1 skrll *(to + size) = *from;
835 1.1 skrll from++;
836 1.1 skrll size++;
837 1.1 skrll }
838 1.1 skrll
839 1.1 skrll *(to + size) = 0;
840 1.1 skrll
841 1.1 skrll return from;
842 1.1 skrll }
843 1.1 skrll
844 1.1 skrll char *
845 1.1 skrll md_atof (int type, char * litP, int * sizeP)
846 1.1 skrll {
847 1.1 skrll return ieee_md_atof (type, litP, sizeP, FALSE);
848 1.1 skrll }
849 1.1 skrll
850 1.1 skrll void
851 1.1 skrll md_begin (void)
852 1.1 skrll {
853 1.1 skrll struct msp430_opcode_s * opcode;
854 1.1 skrll msp430_hash = hash_new ();
855 1.1 skrll
856 1.1 skrll for (opcode = msp430_opcodes; opcode->name; opcode++)
857 1.1 skrll hash_insert (msp430_hash, opcode->name, (char *) opcode);
858 1.1 skrll
859 1.1 skrll bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
860 1.1 skrll }
861 1.1 skrll
862 1.1 skrll static int
863 1.1 skrll check_reg (char * t)
864 1.1 skrll {
865 1.1 skrll /* If this is a reg numb, str 't' must be a number from 0 - 15. */
866 1.1 skrll
867 1.1 skrll if (strlen (t) > 2 && *(t + 2) != '+')
868 1.1 skrll return 1;
869 1.1 skrll
870 1.1 skrll while (*t)
871 1.1 skrll {
872 1.1 skrll if ((*t < '0' || *t > '9') && *t != '+')
873 1.1 skrll break;
874 1.1 skrll t++;
875 1.1 skrll }
876 1.1 skrll
877 1.1 skrll if (*t)
878 1.1 skrll return 1;
879 1.1 skrll
880 1.1 skrll return 0;
881 1.1 skrll }
882 1.1 skrll
883 1.1 skrll
884 1.1 skrll static int
885 1.1 skrll msp430_srcoperand (struct msp430_operand_s * op,
886 1.1 skrll char * l, int bin, int * imm_op)
887 1.1 skrll {
888 1.1 skrll char *__tl = l;
889 1.1 skrll
890 1.1 skrll /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
891 1.1 skrll if (*l == '#')
892 1.1 skrll {
893 1.1 skrll char *h = l;
894 1.1 skrll int vshift = -1;
895 1.1 skrll int rval = 0;
896 1.1 skrll
897 1.1 skrll /* Check if there is:
898 1.1 skrll llo(x) - least significant 16 bits, x &= 0xffff
899 1.1 skrll lhi(x) - x = (x >> 16) & 0xffff,
900 1.1 skrll hlo(x) - x = (x >> 32) & 0xffff,
901 1.1 skrll hhi(x) - x = (x >> 48) & 0xffff
902 1.1 skrll The value _MUST_ be constant expression: #hlo(1231231231). */
903 1.1 skrll
904 1.1 skrll *imm_op = 1;
905 1.1 skrll
906 1.1 skrll if (strncasecmp (h, "#llo(", 5) == 0)
907 1.1 skrll {
908 1.1 skrll vshift = 0;
909 1.1 skrll rval = 3;
910 1.1 skrll }
911 1.1 skrll else if (strncasecmp (h, "#lhi(", 5) == 0)
912 1.1 skrll {
913 1.1 skrll vshift = 1;
914 1.1 skrll rval = 3;
915 1.1 skrll }
916 1.1 skrll else if (strncasecmp (h, "#hlo(", 5) == 0)
917 1.1 skrll {
918 1.1 skrll vshift = 2;
919 1.1 skrll rval = 3;
920 1.1 skrll }
921 1.1 skrll else if (strncasecmp (h, "#hhi(", 5) == 0)
922 1.1 skrll {
923 1.1 skrll vshift = 3;
924 1.1 skrll rval = 3;
925 1.1 skrll }
926 1.1 skrll else if (strncasecmp (h, "#lo(", 4) == 0)
927 1.1 skrll {
928 1.1 skrll vshift = 0;
929 1.1 skrll rval = 2;
930 1.1 skrll }
931 1.1 skrll else if (strncasecmp (h, "#hi(", 4) == 0)
932 1.1 skrll {
933 1.1 skrll vshift = 1;
934 1.1 skrll rval = 2;
935 1.1 skrll }
936 1.1 skrll
937 1.1 skrll op->reg = 0; /* Reg PC. */
938 1.1 skrll op->am = 3;
939 1.1 skrll op->ol = 1; /* Immediate will follow an instruction. */
940 1.1 skrll __tl = h + 1 + rval;
941 1.1 skrll op->mode = OP_EXP;
942 1.1 skrll
943 1.1 skrll parse_exp (__tl, &(op->exp));
944 1.1 skrll if (op->exp.X_op == O_constant)
945 1.1 skrll {
946 1.1 skrll int x = op->exp.X_add_number;
947 1.1 skrll
948 1.1 skrll if (vshift == 0)
949 1.1 skrll {
950 1.1 skrll x = x & 0xffff;
951 1.1 skrll op->exp.X_add_number = x;
952 1.1 skrll }
953 1.1 skrll else if (vshift == 1)
954 1.1 skrll {
955 1.1 skrll x = (x >> 16) & 0xffff;
956 1.1 skrll op->exp.X_add_number = x;
957 1.1 skrll }
958 1.1 skrll else if (vshift > 1)
959 1.1 skrll {
960 1.1 skrll if (x < 0)
961 1.1 skrll op->exp.X_add_number = -1;
962 1.1 skrll else
963 1.1 skrll op->exp.X_add_number = 0; /* Nothing left. */
964 1.1 skrll x = op->exp.X_add_number;
965 1.1 skrll }
966 1.1 skrll
967 1.1 skrll if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
968 1.1 skrll {
969 1.1 skrll as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
970 1.1 skrll return 1;
971 1.1 skrll }
972 1.1 skrll
973 1.1 skrll /* Now check constants. */
974 1.1 skrll /* Substitute register mode with a constant generator if applicable. */
975 1.1 skrll
976 1.1 skrll x = (short) x; /* Extend sign. */
977 1.1 skrll
978 1.1 skrll if (x == 0)
979 1.1 skrll {
980 1.1 skrll op->reg = 3;
981 1.1 skrll op->am = 0;
982 1.1 skrll op->ol = 0;
983 1.1 skrll op->mode = OP_REG;
984 1.1 skrll }
985 1.1 skrll else if (x == 1)
986 1.1 skrll {
987 1.1 skrll op->reg = 3;
988 1.1 skrll op->am = 1;
989 1.1 skrll op->ol = 0;
990 1.1 skrll op->mode = OP_REG;
991 1.1 skrll }
992 1.1 skrll else if (x == 2)
993 1.1 skrll {
994 1.1 skrll op->reg = 3;
995 1.1 skrll op->am = 2;
996 1.1 skrll op->ol = 0;
997 1.1 skrll op->mode = OP_REG;
998 1.1 skrll }
999 1.1 skrll else if (x == -1)
1000 1.1 skrll {
1001 1.1 skrll op->reg = 3;
1002 1.1 skrll op->am = 3;
1003 1.1 skrll op->ol = 0;
1004 1.1 skrll op->mode = OP_REG;
1005 1.1 skrll }
1006 1.1 skrll else if (x == 4)
1007 1.1 skrll {
1008 1.1 skrll #ifdef PUSH_1X_WORKAROUND
1009 1.1 skrll if (bin == 0x1200)
1010 1.1 skrll {
1011 1.1 skrll /* Remove warning as confusing.
1012 1.1.1.2 christos as_warn (_("Hardware push bug workaround")); */
1013 1.1 skrll }
1014 1.1 skrll else
1015 1.1 skrll #endif
1016 1.1 skrll {
1017 1.1 skrll op->reg = 2;
1018 1.1 skrll op->am = 2;
1019 1.1 skrll op->ol = 0;
1020 1.1 skrll op->mode = OP_REG;
1021 1.1 skrll }
1022 1.1 skrll }
1023 1.1 skrll else if (x == 8)
1024 1.1 skrll {
1025 1.1 skrll #ifdef PUSH_1X_WORKAROUND
1026 1.1 skrll if (bin == 0x1200)
1027 1.1 skrll {
1028 1.1 skrll /* Remove warning as confusing.
1029 1.1.1.2 christos as_warn (_("Hardware push bug workaround")); */
1030 1.1 skrll }
1031 1.1 skrll else
1032 1.1 skrll #endif
1033 1.1 skrll {
1034 1.1 skrll op->reg = 2;
1035 1.1 skrll op->am = 3;
1036 1.1 skrll op->ol = 0;
1037 1.1 skrll op->mode = OP_REG;
1038 1.1 skrll }
1039 1.1 skrll }
1040 1.1 skrll }
1041 1.1 skrll else if (op->exp.X_op == O_symbol)
1042 1.1 skrll {
1043 1.1 skrll op->mode = OP_EXP;
1044 1.1 skrll }
1045 1.1 skrll else if (op->exp.X_op == O_big)
1046 1.1 skrll {
1047 1.1 skrll short x;
1048 1.1 skrll if (vshift != -1)
1049 1.1 skrll {
1050 1.1 skrll op->exp.X_op = O_constant;
1051 1.1 skrll op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1052 1.1 skrll x = op->exp.X_add_number;
1053 1.1 skrll }
1054 1.1 skrll else
1055 1.1 skrll {
1056 1.1 skrll as_bad (_
1057 1.1 skrll ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1058 1.1 skrll l);
1059 1.1 skrll return 1;
1060 1.1 skrll }
1061 1.1 skrll
1062 1.1 skrll if (x == 0)
1063 1.1 skrll {
1064 1.1 skrll op->reg = 3;
1065 1.1 skrll op->am = 0;
1066 1.1 skrll op->ol = 0;
1067 1.1 skrll op->mode = OP_REG;
1068 1.1 skrll }
1069 1.1 skrll else if (x == 1)
1070 1.1 skrll {
1071 1.1 skrll op->reg = 3;
1072 1.1 skrll op->am = 1;
1073 1.1 skrll op->ol = 0;
1074 1.1 skrll op->mode = OP_REG;
1075 1.1 skrll }
1076 1.1 skrll else if (x == 2)
1077 1.1 skrll {
1078 1.1 skrll op->reg = 3;
1079 1.1 skrll op->am = 2;
1080 1.1 skrll op->ol = 0;
1081 1.1 skrll op->mode = OP_REG;
1082 1.1 skrll }
1083 1.1 skrll else if (x == -1)
1084 1.1 skrll {
1085 1.1 skrll op->reg = 3;
1086 1.1 skrll op->am = 3;
1087 1.1 skrll op->ol = 0;
1088 1.1 skrll op->mode = OP_REG;
1089 1.1 skrll }
1090 1.1 skrll else if (x == 4)
1091 1.1 skrll {
1092 1.1 skrll op->reg = 2;
1093 1.1 skrll op->am = 2;
1094 1.1 skrll op->ol = 0;
1095 1.1 skrll op->mode = OP_REG;
1096 1.1 skrll }
1097 1.1 skrll else if (x == 8)
1098 1.1 skrll {
1099 1.1 skrll op->reg = 2;
1100 1.1 skrll op->am = 3;
1101 1.1 skrll op->ol = 0;
1102 1.1 skrll op->mode = OP_REG;
1103 1.1 skrll }
1104 1.1 skrll }
1105 1.1 skrll /* Redundant (yet) check. */
1106 1.1 skrll else if (op->exp.X_op == O_register)
1107 1.1 skrll as_bad
1108 1.1 skrll (_("Registers cannot be used within immediate expression [%s]"), l);
1109 1.1 skrll else
1110 1.1 skrll as_bad (_("unknown operand %s"), l);
1111 1.1 skrll
1112 1.1 skrll return 0;
1113 1.1 skrll }
1114 1.1 skrll
1115 1.1 skrll /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1116 1.1 skrll if (*l == '&')
1117 1.1 skrll {
1118 1.1 skrll char *h = l;
1119 1.1 skrll
1120 1.1 skrll op->reg = 2; /* reg 2 in absolute addr mode. */
1121 1.1 skrll op->am = 1; /* mode As == 01 bin. */
1122 1.1 skrll op->ol = 1; /* Immediate value followed by instruction. */
1123 1.1 skrll __tl = h + 1;
1124 1.1 skrll parse_exp (__tl, &(op->exp));
1125 1.1 skrll op->mode = OP_EXP;
1126 1.1 skrll if (op->exp.X_op == O_constant)
1127 1.1 skrll {
1128 1.1 skrll int x = op->exp.X_add_number;
1129 1.1 skrll
1130 1.1 skrll if (x > 65535 || x < -32768)
1131 1.1 skrll {
1132 1.1 skrll as_bad (_("value out of range: %d"), x);
1133 1.1 skrll return 1;
1134 1.1 skrll }
1135 1.1 skrll }
1136 1.1 skrll else if (op->exp.X_op == O_symbol)
1137 1.1 skrll ;
1138 1.1 skrll else
1139 1.1 skrll {
1140 1.1 skrll /* Redundant (yet) check. */
1141 1.1 skrll if (op->exp.X_op == O_register)
1142 1.1 skrll as_bad
1143 1.1 skrll (_("Registers cannot be used within absolute expression [%s]"), l);
1144 1.1 skrll else
1145 1.1 skrll as_bad (_("unknown expression in operand %s"), l);
1146 1.1 skrll return 1;
1147 1.1 skrll }
1148 1.1 skrll return 0;
1149 1.1 skrll }
1150 1.1 skrll
1151 1.1 skrll /* Check if indirect register mode @Rn / postincrement @Rn+. */
1152 1.1 skrll if (*l == '@')
1153 1.1 skrll {
1154 1.1 skrll char *t = l;
1155 1.1 skrll char *m = strchr (l, '+');
1156 1.1 skrll
1157 1.1 skrll if (t != l)
1158 1.1 skrll {
1159 1.1 skrll as_bad (_("unknown addressing mode %s"), l);
1160 1.1 skrll return 1;
1161 1.1 skrll }
1162 1.1 skrll
1163 1.1 skrll t++;
1164 1.1 skrll if (*t != 'r' && *t != 'R')
1165 1.1 skrll {
1166 1.1 skrll as_bad (_("unknown addressing mode %s"), l);
1167 1.1 skrll return 1;
1168 1.1 skrll }
1169 1.1 skrll
1170 1.1 skrll t++; /* Points to the reg value. */
1171 1.1 skrll
1172 1.1 skrll if (check_reg (t))
1173 1.1 skrll {
1174 1.1 skrll as_bad (_("Bad register name r%s"), t);
1175 1.1 skrll return 1;
1176 1.1 skrll }
1177 1.1 skrll
1178 1.1 skrll op->mode = OP_REG;
1179 1.1 skrll op->am = m ? 3 : 2;
1180 1.1 skrll op->ol = 0;
1181 1.1 skrll if (m)
1182 1.1 skrll *m = 0; /* strip '+' */
1183 1.1 skrll op->reg = atoi (t);
1184 1.1 skrll if (op->reg < 0 || op->reg > 15)
1185 1.1 skrll {
1186 1.1 skrll as_bad (_("MSP430 does not have %d registers"), op->reg);
1187 1.1 skrll return 1;
1188 1.1 skrll }
1189 1.1 skrll
1190 1.1 skrll return 0;
1191 1.1 skrll }
1192 1.1 skrll
1193 1.1 skrll /* Check if register indexed X(Rn). */
1194 1.1 skrll do
1195 1.1 skrll {
1196 1.1 skrll char *h = strrchr (l, '(');
1197 1.1 skrll char *m = strrchr (l, ')');
1198 1.1 skrll char *t;
1199 1.1 skrll
1200 1.1 skrll *imm_op = 1;
1201 1.1 skrll
1202 1.1 skrll if (!h)
1203 1.1 skrll break;
1204 1.1 skrll if (!m)
1205 1.1 skrll {
1206 1.1 skrll as_bad (_("')' required"));
1207 1.1 skrll return 1;
1208 1.1 skrll }
1209 1.1 skrll
1210 1.1 skrll t = h;
1211 1.1 skrll op->am = 1;
1212 1.1 skrll op->ol = 1;
1213 1.1 skrll /* Extract a register. */
1214 1.1 skrll t++; /* Advance pointer. */
1215 1.1 skrll
1216 1.1 skrll if (*t != 'r' && *t != 'R')
1217 1.1 skrll {
1218 1.1 skrll as_bad (_
1219 1.1 skrll ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1220 1.1 skrll l);
1221 1.1 skrll return 1;
1222 1.1 skrll }
1223 1.1 skrll t++;
1224 1.1 skrll
1225 1.1 skrll op->reg = *t - '0';
1226 1.1 skrll if (op->reg > 9 || op->reg < 0)
1227 1.1 skrll {
1228 1.1 skrll as_bad (_("unknown operator (r%s substituted as a register name"),
1229 1.1 skrll t);
1230 1.1 skrll return 1;
1231 1.1 skrll }
1232 1.1 skrll t++;
1233 1.1 skrll if (*t != ')')
1234 1.1 skrll {
1235 1.1 skrll op->reg = op->reg * 10;
1236 1.1 skrll op->reg += *t - '0';
1237 1.1 skrll
1238 1.1 skrll if (op->reg > 15)
1239 1.1 skrll {
1240 1.1 skrll as_bad (_("unknown operator %s"), l);
1241 1.1 skrll return 1;
1242 1.1 skrll }
1243 1.1 skrll if (op->reg == 2)
1244 1.1 skrll {
1245 1.1 skrll as_bad (_("r2 should not be used in indexed addressing mode"));
1246 1.1 skrll return 1;
1247 1.1 skrll }
1248 1.1 skrll
1249 1.1 skrll if (*(t + 1) != ')')
1250 1.1 skrll {
1251 1.1 skrll as_bad (_("unknown operator %s"), l);
1252 1.1 skrll return 1;
1253 1.1 skrll }
1254 1.1 skrll }
1255 1.1 skrll
1256 1.1 skrll /* Extract constant. */
1257 1.1 skrll __tl = l;
1258 1.1 skrll *h = 0;
1259 1.1 skrll op->mode = OP_EXP;
1260 1.1 skrll parse_exp (__tl, &(op->exp));
1261 1.1 skrll if (op->exp.X_op == O_constant)
1262 1.1 skrll {
1263 1.1 skrll int x = op->exp.X_add_number;
1264 1.1 skrll
1265 1.1 skrll if (x > 65535 || x < -32768)
1266 1.1 skrll {
1267 1.1 skrll as_bad (_("value out of range: %d"), x);
1268 1.1 skrll return 1;
1269 1.1 skrll }
1270 1.1 skrll
1271 1.1 skrll if (x == 0)
1272 1.1 skrll {
1273 1.1 skrll op->mode = OP_REG;
1274 1.1 skrll op->am = 2;
1275 1.1 skrll op->ol = 0;
1276 1.1 skrll return 0;
1277 1.1 skrll }
1278 1.1 skrll }
1279 1.1 skrll else if (op->exp.X_op == O_symbol)
1280 1.1 skrll ;
1281 1.1 skrll else
1282 1.1 skrll {
1283 1.1 skrll /* Redundant (yet) check. */
1284 1.1 skrll if (op->exp.X_op == O_register)
1285 1.1 skrll as_bad
1286 1.1 skrll (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1287 1.1 skrll else
1288 1.1 skrll as_bad (_("unknown expression in operand %s"), l);
1289 1.1 skrll return 1;
1290 1.1 skrll }
1291 1.1 skrll
1292 1.1 skrll return 0;
1293 1.1 skrll }
1294 1.1 skrll while (0);
1295 1.1 skrll
1296 1.1 skrll /* Register mode 'mov r1,r2'. */
1297 1.1 skrll do
1298 1.1 skrll {
1299 1.1 skrll char *t = l;
1300 1.1 skrll
1301 1.1 skrll /* Operand should be a register. */
1302 1.1 skrll if (*t == 'r' || *t == 'R')
1303 1.1 skrll {
1304 1.1 skrll int x = atoi (t + 1);
1305 1.1 skrll
1306 1.1 skrll if (check_reg (t + 1))
1307 1.1 skrll break;
1308 1.1 skrll
1309 1.1 skrll if (x < 0 || x > 15)
1310 1.1 skrll break; /* Symbolic mode. */
1311 1.1 skrll
1312 1.1 skrll op->mode = OP_REG;
1313 1.1 skrll op->am = 0;
1314 1.1 skrll op->ol = 0;
1315 1.1 skrll op->reg = x;
1316 1.1 skrll return 0;
1317 1.1 skrll }
1318 1.1 skrll }
1319 1.1 skrll while (0);
1320 1.1 skrll
1321 1.1 skrll /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1322 1.1 skrll do
1323 1.1 skrll {
1324 1.1 skrll op->mode = OP_EXP;
1325 1.1 skrll op->reg = 0; /* PC relative... be careful. */
1326 1.1 skrll op->am = 1;
1327 1.1 skrll op->ol = 1;
1328 1.1 skrll __tl = l;
1329 1.1 skrll parse_exp (__tl, &(op->exp));
1330 1.1 skrll return 0;
1331 1.1 skrll }
1332 1.1 skrll while (0);
1333 1.1 skrll
1334 1.1 skrll /* Unreachable. */
1335 1.1 skrll as_bad (_("unknown addressing mode for operand %s"), l);
1336 1.1 skrll return 1;
1337 1.1 skrll }
1338 1.1 skrll
1339 1.1 skrll
1340 1.1 skrll static int
1341 1.1 skrll msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
1342 1.1 skrll {
1343 1.1 skrll int dummy;
1344 1.1 skrll int ret = msp430_srcoperand (op, l, bin, & dummy);
1345 1.1 skrll
1346 1.1 skrll if (ret)
1347 1.1 skrll return ret;
1348 1.1 skrll
1349 1.1 skrll if (op->am == 2)
1350 1.1 skrll {
1351 1.1 skrll char *__tl = "0";
1352 1.1 skrll
1353 1.1 skrll op->mode = OP_EXP;
1354 1.1 skrll op->am = 1;
1355 1.1 skrll op->ol = 1;
1356 1.1 skrll parse_exp (__tl, &(op->exp));
1357 1.1 skrll
1358 1.1 skrll if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1359 1.1 skrll {
1360 1.1 skrll as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1361 1.1 skrll op->reg, op->reg);
1362 1.1 skrll return 1;
1363 1.1 skrll }
1364 1.1 skrll return 0;
1365 1.1 skrll }
1366 1.1 skrll
1367 1.1 skrll if (op->am > 1)
1368 1.1 skrll {
1369 1.1 skrll as_bad (_
1370 1.1 skrll ("this addressing mode is not applicable for destination operand"));
1371 1.1 skrll return 1;
1372 1.1 skrll }
1373 1.1 skrll return 0;
1374 1.1 skrll }
1375 1.1 skrll
1376 1.1 skrll
1377 1.1 skrll /* Parse instruction operands.
1378 1.1 skrll Return binary opcode. */
1379 1.1 skrll
1380 1.1 skrll static unsigned int
1381 1.1 skrll msp430_operands (struct msp430_opcode_s * opcode, char * line)
1382 1.1 skrll {
1383 1.1 skrll int bin = opcode->bin_opcode; /* Opcode mask. */
1384 1.1 skrll int __is = 0;
1385 1.1 skrll char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1386 1.1 skrll char *frag;
1387 1.1 skrll int where;
1388 1.1 skrll struct msp430_operand_s op1, op2;
1389 1.1 skrll int res = 0;
1390 1.1 skrll static short ZEROS = 0;
1391 1.1 skrll int byte_op, imm_op;
1392 1.1 skrll
1393 1.1 skrll /* Opcode is the one from opcodes table
1394 1.1 skrll line contains something like
1395 1.1 skrll [.w] @r2+, 5(R1)
1396 1.1 skrll or
1397 1.1 skrll .b @r2+, 5(R1). */
1398 1.1 skrll
1399 1.1 skrll /* Check if byte or word operation. */
1400 1.1 skrll if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
1401 1.1 skrll {
1402 1.1 skrll bin |= BYTE_OPERATION;
1403 1.1 skrll byte_op = 1;
1404 1.1 skrll }
1405 1.1 skrll else
1406 1.1 skrll byte_op = 0;
1407 1.1 skrll
1408 1.1 skrll /* skip .[bwBW]. */
1409 1.1 skrll while (! ISSPACE (*line) && *line)
1410 1.1 skrll line++;
1411 1.1 skrll
1412 1.1 skrll if (opcode->insn_opnumb && (!*line || *line == '\n'))
1413 1.1 skrll {
1414 1.1 skrll as_bad (_("instruction %s requires %d operand(s)"),
1415 1.1 skrll opcode->name, opcode->insn_opnumb);
1416 1.1 skrll return 0;
1417 1.1 skrll }
1418 1.1 skrll
1419 1.1 skrll memset (l1, 0, sizeof (l1));
1420 1.1 skrll memset (l2, 0, sizeof (l2));
1421 1.1 skrll memset (&op1, 0, sizeof (op1));
1422 1.1 skrll memset (&op2, 0, sizeof (op2));
1423 1.1 skrll
1424 1.1 skrll imm_op = 0;
1425 1.1 skrll
1426 1.1 skrll switch (opcode->fmt)
1427 1.1 skrll {
1428 1.1 skrll case 0: /* Emulated. */
1429 1.1 skrll switch (opcode->insn_opnumb)
1430 1.1 skrll {
1431 1.1 skrll case 0:
1432 1.1 skrll /* Set/clear bits instructions. */
1433 1.1 skrll __is = 2;
1434 1.1 skrll frag = frag_more (__is);
1435 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1436 1.1 skrll dwarf2_emit_insn (__is);
1437 1.1 skrll break;
1438 1.1 skrll case 1:
1439 1.1 skrll /* Something which works with destination operand. */
1440 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1441 1.1 skrll res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1442 1.1 skrll if (res)
1443 1.1 skrll break;
1444 1.1 skrll
1445 1.1 skrll bin |= (op1.reg | (op1.am << 7));
1446 1.1 skrll __is = 1 + op1.ol;
1447 1.1 skrll frag = frag_more (2 * __is);
1448 1.1 skrll where = frag - frag_now->fr_literal;
1449 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1450 1.1 skrll dwarf2_emit_insn (2 * __is);
1451 1.1 skrll
1452 1.1 skrll if (op1.mode == OP_EXP)
1453 1.1 skrll {
1454 1.1 skrll where += 2;
1455 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1456 1.1 skrll
1457 1.1 skrll if (op1.reg)
1458 1.1 skrll fix_new_exp (frag_now, where, 2,
1459 1.1 skrll &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1460 1.1 skrll else
1461 1.1 skrll fix_new_exp (frag_now, where, 2,
1462 1.1 skrll &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1463 1.1 skrll }
1464 1.1 skrll break;
1465 1.1 skrll
1466 1.1 skrll case 2:
1467 1.1 skrll {
1468 1.1 skrll /* Shift instruction. */
1469 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1470 1.1 skrll strncpy (l2, l1, sizeof (l2));
1471 1.1 skrll l2[sizeof (l2) - 1] = '\0';
1472 1.1 skrll res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1473 1.1 skrll res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1474 1.1 skrll
1475 1.1 skrll if (res)
1476 1.1 skrll break; /* An error occurred. All warnings were done before. */
1477 1.1 skrll
1478 1.1 skrll bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1479 1.1 skrll
1480 1.1 skrll __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1481 1.1 skrll frag = frag_more (2 * __is);
1482 1.1 skrll where = frag - frag_now->fr_literal;
1483 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1484 1.1 skrll dwarf2_emit_insn (2 * __is);
1485 1.1 skrll
1486 1.1 skrll if (op1.mode == OP_EXP)
1487 1.1 skrll {
1488 1.1 skrll where += 2; /* Advance 'where' as we do not know _where_. */
1489 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1490 1.1 skrll
1491 1.1 skrll if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1492 1.1 skrll fix_new_exp (frag_now, where, 2,
1493 1.1 skrll &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1494 1.1 skrll else
1495 1.1 skrll fix_new_exp (frag_now, where, 2,
1496 1.1 skrll &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1497 1.1 skrll }
1498 1.1 skrll
1499 1.1 skrll if (op2.mode == OP_EXP)
1500 1.1 skrll {
1501 1.1 skrll imm_op = 0;
1502 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1503 1.1 skrll
1504 1.1 skrll if (op2.reg) /* Not PC relative. */
1505 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1506 1.1 skrll &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1507 1.1 skrll else
1508 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1509 1.1 skrll &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1510 1.1 skrll }
1511 1.1 skrll break;
1512 1.1 skrll }
1513 1.1 skrll case 3:
1514 1.1 skrll /* Branch instruction => mov dst, r0. */
1515 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1516 1.1 skrll
1517 1.1 skrll res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1518 1.1 skrll if (res)
1519 1.1 skrll break;
1520 1.1 skrll
1521 1.1 skrll byte_op = 0;
1522 1.1 skrll imm_op = 0;
1523 1.1 skrll
1524 1.1 skrll bin |= ((op1.reg << 8) | (op1.am << 4));
1525 1.1 skrll __is = 1 + op1.ol;
1526 1.1 skrll frag = frag_more (2 * __is);
1527 1.1 skrll where = frag - frag_now->fr_literal;
1528 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1529 1.1 skrll dwarf2_emit_insn (2 * __is);
1530 1.1 skrll
1531 1.1 skrll if (op1.mode == OP_EXP)
1532 1.1 skrll {
1533 1.1 skrll where += 2;
1534 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1535 1.1 skrll
1536 1.1 skrll if (op1.reg || (op1.reg == 0 && op1.am == 3))
1537 1.1 skrll fix_new_exp (frag_now, where, 2,
1538 1.1 skrll &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1539 1.1 skrll else
1540 1.1 skrll fix_new_exp (frag_now, where, 2,
1541 1.1 skrll &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1542 1.1 skrll }
1543 1.1 skrll break;
1544 1.1 skrll }
1545 1.1 skrll break;
1546 1.1 skrll
1547 1.1 skrll case 1: /* Format 1, double operand. */
1548 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1549 1.1 skrll line = extract_operand (line, l2, sizeof (l2));
1550 1.1 skrll res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1551 1.1 skrll res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1552 1.1 skrll
1553 1.1 skrll if (res)
1554 1.1 skrll break; /* Error occurred. All warnings were done before. */
1555 1.1 skrll
1556 1.1 skrll bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1557 1.1 skrll
1558 1.1 skrll __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1559 1.1 skrll frag = frag_more (2 * __is);
1560 1.1 skrll where = frag - frag_now->fr_literal;
1561 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1562 1.1 skrll dwarf2_emit_insn (2 * __is);
1563 1.1 skrll
1564 1.1 skrll if (op1.mode == OP_EXP)
1565 1.1 skrll {
1566 1.1 skrll where += 2; /* Advance where as we do not know _where_. */
1567 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1568 1.1 skrll
1569 1.1 skrll if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1570 1.1 skrll fix_new_exp (frag_now, where, 2,
1571 1.1 skrll &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1572 1.1 skrll else
1573 1.1 skrll fix_new_exp (frag_now, where, 2,
1574 1.1 skrll &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1575 1.1 skrll }
1576 1.1 skrll
1577 1.1 skrll if (op2.mode == OP_EXP)
1578 1.1 skrll {
1579 1.1 skrll imm_op = 0;
1580 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1581 1.1 skrll
1582 1.1 skrll if (op2.reg) /* Not PC relative. */
1583 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1584 1.1 skrll &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1585 1.1 skrll else
1586 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1587 1.1 skrll &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1588 1.1 skrll }
1589 1.1 skrll break;
1590 1.1 skrll
1591 1.1 skrll case 2: /* Single-operand mostly instr. */
1592 1.1 skrll if (opcode->insn_opnumb == 0)
1593 1.1 skrll {
1594 1.1 skrll /* reti instruction. */
1595 1.1 skrll frag = frag_more (2);
1596 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1597 1.1 skrll dwarf2_emit_insn (2);
1598 1.1 skrll break;
1599 1.1 skrll }
1600 1.1 skrll
1601 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1602 1.1 skrll res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1603 1.1 skrll if (res)
1604 1.1 skrll break; /* Error in operand. */
1605 1.1 skrll
1606 1.1 skrll bin |= op1.reg | (op1.am << 4);
1607 1.1 skrll __is = 1 + op1.ol;
1608 1.1 skrll frag = frag_more (2 * __is);
1609 1.1 skrll where = frag - frag_now->fr_literal;
1610 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1611 1.1 skrll dwarf2_emit_insn (2 * __is);
1612 1.1 skrll
1613 1.1 skrll if (op1.mode == OP_EXP)
1614 1.1 skrll {
1615 1.1 skrll bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1616 1.1 skrll
1617 1.1 skrll if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1618 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1619 1.1 skrll &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1620 1.1 skrll else
1621 1.1 skrll fix_new_exp (frag_now, where + 2, 2,
1622 1.1 skrll &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1623 1.1 skrll }
1624 1.1 skrll break;
1625 1.1 skrll
1626 1.1 skrll case 3: /* Conditional jumps instructions. */
1627 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1628 1.1 skrll /* l1 is a label. */
1629 1.1 skrll if (l1[0])
1630 1.1 skrll {
1631 1.1 skrll char *m = l1;
1632 1.1 skrll expressionS exp;
1633 1.1 skrll
1634 1.1 skrll if (*m == '$')
1635 1.1 skrll m++;
1636 1.1 skrll
1637 1.1 skrll parse_exp (m, &exp);
1638 1.1 skrll frag = frag_more (2); /* Instr size is 1 word. */
1639 1.1 skrll
1640 1.1 skrll /* In order to handle something like:
1641 1.1 skrll
1642 1.1 skrll and #0x8000, r5
1643 1.1 skrll tst r5
1644 1.1 skrll jz 4 ; skip next 4 bytes
1645 1.1 skrll inv r5
1646 1.1 skrll inc r5
1647 1.1 skrll nop ; will jump here if r5 positive or zero
1648 1.1 skrll
1649 1.1 skrll jCOND -n ;assumes jump n bytes backward:
1650 1.1 skrll
1651 1.1 skrll mov r5,r6
1652 1.1 skrll jmp -2
1653 1.1 skrll
1654 1.1 skrll is equal to:
1655 1.1 skrll lab:
1656 1.1 skrll mov r5,r6
1657 1.1 skrll jmp lab
1658 1.1 skrll
1659 1.1 skrll jCOND $n ; jump from PC in either direction. */
1660 1.1 skrll
1661 1.1 skrll if (exp.X_op == O_constant)
1662 1.1 skrll {
1663 1.1 skrll int x = exp.X_add_number;
1664 1.1 skrll
1665 1.1 skrll if (x & 1)
1666 1.1 skrll {
1667 1.1 skrll as_warn (_("Even number required. Rounded to %d"), x + 1);
1668 1.1 skrll x++;
1669 1.1 skrll }
1670 1.1 skrll
1671 1.1 skrll if ((*l1 == '$' && x > 0) || x < 0)
1672 1.1 skrll x -= 2;
1673 1.1 skrll
1674 1.1 skrll x >>= 1;
1675 1.1 skrll
1676 1.1 skrll if (x > 512 || x < -511)
1677 1.1 skrll {
1678 1.1 skrll as_bad (_("Wrong displacement %d"), x << 1);
1679 1.1 skrll break;
1680 1.1 skrll }
1681 1.1 skrll
1682 1.1 skrll bin |= x & 0x3ff;
1683 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1684 1.1 skrll }
1685 1.1 skrll else if (exp.X_op == O_symbol && *l1 != '$')
1686 1.1 skrll {
1687 1.1 skrll where = frag - frag_now->fr_literal;
1688 1.1 skrll fix_new_exp (frag_now, where, 2,
1689 1.1 skrll &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1690 1.1 skrll
1691 1.1 skrll bfd_putl16 ((bfd_vma) bin, frag);
1692 1.1 skrll }
1693 1.1 skrll else if (*l1 == '$')
1694 1.1 skrll {
1695 1.1 skrll as_bad (_("instruction requires label sans '$'"));
1696 1.1 skrll }
1697 1.1 skrll else
1698 1.1 skrll {
1699 1.1 skrll as_bad (_
1700 1.1 skrll ("instruction requires label or value in range -511:512"));
1701 1.1 skrll }
1702 1.1 skrll dwarf2_emit_insn (2 * __is);
1703 1.1 skrll break;
1704 1.1 skrll }
1705 1.1 skrll else
1706 1.1 skrll {
1707 1.1 skrll as_bad (_("instruction requires label"));
1708 1.1 skrll break;
1709 1.1 skrll }
1710 1.1 skrll break;
1711 1.1 skrll
1712 1.1 skrll case 4: /* Extended jumps. */
1713 1.1 skrll if (!msp430_enable_polys)
1714 1.1 skrll {
1715 1.1.1.2 christos as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1716 1.1 skrll break;
1717 1.1 skrll }
1718 1.1 skrll
1719 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1720 1.1 skrll if (l1[0])
1721 1.1 skrll {
1722 1.1 skrll char *m = l1;
1723 1.1 skrll expressionS exp;
1724 1.1 skrll
1725 1.1 skrll /* Ignore absolute addressing. make it PC relative anyway. */
1726 1.1 skrll if (*m == '#' || *m == '$')
1727 1.1 skrll m++;
1728 1.1 skrll
1729 1.1 skrll parse_exp (m, & exp);
1730 1.1 skrll if (exp.X_op == O_symbol)
1731 1.1 skrll {
1732 1.1 skrll /* Relaxation required. */
1733 1.1 skrll struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1734 1.1 skrll
1735 1.1 skrll /* The parameter to dwarf2_emit_insn is actually the offset to the start
1736 1.1 skrll of the insn from the fix piece of instruction that was emitted.
1737 1.1 skrll Since next fragments may have variable size we tie debug info
1738 1.1 skrll to the beginning of the instruction. */
1739 1.1 skrll frag = frag_more (8);
1740 1.1 skrll dwarf2_emit_insn (0);
1741 1.1 skrll bfd_putl16 ((bfd_vma) rc.sop, frag);
1742 1.1 skrll frag = frag_variant (rs_machine_dependent, 8, 2,
1743 1.1 skrll ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
1744 1.1 skrll exp.X_add_symbol,
1745 1.1 skrll 0, /* Offset is zero if jump dist less than 1K. */
1746 1.1 skrll (char *) frag);
1747 1.1 skrll break;
1748 1.1 skrll }
1749 1.1 skrll }
1750 1.1 skrll
1751 1.1 skrll as_bad (_("instruction requires label"));
1752 1.1 skrll break;
1753 1.1 skrll
1754 1.1 skrll case 5: /* Emulated extended branches. */
1755 1.1 skrll if (!msp430_enable_polys)
1756 1.1 skrll {
1757 1.1.1.2 christos as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
1758 1.1 skrll break;
1759 1.1 skrll }
1760 1.1 skrll line = extract_operand (line, l1, sizeof (l1));
1761 1.1 skrll if (l1[0])
1762 1.1 skrll {
1763 1.1 skrll char * m = l1;
1764 1.1 skrll expressionS exp;
1765 1.1 skrll
1766 1.1 skrll /* Ignore absolute addressing. make it PC relative anyway. */
1767 1.1 skrll if (*m == '#' || *m == '$')
1768 1.1 skrll m++;
1769 1.1 skrll
1770 1.1 skrll parse_exp (m, & exp);
1771 1.1 skrll if (exp.X_op == O_symbol)
1772 1.1 skrll {
1773 1.1 skrll /* Relaxation required. */
1774 1.1 skrll struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1775 1.1 skrll
1776 1.1 skrll frag = frag_more (8);
1777 1.1 skrll dwarf2_emit_insn (0);
1778 1.1 skrll bfd_putl16 ((bfd_vma) hc.op0, frag);
1779 1.1 skrll bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1780 1.1 skrll
1781 1.1 skrll frag = frag_variant (rs_machine_dependent, 8, 2,
1782 1.1 skrll ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
1783 1.1 skrll exp.X_add_symbol,
1784 1.1 skrll 0, /* Offset is zero if jump dist less than 1K. */
1785 1.1 skrll (char *) frag);
1786 1.1 skrll break;
1787 1.1 skrll }
1788 1.1 skrll }
1789 1.1 skrll
1790 1.1 skrll as_bad (_("instruction requires label"));
1791 1.1 skrll break;
1792 1.1 skrll
1793 1.1 skrll default:
1794 1.1 skrll as_bad (_("Illegal instruction or not implemented opcode."));
1795 1.1 skrll }
1796 1.1 skrll
1797 1.1 skrll input_line_pointer = line;
1798 1.1 skrll return 0;
1799 1.1 skrll }
1800 1.1 skrll
1801 1.1 skrll void
1802 1.1 skrll md_assemble (char * str)
1803 1.1 skrll {
1804 1.1 skrll struct msp430_opcode_s * opcode;
1805 1.1 skrll char cmd[32];
1806 1.1 skrll unsigned int i = 0;
1807 1.1 skrll
1808 1.1 skrll str = skip_space (str); /* Skip leading spaces. */
1809 1.1 skrll str = extract_cmd (str, cmd, sizeof (cmd));
1810 1.1 skrll
1811 1.1 skrll while (cmd[i] && i < sizeof (cmd))
1812 1.1 skrll {
1813 1.1 skrll char a = TOLOWER (cmd[i]);
1814 1.1 skrll cmd[i] = a;
1815 1.1 skrll i++;
1816 1.1 skrll }
1817 1.1 skrll
1818 1.1 skrll if (!cmd[0])
1819 1.1 skrll {
1820 1.1 skrll as_bad (_("can't find opcode "));
1821 1.1 skrll return;
1822 1.1 skrll }
1823 1.1 skrll
1824 1.1 skrll opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
1825 1.1 skrll
1826 1.1 skrll if (opcode == NULL)
1827 1.1 skrll {
1828 1.1 skrll as_bad (_("unknown opcode `%s'"), cmd);
1829 1.1 skrll return;
1830 1.1 skrll }
1831 1.1 skrll
1832 1.1 skrll {
1833 1.1 skrll char *__t = input_line_pointer;
1834 1.1 skrll
1835 1.1 skrll msp430_operands (opcode, str);
1836 1.1 skrll input_line_pointer = __t;
1837 1.1 skrll }
1838 1.1 skrll }
1839 1.1 skrll
1840 1.1 skrll /* GAS will call this function for each section at the end of the assembly,
1841 1.1 skrll to permit the CPU backend to adjust the alignment of a section. */
1842 1.1 skrll
1843 1.1 skrll valueT
1844 1.1 skrll md_section_align (asection * seg, valueT addr)
1845 1.1 skrll {
1846 1.1 skrll int align = bfd_get_section_alignment (stdoutput, seg);
1847 1.1 skrll
1848 1.1 skrll return ((addr + (1 << align) - 1) & (-1 << align));
1849 1.1 skrll }
1850 1.1 skrll
1851 1.1 skrll /* If you define this macro, it should return the offset between the
1852 1.1 skrll address of a PC relative fixup and the position from which the PC
1853 1.1 skrll relative adjustment should be made. On many processors, the base
1854 1.1 skrll of a PC relative instruction is the next instruction, so this
1855 1.1 skrll macro would return the length of an instruction. */
1856 1.1 skrll
1857 1.1 skrll long
1858 1.1 skrll md_pcrel_from_section (fixS * fixp, segT sec)
1859 1.1 skrll {
1860 1.1 skrll if (fixp->fx_addsy != (symbolS *) NULL
1861 1.1 skrll && (!S_IS_DEFINED (fixp->fx_addsy)
1862 1.1 skrll || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1863 1.1 skrll return 0;
1864 1.1 skrll
1865 1.1 skrll return fixp->fx_frag->fr_address + fixp->fx_where;
1866 1.1 skrll }
1867 1.1 skrll
1868 1.1 skrll /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1869 1.1 skrll Now it handles the situation when relocations
1870 1.1 skrll have to be passed to linker. */
1871 1.1 skrll int
1872 1.1 skrll msp430_force_relocation_local(fixS *fixp)
1873 1.1 skrll {
1874 1.1 skrll if (msp430_enable_polys
1875 1.1 skrll && !msp430_enable_relax)
1876 1.1 skrll return 1;
1877 1.1 skrll else
1878 1.1 skrll return (!fixp->fx_pcrel
1879 1.1 skrll || generic_force_reloc(fixp));
1880 1.1 skrll }
1881 1.1 skrll
1882 1.1 skrll
1883 1.1 skrll /* GAS will call this for each fixup. It should store the correct
1884 1.1 skrll value in the object file. */
1885 1.1 skrll void
1886 1.1 skrll md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
1887 1.1 skrll {
1888 1.1 skrll unsigned char * where;
1889 1.1 skrll unsigned long insn;
1890 1.1 skrll long value;
1891 1.1 skrll
1892 1.1 skrll if (fixp->fx_addsy == (symbolS *) NULL)
1893 1.1 skrll {
1894 1.1 skrll value = *valuep;
1895 1.1 skrll fixp->fx_done = 1;
1896 1.1 skrll }
1897 1.1 skrll else if (fixp->fx_pcrel)
1898 1.1 skrll {
1899 1.1 skrll segT s = S_GET_SEGMENT (fixp->fx_addsy);
1900 1.1 skrll
1901 1.1 skrll if (fixp->fx_addsy && (s == seg || s == absolute_section))
1902 1.1 skrll {
1903 1.1 skrll /* FIXME: We can appear here only in case if we perform a pc
1904 1.1 skrll relative jump to the label which is i) global, ii) locally
1905 1.1 skrll defined or this is a jump to an absolute symbol.
1906 1.1 skrll If this is an absolute symbol -- everything is OK.
1907 1.1 skrll If this is a global label, we've got a symbol value defined
1908 1.1 skrll twice:
1909 1.1 skrll 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1910 1.1 skrll from this section start
1911 1.1 skrll 2. *valuep will contain the real offset from jump insn to the
1912 1.1 skrll label
1913 1.1 skrll So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1914 1.1 skrll will be incorrect. Therefore remove s_get_value. */
1915 1.1 skrll value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
1916 1.1 skrll fixp->fx_done = 1;
1917 1.1 skrll }
1918 1.1 skrll else
1919 1.1 skrll value = *valuep;
1920 1.1 skrll }
1921 1.1 skrll else
1922 1.1 skrll {
1923 1.1 skrll value = fixp->fx_offset;
1924 1.1 skrll
1925 1.1 skrll if (fixp->fx_subsy != (symbolS *) NULL)
1926 1.1 skrll {
1927 1.1 skrll if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1928 1.1 skrll {
1929 1.1 skrll value -= S_GET_VALUE (fixp->fx_subsy);
1930 1.1 skrll fixp->fx_done = 1;
1931 1.1 skrll }
1932 1.1 skrll else
1933 1.1 skrll {
1934 1.1 skrll /* We don't actually support subtracting a symbol. */
1935 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
1936 1.1 skrll _("expression too complex"));
1937 1.1 skrll }
1938 1.1 skrll }
1939 1.1 skrll }
1940 1.1 skrll
1941 1.1 skrll fixp->fx_no_overflow = 1;
1942 1.1 skrll
1943 1.1 skrll /* if polymorphs are enabled and relax disabled.
1944 1.1 skrll do not kill any relocs and pass them to linker. */
1945 1.1 skrll if (msp430_enable_polys
1946 1.1 skrll && !msp430_enable_relax)
1947 1.1 skrll {
1948 1.1 skrll if (!fixp->fx_addsy || (fixp->fx_addsy
1949 1.1 skrll && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
1950 1.1 skrll fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
1951 1.1 skrll else
1952 1.1 skrll fixp->fx_done = 0;
1953 1.1 skrll }
1954 1.1 skrll
1955 1.1 skrll if (fixp->fx_done)
1956 1.1 skrll {
1957 1.1 skrll /* Fetch the instruction, insert the fully resolved operand
1958 1.1 skrll value, and stuff the instruction back again. */
1959 1.1 skrll
1960 1.1 skrll where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
1961 1.1 skrll
1962 1.1 skrll insn = bfd_getl16 (where);
1963 1.1 skrll
1964 1.1 skrll switch (fixp->fx_r_type)
1965 1.1 skrll {
1966 1.1 skrll case BFD_RELOC_MSP430_10_PCREL:
1967 1.1 skrll if (value & 1)
1968 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
1969 1.1 skrll _("odd address operand: %ld"), value);
1970 1.1 skrll
1971 1.1 skrll /* Jumps are in words. */
1972 1.1 skrll value >>= 1;
1973 1.1 skrll --value; /* Correct PC. */
1974 1.1 skrll
1975 1.1 skrll if (value < -512 || value > 511)
1976 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
1977 1.1 skrll _("operand out of range: %ld"), value);
1978 1.1 skrll
1979 1.1 skrll value &= 0x3ff; /* get rid of extended sign */
1980 1.1 skrll bfd_putl16 ((bfd_vma) (value | insn), where);
1981 1.1 skrll break;
1982 1.1 skrll
1983 1.1 skrll case BFD_RELOC_MSP430_RL_PCREL:
1984 1.1 skrll case BFD_RELOC_MSP430_16_PCREL:
1985 1.1 skrll if (value & 1)
1986 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
1987 1.1 skrll _("odd address operand: %ld"), value);
1988 1.1 skrll
1989 1.1 skrll /* Nothing to be corrected here. */
1990 1.1 skrll if (value < -32768 || value > 65536)
1991 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
1992 1.1 skrll _("operand out of range: %ld"), value);
1993 1.1 skrll
1994 1.1 skrll value &= 0xffff; /* Get rid of extended sign. */
1995 1.1 skrll bfd_putl16 ((bfd_vma) value, where);
1996 1.1 skrll break;
1997 1.1 skrll
1998 1.1 skrll case BFD_RELOC_MSP430_16_PCREL_BYTE:
1999 1.1 skrll /* Nothing to be corrected here. */
2000 1.1 skrll if (value < -32768 || value > 65536)
2001 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
2002 1.1 skrll _("operand out of range: %ld"), value);
2003 1.1 skrll
2004 1.1 skrll value &= 0xffff; /* Get rid of extended sign. */
2005 1.1 skrll bfd_putl16 ((bfd_vma) value, where);
2006 1.1 skrll break;
2007 1.1 skrll
2008 1.1 skrll case BFD_RELOC_32:
2009 1.1 skrll bfd_putl16 ((bfd_vma) value, where);
2010 1.1 skrll break;
2011 1.1 skrll
2012 1.1 skrll case BFD_RELOC_MSP430_16:
2013 1.1 skrll case BFD_RELOC_16:
2014 1.1 skrll case BFD_RELOC_MSP430_16_BYTE:
2015 1.1 skrll value &= 0xffff;
2016 1.1 skrll bfd_putl16 ((bfd_vma) value, where);
2017 1.1 skrll break;
2018 1.1 skrll
2019 1.1 skrll default:
2020 1.1 skrll as_fatal (_("line %d: unknown relocation type: 0x%x"),
2021 1.1 skrll fixp->fx_line, fixp->fx_r_type);
2022 1.1 skrll break;
2023 1.1 skrll }
2024 1.1 skrll }
2025 1.1 skrll else
2026 1.1 skrll {
2027 1.1 skrll fixp->fx_addnumber = value;
2028 1.1 skrll }
2029 1.1 skrll }
2030 1.1 skrll
2031 1.1 skrll /* GAS will call this to generate a reloc, passing the resulting reloc
2032 1.1 skrll to `bfd_install_relocation'. This currently works poorly, as
2033 1.1 skrll `bfd_install_relocation' often does the wrong thing, and instances of
2034 1.1 skrll `tc_gen_reloc' have been written to work around the problems, which
2035 1.1 skrll in turns makes it difficult to fix `bfd_install_relocation'. */
2036 1.1 skrll
2037 1.1 skrll /* If while processing a fixup, a reloc really needs to be created
2038 1.1 skrll then it is done here. */
2039 1.1 skrll
2040 1.1 skrll arelent *
2041 1.1 skrll tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2042 1.1 skrll {
2043 1.1 skrll arelent * reloc;
2044 1.1 skrll
2045 1.1 skrll reloc = xmalloc (sizeof (arelent));
2046 1.1 skrll
2047 1.1 skrll reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2048 1.1 skrll *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2049 1.1 skrll
2050 1.1 skrll reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2051 1.1 skrll reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2052 1.1 skrll if (reloc->howto == (reloc_howto_type *) NULL)
2053 1.1 skrll {
2054 1.1 skrll as_bad_where (fixp->fx_file, fixp->fx_line,
2055 1.1 skrll _("reloc %d not supported by object file format"),
2056 1.1 skrll (int) fixp->fx_r_type);
2057 1.1 skrll return NULL;
2058 1.1 skrll }
2059 1.1 skrll
2060 1.1 skrll if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2061 1.1 skrll || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2062 1.1 skrll reloc->address = fixp->fx_offset;
2063 1.1 skrll
2064 1.1 skrll reloc->addend = fixp->fx_offset;
2065 1.1 skrll
2066 1.1 skrll return reloc;
2067 1.1 skrll }
2068 1.1 skrll
2069 1.1 skrll int
2070 1.1 skrll md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
2071 1.1 skrll asection * segment_type ATTRIBUTE_UNUSED)
2072 1.1 skrll {
2073 1.1 skrll if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
2074 1.1 skrll {
2075 1.1 skrll /* This is a jump -> pcrel mode. Nothing to do much here.
2076 1.1 skrll Return value == 2. */
2077 1.1 skrll fragP->fr_subtype =
2078 1.1 skrll ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
2079 1.1 skrll }
2080 1.1 skrll else if (fragP->fr_symbol)
2081 1.1 skrll {
2082 1.1 skrll /* Its got a segment, but its not ours. Even if fr_symbol is in
2083 1.1 skrll an absolute segment, we don't know a displacement until we link
2084 1.1 skrll object files. So it will always be long. This also applies to
2085 1.1 skrll labels in a subsegment of current. Liker may relax it to short
2086 1.1 skrll jump later. Return value == 8. */
2087 1.1 skrll fragP->fr_subtype =
2088 1.1 skrll ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
2089 1.1 skrll }
2090 1.1 skrll else
2091 1.1 skrll {
2092 1.1 skrll /* We know the abs value. may be it is a jump to fixed address.
2093 1.1 skrll Impossible in our case, cause all constants already handled. */
2094 1.1 skrll fragP->fr_subtype =
2095 1.1 skrll ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
2096 1.1 skrll }
2097 1.1 skrll
2098 1.1 skrll return md_relax_table[fragP->fr_subtype].rlx_length;
2099 1.1 skrll }
2100 1.1 skrll
2101 1.1 skrll void
2102 1.1 skrll md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
2103 1.1 skrll asection * sec ATTRIBUTE_UNUSED,
2104 1.1 skrll fragS * fragP)
2105 1.1 skrll {
2106 1.1 skrll char * where = 0;
2107 1.1 skrll int rela = -1;
2108 1.1 skrll int i;
2109 1.1 skrll struct rcodes_s * cc = NULL;
2110 1.1 skrll struct hcodes_s * hc = NULL;
2111 1.1 skrll
2112 1.1 skrll switch (fragP->fr_subtype)
2113 1.1 skrll {
2114 1.1 skrll case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
2115 1.1 skrll case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
2116 1.1 skrll case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
2117 1.1 skrll /* We do not have to convert anything here.
2118 1.1 skrll Just apply a fix. */
2119 1.1 skrll rela = BFD_RELOC_MSP430_10_PCREL;
2120 1.1 skrll break;
2121 1.1 skrll
2122 1.1 skrll case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
2123 1.1 skrll case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
2124 1.1 skrll /* Convert uncond branch jmp lab -> br lab. */
2125 1.1 skrll cc = & msp430_rcodes[7];
2126 1.1 skrll where = fragP->fr_literal + fragP->fr_fix;
2127 1.1 skrll bfd_putl16 (cc->lop0, where);
2128 1.1 skrll rela = BFD_RELOC_MSP430_RL_PCREL;
2129 1.1 skrll fragP->fr_fix += 2;
2130 1.1 skrll break;
2131 1.1 skrll
2132 1.1 skrll case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
2133 1.1 skrll case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
2134 1.1 skrll {
2135 1.1 skrll /* Other simple branches. */
2136 1.1 skrll int insn = bfd_getl16 (fragP->fr_opcode);
2137 1.1 skrll
2138 1.1 skrll insn &= 0xffff;
2139 1.1 skrll /* Find actual instruction. */
2140 1.1 skrll for (i = 0; i < 7 && !cc; i++)
2141 1.1 skrll if (msp430_rcodes[i].sop == insn)
2142 1.1 skrll cc = & msp430_rcodes[i];
2143 1.1 skrll if (!cc || !cc->name)
2144 1.1 skrll as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2145 1.1 skrll __FUNCTION__, (long) insn);
2146 1.1 skrll where = fragP->fr_literal + fragP->fr_fix;
2147 1.1 skrll bfd_putl16 (cc->lop0, where);
2148 1.1 skrll bfd_putl16 (cc->lop1, where + 2);
2149 1.1 skrll rela = BFD_RELOC_MSP430_RL_PCREL;
2150 1.1 skrll fragP->fr_fix += 4;
2151 1.1 skrll }
2152 1.1 skrll break;
2153 1.1 skrll
2154 1.1 skrll case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
2155 1.1 skrll case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2156 1.1 skrll cc = & msp430_rcodes[6];
2157 1.1 skrll where = fragP->fr_literal + fragP->fr_fix;
2158 1.1 skrll bfd_putl16 (cc->lop0, where);
2159 1.1 skrll bfd_putl16 (cc->lop1, where + 2);
2160 1.1 skrll bfd_putl16 (cc->lop2, where + 4);
2161 1.1 skrll rela = BFD_RELOC_MSP430_RL_PCREL;
2162 1.1 skrll fragP->fr_fix += 6;
2163 1.1 skrll break;
2164 1.1 skrll
2165 1.1 skrll case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2166 1.1 skrll {
2167 1.1 skrll int insn = bfd_getl16 (fragP->fr_opcode + 2);
2168 1.1 skrll
2169 1.1 skrll insn &= 0xffff;
2170 1.1 skrll for (i = 0; i < 4 && !hc; i++)
2171 1.1 skrll if (msp430_hcodes[i].op1 == insn)
2172 1.1 skrll hc = &msp430_hcodes[i];
2173 1.1 skrll if (!hc || !hc->name)
2174 1.1 skrll as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2175 1.1 skrll __FUNCTION__, (long) insn);
2176 1.1 skrll rela = BFD_RELOC_MSP430_10_PCREL;
2177 1.1 skrll /* Apply a fix for a first label if necessary.
2178 1.1 skrll another fix will be applied to the next word of insn anyway. */
2179 1.1 skrll if (hc->tlab == 2)
2180 1.1 skrll fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2181 1.1 skrll fragP->fr_offset, TRUE, rela);
2182 1.1 skrll fragP->fr_fix += 2;
2183 1.1 skrll }
2184 1.1 skrll
2185 1.1 skrll break;
2186 1.1 skrll
2187 1.1 skrll case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2188 1.1 skrll case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2189 1.1 skrll {
2190 1.1 skrll int insn = bfd_getl16 (fragP->fr_opcode + 2);
2191 1.1 skrll
2192 1.1 skrll insn &= 0xffff;
2193 1.1 skrll for (i = 0; i < 4 && !hc; i++)
2194 1.1 skrll if (msp430_hcodes[i].op1 == insn)
2195 1.1 skrll hc = & msp430_hcodes[i];
2196 1.1 skrll if (!hc || !hc->name)
2197 1.1 skrll as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2198 1.1 skrll __FUNCTION__, (long) insn);
2199 1.1 skrll rela = BFD_RELOC_MSP430_RL_PCREL;
2200 1.1 skrll where = fragP->fr_literal + fragP->fr_fix;
2201 1.1 skrll bfd_putl16 (hc->lop0, where);
2202 1.1 skrll bfd_putl16 (hc->lop1, where + 2);
2203 1.1 skrll bfd_putl16 (hc->lop2, where + 4);
2204 1.1 skrll fragP->fr_fix += 6;
2205 1.1 skrll }
2206 1.1 skrll break;
2207 1.1 skrll
2208 1.1 skrll default:
2209 1.1 skrll as_fatal (_("internal inconsistency problem in %s: %lx"),
2210 1.1 skrll __FUNCTION__, (long) fragP->fr_subtype);
2211 1.1 skrll break;
2212 1.1 skrll }
2213 1.1 skrll
2214 1.1 skrll /* Now apply fix. */
2215 1.1 skrll fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2216 1.1 skrll fragP->fr_offset, TRUE, rela);
2217 1.1 skrll /* Just fixed 2 bytes. */
2218 1.1 skrll fragP->fr_fix += 2;
2219 1.1 skrll }
2220 1.1 skrll
2221 1.1 skrll /* Relax fragment. Mostly stolen from hc11 and mcore
2222 1.1 skrll which arches I think I know. */
2223 1.1 skrll
2224 1.1 skrll long
2225 1.1 skrll msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2226 1.1 skrll long stretch ATTRIBUTE_UNUSED)
2227 1.1 skrll {
2228 1.1 skrll long growth;
2229 1.1 skrll offsetT aim = 0;
2230 1.1 skrll symbolS *symbolP;
2231 1.1 skrll const relax_typeS *this_type;
2232 1.1 skrll const relax_typeS *start_type;
2233 1.1 skrll relax_substateT next_state;
2234 1.1 skrll relax_substateT this_state;
2235 1.1 skrll const relax_typeS *table = md_relax_table;
2236 1.1 skrll
2237 1.1 skrll /* Nothing to be done if the frag has already max size. */
2238 1.1 skrll if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2239 1.1 skrll || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2240 1.1 skrll return 0;
2241 1.1 skrll
2242 1.1 skrll if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2243 1.1 skrll {
2244 1.1 skrll symbolP = fragP->fr_symbol;
2245 1.1 skrll if (symbol_resolved_p (symbolP))
2246 1.1 skrll as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2247 1.1 skrll __FUNCTION__);
2248 1.1 skrll /* We know the offset. calculate a distance. */
2249 1.1 skrll aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2250 1.1 skrll }
2251 1.1 skrll
2252 1.1 skrll if (!msp430_enable_relax)
2253 1.1 skrll {
2254 1.1 skrll /* Relaxation is not enabled. So, make all jump as long ones
2255 1.1 skrll by setting 'aim' to quite high value. */
2256 1.1 skrll aim = 0x7fff;
2257 1.1 skrll }
2258 1.1 skrll
2259 1.1 skrll this_state = fragP->fr_subtype;
2260 1.1 skrll start_type = this_type = table + this_state;
2261 1.1 skrll
2262 1.1 skrll if (aim < 0)
2263 1.1 skrll {
2264 1.1 skrll /* Look backwards. */
2265 1.1 skrll for (next_state = this_type->rlx_more; next_state;)
2266 1.1 skrll if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
2267 1.1 skrll next_state = 0;
2268 1.1 skrll else
2269 1.1 skrll {
2270 1.1 skrll /* Grow to next state. */
2271 1.1 skrll this_state = next_state;
2272 1.1 skrll this_type = table + this_state;
2273 1.1 skrll next_state = this_type->rlx_more;
2274 1.1 skrll }
2275 1.1 skrll }
2276 1.1 skrll else
2277 1.1 skrll {
2278 1.1 skrll /* Look forwards. */
2279 1.1 skrll for (next_state = this_type->rlx_more; next_state;)
2280 1.1 skrll if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
2281 1.1 skrll next_state = 0;
2282 1.1 skrll else
2283 1.1 skrll {
2284 1.1 skrll /* Grow to next state. */
2285 1.1 skrll this_state = next_state;
2286 1.1 skrll this_type = table + this_state;
2287 1.1 skrll next_state = this_type->rlx_more;
2288 1.1 skrll }
2289 1.1 skrll }
2290 1.1 skrll
2291 1.1 skrll growth = this_type->rlx_length - start_type->rlx_length;
2292 1.1 skrll if (growth != 0)
2293 1.1 skrll fragP->fr_subtype = this_state;
2294 1.1 skrll return growth;
2295 1.1 skrll }
2296