gas: ARM: Fix encoding of VCVTr.s32.f64 instructions
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
3 Copyright (C) 2002-2013 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 #include "as.h"
24 #include <limits.h>
25 #define PUSH_1X_WORKAROUND
26 #include "subsegs.h"
27 #include "opcode/msp430.h"
28 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
30 #include "elf/msp430.h"
31
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
34 following code:
35
36 jump .l1
37 nop
38 jump subroutine ; external symbol
39 .l1:
40 nop
41 ret
42
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
45 2: nop
46 4: br subroutine
47 .l1:
48 8: nop
49 10: ret
50
51 If the 'subroutine' is within +-1024 bytes range then linker
52 will produce:
53 0: jmp .text +0x08
54 2: nop
55 4: jmp subroutine
56 .l1:
57 6: nop
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
59
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
63
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
66
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
68
69 int msp430_enable_relax;
70 int msp430_enable_polys;
71
72 /* Set linkrelax here to avoid fixups in most sections. */
73 int linkrelax = 1;
74
75 /* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
77
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
82
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
85
86 lt < jl jge +4; br lab
87 ltu < jlo lhs +4; br lab
88 le <= see below
89 leu <= see below
90
91 gt > see below
92 gtu > see below
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
96
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
99 'u' means unsigned compares
100
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
103
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
105
106 struct rcodes_s
107 {
108 char * name;
109 int index; /* Corresponding insn_opnumb. */
110 int sop; /* Opcode if jump length is short. */
111 long lpos; /* Label position. */
112 long lop0; /* Opcode 1 _word_ (16 bits). */
113 long lop1; /* Opcode second word. */
114 long lop2; /* Opcode third word. */
115 };
116
117 #define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
119
120 static struct rcodes_s msp430_rcodes[] =
121 {
122 MSP430_RLC (beq, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
130 {0,0,0,0,0,0,0}
131 };
132
133 #undef MSP430_RLC
134 #define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
136
137 static struct rcodes_s msp430x_rcodes[] =
138 {
139 MSP430_RLC (beq, 0, 0x2400, 0x2000),
140 MSP430_RLC (bne, 1, 0x2000, 0x2400),
141 MSP430_RLC (blt, 2, 0x3800, 0x3400),
142 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
143 MSP430_RLC (bge, 4, 0x3400, 0x3800),
144 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
145 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
146 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
147 {0,0,0,0,0,0,0}
148 };
149 #undef MSP430_RLC
150
151 /* More difficult than above and they have format 5.
152
153 COND EXPL SHORT LONG
154 =================================================================
155 gt > jeq +2; jge label jeq +6; jl +4; br label
156 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
157 leu <= jeq label; jlo label jeq +2; jhs +4; br label
158 le <= jeq label; jl label jeq +2; jge +4; br label
159 ================================================================= */
160
161 struct hcodes_s
162 {
163 char * name;
164 int index; /* Corresponding insn_opnumb. */
165 int tlab; /* Number of labels in short mode. */
166 int op0; /* Opcode for first word of short jump. */
167 int op1; /* Opcode for second word of short jump. */
168 int lop0; /* Opcodes for long jump mode. */
169 int lop1;
170 int lop2;
171 };
172
173 static struct hcodes_s msp430_hcodes[] =
174 {
175 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
176 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
177 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
178 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
179 {0,0,0,0,0,0,0,0}
180 };
181
182 static struct hcodes_s msp430x_hcodes[] =
183 {
184 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
185 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
186 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
187 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
188 {0,0,0,0,0,0,0,0}
189 };
190
191 const char comment_chars[] = ";";
192 const char line_comment_chars[] = "#";
193 const char line_separator_chars[] = "{";
194 const char EXP_CHARS[] = "eE";
195 const char FLT_CHARS[] = "dD";
196
197 /* Handle long expressions. */
198 extern LITTLENUM_TYPE generic_bignum[];
199
200 static struct hash_control *msp430_hash;
201
202 /* Relaxations. */
203 #define STATE_UNCOND_BRANCH 1 /* jump */
204 #define STATE_NOOV_BRANCH 3 /* bltn */
205 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
206 #define STATE_EMUL_BRANCH 4
207
208 #define CNRL 2
209 #define CUBL 4
210 #define CNOL 8
211 #define CSBL 6
212 #define CEBL 4
213
214 /* Length. */
215 #define STATE_BITS10 1 /* wild guess. short jump */
216 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
217 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
218
219 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
220 #define RELAX_STATE(s) ((s) & 3)
221 #define RELAX_LEN(s) ((s) >> 2)
222 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
223
224 relax_typeS md_relax_table[] =
225 {
226 /* Unused. */
227 {1, 1, 0, 0},
228 {1, 1, 0, 0},
229 {1, 1, 0, 0},
230 {1, 1, 0, 0},
231
232 /* Unconditional jump. */
233 {1, 1, 8, 5},
234 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
235 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
236 {1, 1, CUBL, 0}, /* state undef */
237
238 /* Simple branches. */
239 {0, 0, 8, 9},
240 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
241 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
242 {1, 1, CSBL, 0},
243
244 /* blt no overflow branch. */
245 {1, 1, 8, 13},
246 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
247 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
248 {1, 1, CNOL, 0},
249
250 /* Emulated branches. */
251 {1, 1, 8, 17},
252 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
253 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
254 {1, 1, CNOL, 0}
255 };
256
257
258 #define MAX_OP_LEN 256
259
260 typedef enum msp_isa
261 {
262 MSP_ISA_430,
263 MSP_ISA_430X,
264 MSP_ISA_430Xv2
265 } msp_isa;
266
267 struct mcu_type_s
268 {
269 char * name;
270 msp_isa isa;
271 };
272
273 static struct mcu_type_s mcu_types[] =
274 {
275 {"msp430afe221", MSP_ISA_430},
276 {"msp430afe222", MSP_ISA_430},
277 {"msp430afe223", MSP_ISA_430},
278 {"msp430afe231", MSP_ISA_430},
279 {"msp430afe232", MSP_ISA_430},
280 {"msp430afe233", MSP_ISA_430},
281 {"msp430afe251", MSP_ISA_430},
282 {"msp430afe252", MSP_ISA_430},
283 {"msp430afe253", MSP_ISA_430},
284 {"msp430c091", MSP_ISA_430},
285 {"msp430c092", MSP_ISA_430},
286 {"msp430c111", MSP_ISA_430},
287 {"msp430c1111", MSP_ISA_430},
288 {"msp430c112", MSP_ISA_430},
289 {"msp430c1121", MSP_ISA_430},
290 {"msp430e112", MSP_ISA_430},
291 {"msp430c1331", MSP_ISA_430},
292 {"msp430c1351", MSP_ISA_430},
293 {"msp430c311s", MSP_ISA_430},
294 {"msp430c312", MSP_ISA_430},
295 {"msp430c313", MSP_ISA_430},
296 {"msp430c314", MSP_ISA_430},
297 {"msp430c315", MSP_ISA_430},
298 {"msp430c323", MSP_ISA_430},
299 {"msp430c325", MSP_ISA_430},
300 {"msp430c336", MSP_ISA_430},
301 {"msp430c337", MSP_ISA_430},
302 {"msp430c412", MSP_ISA_430},
303 {"msp430c413", MSP_ISA_430},
304 {"msp430e313", MSP_ISA_430},
305 {"msp430e315", MSP_ISA_430},
306 {"msp430e325", MSP_ISA_430},
307 {"msp430e337", MSP_ISA_430},
308 {"msp430f110", MSP_ISA_430},
309 {"msp430f1101", MSP_ISA_430},
310 {"msp430f1101a", MSP_ISA_430},
311 {"msp430f1111", MSP_ISA_430},
312 {"msp430f1111a", MSP_ISA_430},
313 {"msp430f112", MSP_ISA_430},
314 {"msp430f1121", MSP_ISA_430},
315 {"msp430f1121a", MSP_ISA_430},
316 {"msp430f1122", MSP_ISA_430},
317 {"msp430f1132", MSP_ISA_430},
318 {"msp430f122", MSP_ISA_430},
319 {"msp430f1222", MSP_ISA_430},
320 {"msp430f123", MSP_ISA_430},
321 {"msp430f1232", MSP_ISA_430},
322 {"msp430f133", MSP_ISA_430},
323 {"msp430f135", MSP_ISA_430},
324 {"msp430f147", MSP_ISA_430},
325 {"msp430f1471", MSP_ISA_430},
326 {"msp430f148", MSP_ISA_430},
327 {"msp430f1481", MSP_ISA_430},
328 {"msp430f149", MSP_ISA_430},
329 {"msp430f1491", MSP_ISA_430},
330 {"msp430f155", MSP_ISA_430},
331 {"msp430f156", MSP_ISA_430},
332 {"msp430f157", MSP_ISA_430},
333 {"msp430f1610", MSP_ISA_430},
334 {"msp430f1611", MSP_ISA_430},
335 {"msp430f1612", MSP_ISA_430},
336 {"msp430f167", MSP_ISA_430},
337 {"msp430f168", MSP_ISA_430},
338 {"msp430f169", MSP_ISA_430},
339 {"msp430f2001", MSP_ISA_430},
340 {"msp430f2002", MSP_ISA_430},
341 {"msp430f2003", MSP_ISA_430},
342 {"msp430f2011", MSP_ISA_430},
343 {"msp430f2012", MSP_ISA_430},
344 {"msp430f2013", MSP_ISA_430},
345 {"msp430f2101", MSP_ISA_430},
346 {"msp430f2111", MSP_ISA_430},
347 {"msp430f2112", MSP_ISA_430},
348 {"msp430f2121", MSP_ISA_430},
349 {"msp430f2122", MSP_ISA_430},
350 {"msp430f2131", MSP_ISA_430},
351 {"msp430f2132", MSP_ISA_430},
352 {"msp430f2232", MSP_ISA_430},
353 {"msp430f2234", MSP_ISA_430},
354 {"msp430f2252", MSP_ISA_430},
355 {"msp430f2254", MSP_ISA_430},
356 {"msp430f2272", MSP_ISA_430},
357 {"msp430f2274", MSP_ISA_430},
358 {"msp430f233", MSP_ISA_430},
359 {"msp430f2330", MSP_ISA_430},
360 {"msp430f235", MSP_ISA_430},
361 {"msp430f2350", MSP_ISA_430},
362 {"msp430f2370", MSP_ISA_430},
363 {"msp430f2410", MSP_ISA_430},
364 {"msp430f247", MSP_ISA_430},
365 {"msp430f2471", MSP_ISA_430},
366 {"msp430f248", MSP_ISA_430},
367 {"msp430f2481", MSP_ISA_430},
368 {"msp430f249", MSP_ISA_430},
369 {"msp430f2491", MSP_ISA_430},
370 {"msp430f412", MSP_ISA_430},
371 {"msp430f413", MSP_ISA_430},
372 {"msp430f4132", MSP_ISA_430},
373 {"msp430f415", MSP_ISA_430},
374 {"msp430f4152", MSP_ISA_430},
375 {"msp430f417", MSP_ISA_430},
376 {"msp430f423", MSP_ISA_430},
377 {"msp430f423a", MSP_ISA_430},
378 {"msp430f425", MSP_ISA_430},
379 {"msp430f4250", MSP_ISA_430},
380 {"msp430f425a", MSP_ISA_430},
381 {"msp430f4260", MSP_ISA_430},
382 {"msp430f427", MSP_ISA_430},
383 {"msp430f4270", MSP_ISA_430},
384 {"msp430f427a", MSP_ISA_430},
385 {"msp430f435", MSP_ISA_430},
386 {"msp430f4351", MSP_ISA_430},
387 {"msp430f436", MSP_ISA_430},
388 {"msp430f4361", MSP_ISA_430},
389 {"msp430f437", MSP_ISA_430},
390 {"msp430f4371", MSP_ISA_430},
391 {"msp430f438", MSP_ISA_430},
392 {"msp430f439", MSP_ISA_430},
393 {"msp430f447", MSP_ISA_430},
394 {"msp430f448", MSP_ISA_430},
395 {"msp430f4481", MSP_ISA_430},
396 {"msp430f449", MSP_ISA_430},
397 {"msp430f4491", MSP_ISA_430},
398 {"msp430f477", MSP_ISA_430},
399 {"msp430f478", MSP_ISA_430},
400 {"msp430f4783", MSP_ISA_430},
401 {"msp430f4784", MSP_ISA_430},
402 {"msp430f479", MSP_ISA_430},
403 {"msp430f4793", MSP_ISA_430},
404 {"msp430f4794", MSP_ISA_430},
405 {"msp430fe423", MSP_ISA_430},
406 {"msp430fe4232", MSP_ISA_430},
407 {"msp430fe423a", MSP_ISA_430},
408 {"msp430fe4242", MSP_ISA_430},
409 {"msp430fe425", MSP_ISA_430},
410 {"msp430fe4252", MSP_ISA_430},
411 {"msp430fe425a", MSP_ISA_430},
412 {"msp430fe427", MSP_ISA_430},
413 {"msp430fe4272", MSP_ISA_430},
414 {"msp430fe427a", MSP_ISA_430},
415 {"msp430fg4250", MSP_ISA_430},
416 {"msp430fg4260", MSP_ISA_430},
417 {"msp430fg4270", MSP_ISA_430},
418 {"msp430fg437", MSP_ISA_430},
419 {"msp430fg438", MSP_ISA_430},
420 {"msp430fg439", MSP_ISA_430},
421 {"msp430fg477", MSP_ISA_430},
422 {"msp430fg478", MSP_ISA_430},
423 {"msp430fg479", MSP_ISA_430},
424 {"msp430fw423", MSP_ISA_430},
425 {"msp430fw425", MSP_ISA_430},
426 {"msp430fw427", MSP_ISA_430},
427 {"msp430fw428", MSP_ISA_430},
428 {"msp430fw429", MSP_ISA_430},
429 {"msp430g2001", MSP_ISA_430},
430 {"msp430g2101", MSP_ISA_430},
431 {"msp430g2102", MSP_ISA_430},
432 {"msp430g2111", MSP_ISA_430},
433 {"msp430g2112", MSP_ISA_430},
434 {"msp430g2113", MSP_ISA_430},
435 {"msp430g2121", MSP_ISA_430},
436 {"msp430g2131", MSP_ISA_430},
437 {"msp430g2132", MSP_ISA_430},
438 {"msp430g2152", MSP_ISA_430},
439 {"msp430g2153", MSP_ISA_430},
440 {"msp430g2201", MSP_ISA_430},
441 {"msp430g2202", MSP_ISA_430},
442 {"msp430g2203", MSP_ISA_430},
443 {"msp430g2210", MSP_ISA_430},
444 {"msp430g2211", MSP_ISA_430},
445 {"msp430g2212", MSP_ISA_430},
446 {"msp430g2213", MSP_ISA_430},
447 {"msp430g2221", MSP_ISA_430},
448 {"msp430g2230", MSP_ISA_430},
449 {"msp430g2231", MSP_ISA_430},
450 {"msp430g2232", MSP_ISA_430},
451 {"msp430g2233", MSP_ISA_430},
452 {"msp430g2252", MSP_ISA_430},
453 {"msp430g2253", MSP_ISA_430},
454 {"msp430g2302", MSP_ISA_430},
455 {"msp430g2303", MSP_ISA_430},
456 {"msp430g2312", MSP_ISA_430},
457 {"msp430g2313", MSP_ISA_430},
458 {"msp430g2332", MSP_ISA_430},
459 {"msp430g2333", MSP_ISA_430},
460 {"msp430g2352", MSP_ISA_430},
461 {"msp430g2353", MSP_ISA_430},
462 {"msp430g2402", MSP_ISA_430},
463 {"msp430g2403", MSP_ISA_430},
464 {"msp430g2412", MSP_ISA_430},
465 {"msp430g2413", MSP_ISA_430},
466 {"msp430g2432", MSP_ISA_430},
467 {"msp430g2433", MSP_ISA_430},
468 {"msp430g2444", MSP_ISA_430},
469 {"msp430g2452", MSP_ISA_430},
470 {"msp430g2453", MSP_ISA_430},
471 {"msp430g2513", MSP_ISA_430},
472 {"msp430g2533", MSP_ISA_430},
473 {"msp430g2544", MSP_ISA_430},
474 {"msp430g2553", MSP_ISA_430},
475 {"msp430g2744", MSP_ISA_430},
476 {"msp430g2755", MSP_ISA_430},
477 {"msp430g2855", MSP_ISA_430},
478 {"msp430g2955", MSP_ISA_430},
479 {"msp430l092", MSP_ISA_430},
480 {"msp430p112", MSP_ISA_430},
481 {"msp430p313", MSP_ISA_430},
482 {"msp430p315", MSP_ISA_430},
483 {"msp430p315s", MSP_ISA_430},
484 {"msp430p325", MSP_ISA_430},
485 {"msp430p337", MSP_ISA_430},
486 {"msp430tch5e", MSP_ISA_430},
487
488 /* NB/ This section of the list should be kept in sync with the ones in:
489 gcc/config/msp430/t-msp430
490 gcc/config/msp430/msp430.c */
491
492 {"msp430cg4616", MSP_ISA_430X},
493 {"msp430cg4617", MSP_ISA_430X},
494 {"msp430cg4618", MSP_ISA_430X},
495 {"msp430cg4619", MSP_ISA_430X},
496 {"msp430f2416", MSP_ISA_430X},
497 {"msp430f2417", MSP_ISA_430X},
498 {"msp430f2418", MSP_ISA_430X},
499 {"msp430f2419", MSP_ISA_430X},
500 {"msp430f2616", MSP_ISA_430X},
501 {"msp430f2617", MSP_ISA_430X},
502 {"msp430f2618", MSP_ISA_430X},
503 {"msp430f2619", MSP_ISA_430X},
504 {"msp430f47126", MSP_ISA_430X},
505 {"msp430f47127", MSP_ISA_430X},
506 {"msp430f47163", MSP_ISA_430X},
507 {"msp430f47173", MSP_ISA_430X},
508 {"msp430f47183", MSP_ISA_430X},
509 {"msp430f47193", MSP_ISA_430X},
510 {"msp430f47166", MSP_ISA_430X},
511 {"msp430f47176", MSP_ISA_430X},
512 {"msp430f47186", MSP_ISA_430X},
513 {"msp430f47196", MSP_ISA_430X},
514 {"msp430f47167", MSP_ISA_430X},
515 {"msp430f47177", MSP_ISA_430X},
516 {"msp430f47187", MSP_ISA_430X},
517 {"msp430f47197", MSP_ISA_430X},
518 {"msp430f46161", MSP_ISA_430X},
519 {"msp430f46171", MSP_ISA_430X},
520 {"msp430f46181", MSP_ISA_430X},
521 {"msp430f46191", MSP_ISA_430X},
522 {"msp430f4616", MSP_ISA_430X},
523 {"msp430f4617", MSP_ISA_430X},
524 {"msp430f4618", MSP_ISA_430X},
525 {"msp430f4619", MSP_ISA_430X},
526 {"msp430fg4616", MSP_ISA_430X},
527 {"msp430fg4617", MSP_ISA_430X},
528 {"msp430fg4618", MSP_ISA_430X},
529 {"msp430fg4619", MSP_ISA_430X},
530
531 {"msp430x241x", MSP_ISA_430X},
532 {"msp430x26x", MSP_ISA_430X},
533 {"msp430x461x1", MSP_ISA_430X},
534 {"msp430x46x", MSP_ISA_430X},
535 {"msp430x471x3", MSP_ISA_430X},
536 {"msp430x471x6", MSP_ISA_430X},
537 {"msp430x471x7", MSP_ISA_430X},
538 {"msp430xg46x", MSP_ISA_430X},
539
540 {"msp430f5418", MSP_ISA_430Xv2},
541 {"msp430f5419", MSP_ISA_430Xv2},
542 {"msp430f5435", MSP_ISA_430Xv2},
543 {"msp430f5436", MSP_ISA_430Xv2},
544 {"msp430f5437", MSP_ISA_430Xv2},
545 {"msp430f5438", MSP_ISA_430Xv2},
546 {"msp430f5418a", MSP_ISA_430Xv2},
547 {"msp430f5419a", MSP_ISA_430Xv2},
548 {"msp430f5435a", MSP_ISA_430Xv2},
549 {"msp430f5436a", MSP_ISA_430Xv2},
550 {"msp430f5437a", MSP_ISA_430Xv2},
551 {"msp430f5438a", MSP_ISA_430Xv2},
552 {"msp430f5212", MSP_ISA_430Xv2},
553 {"msp430f5213", MSP_ISA_430Xv2},
554 {"msp430f5214", MSP_ISA_430Xv2},
555 {"msp430f5217", MSP_ISA_430Xv2},
556 {"msp430f5218", MSP_ISA_430Xv2},
557 {"msp430f5219", MSP_ISA_430Xv2},
558 {"msp430f5222", MSP_ISA_430Xv2},
559 {"msp430f5223", MSP_ISA_430Xv2},
560 {"msp430f5224", MSP_ISA_430Xv2},
561 {"msp430f5227", MSP_ISA_430Xv2},
562 {"msp430f5228", MSP_ISA_430Xv2},
563 {"msp430f5229", MSP_ISA_430Xv2},
564 {"msp430f5304", MSP_ISA_430Xv2},
565 {"msp430f5308", MSP_ISA_430Xv2},
566 {"msp430f5309", MSP_ISA_430Xv2},
567 {"msp430f5310", MSP_ISA_430Xv2},
568 {"msp430f5340", MSP_ISA_430Xv2},
569 {"msp430f5341", MSP_ISA_430Xv2},
570 {"msp430f5342", MSP_ISA_430Xv2},
571 {"msp430f5324", MSP_ISA_430Xv2},
572 {"msp430f5325", MSP_ISA_430Xv2},
573 {"msp430f5326", MSP_ISA_430Xv2},
574 {"msp430f5327", MSP_ISA_430Xv2},
575 {"msp430f5328", MSP_ISA_430Xv2},
576 {"msp430f5329", MSP_ISA_430Xv2},
577 {"msp430f5500", MSP_ISA_430Xv2},
578 {"msp430f5501", MSP_ISA_430Xv2},
579 {"msp430f5502", MSP_ISA_430Xv2},
580 {"msp430f5503", MSP_ISA_430Xv2},
581 {"msp430f5504", MSP_ISA_430Xv2},
582 {"msp430f5505", MSP_ISA_430Xv2},
583 {"msp430f5506", MSP_ISA_430Xv2},
584 {"msp430f5507", MSP_ISA_430Xv2},
585 {"msp430f5508", MSP_ISA_430Xv2},
586 {"msp430f5509", MSP_ISA_430Xv2},
587 {"msp430f5510", MSP_ISA_430Xv2},
588 {"msp430f5513", MSP_ISA_430Xv2},
589 {"msp430f5514", MSP_ISA_430Xv2},
590 {"msp430f5515", MSP_ISA_430Xv2},
591 {"msp430f5517", MSP_ISA_430Xv2},
592 {"msp430f5519", MSP_ISA_430Xv2},
593 {"msp430f5521", MSP_ISA_430Xv2},
594 {"msp430f5522", MSP_ISA_430Xv2},
595 {"msp430f5524", MSP_ISA_430Xv2},
596 {"msp430f5525", MSP_ISA_430Xv2},
597 {"msp430f5526", MSP_ISA_430Xv2},
598 {"msp430f5527", MSP_ISA_430Xv2},
599 {"msp430f5528", MSP_ISA_430Xv2},
600 {"msp430f5529", MSP_ISA_430Xv2},
601 {"cc430f5133", MSP_ISA_430Xv2},
602 {"cc430f5135", MSP_ISA_430Xv2},
603 {"cc430f5137", MSP_ISA_430Xv2},
604 {"cc430f6125", MSP_ISA_430Xv2},
605 {"cc430f6126", MSP_ISA_430Xv2},
606 {"cc430f6127", MSP_ISA_430Xv2},
607 {"cc430f6135", MSP_ISA_430Xv2},
608 {"cc430f6137", MSP_ISA_430Xv2},
609 {"cc430f5123", MSP_ISA_430Xv2},
610 {"cc430f5125", MSP_ISA_430Xv2},
611 {"cc430f5143", MSP_ISA_430Xv2},
612 {"cc430f5145", MSP_ISA_430Xv2},
613 {"cc430f5147", MSP_ISA_430Xv2},
614 {"cc430f6143", MSP_ISA_430Xv2},
615 {"cc430f6145", MSP_ISA_430Xv2},
616 {"cc430f6147", MSP_ISA_430Xv2},
617 {"msp430f5333", MSP_ISA_430Xv2},
618 {"msp430f5335", MSP_ISA_430Xv2},
619 {"msp430f5336", MSP_ISA_430Xv2},
620 {"msp430f5338", MSP_ISA_430Xv2},
621 {"msp430f5630", MSP_ISA_430Xv2},
622 {"msp430f5631", MSP_ISA_430Xv2},
623 {"msp430f5632", MSP_ISA_430Xv2},
624 {"msp430f5633", MSP_ISA_430Xv2},
625 {"msp430f5634", MSP_ISA_430Xv2},
626 {"msp430f5635", MSP_ISA_430Xv2},
627 {"msp430f5636", MSP_ISA_430Xv2},
628 {"msp430f5637", MSP_ISA_430Xv2},
629 {"msp430f5638", MSP_ISA_430Xv2},
630 {"msp430f6433", MSP_ISA_430Xv2},
631 {"msp430f6435", MSP_ISA_430Xv2},
632 {"msp430f6436", MSP_ISA_430Xv2},
633 {"msp430f6438", MSP_ISA_430Xv2},
634 {"msp430f6630", MSP_ISA_430Xv2},
635 {"msp430f6631", MSP_ISA_430Xv2},
636 {"msp430f6632", MSP_ISA_430Xv2},
637 {"msp430f6633", MSP_ISA_430Xv2},
638 {"msp430f6634", MSP_ISA_430Xv2},
639 {"msp430f6635", MSP_ISA_430Xv2},
640 {"msp430f6636", MSP_ISA_430Xv2},
641 {"msp430f6637", MSP_ISA_430Xv2},
642 {"msp430f6638", MSP_ISA_430Xv2},
643 {"msp430f5358", MSP_ISA_430Xv2},
644 {"msp430f5359", MSP_ISA_430Xv2},
645 {"msp430f5658", MSP_ISA_430Xv2},
646 {"msp430f5659", MSP_ISA_430Xv2},
647 {"msp430f6458", MSP_ISA_430Xv2},
648 {"msp430f6459", MSP_ISA_430Xv2},
649 {"msp430f6658", MSP_ISA_430Xv2},
650 {"msp430f6659", MSP_ISA_430Xv2},
651 {"msp430f5131", MSP_ISA_430Xv2},
652 {"msp430f5151", MSP_ISA_430Xv2},
653 {"msp430f5171", MSP_ISA_430Xv2},
654 {"msp430f5132", MSP_ISA_430Xv2},
655 {"msp430f5152", MSP_ISA_430Xv2},
656 {"msp430f5172", MSP_ISA_430Xv2},
657 {"msp430f6720", MSP_ISA_430Xv2},
658 {"msp430f6721", MSP_ISA_430Xv2},
659 {"msp430f6723", MSP_ISA_430Xv2},
660 {"msp430f6724", MSP_ISA_430Xv2},
661 {"msp430f6725", MSP_ISA_430Xv2},
662 {"msp430f6726", MSP_ISA_430Xv2},
663 {"msp430f6730", MSP_ISA_430Xv2},
664 {"msp430f6731", MSP_ISA_430Xv2},
665 {"msp430f6733", MSP_ISA_430Xv2},
666 {"msp430f6734", MSP_ISA_430Xv2},
667 {"msp430f6735", MSP_ISA_430Xv2},
668 {"msp430f6736", MSP_ISA_430Xv2},
669 {"msp430f67451", MSP_ISA_430Xv2},
670 {"msp430f67651", MSP_ISA_430Xv2},
671 {"msp430f67751", MSP_ISA_430Xv2},
672 {"msp430f67461", MSP_ISA_430Xv2},
673 {"msp430f67661", MSP_ISA_430Xv2},
674 {"msp430f67761", MSP_ISA_430Xv2},
675 {"msp430f67471", MSP_ISA_430Xv2},
676 {"msp430f67671", MSP_ISA_430Xv2},
677 {"msp430f67771", MSP_ISA_430Xv2},
678 {"msp430f67481", MSP_ISA_430Xv2},
679 {"msp430f67681", MSP_ISA_430Xv2},
680 {"msp430f67781", MSP_ISA_430Xv2},
681 {"msp430f67491", MSP_ISA_430Xv2},
682 {"msp430f67691", MSP_ISA_430Xv2},
683 {"msp430f67791", MSP_ISA_430Xv2},
684 {"msp430f6745", MSP_ISA_430Xv2},
685 {"msp430f6765", MSP_ISA_430Xv2},
686 {"msp430f6775", MSP_ISA_430Xv2},
687 {"msp430f6746", MSP_ISA_430Xv2},
688 {"msp430f6766", MSP_ISA_430Xv2},
689 {"msp430f6776", MSP_ISA_430Xv2},
690 {"msp430f6747", MSP_ISA_430Xv2},
691 {"msp430f6767", MSP_ISA_430Xv2},
692 {"msp430f6777", MSP_ISA_430Xv2},
693 {"msp430f6748", MSP_ISA_430Xv2},
694 {"msp430f6768", MSP_ISA_430Xv2},
695 {"msp430f6778", MSP_ISA_430Xv2},
696 {"msp430f6749", MSP_ISA_430Xv2},
697 {"msp430f6769", MSP_ISA_430Xv2},
698 {"msp430f6779", MSP_ISA_430Xv2},
699 {"msp430fr5720", MSP_ISA_430Xv2},
700 {"msp430fr5721", MSP_ISA_430Xv2},
701 {"msp430fr5722", MSP_ISA_430Xv2},
702 {"msp430fr5723", MSP_ISA_430Xv2},
703 {"msp430fr5724", MSP_ISA_430Xv2},
704 {"msp430fr5725", MSP_ISA_430Xv2},
705 {"msp430fr5726", MSP_ISA_430Xv2},
706 {"msp430fr5727", MSP_ISA_430Xv2},
707 {"msp430fr5728", MSP_ISA_430Xv2},
708 {"msp430fr5729", MSP_ISA_430Xv2},
709 {"msp430fr5730", MSP_ISA_430Xv2},
710 {"msp430fr5731", MSP_ISA_430Xv2},
711 {"msp430fr5732", MSP_ISA_430Xv2},
712 {"msp430fr5733", MSP_ISA_430Xv2},
713 {"msp430fr5734", MSP_ISA_430Xv2},
714 {"msp430fr5735", MSP_ISA_430Xv2},
715 {"msp430fr5736", MSP_ISA_430Xv2},
716 {"msp430fr5737", MSP_ISA_430Xv2},
717 {"msp430fr5738", MSP_ISA_430Xv2},
718 {"msp430fr5739", MSP_ISA_430Xv2},
719 {"msp430bt5190", MSP_ISA_430Xv2},
720 {"msp430fr5949", MSP_ISA_430Xv2},
721 {"msp430fr5969", MSP_ISA_430Xv2},
722 {"msp430sl5438a", MSP_ISA_430Xv2},
723
724 /* Generic names. */
725 {"msp430", MSP_ISA_430},
726 {"msp430X", MSP_ISA_430X},
727 {"msp430Xv2", MSP_ISA_430Xv2},
728
729 {NULL, 0}
730 };
731
732 static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
733 static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
734 static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
735
736 static struct mcu_type_s * msp430_mcu = & default_mcu;
737
738 static inline bfd_boolean
739 target_is_430x (void)
740 {
741 return msp430_mcu->isa >= MSP_ISA_430X;
742 }
743
744 static inline bfd_boolean
745 target_is_430xv2 (void)
746 {
747 return msp430_mcu->isa == MSP_ISA_430Xv2;
748 }
749
750 /* Generate a 16-bit relocation.
751 For the 430X we generate a relocation without linkwer range checking
752 if the value is being used in an extended (ie 20-bit) instruction.
753 For the 430 we generate a relocation without assembler range checking
754 if we are handling an immediate value or a byte-width instruction. */
755 #undef CHECK_RELOC_MSP430
756 #define CHECK_RELOC_MSP430 \
757 (target_is_430x () \
758 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
759 : ((imm_op || byte_op) \
760 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
761
762 /* Generate a 16-bit pc-relative relocation.
763 For the 430X we generate a relocation without linkwer range checking.
764 For the 430 we generate a relocation without assembler range checking
765 if we are handling an immediate value or a byte-width instruction. */
766 #undef CHECK_RELOC_MSP430_PCREL
767 #define CHECK_RELOC_MSP430_PCREL \
768 (target_is_430x () \
769 ? BFD_RELOC_MSP430X_PCR16 \
770 : (imm_op || byte_op) \
771 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
772
773 /* Profiling capability:
774 It is a performance hit to use gcc's profiling approach for this tiny target.
775 Even more -- jtag hardware facility does not perform any profiling functions.
776 However we've got gdb's built-in simulator where we can do anything.
777 Therefore my suggestion is:
778
779 We define new section ".profiler" which holds all profiling information.
780 We define new pseudo operation .profiler which will instruct assembler to
781 add new profile entry to the object file. Profile should take place at the
782 present address.
783
784 Pseudo-op format:
785
786 .profiler flags,function_to_profile [, cycle_corrector, extra]
787
788 where 'flags' is a combination of the following chars:
789 s - function Start
790 x - function eXit
791 i - function is in Init section
792 f - function is in Fini section
793 l - Library call
794 c - libC standard call
795 d - stack value Demand (saved at run-time in simulator)
796 I - Interrupt service routine
797 P - Prologue start
798 p - Prologue end
799 E - Epilogue start
800 e - Epilogue end
801 j - long Jump/ sjlj unwind
802 a - an Arbitrary code fragment
803 t - exTra parameter saved (constant value like frame size)
804 '""' optional: "sil" == sil
805
806 function_to_profile - function's address
807 cycle_corrector - a value which should be added to the cycle
808 counter, zero if omitted
809 extra - some extra parameter, zero if omitted.
810
811 For example:
812 ------------------------------
813 .global fxx
814 .type fxx,@function
815 fxx:
816 .LFrameOffset_fxx=0x08
817 .profiler "scdP", fxx ; function entry.
818 ; we also demand stack value to be displayed
819 push r11
820 push r10
821 push r9
822 push r8
823 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
824 ; (this is a prologue end)
825 ; note, that spare var filled with the frame size
826 mov r15,r8
827 ....
828 .profiler cdE,fxx ; check stack
829 pop r8
830 pop r9
831 pop r10
832 pop r11
833 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
834 ret ; cause 'ret' insn takes 3 cycles
835 -------------------------------
836
837 This profiling approach does not produce any overhead and
838 absolutely harmless.
839 So, even profiled code can be uploaded to the MCU. */
840 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
841 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
842 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
843 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
844 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
845 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
846 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
847 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
848 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
849 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
850 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
851 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
852 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
853 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
854 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
855 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
856
857 static int
858 pow2value (int y)
859 {
860 int n = 0;
861 unsigned int x;
862
863 x = y;
864
865 if (!x)
866 return 1;
867
868 for (; x; x = x >> 1)
869 if (x & 1)
870 n++;
871
872 return n == 1;
873 }
874
875 /* Parse ordinary expression. */
876
877 static char *
878 parse_exp (char * s, expressionS * op)
879 {
880 input_line_pointer = s;
881 expression (op);
882 if (op->X_op == O_absent)
883 as_bad (_("missing operand"));
884 return input_line_pointer;
885 }
886
887
888 /* Delete spaces from s: X ( r 1 2) => X(r12). */
889
890 static void
891 del_spaces (char * s)
892 {
893 while (*s)
894 {
895 if (ISSPACE (*s))
896 {
897 char *m = s + 1;
898
899 while (ISSPACE (*m) && *m)
900 m++;
901 memmove (s, m, strlen (m) + 1);
902 }
903 else
904 s++;
905 }
906 }
907
908 static inline char *
909 skip_space (char * s)
910 {
911 while (ISSPACE (*s))
912 ++s;
913 return s;
914 }
915
916 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
917
918 static char *
919 extract_operand (char * from, char * to, int limit)
920 {
921 int size = 0;
922
923 /* Drop leading whitespace. */
924 from = skip_space (from);
925
926 while (size < limit && *from)
927 {
928 *(to + size) = *from;
929 if (*from == ',' || *from == ';' || *from == '\n')
930 break;
931 from++;
932 size++;
933 }
934
935 *(to + size) = 0;
936 del_spaces (to);
937
938 from++;
939
940 return from;
941 }
942
943 static void
944 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
945 {
946 char buffer[1024];
947 char f[32];
948 char * str = buffer;
949 char * flags = f;
950 int p_flags = 0;
951 char * halt;
952 int ops = 0;
953 int left;
954 char * s;
955 segT seg;
956 int subseg;
957 char * end = 0;
958 expressionS exp;
959 expressionS exp1;
960
961 s = input_line_pointer;
962 end = input_line_pointer;
963
964 while (*end && *end != '\n')
965 end++;
966
967 while (*s && *s != '\n')
968 {
969 if (*s == ',')
970 ops++;
971 s++;
972 }
973
974 left = 3 - ops;
975
976 if (ops < 1)
977 {
978 as_bad (_(".profiler pseudo requires at least two operands."));
979 input_line_pointer = end;
980 return;
981 }
982
983 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
984
985 while (*flags)
986 {
987 switch (*flags)
988 {
989 case '"':
990 break;
991 case 'a':
992 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
993 break;
994 case 'j':
995 p_flags |= MSP430_PROFILER_FLAG_JUMP;
996 break;
997 case 'P':
998 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
999 break;
1000 case 'p':
1001 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
1002 break;
1003 case 'E':
1004 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
1005 break;
1006 case 'e':
1007 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
1008 break;
1009 case 's':
1010 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
1011 break;
1012 case 'x':
1013 p_flags |= MSP430_PROFILER_FLAG_EXIT;
1014 break;
1015 case 'i':
1016 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
1017 break;
1018 case 'f':
1019 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
1020 break;
1021 case 'l':
1022 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
1023 break;
1024 case 'c':
1025 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
1026 break;
1027 case 'd':
1028 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
1029 break;
1030 case 'I':
1031 p_flags |= MSP430_PROFILER_FLAG_ISR;
1032 break;
1033 case 't':
1034 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
1035 break;
1036 default:
1037 as_warn (_("unknown profiling flag - ignored."));
1038 break;
1039 }
1040 flags++;
1041 }
1042
1043 if (p_flags
1044 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
1045 | MSP430_PROFILER_FLAG_EXIT))
1046 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
1047 | MSP430_PROFILER_FLAG_PROLEND
1048 | MSP430_PROFILER_FLAG_EPISTART
1049 | MSP430_PROFILER_FLAG_EPIEND))
1050 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
1051 | MSP430_PROFILER_FLAG_FINISECT))))
1052 {
1053 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
1054 input_line_pointer = end;
1055 return;
1056 }
1057
1058 /* Generate temp symbol which denotes current location. */
1059 if (now_seg == absolute_section) /* Paranoia ? */
1060 {
1061 exp1.X_op = O_constant;
1062 exp1.X_add_number = abs_section_offset;
1063 as_warn (_("profiling in absolute section?"));
1064 }
1065 else
1066 {
1067 exp1.X_op = O_symbol;
1068 exp1.X_add_symbol = symbol_temp_new_now ();
1069 exp1.X_add_number = 0;
1070 }
1071
1072 /* Generate a symbol which holds flags value. */
1073 exp.X_op = O_constant;
1074 exp.X_add_number = p_flags;
1075
1076 /* Save current section. */
1077 seg = now_seg;
1078 subseg = now_subseg;
1079
1080 /* Now go to .profiler section. */
1081 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
1082
1083 /* Save flags. */
1084 emit_expr (& exp, 2);
1085
1086 /* Save label value. */
1087 emit_expr (& exp1, 2);
1088
1089 while (ops--)
1090 {
1091 /* Now get profiling info. */
1092 halt = extract_operand (input_line_pointer, str, 1024);
1093 /* Process like ".word xxx" directive. */
1094 parse_exp (str, & exp);
1095 emit_expr (& exp, 2);
1096 input_line_pointer = halt;
1097 }
1098
1099 /* Fill the rest with zeros. */
1100 exp.X_op = O_constant;
1101 exp.X_add_number = 0;
1102 while (left--)
1103 emit_expr (& exp, 2);
1104
1105 /* Return to current section. */
1106 subseg_set (seg, subseg);
1107 }
1108
1109 static char *
1110 extract_word (char * from, char * to, int limit)
1111 {
1112 char *op_end;
1113 int size = 0;
1114
1115 /* Drop leading whitespace. */
1116 from = skip_space (from);
1117 *to = 0;
1118
1119 /* Find the op code end. */
1120 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
1121 {
1122 to[size++] = *op_end++;
1123 if (size + 1 >= limit)
1124 break;
1125 }
1126
1127 to[size] = 0;
1128 return op_end;
1129 }
1130
1131 #define OPTION_MMCU 'm'
1132 #define OPTION_RELAX 'Q'
1133 #define OPTION_POLYMORPHS 'P'
1134 #define OPTION_LARGE 'l'
1135 static bfd_boolean large_model = FALSE;
1136 #define OPTION_INTR_NOPS 'n'
1137 #define OPTION_NO_INTR_NOPS 'N'
1138 static bfd_boolean gen_interrupt_nops = FALSE;
1139 #define OPTION_MCPU 'c'
1140 #define OPTION_MOVE_DATA 'd'
1141 static bfd_boolean move_data = FALSE;
1142
1143 static void
1144 msp430_set_arch (int option)
1145 {
1146 char *str = (char *) alloca (32); /* 32 for good measure. */
1147
1148 input_line_pointer = extract_word (input_line_pointer, str, 32);
1149
1150 md_parse_option (option, str);
1151 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1152 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1153 }
1154
1155 static void
1156 show_mcu_list (FILE * stream)
1157 {
1158 int i;
1159
1160 fprintf (stream, _("Known MCU names:\n"));
1161
1162 for (i = 0; mcu_types[i].name; i++)
1163 {
1164 fprintf (stream, "%14.14s", mcu_types[i].name);
1165 if ((i % 6) == 5)
1166 fprintf (stream, "\n");
1167 }
1168
1169 fprintf (stream, "\n");
1170 }
1171
1172 int
1173 md_parse_option (int c, char * arg)
1174 {
1175 int i;
1176
1177 switch (c)
1178 {
1179 case OPTION_MMCU:
1180 if (arg == NULL)
1181 as_fatal (_("MCU option requires a name\n"));
1182
1183 for (i = 0; mcu_types[i].name; ++i)
1184 if (strcasecmp (mcu_types[i].name, arg) == 0)
1185 break;
1186
1187 if (mcu_types[i].name == NULL)
1188 {
1189 show_mcu_list (stderr);
1190 as_fatal (_("unknown MCU: %s\n"), arg);
1191 }
1192
1193 /* Allow switching to the same or a lesser architecture. */
1194 if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
1195 msp430_mcu = mcu_types + i;
1196 else
1197 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1198 msp430_mcu->name, mcu_types[i].name);
1199 return 1;
1200
1201 case OPTION_MCPU:
1202 if (strcmp (arg, "430") == 0)
1203 msp430_mcu = & default_mcu;
1204 else if (strcmp (arg, "430x") == 0
1205 || strcmp (arg, "430X") == 0)
1206 msp430_mcu = & msp430x_mcu;
1207 else if (strcasecmp (arg, "430xv2") == 0)
1208 msp430_mcu = & msp430xv2_mcu;
1209 else
1210 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1211
1212 return 1;
1213
1214 case OPTION_RELAX:
1215 msp430_enable_relax = 1;
1216 return 1;
1217
1218 case OPTION_POLYMORPHS:
1219 msp430_enable_polys = 1;
1220 return 1;
1221
1222 case OPTION_LARGE:
1223 large_model = TRUE;
1224 return 1;
1225
1226 case OPTION_NO_INTR_NOPS:
1227 gen_interrupt_nops = FALSE;
1228 return 1;
1229 case OPTION_INTR_NOPS:
1230 gen_interrupt_nops = TRUE;
1231 return 1;
1232
1233 case OPTION_MOVE_DATA:
1234 move_data = TRUE;
1235 return 1;
1236 }
1237
1238 return 0;
1239 }
1240
1241 static void
1242 msp430_section (int arg)
1243 {
1244 char * saved_ilp = input_line_pointer;
1245 char * name = obj_elf_section_name ();
1246
1247 if (strncmp (name, ".bss", 4) == 0
1248 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1249 (void) symbol_find_or_make ("__crt0_init_bss");
1250
1251 if (move_data
1252 && (strncmp (name, ".data", 5) == 0
1253 || strncmp (name, ".gnu.linkonce.d.", 16) == 0))
1254 (void) symbol_find_or_make ("__crt0_movedata");
1255
1256 input_line_pointer = saved_ilp;
1257 obj_elf_section (arg);
1258 }
1259
1260 const pseudo_typeS md_pseudo_table[] =
1261 {
1262 {"arch", msp430_set_arch, OPTION_MMCU},
1263 {"cpu", msp430_set_arch, OPTION_MCPU},
1264 {"profiler", msp430_profiler, 0},
1265 {"section", msp430_section, 0},
1266 {"section.s", msp430_section, 0},
1267 {"sect", msp430_section, 0},
1268 {"sect.s", msp430_section, 0},
1269 {"pushsection", msp430_section, 1},
1270 {NULL, NULL, 0}
1271 };
1272
1273 const char *md_shortopts = "mm:,mP,mQ,ml,mN";
1274
1275 struct option md_longopts[] =
1276 {
1277 {"mmcu", required_argument, NULL, OPTION_MMCU},
1278 {"mcpu", required_argument, NULL, OPTION_MCPU},
1279 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1280 {"mQ", no_argument, NULL, OPTION_RELAX},
1281 {"ml", no_argument, NULL, OPTION_LARGE},
1282 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1283 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1284 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1285 {NULL, no_argument, NULL, 0}
1286 };
1287
1288 size_t md_longopts_size = sizeof (md_longopts);
1289
1290 void
1291 md_show_usage (FILE * stream)
1292 {
1293 fprintf (stream,
1294 _("MSP430 options:\n"
1295 " -mmcu=<msp430-name> - select microcontroller type\n"
1296 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1297 fprintf (stream,
1298 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1299 " -mP - enable polymorph instructions\n"));
1300 fprintf (stream,
1301 _(" -ml - enable large code model\n"));
1302 fprintf (stream,
1303 _(" -mN - disable generation of NOP after changing interrupts\n"));
1304 fprintf (stream,
1305 _(" -mn - enable generation of NOP after changing interrupts\n"));
1306 fprintf (stream,
1307 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1308
1309 show_mcu_list (stream);
1310 }
1311
1312 symbolS *
1313 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1314 {
1315 return NULL;
1316 }
1317
1318 static char *
1319 extract_cmd (char * from, char * to, int limit)
1320 {
1321 int size = 0;
1322
1323 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1324 {
1325 *(to + size) = *from;
1326 from++;
1327 size++;
1328 }
1329
1330 *(to + size) = 0;
1331
1332 return from;
1333 }
1334
1335 char *
1336 md_atof (int type, char * litP, int * sizeP)
1337 {
1338 return ieee_md_atof (type, litP, sizeP, FALSE);
1339 }
1340
1341 void
1342 md_begin (void)
1343 {
1344 struct msp430_opcode_s * opcode;
1345 msp430_hash = hash_new ();
1346
1347 for (opcode = msp430_opcodes; opcode->name; opcode++)
1348 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1349
1350 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1351 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1352 }
1353
1354 /* Returns the register number equivalent to the string T.
1355 Returns -1 if there is no such register.
1356 Skips a leading 'r' or 'R' character if there is one.
1357 Handles the register aliases PC and SP. */
1358
1359 static signed int
1360 check_reg (char * t)
1361 {
1362 signed int val;
1363
1364 if (t == NULL)
1365 return -1;
1366
1367 if (*t == 'r' || *t == 'R')
1368 ++t;
1369
1370 if (strncasecmp (t, "pc", 2) == 0)
1371 return 0;
1372
1373 if (strncasecmp (t, "sp", 2) == 0)
1374 return 1;
1375
1376 if (strncasecmp (t, "sr", 2) == 0)
1377 return 2;
1378
1379 if (*t == '0')
1380 return 0;
1381
1382 val = atoi (t);
1383
1384 if (val < 1 || val > 15)
1385 return -1;
1386
1387 return val;
1388 }
1389
1390 static int
1391 msp430_srcoperand (struct msp430_operand_s * op,
1392 char * l,
1393 int bin,
1394 int * imm_op,
1395 bfd_boolean allow_20bit_values,
1396 bfd_boolean constants_allowed)
1397 {
1398 char *__tl = l;
1399
1400 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1401 if (*l == '#')
1402 {
1403 char *h = l;
1404 int vshift = -1;
1405 int rval = 0;
1406
1407 /* Check if there is:
1408 llo(x) - least significant 16 bits, x &= 0xffff
1409 lhi(x) - x = (x >> 16) & 0xffff,
1410 hlo(x) - x = (x >> 32) & 0xffff,
1411 hhi(x) - x = (x >> 48) & 0xffff
1412 The value _MUST_ be constant expression: #hlo(1231231231). */
1413
1414 *imm_op = 1;
1415
1416 if (strncasecmp (h, "#llo(", 5) == 0)
1417 {
1418 vshift = 0;
1419 rval = 3;
1420 }
1421 else if (strncasecmp (h, "#lhi(", 5) == 0)
1422 {
1423 vshift = 1;
1424 rval = 3;
1425 }
1426 else if (strncasecmp (h, "#hlo(", 5) == 0)
1427 {
1428 vshift = 2;
1429 rval = 3;
1430 }
1431 else if (strncasecmp (h, "#hhi(", 5) == 0)
1432 {
1433 vshift = 3;
1434 rval = 3;
1435 }
1436 else if (strncasecmp (h, "#lo(", 4) == 0)
1437 {
1438 vshift = 0;
1439 rval = 2;
1440 }
1441 else if (strncasecmp (h, "#hi(", 4) == 0)
1442 {
1443 vshift = 1;
1444 rval = 2;
1445 }
1446
1447 op->reg = 0; /* Reg PC. */
1448 op->am = 3;
1449 op->ol = 1; /* Immediate will follow an instruction. */
1450 __tl = h + 1 + rval;
1451 op->mode = OP_EXP;
1452
1453 parse_exp (__tl, &(op->exp));
1454 if (op->exp.X_op == O_constant)
1455 {
1456 int x = op->exp.X_add_number;
1457
1458 if (vshift == 0)
1459 {
1460 x = x & 0xffff;
1461 op->exp.X_add_number = x;
1462 }
1463 else if (vshift == 1)
1464 {
1465 x = (x >> 16) & 0xffff;
1466 op->exp.X_add_number = x;
1467 }
1468 else if (vshift > 1)
1469 {
1470 if (x < 0)
1471 op->exp.X_add_number = -1;
1472 else
1473 op->exp.X_add_number = 0; /* Nothing left. */
1474 x = op->exp.X_add_number;
1475 }
1476
1477 if (allow_20bit_values)
1478 {
1479 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1480 {
1481 as_bad (_("value 0x%x out of extended range."), x);
1482 return 1;
1483 }
1484 }
1485 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1486 {
1487 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1488 return 1;
1489 }
1490
1491 /* Now check constants. */
1492 /* Substitute register mode with a constant generator if applicable. */
1493
1494 if (!allow_20bit_values)
1495 x = (short) x; /* Extend sign. */
1496
1497 if (! constants_allowed)
1498 ;
1499 else if (x == 0)
1500 {
1501 op->reg = 3;
1502 op->am = 0;
1503 op->ol = 0;
1504 op->mode = OP_REG;
1505 }
1506 else if (x == 1)
1507 {
1508 op->reg = 3;
1509 op->am = 1;
1510 op->ol = 0;
1511 op->mode = OP_REG;
1512 }
1513 else if (x == 2)
1514 {
1515 op->reg = 3;
1516 op->am = 2;
1517 op->ol = 0;
1518 op->mode = OP_REG;
1519 }
1520 else if (x == -1)
1521 {
1522 op->reg = 3;
1523 op->am = 3;
1524 op->ol = 0;
1525 op->mode = OP_REG;
1526 }
1527 else if (x == 4)
1528 {
1529 #ifdef PUSH_1X_WORKAROUND
1530 if (bin == 0x1200)
1531 {
1532 /* Remove warning as confusing.
1533 as_warn (_("Hardware push bug workaround")); */
1534 }
1535 else
1536 #endif
1537 {
1538 op->reg = 2;
1539 op->am = 2;
1540 op->ol = 0;
1541 op->mode = OP_REG;
1542 }
1543 }
1544 else if (x == 8)
1545 {
1546 #ifdef PUSH_1X_WORKAROUND
1547 if (bin == 0x1200)
1548 {
1549 /* Remove warning as confusing.
1550 as_warn (_("Hardware push bug workaround")); */
1551 }
1552 else
1553 #endif
1554 {
1555 op->reg = 2;
1556 op->am = 3;
1557 op->ol = 0;
1558 op->mode = OP_REG;
1559 }
1560 }
1561 }
1562 else if (op->exp.X_op == O_symbol)
1563 {
1564 op->mode = OP_EXP;
1565 }
1566 else if (op->exp.X_op == O_big)
1567 {
1568 short x;
1569 if (vshift != -1)
1570 {
1571 op->exp.X_op = O_constant;
1572 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1573 x = op->exp.X_add_number;
1574 }
1575 else
1576 {
1577 as_bad (_
1578 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1579 l);
1580 return 1;
1581 }
1582
1583 if (x == 0)
1584 {
1585 op->reg = 3;
1586 op->am = 0;
1587 op->ol = 0;
1588 op->mode = OP_REG;
1589 }
1590 else if (x == 1)
1591 {
1592 op->reg = 3;
1593 op->am = 1;
1594 op->ol = 0;
1595 op->mode = OP_REG;
1596 }
1597 else if (x == 2)
1598 {
1599 op->reg = 3;
1600 op->am = 2;
1601 op->ol = 0;
1602 op->mode = OP_REG;
1603 }
1604 else if (x == -1)
1605 {
1606 op->reg = 3;
1607 op->am = 3;
1608 op->ol = 0;
1609 op->mode = OP_REG;
1610 }
1611 else if (x == 4)
1612 {
1613 op->reg = 2;
1614 op->am = 2;
1615 op->ol = 0;
1616 op->mode = OP_REG;
1617 }
1618 else if (x == 8)
1619 {
1620 op->reg = 2;
1621 op->am = 3;
1622 op->ol = 0;
1623 op->mode = OP_REG;
1624 }
1625 }
1626 /* Redundant (yet) check. */
1627 else if (op->exp.X_op == O_register)
1628 as_bad
1629 (_("Registers cannot be used within immediate expression [%s]"), l);
1630 else
1631 as_bad (_("unknown operand %s"), l);
1632
1633 return 0;
1634 }
1635
1636 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1637 if (*l == '&')
1638 {
1639 char *h = l;
1640
1641 op->reg = 2; /* reg 2 in absolute addr mode. */
1642 op->am = 1; /* mode As == 01 bin. */
1643 op->ol = 1; /* Immediate value followed by instruction. */
1644 __tl = h + 1;
1645 parse_exp (__tl, &(op->exp));
1646 op->mode = OP_EXP;
1647 if (op->exp.X_op == O_constant)
1648 {
1649 int x = op->exp.X_add_number;
1650
1651 if (allow_20bit_values)
1652 {
1653 if (x > 0xfffff || x < -(0x7ffff))
1654 {
1655 as_bad (_("value 0x%x out of extended range."), x);
1656 return 1;
1657 }
1658 }
1659 else if (x > 65535 || x < -32768)
1660 {
1661 as_bad (_("value out of range: 0x%x"), x);
1662 return 1;
1663 }
1664 }
1665 else if (op->exp.X_op == O_symbol)
1666 ;
1667 else
1668 {
1669 /* Redundant (yet) check. */
1670 if (op->exp.X_op == O_register)
1671 as_bad
1672 (_("Registers cannot be used within absolute expression [%s]"), l);
1673 else
1674 as_bad (_("unknown expression in operand %s"), l);
1675 return 1;
1676 }
1677 return 0;
1678 }
1679
1680 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1681 if (*l == '@')
1682 {
1683 char *t = l;
1684 char *m = strchr (l, '+');
1685
1686 if (t != l)
1687 {
1688 as_bad (_("unknown addressing mode %s"), l);
1689 return 1;
1690 }
1691
1692 t++;
1693
1694 if ((op->reg = check_reg (t)) == -1)
1695 {
1696 as_bad (_("Bad register name %s"), t);
1697 return 1;
1698 }
1699
1700 op->mode = OP_REG;
1701 op->am = m ? 3 : 2;
1702 op->ol = 0;
1703
1704 /* PC cannot be used in indirect addressing. */
1705 if (target_is_430xv2 () && op->reg == 0)
1706 {
1707 as_bad (_("cannot use indirect addressing with the PC"));
1708 return 1;
1709 }
1710 return 0;
1711 }
1712
1713 /* Check if register indexed X(Rn). */
1714 do
1715 {
1716 char *h = strrchr (l, '(');
1717 char *m = strrchr (l, ')');
1718 char *t;
1719
1720 *imm_op = 1;
1721
1722 if (!h)
1723 break;
1724 if (!m)
1725 {
1726 as_bad (_("')' required"));
1727 return 1;
1728 }
1729
1730 t = h;
1731 op->am = 1;
1732 op->ol = 1;
1733
1734 /* Extract a register. */
1735 if ((op->reg = check_reg (t + 1)) == -1)
1736 {
1737 as_bad (_
1738 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1739 l);
1740 return 1;
1741 }
1742
1743 if (op->reg == 2)
1744 {
1745 as_bad (_("r2 should not be used in indexed addressing mode"));
1746 return 1;
1747 }
1748
1749 /* Extract constant. */
1750 __tl = l;
1751 *h = 0;
1752 op->mode = OP_EXP;
1753 parse_exp (__tl, &(op->exp));
1754 if (op->exp.X_op == O_constant)
1755 {
1756 int x = op->exp.X_add_number;
1757
1758 if (allow_20bit_values)
1759 {
1760 if (x > 0xfffff || x < - (0x7ffff))
1761 {
1762 as_bad (_("value 0x%x out of extended range."), x);
1763 return 1;
1764 }
1765 }
1766 else if (x > 65535 || x < -32768)
1767 {
1768 as_bad (_("value out of range: 0x%x"), x);
1769 return 1;
1770 }
1771
1772 if (x == 0)
1773 {
1774 op->mode = OP_REG;
1775 op->am = 2;
1776 op->ol = 0;
1777 return 0;
1778 }
1779 }
1780 else if (op->exp.X_op == O_symbol)
1781 ;
1782 else
1783 {
1784 /* Redundant (yet) check. */
1785 if (op->exp.X_op == O_register)
1786 as_bad
1787 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1788 else
1789 as_bad (_("unknown expression in operand %s"), l);
1790 return 1;
1791 }
1792
1793 return 0;
1794 }
1795 while (0);
1796
1797 /* Possibly register mode 'mov r1,r2'. */
1798 if ((op->reg = check_reg (l)) != -1)
1799 {
1800 op->mode = OP_REG;
1801 op->am = 0;
1802 op->ol = 0;
1803 return 0;
1804 }
1805
1806 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1807 do
1808 {
1809 op->mode = OP_EXP;
1810 op->reg = 0; /* PC relative... be careful. */
1811 /* An expression starting with a minus sign is a constant, not an address. */
1812 op->am = (*l == '-' ? 3 : 1);
1813 op->ol = 1;
1814 __tl = l;
1815 parse_exp (__tl, &(op->exp));
1816 return 0;
1817 }
1818 while (0);
1819
1820 /* Unreachable. */
1821 as_bad (_("unknown addressing mode for operand %s"), l);
1822 return 1;
1823 }
1824
1825
1826 static int
1827 msp430_dstoperand (struct msp430_operand_s * op,
1828 char * l,
1829 int bin,
1830 bfd_boolean allow_20bit_values,
1831 bfd_boolean constants_allowed)
1832 {
1833 int dummy;
1834 int ret = msp430_srcoperand (op, l, bin, & dummy,
1835 allow_20bit_values,
1836 constants_allowed);
1837
1838 if (ret)
1839 return ret;
1840
1841 if (op->am == 2)
1842 {
1843 char *__tl = "0";
1844
1845 op->mode = OP_EXP;
1846 op->am = 1;
1847 op->ol = 1;
1848 parse_exp (__tl, &(op->exp));
1849
1850 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1851 {
1852 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1853 op->reg, op->reg);
1854 return 1;
1855 }
1856 return 0;
1857 }
1858
1859 if (op->am > 1)
1860 {
1861 as_bad (_
1862 ("this addressing mode is not applicable for destination operand"));
1863 return 1;
1864 }
1865 return 0;
1866 }
1867
1868
1869 /* Attempt to encode a MOVA instruction with the given operands.
1870 Returns the length of the encoded instruction if successful
1871 or 0 upon failure. If the encoding fails, an error message
1872 will be returned if a pointer is provided. */
1873
1874 static int
1875 try_encode_mova (bfd_boolean imm_op,
1876 int bin,
1877 struct msp430_operand_s * op1,
1878 struct msp430_operand_s * op2,
1879 const char ** error_message_return)
1880 {
1881 short ZEROS = 0;
1882 char *frag;
1883 int where;
1884
1885 /* Only a restricted subset of the normal MSP430 addressing modes
1886 are supported here, so check for the ones that are allowed. */
1887 if (imm_op)
1888 {
1889 if (op1->mode == OP_EXP)
1890 {
1891 if (op2->mode != OP_REG)
1892 {
1893 if (error_message_return != NULL)
1894 * error_message_return = _("expected register as second argument of %s");
1895 return 0;
1896 }
1897
1898 if (op1->am == 3)
1899 {
1900 /* MOVA #imm20, Rdst. */
1901 bin |= 0x80 | op2->reg;
1902 frag = frag_more (4);
1903 where = frag - frag_now->fr_literal;
1904 if (op1->exp.X_op == O_constant)
1905 {
1906 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1907 bfd_putl16 ((bfd_vma) bin, frag);
1908 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1909 }
1910 else
1911 {
1912 bfd_putl16 ((bfd_vma) bin, frag);
1913 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1914 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1915 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1916 }
1917
1918 return 4;
1919 }
1920 else if (op1->am == 1)
1921 {
1922 /* MOVA z16(Rsrc), Rdst. */
1923 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1924 frag = frag_more (4);
1925 where = frag - frag_now->fr_literal;
1926 bfd_putl16 ((bfd_vma) bin, frag);
1927 if (op1->exp.X_op == O_constant)
1928 {
1929 if (op1->exp.X_add_number > 0xffff
1930 || op1->exp.X_add_number < -(0x7fff))
1931 {
1932 if (error_message_return != NULL)
1933 * error_message_return = _("index value too big for %s");
1934 return 0;
1935 }
1936 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1937 }
1938 else
1939 {
1940 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1941 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1942 op1->reg == 0 ?
1943 BFD_RELOC_MSP430X_PCR16 :
1944 BFD_RELOC_MSP430X_ABS16);
1945 }
1946 return 4;
1947 }
1948
1949 if (error_message_return != NULL)
1950 * error_message_return = _("unexpected addressing mode for %s");
1951 return 0;
1952 }
1953 else if (op1->am == 0)
1954 {
1955 /* MOVA Rsrc, ... */
1956 if (op2->mode == OP_REG)
1957 {
1958 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1959 frag = frag_more (2);
1960 where = frag - frag_now->fr_literal;
1961 bfd_putl16 ((bfd_vma) bin, frag);
1962 return 2;
1963 }
1964 else if (op2->am == 1)
1965 {
1966 if (op2->reg == 2)
1967 {
1968 /* MOVA Rsrc, &abs20. */
1969 bin |= 0x60 | (op1->reg << 8);
1970 frag = frag_more (4);
1971 where = frag - frag_now->fr_literal;
1972 if (op2->exp.X_op == O_constant)
1973 {
1974 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1975 bfd_putl16 ((bfd_vma) bin, frag);
1976 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1977 }
1978 else
1979 {
1980 bfd_putl16 ((bfd_vma) bin, frag);
1981 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1982 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1983 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1984 }
1985 return 4;
1986 }
1987
1988 /* MOVA Rsrc, z16(Rdst). */
1989 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1990 frag = frag_more (4);
1991 where = frag - frag_now->fr_literal;
1992 bfd_putl16 ((bfd_vma) bin, frag);
1993 if (op2->exp.X_op == O_constant)
1994 {
1995 if (op2->exp.X_add_number > 0xffff
1996 || op2->exp.X_add_number < -(0x7fff))
1997 {
1998 if (error_message_return != NULL)
1999 * error_message_return = _("index value too big for %s");
2000 return 0;
2001 }
2002 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2003 }
2004 else
2005 {
2006 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2007 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2008 op2->reg == 0 ?
2009 BFD_RELOC_MSP430X_PCR16 :
2010 BFD_RELOC_MSP430X_ABS16);
2011 }
2012 return 4;
2013 }
2014
2015 if (error_message_return != NULL)
2016 * error_message_return = _("unexpected addressing mode for %s");
2017 return 0;
2018 }
2019 }
2020
2021 /* imm_op == FALSE. */
2022
2023 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2024 {
2025 /* MOVA &abs20, Rdst. */
2026 if (op2->mode != OP_REG)
2027 {
2028 if (error_message_return != NULL)
2029 * error_message_return = _("expected register as second argument of %s");
2030 return 0;
2031 }
2032
2033 if (op2->reg == 2 || op2->reg == 3)
2034 {
2035 if (error_message_return != NULL)
2036 * error_message_return = _("constant generator destination register found in %s");
2037 return 0;
2038 }
2039
2040 bin |= 0x20 | op2->reg;
2041 frag = frag_more (4);
2042 where = frag - frag_now->fr_literal;
2043 if (op1->exp.X_op == O_constant)
2044 {
2045 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2046 bfd_putl16 ((bfd_vma) bin, frag);
2047 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2048 }
2049 else
2050 {
2051 bfd_putl16 ((bfd_vma) bin, frag);
2052 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2053 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2054 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2055 }
2056 return 4;
2057 }
2058 else if (op1->mode == OP_REG)
2059 {
2060 if (op1->am == 3)
2061 {
2062 /* MOVA @Rsrc+, Rdst. */
2063 if (op2->mode != OP_REG)
2064 {
2065 if (error_message_return != NULL)
2066 * error_message_return = _("expected register as second argument of %s");
2067 return 0;
2068 }
2069
2070 if (op2->reg == 2 || op2->reg == 3)
2071 {
2072 if (error_message_return != NULL)
2073 * error_message_return = _("constant generator destination register found in %s");
2074 return 0;
2075 }
2076
2077 if (op1->reg == 2 || op1->reg == 3)
2078 {
2079 if (error_message_return != NULL)
2080 * error_message_return = _("constant generator source register found in %s");
2081 return 0;
2082 }
2083
2084 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2085 frag = frag_more (2);
2086 where = frag - frag_now->fr_literal;
2087 bfd_putl16 ((bfd_vma) bin, frag);
2088 return 2;
2089 }
2090 else if (op1->am == 2)
2091 {
2092 /* MOVA @Rsrc,Rdst */
2093 if (op2->mode != OP_REG)
2094 {
2095 if (error_message_return != NULL)
2096 * error_message_return = _("expected register as second argument of %s");
2097 return 0;
2098 }
2099
2100 if (op2->reg == 2 || op2->reg == 3)
2101 {
2102 if (error_message_return != NULL)
2103 * error_message_return = _("constant generator destination register found in %s");
2104 return 0;
2105 }
2106
2107 if (op1->reg == 2 || op1->reg == 3)
2108 {
2109 if (error_message_return != NULL)
2110 * error_message_return = _("constant generator source register found in %s");
2111 return 0;
2112 }
2113
2114 bin |= (op1->reg << 8) | op2->reg;
2115 frag = frag_more (2);
2116 where = frag - frag_now->fr_literal;
2117 bfd_putl16 ((bfd_vma) bin, frag);
2118 return 2;
2119 }
2120 }
2121
2122 if (error_message_return != NULL)
2123 * error_message_return = _("unexpected addressing mode for %s");
2124
2125 return 0;
2126 }
2127
2128 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2129
2130 /* Parse instruction operands.
2131 Return binary opcode. */
2132
2133 static unsigned int
2134 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2135 {
2136 int bin = opcode->bin_opcode; /* Opcode mask. */
2137 int insn_length = 0;
2138 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2139 char *frag;
2140 int where;
2141 struct msp430_operand_s op1, op2;
2142 int res = 0;
2143 static short ZEROS = 0;
2144 int byte_op, imm_op;
2145 int op_length = 0;
2146 int fmt;
2147 int extended = 0x1800;
2148 bfd_boolean extended_op = FALSE;
2149 bfd_boolean addr_op;
2150 const char * error_message;
2151 static signed int repeat_count = 0;
2152 bfd_boolean fix_emitted;
2153
2154 /* Opcode is the one from opcodes table
2155 line contains something like
2156 [.w] @r2+, 5(R1)
2157 or
2158 .b @r2+, 5(R1). */
2159
2160 byte_op = 0;
2161 addr_op = FALSE;
2162 if (*line == '.')
2163 {
2164 bfd_boolean check = FALSE;
2165 ++ line;
2166
2167 switch (TOLOWER (* line))
2168 {
2169 case 'b':
2170 /* Byte operation. */
2171 bin |= BYTE_OPERATION;
2172 byte_op = 1;
2173 check = TRUE;
2174 break;
2175
2176 case 'a':
2177 /* "Address" ops work on 20-bit values. */
2178 addr_op = TRUE;
2179 bin |= BYTE_OPERATION;
2180 check = TRUE;
2181 break;
2182
2183 case 'w':
2184 /* Word operation - this is the default. */
2185 check = TRUE;
2186 break;
2187
2188 case 0:
2189 case ' ':
2190 case '\n':
2191 case '\r':
2192 as_warn (_("no size modifier after period, .w assumed"));
2193 break;
2194
2195 default:
2196 as_bad (_("unrecognised instruction size modifier .%c"),
2197 * line);
2198 return 0;
2199 }
2200
2201 if (check)
2202 {
2203 ++ line;
2204
2205 }
2206 }
2207
2208 if (*line && ! ISSPACE (*line))
2209 {
2210 as_bad (_("junk found after instruction: %s.%s"),
2211 opcode->name, line);
2212 return 0;
2213 }
2214
2215 /* Catch the case where the programmer has used a ".a" size modifier on an
2216 instruction that does not support it. Look for an alternative extended
2217 instruction that has the same name without the period. Eg: "add.a"
2218 becomes "adda". Although this not an officially supported way of
2219 specifing instruction aliases other MSP430 assemblers allow it. So we
2220 support it for compatibility purposes. */
2221 if (addr_op && opcode->fmt >= 0)
2222 {
2223 char * old_name = opcode->name;
2224 char real_name[32];
2225
2226 sprintf (real_name, "%sa", old_name);
2227 opcode = hash_find (msp430_hash, real_name);
2228 if (opcode == NULL)
2229 {
2230 as_bad (_("instruction %s.a does not exist"), old_name);
2231 return 0;
2232 }
2233 #if 0 /* Enable for debugging. */
2234 as_warn ("treating %s.a as %s", old_name, real_name);
2235 #endif
2236 addr_op = FALSE;
2237 bin = opcode->bin_opcode;
2238 }
2239
2240 if (opcode->fmt != -1
2241 && opcode->insn_opnumb
2242 && (!*line || *line == '\n'))
2243 {
2244 as_bad (_("instruction %s requires %d operand(s)"),
2245 opcode->name, opcode->insn_opnumb);
2246 return 0;
2247 }
2248
2249 memset (l1, 0, sizeof (l1));
2250 memset (l2, 0, sizeof (l2));
2251 memset (&op1, 0, sizeof (op1));
2252 memset (&op2, 0, sizeof (op2));
2253
2254 imm_op = 0;
2255
2256 if ((fmt = opcode->fmt) < 0)
2257 {
2258 if (! target_is_430x ())
2259 {
2260 as_bad (_("instruction %s requires MSP430X mcu"),
2261 opcode->name);
2262 return 0;
2263 }
2264
2265 fmt = (-fmt) - 1;
2266 extended_op = TRUE;
2267 }
2268
2269 if (repeat_count)
2270 {
2271 /* If requested set the extended instruction repeat count. */
2272 if (extended_op)
2273 {
2274 if (repeat_count > 0)
2275 extended |= (repeat_count - 1);
2276 else
2277 extended |= (1 << 7) | (- repeat_count);
2278 }
2279 else
2280 as_bad (_("unable to repeat %s insn"), opcode->name);
2281
2282 repeat_count = 0;
2283 }
2284
2285 switch (fmt)
2286 {
2287 case 0: /* Emulated. */
2288 switch (opcode->insn_opnumb)
2289 {
2290 case 0:
2291 /* Set/clear bits instructions. */
2292 if (extended_op)
2293 {
2294 if (!addr_op)
2295 extended |= BYTE_OPERATION;
2296
2297 /* Emit the extension word. */
2298 insn_length += 2;
2299 frag = frag_more (insn_length);
2300 bfd_putl16 (extended, frag);
2301 }
2302
2303 insn_length += 2;
2304 frag = frag_more (insn_length);
2305 bfd_putl16 ((bfd_vma) bin, frag);
2306
2307 if (gen_interrupt_nops
2308 && (is_opcode ("eint") || is_opcode ("dint")))
2309 {
2310 /* Emit a NOP following interrupt enable/disable.
2311 See 1.3.4.1 of the MSP430x5xx User Guide. */
2312 insn_length += 2;
2313 frag = frag_more (2);
2314 as_warn (_("a NOP instruction has been inserted after %s"),
2315 opcode->name);
2316 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2317 }
2318 dwarf2_emit_insn (insn_length);
2319 break;
2320
2321 case 1:
2322 /* Something which works with destination operand. */
2323 line = extract_operand (line, l1, sizeof (l1));
2324 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2325 if (res)
2326 break;
2327
2328 /* Compute the entire instruction length, in bytes. */
2329 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2330 frag = frag_more (insn_length);
2331 where = frag - frag_now->fr_literal;
2332
2333 if (extended_op)
2334 {
2335 if (!addr_op)
2336 extended |= BYTE_OPERATION;
2337
2338 if (op1.ol != 0 && ((extended & 0xf) != 0))
2339 {
2340 as_bad (_("repeat instruction used with non-register mode instruction"));
2341 extended &= ~ 0xf;
2342 }
2343
2344 if (op1.mode == OP_EXP)
2345 {
2346 if (op1.exp.X_op == O_constant)
2347 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2348
2349 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2350 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2351 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2352 else
2353 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2354 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2355 }
2356
2357 /* Emit the extension word. */
2358 bfd_putl16 (extended, frag);
2359 frag += 2;
2360 where += 2;
2361 }
2362
2363 bin |= (op1.reg | (op1.am << 7));
2364 bfd_putl16 ((bfd_vma) bin, frag);
2365 frag += 2;
2366 where += 2;
2367
2368 if (op1.mode == OP_EXP)
2369 {
2370 if (op1.exp.X_op == O_constant)
2371 {
2372 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2373 }
2374 else
2375 {
2376 bfd_putl16 ((bfd_vma) ZEROS, frag);
2377
2378 if (!extended_op)
2379 {
2380 if (op1.reg)
2381 fix_new_exp (frag_now, where, 2,
2382 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2383 else
2384 fix_new_exp (frag_now, where, 2,
2385 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2386 }
2387 }
2388 }
2389
2390 if (gen_interrupt_nops
2391 && is_opcode ("clr")
2392 && bin == 0x4302 /* CLR R2*/)
2393 {
2394 /* Emit a NOP following interrupt enable/disable.
2395 See 1.3.4.1 of the MSP430x5xx User Guide. */
2396 insn_length += 2;
2397 frag = frag_more (2);
2398 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2399 as_warn (_("a NOP instruction has been inserted after %s"),
2400 opcode->name);
2401 }
2402
2403 dwarf2_emit_insn (insn_length);
2404 break;
2405
2406 case 2:
2407 /* Shift instruction. */
2408 line = extract_operand (line, l1, sizeof (l1));
2409 strncpy (l2, l1, sizeof (l2));
2410 l2[sizeof (l2) - 1] = '\0';
2411 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2412 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2413
2414 if (res)
2415 break; /* An error occurred. All warnings were done before. */
2416
2417 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2418 frag = frag_more (insn_length);
2419 where = frag - frag_now->fr_literal;
2420
2421 if (target_is_430xv2 ()
2422 && op1.mode == OP_REG
2423 && op1.reg == 0
2424 && (is_opcode ("rlax")
2425 || is_opcode ("rlcx")
2426 || is_opcode ("rla")
2427 || is_opcode ("rlc")))
2428 {
2429 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2430 return 0;
2431 }
2432
2433 if (extended_op)
2434 {
2435 if (!addr_op)
2436 extended |= BYTE_OPERATION;
2437
2438 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2439 {
2440 as_bad (_("repeat instruction used with non-register mode instruction"));
2441 extended &= ~ 0xf;
2442 }
2443
2444 if (op1.mode == OP_EXP)
2445 {
2446 if (op1.exp.X_op == O_constant)
2447 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2448
2449 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2450 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2451 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2452 else
2453 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2454 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2455 }
2456
2457 if (op2.mode == OP_EXP)
2458 {
2459 if (op2.exp.X_op == O_constant)
2460 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2461
2462 else if (op1.mode == OP_EXP)
2463 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2464 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2465 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2466 else
2467 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2468 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2469 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2470 }
2471
2472 /* Emit the extension word. */
2473 bfd_putl16 (extended, frag);
2474 frag += 2;
2475 where += 2;
2476 }
2477
2478 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2479 bfd_putl16 ((bfd_vma) bin, frag);
2480 frag += 2;
2481 where += 2;
2482
2483 if (op1.mode == OP_EXP)
2484 {
2485 if (op1.exp.X_op == O_constant)
2486 {
2487 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2488 }
2489 else
2490 {
2491 bfd_putl16 ((bfd_vma) ZEROS, frag);
2492
2493 if (!extended_op)
2494 {
2495 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2496 fix_new_exp (frag_now, where, 2,
2497 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2498 else
2499 fix_new_exp (frag_now, where, 2,
2500 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2501 }
2502 }
2503 frag += 2;
2504 where += 2;
2505 }
2506
2507 if (op2.mode == OP_EXP)
2508 {
2509 if (op2.exp.X_op == O_constant)
2510 {
2511 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2512 }
2513 else
2514 {
2515 bfd_putl16 ((bfd_vma) ZEROS, frag);
2516
2517 if (!extended_op)
2518 {
2519 if (op2.reg) /* Not PC relative. */
2520 fix_new_exp (frag_now, where, 2,
2521 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2522 else
2523 fix_new_exp (frag_now, where, 2,
2524 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2525 }
2526 }
2527 }
2528
2529 dwarf2_emit_insn (insn_length);
2530 break;
2531
2532 case 3:
2533 /* Branch instruction => mov dst, r0. */
2534 if (extended_op)
2535 {
2536 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2537 return 0;
2538 }
2539
2540 line = extract_operand (line, l1, sizeof (l1));
2541 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2542 if (res)
2543 break;
2544
2545 byte_op = 0;
2546 imm_op = 0;
2547 bin |= ((op1.reg << 8) | (op1.am << 4));
2548 op_length = 2 + 2 * op1.ol;
2549 frag = frag_more (op_length);
2550 where = frag - frag_now->fr_literal;
2551 bfd_putl16 ((bfd_vma) bin, frag);
2552
2553 if (op1.mode == OP_EXP)
2554 {
2555 if (op1.exp.X_op == O_constant)
2556 {
2557 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2558 }
2559 else
2560 {
2561 where += 2;
2562
2563 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2564
2565 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2566 fix_new_exp (frag_now, where, 2,
2567 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2568 else
2569 fix_new_exp (frag_now, where, 2,
2570 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2571 }
2572 }
2573
2574 dwarf2_emit_insn (insn_length + op_length);
2575 break;
2576
2577 case 4:
2578 /* CALLA instructions. */
2579 fix_emitted = FALSE;
2580
2581 line = extract_operand (line, l1, sizeof (l1));
2582 imm_op = 0;
2583
2584 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2585 extended_op, FALSE);
2586 if (res)
2587 break;
2588
2589 byte_op = 0;
2590
2591 op_length = 2 + 2 * op1.ol;
2592 frag = frag_more (op_length);
2593 where = frag - frag_now->fr_literal;
2594
2595 if (imm_op)
2596 {
2597 if (op1.am == 3)
2598 {
2599 bin |= 0xb0;
2600
2601 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2602 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2603 fix_emitted = TRUE;
2604 }
2605 else if (op1.am == 1)
2606 {
2607 if (op1.reg == 0)
2608 {
2609 bin |= 0x90;
2610
2611 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2612 BFD_RELOC_MSP430X_PCR20_CALL);
2613 fix_emitted = TRUE;
2614 }
2615 else
2616 bin |= 0x50 | op1.reg;
2617 }
2618 else if (op1.am == 0)
2619 bin |= 0x40 | op1.reg;
2620 }
2621 else if (op1.am == 1)
2622 {
2623 bin |= 0x80;
2624
2625 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2626 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2627 fix_emitted = TRUE;
2628 }
2629 else if (op1.am == 2)
2630 bin |= 0x60 | op1.reg;
2631 else if (op1.am == 3)
2632 bin |= 0x70 | op1.reg;
2633
2634 bfd_putl16 ((bfd_vma) bin, frag);
2635
2636 if (op1.mode == OP_EXP)
2637 {
2638 if (op1.ol != 1)
2639 {
2640 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2641 return 0;
2642 }
2643
2644 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2645
2646 if (! fix_emitted)
2647 fix_new_exp (frag_now, where + 2, 2,
2648 &(op1.exp), FALSE, BFD_RELOC_16);
2649 }
2650
2651 dwarf2_emit_insn (insn_length + op_length);
2652 break;
2653
2654 case 5:
2655 {
2656 int n;
2657 int reg;
2658
2659 /* [POP|PUSH]M[.A] #N, Rd */
2660 line = extract_operand (line, l1, sizeof (l1));
2661 line = extract_operand (line, l2, sizeof (l2));
2662
2663 if (*l1 != '#')
2664 {
2665 as_bad (_("expected #n as first argument of %s"), opcode->name);
2666 return 0;
2667 }
2668 parse_exp (l1 + 1, &(op1.exp));
2669 if (op1.exp.X_op != O_constant)
2670 {
2671 as_bad (_("expected constant expression for first argument of %s"),
2672 opcode->name);
2673 return 0;
2674 }
2675
2676 if ((reg = check_reg (l2)) == -1)
2677 {
2678 as_bad (_("expected register as second argument of %s"),
2679 opcode->name);
2680 return 0;
2681 }
2682
2683 op_length = 2;
2684 frag = frag_more (op_length);
2685 where = frag - frag_now->fr_literal;
2686 bin = opcode->bin_opcode;
2687 if (! addr_op)
2688 bin |= 0x100;
2689 n = op1.exp.X_add_number;
2690 bin |= (n - 1) << 4;
2691 if (is_opcode ("pushm"))
2692 bin |= reg;
2693 else
2694 {
2695 if (reg - n + 1 < 0)
2696 {
2697 as_bad (_("Too many registers popped"));
2698 return 0;
2699 }
2700
2701 /* CPU21 parts cannot use POPM to restore the SR register. */
2702 if (target_is_430xv2 ()
2703 && (reg - n + 1 < 3)
2704 && reg >= 2
2705 && is_opcode ("popm"))
2706 {
2707 as_bad (_("Cannot use POPM to restore the SR register"));
2708 return 0;
2709 }
2710
2711 bin |= (reg - n + 1);
2712 }
2713
2714 bfd_putl16 ((bfd_vma) bin, frag);
2715 dwarf2_emit_insn (op_length);
2716 break;
2717 }
2718
2719 case 6:
2720 {
2721 int n;
2722 int reg;
2723
2724 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2725 if (extended & 0xff)
2726 {
2727 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2728 return 0;
2729 }
2730
2731 line = extract_operand (line, l1, sizeof (l1));
2732 line = extract_operand (line, l2, sizeof (l2));
2733
2734 if (*l1 != '#')
2735 {
2736 as_bad (_("expected #n as first argument of %s"), opcode->name);
2737 return 0;
2738 }
2739 parse_exp (l1 + 1, &(op1.exp));
2740 if (op1.exp.X_op != O_constant)
2741 {
2742 as_bad (_("expected constant expression for first argument of %s"),
2743 opcode->name);
2744 return 0;
2745 }
2746 n = op1.exp.X_add_number;
2747 if (n > 4 || n < 1)
2748 {
2749 as_bad (_("expected first argument of %s to be in the range 1-4"),
2750 opcode->name);
2751 return 0;
2752 }
2753
2754 if ((reg = check_reg (l2)) == -1)
2755 {
2756 as_bad (_("expected register as second argument of %s"),
2757 opcode->name);
2758 return 0;
2759 }
2760
2761 if (target_is_430xv2 () && reg == 0)
2762 {
2763 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2764 return 0;
2765 }
2766
2767 op_length = 2;
2768 frag = frag_more (op_length);
2769 where = frag - frag_now->fr_literal;
2770
2771 bin = opcode->bin_opcode;
2772 if (! addr_op)
2773 bin |= 0x10;
2774 bin |= (n - 1) << 10;
2775 bin |= reg;
2776
2777 bfd_putl16 ((bfd_vma) bin, frag);
2778 dwarf2_emit_insn (op_length);
2779 break;
2780 }
2781
2782 case 7:
2783 {
2784 int reg;
2785
2786 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2787 if (extended & 0xff)
2788 {
2789 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2790 return 0;
2791 }
2792
2793 line = extract_operand (line, l1, sizeof (l1));
2794 if ((reg = check_reg (l1)) == -1)
2795 {
2796 as_bad (_("expected register as argument of %s"),
2797 opcode->name);
2798 return 0;
2799 }
2800
2801 if (target_is_430xv2 () && reg == 0)
2802 {
2803 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2804 return 0;
2805 }
2806
2807 if (byte_op)
2808 {
2809 /* Tricky - there is no single instruction that will do this.
2810 Encode as: RRA.B rN { BIC.B #0x80, rN */
2811 op_length = 6;
2812 frag = frag_more (op_length);
2813 where = frag - frag_now->fr_literal;
2814 bin = 0x1140 | reg;
2815 bfd_putl16 ((bfd_vma) bin, frag);
2816 dwarf2_emit_insn (2);
2817 bin = 0xc070 | reg;
2818 bfd_putl16 ((bfd_vma) bin, frag + 2);
2819 bin = 0x0080;
2820 bfd_putl16 ((bfd_vma) bin, frag + 4);
2821 dwarf2_emit_insn (4);
2822 }
2823 else
2824 {
2825 /* Encode as RRUM[.A] rN. */
2826 bin = opcode->bin_opcode;
2827 if (! addr_op)
2828 bin |= 0x10;
2829 bin |= reg;
2830 op_length = 2;
2831 frag = frag_more (op_length);
2832 where = frag - frag_now->fr_literal;
2833 bfd_putl16 ((bfd_vma) bin, frag);
2834 dwarf2_emit_insn (op_length);
2835 }
2836 break;
2837 }
2838
2839 case 8:
2840 {
2841 bfd_boolean need_reloc = FALSE;
2842 int n;
2843 int reg;
2844
2845 /* ADDA, CMPA and SUBA address instructions. */
2846 if (extended & 0xff)
2847 {
2848 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2849 return 0;
2850 }
2851
2852 line = extract_operand (line, l1, sizeof (l1));
2853 line = extract_operand (line, l2, sizeof (l2));
2854
2855 bin = opcode->bin_opcode;
2856
2857 if (*l1 == '#')
2858 {
2859 parse_exp (l1 + 1, &(op1.exp));
2860
2861 if (op1.exp.X_op == O_constant)
2862 {
2863 n = op1.exp.X_add_number;
2864 if (n > 0xfffff || n < - (0x7ffff))
2865 {
2866 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2867 opcode->name);
2868 return 0;
2869 }
2870
2871 bin |= ((n >> 16) & 0xf) << 8;
2872 }
2873 else
2874 {
2875 n = 0;
2876 need_reloc = TRUE;
2877 }
2878
2879 op_length = 4;
2880 }
2881 else
2882 {
2883 if ((n = check_reg (l1)) == -1)
2884 {
2885 as_bad (_("expected register name or constant as first argument of %s"),
2886 opcode->name);
2887 return 0;
2888 }
2889
2890 bin |= (n << 8) | (1 << 6);
2891 op_length = 2;
2892 }
2893
2894 if ((reg = check_reg (l2)) == -1)
2895 {
2896 as_bad (_("expected register as second argument of %s"),
2897 opcode->name);
2898 return 0;
2899 }
2900
2901 frag = frag_more (op_length);
2902 where = frag - frag_now->fr_literal;
2903 bin |= reg;
2904 if (need_reloc)
2905 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2906 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2907
2908 bfd_putl16 ((bfd_vma) bin, frag);
2909 if (op_length == 4)
2910 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2911 dwarf2_emit_insn (op_length);
2912 break;
2913 }
2914
2915 case 9: /* MOVA, BRA, RETA. */
2916 imm_op = 0;
2917 bin = opcode->bin_opcode;
2918
2919 if (is_opcode ("reta"))
2920 {
2921 /* The RETA instruction does not take any arguments.
2922 The implicit first argument is @SP+.
2923 The implicit second argument is PC. */
2924 op1.mode = OP_REG;
2925 op1.am = 3;
2926 op1.reg = 1;
2927
2928 op2.mode = OP_REG;
2929 op2.reg = 0;
2930 }
2931 else
2932 {
2933 line = extract_operand (line, l1, sizeof (l1));
2934 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2935 &imm_op, extended_op, FALSE);
2936
2937 if (is_opcode ("bra"))
2938 {
2939 /* This is the BRA synthetic instruction.
2940 The second argument is always PC. */
2941 op2.mode = OP_REG;
2942 op2.reg = 0;
2943 }
2944 else
2945 {
2946 line = extract_operand (line, l2, sizeof (l2));
2947 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2948 extended_op, TRUE);
2949 }
2950
2951 if (res)
2952 break; /* Error occurred. All warnings were done before. */
2953 }
2954
2955 /* Only a restricted subset of the normal MSP430 addressing modes
2956 are supported here, so check for the ones that are allowed. */
2957 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2958 & error_message)) == 0)
2959 {
2960 as_bad (error_message, opcode->name);
2961 return 0;
2962 }
2963 dwarf2_emit_insn (op_length);
2964 break;
2965
2966 case 10: /* RPT */
2967 line = extract_operand (line, l1, sizeof l1);
2968 /* The RPT instruction only accepted immediates and registers. */
2969 if (*l1 == '#')
2970 {
2971 parse_exp (l1 + 1, &(op1.exp));
2972 if (op1.exp.X_op != O_constant)
2973 {
2974 as_bad (_("expected constant value as argument to RPT"));
2975 return 0;
2976 }
2977 if (op1.exp.X_add_number < 1
2978 || op1.exp.X_add_number > (1 << 4))
2979 {
2980 as_bad (_("expected constant in the range 2..16"));
2981 return 0;
2982 }
2983
2984 /* We silently accept and ignore a repeat count of 1. */
2985 if (op1.exp.X_add_number > 1)
2986 repeat_count = op1.exp.X_add_number;
2987 }
2988 else
2989 {
2990 int reg;
2991
2992 if ((reg = check_reg (l1)) != -1)
2993 {
2994 if (reg == 0)
2995 as_warn (_("PC used as an argument to RPT"));
2996 else
2997 repeat_count = - reg;
2998 }
2999 else
3000 {
3001 as_bad (_("expected constant or register name as argument to RPT insn"));
3002 return 0;
3003 }
3004 }
3005 break;
3006
3007 default:
3008 as_bad (_("Illegal emulated instruction "));
3009 break;
3010 }
3011 break;
3012
3013 case 1: /* Format 1, double operand. */
3014 line = extract_operand (line, l1, sizeof (l1));
3015 line = extract_operand (line, l2, sizeof (l2));
3016 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3017 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3018
3019 if (res)
3020 break; /* Error occurred. All warnings were done before. */
3021
3022 if (extended_op
3023 && is_opcode ("movx")
3024 && addr_op
3025 && msp430_enable_relax)
3026 {
3027 /* This is the MOVX.A instruction. See if we can convert
3028 it into the MOVA instruction instead. This saves 2 bytes. */
3029 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3030 NULL)) != 0)
3031 {
3032 dwarf2_emit_insn (op_length);
3033 break;
3034 }
3035 }
3036
3037 /* Compute the entire length of the instruction in bytes. */
3038 insn_length =
3039 (extended_op ? 2 : 0) /* The extension word. */
3040 + 2 /* The opcode */
3041 + (2 * op1.ol) /* The first operand. */
3042 + (2 * op2.ol); /* The second operand. */
3043
3044 frag = frag_more (insn_length);
3045 where = frag - frag_now->fr_literal;
3046
3047 if (extended_op)
3048 {
3049 if (!addr_op)
3050 extended |= BYTE_OPERATION;
3051
3052 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3053 {
3054 as_bad (_("repeat instruction used with non-register mode instruction"));
3055 extended &= ~ 0xf;
3056 }
3057
3058 /* If necessary, emit a reloc to update the extension word. */
3059 if (op1.mode == OP_EXP)
3060 {
3061 if (op1.exp.X_op == O_constant)
3062 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3063
3064 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3065 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3066 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3067 else
3068 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3069 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3070 }
3071
3072 if (op2.mode == OP_EXP)
3073 {
3074 if (op2.exp.X_op == O_constant)
3075 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3076
3077 else if (op1.mode == OP_EXP)
3078 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3079 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3080 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3081
3082 else
3083 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3084 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3085 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3086 }
3087
3088 /* Emit the extension word. */
3089 bfd_putl16 (extended, frag);
3090 where += 2;
3091 frag += 2;
3092 }
3093
3094 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3095 bfd_putl16 ((bfd_vma) bin, frag);
3096 where += 2;
3097 frag += 2;
3098
3099 if (op1.mode == OP_EXP)
3100 {
3101 if (op1.exp.X_op == O_constant)
3102 {
3103 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3104 }
3105 else
3106 {
3107 bfd_putl16 ((bfd_vma) ZEROS, frag);
3108
3109 if (!extended_op)
3110 {
3111 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3112 fix_new_exp (frag_now, where, 2,
3113 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3114 else
3115 fix_new_exp (frag_now, where, 2,
3116 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3117 }
3118 }
3119
3120 where += 2;
3121 frag += 2;
3122 }
3123
3124 if (op2.mode == OP_EXP)
3125 {
3126 if (op2.exp.X_op == O_constant)
3127 {
3128 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3129 }
3130 else
3131 {
3132 bfd_putl16 ((bfd_vma) ZEROS, frag);
3133
3134 if (!extended_op)
3135 {
3136 if (op2.reg) /* Not PC relative. */
3137 fix_new_exp (frag_now, where, 2,
3138 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3139 else
3140 fix_new_exp (frag_now, where, 2,
3141 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3142 }
3143 }
3144 }
3145
3146 if (gen_interrupt_nops
3147 && ( (is_opcode ("bic") && bin == 0xc232)
3148 || (is_opcode ("bis") && bin == 0xd232)
3149 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
3150 {
3151 /* Emit a NOP following interrupt enable/disable.
3152 See 1.3.4.1 of the MSP430x5xx User Guide. */
3153 insn_length += 2;
3154 frag = frag_more (2);
3155 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3156 as_warn (_("a NOP instruction has been inserted after %s"),
3157 opcode->name);
3158 }
3159
3160 dwarf2_emit_insn (insn_length);
3161 break;
3162
3163 case 2: /* Single-operand mostly instr. */
3164 if (opcode->insn_opnumb == 0)
3165 {
3166 /* reti instruction. */
3167 insn_length += 2;
3168 frag = frag_more (2);
3169 bfd_putl16 ((bfd_vma) bin, frag);
3170 dwarf2_emit_insn (insn_length);
3171 break;
3172 }
3173
3174 line = extract_operand (line, l1, sizeof (l1));
3175 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3176 &imm_op, extended_op, TRUE);
3177 if (res)
3178 break; /* Error in operand. */
3179
3180 if (target_is_430xv2 ()
3181 && op1.mode == OP_REG
3182 && op1.reg == 0
3183 && (is_opcode ("rrax")
3184 || is_opcode ("rrcx")
3185 || is_opcode ("rra")
3186 || is_opcode ("rrc")))
3187 {
3188 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3189 return 0;
3190 }
3191
3192 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3193 frag = frag_more (insn_length);
3194 where = frag - frag_now->fr_literal;
3195
3196 if (extended_op)
3197 {
3198 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3199 {
3200 /* These two instructions use a special
3201 encoding of the A/L and B/W bits. */
3202 bin &= ~ BYTE_OPERATION;
3203
3204 if (byte_op)
3205 {
3206 as_bad (_("%s instruction does not accept a .b suffix"),
3207 opcode->name);
3208 return 0;
3209 }
3210 else if (! addr_op)
3211 extended |= BYTE_OPERATION;
3212 }
3213 else if (! addr_op)
3214 extended |= BYTE_OPERATION;
3215
3216 if (op1.ol != 0 && ((extended & 0xf) != 0))
3217 {
3218 as_bad (_("repeat instruction used with non-register mode instruction"));
3219 extended &= ~ 0xf;
3220 }
3221
3222 if (op1.mode == OP_EXP)
3223 {
3224 if (op1.exp.X_op == O_constant)
3225 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3226
3227 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3228 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3229 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3230 else
3231 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3232 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3233 }
3234
3235 /* Emit the extension word. */
3236 bfd_putl16 (extended, frag);
3237 frag += 2;
3238 where += 2;
3239 }
3240
3241 bin |= op1.reg | (op1.am << 4);
3242 bfd_putl16 ((bfd_vma) bin, frag);
3243 frag += 2;
3244 where += 2;
3245
3246 if (op1.mode == OP_EXP)
3247 {
3248 if (op1.exp.X_op == O_constant)
3249 {
3250 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3251 }
3252 else
3253 {
3254 bfd_putl16 ((bfd_vma) ZEROS, frag);
3255
3256 if (!extended_op)
3257 {
3258 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3259 fix_new_exp (frag_now, where, 2,
3260 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3261 else
3262 fix_new_exp (frag_now, where, 2,
3263 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3264 }
3265 }
3266 }
3267
3268 dwarf2_emit_insn (insn_length);
3269 break;
3270
3271 case 3: /* Conditional jumps instructions. */
3272 line = extract_operand (line, l1, sizeof (l1));
3273 /* l1 is a label. */
3274 if (l1[0])
3275 {
3276 char *m = l1;
3277 expressionS exp;
3278
3279 if (*m == '$')
3280 m++;
3281
3282 parse_exp (m, &exp);
3283
3284 /* In order to handle something like:
3285
3286 and #0x8000, r5
3287 tst r5
3288 jz 4 ; skip next 4 bytes
3289 inv r5
3290 inc r5
3291 nop ; will jump here if r5 positive or zero
3292
3293 jCOND -n ;assumes jump n bytes backward:
3294
3295 mov r5,r6
3296 jmp -2
3297
3298 is equal to:
3299 lab:
3300 mov r5,r6
3301 jmp lab
3302
3303 jCOND $n ; jump from PC in either direction. */
3304
3305 if (exp.X_op == O_constant)
3306 {
3307 int x = exp.X_add_number;
3308
3309 if (x & 1)
3310 {
3311 as_warn (_("Even number required. Rounded to %d"), x + 1);
3312 x++;
3313 }
3314
3315 if ((*l1 == '$' && x > 0) || x < 0)
3316 x -= 2;
3317
3318 x >>= 1;
3319
3320 if (x > 512 || x < -511)
3321 {
3322 as_bad (_("Wrong displacement %d"), x << 1);
3323 break;
3324 }
3325
3326 insn_length += 2;
3327 frag = frag_more (2); /* Instr size is 1 word. */
3328
3329 bin |= x & 0x3ff;
3330 bfd_putl16 ((bfd_vma) bin, frag);
3331 }
3332 else if (exp.X_op == O_symbol && *l1 != '$')
3333 {
3334 insn_length += 2;
3335 frag = frag_more (2); /* Instr size is 1 word. */
3336 where = frag - frag_now->fr_literal;
3337 fix_new_exp (frag_now, where, 2,
3338 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3339
3340 bfd_putl16 ((bfd_vma) bin, frag);
3341 }
3342 else if (*l1 == '$')
3343 {
3344 as_bad (_("instruction requires label sans '$'"));
3345 }
3346 else
3347 as_bad (_
3348 ("instruction requires label or value in range -511:512"));
3349 dwarf2_emit_insn (insn_length);
3350 break;
3351 }
3352 else
3353 {
3354 as_bad (_("instruction requires label"));
3355 break;
3356 }
3357 break;
3358
3359 case 4: /* Extended jumps. */
3360 if (!msp430_enable_polys)
3361 {
3362 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3363 break;
3364 }
3365
3366 line = extract_operand (line, l1, sizeof (l1));
3367 if (l1[0])
3368 {
3369 char *m = l1;
3370 expressionS exp;
3371
3372 /* Ignore absolute addressing. make it PC relative anyway. */
3373 if (*m == '#' || *m == '$')
3374 m++;
3375
3376 parse_exp (m, & exp);
3377 if (exp.X_op == O_symbol)
3378 {
3379 /* Relaxation required. */
3380 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3381
3382 if (target_is_430x ())
3383 rc = msp430x_rcodes[opcode->insn_opnumb];
3384
3385 /* The parameter to dwarf2_emit_insn is actually the offset to
3386 the start of the insn from the fix piece of instruction that
3387 was emitted. Since next fragments may have variable size we
3388 tie debug info to the beginning of the instruction. */
3389 insn_length += 8;
3390 frag = frag_more (8);
3391 dwarf2_emit_insn (0);
3392 bfd_putl16 ((bfd_vma) rc.sop, frag);
3393 frag = frag_variant (rs_machine_dependent, 8, 2,
3394 /* Wild guess. */
3395 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3396 exp.X_add_symbol,
3397 0, /* Offset is zero if jump dist less than 1K. */
3398 (char *) frag);
3399 break;
3400 }
3401 }
3402
3403 as_bad (_("instruction requires label"));
3404 break;
3405
3406 case 5: /* Emulated extended branches. */
3407 if (!msp430_enable_polys)
3408 {
3409 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3410 break;
3411 }
3412 line = extract_operand (line, l1, sizeof (l1));
3413 if (l1[0])
3414 {
3415 char * m = l1;
3416 expressionS exp;
3417
3418 /* Ignore absolute addressing. make it PC relative anyway. */
3419 if (*m == '#' || *m == '$')
3420 m++;
3421
3422 parse_exp (m, & exp);
3423 if (exp.X_op == O_symbol)
3424 {
3425 /* Relaxation required. */
3426 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3427
3428 if (target_is_430x ())
3429 hc = msp430x_hcodes[opcode->insn_opnumb];
3430
3431 insn_length += 8;
3432 frag = frag_more (8);
3433 dwarf2_emit_insn (0);
3434 bfd_putl16 ((bfd_vma) hc.op0, frag);
3435 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3436
3437 frag = frag_variant (rs_machine_dependent, 8, 2,
3438 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3439 exp.X_add_symbol,
3440 0, /* Offset is zero if jump dist less than 1K. */
3441 (char *) frag);
3442 break;
3443 }
3444 }
3445
3446 as_bad (_("instruction requires label"));
3447 break;
3448
3449 default:
3450 as_bad (_("Illegal instruction or not implemented opcode."));
3451 }
3452
3453 input_line_pointer = line;
3454 return 0;
3455 }
3456
3457 void
3458 md_assemble (char * str)
3459 {
3460 struct msp430_opcode_s * opcode;
3461 char cmd[32];
3462 unsigned int i = 0;
3463
3464 str = skip_space (str); /* Skip leading spaces. */
3465 str = extract_cmd (str, cmd, sizeof (cmd));
3466
3467 while (cmd[i] && i < sizeof (cmd))
3468 {
3469 char a = TOLOWER (cmd[i]);
3470 cmd[i] = a;
3471 i++;
3472 }
3473
3474 if (!cmd[0])
3475 {
3476 as_bad (_("can't find opcode "));
3477 return;
3478 }
3479
3480 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3481
3482 if (opcode == NULL)
3483 {
3484 as_bad (_("unknown opcode `%s'"), cmd);
3485 return;
3486 }
3487
3488 {
3489 char *__t = input_line_pointer;
3490
3491 msp430_operands (opcode, str);
3492 input_line_pointer = __t;
3493 }
3494 }
3495
3496 /* GAS will call this function for each section at the end of the assembly,
3497 to permit the CPU backend to adjust the alignment of a section. */
3498
3499 valueT
3500 md_section_align (asection * seg, valueT addr)
3501 {
3502 int align = bfd_get_section_alignment (stdoutput, seg);
3503
3504 return ((addr + (1 << align) - 1) & (-1 << align));
3505 }
3506
3507 /* If you define this macro, it should return the offset between the
3508 address of a PC relative fixup and the position from which the PC
3509 relative adjustment should be made. On many processors, the base
3510 of a PC relative instruction is the next instruction, so this
3511 macro would return the length of an instruction. */
3512
3513 long
3514 md_pcrel_from_section (fixS * fixp, segT sec)
3515 {
3516 if (fixp->fx_addsy != (symbolS *) NULL
3517 && (!S_IS_DEFINED (fixp->fx_addsy)
3518 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3519 return 0;
3520
3521 return fixp->fx_frag->fr_address + fixp->fx_where;
3522 }
3523
3524 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3525 Now it handles the situation when relocations
3526 have to be passed to linker. */
3527 int
3528 msp430_force_relocation_local (fixS *fixp)
3529 {
3530 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3531 return 1;
3532 if (fixp->fx_pcrel)
3533 return 1;
3534 if (msp430_enable_polys
3535 && !msp430_enable_relax)
3536 return 1;
3537
3538 return (!fixp->fx_pcrel
3539 || generic_force_reloc (fixp));
3540 }
3541
3542
3543 /* GAS will call this for each fixup. It should store the correct
3544 value in the object file. */
3545 void
3546 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3547 {
3548 unsigned char * where;
3549 unsigned long insn;
3550 long value;
3551
3552 if (fixp->fx_addsy == (symbolS *) NULL)
3553 {
3554 value = *valuep;
3555 fixp->fx_done = 1;
3556 }
3557 else if (fixp->fx_pcrel)
3558 {
3559 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3560
3561 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3562 {
3563 /* FIXME: We can appear here only in case if we perform a pc
3564 relative jump to the label which is i) global, ii) locally
3565 defined or this is a jump to an absolute symbol.
3566 If this is an absolute symbol -- everything is OK.
3567 If this is a global label, we've got a symbol value defined
3568 twice:
3569 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3570 from this section start
3571 2. *valuep will contain the real offset from jump insn to the
3572 label
3573 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3574 will be incorrect. Therefore remove s_get_value. */
3575 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3576 fixp->fx_done = 1;
3577 }
3578 else
3579 value = *valuep;
3580 }
3581 else
3582 {
3583 value = fixp->fx_offset;
3584
3585 if (fixp->fx_subsy != (symbolS *) NULL)
3586 {
3587 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3588 {
3589 value -= S_GET_VALUE (fixp->fx_subsy);
3590 fixp->fx_done = 1;
3591 }
3592 }
3593 }
3594
3595 fixp->fx_no_overflow = 1;
3596
3597 /* If polymorphs are enabled and relax disabled.
3598 do not kill any relocs and pass them to linker. */
3599 if (msp430_enable_polys
3600 && !msp430_enable_relax)
3601 {
3602 if (!fixp->fx_addsy || (fixp->fx_addsy
3603 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
3604 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3605 else
3606 fixp->fx_done = 0;
3607 }
3608
3609 if (fixp->fx_done)
3610 {
3611 /* Fetch the instruction, insert the fully resolved operand
3612 value, and stuff the instruction back again. */
3613 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3614
3615 insn = bfd_getl16 (where);
3616
3617 switch (fixp->fx_r_type)
3618 {
3619 case BFD_RELOC_MSP430_10_PCREL:
3620 if (value & 1)
3621 as_bad_where (fixp->fx_file, fixp->fx_line,
3622 _("odd address operand: %ld"), value);
3623
3624 /* Jumps are in words. */
3625 value >>= 1;
3626 --value; /* Correct PC. */
3627
3628 if (value < -512 || value > 511)
3629 as_bad_where (fixp->fx_file, fixp->fx_line,
3630 _("operand out of range: %ld"), value);
3631
3632 value &= 0x3ff; /* get rid of extended sign */
3633 bfd_putl16 ((bfd_vma) (value | insn), where);
3634 break;
3635
3636 case BFD_RELOC_MSP430X_PCR16:
3637 case BFD_RELOC_MSP430_RL_PCREL:
3638 case BFD_RELOC_MSP430_16_PCREL:
3639 if (value & 1)
3640 as_bad_where (fixp->fx_file, fixp->fx_line,
3641 _("odd address operand: %ld"), value);
3642 /* Fall through. */
3643
3644 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3645 /* Nothing to be corrected here. */
3646 if (value < -32768 || value > 65536)
3647 as_bad_where (fixp->fx_file, fixp->fx_line,
3648 _("operand out of range: %ld"), value);
3649 /* Fall through. */
3650
3651 case BFD_RELOC_MSP430X_ABS16:
3652 case BFD_RELOC_MSP430_16:
3653 case BFD_RELOC_16:
3654 case BFD_RELOC_MSP430_16_BYTE:
3655 value &= 0xffff; /* Get rid of extended sign. */
3656 bfd_putl16 ((bfd_vma) value, where);
3657 break;
3658
3659 case BFD_RELOC_32:
3660 bfd_putl16 ((bfd_vma) value, where);
3661 break;
3662
3663 case BFD_RELOC_MSP430_ABS8:
3664 case BFD_RELOC_8:
3665 bfd_put_8 (NULL, (bfd_vma) value, where);
3666 break;
3667
3668 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3669 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3670 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3671 value >>= 16;
3672 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3673 break;
3674
3675 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3676 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3677 value >>= 16;
3678 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3679 break;
3680
3681 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3682 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3683 value >>= 16;
3684 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3685 break;
3686
3687 case BFD_RELOC_MSP430X_PCR20_CALL:
3688 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3689 value >>= 16;
3690 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3691 break;
3692
3693 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3694 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3695 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3696 value >>= 16;
3697 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3698 break;
3699
3700 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3701 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3702 value >>= 16;
3703 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3704 break;
3705
3706 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3707 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3708 value >>= 16;
3709 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3710 break;
3711
3712 default:
3713 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3714 fixp->fx_line, fixp->fx_r_type);
3715 break;
3716 }
3717 }
3718 else
3719 {
3720 fixp->fx_addnumber = value;
3721 }
3722 }
3723
3724 static bfd_boolean
3725 S_IS_GAS_LOCAL (symbolS * s)
3726 {
3727 const char * name;
3728 unsigned int len;
3729
3730 if (s == NULL)
3731 return FALSE;
3732 name = S_GET_NAME (s);
3733 len = strlen (name) - 1;
3734
3735 return name[len] == 1 || name[len] == 2;
3736 }
3737
3738 /* GAS will call this to generate a reloc, passing the resulting reloc
3739 to `bfd_install_relocation'. This currently works poorly, as
3740 `bfd_install_relocation' often does the wrong thing, and instances of
3741 `tc_gen_reloc' have been written to work around the problems, which
3742 in turns makes it difficult to fix `bfd_install_relocation'. */
3743
3744 /* If while processing a fixup, a reloc really needs to be created
3745 then it is done here. */
3746
3747 arelent **
3748 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
3749 {
3750 static arelent * no_relocs = NULL;
3751 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3752 arelent *reloc;
3753
3754 reloc = xmalloc (sizeof (arelent));
3755 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3756 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3757
3758 if (reloc->howto == (reloc_howto_type *) NULL)
3759 {
3760 as_bad_where (fixp->fx_file, fixp->fx_line,
3761 _("reloc %d not supported by object file format"),
3762 (int) fixp->fx_r_type);
3763 free (reloc);
3764 return & no_relocs;
3765 }
3766
3767 relocs[0] = reloc;
3768 relocs[1] = NULL;
3769
3770 if (fixp->fx_subsy
3771 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3772 {
3773 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3774 fixp->fx_subsy = NULL;
3775 }
3776
3777 if (fixp->fx_addsy && fixp->fx_subsy)
3778 {
3779 asection *asec, *ssec;
3780
3781 asec = S_GET_SEGMENT (fixp->fx_addsy);
3782 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3783
3784 /* If we have a difference between two different, non-absolute symbols
3785 we must generate two relocs (one for each symbol) and allow the
3786 linker to resolve them - relaxation may change the distances between
3787 symbols, even local symbols defined in the same section.
3788
3789 Unfortunately we cannot do this with assembler generated local labels
3790 because there can be multiple incarnations of the same label, with
3791 exactly the same name, in any given section and the linker will have
3792 no way to identify the correct one. Instead we just have to hope
3793 that no relaxtion will occur between the local label and the other
3794 symbol in the expression.
3795
3796 Similarly we have to compute differences between symbols in the .eh_frame
3797 section as the linker is not smart enough to apply relocations there
3798 before attempting to process it. */
3799 if ((ssec != absolute_section || asec != absolute_section)
3800 && (fixp->fx_addsy != fixp->fx_subsy)
3801 && strcmp (ssec->name, ".eh_frame") != 0
3802 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3803 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3804 {
3805 arelent * reloc2 = xmalloc (sizeof * reloc);
3806
3807 relocs[0] = reloc2;
3808 relocs[1] = reloc;
3809
3810 reloc2->address = reloc->address;
3811 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3812 BFD_RELOC_MSP430_SYM_DIFF);
3813 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3814
3815 if (ssec == absolute_section)
3816 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3817 else
3818 {
3819 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3820 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3821 }
3822
3823 reloc->addend = fixp->fx_offset;
3824 if (asec == absolute_section)
3825 {
3826 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3827 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3828 }
3829 else
3830 {
3831 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3832 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3833 }
3834
3835 fixp->fx_pcrel = 0;
3836 fixp->fx_done = 1;
3837 return relocs;
3838 }
3839 else
3840 {
3841 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3842
3843 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3844 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3845
3846 switch (fixp->fx_r_type)
3847 {
3848 case BFD_RELOC_8:
3849 md_number_to_chars (fixpos, reloc->addend, 1);
3850 break;
3851
3852 case BFD_RELOC_16:
3853 md_number_to_chars (fixpos, reloc->addend, 2);
3854 break;
3855
3856 case BFD_RELOC_24:
3857 md_number_to_chars (fixpos, reloc->addend, 3);
3858 break;
3859
3860 case BFD_RELOC_32:
3861 md_number_to_chars (fixpos, reloc->addend, 4);
3862 break;
3863
3864 default:
3865 reloc->sym_ptr_ptr
3866 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3867 return relocs;
3868 }
3869
3870 free (reloc);
3871 return & no_relocs;
3872 }
3873 }
3874 else
3875 {
3876 #if 0
3877 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3878 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3879 {
3880 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3881 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3882
3883 md_number_to_chars (fixpos, amount, 2);
3884 free (reloc);
3885 return & no_relocs;
3886 }
3887 #endif
3888 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3889 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3890 reloc->addend = fixp->fx_offset;
3891
3892 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3893 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3894 reloc->address = fixp->fx_offset;
3895 }
3896
3897 return relocs;
3898 }
3899
3900 int
3901 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3902 asection * segment_type ATTRIBUTE_UNUSED)
3903 {
3904 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3905 {
3906 /* This is a jump -> pcrel mode. Nothing to do much here.
3907 Return value == 2. */
3908 fragP->fr_subtype =
3909 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3910 }
3911 else if (fragP->fr_symbol)
3912 {
3913 /* Its got a segment, but its not ours. Even if fr_symbol is in
3914 an absolute segment, we don't know a displacement until we link
3915 object files. So it will always be long. This also applies to
3916 labels in a subsegment of current. Liker may relax it to short
3917 jump later. Return value == 8. */
3918 fragP->fr_subtype =
3919 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3920 }
3921 else
3922 {
3923 /* We know the abs value. may be it is a jump to fixed address.
3924 Impossible in our case, cause all constants already handled. */
3925 fragP->fr_subtype =
3926 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3927 }
3928
3929 return md_relax_table[fragP->fr_subtype].rlx_length;
3930 }
3931
3932 void
3933 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3934 asection * sec ATTRIBUTE_UNUSED,
3935 fragS * fragP)
3936 {
3937 char * where = 0;
3938 int rela = -1;
3939 int i;
3940 struct rcodes_s * cc = NULL;
3941 struct hcodes_s * hc = NULL;
3942
3943 switch (fragP->fr_subtype)
3944 {
3945 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3946 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3947 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3948 /* We do not have to convert anything here.
3949 Just apply a fix. */
3950 rela = BFD_RELOC_MSP430_10_PCREL;
3951 break;
3952
3953 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3954 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3955 /* Convert uncond branch jmp lab -> br lab. */
3956 if (target_is_430x ())
3957 cc = msp430x_rcodes + 7;
3958 else
3959 cc = msp430_rcodes + 7;
3960 where = fragP->fr_literal + fragP->fr_fix;
3961 bfd_putl16 (cc->lop0, where);
3962 rela = BFD_RELOC_MSP430_RL_PCREL;
3963 fragP->fr_fix += 2;
3964 break;
3965
3966 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3967 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3968 {
3969 /* Other simple branches. */
3970 int insn = bfd_getl16 (fragP->fr_opcode);
3971
3972 insn &= 0xffff;
3973 /* Find actual instruction. */
3974 if (target_is_430x ())
3975 {
3976 for (i = 0; i < 7 && !cc; i++)
3977 if (msp430x_rcodes[i].sop == insn)
3978 cc = msp430x_rcodes + i;
3979 }
3980 else
3981 {
3982 for (i = 0; i < 7 && !cc; i++)
3983 if (msp430_rcodes[i].sop == insn)
3984 cc = & msp430_rcodes[i];
3985 }
3986
3987 if (!cc || !cc->name)
3988 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3989 __FUNCTION__, (long) insn);
3990 where = fragP->fr_literal + fragP->fr_fix;
3991 bfd_putl16 (cc->lop0, where);
3992 bfd_putl16 (cc->lop1, where + 2);
3993 rela = BFD_RELOC_MSP430_RL_PCREL;
3994 fragP->fr_fix += 4;
3995 }
3996 break;
3997
3998 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3999 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
4000 if (target_is_430x ())
4001 cc = msp430x_rcodes + 6;
4002 else
4003 cc = msp430_rcodes + 6;
4004 where = fragP->fr_literal + fragP->fr_fix;
4005 bfd_putl16 (cc->lop0, where);
4006 bfd_putl16 (cc->lop1, where + 2);
4007 bfd_putl16 (cc->lop2, where + 4);
4008 rela = BFD_RELOC_MSP430_RL_PCREL;
4009 fragP->fr_fix += 6;
4010 break;
4011
4012 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4013 {
4014 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4015
4016 insn &= 0xffff;
4017 if (target_is_430x ())
4018 {
4019 for (i = 0; i < 4 && !hc; i++)
4020 if (msp430x_hcodes[i].op1 == insn)
4021 hc = msp430x_hcodes + i;
4022 }
4023 else
4024 {
4025 for (i = 0; i < 4 && !hc; i++)
4026 if (msp430_hcodes[i].op1 == insn)
4027 hc = &msp430_hcodes[i];
4028 }
4029 if (!hc || !hc->name)
4030 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4031 __FUNCTION__, (long) insn);
4032 rela = BFD_RELOC_MSP430_10_PCREL;
4033 /* Apply a fix for a first label if necessary.
4034 another fix will be applied to the next word of insn anyway. */
4035 if (hc->tlab == 2)
4036 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4037 fragP->fr_offset, TRUE, rela);
4038 fragP->fr_fix += 2;
4039 }
4040
4041 break;
4042
4043 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4044 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4045 {
4046 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4047
4048 insn &= 0xffff;
4049 if (target_is_430x ())
4050 {
4051 for (i = 0; i < 4 && !hc; i++)
4052 if (msp430x_hcodes[i].op1 == insn)
4053 hc = msp430x_hcodes + i;
4054 }
4055 else
4056 {
4057 for (i = 0; i < 4 && !hc; i++)
4058 if (msp430_hcodes[i].op1 == insn)
4059 hc = & msp430_hcodes[i];
4060 }
4061 if (!hc || !hc->name)
4062 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4063 __FUNCTION__, (long) insn);
4064 rela = BFD_RELOC_MSP430_RL_PCREL;
4065 where = fragP->fr_literal + fragP->fr_fix;
4066 bfd_putl16 (hc->lop0, where);
4067 bfd_putl16 (hc->lop1, where + 2);
4068 bfd_putl16 (hc->lop2, where + 4);
4069 fragP->fr_fix += 6;
4070 }
4071 break;
4072
4073 default:
4074 as_fatal (_("internal inconsistency problem in %s: %lx"),
4075 __FUNCTION__, (long) fragP->fr_subtype);
4076 break;
4077 }
4078
4079 /* Now apply fix. */
4080 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4081 fragP->fr_offset, TRUE, rela);
4082 /* Just fixed 2 bytes. */
4083 fragP->fr_fix += 2;
4084 }
4085
4086 /* Relax fragment. Mostly stolen from hc11 and mcore
4087 which arches I think I know. */
4088
4089 long
4090 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4091 long stretch ATTRIBUTE_UNUSED)
4092 {
4093 long growth;
4094 offsetT aim = 0;
4095 symbolS *symbolP;
4096 const relax_typeS *this_type;
4097 const relax_typeS *start_type;
4098 relax_substateT next_state;
4099 relax_substateT this_state;
4100 const relax_typeS *table = md_relax_table;
4101
4102 /* Nothing to be done if the frag has already max size. */
4103 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4104 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4105 return 0;
4106
4107 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4108 {
4109 symbolP = fragP->fr_symbol;
4110 if (symbol_resolved_p (symbolP))
4111 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4112 __FUNCTION__);
4113 /* We know the offset. calculate a distance. */
4114 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4115 }
4116
4117 if (!msp430_enable_relax)
4118 {
4119 /* Relaxation is not enabled. So, make all jump as long ones
4120 by setting 'aim' to quite high value. */
4121 aim = 0x7fff;
4122 }
4123
4124 this_state = fragP->fr_subtype;
4125 start_type = this_type = table + this_state;
4126
4127 if (aim < 0)
4128 {
4129 /* Look backwards. */
4130 for (next_state = this_type->rlx_more; next_state;)
4131 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4132 next_state = 0;
4133 else
4134 {
4135 /* Grow to next state. */
4136 this_state = next_state;
4137 this_type = table + this_state;
4138 next_state = this_type->rlx_more;
4139 }
4140 }
4141 else
4142 {
4143 /* Look forwards. */
4144 for (next_state = this_type->rlx_more; next_state;)
4145 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4146 next_state = 0;
4147 else
4148 {
4149 /* Grow to next state. */
4150 this_state = next_state;
4151 this_type = table + this_state;
4152 next_state = this_type->rlx_more;
4153 }
4154 }
4155
4156 growth = this_type->rlx_length - start_type->rlx_length;
4157 if (growth != 0)
4158 fragP->fr_subtype = this_state;
4159 return growth;
4160 }
4161
4162 /* Return FALSE if the fixup in fixp should be left alone and not
4163 adjusted. We return FALSE here so that linker relaxation will
4164 work. */
4165
4166 bfd_boolean
4167 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4168 {
4169 /* If the symbol is in a non-code section then it should be OK. */
4170 if (fixp->fx_addsy
4171 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4172 return TRUE;
4173
4174 return FALSE;
4175 }
4176
4177 /* Set the contents of the .MSP430.attributes section. */
4178
4179 void
4180 msp430_md_end (void)
4181 {
4182 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4183 target_is_430x () ? 2 : 1);
4184
4185 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4186 large_model ? 2 : 1);
4187
4188 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4189 large_model ? 2 : 1);
4190 }
4191
4192 /* Returns FALSE if there is a msp430 specific reason why the
4193 subtraction of two same-section symbols cannot be computed by
4194 the assembler. */
4195
4196 bfd_boolean
4197 msp430_allow_local_subtract (expressionS * left,
4198 expressionS * right,
4199 segT section)
4200 {
4201 /* If the symbols are not in a code section then they are OK. */
4202 if ((section->flags & SEC_CODE) == 0)
4203 return TRUE;
4204
4205 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4206 return TRUE;
4207
4208 if (left->X_add_symbol == right->X_add_symbol)
4209 return TRUE;
4210
4211 /* We have to assume that there may be instructions between the
4212 two symbols and that relaxation may increase the distance between
4213 them. */
4214 return FALSE;
4215 }
This page took 0.123534 seconds and 4 git commands to generate.