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