1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2013 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
25 #define PUSH_1X_WORKAROUND
27 #include "opcode/msp430.h"
28 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
30 #include "elf/msp430.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
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.
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.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax
;
70 int msp430_enable_polys
;
72 /* Set linkrelax here to avoid fixups in most sections. */
75 /* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
86 lt < jl jge +4; br lab
87 ltu < jlo lhs +4; br lab
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
99 'u' means unsigned compares
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
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. */
117 #define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
120 static struct rcodes_s msp430_rcodes
[] =
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},
134 #define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
137 static struct rcodes_s msp430x_rcodes
[] =
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},
151 /* More difficult than above and they have format 5.
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 ================================================================= */
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. */
173 static struct hcodes_s msp430_hcodes
[] =
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 },
182 static struct hcodes_s msp430x_hcodes
[] =
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 },
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";
197 /* Handle long expressions. */
198 extern LITTLENUM_TYPE generic_bignum
[];
200 static struct hash_control
*msp430_hash
;
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
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 */
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)
224 relax_typeS md_relax_table
[] =
232 /* Unconditional jump. */
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 */
238 /* Simple branches. */
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 */
244 /* blt no overflow branch. */
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 */
250 /* Emulated branches. */
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 */
258 #define MAX_OP_LEN 256
273 static struct mcu_type_s mcu_types
[] =
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
},
488 {"msp430cg4616", MSP_ISA_430X
},
489 {"msp430cg4617", MSP_ISA_430X
},
490 {"msp430cg4618", MSP_ISA_430X
},
491 {"msp430cg4619", MSP_ISA_430X
},
492 {"msp430f2416", MSP_ISA_430X
},
493 {"msp430f2417", MSP_ISA_430X
},
494 {"msp430f2418", MSP_ISA_430X
},
495 {"msp430f2419", MSP_ISA_430X
},
496 {"msp430f2616", MSP_ISA_430X
},
497 {"msp430f2617", MSP_ISA_430X
},
498 {"msp430f2618", MSP_ISA_430X
},
499 {"msp430f2619", MSP_ISA_430X
},
500 {"msp430f47126", MSP_ISA_430X
},
501 {"msp430f47127", MSP_ISA_430X
},
502 {"msp430f47163", MSP_ISA_430X
},
503 {"msp430f47173", MSP_ISA_430X
},
504 {"msp430f47183", MSP_ISA_430X
},
505 {"msp430f47193", MSP_ISA_430X
},
506 {"msp430f47166", MSP_ISA_430X
},
507 {"msp430f47176", MSP_ISA_430X
},
508 {"msp430f47186", MSP_ISA_430X
},
509 {"msp430f47196", MSP_ISA_430X
},
510 {"msp430f47167", MSP_ISA_430X
},
511 {"msp430f47177", MSP_ISA_430X
},
512 {"msp430f47187", MSP_ISA_430X
},
513 {"msp430f47197", MSP_ISA_430X
},
514 {"msp430f46161", MSP_ISA_430X
},
515 {"msp430f46171", MSP_ISA_430X
},
516 {"msp430f46181", MSP_ISA_430X
},
517 {"msp430f46191", MSP_ISA_430X
},
518 {"msp430f4616", MSP_ISA_430X
},
519 {"msp430f4617", MSP_ISA_430X
},
520 {"msp430f4618", MSP_ISA_430X
},
521 {"msp430f4619", MSP_ISA_430X
},
522 {"msp430fg4616", MSP_ISA_430X
},
523 {"msp430fg4617", MSP_ISA_430X
},
524 {"msp430fg4618", MSP_ISA_430X
},
525 {"msp430fg4619", MSP_ISA_430X
},
527 {"msp430f5418", MSP_ISA_430Xv2
},
528 {"msp430f5419", MSP_ISA_430Xv2
},
529 {"msp430f5435", MSP_ISA_430Xv2
},
530 {"msp430f5436", MSP_ISA_430Xv2
},
531 {"msp430f5437", MSP_ISA_430Xv2
},
532 {"msp430f5438", MSP_ISA_430Xv2
},
533 {"msp430f5418a", MSP_ISA_430Xv2
},
534 {"msp430f5419a", MSP_ISA_430Xv2
},
535 {"msp430f5435a", MSP_ISA_430Xv2
},
536 {"msp430f5436a", MSP_ISA_430Xv2
},
537 {"msp430f5437a", MSP_ISA_430Xv2
},
538 {"msp430f5438a", MSP_ISA_430Xv2
},
539 {"msp430f5212", MSP_ISA_430Xv2
},
540 {"msp430f5213", MSP_ISA_430Xv2
},
541 {"msp430f5214", MSP_ISA_430Xv2
},
542 {"msp430f5217", MSP_ISA_430Xv2
},
543 {"msp430f5218", MSP_ISA_430Xv2
},
544 {"msp430f5219", MSP_ISA_430Xv2
},
545 {"msp430f5222", MSP_ISA_430Xv2
},
546 {"msp430f5223", MSP_ISA_430Xv2
},
547 {"msp430f5224", MSP_ISA_430Xv2
},
548 {"msp430f5227", MSP_ISA_430Xv2
},
549 {"msp430f5228", MSP_ISA_430Xv2
},
550 {"msp430f5229", MSP_ISA_430Xv2
},
551 {"msp430f5304", MSP_ISA_430Xv2
},
552 {"msp430f5308", MSP_ISA_430Xv2
},
553 {"msp430f5309", MSP_ISA_430Xv2
},
554 {"msp430f5310", MSP_ISA_430Xv2
},
555 {"msp430f5340", MSP_ISA_430Xv2
},
556 {"msp430f5341", MSP_ISA_430Xv2
},
557 {"msp430f5342", MSP_ISA_430Xv2
},
558 {"msp430f5324", MSP_ISA_430Xv2
},
559 {"msp430f5325", MSP_ISA_430Xv2
},
560 {"msp430f5326", MSP_ISA_430Xv2
},
561 {"msp430f5327", MSP_ISA_430Xv2
},
562 {"msp430f5328", MSP_ISA_430Xv2
},
563 {"msp430f5329", MSP_ISA_430Xv2
},
564 {"msp430f5500", MSP_ISA_430Xv2
},
565 {"msp430f5501", MSP_ISA_430Xv2
},
566 {"msp430f5502", MSP_ISA_430Xv2
},
567 {"msp430f5503", MSP_ISA_430Xv2
},
568 {"msp430f5504", MSP_ISA_430Xv2
},
569 {"msp430f5505", MSP_ISA_430Xv2
},
570 {"msp430f5506", MSP_ISA_430Xv2
},
571 {"msp430f5507", MSP_ISA_430Xv2
},
572 {"msp430f5508", MSP_ISA_430Xv2
},
573 {"msp430f5509", MSP_ISA_430Xv2
},
574 {"msp430f5510", MSP_ISA_430Xv2
},
575 {"msp430f5513", MSP_ISA_430Xv2
},
576 {"msp430f5514", MSP_ISA_430Xv2
},
577 {"msp430f5515", MSP_ISA_430Xv2
},
578 {"msp430f5517", MSP_ISA_430Xv2
},
579 {"msp430f5519", MSP_ISA_430Xv2
},
580 {"msp430f5521", MSP_ISA_430Xv2
},
581 {"msp430f5522", MSP_ISA_430Xv2
},
582 {"msp430f5524", MSP_ISA_430Xv2
},
583 {"msp430f5525", MSP_ISA_430Xv2
},
584 {"msp430f5526", MSP_ISA_430Xv2
},
585 {"msp430f5527", MSP_ISA_430Xv2
},
586 {"msp430f5528", MSP_ISA_430Xv2
},
587 {"msp430f5529", MSP_ISA_430Xv2
},
588 {"cc430f5133", MSP_ISA_430Xv2
},
589 {"cc430f5135", MSP_ISA_430Xv2
},
590 {"cc430f5137", MSP_ISA_430Xv2
},
591 {"cc430f6125", MSP_ISA_430Xv2
},
592 {"cc430f6126", MSP_ISA_430Xv2
},
593 {"cc430f6127", MSP_ISA_430Xv2
},
594 {"cc430f6135", MSP_ISA_430Xv2
},
595 {"cc430f6137", MSP_ISA_430Xv2
},
596 {"cc430f5123", MSP_ISA_430Xv2
},
597 {"cc430f5125", MSP_ISA_430Xv2
},
598 {"cc430f5143", MSP_ISA_430Xv2
},
599 {"cc430f5145", MSP_ISA_430Xv2
},
600 {"cc430f5147", MSP_ISA_430Xv2
},
601 {"cc430f6143", MSP_ISA_430Xv2
},
602 {"cc430f6145", MSP_ISA_430Xv2
},
603 {"cc430f6147", MSP_ISA_430Xv2
},
604 {"msp430f5333", MSP_ISA_430Xv2
},
605 {"msp430f5335", MSP_ISA_430Xv2
},
606 {"msp430f5336", MSP_ISA_430Xv2
},
607 {"msp430f5338", MSP_ISA_430Xv2
},
608 {"msp430f5630", MSP_ISA_430Xv2
},
609 {"msp430f5631", MSP_ISA_430Xv2
},
610 {"msp430f5632", MSP_ISA_430Xv2
},
611 {"msp430f5633", MSP_ISA_430Xv2
},
612 {"msp430f5634", MSP_ISA_430Xv2
},
613 {"msp430f5635", MSP_ISA_430Xv2
},
614 {"msp430f5636", MSP_ISA_430Xv2
},
615 {"msp430f5637", MSP_ISA_430Xv2
},
616 {"msp430f5638", MSP_ISA_430Xv2
},
617 {"msp430f6433", MSP_ISA_430Xv2
},
618 {"msp430f6435", MSP_ISA_430Xv2
},
619 {"msp430f6436", MSP_ISA_430Xv2
},
620 {"msp430f6438", MSP_ISA_430Xv2
},
621 {"msp430f6630", MSP_ISA_430Xv2
},
622 {"msp430f6631", MSP_ISA_430Xv2
},
623 {"msp430f6632", MSP_ISA_430Xv2
},
624 {"msp430f6633", MSP_ISA_430Xv2
},
625 {"msp430f6634", MSP_ISA_430Xv2
},
626 {"msp430f6635", MSP_ISA_430Xv2
},
627 {"msp430f6636", MSP_ISA_430Xv2
},
628 {"msp430f6637", MSP_ISA_430Xv2
},
629 {"msp430f6638", MSP_ISA_430Xv2
},
630 {"msp430f5358", MSP_ISA_430Xv2
},
631 {"msp430f5359", MSP_ISA_430Xv2
},
632 {"msp430f5658", MSP_ISA_430Xv2
},
633 {"msp430f5659", MSP_ISA_430Xv2
},
634 {"msp430f6458", MSP_ISA_430Xv2
},
635 {"msp430f6459", MSP_ISA_430Xv2
},
636 {"msp430f6658", MSP_ISA_430Xv2
},
637 {"msp430f6659", MSP_ISA_430Xv2
},
638 {"msp430f5131", MSP_ISA_430Xv2
},
639 {"msp430f5151", MSP_ISA_430Xv2
},
640 {"msp430f5171", MSP_ISA_430Xv2
},
641 {"msp430f5132", MSP_ISA_430Xv2
},
642 {"msp430f5152", MSP_ISA_430Xv2
},
643 {"msp430f5172", MSP_ISA_430Xv2
},
644 {"msp430f6720", MSP_ISA_430Xv2
},
645 {"msp430f6721", MSP_ISA_430Xv2
},
646 {"msp430f6723", MSP_ISA_430Xv2
},
647 {"msp430f6724", MSP_ISA_430Xv2
},
648 {"msp430f6725", MSP_ISA_430Xv2
},
649 {"msp430f6726", MSP_ISA_430Xv2
},
650 {"msp430f6730", MSP_ISA_430Xv2
},
651 {"msp430f6731", MSP_ISA_430Xv2
},
652 {"msp430f6733", MSP_ISA_430Xv2
},
653 {"msp430f6734", MSP_ISA_430Xv2
},
654 {"msp430f6735", MSP_ISA_430Xv2
},
655 {"msp430f6736", MSP_ISA_430Xv2
},
656 {"msp430f67451", MSP_ISA_430Xv2
},
657 {"msp430f67651", MSP_ISA_430Xv2
},
658 {"msp430f67751", MSP_ISA_430Xv2
},
659 {"msp430f67461", MSP_ISA_430Xv2
},
660 {"msp430f67661", MSP_ISA_430Xv2
},
661 {"msp430f67761", MSP_ISA_430Xv2
},
662 {"msp430f67471", MSP_ISA_430Xv2
},
663 {"msp430f67671", MSP_ISA_430Xv2
},
664 {"msp430f67771", MSP_ISA_430Xv2
},
665 {"msp430f67481", MSP_ISA_430Xv2
},
666 {"msp430f67681", MSP_ISA_430Xv2
},
667 {"msp430f67781", MSP_ISA_430Xv2
},
668 {"msp430f67491", MSP_ISA_430Xv2
},
669 {"msp430f67691", MSP_ISA_430Xv2
},
670 {"msp430f67791", MSP_ISA_430Xv2
},
671 {"msp430f6745", MSP_ISA_430Xv2
},
672 {"msp430f6765", MSP_ISA_430Xv2
},
673 {"msp430f6775", MSP_ISA_430Xv2
},
674 {"msp430f6746", MSP_ISA_430Xv2
},
675 {"msp430f6766", MSP_ISA_430Xv2
},
676 {"msp430f6776", MSP_ISA_430Xv2
},
677 {"msp430f6747", MSP_ISA_430Xv2
},
678 {"msp430f6767", MSP_ISA_430Xv2
},
679 {"msp430f6777", MSP_ISA_430Xv2
},
680 {"msp430f6748", MSP_ISA_430Xv2
},
681 {"msp430f6768", MSP_ISA_430Xv2
},
682 {"msp430f6778", MSP_ISA_430Xv2
},
683 {"msp430f6749", MSP_ISA_430Xv2
},
684 {"msp430f6769", MSP_ISA_430Xv2
},
685 {"msp430f6779", MSP_ISA_430Xv2
},
686 {"msp430fr5720", MSP_ISA_430Xv2
},
687 {"msp430fr5721", MSP_ISA_430Xv2
},
688 {"msp430fr5722", MSP_ISA_430Xv2
},
689 {"msp430fr5723", MSP_ISA_430Xv2
},
690 {"msp430fr5724", MSP_ISA_430Xv2
},
691 {"msp430fr5725", MSP_ISA_430Xv2
},
692 {"msp430fr5726", MSP_ISA_430Xv2
},
693 {"msp430fr5727", MSP_ISA_430Xv2
},
694 {"msp430fr5728", MSP_ISA_430Xv2
},
695 {"msp430fr5729", MSP_ISA_430Xv2
},
696 {"msp430fr5730", MSP_ISA_430Xv2
},
697 {"msp430fr5731", MSP_ISA_430Xv2
},
698 {"msp430fr5732", MSP_ISA_430Xv2
},
699 {"msp430fr5733", MSP_ISA_430Xv2
},
700 {"msp430fr5734", MSP_ISA_430Xv2
},
701 {"msp430fr5735", MSP_ISA_430Xv2
},
702 {"msp430fr5736", MSP_ISA_430Xv2
},
703 {"msp430fr5737", MSP_ISA_430Xv2
},
704 {"msp430fr5738", MSP_ISA_430Xv2
},
705 {"msp430fr5739", MSP_ISA_430Xv2
},
706 {"msp430bt5190", MSP_ISA_430Xv2
},
707 {"msp430fr5949", MSP_ISA_430Xv2
},
708 {"msp430fr5969", MSP_ISA_430Xv2
},
709 {"msp430sl5438a", MSP_ISA_430Xv2
},
712 {"msp430", MSP_ISA_430
},
713 {"msp430X", MSP_ISA_430X
},
714 {"msp430Xv2", MSP_ISA_430Xv2
},
719 static struct mcu_type_s default_mcu
= { "msp430x11", MSP_ISA_430
};
720 static struct mcu_type_s msp430x_mcu
= { "msp430x", MSP_ISA_430X
};
721 static struct mcu_type_s msp430xv2_mcu
= { "msp430xv2", MSP_ISA_430Xv2
};
723 static struct mcu_type_s
* msp430_mcu
= & default_mcu
;
725 static inline bfd_boolean
726 target_is_430x (void)
728 return msp430_mcu
->isa
>= MSP_ISA_430X
;
731 static inline bfd_boolean
732 target_is_430xv2 (void)
734 return msp430_mcu
->isa
== MSP_ISA_430Xv2
;
737 /* Generate a 16-bit relocation.
738 For the 430X we generate a relocation without linkwer range checking
739 if the value is being used in an extended (ie 20-bit) instruction.
740 For the 430 we generate a relocation without assembler range checking
741 if we are handling an immediate value or a byte-width instruction. */
742 #undef CHECK_RELOC_MSP430
743 #define CHECK_RELOC_MSP430 \
745 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
746 : ((imm_op || byte_op) \
747 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
749 /* Generate a 16-bit pc-relative relocation.
750 For the 430X we generate a relocation without linkwer range checking.
751 For the 430 we generate a relocation without assembler range checking
752 if we are handling an immediate value or a byte-width instruction. */
753 #undef CHECK_RELOC_MSP430_PCREL
754 #define CHECK_RELOC_MSP430_PCREL \
756 ? BFD_RELOC_MSP430X_PCR16 \
757 : (imm_op || byte_op) \
758 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
760 /* Profiling capability:
761 It is a performance hit to use gcc's profiling approach for this tiny target.
762 Even more -- jtag hardware facility does not perform any profiling functions.
763 However we've got gdb's built-in simulator where we can do anything.
764 Therefore my suggestion is:
766 We define new section ".profiler" which holds all profiling information.
767 We define new pseudo operation .profiler which will instruct assembler to
768 add new profile entry to the object file. Profile should take place at the
773 .profiler flags,function_to_profile [, cycle_corrector, extra]
775 where 'flags' is a combination of the following chars:
778 i - function is in Init section
779 f - function is in Fini section
781 c - libC standard call
782 d - stack value Demand (saved at run-time in simulator)
783 I - Interrupt service routine
788 j - long Jump/ sjlj unwind
789 a - an Arbitrary code fragment
790 t - exTra parameter saved (constant value like frame size)
791 '""' optional: "sil" == sil
793 function_to_profile - function's address
794 cycle_corrector - a value which should be added to the cycle
795 counter, zero if omitted
796 extra - some extra parameter, zero if omitted.
799 ------------------------------
803 .LFrameOffset_fxx=0x08
804 .profiler "scdP", fxx ; function entry.
805 ; we also demand stack value to be displayed
810 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
811 ; (this is a prologue end)
812 ; note, that spare var filled with the frame size
815 .profiler cdE,fxx ; check stack
820 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
821 ret ; cause 'ret' insn takes 3 cycles
822 -------------------------------
824 This profiling approach does not produce any overhead and
826 So, even profiled code can be uploaded to the MCU. */
827 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
828 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
829 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
830 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
831 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
832 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
833 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
834 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
835 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
836 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
837 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
838 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
839 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
840 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
841 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
842 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
855 for (; x
; x
= x
>> 1)
862 /* Parse ordinary expression. */
865 parse_exp (char * s
, expressionS
* op
)
867 input_line_pointer
= s
;
869 if (op
->X_op
== O_absent
)
870 as_bad (_("missing operand"));
871 return input_line_pointer
;
875 /* Delete spaces from s: X ( r 1 2) => X(r12). */
878 del_spaces (char * s
)
886 while (ISSPACE (*m
) && *m
)
888 memmove (s
, m
, strlen (m
) + 1);
896 skip_space (char * s
)
903 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
906 extract_operand (char * from
, char * to
, int limit
)
910 /* Drop leading whitespace. */
911 from
= skip_space (from
);
913 while (size
< limit
&& *from
)
915 *(to
+ size
) = *from
;
916 if (*from
== ',' || *from
== ';' || *from
== '\n')
931 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
948 s
= input_line_pointer
;
949 end
= input_line_pointer
;
951 while (*end
&& *end
!= '\n')
954 while (*s
&& *s
!= '\n')
965 as_bad (_(".profiler pseudo requires at least two operands."));
966 input_line_pointer
= end
;
970 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
979 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
982 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
985 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
988 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
991 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
994 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
997 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
1000 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
1003 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
1006 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
1009 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
1012 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
1015 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
1018 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
1021 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
1024 as_warn (_("unknown profiling flag - ignored."));
1031 && ( ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_ENTRY
1032 | MSP430_PROFILER_FLAG_EXIT
))
1033 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_PROLSTART
1034 | MSP430_PROFILER_FLAG_PROLEND
1035 | MSP430_PROFILER_FLAG_EPISTART
1036 | MSP430_PROFILER_FLAG_EPIEND
))
1037 || ! pow2value (p_flags
& ( MSP430_PROFILER_FLAG_INITSECT
1038 | MSP430_PROFILER_FLAG_FINISECT
))))
1040 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
1041 input_line_pointer
= end
;
1045 /* Generate temp symbol which denotes current location. */
1046 if (now_seg
== absolute_section
) /* Paranoia ? */
1048 exp1
.X_op
= O_constant
;
1049 exp1
.X_add_number
= abs_section_offset
;
1050 as_warn (_("profiling in absolute section?"));
1054 exp1
.X_op
= O_symbol
;
1055 exp1
.X_add_symbol
= symbol_temp_new_now ();
1056 exp1
.X_add_number
= 0;
1059 /* Generate a symbol which holds flags value. */
1060 exp
.X_op
= O_constant
;
1061 exp
.X_add_number
= p_flags
;
1063 /* Save current section. */
1065 subseg
= now_subseg
;
1067 /* Now go to .profiler section. */
1068 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
1071 emit_expr (& exp
, 2);
1073 /* Save label value. */
1074 emit_expr (& exp1
, 2);
1078 /* Now get profiling info. */
1079 halt
= extract_operand (input_line_pointer
, str
, 1024);
1080 /* Process like ".word xxx" directive. */
1081 parse_exp (str
, & exp
);
1082 emit_expr (& exp
, 2);
1083 input_line_pointer
= halt
;
1086 /* Fill the rest with zeros. */
1087 exp
.X_op
= O_constant
;
1088 exp
.X_add_number
= 0;
1090 emit_expr (& exp
, 2);
1092 /* Return to current section. */
1093 subseg_set (seg
, subseg
);
1097 extract_word (char * from
, char * to
, int limit
)
1102 /* Drop leading whitespace. */
1103 from
= skip_space (from
);
1106 /* Find the op code end. */
1107 for (op_end
= from
; *op_end
!= 0 && is_part_of_name (*op_end
);)
1109 to
[size
++] = *op_end
++;
1110 if (size
+ 1 >= limit
)
1118 #define OPTION_MMCU 'm'
1119 #define OPTION_RELAX 'Q'
1120 #define OPTION_POLYMORPHS 'P'
1121 #define OPTION_LARGE 'l'
1122 static bfd_boolean large_model
= FALSE
;
1123 #define OPTION_NO_INTR_NOPS 'N'
1124 static bfd_boolean gen_interrupt_nops
= TRUE
;
1125 #define OPTION_MCPU 'c'
1126 #define OPTION_MOVE_DATA 'd'
1127 static bfd_boolean move_data
= FALSE
;
1130 msp430_set_arch (int option
)
1132 char *str
= (char *) alloca (32); /* 32 for good measure. */
1134 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
1136 md_parse_option (option
, str
);
1137 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1138 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1142 show_mcu_list (FILE * stream
)
1146 fprintf (stream
, _("Known MCU names:\n"));
1148 for (i
= 0; mcu_types
[i
].name
; i
++)
1150 fprintf (stream
, "%14.14s", mcu_types
[i
].name
);
1152 fprintf (stream
, "\n");
1155 fprintf (stream
, "\n");
1159 md_parse_option (int c
, char * arg
)
1167 as_fatal (_("MCU option requires a name\n"));
1169 for (i
= 0; mcu_types
[i
].name
; ++i
)
1170 if (strcasecmp (mcu_types
[i
].name
, arg
) == 0)
1173 if (mcu_types
[i
].name
== NULL
)
1175 show_mcu_list (stderr
);
1176 as_fatal (_("unknown MCU: %s\n"), arg
);
1179 /* Allow switching to the same or a lesser architecture. */
1180 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->isa
>= mcu_types
[i
].isa
)
1181 msp430_mcu
= mcu_types
+ i
;
1183 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1184 msp430_mcu
->name
, mcu_types
[i
].name
);
1188 if (strcmp (arg
, "430") == 0)
1189 msp430_mcu
= & default_mcu
;
1190 else if (strcmp (arg
, "430x") == 0
1191 || strcmp (arg
, "430X") == 0)
1192 msp430_mcu
= & msp430x_mcu
;
1193 else if (strcasecmp (arg
, "430xv2") == 0)
1194 msp430_mcu
= & msp430xv2_mcu
;
1196 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1201 msp430_enable_relax
= 1;
1204 case OPTION_POLYMORPHS
:
1205 msp430_enable_polys
= 1;
1212 case OPTION_NO_INTR_NOPS
:
1213 gen_interrupt_nops
= FALSE
;
1216 case OPTION_MOVE_DATA
:
1225 msp430_section (int arg
)
1227 char * saved_ilp
= input_line_pointer
;
1228 char * name
= obj_elf_section_name ();
1230 if (strncmp (name
, ".bss", 4) == 0
1231 || strncmp (name
, ".gnu.linkonce.b.", 16) == 0)
1232 (void) symbol_find_or_make ("__crt0_init_bss");
1235 && (strncmp (name
, ".data", 5) == 0
1236 || strncmp (name
, ".gnu.linkonce.d.", 16) == 0))
1237 (void) symbol_find_or_make ("__crt0_movedata");
1239 input_line_pointer
= saved_ilp
;
1240 obj_elf_section (arg
);
1243 const pseudo_typeS md_pseudo_table
[] =
1245 {"arch", msp430_set_arch
, OPTION_MMCU
},
1246 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1247 {"profiler", msp430_profiler
, 0},
1248 {"section", msp430_section
, 0},
1249 {"section.s", msp430_section
, 0},
1250 {"sect", msp430_section
, 0},
1251 {"sect.s", msp430_section
, 0},
1252 {"pushsection", msp430_section
, 1},
1256 const char *md_shortopts
= "mm:,mP,mQ,ml,mN";
1258 struct option md_longopts
[] =
1260 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1261 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1262 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1263 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1264 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1265 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1266 {"md", no_argument
, NULL
, OPTION_MOVE_DATA
},
1267 {NULL
, no_argument
, NULL
, 0}
1270 size_t md_longopts_size
= sizeof (md_longopts
);
1273 md_show_usage (FILE * stream
)
1276 _("MSP430 options:\n"
1277 " -mmcu=<msp430-name> - select microcontroller type\n"
1278 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1280 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1281 " -mP - enable polymorph instructions\n"));
1283 _(" -ml - enable large code model\n"));
1285 _(" -mN - disable generation of NOP after changing interrupts\n"));
1287 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1289 show_mcu_list (stream
);
1293 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1299 extract_cmd (char * from
, char * to
, int limit
)
1303 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1305 *(to
+ size
) = *from
;
1316 md_atof (int type
, char * litP
, int * sizeP
)
1318 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1324 struct msp430_opcode_s
* opcode
;
1325 msp430_hash
= hash_new ();
1327 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1328 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1330 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1331 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1334 /* Returns the register number equivalent to the string T.
1335 Returns -1 if there is no such register.
1336 Skips a leading 'r' or 'R' character if there is one.
1337 Handles the register aliases PC and SP. */
1340 check_reg (char * t
)
1347 if (*t
== 'r' || *t
== 'R')
1350 if (strncasecmp (t
, "pc", 2) == 0)
1353 if (strncasecmp (t
, "sp", 2) == 0)
1356 if (strncasecmp (t
, "sr", 2) == 0)
1364 if (val
< 1 || val
> 15)
1371 msp430_srcoperand (struct msp430_operand_s
* op
,
1375 bfd_boolean allow_20bit_values
,
1376 bfd_boolean constants_allowed
)
1380 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1387 /* Check if there is:
1388 llo(x) - least significant 16 bits, x &= 0xffff
1389 lhi(x) - x = (x >> 16) & 0xffff,
1390 hlo(x) - x = (x >> 32) & 0xffff,
1391 hhi(x) - x = (x >> 48) & 0xffff
1392 The value _MUST_ be constant expression: #hlo(1231231231). */
1396 if (strncasecmp (h
, "#llo(", 5) == 0)
1401 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1406 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1411 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1416 else if (strncasecmp (h
, "#lo(", 4) == 0)
1421 else if (strncasecmp (h
, "#hi(", 4) == 0)
1427 op
->reg
= 0; /* Reg PC. */
1429 op
->ol
= 1; /* Immediate will follow an instruction. */
1430 __tl
= h
+ 1 + rval
;
1433 parse_exp (__tl
, &(op
->exp
));
1434 if (op
->exp
.X_op
== O_constant
)
1436 int x
= op
->exp
.X_add_number
;
1441 op
->exp
.X_add_number
= x
;
1443 else if (vshift
== 1)
1445 x
= (x
>> 16) & 0xffff;
1446 op
->exp
.X_add_number
= x
;
1448 else if (vshift
> 1)
1451 op
->exp
.X_add_number
= -1;
1453 op
->exp
.X_add_number
= 0; /* Nothing left. */
1454 x
= op
->exp
.X_add_number
;
1457 if (allow_20bit_values
)
1459 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< - (0x7ffff))
1461 as_bad (_("value 0x%x out of extended range."), x
);
1465 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1467 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1471 /* Now check constants. */
1472 /* Substitute register mode with a constant generator if applicable. */
1474 if (!allow_20bit_values
)
1475 x
= (short) x
; /* Extend sign. */
1477 if (! constants_allowed
)
1509 #ifdef PUSH_1X_WORKAROUND
1512 /* Remove warning as confusing.
1513 as_warn (_("Hardware push bug workaround")); */
1526 #ifdef PUSH_1X_WORKAROUND
1529 /* Remove warning as confusing.
1530 as_warn (_("Hardware push bug workaround")); */
1542 else if (op
->exp
.X_op
== O_symbol
)
1546 else if (op
->exp
.X_op
== O_big
)
1551 op
->exp
.X_op
= O_constant
;
1552 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1553 x
= op
->exp
.X_add_number
;
1558 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1606 /* Redundant (yet) check. */
1607 else if (op
->exp
.X_op
== O_register
)
1609 (_("Registers cannot be used within immediate expression [%s]"), l
);
1611 as_bad (_("unknown operand %s"), l
);
1616 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1621 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1622 op
->am
= 1; /* mode As == 01 bin. */
1623 op
->ol
= 1; /* Immediate value followed by instruction. */
1625 parse_exp (__tl
, &(op
->exp
));
1627 if (op
->exp
.X_op
== O_constant
)
1629 int x
= op
->exp
.X_add_number
;
1631 if (allow_20bit_values
)
1633 if (x
> 0xfffff || x
< -(0x7ffff))
1635 as_bad (_("value 0x%x out of extended range."), x
);
1639 else if (x
> 65535 || x
< -32768)
1641 as_bad (_("value out of range: 0x%x"), x
);
1645 else if (op
->exp
.X_op
== O_symbol
)
1649 /* Redundant (yet) check. */
1650 if (op
->exp
.X_op
== O_register
)
1652 (_("Registers cannot be used within absolute expression [%s]"), l
);
1654 as_bad (_("unknown expression in operand %s"), l
);
1660 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1664 char *m
= strchr (l
, '+');
1668 as_bad (_("unknown addressing mode %s"), l
);
1674 if ((op
->reg
= check_reg (t
)) == -1)
1676 as_bad (_("Bad register name %s"), t
);
1684 /* PC cannot be used in indirect addressing. */
1685 if (target_is_430xv2 () && op
->reg
== 0)
1687 as_bad (_("cannot use indirect addressing with the PC"));
1693 /* Check if register indexed X(Rn). */
1696 char *h
= strrchr (l
, '(');
1697 char *m
= strrchr (l
, ')');
1706 as_bad (_("')' required"));
1714 /* Extract a register. */
1715 if ((op
->reg
= check_reg (t
+ 1)) == -1)
1718 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1725 as_bad (_("r2 should not be used in indexed addressing mode"));
1729 /* Extract constant. */
1733 parse_exp (__tl
, &(op
->exp
));
1734 if (op
->exp
.X_op
== O_constant
)
1736 int x
= op
->exp
.X_add_number
;
1738 if (allow_20bit_values
)
1740 if (x
> 0xfffff || x
< - (0x7ffff))
1742 as_bad (_("value 0x%x out of extended range."), x
);
1746 else if (x
> 65535 || x
< -32768)
1748 as_bad (_("value out of range: 0x%x"), x
);
1760 else if (op
->exp
.X_op
== O_symbol
)
1764 /* Redundant (yet) check. */
1765 if (op
->exp
.X_op
== O_register
)
1767 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1769 as_bad (_("unknown expression in operand %s"), l
);
1777 /* Possibly register mode 'mov r1,r2'. */
1778 if ((op
->reg
= check_reg (l
)) != -1)
1786 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1790 op
->reg
= 0; /* PC relative... be careful. */
1791 /* An expression starting with a minus sign is a constant, not an address. */
1792 op
->am
= (*l
== '-' ? 3 : 1);
1795 parse_exp (__tl
, &(op
->exp
));
1801 as_bad (_("unknown addressing mode for operand %s"), l
);
1807 msp430_dstoperand (struct msp430_operand_s
* op
,
1810 bfd_boolean allow_20bit_values
,
1811 bfd_boolean constants_allowed
)
1814 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
1828 parse_exp (__tl
, &(op
->exp
));
1830 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1832 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1842 ("this addressing mode is not applicable for destination operand"));
1849 /* Attempt to encode a MOVA instruction with the given operands.
1850 Returns the length of the encoded instruction if successful
1851 or 0 upon failure. If the encoding fails, an error message
1852 will be returned if a pointer is provided. */
1855 try_encode_mova (bfd_boolean imm_op
,
1857 struct msp430_operand_s
* op1
,
1858 struct msp430_operand_s
* op2
,
1859 const char ** error_message_return
)
1865 /* Only a restricted subset of the normal MSP430 addressing modes
1866 are supported here, so check for the ones that are allowed. */
1869 if (op1
->mode
== OP_EXP
)
1871 if (op2
->mode
!= OP_REG
)
1873 if (error_message_return
!= NULL
)
1874 * error_message_return
= _("expected register as second argument of %s");
1880 /* MOVA #imm20, Rdst. */
1881 bin
|= 0x80 | op2
->reg
;
1882 frag
= frag_more (4);
1883 where
= frag
- frag_now
->fr_literal
;
1884 if (op1
->exp
.X_op
== O_constant
)
1886 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
1887 bfd_putl16 ((bfd_vma
) bin
, frag
);
1888 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
1892 bfd_putl16 ((bfd_vma
) bin
, frag
);
1893 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
1894 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
1895 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1900 else if (op1
->am
== 1)
1902 /* MOVA z16(Rsrc), Rdst. */
1903 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
1904 frag
= frag_more (4);
1905 where
= frag
- frag_now
->fr_literal
;
1906 bfd_putl16 ((bfd_vma
) bin
, frag
);
1907 if (op1
->exp
.X_op
== O_constant
)
1909 if (op1
->exp
.X_add_number
> 0xffff
1910 || op1
->exp
.X_add_number
< -(0x7fff))
1912 if (error_message_return
!= NULL
)
1913 * error_message_return
= _("index value too big for %s");
1916 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
1920 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1921 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
1923 BFD_RELOC_MSP430X_PCR16
:
1924 BFD_RELOC_MSP430X_ABS16
);
1929 if (error_message_return
!= NULL
)
1930 * error_message_return
= _("unexpected addressing mode for %s");
1933 else if (op1
->am
== 0)
1935 /* MOVA Rsrc, ... */
1936 if (op2
->mode
== OP_REG
)
1938 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
1939 frag
= frag_more (2);
1940 where
= frag
- frag_now
->fr_literal
;
1941 bfd_putl16 ((bfd_vma
) bin
, frag
);
1944 else if (op2
->am
== 1)
1948 /* MOVA Rsrc, &abs20. */
1949 bin
|= 0x60 | (op1
->reg
<< 8);
1950 frag
= frag_more (4);
1951 where
= frag
- frag_now
->fr_literal
;
1952 if (op2
->exp
.X_op
== O_constant
)
1954 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
1955 bfd_putl16 ((bfd_vma
) bin
, frag
);
1956 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
1960 bfd_putl16 ((bfd_vma
) bin
, frag
);
1961 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1962 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
1963 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
1968 /* MOVA Rsrc, z16(Rdst). */
1969 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
1970 frag
= frag_more (4);
1971 where
= frag
- frag_now
->fr_literal
;
1972 bfd_putl16 ((bfd_vma
) bin
, frag
);
1973 if (op2
->exp
.X_op
== O_constant
)
1975 if (op2
->exp
.X_add_number
> 0xffff
1976 || op2
->exp
.X_add_number
< -(0x7fff))
1978 if (error_message_return
!= NULL
)
1979 * error_message_return
= _("index value too big for %s");
1982 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
1986 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1987 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
1989 BFD_RELOC_MSP430X_PCR16
:
1990 BFD_RELOC_MSP430X_ABS16
);
1995 if (error_message_return
!= NULL
)
1996 * error_message_return
= _("unexpected addressing mode for %s");
2001 /* imm_op == FALSE. */
2003 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
2005 /* MOVA &abs20, Rdst. */
2006 if (op2
->mode
!= OP_REG
)
2008 if (error_message_return
!= NULL
)
2009 * error_message_return
= _("expected register as second argument of %s");
2013 if (op2
->reg
== 2 || op2
->reg
== 3)
2015 if (error_message_return
!= NULL
)
2016 * error_message_return
= _("constant generator destination register found in %s");
2020 bin
|= 0x20 | op2
->reg
;
2021 frag
= frag_more (4);
2022 where
= frag
- frag_now
->fr_literal
;
2023 if (op1
->exp
.X_op
== O_constant
)
2025 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
2026 bfd_putl16 ((bfd_vma
) bin
, frag
);
2027 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
2031 bfd_putl16 ((bfd_vma
) bin
, frag
);
2032 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2033 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
2034 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2038 else if (op1
->mode
== OP_REG
)
2042 /* MOVA @Rsrc+, Rdst. */
2043 if (op2
->mode
!= OP_REG
)
2045 if (error_message_return
!= NULL
)
2046 * error_message_return
= _("expected register as second argument of %s");
2050 if (op2
->reg
== 2 || op2
->reg
== 3)
2052 if (error_message_return
!= NULL
)
2053 * error_message_return
= _("constant generator destination register found in %s");
2057 if (op1
->reg
== 2 || op1
->reg
== 3)
2059 if (error_message_return
!= NULL
)
2060 * error_message_return
= _("constant generator source register found in %s");
2064 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2065 frag
= frag_more (2);
2066 where
= frag
- frag_now
->fr_literal
;
2067 bfd_putl16 ((bfd_vma
) bin
, frag
);
2070 else if (op1
->am
== 2)
2072 /* MOVA @Rsrc,Rdst */
2073 if (op2
->mode
!= OP_REG
)
2075 if (error_message_return
!= NULL
)
2076 * error_message_return
= _("expected register as second argument of %s");
2080 if (op2
->reg
== 2 || op2
->reg
== 3)
2082 if (error_message_return
!= NULL
)
2083 * error_message_return
= _("constant generator destination register found in %s");
2087 if (op1
->reg
== 2 || op1
->reg
== 3)
2089 if (error_message_return
!= NULL
)
2090 * error_message_return
= _("constant generator source register found in %s");
2094 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2095 frag
= frag_more (2);
2096 where
= frag
- frag_now
->fr_literal
;
2097 bfd_putl16 ((bfd_vma
) bin
, frag
);
2102 if (error_message_return
!= NULL
)
2103 * error_message_return
= _("unexpected addressing mode for %s");
2108 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2110 /* Parse instruction operands.
2111 Return binary opcode. */
2114 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2116 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2117 int insn_length
= 0;
2118 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2121 struct msp430_operand_s op1
, op2
;
2123 static short ZEROS
= 0;
2124 int byte_op
, imm_op
;
2127 int extended
= 0x1800;
2128 bfd_boolean extended_op
= FALSE
;
2129 bfd_boolean addr_op
;
2130 const char * error_message
;
2131 static signed int repeat_count
= 0;
2132 bfd_boolean fix_emitted
;
2134 /* Opcode is the one from opcodes table
2135 line contains something like
2140 /* Check if byte or word operation. */
2141 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
2143 bin
|= BYTE_OPERATION
;
2149 /* "Address" ops work on 20-bit values. */
2150 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'a')
2153 bin
|= BYTE_OPERATION
;
2158 /* skip .[aAbwBW]. */
2159 while (! ISSPACE (*line
) && *line
)
2162 if (opcode
->fmt
!= -1
2163 && opcode
->insn_opnumb
2164 && (!*line
|| *line
== '\n'))
2166 as_bad (_("instruction %s requires %d operand(s)"),
2167 opcode
->name
, opcode
->insn_opnumb
);
2171 memset (l1
, 0, sizeof (l1
));
2172 memset (l2
, 0, sizeof (l2
));
2173 memset (&op1
, 0, sizeof (op1
));
2174 memset (&op2
, 0, sizeof (op2
));
2178 if ((fmt
= opcode
->fmt
) < 0)
2180 if (! target_is_430x ())
2182 as_bad (_("instruction %s requires MSP430X mcu"),
2193 /* If requested set the extended instruction repeat count. */
2196 if (repeat_count
> 0)
2197 extended
|= (repeat_count
- 1);
2199 extended
|= (1 << 7) | (- repeat_count
);
2202 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2209 case 0: /* Emulated. */
2210 switch (opcode
->insn_opnumb
)
2213 /* Set/clear bits instructions. */
2217 extended
|= BYTE_OPERATION
;
2219 /* Emit the extension word. */
2221 frag
= frag_more (insn_length
);
2222 bfd_putl16 (extended
, frag
);
2226 frag
= frag_more (insn_length
);
2227 bfd_putl16 ((bfd_vma
) bin
, frag
);
2229 if (gen_interrupt_nops
2230 && target_is_430xv2 ()
2231 && (is_opcode ("eint") || is_opcode ("dint")))
2233 /* Emit a NOP following interrupt enable/disable.
2234 See 1.3.4.1 of the MSP430x5xx User Guide. */
2236 frag
= frag_more (2);
2237 as_warn (_("a NOP instruction has been inserted after %s"),
2239 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2241 dwarf2_emit_insn (insn_length
);
2245 /* Something which works with destination operand. */
2246 line
= extract_operand (line
, l1
, sizeof (l1
));
2247 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2251 /* Compute the entire instruction length, in bytes. */
2252 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2253 frag
= frag_more (insn_length
);
2254 where
= frag
- frag_now
->fr_literal
;
2259 extended
|= BYTE_OPERATION
;
2261 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2263 as_bad (_("repeat instruction used with non-register mode instruction"));
2267 if (op1
.mode
== OP_EXP
)
2269 if (op1
.exp
.X_op
== O_constant
)
2270 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2272 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2273 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2274 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2276 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2277 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2280 /* Emit the extension word. */
2281 bfd_putl16 (extended
, frag
);
2286 bin
|= (op1
.reg
| (op1
.am
<< 7));
2287 bfd_putl16 ((bfd_vma
) bin
, frag
);
2291 if (op1
.mode
== OP_EXP
)
2293 if (op1
.exp
.X_op
== O_constant
)
2295 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2299 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2304 fix_new_exp (frag_now
, where
, 2,
2305 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2307 fix_new_exp (frag_now
, where
, 2,
2308 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2313 if (gen_interrupt_nops
2314 && target_is_430xv2 ()
2315 && is_opcode ("clr")
2316 && bin
== 0x4302 /* CLR R2*/)
2318 /* Emit a NOP following interrupt enable/disable.
2319 See 1.3.4.1 of the MSP430x5xx User Guide. */
2321 frag
= frag_more (2);
2322 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2323 as_warn (_("a NOP instruction has been inserted after %s"),
2327 dwarf2_emit_insn (insn_length
);
2331 /* Shift instruction. */
2332 line
= extract_operand (line
, l1
, sizeof (l1
));
2333 strncpy (l2
, l1
, sizeof (l2
));
2334 l2
[sizeof (l2
) - 1] = '\0';
2335 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2336 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2339 break; /* An error occurred. All warnings were done before. */
2341 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2342 frag
= frag_more (insn_length
);
2343 where
= frag
- frag_now
->fr_literal
;
2345 if (target_is_430xv2 ()
2346 && op1
.mode
== OP_REG
2348 && (is_opcode ("rlax")
2349 || is_opcode ("rlcx")
2350 || is_opcode ("rla")
2351 || is_opcode ("rlc")))
2353 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2360 extended
|= BYTE_OPERATION
;
2362 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2364 as_bad (_("repeat instruction used with non-register mode instruction"));
2368 if (op1
.mode
== OP_EXP
)
2370 if (op1
.exp
.X_op
== O_constant
)
2371 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2373 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2374 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2375 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2377 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2378 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2381 if (op2
.mode
== OP_EXP
)
2383 if (op2
.exp
.X_op
== O_constant
)
2384 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2386 else if (op1
.mode
== OP_EXP
)
2387 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2388 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2389 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2391 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2392 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2393 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2396 /* Emit the extension word. */
2397 bfd_putl16 (extended
, frag
);
2402 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2403 bfd_putl16 ((bfd_vma
) bin
, frag
);
2407 if (op1
.mode
== OP_EXP
)
2409 if (op1
.exp
.X_op
== O_constant
)
2411 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2415 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2419 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2420 fix_new_exp (frag_now
, where
, 2,
2421 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2423 fix_new_exp (frag_now
, where
, 2,
2424 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2431 if (op2
.mode
== OP_EXP
)
2433 if (op2
.exp
.X_op
== O_constant
)
2435 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2439 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2443 if (op2
.reg
) /* Not PC relative. */
2444 fix_new_exp (frag_now
, where
, 2,
2445 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2447 fix_new_exp (frag_now
, where
, 2,
2448 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2453 dwarf2_emit_insn (insn_length
);
2457 /* Branch instruction => mov dst, r0. */
2460 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2464 line
= extract_operand (line
, l1
, sizeof (l1
));
2465 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2471 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2472 op_length
= 2 + 2 * op1
.ol
;
2473 frag
= frag_more (op_length
);
2474 where
= frag
- frag_now
->fr_literal
;
2475 bfd_putl16 ((bfd_vma
) bin
, frag
);
2477 if (op1
.mode
== OP_EXP
)
2479 if (op1
.exp
.X_op
== O_constant
)
2481 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2487 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2489 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
2490 fix_new_exp (frag_now
, where
, 2,
2491 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2493 fix_new_exp (frag_now
, where
, 2,
2494 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2498 dwarf2_emit_insn (insn_length
+ op_length
);
2502 /* CALLA instructions. */
2503 fix_emitted
= FALSE
;
2505 line
= extract_operand (line
, l1
, sizeof (l1
));
2508 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
2509 extended_op
, FALSE
);
2515 op_length
= 2 + 2 * op1
.ol
;
2516 frag
= frag_more (op_length
);
2517 where
= frag
- frag_now
->fr_literal
;
2525 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2526 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2529 else if (op1
.am
== 1)
2535 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2536 BFD_RELOC_MSP430X_PCR20_CALL
);
2540 bin
|= 0x50 | op1
.reg
;
2542 else if (op1
.am
== 0)
2543 bin
|= 0x40 | op1
.reg
;
2545 else if (op1
.am
== 1)
2549 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2550 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2553 else if (op1
.am
== 2)
2554 bin
|= 0x60 | op1
.reg
;
2555 else if (op1
.am
== 3)
2556 bin
|= 0x70 | op1
.reg
;
2558 bfd_putl16 ((bfd_vma
) bin
, frag
);
2560 if (op1
.mode
== OP_EXP
)
2564 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
2568 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2571 fix_new_exp (frag_now
, where
+ 2, 2,
2572 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
2575 dwarf2_emit_insn (insn_length
+ op_length
);
2583 /* [POP|PUSH]M[.A] #N, Rd */
2584 line
= extract_operand (line
, l1
, sizeof (l1
));
2585 line
= extract_operand (line
, l2
, sizeof (l2
));
2589 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
2592 parse_exp (l1
+ 1, &(op1
.exp
));
2593 if (op1
.exp
.X_op
!= O_constant
)
2595 as_bad (_("expected constant expression for first argument of %s"),
2600 if ((reg
= check_reg (l2
)) == -1)
2602 as_bad (_("expected register as second argument of %s"),
2608 frag
= frag_more (op_length
);
2609 where
= frag
- frag_now
->fr_literal
;
2610 bin
= opcode
->bin_opcode
;
2613 n
= op1
.exp
.X_add_number
;
2614 bin
|= (n
- 1) << 4;
2615 if (is_opcode ("pushm"))
2619 if (reg
- n
+ 1 < 0)
2621 as_bad (_("Too many registers popped"));
2625 /* CPU21 parts cannot use POPM to restore the SR register. */
2626 if (target_is_430xv2 ()
2627 && (reg
- n
+ 1 < 3)
2629 && is_opcode ("popm"))
2631 as_bad (_("Cannot use POPM to restore the SR register"));
2635 bin
|= (reg
- n
+ 1);
2638 bfd_putl16 ((bfd_vma
) bin
, frag
);
2639 dwarf2_emit_insn (op_length
);
2648 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2649 if (extended
& 0xff)
2651 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2655 line
= extract_operand (line
, l1
, sizeof (l1
));
2656 line
= extract_operand (line
, l2
, sizeof (l2
));
2660 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
2663 parse_exp (l1
+ 1, &(op1
.exp
));
2664 if (op1
.exp
.X_op
!= O_constant
)
2666 as_bad (_("expected constant expression for first argument of %s"),
2670 n
= op1
.exp
.X_add_number
;
2673 as_bad (_("expected first argument of %s to be in the range 1-4"),
2678 if ((reg
= check_reg (l2
)) == -1)
2680 as_bad (_("expected register as second argument of %s"),
2685 if (target_is_430xv2 () && reg
== 0)
2687 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2692 frag
= frag_more (op_length
);
2693 where
= frag
- frag_now
->fr_literal
;
2695 bin
= opcode
->bin_opcode
;
2698 bin
|= (n
- 1) << 10;
2701 bfd_putl16 ((bfd_vma
) bin
, frag
);
2702 dwarf2_emit_insn (op_length
);
2710 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2711 if (extended
& 0xff)
2713 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2717 line
= extract_operand (line
, l1
, sizeof (l1
));
2718 if ((reg
= check_reg (l1
)) == -1)
2720 as_bad (_("expected register as argument of %s"),
2725 if (target_is_430xv2 () && reg
== 0)
2727 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2733 /* Tricky - there is no single instruction that will do this.
2734 Encode as: RRA.B rN { BIC.B #0x80, rN */
2736 frag
= frag_more (op_length
);
2737 where
= frag
- frag_now
->fr_literal
;
2739 bfd_putl16 ((bfd_vma
) bin
, frag
);
2740 dwarf2_emit_insn (2);
2742 bfd_putl16 ((bfd_vma
) bin
, frag
+ 2);
2744 bfd_putl16 ((bfd_vma
) bin
, frag
+ 4);
2745 dwarf2_emit_insn (4);
2749 /* Encode as RRUM[.A] rN. */
2750 bin
= opcode
->bin_opcode
;
2755 frag
= frag_more (op_length
);
2756 where
= frag
- frag_now
->fr_literal
;
2757 bfd_putl16 ((bfd_vma
) bin
, frag
);
2758 dwarf2_emit_insn (op_length
);
2765 bfd_boolean need_reloc
= FALSE
;
2769 /* ADDA, CMPA and SUBA address instructions. */
2770 if (extended
& 0xff)
2772 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2776 line
= extract_operand (line
, l1
, sizeof (l1
));
2777 line
= extract_operand (line
, l2
, sizeof (l2
));
2779 bin
= opcode
->bin_opcode
;
2783 parse_exp (l1
+ 1, &(op1
.exp
));
2785 if (op1
.exp
.X_op
== O_constant
)
2787 n
= op1
.exp
.X_add_number
;
2788 if (n
> 0xfffff || n
< - (0x7ffff))
2790 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2795 bin
|= ((n
>> 16) & 0xf) << 8;
2807 if ((n
= check_reg (l1
)) == -1)
2809 as_bad (_("expected register name or constant as first argument of %s"),
2814 bin
|= (n
<< 8) | (1 << 6);
2818 if ((reg
= check_reg (l2
)) == -1)
2820 as_bad (_("expected register as second argument of %s"),
2825 frag
= frag_more (op_length
);
2826 where
= frag
- frag_now
->fr_literal
;
2829 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2830 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2832 bfd_putl16 ((bfd_vma
) bin
, frag
);
2834 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
2835 dwarf2_emit_insn (op_length
);
2839 case 9: /* MOVA, BRA, RETA. */
2841 bin
= opcode
->bin_opcode
;
2843 if (is_opcode ("reta"))
2845 /* The RETA instruction does not take any arguments.
2846 The implicit first argument is @SP+.
2847 The implicit second argument is PC. */
2857 line
= extract_operand (line
, l1
, sizeof (l1
));
2858 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
2859 &imm_op
, extended_op
, FALSE
);
2861 if (is_opcode ("bra"))
2863 /* This is the BRA synthetic instruction.
2864 The second argument is always PC. */
2870 line
= extract_operand (line
, l2
, sizeof (l2
));
2871 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
2876 break; /* Error occurred. All warnings were done before. */
2879 /* Only a restricted subset of the normal MSP430 addressing modes
2880 are supported here, so check for the ones that are allowed. */
2881 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
2882 & error_message
)) == 0)
2884 as_bad (error_message
, opcode
->name
);
2887 dwarf2_emit_insn (op_length
);
2891 line
= extract_operand (line
, l1
, sizeof l1
);
2892 /* The RPT instruction only accepted immediates and registers. */
2895 parse_exp (l1
+ 1, &(op1
.exp
));
2896 if (op1
.exp
.X_op
!= O_constant
)
2898 as_bad (_("expected constant value as argument to RPT"));
2901 if (op1
.exp
.X_add_number
< 1
2902 || op1
.exp
.X_add_number
> (1 << 4))
2904 as_bad (_("expected constant in the range 2..16"));
2908 /* We silently accept and ignore a repeat count of 1. */
2909 if (op1
.exp
.X_add_number
> 1)
2910 repeat_count
= op1
.exp
.X_add_number
;
2916 if ((reg
= check_reg (l1
)) != -1)
2919 as_warn (_("PC used as an argument to RPT"));
2921 repeat_count
= - reg
;
2925 as_bad (_("expected constant or register name as argument to RPT insn"));
2932 as_bad (_("Illegal emulated instruction "));
2937 case 1: /* Format 1, double operand. */
2938 line
= extract_operand (line
, l1
, sizeof (l1
));
2939 line
= extract_operand (line
, l2
, sizeof (l2
));
2940 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2941 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2944 break; /* Error occurred. All warnings were done before. */
2947 && is_opcode ("movx")
2949 && msp430_enable_relax
)
2951 /* This is the MOVX.A instruction. See if we can convert
2952 it into the MOVA instruction instead. This saves 2 bytes. */
2953 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
2956 dwarf2_emit_insn (op_length
);
2961 /* Compute the entire length of the instruction in bytes. */
2963 (extended_op
? 2 : 0) /* The extension word. */
2964 + 2 /* The opcode */
2965 + (2 * op1
.ol
) /* The first operand. */
2966 + (2 * op2
.ol
); /* The second operand. */
2968 frag
= frag_more (insn_length
);
2969 where
= frag
- frag_now
->fr_literal
;
2974 extended
|= BYTE_OPERATION
;
2976 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2978 as_bad (_("repeat instruction used with non-register mode instruction"));
2982 /* If necessary, emit a reloc to update the extension word. */
2983 if (op1
.mode
== OP_EXP
)
2985 if (op1
.exp
.X_op
== O_constant
)
2986 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2988 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2989 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2990 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2992 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2993 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2996 if (op2
.mode
== OP_EXP
)
2998 if (op2
.exp
.X_op
== O_constant
)
2999 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
3001 else if (op1
.mode
== OP_EXP
)
3002 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
3003 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3004 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
3007 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
3008 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
3009 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
3012 /* Emit the extension word. */
3013 bfd_putl16 (extended
, frag
);
3018 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
3019 bfd_putl16 ((bfd_vma
) bin
, frag
);
3023 if (op1
.mode
== OP_EXP
)
3025 if (op1
.exp
.X_op
== O_constant
)
3027 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3031 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3035 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
3036 fix_new_exp (frag_now
, where
, 2,
3037 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
3039 fix_new_exp (frag_now
, where
, 2,
3040 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3048 if (op2
.mode
== OP_EXP
)
3050 if (op2
.exp
.X_op
== O_constant
)
3052 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3056 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3060 if (op2
.reg
) /* Not PC relative. */
3061 fix_new_exp (frag_now
, where
, 2,
3062 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
3064 fix_new_exp (frag_now
, where
, 2,
3065 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3070 if (gen_interrupt_nops
3071 && target_is_430xv2 ()
3072 && ( (is_opcode ("bic") && bin
== 0xc232)
3073 || (is_opcode ("bis") && bin
== 0xd232)
3074 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2)))
3076 /* Emit a NOP following interrupt enable/disable.
3077 See 1.3.4.1 of the MSP430x5xx User Guide. */
3079 frag
= frag_more (2);
3080 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
3081 as_warn (_("a NOP instruction has been inserted after %s"),
3085 dwarf2_emit_insn (insn_length
);
3088 case 2: /* Single-operand mostly instr. */
3089 if (opcode
->insn_opnumb
== 0)
3091 /* reti instruction. */
3093 frag
= frag_more (2);
3094 bfd_putl16 ((bfd_vma
) bin
, frag
);
3095 dwarf2_emit_insn (insn_length
);
3099 line
= extract_operand (line
, l1
, sizeof (l1
));
3100 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3101 &imm_op
, extended_op
, TRUE
);
3103 break; /* Error in operand. */
3105 if (target_is_430xv2 ()
3106 && op1
.mode
== OP_REG
3108 && (is_opcode ("rrax")
3109 || is_opcode ("rrcx")
3110 || is_opcode ("rra")
3111 || is_opcode ("rrc")))
3113 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3117 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3118 frag
= frag_more (insn_length
);
3119 where
= frag
- frag_now
->fr_literal
;
3123 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3125 /* These two instructions use a special
3126 encoding of the A/L and B/W bits. */
3127 bin
&= ~ BYTE_OPERATION
;
3131 as_bad (_("%s instruction does not accept a .b suffix"),
3136 extended
|= BYTE_OPERATION
;
3139 extended
|= BYTE_OPERATION
;
3141 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3143 as_bad (_("repeat instruction used with non-register mode instruction"));
3147 if (op1
.mode
== OP_EXP
)
3149 if (op1
.exp
.X_op
== O_constant
)
3150 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3152 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
3153 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3154 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3156 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3157 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3160 /* Emit the extension word. */
3161 bfd_putl16 (extended
, frag
);
3166 bin
|= op1
.reg
| (op1
.am
<< 4);
3167 bfd_putl16 ((bfd_vma
) bin
, frag
);
3171 if (op1
.mode
== OP_EXP
)
3173 if (op1
.exp
.X_op
== O_constant
)
3175 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3179 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3183 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
3184 fix_new_exp (frag_now
, where
, 2,
3185 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
3187 fix_new_exp (frag_now
, where
, 2,
3188 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3193 dwarf2_emit_insn (insn_length
);
3196 case 3: /* Conditional jumps instructions. */
3197 line
= extract_operand (line
, l1
, sizeof (l1
));
3198 /* l1 is a label. */
3207 parse_exp (m
, &exp
);
3209 /* In order to handle something like:
3213 jz 4 ; skip next 4 bytes
3216 nop ; will jump here if r5 positive or zero
3218 jCOND -n ;assumes jump n bytes backward:
3228 jCOND $n ; jump from PC in either direction. */
3230 if (exp
.X_op
== O_constant
)
3232 int x
= exp
.X_add_number
;
3236 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3240 if ((*l1
== '$' && x
> 0) || x
< 0)
3245 if (x
> 512 || x
< -511)
3247 as_bad (_("Wrong displacement %d"), x
<< 1);
3252 frag
= frag_more (2); /* Instr size is 1 word. */
3255 bfd_putl16 ((bfd_vma
) bin
, frag
);
3257 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3260 frag
= frag_more (2); /* Instr size is 1 word. */
3261 where
= frag
- frag_now
->fr_literal
;
3262 fix_new_exp (frag_now
, where
, 2,
3263 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3265 bfd_putl16 ((bfd_vma
) bin
, frag
);
3267 else if (*l1
== '$')
3269 as_bad (_("instruction requires label sans '$'"));
3273 ("instruction requires label or value in range -511:512"));
3274 dwarf2_emit_insn (insn_length
);
3279 as_bad (_("instruction requires label"));
3284 case 4: /* Extended jumps. */
3285 if (!msp430_enable_polys
)
3287 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3291 line
= extract_operand (line
, l1
, sizeof (l1
));
3297 /* Ignore absolute addressing. make it PC relative anyway. */
3298 if (*m
== '#' || *m
== '$')
3301 parse_exp (m
, & exp
);
3302 if (exp
.X_op
== O_symbol
)
3304 /* Relaxation required. */
3305 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3307 if (target_is_430x ())
3308 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3310 /* The parameter to dwarf2_emit_insn is actually the offset to
3311 the start of the insn from the fix piece of instruction that
3312 was emitted. Since next fragments may have variable size we
3313 tie debug info to the beginning of the instruction. */
3315 frag
= frag_more (8);
3316 dwarf2_emit_insn (0);
3317 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3318 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3320 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3322 0, /* Offset is zero if jump dist less than 1K. */
3328 as_bad (_("instruction requires label"));
3331 case 5: /* Emulated extended branches. */
3332 if (!msp430_enable_polys
)
3334 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3337 line
= extract_operand (line
, l1
, sizeof (l1
));
3343 /* Ignore absolute addressing. make it PC relative anyway. */
3344 if (*m
== '#' || *m
== '$')
3347 parse_exp (m
, & exp
);
3348 if (exp
.X_op
== O_symbol
)
3350 /* Relaxation required. */
3351 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3353 if (target_is_430x ())
3354 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3357 frag
= frag_more (8);
3358 dwarf2_emit_insn (0);
3359 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3360 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3362 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3363 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3365 0, /* Offset is zero if jump dist less than 1K. */
3371 as_bad (_("instruction requires label"));
3375 as_bad (_("Illegal instruction or not implemented opcode."));
3378 input_line_pointer
= line
;
3383 md_assemble (char * str
)
3385 struct msp430_opcode_s
* opcode
;
3389 str
= skip_space (str
); /* Skip leading spaces. */
3390 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
3392 while (cmd
[i
] && i
< sizeof (cmd
))
3394 char a
= TOLOWER (cmd
[i
]);
3401 as_bad (_("can't find opcode "));
3405 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3409 as_bad (_("unknown opcode `%s'"), cmd
);
3414 char *__t
= input_line_pointer
;
3416 msp430_operands (opcode
, str
);
3417 input_line_pointer
= __t
;
3421 /* GAS will call this function for each section at the end of the assembly,
3422 to permit the CPU backend to adjust the alignment of a section. */
3425 md_section_align (asection
* seg
, valueT addr
)
3427 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3429 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
3432 /* If you define this macro, it should return the offset between the
3433 address of a PC relative fixup and the position from which the PC
3434 relative adjustment should be made. On many processors, the base
3435 of a PC relative instruction is the next instruction, so this
3436 macro would return the length of an instruction. */
3439 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3441 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3442 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3443 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3446 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3449 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3450 Now it handles the situation when relocations
3451 have to be passed to linker. */
3453 msp430_force_relocation_local (fixS
*fixp
)
3455 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3459 if (msp430_enable_polys
3460 && !msp430_enable_relax
)
3463 return (!fixp
->fx_pcrel
3464 || generic_force_reloc (fixp
));
3468 /* GAS will call this for each fixup. It should store the correct
3469 value in the object file. */
3471 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3473 unsigned char * where
;
3477 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3482 else if (fixp
->fx_pcrel
)
3484 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3486 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3488 /* FIXME: We can appear here only in case if we perform a pc
3489 relative jump to the label which is i) global, ii) locally
3490 defined or this is a jump to an absolute symbol.
3491 If this is an absolute symbol -- everything is OK.
3492 If this is a global label, we've got a symbol value defined
3494 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3495 from this section start
3496 2. *valuep will contain the real offset from jump insn to the
3498 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3499 will be incorrect. Therefore remove s_get_value. */
3500 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
3508 value
= fixp
->fx_offset
;
3510 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
3512 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3514 value
-= S_GET_VALUE (fixp
->fx_subsy
);
3520 fixp
->fx_no_overflow
= 1;
3522 /* If polymorphs are enabled and relax disabled.
3523 do not kill any relocs and pass them to linker. */
3524 if (msp430_enable_polys
3525 && !msp430_enable_relax
)
3527 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
3528 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
3529 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
3536 /* Fetch the instruction, insert the fully resolved operand
3537 value, and stuff the instruction back again. */
3538 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
3540 insn
= bfd_getl16 (where
);
3542 switch (fixp
->fx_r_type
)
3544 case BFD_RELOC_MSP430_10_PCREL
:
3546 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3547 _("odd address operand: %ld"), value
);
3549 /* Jumps are in words. */
3551 --value
; /* Correct PC. */
3553 if (value
< -512 || value
> 511)
3554 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3555 _("operand out of range: %ld"), value
);
3557 value
&= 0x3ff; /* get rid of extended sign */
3558 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
3561 case BFD_RELOC_MSP430X_PCR16
:
3562 case BFD_RELOC_MSP430_RL_PCREL
:
3563 case BFD_RELOC_MSP430_16_PCREL
:
3565 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3566 _("odd address operand: %ld"), value
);
3569 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
3570 /* Nothing to be corrected here. */
3571 if (value
< -32768 || value
> 65536)
3572 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3573 _("operand out of range: %ld"), value
);
3576 case BFD_RELOC_MSP430X_ABS16
:
3577 case BFD_RELOC_MSP430_16
:
3579 case BFD_RELOC_MSP430_16_BYTE
:
3580 value
&= 0xffff; /* Get rid of extended sign. */
3581 bfd_putl16 ((bfd_vma
) value
, where
);
3585 bfd_putl16 ((bfd_vma
) value
, where
);
3588 case BFD_RELOC_MSP430_ABS8
:
3590 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
3593 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
3594 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
3595 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3597 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
3600 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
3601 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3603 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
3606 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
3607 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3609 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3612 case BFD_RELOC_MSP430X_PCR20_CALL
:
3613 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3615 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3618 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
3619 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
3620 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3622 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3625 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
3626 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3628 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3631 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
3632 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3634 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3638 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3639 fixp
->fx_line
, fixp
->fx_r_type
);
3645 fixp
->fx_addnumber
= value
;
3650 S_IS_GAS_LOCAL (symbolS
* s
)
3657 name
= S_GET_NAME (s
);
3658 len
= strlen (name
) - 1;
3660 return name
[len
] == 1 || name
[len
] == 2;
3663 /* GAS will call this to generate a reloc, passing the resulting reloc
3664 to `bfd_install_relocation'. This currently works poorly, as
3665 `bfd_install_relocation' often does the wrong thing, and instances of
3666 `tc_gen_reloc' have been written to work around the problems, which
3667 in turns makes it difficult to fix `bfd_install_relocation'. */
3669 /* If while processing a fixup, a reloc really needs to be created
3670 then it is done here. */
3673 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
3675 static arelent
* no_relocs
= NULL
;
3676 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
3679 reloc
= xmalloc (sizeof (arelent
));
3680 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3681 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3683 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3685 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3686 _("reloc %d not supported by object file format"),
3687 (int) fixp
->fx_r_type
);
3696 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3698 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
3699 fixp
->fx_subsy
= NULL
;
3702 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
3704 asection
*asec
, *ssec
;
3706 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
3707 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
3709 /* If we have a difference between two different, non-absolute symbols
3710 we must generate two relocs (one for each symbol) and allow the
3711 linker to resolve them - relaxation may change the distances between
3712 symbols, even local symbols defined in the same section.
3714 Unfortunately we cannot do this with assembler generated local labels
3715 because there can be multiple incarnations of the same label, with
3716 exactly the same name, in any given section and the linker will have
3717 no way to identify the correct one. Instead we just have to hope
3718 that no relaxtion will occur between the local label and the other
3719 symbol in the expression.
3721 Similarly we have to compute differences between symbols in the .eh_frame
3722 section as the linker is not smart enough to apply relocations there
3723 before attempting to process it. */
3724 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
3725 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
3726 && strcmp (ssec
->name
, ".eh_frame") != 0
3727 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
3728 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
3730 arelent
* reloc2
= xmalloc (sizeof * reloc
);
3735 reloc2
->address
= reloc
->address
;
3736 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
3737 BFD_RELOC_MSP430_SYM_DIFF
);
3738 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
3740 if (ssec
== absolute_section
)
3741 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
3744 reloc2
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3745 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
3748 reloc
->addend
= fixp
->fx_offset
;
3749 if (asec
== absolute_section
)
3751 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
3752 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
3756 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3757 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3766 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
3768 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
3769 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
3771 switch (fixp
->fx_r_type
)
3774 md_number_to_chars (fixpos
, reloc
->addend
, 1);
3778 md_number_to_chars (fixpos
, reloc
->addend
, 2);
3782 md_number_to_chars (fixpos
, reloc
->addend
, 3);
3786 md_number_to_chars (fixpos
, reloc
->addend
, 4);
3791 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
3802 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
3803 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
3805 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
3806 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
3808 md_number_to_chars (fixpos
, amount
, 2);
3813 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3814 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3815 reloc
->addend
= fixp
->fx_offset
;
3817 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3818 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3819 reloc
->address
= fixp
->fx_offset
;
3826 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
3827 asection
* segment_type ATTRIBUTE_UNUSED
)
3829 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
3831 /* This is a jump -> pcrel mode. Nothing to do much here.
3832 Return value == 2. */
3834 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
3836 else if (fragP
->fr_symbol
)
3838 /* Its got a segment, but its not ours. Even if fr_symbol is in
3839 an absolute segment, we don't know a displacement until we link
3840 object files. So it will always be long. This also applies to
3841 labels in a subsegment of current. Liker may relax it to short
3842 jump later. Return value == 8. */
3844 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
3848 /* We know the abs value. may be it is a jump to fixed address.
3849 Impossible in our case, cause all constants already handled. */
3851 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
3854 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3858 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
3859 asection
* sec ATTRIBUTE_UNUSED
,
3865 struct rcodes_s
* cc
= NULL
;
3866 struct hcodes_s
* hc
= NULL
;
3868 switch (fragP
->fr_subtype
)
3870 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
3871 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
3872 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
3873 /* We do not have to convert anything here.
3874 Just apply a fix. */
3875 rela
= BFD_RELOC_MSP430_10_PCREL
;
3878 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
3879 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
3880 /* Convert uncond branch jmp lab -> br lab. */
3881 if (target_is_430x ())
3882 cc
= msp430x_rcodes
+ 7;
3884 cc
= msp430_rcodes
+ 7;
3885 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3886 bfd_putl16 (cc
->lop0
, where
);
3887 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3891 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
3892 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
3894 /* Other simple branches. */
3895 int insn
= bfd_getl16 (fragP
->fr_opcode
);
3898 /* Find actual instruction. */
3899 if (target_is_430x ())
3901 for (i
= 0; i
< 7 && !cc
; i
++)
3902 if (msp430x_rcodes
[i
].sop
== insn
)
3903 cc
= msp430x_rcodes
+ i
;
3907 for (i
= 0; i
< 7 && !cc
; i
++)
3908 if (msp430_rcodes
[i
].sop
== insn
)
3909 cc
= & msp430_rcodes
[i
];
3912 if (!cc
|| !cc
->name
)
3913 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3914 __FUNCTION__
, (long) insn
);
3915 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3916 bfd_putl16 (cc
->lop0
, where
);
3917 bfd_putl16 (cc
->lop1
, where
+ 2);
3918 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3923 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
3924 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
3925 if (target_is_430x ())
3926 cc
= msp430x_rcodes
+ 6;
3928 cc
= msp430_rcodes
+ 6;
3929 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3930 bfd_putl16 (cc
->lop0
, where
);
3931 bfd_putl16 (cc
->lop1
, where
+ 2);
3932 bfd_putl16 (cc
->lop2
, where
+ 4);
3933 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3937 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
3939 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
3942 if (target_is_430x ())
3944 for (i
= 0; i
< 4 && !hc
; i
++)
3945 if (msp430x_hcodes
[i
].op1
== insn
)
3946 hc
= msp430x_hcodes
+ i
;
3950 for (i
= 0; i
< 4 && !hc
; i
++)
3951 if (msp430_hcodes
[i
].op1
== insn
)
3952 hc
= &msp430_hcodes
[i
];
3954 if (!hc
|| !hc
->name
)
3955 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3956 __FUNCTION__
, (long) insn
);
3957 rela
= BFD_RELOC_MSP430_10_PCREL
;
3958 /* Apply a fix for a first label if necessary.
3959 another fix will be applied to the next word of insn anyway. */
3961 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3962 fragP
->fr_offset
, TRUE
, rela
);
3968 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
3969 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
3971 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
3974 if (target_is_430x ())
3976 for (i
= 0; i
< 4 && !hc
; i
++)
3977 if (msp430x_hcodes
[i
].op1
== insn
)
3978 hc
= msp430x_hcodes
+ i
;
3982 for (i
= 0; i
< 4 && !hc
; i
++)
3983 if (msp430_hcodes
[i
].op1
== insn
)
3984 hc
= & msp430_hcodes
[i
];
3986 if (!hc
|| !hc
->name
)
3987 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3988 __FUNCTION__
, (long) insn
);
3989 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3990 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3991 bfd_putl16 (hc
->lop0
, where
);
3992 bfd_putl16 (hc
->lop1
, where
+ 2);
3993 bfd_putl16 (hc
->lop2
, where
+ 4);
3999 as_fatal (_("internal inconsistency problem in %s: %lx"),
4000 __FUNCTION__
, (long) fragP
->fr_subtype
);
4004 /* Now apply fix. */
4005 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
4006 fragP
->fr_offset
, TRUE
, rela
);
4007 /* Just fixed 2 bytes. */
4011 /* Relax fragment. Mostly stolen from hc11 and mcore
4012 which arches I think I know. */
4015 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
4016 long stretch ATTRIBUTE_UNUSED
)
4021 const relax_typeS
*this_type
;
4022 const relax_typeS
*start_type
;
4023 relax_substateT next_state
;
4024 relax_substateT this_state
;
4025 const relax_typeS
*table
= md_relax_table
;
4027 /* Nothing to be done if the frag has already max size. */
4028 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
4029 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
4032 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
4034 symbolP
= fragP
->fr_symbol
;
4035 if (symbol_resolved_p (symbolP
))
4036 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4038 /* We know the offset. calculate a distance. */
4039 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4042 if (!msp430_enable_relax
)
4044 /* Relaxation is not enabled. So, make all jump as long ones
4045 by setting 'aim' to quite high value. */
4049 this_state
= fragP
->fr_subtype
;
4050 start_type
= this_type
= table
+ this_state
;
4054 /* Look backwards. */
4055 for (next_state
= this_type
->rlx_more
; next_state
;)
4056 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4060 /* Grow to next state. */
4061 this_state
= next_state
;
4062 this_type
= table
+ this_state
;
4063 next_state
= this_type
->rlx_more
;
4068 /* Look forwards. */
4069 for (next_state
= this_type
->rlx_more
; next_state
;)
4070 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4074 /* Grow to next state. */
4075 this_state
= next_state
;
4076 this_type
= table
+ this_state
;
4077 next_state
= this_type
->rlx_more
;
4081 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4083 fragP
->fr_subtype
= this_state
;
4087 /* Return FALSE if the fixup in fixp should be left alone and not
4088 adjusted. We return FALSE here so that linker relaxation will
4092 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4094 /* If the symbol is in a non-code section then it should be OK. */
4096 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4102 /* Set the contents of the .MSP430.attributes section. */
4105 msp430_md_end (void)
4107 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4108 target_is_430x () ? 2 : 1);
4110 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4111 large_model
? 2 : 1);
4113 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4114 large_model
? 2 : 1);
4117 /* Returns FALSE if there is a msp430 specific reason why the
4118 subtraction of two same-section symbols cannot be computed by
4122 msp430_allow_local_subtract (expressionS
* left
,
4123 expressionS
* right
,
4126 /* If the symbols are not in a code section then they are OK. */
4127 if ((section
->flags
& SEC_CODE
) == 0)
4130 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4133 if (left
->X_add_symbol
== right
->X_add_symbol
)
4136 /* We have to assume that there may be instructions between the
4137 two symbols and that relaxation may increase the distance between