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'
1128 msp430_set_arch (int option
)
1130 char *str
= (char *) alloca (32); /* 32 for good measure. */
1132 input_line_pointer
= extract_word (input_line_pointer
, str
, 32);
1134 md_parse_option (option
, str
);
1135 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1136 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1140 show_mcu_list (FILE * stream
)
1144 fprintf (stream
, _("Known MCU names:\n"));
1146 for (i
= 0; mcu_types
[i
].name
; i
++)
1148 fprintf (stream
, "%14.14s", mcu_types
[i
].name
);
1150 fprintf (stream
, "\n");
1153 fprintf (stream
, "\n");
1157 md_parse_option (int c
, char * arg
)
1165 as_fatal (_("MCU option requires a name\n"));
1167 for (i
= 0; mcu_types
[i
].name
; ++i
)
1168 if (strcasecmp (mcu_types
[i
].name
, arg
) == 0)
1171 if (mcu_types
[i
].name
== NULL
)
1173 show_mcu_list (stderr
);
1174 as_fatal (_("unknown MCU: %s\n"), arg
);
1177 /* Allow switching to the same or a lesser architecture. */
1178 if (msp430_mcu
== &default_mcu
|| msp430_mcu
->isa
>= mcu_types
[i
].isa
)
1179 msp430_mcu
= mcu_types
+ i
;
1181 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1182 msp430_mcu
->name
, mcu_types
[i
].name
);
1186 if (strcmp (arg
, "430") == 0)
1187 msp430_mcu
= & default_mcu
;
1188 else if (strcmp (arg
, "430x") == 0
1189 || strcmp (arg
, "430X") == 0)
1190 msp430_mcu
= & msp430x_mcu
;
1191 else if (strcasecmp (arg
, "430xv2") == 0)
1192 msp430_mcu
= & msp430xv2_mcu
;
1194 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg
);
1199 msp430_enable_relax
= 1;
1202 case OPTION_POLYMORPHS
:
1203 msp430_enable_polys
= 1;
1210 case OPTION_NO_INTR_NOPS
:
1211 gen_interrupt_nops
= FALSE
;
1219 const pseudo_typeS md_pseudo_table
[] =
1221 {"arch", msp430_set_arch
, OPTION_MMCU
},
1222 {"cpu", msp430_set_arch
, OPTION_MCPU
},
1223 {"profiler", msp430_profiler
, 0},
1227 const char *md_shortopts
= "mm:,mP,mQ,ml,mN";
1229 struct option md_longopts
[] =
1231 {"mmcu", required_argument
, NULL
, OPTION_MMCU
},
1232 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
1233 {"mP", no_argument
, NULL
, OPTION_POLYMORPHS
},
1234 {"mQ", no_argument
, NULL
, OPTION_RELAX
},
1235 {"ml", no_argument
, NULL
, OPTION_LARGE
},
1236 {"mN", no_argument
, NULL
, OPTION_NO_INTR_NOPS
},
1237 {NULL
, no_argument
, NULL
, 0}
1240 size_t md_longopts_size
= sizeof (md_longopts
);
1243 md_show_usage (FILE * stream
)
1246 _("MSP430 options:\n"
1247 " -mmcu=<msp430-name> - select microcontroller type\n"
1248 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1250 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1251 " -mP - enable polymorph instructions\n"));
1253 _(" -ml - enable large code model\n"));
1255 _(" -mN - disable generation of NOP after changing interrupts\n"));
1257 show_mcu_list (stream
);
1261 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1267 extract_cmd (char * from
, char * to
, int limit
)
1271 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
1273 *(to
+ size
) = *from
;
1284 md_atof (int type
, char * litP
, int * sizeP
)
1286 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1292 struct msp430_opcode_s
* opcode
;
1293 msp430_hash
= hash_new ();
1295 for (opcode
= msp430_opcodes
; opcode
->name
; opcode
++)
1296 hash_insert (msp430_hash
, opcode
->name
, (char *) opcode
);
1298 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
,
1299 target_is_430x () ? bfd_mach_msp430x
: bfd_mach_msp11
);
1302 /* Returns the register number equivalent to the string T.
1303 Returns -1 if there is no such register.
1304 Skips a leading 'r' or 'R' character if there is one.
1305 Handles the register aliases PC and SP. */
1308 check_reg (char * t
)
1315 if (*t
== 'r' || *t
== 'R')
1318 if (strncasecmp (t
, "pc", 2) == 0)
1321 if (strncasecmp (t
, "sp", 2) == 0)
1324 if (strncasecmp (t
, "sr", 2) == 0)
1332 if (val
< 1 || val
> 15)
1339 msp430_srcoperand (struct msp430_operand_s
* op
,
1343 bfd_boolean allow_20bit_values
,
1344 bfd_boolean constants_allowed
)
1348 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1355 /* Check if there is:
1356 llo(x) - least significant 16 bits, x &= 0xffff
1357 lhi(x) - x = (x >> 16) & 0xffff,
1358 hlo(x) - x = (x >> 32) & 0xffff,
1359 hhi(x) - x = (x >> 48) & 0xffff
1360 The value _MUST_ be constant expression: #hlo(1231231231). */
1364 if (strncasecmp (h
, "#llo(", 5) == 0)
1369 else if (strncasecmp (h
, "#lhi(", 5) == 0)
1374 else if (strncasecmp (h
, "#hlo(", 5) == 0)
1379 else if (strncasecmp (h
, "#hhi(", 5) == 0)
1384 else if (strncasecmp (h
, "#lo(", 4) == 0)
1389 else if (strncasecmp (h
, "#hi(", 4) == 0)
1395 op
->reg
= 0; /* Reg PC. */
1397 op
->ol
= 1; /* Immediate will follow an instruction. */
1398 __tl
= h
+ 1 + rval
;
1401 parse_exp (__tl
, &(op
->exp
));
1402 if (op
->exp
.X_op
== O_constant
)
1404 int x
= op
->exp
.X_add_number
;
1409 op
->exp
.X_add_number
= x
;
1411 else if (vshift
== 1)
1413 x
= (x
>> 16) & 0xffff;
1414 op
->exp
.X_add_number
= x
;
1416 else if (vshift
> 1)
1419 op
->exp
.X_add_number
= -1;
1421 op
->exp
.X_add_number
= 0; /* Nothing left. */
1422 x
= op
->exp
.X_add_number
;
1425 if (allow_20bit_values
)
1427 if (op
->exp
.X_add_number
> 0xfffff || op
->exp
.X_add_number
< - (0x7ffff))
1429 as_bad (_("value 0x%x out of extended range."), x
);
1433 else if (op
->exp
.X_add_number
> 65535 || op
->exp
.X_add_number
< -32768)
1435 as_bad (_("value %d out of range. Use #lo() or #hi()"), x
);
1439 /* Now check constants. */
1440 /* Substitute register mode with a constant generator if applicable. */
1442 if (!allow_20bit_values
)
1443 x
= (short) x
; /* Extend sign. */
1445 if (! constants_allowed
)
1477 #ifdef PUSH_1X_WORKAROUND
1480 /* Remove warning as confusing.
1481 as_warn (_("Hardware push bug workaround")); */
1494 #ifdef PUSH_1X_WORKAROUND
1497 /* Remove warning as confusing.
1498 as_warn (_("Hardware push bug workaround")); */
1510 else if (op
->exp
.X_op
== O_symbol
)
1514 else if (op
->exp
.X_op
== O_big
)
1519 op
->exp
.X_op
= O_constant
;
1520 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
1521 x
= op
->exp
.X_add_number
;
1526 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1574 /* Redundant (yet) check. */
1575 else if (op
->exp
.X_op
== O_register
)
1577 (_("Registers cannot be used within immediate expression [%s]"), l
);
1579 as_bad (_("unknown operand %s"), l
);
1584 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1589 op
->reg
= 2; /* reg 2 in absolute addr mode. */
1590 op
->am
= 1; /* mode As == 01 bin. */
1591 op
->ol
= 1; /* Immediate value followed by instruction. */
1593 parse_exp (__tl
, &(op
->exp
));
1595 if (op
->exp
.X_op
== O_constant
)
1597 int x
= op
->exp
.X_add_number
;
1599 if (allow_20bit_values
)
1601 if (x
> 0xfffff || x
< -(0x7ffff))
1603 as_bad (_("value 0x%x out of extended range."), x
);
1607 else if (x
> 65535 || x
< -32768)
1609 as_bad (_("value out of range: 0x%x"), x
);
1613 else if (op
->exp
.X_op
== O_symbol
)
1617 /* Redundant (yet) check. */
1618 if (op
->exp
.X_op
== O_register
)
1620 (_("Registers cannot be used within absolute expression [%s]"), l
);
1622 as_bad (_("unknown expression in operand %s"), l
);
1628 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1632 char *m
= strchr (l
, '+');
1636 as_bad (_("unknown addressing mode %s"), l
);
1642 if ((op
->reg
= check_reg (t
)) == -1)
1644 as_bad (_("Bad register name %s"), t
);
1655 /* Check if register indexed X(Rn). */
1658 char *h
= strrchr (l
, '(');
1659 char *m
= strrchr (l
, ')');
1668 as_bad (_("')' required"));
1676 /* Extract a register. */
1677 if ((op
->reg
= check_reg (t
+ 1)) == -1)
1680 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1687 as_bad (_("r2 should not be used in indexed addressing mode"));
1691 /* Extract constant. */
1695 parse_exp (__tl
, &(op
->exp
));
1696 if (op
->exp
.X_op
== O_constant
)
1698 int x
= op
->exp
.X_add_number
;
1700 if (allow_20bit_values
)
1702 if (x
> 0xfffff || x
< - (0x7ffff))
1704 as_bad (_("value 0x%x out of extended range."), x
);
1708 else if (x
> 65535 || x
< -32768)
1710 as_bad (_("value out of range: 0x%x"), x
);
1722 else if (op
->exp
.X_op
== O_symbol
)
1726 /* Redundant (yet) check. */
1727 if (op
->exp
.X_op
== O_register
)
1729 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1731 as_bad (_("unknown expression in operand %s"), l
);
1739 /* Possibly register mode 'mov r1,r2'. */
1740 if ((op
->reg
= check_reg (l
)) != -1)
1748 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1752 op
->reg
= 0; /* PC relative... be careful. */
1753 /* An expression starting with a minus sign is a constant, not an address. */
1754 op
->am
= (*l
== '-' ? 3 : 1);
1757 parse_exp (__tl
, &(op
->exp
));
1763 as_bad (_("unknown addressing mode for operand %s"), l
);
1769 msp430_dstoperand (struct msp430_operand_s
* op
,
1772 bfd_boolean allow_20bit_values
,
1773 bfd_boolean constants_allowed
)
1776 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
,
1790 parse_exp (__tl
, &(op
->exp
));
1792 if (op
->exp
.X_op
!= O_constant
|| op
->exp
.X_add_number
!= 0)
1794 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1804 ("this addressing mode is not applicable for destination operand"));
1811 /* Attempt to encode a MOVA instruction with the given operands.
1812 Returns the length of the encoded instruction if successful
1813 or 0 upon failure. If the encoding fails, an error message
1814 will be returned if a pointer is provided. */
1817 try_encode_mova (bfd_boolean imm_op
,
1819 struct msp430_operand_s
* op1
,
1820 struct msp430_operand_s
* op2
,
1821 const char ** error_message_return
)
1827 /* Only a restricted subset of the normal MSP430 addressing modes
1828 are supported here, so check for the ones that are allowed. */
1831 if (op1
->mode
== OP_EXP
)
1833 if (op2
->mode
!= OP_REG
)
1835 if (error_message_return
!= NULL
)
1836 * error_message_return
= _("expected register as second argument of %s");
1842 /* MOVA #imm20, Rdst. */
1843 bin
|= 0x80 | op2
->reg
;
1844 frag
= frag_more (4);
1845 where
= frag
- frag_now
->fr_literal
;
1846 if (op1
->exp
.X_op
== O_constant
)
1848 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
1849 bfd_putl16 ((bfd_vma
) bin
, frag
);
1850 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
1854 bfd_putl16 ((bfd_vma
) bin
, frag
);
1855 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
1856 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
1857 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1862 else if (op1
->am
== 1)
1864 /* MOVA z16(Rsrc), Rdst. */
1865 bin
|= 0x30 | (op1
->reg
<< 8) | op2
->reg
;
1866 frag
= frag_more (4);
1867 where
= frag
- frag_now
->fr_literal
;
1868 bfd_putl16 ((bfd_vma
) bin
, frag
);
1869 if (op1
->exp
.X_op
== O_constant
)
1871 if (op1
->exp
.X_add_number
> 0xffff
1872 || op1
->exp
.X_add_number
< -(0x7fff))
1874 if (error_message_return
!= NULL
)
1875 * error_message_return
= _("index value too big for %s");
1878 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
1882 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1883 fix_new_exp (frag_now
, where
+ 2, 2, &(op1
->exp
), FALSE
,
1885 BFD_RELOC_MSP430X_PCR16
:
1886 BFD_RELOC_MSP430X_ABS16
);
1891 if (error_message_return
!= NULL
)
1892 * error_message_return
= _("unexpected addressing mode for %s");
1895 else if (op1
->am
== 0)
1897 /* MOVA Rsrc, ... */
1898 if (op2
->mode
== OP_REG
)
1900 bin
|= 0xc0 | (op1
->reg
<< 8) | op2
->reg
;
1901 frag
= frag_more (2);
1902 where
= frag
- frag_now
->fr_literal
;
1903 bfd_putl16 ((bfd_vma
) bin
, frag
);
1906 else if (op2
->am
== 1)
1910 /* MOVA Rsrc, &abs20. */
1911 bin
|= 0x60 | (op1
->reg
<< 8);
1912 frag
= frag_more (4);
1913 where
= frag
- frag_now
->fr_literal
;
1914 if (op2
->exp
.X_op
== O_constant
)
1916 bin
|= (op2
->exp
.X_add_number
>> 16) & 0xf;
1917 bfd_putl16 ((bfd_vma
) bin
, frag
);
1918 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
1922 bfd_putl16 ((bfd_vma
) bin
, frag
);
1923 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1924 fix_new_exp (frag_now
, where
, 4, &(op2
->exp
), FALSE
,
1925 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
1930 /* MOVA Rsrc, z16(Rdst). */
1931 bin
|= 0x70 | (op1
->reg
<< 8) | op2
->reg
;
1932 frag
= frag_more (4);
1933 where
= frag
- frag_now
->fr_literal
;
1934 bfd_putl16 ((bfd_vma
) bin
, frag
);
1935 if (op2
->exp
.X_op
== O_constant
)
1937 if (op2
->exp
.X_add_number
> 0xffff
1938 || op2
->exp
.X_add_number
< -(0x7fff))
1940 if (error_message_return
!= NULL
)
1941 * error_message_return
= _("index value too big for %s");
1944 bfd_putl16 (op2
->exp
.X_add_number
& 0xffff, frag
+ 2);
1948 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1949 fix_new_exp (frag_now
, where
+ 2, 2, &(op2
->exp
), FALSE
,
1951 BFD_RELOC_MSP430X_PCR16
:
1952 BFD_RELOC_MSP430X_ABS16
);
1957 if (error_message_return
!= NULL
)
1958 * error_message_return
= _("unexpected addressing mode for %s");
1963 /* imm_op == FALSE. */
1965 if (op1
->reg
== 2 && op1
->am
== 1 && op1
->mode
== OP_EXP
)
1967 /* MOVA &abs20, Rdst. */
1968 if (op2
->mode
!= OP_REG
)
1970 if (error_message_return
!= NULL
)
1971 * error_message_return
= _("expected register as second argument of %s");
1975 if (op2
->reg
== 2 || op2
->reg
== 3)
1977 if (error_message_return
!= NULL
)
1978 * error_message_return
= _("constant generator destination register found in %s");
1982 bin
|= 0x20 | op2
->reg
;
1983 frag
= frag_more (4);
1984 where
= frag
- frag_now
->fr_literal
;
1985 if (op1
->exp
.X_op
== O_constant
)
1987 bin
|= ((op1
->exp
.X_add_number
>> 16) & 0xf) << 8;
1988 bfd_putl16 ((bfd_vma
) bin
, frag
);
1989 bfd_putl16 (op1
->exp
.X_add_number
& 0xffff, frag
+ 2);
1993 bfd_putl16 ((bfd_vma
) bin
, frag
);
1994 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1995 fix_new_exp (frag_now
, where
, 4, &(op1
->exp
), FALSE
,
1996 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2000 else if (op1
->mode
== OP_REG
)
2004 /* MOVA @Rsrc+, Rdst. */
2005 if (op2
->mode
!= OP_REG
)
2007 if (error_message_return
!= NULL
)
2008 * error_message_return
= _("expected register as second argument of %s");
2012 if (op2
->reg
== 2 || op2
->reg
== 3)
2014 if (error_message_return
!= NULL
)
2015 * error_message_return
= _("constant generator destination register found in %s");
2019 if (op1
->reg
== 2 || op1
->reg
== 3)
2021 if (error_message_return
!= NULL
)
2022 * error_message_return
= _("constant generator source register found in %s");
2026 bin
|= 0x10 | (op1
->reg
<< 8) | op2
->reg
;
2027 frag
= frag_more (2);
2028 where
= frag
- frag_now
->fr_literal
;
2029 bfd_putl16 ((bfd_vma
) bin
, frag
);
2032 else if (op1
->am
== 2)
2034 /* MOVA @Rsrc,Rdst */
2035 if (op2
->mode
!= OP_REG
)
2037 if (error_message_return
!= NULL
)
2038 * error_message_return
= _("expected register as second argument of %s");
2042 if (op2
->reg
== 2 || op2
->reg
== 3)
2044 if (error_message_return
!= NULL
)
2045 * error_message_return
= _("constant generator destination register found in %s");
2049 if (op1
->reg
== 2 || op1
->reg
== 3)
2051 if (error_message_return
!= NULL
)
2052 * error_message_return
= _("constant generator source register found in %s");
2056 bin
|= (op1
->reg
<< 8) | op2
->reg
;
2057 frag
= frag_more (2);
2058 where
= frag
- frag_now
->fr_literal
;
2059 bfd_putl16 ((bfd_vma
) bin
, frag
);
2064 if (error_message_return
!= NULL
)
2065 * error_message_return
= _("unexpected addressing mode for %s");
2070 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2072 /* Parse instruction operands.
2073 Return binary opcode. */
2076 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
2078 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
2079 int insn_length
= 0;
2080 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
2083 struct msp430_operand_s op1
, op2
;
2085 static short ZEROS
= 0;
2086 int byte_op
, imm_op
;
2089 int extended
= 0x1800;
2090 bfd_boolean extended_op
= FALSE
;
2091 bfd_boolean addr_op
;
2092 const char * error_message
;
2093 static signed int repeat_count
= 0;
2094 bfd_boolean fix_emitted
;
2096 /* Opcode is the one from opcodes table
2097 line contains something like
2102 /* Check if byte or word operation. */
2103 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
2105 bin
|= BYTE_OPERATION
;
2111 /* "Address" ops work on 20-bit values. */
2112 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'a')
2115 bin
|= BYTE_OPERATION
;
2120 /* skip .[aAbwBW]. */
2121 while (! ISSPACE (*line
) && *line
)
2124 if (opcode
->fmt
!= -1
2125 && opcode
->insn_opnumb
2126 && (!*line
|| *line
== '\n'))
2128 as_bad (_("instruction %s requires %d operand(s)"),
2129 opcode
->name
, opcode
->insn_opnumb
);
2133 memset (l1
, 0, sizeof (l1
));
2134 memset (l2
, 0, sizeof (l2
));
2135 memset (&op1
, 0, sizeof (op1
));
2136 memset (&op2
, 0, sizeof (op2
));
2140 if ((fmt
= opcode
->fmt
) < 0)
2142 if (! target_is_430x ())
2144 as_bad (_("instruction %s requires MSP430X mcu"),
2155 /* If requested set the extended instruction repeat count. */
2158 if (repeat_count
> 0)
2159 extended
|= (repeat_count
- 1);
2161 extended
|= (1 << 7) | (- repeat_count
);
2164 as_bad (_("unable to repeat %s insn"), opcode
->name
);
2171 case 0: /* Emulated. */
2172 switch (opcode
->insn_opnumb
)
2175 /* Set/clear bits instructions. */
2179 extended
|= BYTE_OPERATION
;
2181 /* Emit the extension word. */
2183 frag
= frag_more (insn_length
);
2184 bfd_putl16 (extended
, frag
);
2188 frag
= frag_more (insn_length
);
2189 bfd_putl16 ((bfd_vma
) bin
, frag
);
2191 if (gen_interrupt_nops
2192 && target_is_430xv2 ()
2193 && (is_opcode ("eint") || is_opcode ("dint")))
2195 /* Emit a NOP following interrupt enable/disable.
2196 See 1.3.4.1 of the MSP430x5xx User Guide. */
2198 frag
= frag_more (2);
2199 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2201 dwarf2_emit_insn (insn_length
);
2205 /* Something which works with destination operand. */
2206 line
= extract_operand (line
, l1
, sizeof (l1
));
2207 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
, extended_op
, TRUE
);
2211 /* Compute the entire instruction length, in bytes. */
2212 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
2213 frag
= frag_more (insn_length
);
2214 where
= frag
- frag_now
->fr_literal
;
2219 extended
|= BYTE_OPERATION
;
2221 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
2223 as_bad (_("repeat instruction used with non-register mode instruction"));
2227 if (op1
.mode
== OP_EXP
)
2229 if (op1
.exp
.X_op
== O_constant
)
2230 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2232 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2233 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2234 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2236 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2237 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2240 /* Emit the extension word. */
2241 bfd_putl16 (extended
, frag
);
2246 bin
|= (op1
.reg
| (op1
.am
<< 7));
2247 bfd_putl16 ((bfd_vma
) bin
, frag
);
2251 if (op1
.mode
== OP_EXP
)
2253 if (op1
.exp
.X_op
== O_constant
)
2255 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2259 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2264 fix_new_exp (frag_now
, where
, 2,
2265 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2267 fix_new_exp (frag_now
, where
, 2,
2268 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2273 if (gen_interrupt_nops
2274 && target_is_430xv2 ()
2275 && is_opcode ("clr")
2276 && bin
== 0x4302 /* CLR R2*/)
2278 /* Emit a NOP following interrupt enable/disable.
2279 See 1.3.4.1 of the MSP430x5xx User Guide. */
2281 frag
= frag_more (2);
2282 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
2285 dwarf2_emit_insn (insn_length
);
2289 /* Shift instruction. */
2290 line
= extract_operand (line
, l1
, sizeof (l1
));
2291 strncpy (l2
, l1
, sizeof (l2
));
2292 l2
[sizeof (l2
) - 1] = '\0';
2293 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2294 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2297 break; /* An error occurred. All warnings were done before. */
2299 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2) + (op2
.ol
* 2);
2300 frag
= frag_more (insn_length
);
2301 where
= frag
- frag_now
->fr_literal
;
2303 /* Issue 3831743. */
2304 if (op1
.mode
== OP_REG
2306 && (is_opcode ("rlax")
2307 || is_opcode ("rlcx")
2308 || is_opcode ("rla")
2309 || is_opcode ("rlc")))
2311 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2318 extended
|= BYTE_OPERATION
;
2320 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2322 as_bad (_("repeat instruction used with non-register mode instruction"));
2326 if (op1
.mode
== OP_EXP
)
2328 if (op1
.exp
.X_op
== O_constant
)
2329 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2331 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2332 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2333 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2335 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2336 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2339 if (op2
.mode
== OP_EXP
)
2341 if (op2
.exp
.X_op
== O_constant
)
2342 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2344 else if (op1
.mode
== OP_EXP
)
2345 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2346 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2347 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2349 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2350 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2351 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2354 /* Emit the extension word. */
2355 bfd_putl16 (extended
, frag
);
2360 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2361 bfd_putl16 ((bfd_vma
) bin
, frag
);
2365 if (op1
.mode
== OP_EXP
)
2367 if (op1
.exp
.X_op
== O_constant
)
2369 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2373 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2377 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2378 fix_new_exp (frag_now
, where
, 2,
2379 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2381 fix_new_exp (frag_now
, where
, 2,
2382 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2389 if (op2
.mode
== OP_EXP
)
2391 if (op2
.exp
.X_op
== O_constant
)
2393 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
2397 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2401 if (op2
.reg
) /* Not PC relative. */
2402 fix_new_exp (frag_now
, where
, 2,
2403 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2405 fix_new_exp (frag_now
, where
, 2,
2406 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2411 dwarf2_emit_insn (insn_length
);
2415 /* Branch instruction => mov dst, r0. */
2418 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2422 line
= extract_operand (line
, l1
, sizeof (l1
));
2423 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, FALSE
);
2429 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
2430 op_length
= 2 + 2 * op1
.ol
;
2431 frag
= frag_more (op_length
);
2432 where
= frag
- frag_now
->fr_literal
;
2433 bfd_putl16 ((bfd_vma
) bin
, frag
);
2435 if (op1
.mode
== OP_EXP
)
2437 if (op1
.exp
.X_op
== O_constant
)
2439 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
+ 2);
2445 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2447 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3))
2448 fix_new_exp (frag_now
, where
, 2,
2449 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2451 fix_new_exp (frag_now
, where
, 2,
2452 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
2456 dwarf2_emit_insn (insn_length
+ op_length
);
2460 /* CALLA instructions. */
2461 fix_emitted
= FALSE
;
2463 line
= extract_operand (line
, l1
, sizeof (l1
));
2466 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
,
2467 extended_op
, FALSE
);
2473 op_length
= 2 + 2 * op1
.ol
;
2474 frag
= frag_more (op_length
);
2475 where
= frag
- frag_now
->fr_literal
;
2483 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2484 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2487 else if (op1
.am
== 1)
2493 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2494 BFD_RELOC_MSP430X_PCR20_CALL
);
2498 bin
|= 0x50 | op1
.reg
;
2500 else if (op1
.am
== 0)
2501 bin
|= 0x40 | op1
.reg
;
2503 else if (op1
.am
== 1)
2507 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2508 BFD_RELOC_MSP430X_ABS20_ADR_DST
);
2511 else if (op1
.am
== 2)
2512 bin
|= 0x60 | op1
.reg
;
2513 else if (op1
.am
== 3)
2514 bin
|= 0x70 | op1
.reg
;
2516 bfd_putl16 ((bfd_vma
) bin
, frag
);
2518 if (op1
.mode
== OP_EXP
)
2522 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1
.ol
);
2526 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
2529 fix_new_exp (frag_now
, where
+ 2, 2,
2530 &(op1
.exp
), FALSE
, BFD_RELOC_16
);
2533 dwarf2_emit_insn (insn_length
+ op_length
);
2541 /* [POP|PUSH]M[.A] #N, Rd */
2542 line
= extract_operand (line
, l1
, sizeof (l1
));
2543 line
= extract_operand (line
, l2
, sizeof (l2
));
2547 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
2550 parse_exp (l1
+ 1, &(op1
.exp
));
2551 if (op1
.exp
.X_op
!= O_constant
)
2553 as_bad (_("expected constant expression for first argument of %s"),
2558 if ((reg
= check_reg (l2
)) == -1)
2560 as_bad (_("expected register as second argument of %s"),
2566 frag
= frag_more (op_length
);
2567 where
= frag
- frag_now
->fr_literal
;
2568 bin
= opcode
->bin_opcode
;
2571 n
= op1
.exp
.X_add_number
;
2572 bin
|= (n
- 1) << 4;
2573 if (is_opcode ("pushm"))
2577 if (reg
- n
+ 1 < 0)
2579 as_bad (_("Too many registers popped"));
2583 /* Issue 3831713: CPU21 parts cannot use POPM to restore the SR register. */
2584 if (target_is_430x ()
2585 && (reg
- n
+ 1 < 3)
2587 && is_opcode ("popm"))
2589 as_bad (_("Cannot use POPM to restore the SR register"));
2593 bin
|= (reg
- n
+ 1);
2596 bfd_putl16 ((bfd_vma
) bin
, frag
);
2597 dwarf2_emit_insn (op_length
);
2606 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2607 if (extended
& 0xff)
2609 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2613 line
= extract_operand (line
, l1
, sizeof (l1
));
2614 line
= extract_operand (line
, l2
, sizeof (l2
));
2618 as_bad (_("expected #n as first argument of %s"), opcode
->name
);
2621 parse_exp (l1
+ 1, &(op1
.exp
));
2622 if (op1
.exp
.X_op
!= O_constant
)
2624 as_bad (_("expected constant expression for first argument of %s"),
2628 n
= op1
.exp
.X_add_number
;
2631 as_bad (_("expected first argument of %s to be in the range 1-4"),
2636 if ((reg
= check_reg (l2
)) == -1)
2638 as_bad (_("expected register as second argument of %s"),
2643 /* Issue 3831743. */
2646 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2651 frag
= frag_more (op_length
);
2652 where
= frag
- frag_now
->fr_literal
;
2654 bin
= opcode
->bin_opcode
;
2657 bin
|= (n
- 1) << 10;
2660 bfd_putl16 ((bfd_vma
) bin
, frag
);
2661 dwarf2_emit_insn (op_length
);
2669 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2670 if (extended
& 0xff)
2672 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2676 line
= extract_operand (line
, l1
, sizeof (l1
));
2677 if ((reg
= check_reg (l1
)) == -1)
2679 as_bad (_("expected register as argument of %s"),
2684 /* Issue 3831743. */
2687 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
2693 /* Tricky - there is no single instruction that will do this.
2694 Encode as: RRA.B rN { BIC.B #0x80, rN */
2696 frag
= frag_more (op_length
);
2697 where
= frag
- frag_now
->fr_literal
;
2699 bfd_putl16 ((bfd_vma
) bin
, frag
);
2700 dwarf2_emit_insn (2);
2702 bfd_putl16 ((bfd_vma
) bin
, frag
+ 2);
2704 bfd_putl16 ((bfd_vma
) bin
, frag
+ 4);
2705 dwarf2_emit_insn (4);
2709 /* Encode as RRUM[.A] rN. */
2710 bin
= opcode
->bin_opcode
;
2715 frag
= frag_more (op_length
);
2716 where
= frag
- frag_now
->fr_literal
;
2717 bfd_putl16 ((bfd_vma
) bin
, frag
);
2718 dwarf2_emit_insn (op_length
);
2725 bfd_boolean need_reloc
= FALSE
;
2729 /* ADDA, CMPA and SUBA address instructions. */
2730 if (extended
& 0xff)
2732 as_bad (_("repeat count cannot be used with %s"), opcode
->name
);
2736 line
= extract_operand (line
, l1
, sizeof (l1
));
2737 line
= extract_operand (line
, l2
, sizeof (l2
));
2739 bin
= opcode
->bin_opcode
;
2743 parse_exp (l1
+ 1, &(op1
.exp
));
2745 if (op1
.exp
.X_op
== O_constant
)
2747 n
= op1
.exp
.X_add_number
;
2748 if (n
> 0xfffff || n
< - (0x7ffff))
2750 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2755 bin
|= ((n
>> 16) & 0xf) << 8;
2767 if ((n
= check_reg (l1
)) == -1)
2769 as_bad (_("expected register name or constant as first argument of %s"),
2774 bin
|= (n
<< 8) | (1 << 6);
2778 if ((reg
= check_reg (l2
)) == -1)
2780 as_bad (_("expected register as second argument of %s"),
2785 frag
= frag_more (op_length
);
2786 where
= frag
- frag_now
->fr_literal
;
2789 fix_new_exp (frag_now
, where
, 4, &(op1
.exp
), FALSE
,
2790 BFD_RELOC_MSP430X_ABS20_ADR_SRC
);
2792 bfd_putl16 ((bfd_vma
) bin
, frag
);
2794 bfd_putl16 ((bfd_vma
) (n
& 0xffff), frag
+ 2);
2795 dwarf2_emit_insn (op_length
);
2799 case 9: /* MOVA, BRA, RETA. */
2801 bin
= opcode
->bin_opcode
;
2803 if (is_opcode ("reta"))
2805 /* The RETA instruction does not take any arguments.
2806 The implicit first argument is @SP+.
2807 The implicit second argument is PC. */
2817 line
= extract_operand (line
, l1
, sizeof (l1
));
2818 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
2819 &imm_op
, extended_op
, FALSE
);
2821 if (is_opcode ("bra"))
2823 /* This is the BRA synthetic instruction.
2824 The second argument is always PC. */
2830 line
= extract_operand (line
, l2
, sizeof (l2
));
2831 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
,
2836 break; /* Error occurred. All warnings were done before. */
2839 /* Only a restricted subset of the normal MSP430 addressing modes
2840 are supported here, so check for the ones that are allowed. */
2841 if ((op_length
= try_encode_mova (imm_op
, bin
, & op1
, & op2
,
2842 & error_message
)) == 0)
2844 as_bad (error_message
, opcode
->name
);
2847 dwarf2_emit_insn (op_length
);
2851 line
= extract_operand (line
, l1
, sizeof l1
);
2852 /* The RPT instruction only accepted immediates and registers. */
2855 parse_exp (l1
+ 1, &(op1
.exp
));
2856 if (op1
.exp
.X_op
!= O_constant
)
2858 as_bad (_("expected constant value as argument to RPT"));
2861 if (op1
.exp
.X_add_number
< 1
2862 || op1
.exp
.X_add_number
> (1 << 4))
2864 as_bad (_("expected constant in the range 2..16"));
2868 /* We silently accept and ignore a repeat count of 1. */
2869 if (op1
.exp
.X_add_number
> 1)
2870 repeat_count
= op1
.exp
.X_add_number
;
2876 if ((reg
= check_reg (l1
)) != -1)
2879 as_warn (_("PC used as an argument to RPT"));
2881 repeat_count
= - reg
;
2885 as_bad (_("expected constant or register name as argument to RPT insn"));
2892 as_bad (_("Illegal emulated instruction "));
2897 case 1: /* Format 1, double operand. */
2898 line
= extract_operand (line
, l1
, sizeof (l1
));
2899 line
= extract_operand (line
, l2
, sizeof (l2
));
2900 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
, extended_op
, TRUE
);
2901 res
+= msp430_dstoperand (&op2
, l2
, opcode
->bin_opcode
, extended_op
, TRUE
);
2904 break; /* Error occurred. All warnings were done before. */
2907 && is_opcode ("movx")
2909 && msp430_enable_relax
)
2911 /* This is the MOVX.A instruction. See if we can convert
2912 it into the MOVA instruction instead. This saves 2 bytes. */
2913 if ((op_length
= try_encode_mova (imm_op
, 0x0000, & op1
, & op2
,
2916 dwarf2_emit_insn (op_length
);
2921 /* Compute the entire length of the instruction in bytes. */
2923 (extended_op
? 2 : 0) /* The extension word. */
2924 + 2 /* The opcode */
2925 + (2 * op1
.ol
) /* The first operand. */
2926 + (2 * op2
.ol
); /* The second operand. */
2928 frag
= frag_more (insn_length
);
2929 where
= frag
- frag_now
->fr_literal
;
2934 extended
|= BYTE_OPERATION
;
2936 if ((op1
.ol
!= 0 || op2
.ol
!= 0) && ((extended
& 0xf) != 0))
2938 as_bad (_("repeat instruction used with non-register mode instruction"));
2942 /* If necessary, emit a reloc to update the extension word. */
2943 if (op1
.mode
== OP_EXP
)
2945 if (op1
.exp
.X_op
== O_constant
)
2946 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
2948 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2949 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2950 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
2952 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
2953 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
2956 if (op2
.mode
== OP_EXP
)
2958 if (op2
.exp
.X_op
== O_constant
)
2959 extended
|= (op2
.exp
.X_add_number
>> 16) & 0xf;
2961 else if (op1
.mode
== OP_EXP
)
2962 fix_new_exp (frag_now
, where
, 8, &(op2
.exp
), FALSE
,
2963 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2964 : BFD_RELOC_MSP430X_PCR20_EXT_ODST
);
2967 fix_new_exp (frag_now
, where
, 6, &(op2
.exp
), FALSE
,
2968 op2
.reg
? BFD_RELOC_MSP430X_ABS20_EXT_DST
2969 : BFD_RELOC_MSP430X_PCR20_EXT_DST
);
2972 /* Emit the extension word. */
2973 bfd_putl16 (extended
, frag
);
2978 bin
|= (op2
.reg
| (op1
.reg
<< 8) | (op1
.am
<< 4) | (op2
.am
<< 7));
2979 bfd_putl16 ((bfd_vma
) bin
, frag
);
2983 if (op1
.mode
== OP_EXP
)
2985 if (op1
.exp
.X_op
== O_constant
)
2987 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
2991 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
2995 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
2996 fix_new_exp (frag_now
, where
, 2,
2997 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
2999 fix_new_exp (frag_now
, where
, 2,
3000 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3008 if (op2
.mode
== OP_EXP
)
3010 if (op2
.exp
.X_op
== O_constant
)
3012 bfd_putl16 (op2
.exp
.X_add_number
& 0xffff, frag
);
3016 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3020 if (op2
.reg
) /* Not PC relative. */
3021 fix_new_exp (frag_now
, where
, 2,
3022 &(op2
.exp
), FALSE
, CHECK_RELOC_MSP430
);
3024 fix_new_exp (frag_now
, where
, 2,
3025 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3030 if (gen_interrupt_nops
3031 && target_is_430xv2 ()
3032 && ( (is_opcode ("bic") && bin
== 0xc232)
3033 || (is_opcode ("bis") && bin
== 0xd232)
3034 || (is_opcode ("mov") && op2
.mode
== OP_REG
&& op2
.reg
== 2)))
3036 /* Emit a NOP following interrupt enable/disable.
3037 See 1.3.4.1 of the MSP430x5xx User Guide. */
3039 frag
= frag_more (2);
3040 bfd_putl16 ((bfd_vma
) 0x4303 /* NOP */, frag
);
3043 dwarf2_emit_insn (insn_length
);
3046 case 2: /* Single-operand mostly instr. */
3047 if (opcode
->insn_opnumb
== 0)
3049 /* reti instruction. */
3051 frag
= frag_more (2);
3052 bfd_putl16 ((bfd_vma
) bin
, frag
);
3053 dwarf2_emit_insn (insn_length
);
3057 line
= extract_operand (line
, l1
, sizeof (l1
));
3058 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
,
3059 &imm_op
, extended_op
, TRUE
);
3061 break; /* Error in operand. */
3063 /* Issue 3831743. */
3064 if (op1
.mode
== OP_REG
3066 && (is_opcode ("rrax")
3067 || is_opcode ("rrcx")
3068 || is_opcode ("rra")
3069 || is_opcode ("rrc")))
3071 as_bad (_("%s: attempt to rotate the PC register"), opcode
->name
);
3075 insn_length
= (extended_op
? 2 : 0) + 2 + (op1
.ol
* 2);
3076 frag
= frag_more (insn_length
);
3077 where
= frag
- frag_now
->fr_literal
;
3081 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3083 /* These two instructions use a special
3084 encoding of the A/L and B/W bits. */
3085 bin
&= ~ BYTE_OPERATION
;
3089 as_bad (_("%s instruction does not accept a .b suffix"),
3094 extended
|= BYTE_OPERATION
;
3097 extended
|= BYTE_OPERATION
;
3099 if (op1
.ol
!= 0 && ((extended
& 0xf) != 0))
3101 as_bad (_("repeat instruction used with non-register mode instruction"));
3105 if (op1
.mode
== OP_EXP
)
3107 if (op1
.exp
.X_op
== O_constant
)
3108 extended
|= ((op1
.exp
.X_add_number
>> 16) & 0xf) << 7;
3110 else if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
3111 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3112 BFD_RELOC_MSP430X_ABS20_EXT_SRC
);
3114 fix_new_exp (frag_now
, where
, 6, &(op1
.exp
), FALSE
,
3115 BFD_RELOC_MSP430X_PCR20_EXT_SRC
);
3118 /* Emit the extension word. */
3119 bfd_putl16 (extended
, frag
);
3124 bin
|= op1
.reg
| (op1
.am
<< 4);
3125 bfd_putl16 ((bfd_vma
) bin
, frag
);
3129 if (op1
.mode
== OP_EXP
)
3131 if (op1
.exp
.X_op
== O_constant
)
3133 bfd_putl16 (op1
.exp
.X_add_number
& 0xffff, frag
);
3137 bfd_putl16 ((bfd_vma
) ZEROS
, frag
);
3141 if (op1
.reg
|| (op1
.reg
== 0 && op1
.am
== 3)) /* Not PC relative. */
3142 fix_new_exp (frag_now
, where
, 2,
3143 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
3145 fix_new_exp (frag_now
, where
, 2,
3146 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
3151 dwarf2_emit_insn (insn_length
);
3154 case 3: /* Conditional jumps instructions. */
3155 line
= extract_operand (line
, l1
, sizeof (l1
));
3156 /* l1 is a label. */
3165 parse_exp (m
, &exp
);
3167 /* In order to handle something like:
3171 jz 4 ; skip next 4 bytes
3174 nop ; will jump here if r5 positive or zero
3176 jCOND -n ;assumes jump n bytes backward:
3186 jCOND $n ; jump from PC in either direction. */
3188 if (exp
.X_op
== O_constant
)
3190 int x
= exp
.X_add_number
;
3194 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
3198 if ((*l1
== '$' && x
> 0) || x
< 0)
3203 if (x
> 512 || x
< -511)
3205 as_bad (_("Wrong displacement %d"), x
<< 1);
3210 frag
= frag_more (2); /* Instr size is 1 word. */
3213 bfd_putl16 ((bfd_vma
) bin
, frag
);
3215 else if (exp
.X_op
== O_symbol
&& *l1
!= '$')
3218 frag
= frag_more (2); /* Instr size is 1 word. */
3219 where
= frag
- frag_now
->fr_literal
;
3220 fix_new_exp (frag_now
, where
, 2,
3221 &exp
, TRUE
, BFD_RELOC_MSP430_10_PCREL
);
3223 bfd_putl16 ((bfd_vma
) bin
, frag
);
3225 else if (*l1
== '$')
3227 as_bad (_("instruction requires label sans '$'"));
3231 ("instruction requires label or value in range -511:512"));
3232 dwarf2_emit_insn (insn_length
);
3237 as_bad (_("instruction requires label"));
3242 case 4: /* Extended jumps. */
3243 if (!msp430_enable_polys
)
3245 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3249 line
= extract_operand (line
, l1
, sizeof (l1
));
3255 /* Ignore absolute addressing. make it PC relative anyway. */
3256 if (*m
== '#' || *m
== '$')
3259 parse_exp (m
, & exp
);
3260 if (exp
.X_op
== O_symbol
)
3262 /* Relaxation required. */
3263 struct rcodes_s rc
= msp430_rcodes
[opcode
->insn_opnumb
];
3265 if (target_is_430x ())
3266 rc
= msp430x_rcodes
[opcode
->insn_opnumb
];
3268 /* The parameter to dwarf2_emit_insn is actually the offset to
3269 the start of the insn from the fix piece of instruction that
3270 was emitted. Since next fragments may have variable size we
3271 tie debug info to the beginning of the instruction. */
3273 frag
= frag_more (8);
3274 dwarf2_emit_insn (0);
3275 bfd_putl16 ((bfd_vma
) rc
.sop
, frag
);
3276 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3278 ENCODE_RELAX (rc
.lpos
, STATE_BITS10
),
3280 0, /* Offset is zero if jump dist less than 1K. */
3286 as_bad (_("instruction requires label"));
3289 case 5: /* Emulated extended branches. */
3290 if (!msp430_enable_polys
)
3292 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3295 line
= extract_operand (line
, l1
, sizeof (l1
));
3301 /* Ignore absolute addressing. make it PC relative anyway. */
3302 if (*m
== '#' || *m
== '$')
3305 parse_exp (m
, & exp
);
3306 if (exp
.X_op
== O_symbol
)
3308 /* Relaxation required. */
3309 struct hcodes_s hc
= msp430_hcodes
[opcode
->insn_opnumb
];
3311 if (target_is_430x ())
3312 hc
= msp430x_hcodes
[opcode
->insn_opnumb
];
3315 frag
= frag_more (8);
3316 dwarf2_emit_insn (0);
3317 bfd_putl16 ((bfd_vma
) hc
.op0
, frag
);
3318 bfd_putl16 ((bfd_vma
) hc
.op1
, frag
+2);
3320 frag
= frag_variant (rs_machine_dependent
, 8, 2,
3321 ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
), /* Wild guess. */
3323 0, /* Offset is zero if jump dist less than 1K. */
3329 as_bad (_("instruction requires label"));
3333 as_bad (_("Illegal instruction or not implemented opcode."));
3336 input_line_pointer
= line
;
3341 md_assemble (char * str
)
3343 struct msp430_opcode_s
* opcode
;
3347 str
= skip_space (str
); /* Skip leading spaces. */
3348 str
= extract_cmd (str
, cmd
, sizeof (cmd
));
3350 while (cmd
[i
] && i
< sizeof (cmd
))
3352 char a
= TOLOWER (cmd
[i
]);
3359 as_bad (_("can't find opcode "));
3363 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
3367 as_bad (_("unknown opcode `%s'"), cmd
);
3372 char *__t
= input_line_pointer
;
3374 msp430_operands (opcode
, str
);
3375 input_line_pointer
= __t
;
3379 /* GAS will call this function for each section at the end of the assembly,
3380 to permit the CPU backend to adjust the alignment of a section. */
3383 md_section_align (asection
* seg
, valueT addr
)
3385 int align
= bfd_get_section_alignment (stdoutput
, seg
);
3387 return ((addr
+ (1 << align
) - 1) & (-1 << align
));
3390 /* If you define this macro, it should return the offset between the
3391 address of a PC relative fixup and the position from which the PC
3392 relative adjustment should be made. On many processors, the base
3393 of a PC relative instruction is the next instruction, so this
3394 macro would return the length of an instruction. */
3397 md_pcrel_from_section (fixS
* fixp
, segT sec
)
3399 if (fixp
->fx_addsy
!= (symbolS
*) NULL
3400 && (!S_IS_DEFINED (fixp
->fx_addsy
)
3401 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
3404 return fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3407 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3408 Now it handles the situation when relocations
3409 have to be passed to linker. */
3411 msp430_force_relocation_local (fixS
*fixp
)
3413 if (fixp
->fx_r_type
== BFD_RELOC_MSP430_10_PCREL
)
3417 if (msp430_enable_polys
3418 && !msp430_enable_relax
)
3421 return (!fixp
->fx_pcrel
3422 || generic_force_reloc (fixp
));
3426 /* GAS will call this for each fixup. It should store the correct
3427 value in the object file. */
3429 md_apply_fix (fixS
* fixp
, valueT
* valuep
, segT seg
)
3431 unsigned char * where
;
3435 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
3440 else if (fixp
->fx_pcrel
)
3442 segT s
= S_GET_SEGMENT (fixp
->fx_addsy
);
3444 if (fixp
->fx_addsy
&& (s
== seg
|| s
== absolute_section
))
3446 /* FIXME: We can appear here only in case if we perform a pc
3447 relative jump to the label which is i) global, ii) locally
3448 defined or this is a jump to an absolute symbol.
3449 If this is an absolute symbol -- everything is OK.
3450 If this is a global label, we've got a symbol value defined
3452 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3453 from this section start
3454 2. *valuep will contain the real offset from jump insn to the
3456 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3457 will be incorrect. Therefore remove s_get_value. */
3458 value
= /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep
;
3466 value
= fixp
->fx_offset
;
3468 if (fixp
->fx_subsy
!= (symbolS
*) NULL
)
3470 if (S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3472 value
-= S_GET_VALUE (fixp
->fx_subsy
);
3478 fixp
->fx_no_overflow
= 1;
3480 /* If polymorphs are enabled and relax disabled.
3481 do not kill any relocs and pass them to linker. */
3482 if (msp430_enable_polys
3483 && !msp430_enable_relax
)
3485 if (!fixp
->fx_addsy
|| (fixp
->fx_addsy
3486 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
))
3487 fixp
->fx_done
= 1; /* It is ok to kill 'abs' reloc. */
3494 /* Fetch the instruction, insert the fully resolved operand
3495 value, and stuff the instruction back again. */
3496 where
= (unsigned char *) fixp
->fx_frag
->fr_literal
+ fixp
->fx_where
;
3498 insn
= bfd_getl16 (where
);
3500 switch (fixp
->fx_r_type
)
3502 case BFD_RELOC_MSP430_10_PCREL
:
3504 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3505 _("odd address operand: %ld"), value
);
3507 /* Jumps are in words. */
3509 --value
; /* Correct PC. */
3511 if (value
< -512 || value
> 511)
3512 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3513 _("operand out of range: %ld"), value
);
3515 value
&= 0x3ff; /* get rid of extended sign */
3516 bfd_putl16 ((bfd_vma
) (value
| insn
), where
);
3519 case BFD_RELOC_MSP430X_PCR16
:
3520 case BFD_RELOC_MSP430_RL_PCREL
:
3521 case BFD_RELOC_MSP430_16_PCREL
:
3523 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3524 _("odd address operand: %ld"), value
);
3527 case BFD_RELOC_MSP430_16_PCREL_BYTE
:
3528 /* Nothing to be corrected here. */
3529 if (value
< -32768 || value
> 65536)
3530 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3531 _("operand out of range: %ld"), value
);
3534 case BFD_RELOC_MSP430X_ABS16
:
3535 case BFD_RELOC_MSP430_16
:
3537 case BFD_RELOC_MSP430_16_BYTE
:
3538 value
&= 0xffff; /* Get rid of extended sign. */
3539 bfd_putl16 ((bfd_vma
) value
, where
);
3543 bfd_putl16 ((bfd_vma
) value
, where
);
3546 case BFD_RELOC_MSP430_ABS8
:
3548 bfd_put_8 (NULL
, (bfd_vma
) value
, where
);
3551 case BFD_RELOC_MSP430X_ABS20_EXT_SRC
:
3552 case BFD_RELOC_MSP430X_PCR20_EXT_SRC
:
3553 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3555 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 7) | insn
), where
);
3558 case BFD_RELOC_MSP430X_ABS20_ADR_SRC
:
3559 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3561 bfd_putl16 ((bfd_vma
) (((value
& 0xf) << 8) | insn
), where
);
3564 case BFD_RELOC_MSP430X_ABS20_EXT_ODST
:
3565 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3567 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3570 case BFD_RELOC_MSP430X_PCR20_CALL
:
3571 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3573 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3576 case BFD_RELOC_MSP430X_ABS20_EXT_DST
:
3577 case BFD_RELOC_MSP430X_PCR20_EXT_DST
:
3578 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 4);
3580 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3583 case BFD_RELOC_MSP430X_PCR20_EXT_ODST
:
3584 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 6);
3586 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3589 case BFD_RELOC_MSP430X_ABS20_ADR_DST
:
3590 bfd_putl16 ((bfd_vma
) (value
& 0xffff), where
+ 2);
3592 bfd_putl16 ((bfd_vma
) ((value
& 0xf) | insn
), where
);
3596 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3597 fixp
->fx_line
, fixp
->fx_r_type
);
3603 fixp
->fx_addnumber
= value
;
3608 S_IS_GAS_LOCAL (symbolS
* s
)
3615 name
= S_GET_NAME (s
);
3616 len
= strlen (name
) - 1;
3618 return name
[len
] == 1 || name
[len
] == 2;
3621 /* GAS will call this to generate a reloc, passing the resulting reloc
3622 to `bfd_install_relocation'. This currently works poorly, as
3623 `bfd_install_relocation' often does the wrong thing, and instances of
3624 `tc_gen_reloc' have been written to work around the problems, which
3625 in turns makes it difficult to fix `bfd_install_relocation'. */
3627 /* If while processing a fixup, a reloc really needs to be created
3628 then it is done here. */
3631 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
3633 static arelent
* no_relocs
= NULL
;
3634 static arelent
* relocs
[MAX_RELOC_EXPANSION
+ 1];
3637 reloc
= xmalloc (sizeof (arelent
));
3638 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3639 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3641 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3643 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3644 _("reloc %d not supported by object file format"),
3645 (int) fixp
->fx_r_type
);
3654 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
3656 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
3657 fixp
->fx_subsy
= NULL
;
3660 if (fixp
->fx_addsy
&& fixp
->fx_subsy
)
3662 asection
*asec
, *ssec
;
3664 asec
= S_GET_SEGMENT (fixp
->fx_addsy
);
3665 ssec
= S_GET_SEGMENT (fixp
->fx_subsy
);
3667 /* If we have a difference between two different, non-absolute symbols
3668 we must generate two relocs (one for each symbol) and allow the
3669 linker to resolve them - relaxation may change the distances between
3670 symbols, even local symbols defined in the same section.
3672 Unfortunately we cannot do this with assembler generated local labels
3673 because there can be multiple incarnations of the same label, with
3674 exactly the same name, in any given section and the linker will have
3675 no way to identify the correct one. Instead we just have to hope
3676 that no relaxtion will occur between the local label and the other
3677 symbol in the expression.
3679 Similarly we have to compute differences between symbols in the .eh_frame
3680 section as the linker is not smart enough to apply relocations there
3681 before attempting to process it. */
3682 if ((ssec
!= absolute_section
|| asec
!= absolute_section
)
3683 && (fixp
->fx_addsy
!= fixp
->fx_subsy
)
3684 && strcmp (ssec
->name
, ".eh_frame") != 0
3685 && ! S_IS_GAS_LOCAL (fixp
->fx_addsy
)
3686 && ! S_IS_GAS_LOCAL (fixp
->fx_subsy
))
3688 arelent
* reloc2
= xmalloc (sizeof * reloc
);
3693 reloc2
->address
= reloc
->address
;
3694 reloc2
->howto
= bfd_reloc_type_lookup (stdoutput
,
3695 BFD_RELOC_MSP430_SYM_DIFF
);
3696 reloc2
->addend
= - S_GET_VALUE (fixp
->fx_subsy
);
3698 if (ssec
== absolute_section
)
3699 reloc2
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
3702 reloc2
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3703 *reloc2
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
3706 reloc
->addend
= fixp
->fx_offset
;
3707 if (asec
== absolute_section
)
3709 reloc
->addend
+= S_GET_VALUE (fixp
->fx_addsy
);
3710 reloc
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
3714 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3715 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3724 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
3726 reloc
->addend
= (S_GET_VALUE (fixp
->fx_addsy
)
3727 - S_GET_VALUE (fixp
->fx_subsy
) + fixp
->fx_offset
);
3729 switch (fixp
->fx_r_type
)
3732 md_number_to_chars (fixpos
, reloc
->addend
, 1);
3736 md_number_to_chars (fixpos
, reloc
->addend
, 2);
3740 md_number_to_chars (fixpos
, reloc
->addend
, 3);
3744 md_number_to_chars (fixpos
, reloc
->addend
, 4);
3749 = (asymbol
**) bfd_abs_section_ptr
->symbol_ptr_ptr
;
3760 if (fixp
->fx_r_type
== BFD_RELOC_MSP430X_ABS16
3761 && S_GET_SEGMENT (fixp
->fx_addsy
) == absolute_section
)
3763 bfd_vma amount
= S_GET_VALUE (fixp
->fx_addsy
);
3764 char *fixpos
= fixp
->fx_where
+ fixp
->fx_frag
->fr_literal
;
3766 md_number_to_chars (fixpos
, amount
, 2);
3771 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
3772 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3773 reloc
->addend
= fixp
->fx_offset
;
3775 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3776 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3777 reloc
->address
= fixp
->fx_offset
;
3784 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
3785 asection
* segment_type ATTRIBUTE_UNUSED
)
3787 if (fragP
->fr_symbol
&& S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
3789 /* This is a jump -> pcrel mode. Nothing to do much here.
3790 Return value == 2. */
3792 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_BITS10
);
3794 else if (fragP
->fr_symbol
)
3796 /* Its got a segment, but its not ours. Even if fr_symbol is in
3797 an absolute segment, we don't know a displacement until we link
3798 object files. So it will always be long. This also applies to
3799 labels in a subsegment of current. Liker may relax it to short
3800 jump later. Return value == 8. */
3802 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
3806 /* We know the abs value. may be it is a jump to fixed address.
3807 Impossible in our case, cause all constants already handled. */
3809 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
3812 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
3816 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
3817 asection
* sec ATTRIBUTE_UNUSED
,
3823 struct rcodes_s
* cc
= NULL
;
3824 struct hcodes_s
* hc
= NULL
;
3826 switch (fragP
->fr_subtype
)
3828 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_BITS10
):
3829 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_BITS10
):
3830 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_BITS10
):
3831 /* We do not have to convert anything here.
3832 Just apply a fix. */
3833 rela
= BFD_RELOC_MSP430_10_PCREL
;
3836 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_WORD
):
3837 case ENCODE_RELAX (STATE_UNCOND_BRANCH
, STATE_UNDEF
):
3838 /* Convert uncond branch jmp lab -> br lab. */
3839 if (target_is_430x ())
3840 cc
= msp430x_rcodes
+ 7;
3842 cc
= msp430_rcodes
+ 7;
3843 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3844 bfd_putl16 (cc
->lop0
, where
);
3845 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3849 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_WORD
):
3850 case ENCODE_RELAX (STATE_SIMPLE_BRANCH
, STATE_UNDEF
):
3852 /* Other simple branches. */
3853 int insn
= bfd_getl16 (fragP
->fr_opcode
);
3856 /* Find actual instruction. */
3857 if (target_is_430x ())
3859 for (i
= 0; i
< 7 && !cc
; i
++)
3860 if (msp430x_rcodes
[i
].sop
== insn
)
3861 cc
= msp430x_rcodes
+ i
;
3865 for (i
= 0; i
< 7 && !cc
; i
++)
3866 if (msp430_rcodes
[i
].sop
== insn
)
3867 cc
= & msp430_rcodes
[i
];
3870 if (!cc
|| !cc
->name
)
3871 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3872 __FUNCTION__
, (long) insn
);
3873 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3874 bfd_putl16 (cc
->lop0
, where
);
3875 bfd_putl16 (cc
->lop1
, where
+ 2);
3876 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3881 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_WORD
):
3882 case ENCODE_RELAX (STATE_NOOV_BRANCH
, STATE_UNDEF
):
3883 if (target_is_430x ())
3884 cc
= msp430x_rcodes
+ 6;
3886 cc
= msp430_rcodes
+ 6;
3887 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3888 bfd_putl16 (cc
->lop0
, where
);
3889 bfd_putl16 (cc
->lop1
, where
+ 2);
3890 bfd_putl16 (cc
->lop2
, where
+ 4);
3891 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3895 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
3897 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
3900 if (target_is_430x ())
3902 for (i
= 0; i
< 4 && !hc
; i
++)
3903 if (msp430x_hcodes
[i
].op1
== insn
)
3904 hc
= msp430x_hcodes
+ i
;
3908 for (i
= 0; i
< 4 && !hc
; i
++)
3909 if (msp430_hcodes
[i
].op1
== insn
)
3910 hc
= &msp430_hcodes
[i
];
3912 if (!hc
|| !hc
->name
)
3913 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3914 __FUNCTION__
, (long) insn
);
3915 rela
= BFD_RELOC_MSP430_10_PCREL
;
3916 /* Apply a fix for a first label if necessary.
3917 another fix will be applied to the next word of insn anyway. */
3919 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3920 fragP
->fr_offset
, TRUE
, rela
);
3926 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_WORD
):
3927 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_UNDEF
):
3929 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
3932 if (target_is_430x ())
3934 for (i
= 0; i
< 4 && !hc
; i
++)
3935 if (msp430x_hcodes
[i
].op1
== insn
)
3936 hc
= msp430x_hcodes
+ i
;
3940 for (i
= 0; i
< 4 && !hc
; i
++)
3941 if (msp430_hcodes
[i
].op1
== insn
)
3942 hc
= & msp430_hcodes
[i
];
3944 if (!hc
|| !hc
->name
)
3945 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
3946 __FUNCTION__
, (long) insn
);
3947 rela
= BFD_RELOC_MSP430_RL_PCREL
;
3948 where
= fragP
->fr_literal
+ fragP
->fr_fix
;
3949 bfd_putl16 (hc
->lop0
, where
);
3950 bfd_putl16 (hc
->lop1
, where
+ 2);
3951 bfd_putl16 (hc
->lop2
, where
+ 4);
3957 as_fatal (_("internal inconsistency problem in %s: %lx"),
3958 __FUNCTION__
, (long) fragP
->fr_subtype
);
3962 /* Now apply fix. */
3963 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
3964 fragP
->fr_offset
, TRUE
, rela
);
3965 /* Just fixed 2 bytes. */
3969 /* Relax fragment. Mostly stolen from hc11 and mcore
3970 which arches I think I know. */
3973 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
3974 long stretch ATTRIBUTE_UNUSED
)
3979 const relax_typeS
*this_type
;
3980 const relax_typeS
*start_type
;
3981 relax_substateT next_state
;
3982 relax_substateT this_state
;
3983 const relax_typeS
*table
= md_relax_table
;
3985 /* Nothing to be done if the frag has already max size. */
3986 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_UNDEF
3987 || RELAX_STATE (fragP
->fr_subtype
) == STATE_WORD
)
3990 if (RELAX_STATE (fragP
->fr_subtype
) == STATE_BITS10
)
3992 symbolP
= fragP
->fr_symbol
;
3993 if (symbol_resolved_p (symbolP
))
3994 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
3996 /* We know the offset. calculate a distance. */
3997 aim
= S_GET_VALUE (symbolP
) - fragP
->fr_address
- fragP
->fr_fix
;
4000 if (!msp430_enable_relax
)
4002 /* Relaxation is not enabled. So, make all jump as long ones
4003 by setting 'aim' to quite high value. */
4007 this_state
= fragP
->fr_subtype
;
4008 start_type
= this_type
= table
+ this_state
;
4012 /* Look backwards. */
4013 for (next_state
= this_type
->rlx_more
; next_state
;)
4014 if (aim
>= this_type
->rlx_backward
|| !this_type
->rlx_backward
)
4018 /* Grow to next state. */
4019 this_state
= next_state
;
4020 this_type
= table
+ this_state
;
4021 next_state
= this_type
->rlx_more
;
4026 /* Look forwards. */
4027 for (next_state
= this_type
->rlx_more
; next_state
;)
4028 if (aim
<= this_type
->rlx_forward
|| !this_type
->rlx_forward
)
4032 /* Grow to next state. */
4033 this_state
= next_state
;
4034 this_type
= table
+ this_state
;
4035 next_state
= this_type
->rlx_more
;
4039 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
4041 fragP
->fr_subtype
= this_state
;
4045 /* Return FALSE if the fixup in fixp should be left alone and not
4046 adjusted. We return FALSE here so that linker relaxation will
4050 msp430_fix_adjustable (struct fix
*fixp ATTRIBUTE_UNUSED
)
4052 /* If the symbol is in a non-code section then it should be OK. */
4054 && ((S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_CODE
) == 0))
4060 /* Set the contents of the .MSP430.attributes section. */
4063 msp430_md_end (void)
4065 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_ISA
,
4066 target_is_430x () ? 2 : 1);
4068 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Code_Model
,
4069 large_model
? 2 : 1);
4071 bfd_elf_add_proc_attr_int (stdoutput
, OFBA_MSPABI_Tag_Data_Model
,
4072 large_model
? 2 : 1);
4075 /* Returns FALSE if there is a msp430 specific reason why the
4076 subtraction of two same-section symbols cannot be computed by
4080 msp430_allow_local_subtract (expressionS
* left
,
4081 expressionS
* right
,
4084 /* If the symbols are not in a code section then they are OK. */
4085 if ((section
->flags
& SEC_CODE
) == 0)
4088 if (S_IS_GAS_LOCAL (left
->X_add_symbol
) || S_IS_GAS_LOCAL (right
->X_add_symbol
))
4091 if (left
->X_add_symbol
== right
->X_add_symbol
)
4094 /* We have to assume that there may be instructions between the
4095 two symbols and that relaxation may increase the distance between