1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2014 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 /* NB/ This section of the list should be kept in sync with the ones in:
489 gcc/config/msp430/t-msp430
490 gcc/config/msp430/msp430.c */
492 {"msp430cg4616", MSP_ISA_430X},
493 {"msp430cg4617", MSP_ISA_430X},
494 {"msp430cg4618", MSP_ISA_430X},
495 {"msp430cg4619", MSP_ISA_430X},
496 {"msp430f2416", MSP_ISA_430X},
497 {"msp430f2417", MSP_ISA_430X},
498 {"msp430f2418", MSP_ISA_430X},
499 {"msp430f2419", MSP_ISA_430X},
500 {"msp430f2616", MSP_ISA_430X},
501 {"msp430f2617", MSP_ISA_430X},
502 {"msp430f2618", MSP_ISA_430X},
503 {"msp430f2619", MSP_ISA_430X},
504 {"msp430f47126", MSP_ISA_430X},
505 {"msp430f47127", MSP_ISA_430X},
506 {"msp430f47163", MSP_ISA_430X},
507 {"msp430f47173", MSP_ISA_430X},
508 {"msp430f47183", MSP_ISA_430X},
509 {"msp430f47193", MSP_ISA_430X},
510 {"msp430f47166", MSP_ISA_430X},
511 {"msp430f47176", MSP_ISA_430X},
512 {"msp430f47186", MSP_ISA_430X},
513 {"msp430f47196", MSP_ISA_430X},
514 {"msp430f47167", MSP_ISA_430X},
515 {"msp430f47177", MSP_ISA_430X},
516 {"msp430f47187", MSP_ISA_430X},
517 {"msp430f47197", MSP_ISA_430X},
518 {"msp430f46161", MSP_ISA_430X},
519 {"msp430f46171", MSP_ISA_430X},
520 {"msp430f46181", MSP_ISA_430X},
521 {"msp430f46191", MSP_ISA_430X},
522 {"msp430f4616", MSP_ISA_430X},
523 {"msp430f4617", MSP_ISA_430X},
524 {"msp430f4618", MSP_ISA_430X},
525 {"msp430f4619", MSP_ISA_430X},
526 {"msp430fg4616", MSP_ISA_430X},
527 {"msp430fg4617", MSP_ISA_430X},
528 {"msp430fg4618", MSP_ISA_430X},
529 {"msp430fg4619", MSP_ISA_430X},
531 {"msp430x241x", MSP_ISA_430X},
532 {"msp430x26x", MSP_ISA_430X},
533 {"msp430x461x1", MSP_ISA_430X},
534 {"msp430x46x", MSP_ISA_430X},
535 {"msp430x471x3", MSP_ISA_430X},
536 {"msp430x471x6", MSP_ISA_430X},
537 {"msp430x471x7", MSP_ISA_430X},
538 {"msp430xg46x", MSP_ISA_430X},
540 {"msp430f5418", MSP_ISA_430Xv2},
541 {"msp430f5419", MSP_ISA_430Xv2},
542 {"msp430f5435", MSP_ISA_430Xv2},
543 {"msp430f5436", MSP_ISA_430Xv2},
544 {"msp430f5437", MSP_ISA_430Xv2},
545 {"msp430f5438", MSP_ISA_430Xv2},
546 {"msp430f5418a", MSP_ISA_430Xv2},
547 {"msp430f5419a", MSP_ISA_430Xv2},
548 {"msp430f5435a", MSP_ISA_430Xv2},
549 {"msp430f5436a", MSP_ISA_430Xv2},
550 {"msp430f5437a", MSP_ISA_430Xv2},
551 {"msp430f5438a", MSP_ISA_430Xv2},
552 {"msp430f5212", MSP_ISA_430Xv2},
553 {"msp430f5213", MSP_ISA_430Xv2},
554 {"msp430f5214", MSP_ISA_430Xv2},
555 {"msp430f5217", MSP_ISA_430Xv2},
556 {"msp430f5218", MSP_ISA_430Xv2},
557 {"msp430f5219", MSP_ISA_430Xv2},
558 {"msp430f5222", MSP_ISA_430Xv2},
559 {"msp430f5223", MSP_ISA_430Xv2},
560 {"msp430f5224", MSP_ISA_430Xv2},
561 {"msp430f5227", MSP_ISA_430Xv2},
562 {"msp430f5228", MSP_ISA_430Xv2},
563 {"msp430f5229", MSP_ISA_430Xv2},
564 {"msp430f5304", MSP_ISA_430Xv2},
565 {"msp430f5308", MSP_ISA_430Xv2},
566 {"msp430f5309", MSP_ISA_430Xv2},
567 {"msp430f5310", MSP_ISA_430Xv2},
568 {"msp430f5340", MSP_ISA_430Xv2},
569 {"msp430f5341", MSP_ISA_430Xv2},
570 {"msp430f5342", MSP_ISA_430Xv2},
571 {"msp430f5324", MSP_ISA_430Xv2},
572 {"msp430f5325", MSP_ISA_430Xv2},
573 {"msp430f5326", MSP_ISA_430Xv2},
574 {"msp430f5327", MSP_ISA_430Xv2},
575 {"msp430f5328", MSP_ISA_430Xv2},
576 {"msp430f5329", MSP_ISA_430Xv2},
577 {"msp430f5500", MSP_ISA_430Xv2},
578 {"msp430f5501", MSP_ISA_430Xv2},
579 {"msp430f5502", MSP_ISA_430Xv2},
580 {"msp430f5503", MSP_ISA_430Xv2},
581 {"msp430f5504", MSP_ISA_430Xv2},
582 {"msp430f5505", MSP_ISA_430Xv2},
583 {"msp430f5506", MSP_ISA_430Xv2},
584 {"msp430f5507", MSP_ISA_430Xv2},
585 {"msp430f5508", MSP_ISA_430Xv2},
586 {"msp430f5509", MSP_ISA_430Xv2},
587 {"msp430f5510", MSP_ISA_430Xv2},
588 {"msp430f5513", MSP_ISA_430Xv2},
589 {"msp430f5514", MSP_ISA_430Xv2},
590 {"msp430f5515", MSP_ISA_430Xv2},
591 {"msp430f5517", MSP_ISA_430Xv2},
592 {"msp430f5519", MSP_ISA_430Xv2},
593 {"msp430f5521", MSP_ISA_430Xv2},
594 {"msp430f5522", MSP_ISA_430Xv2},
595 {"msp430f5524", MSP_ISA_430Xv2},
596 {"msp430f5525", MSP_ISA_430Xv2},
597 {"msp430f5526", MSP_ISA_430Xv2},
598 {"msp430f5527", MSP_ISA_430Xv2},
599 {"msp430f5528", MSP_ISA_430Xv2},
600 {"msp430f5529", MSP_ISA_430Xv2},
601 {"cc430f5133", MSP_ISA_430Xv2},
602 {"cc430f5135", MSP_ISA_430Xv2},
603 {"cc430f5137", MSP_ISA_430Xv2},
604 {"cc430f6125", MSP_ISA_430Xv2},
605 {"cc430f6126", MSP_ISA_430Xv2},
606 {"cc430f6127", MSP_ISA_430Xv2},
607 {"cc430f6135", MSP_ISA_430Xv2},
608 {"cc430f6137", MSP_ISA_430Xv2},
609 {"cc430f5123", MSP_ISA_430Xv2},
610 {"cc430f5125", MSP_ISA_430Xv2},
611 {"cc430f5143", MSP_ISA_430Xv2},
612 {"cc430f5145", MSP_ISA_430Xv2},
613 {"cc430f5147", MSP_ISA_430Xv2},
614 {"cc430f6143", MSP_ISA_430Xv2},
615 {"cc430f6145", MSP_ISA_430Xv2},
616 {"cc430f6147", MSP_ISA_430Xv2},
617 {"msp430f5333", MSP_ISA_430Xv2},
618 {"msp430f5335", MSP_ISA_430Xv2},
619 {"msp430f5336", MSP_ISA_430Xv2},
620 {"msp430f5338", MSP_ISA_430Xv2},
621 {"msp430f5630", MSP_ISA_430Xv2},
622 {"msp430f5631", MSP_ISA_430Xv2},
623 {"msp430f5632", MSP_ISA_430Xv2},
624 {"msp430f5633", MSP_ISA_430Xv2},
625 {"msp430f5634", MSP_ISA_430Xv2},
626 {"msp430f5635", MSP_ISA_430Xv2},
627 {"msp430f5636", MSP_ISA_430Xv2},
628 {"msp430f5637", MSP_ISA_430Xv2},
629 {"msp430f5638", MSP_ISA_430Xv2},
630 {"msp430f6433", MSP_ISA_430Xv2},
631 {"msp430f6435", MSP_ISA_430Xv2},
632 {"msp430f6436", MSP_ISA_430Xv2},
633 {"msp430f6438", MSP_ISA_430Xv2},
634 {"msp430f6630", MSP_ISA_430Xv2},
635 {"msp430f6631", MSP_ISA_430Xv2},
636 {"msp430f6632", MSP_ISA_430Xv2},
637 {"msp430f6633", MSP_ISA_430Xv2},
638 {"msp430f6634", MSP_ISA_430Xv2},
639 {"msp430f6635", MSP_ISA_430Xv2},
640 {"msp430f6636", MSP_ISA_430Xv2},
641 {"msp430f6637", MSP_ISA_430Xv2},
642 {"msp430f6638", MSP_ISA_430Xv2},
643 {"msp430f5358", MSP_ISA_430Xv2},
644 {"msp430f5359", MSP_ISA_430Xv2},
645 {"msp430f5658", MSP_ISA_430Xv2},
646 {"msp430f5659", MSP_ISA_430Xv2},
647 {"msp430f6458", MSP_ISA_430Xv2},
648 {"msp430f6459", MSP_ISA_430Xv2},
649 {"msp430f6658", MSP_ISA_430Xv2},
650 {"msp430f6659", MSP_ISA_430Xv2},
651 {"msp430f5131", MSP_ISA_430Xv2},
652 {"msp430f5151", MSP_ISA_430Xv2},
653 {"msp430f5171", MSP_ISA_430Xv2},
654 {"msp430f5132", MSP_ISA_430Xv2},
655 {"msp430f5152", MSP_ISA_430Xv2},
656 {"msp430f5172", MSP_ISA_430Xv2},
657 {"msp430f6720", MSP_ISA_430Xv2},
658 {"msp430f6721", MSP_ISA_430Xv2},
659 {"msp430f6723", MSP_ISA_430Xv2},
660 {"msp430f6724", MSP_ISA_430Xv2},
661 {"msp430f6725", MSP_ISA_430Xv2},
662 {"msp430f6726", MSP_ISA_430Xv2},
663 {"msp430f6730", MSP_ISA_430Xv2},
664 {"msp430f6731", MSP_ISA_430Xv2},
665 {"msp430f6733", MSP_ISA_430Xv2},
666 {"msp430f6734", MSP_ISA_430Xv2},
667 {"msp430f6735", MSP_ISA_430Xv2},
668 {"msp430f6736", MSP_ISA_430Xv2},
669 {"msp430f67451", MSP_ISA_430Xv2},
670 {"msp430f67651", MSP_ISA_430Xv2},
671 {"msp430f67751", MSP_ISA_430Xv2},
672 {"msp430f67461", MSP_ISA_430Xv2},
673 {"msp430f67661", MSP_ISA_430Xv2},
674 {"msp430f67761", MSP_ISA_430Xv2},
675 {"msp430f67471", MSP_ISA_430Xv2},
676 {"msp430f67671", MSP_ISA_430Xv2},
677 {"msp430f67771", MSP_ISA_430Xv2},
678 {"msp430f67481", MSP_ISA_430Xv2},
679 {"msp430f67681", MSP_ISA_430Xv2},
680 {"msp430f67781", MSP_ISA_430Xv2},
681 {"msp430f67491", MSP_ISA_430Xv2},
682 {"msp430f67691", MSP_ISA_430Xv2},
683 {"msp430f67791", MSP_ISA_430Xv2},
684 {"msp430f6745", MSP_ISA_430Xv2},
685 {"msp430f6765", MSP_ISA_430Xv2},
686 {"msp430f6775", MSP_ISA_430Xv2},
687 {"msp430f6746", MSP_ISA_430Xv2},
688 {"msp430f6766", MSP_ISA_430Xv2},
689 {"msp430f6776", MSP_ISA_430Xv2},
690 {"msp430f6747", MSP_ISA_430Xv2},
691 {"msp430f6767", MSP_ISA_430Xv2},
692 {"msp430f6777", MSP_ISA_430Xv2},
693 {"msp430f6748", MSP_ISA_430Xv2},
694 {"msp430f6768", MSP_ISA_430Xv2},
695 {"msp430f6778", MSP_ISA_430Xv2},
696 {"msp430f6749", MSP_ISA_430Xv2},
697 {"msp430f6769", MSP_ISA_430Xv2},
698 {"msp430f6779", MSP_ISA_430Xv2},
699 {"msp430fr5720", MSP_ISA_430Xv2},
700 {"msp430fr5721", MSP_ISA_430Xv2},
701 {"msp430fr5722", MSP_ISA_430Xv2},
702 {"msp430fr5723", MSP_ISA_430Xv2},
703 {"msp430fr5724", MSP_ISA_430Xv2},
704 {"msp430fr5725", MSP_ISA_430Xv2},
705 {"msp430fr5726", MSP_ISA_430Xv2},
706 {"msp430fr5727", MSP_ISA_430Xv2},
707 {"msp430fr5728", MSP_ISA_430Xv2},
708 {"msp430fr5729", MSP_ISA_430Xv2},
709 {"msp430fr5730", MSP_ISA_430Xv2},
710 {"msp430fr5731", MSP_ISA_430Xv2},
711 {"msp430fr5732", MSP_ISA_430Xv2},
712 {"msp430fr5733", MSP_ISA_430Xv2},
713 {"msp430fr5734", MSP_ISA_430Xv2},
714 {"msp430fr5735", MSP_ISA_430Xv2},
715 {"msp430fr5736", MSP_ISA_430Xv2},
716 {"msp430fr5737", MSP_ISA_430Xv2},
717 {"msp430fr5738", MSP_ISA_430Xv2},
718 {"msp430fr5739", MSP_ISA_430Xv2},
719 {"msp430bt5190", MSP_ISA_430Xv2},
720 {"msp430fr5949", MSP_ISA_430Xv2},
721 {"msp430fr5969", MSP_ISA_430Xv2},
722 {"msp430sl5438a", MSP_ISA_430Xv2},
725 {"msp430", MSP_ISA_430},
726 {"msp430X", MSP_ISA_430X},
727 {"msp430Xv2", MSP_ISA_430Xv2},
732 static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
733 static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
734 static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
736 static struct mcu_type_s * msp430_mcu = & default_mcu;
738 static inline bfd_boolean
739 target_is_430x (void)
741 return msp430_mcu->isa >= MSP_ISA_430X;
744 static inline bfd_boolean
745 target_is_430xv2 (void)
747 return msp430_mcu->isa == MSP_ISA_430Xv2;
750 /* Generate a 16-bit relocation.
751 For the 430X we generate a relocation without linkwer range checking
752 if the value is being used in an extended (ie 20-bit) instruction.
753 For the 430 we generate a relocation without assembler range checking
754 if we are handling an immediate value or a byte-width instruction. */
755 #undef CHECK_RELOC_MSP430
756 #define CHECK_RELOC_MSP430 \
758 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
759 : ((imm_op || byte_op) \
760 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
762 /* Generate a 16-bit pc-relative relocation.
763 For the 430X we generate a relocation without linkwer range checking.
764 For the 430 we generate a relocation without assembler range checking
765 if we are handling an immediate value or a byte-width instruction. */
766 #undef CHECK_RELOC_MSP430_PCREL
767 #define CHECK_RELOC_MSP430_PCREL \
769 ? BFD_RELOC_MSP430X_PCR16 \
770 : (imm_op || byte_op) \
771 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
773 /* Profiling capability:
774 It is a performance hit to use gcc's profiling approach for this tiny target.
775 Even more -- jtag hardware facility does not perform any profiling functions.
776 However we've got gdb's built-in simulator where we can do anything.
777 Therefore my suggestion is:
779 We define new section ".profiler" which holds all profiling information.
780 We define new pseudo operation .profiler which will instruct assembler to
781 add new profile entry to the object file. Profile should take place at the
786 .profiler flags,function_to_profile [, cycle_corrector, extra]
788 where 'flags' is a combination of the following chars:
791 i - function is in Init section
792 f - function is in Fini section
794 c - libC standard call
795 d - stack value Demand (saved at run-time in simulator)
796 I - Interrupt service routine
801 j - long Jump/ sjlj unwind
802 a - an Arbitrary code fragment
803 t - exTra parameter saved (constant value like frame size)
804 '""' optional: "sil" == sil
806 function_to_profile - function's address
807 cycle_corrector - a value which should be added to the cycle
808 counter, zero if omitted
809 extra - some extra parameter, zero if omitted.
812 ------------------------------
816 .LFrameOffset_fxx=0x08
817 .profiler "scdP", fxx ; function entry.
818 ; we also demand stack value to be displayed
823 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
824 ; (this is a prologue end)
825 ; note, that spare var filled with the frame size
828 .profiler cdE,fxx ; check stack
833 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
834 ret ; cause 'ret' insn takes 3 cycles
835 -------------------------------
837 This profiling approach does not produce any overhead and
839 So, even profiled code can be uploaded to the MCU. */
840 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
841 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
842 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
843 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
844 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
845 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
846 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
847 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
848 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
849 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
850 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
851 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
852 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
853 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
854 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
855 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
868 for (; x; x = x >> 1)
875 /* Parse ordinary expression. */
878 parse_exp (char * s, expressionS * op)
880 input_line_pointer = s;
882 if (op->X_op == O_absent)
883 as_bad (_("missing operand"));
884 return input_line_pointer;
888 /* Delete spaces from s: X ( r 1 2) => X(r12). */
891 del_spaces (char * s)
899 while (ISSPACE (*m) && *m)
901 memmove (s, m, strlen (m) + 1);
909 skip_space (char * s)
916 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
919 extract_operand (char * from, char * to, int limit)
923 /* Drop leading whitespace. */
924 from = skip_space (from);
926 while (size < limit && *from)
928 *(to + size) = *from;
929 if (*from == ',' || *from == ';' || *from == '\n')
944 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
961 s = input_line_pointer;
962 end = input_line_pointer;
964 while (*end && *end != '\n')
967 while (*s && *s != '\n')
978 as_bad (_(".profiler pseudo requires at least two operands."));
979 input_line_pointer = end;
983 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
992 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
995 p_flags |= MSP430_PROFILER_FLAG_JUMP;
998 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
1001 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
1004 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
1007 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
1010 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
1013 p_flags |= MSP430_PROFILER_FLAG_EXIT;
1016 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
1019 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
1022 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
1025 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
1028 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
1031 p_flags |= MSP430_PROFILER_FLAG_ISR;
1034 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
1037 as_warn (_("unknown profiling flag - ignored."));
1044 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
1045 | MSP430_PROFILER_FLAG_EXIT))
1046 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
1047 | MSP430_PROFILER_FLAG_PROLEND
1048 | MSP430_PROFILER_FLAG_EPISTART
1049 | MSP430_PROFILER_FLAG_EPIEND))
1050 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
1051 | MSP430_PROFILER_FLAG_FINISECT))))
1053 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
1054 input_line_pointer = end;
1058 /* Generate temp symbol which denotes current location. */
1059 if (now_seg == absolute_section) /* Paranoia ? */
1061 exp1.X_op = O_constant;
1062 exp1.X_add_number = abs_section_offset;
1063 as_warn (_("profiling in absolute section?"));
1067 exp1.X_op = O_symbol;
1068 exp1.X_add_symbol = symbol_temp_new_now ();
1069 exp1.X_add_number = 0;
1072 /* Generate a symbol which holds flags value. */
1073 exp.X_op = O_constant;
1074 exp.X_add_number = p_flags;
1076 /* Save current section. */
1078 subseg = now_subseg;
1080 /* Now go to .profiler section. */
1081 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
1084 emit_expr (& exp, 2);
1086 /* Save label value. */
1087 emit_expr (& exp1, 2);
1091 /* Now get profiling info. */
1092 halt = extract_operand (input_line_pointer, str, 1024);
1093 /* Process like ".word xxx" directive. */
1094 parse_exp (str, & exp);
1095 emit_expr (& exp, 2);
1096 input_line_pointer = halt;
1099 /* Fill the rest with zeros. */
1100 exp.X_op = O_constant;
1101 exp.X_add_number = 0;
1103 emit_expr (& exp, 2);
1105 /* Return to current section. */
1106 subseg_set (seg, subseg);
1110 extract_word (char * from, char * to, int limit)
1115 /* Drop leading whitespace. */
1116 from = skip_space (from);
1119 /* Find the op code end. */
1120 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
1122 to[size++] = *op_end++;
1123 if (size + 1 >= limit)
1131 #define OPTION_MMCU 'm'
1132 #define OPTION_RELAX 'Q'
1133 #define OPTION_POLYMORPHS 'P'
1134 #define OPTION_LARGE 'l'
1135 static bfd_boolean large_model = FALSE;
1136 #define OPTION_INTR_NOPS 'n'
1137 #define OPTION_NO_INTR_NOPS 'N'
1138 static bfd_boolean gen_interrupt_nops = FALSE;
1139 #define OPTION_MCPU 'c'
1140 #define OPTION_MOVE_DATA 'd'
1141 static bfd_boolean move_data = FALSE;
1144 msp430_set_arch (int option)
1146 char *str = (char *) alloca (32); /* 32 for good measure. */
1148 input_line_pointer = extract_word (input_line_pointer, str, 32);
1150 md_parse_option (option, str);
1151 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1152 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1156 md_parse_option (int c, char * arg)
1164 as_fatal (_("MCU option requires a name\n"));
1166 for (i = 0; mcu_types[i].name; ++i)
1167 if (strcasecmp (mcu_types[i].name, arg) == 0)
1170 if (mcu_types[i].name != NULL)
1172 /* Allow switching to the same or a lesser architecture. */
1173 if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
1174 msp430_mcu = mcu_types + i;
1176 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1177 msp430_mcu->name, mcu_types[i].name);
1179 /* It is not an error if we do not match the MCU name. */
1183 if (strcmp (arg, "430") == 0
1184 || strcasecmp (arg, "msp430") == 0)
1185 msp430_mcu = & default_mcu;
1186 else if (strcasecmp (arg, "430x") == 0
1187 || strcasecmp (arg, "msp430x") == 0)
1188 msp430_mcu = & msp430x_mcu;
1189 else if (strcasecmp (arg, "430xv2") == 0
1190 || strcasecmp (arg, "msp430xv2") == 0)
1191 msp430_mcu = & msp430xv2_mcu;
1193 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1197 msp430_enable_relax = 1;
1200 case OPTION_POLYMORPHS:
1201 msp430_enable_polys = 1;
1208 case OPTION_NO_INTR_NOPS:
1209 gen_interrupt_nops = FALSE;
1211 case OPTION_INTR_NOPS:
1212 gen_interrupt_nops = TRUE;
1215 case OPTION_MOVE_DATA:
1223 /* The intention here is to have the mere presence of these sections
1224 cause the object to have a reference to a well-known symbol. This
1225 reference pulls in the bits of the runtime (crt0) that initialize
1226 these sections. Thus, for example, the startup code to call
1227 memset() to initialize .bss will only be linked in when there is a
1228 non-empty .bss section. Otherwise, the call would exist but have a
1229 zero length parameter, which is a waste of memory and cycles.
1231 The code which initializes these sections should have a global
1232 label for these symbols, and should be marked with KEEP() in the
1236 msp430_section (int arg)
1238 char * saved_ilp = input_line_pointer;
1239 char * name = obj_elf_section_name ();
1241 if (strncmp (name, ".bss", 4) == 0
1242 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1243 (void) symbol_find_or_make ("__crt0_init_bss");
1245 if (strncmp (name, ".data", 5) == 0
1246 || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
1247 (void) symbol_find_or_make ("__crt0_movedata");
1249 input_line_pointer = saved_ilp;
1250 obj_elf_section (arg);
1254 msp430_frob_section (asection *sec)
1256 const char *name = sec->name;
1261 if (strncmp (name, ".bss", 4) == 0
1262 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1263 (void) symbol_find_or_make ("__crt0_init_bss");
1265 if (strncmp (name, ".data", 5) == 0
1266 || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
1267 (void) symbol_find_or_make ("__crt0_movedata");
1271 msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
1273 symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
1276 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
1277 (void) symbol_find_or_make ("__crt0_init_bss");
1281 msp430_comm (int needs_align)
1283 s_comm_internal (needs_align, elf_common_parse);
1284 (void) symbol_find_or_make ("__crt0_init_bss");
1288 msp430_refsym (int arg ATTRIBUTE_UNUSED)
1290 char sym_name[1024];
1291 input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
1293 (void) symbol_find_or_make (sym_name);
1296 const pseudo_typeS md_pseudo_table[] =
1298 {"arch", msp430_set_arch, OPTION_MMCU},
1299 {"cpu", msp430_set_arch, OPTION_MCPU},
1300 {"profiler", msp430_profiler, 0},
1301 {"section", msp430_section, 0},
1302 {"section.s", msp430_section, 0},
1303 {"sect", msp430_section, 0},
1304 {"sect.s", msp430_section, 0},
1305 {"pushsection", msp430_section, 1},
1306 {"refsym", msp430_refsym, 0},
1307 {"comm", msp430_comm, 0},
1308 {"lcomm", msp430_lcomm, 0},
1312 const char *md_shortopts = "mm:,mP,mQ,ml,mN";
1314 struct option md_longopts[] =
1316 {"mmcu", required_argument, NULL, OPTION_MMCU},
1317 {"mcpu", required_argument, NULL, OPTION_MCPU},
1318 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1319 {"mQ", no_argument, NULL, OPTION_RELAX},
1320 {"ml", no_argument, NULL, OPTION_LARGE},
1321 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1322 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1323 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1324 {NULL, no_argument, NULL, 0}
1327 size_t md_longopts_size = sizeof (md_longopts);
1330 md_show_usage (FILE * stream)
1333 _("MSP430 options:\n"
1334 " -mmcu=<msp430-name> - select microcontroller type\n"
1335 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1337 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1338 " -mP - enable polymorph instructions\n"));
1340 _(" -ml - enable large code model\n"));
1342 _(" -mN - disable generation of NOP after changing interrupts\n"));
1344 _(" -mn - enable generation of NOP after changing interrupts\n"));
1346 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1350 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1356 extract_cmd (char * from, char * to, int limit)
1360 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1362 *(to + size) = *from;
1373 md_atof (int type, char * litP, int * sizeP)
1375 return ieee_md_atof (type, litP, sizeP, FALSE);
1381 struct msp430_opcode_s * opcode;
1382 msp430_hash = hash_new ();
1384 for (opcode = msp430_opcodes; opcode->name; opcode++)
1385 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1387 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1388 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1391 /* Returns the register number equivalent to the string T.
1392 Returns -1 if there is no such register.
1393 Skips a leading 'r' or 'R' character if there is one.
1394 Handles the register aliases PC and SP. */
1397 check_reg (char * t)
1404 if (*t == 'r' || *t == 'R')
1407 if (strncasecmp (t, "pc", 2) == 0)
1410 if (strncasecmp (t, "sp", 2) == 0)
1413 if (strncasecmp (t, "sr", 2) == 0)
1421 if (val < 1 || val > 15)
1428 msp430_srcoperand (struct msp430_operand_s * op,
1432 bfd_boolean allow_20bit_values,
1433 bfd_boolean constants_allowed)
1437 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1444 /* Check if there is:
1445 llo(x) - least significant 16 bits, x &= 0xffff
1446 lhi(x) - x = (x >> 16) & 0xffff,
1447 hlo(x) - x = (x >> 32) & 0xffff,
1448 hhi(x) - x = (x >> 48) & 0xffff
1449 The value _MUST_ be constant expression: #hlo(1231231231). */
1453 if (strncasecmp (h, "#llo(", 5) == 0)
1458 else if (strncasecmp (h, "#lhi(", 5) == 0)
1463 else if (strncasecmp (h, "#hlo(", 5) == 0)
1468 else if (strncasecmp (h, "#hhi(", 5) == 0)
1473 else if (strncasecmp (h, "#lo(", 4) == 0)
1478 else if (strncasecmp (h, "#hi(", 4) == 0)
1484 op->reg = 0; /* Reg PC. */
1486 op->ol = 1; /* Immediate will follow an instruction. */
1487 __tl = h + 1 + rval;
1490 parse_exp (__tl, &(op->exp));
1491 if (op->exp.X_op == O_constant)
1493 int x = op->exp.X_add_number;
1498 op->exp.X_add_number = x;
1500 else if (vshift == 1)
1502 x = (x >> 16) & 0xffff;
1503 op->exp.X_add_number = x;
1505 else if (vshift > 1)
1508 op->exp.X_add_number = -1;
1510 op->exp.X_add_number = 0; /* Nothing left. */
1511 x = op->exp.X_add_number;
1514 if (allow_20bit_values)
1516 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1518 as_bad (_("value 0x%x out of extended range."), x);
1522 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1524 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1528 /* Now check constants. */
1529 /* Substitute register mode with a constant generator if applicable. */
1531 if (!allow_20bit_values)
1532 x = (short) x; /* Extend sign. */
1534 if (! constants_allowed)
1566 #ifdef PUSH_1X_WORKAROUND
1569 /* Remove warning as confusing.
1570 as_warn (_("Hardware push bug workaround")); */
1583 #ifdef PUSH_1X_WORKAROUND
1586 /* Remove warning as confusing.
1587 as_warn (_("Hardware push bug workaround")); */
1599 else if (op->exp.X_op == O_symbol)
1603 else if (op->exp.X_op == O_big)
1608 op->exp.X_op = O_constant;
1609 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1610 x = op->exp.X_add_number;
1615 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1663 /* Redundant (yet) check. */
1664 else if (op->exp.X_op == O_register)
1666 (_("Registers cannot be used within immediate expression [%s]"), l);
1668 as_bad (_("unknown operand %s"), l);
1673 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1678 op->reg = 2; /* reg 2 in absolute addr mode. */
1679 op->am = 1; /* mode As == 01 bin. */
1680 op->ol = 1; /* Immediate value followed by instruction. */
1682 parse_exp (__tl, &(op->exp));
1684 if (op->exp.X_op == O_constant)
1686 int x = op->exp.X_add_number;
1688 if (allow_20bit_values)
1690 if (x > 0xfffff || x < -(0x7ffff))
1692 as_bad (_("value 0x%x out of extended range."), x);
1696 else if (x > 65535 || x < -32768)
1698 as_bad (_("value out of range: 0x%x"), x);
1702 else if (op->exp.X_op == O_symbol)
1706 /* Redundant (yet) check. */
1707 if (op->exp.X_op == O_register)
1709 (_("Registers cannot be used within absolute expression [%s]"), l);
1711 as_bad (_("unknown expression in operand %s"), l);
1717 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1721 char *m = strchr (l, '+');
1725 as_bad (_("unknown addressing mode %s"), l);
1731 if ((op->reg = check_reg (t)) == -1)
1733 as_bad (_("Bad register name %s"), t);
1741 /* PC cannot be used in indirect addressing. */
1742 if (target_is_430xv2 () && op->reg == 0)
1744 as_bad (_("cannot use indirect addressing with the PC"));
1750 /* Check if register indexed X(Rn). */
1753 char *h = strrchr (l, '(');
1754 char *m = strrchr (l, ')');
1763 as_bad (_("')' required"));
1771 /* Extract a register. */
1772 if ((op->reg = check_reg (t + 1)) == -1)
1775 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1782 as_bad (_("r2 should not be used in indexed addressing mode"));
1786 /* Extract constant. */
1790 parse_exp (__tl, &(op->exp));
1791 if (op->exp.X_op == O_constant)
1793 int x = op->exp.X_add_number;
1795 if (allow_20bit_values)
1797 if (x > 0xfffff || x < - (0x7ffff))
1799 as_bad (_("value 0x%x out of extended range."), x);
1803 else if (x > 65535 || x < -32768)
1805 as_bad (_("value out of range: 0x%x"), x);
1817 else if (op->exp.X_op == O_symbol)
1821 /* Redundant (yet) check. */
1822 if (op->exp.X_op == O_register)
1824 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1826 as_bad (_("unknown expression in operand %s"), l);
1834 /* Possibly register mode 'mov r1,r2'. */
1835 if ((op->reg = check_reg (l)) != -1)
1843 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1847 op->reg = 0; /* PC relative... be careful. */
1848 /* An expression starting with a minus sign is a constant, not an address. */
1849 op->am = (*l == '-' ? 3 : 1);
1852 parse_exp (__tl, &(op->exp));
1858 as_bad (_("unknown addressing mode for operand %s"), l);
1864 msp430_dstoperand (struct msp430_operand_s * op,
1867 bfd_boolean allow_20bit_values,
1868 bfd_boolean constants_allowed)
1871 int ret = msp430_srcoperand (op, l, bin, & dummy,
1885 parse_exp (__tl, &(op->exp));
1887 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1889 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1899 ("this addressing mode is not applicable for destination operand"));
1906 /* Attempt to encode a MOVA instruction with the given operands.
1907 Returns the length of the encoded instruction if successful
1908 or 0 upon failure. If the encoding fails, an error message
1909 will be returned if a pointer is provided. */
1912 try_encode_mova (bfd_boolean imm_op,
1914 struct msp430_operand_s * op1,
1915 struct msp430_operand_s * op2,
1916 const char ** error_message_return)
1922 /* Only a restricted subset of the normal MSP430 addressing modes
1923 are supported here, so check for the ones that are allowed. */
1926 if (op1->mode == OP_EXP)
1928 if (op2->mode != OP_REG)
1930 if (error_message_return != NULL)
1931 * error_message_return = _("expected register as second argument of %s");
1937 /* MOVA #imm20, Rdst. */
1938 bin |= 0x80 | op2->reg;
1939 frag = frag_more (4);
1940 where = frag - frag_now->fr_literal;
1941 if (op1->exp.X_op == O_constant)
1943 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1944 bfd_putl16 ((bfd_vma) bin, frag);
1945 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1949 bfd_putl16 ((bfd_vma) bin, frag);
1950 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1951 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1952 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1957 else if (op1->am == 1)
1959 /* MOVA z16(Rsrc), Rdst. */
1960 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1961 frag = frag_more (4);
1962 where = frag - frag_now->fr_literal;
1963 bfd_putl16 ((bfd_vma) bin, frag);
1964 if (op1->exp.X_op == O_constant)
1966 if (op1->exp.X_add_number > 0xffff
1967 || op1->exp.X_add_number < -(0x7fff))
1969 if (error_message_return != NULL)
1970 * error_message_return = _("index value too big for %s");
1973 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1977 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1978 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1980 BFD_RELOC_MSP430X_PCR16 :
1981 BFD_RELOC_MSP430X_ABS16);
1986 if (error_message_return != NULL)
1987 * error_message_return = _("unexpected addressing mode for %s");
1990 else if (op1->am == 0)
1992 /* MOVA Rsrc, ... */
1993 if (op2->mode == OP_REG)
1995 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1996 frag = frag_more (2);
1997 where = frag - frag_now->fr_literal;
1998 bfd_putl16 ((bfd_vma) bin, frag);
2001 else if (op2->am == 1)
2005 /* MOVA Rsrc, &abs20. */
2006 bin |= 0x60 | (op1->reg << 8);
2007 frag = frag_more (4);
2008 where = frag - frag_now->fr_literal;
2009 if (op2->exp.X_op == O_constant)
2011 bin |= (op2->exp.X_add_number >> 16) & 0xf;
2012 bfd_putl16 ((bfd_vma) bin, frag);
2013 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2017 bfd_putl16 ((bfd_vma) bin, frag);
2018 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2019 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
2020 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2025 /* MOVA Rsrc, z16(Rdst). */
2026 bin |= 0x70 | (op1->reg << 8) | op2->reg;
2027 frag = frag_more (4);
2028 where = frag - frag_now->fr_literal;
2029 bfd_putl16 ((bfd_vma) bin, frag);
2030 if (op2->exp.X_op == O_constant)
2032 if (op2->exp.X_add_number > 0xffff
2033 || op2->exp.X_add_number < -(0x7fff))
2035 if (error_message_return != NULL)
2036 * error_message_return = _("index value too big for %s");
2039 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2043 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2044 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2046 BFD_RELOC_MSP430X_PCR16 :
2047 BFD_RELOC_MSP430X_ABS16);
2052 if (error_message_return != NULL)
2053 * error_message_return = _("unexpected addressing mode for %s");
2058 /* imm_op == FALSE. */
2060 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2062 /* MOVA &abs20, Rdst. */
2063 if (op2->mode != OP_REG)
2065 if (error_message_return != NULL)
2066 * error_message_return = _("expected register as second argument of %s");
2070 if (op2->reg == 2 || op2->reg == 3)
2072 if (error_message_return != NULL)
2073 * error_message_return = _("constant generator destination register found in %s");
2077 bin |= 0x20 | op2->reg;
2078 frag = frag_more (4);
2079 where = frag - frag_now->fr_literal;
2080 if (op1->exp.X_op == O_constant)
2082 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2083 bfd_putl16 ((bfd_vma) bin, frag);
2084 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2088 bfd_putl16 ((bfd_vma) bin, frag);
2089 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2090 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2091 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2095 else if (op1->mode == OP_REG)
2099 /* MOVA @Rsrc+, Rdst. */
2100 if (op2->mode != OP_REG)
2102 if (error_message_return != NULL)
2103 * error_message_return = _("expected register as second argument of %s");
2107 if (op2->reg == 2 || op2->reg == 3)
2109 if (error_message_return != NULL)
2110 * error_message_return = _("constant generator destination register found in %s");
2114 if (op1->reg == 2 || op1->reg == 3)
2116 if (error_message_return != NULL)
2117 * error_message_return = _("constant generator source register found in %s");
2121 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2122 frag = frag_more (2);
2123 where = frag - frag_now->fr_literal;
2124 bfd_putl16 ((bfd_vma) bin, frag);
2127 else if (op1->am == 2)
2129 /* MOVA @Rsrc,Rdst */
2130 if (op2->mode != OP_REG)
2132 if (error_message_return != NULL)
2133 * error_message_return = _("expected register as second argument of %s");
2137 if (op2->reg == 2 || op2->reg == 3)
2139 if (error_message_return != NULL)
2140 * error_message_return = _("constant generator destination register found in %s");
2144 if (op1->reg == 2 || op1->reg == 3)
2146 if (error_message_return != NULL)
2147 * error_message_return = _("constant generator source register found in %s");
2151 bin |= (op1->reg << 8) | op2->reg;
2152 frag = frag_more (2);
2153 where = frag - frag_now->fr_literal;
2154 bfd_putl16 ((bfd_vma) bin, frag);
2159 if (error_message_return != NULL)
2160 * error_message_return = _("unexpected addressing mode for %s");
2165 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2167 /* Parse instruction operands.
2168 Return binary opcode. */
2171 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2173 int bin = opcode->bin_opcode; /* Opcode mask. */
2174 int insn_length = 0;
2175 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2178 struct msp430_operand_s op1, op2;
2180 static short ZEROS = 0;
2181 int byte_op, imm_op;
2184 int extended = 0x1800;
2185 bfd_boolean extended_op = FALSE;
2186 bfd_boolean addr_op;
2187 const char * error_message;
2188 static signed int repeat_count = 0;
2189 bfd_boolean fix_emitted;
2191 /* Opcode is the one from opcodes table
2192 line contains something like
2201 bfd_boolean check = FALSE;
2204 switch (TOLOWER (* line))
2207 /* Byte operation. */
2208 bin |= BYTE_OPERATION;
2214 /* "Address" ops work on 20-bit values. */
2216 bin |= BYTE_OPERATION;
2221 /* Word operation - this is the default. */
2229 as_warn (_("no size modifier after period, .w assumed"));
2233 as_bad (_("unrecognised instruction size modifier .%c"),
2245 if (*line && ! ISSPACE (*line))
2247 as_bad (_("junk found after instruction: %s.%s"),
2248 opcode->name, line);
2252 /* Catch the case where the programmer has used a ".a" size modifier on an
2253 instruction that does not support it. Look for an alternative extended
2254 instruction that has the same name without the period. Eg: "add.a"
2255 becomes "adda". Although this not an officially supported way of
2256 specifing instruction aliases other MSP430 assemblers allow it. So we
2257 support it for compatibility purposes. */
2258 if (addr_op && opcode->fmt >= 0)
2260 char * old_name = opcode->name;
2263 sprintf (real_name, "%sa", old_name);
2264 opcode = hash_find (msp430_hash, real_name);
2267 as_bad (_("instruction %s.a does not exist"), old_name);
2270 #if 0 /* Enable for debugging. */
2271 as_warn ("treating %s.a as %s", old_name, real_name);
2274 bin = opcode->bin_opcode;
2277 if (opcode->fmt != -1
2278 && opcode->insn_opnumb
2279 && (!*line || *line == '\n'))
2281 as_bad (_("instruction %s requires %d operand(s)"),
2282 opcode->name, opcode->insn_opnumb);
2286 memset (l1, 0, sizeof (l1));
2287 memset (l2, 0, sizeof (l2));
2288 memset (&op1, 0, sizeof (op1));
2289 memset (&op2, 0, sizeof (op2));
2293 if ((fmt = opcode->fmt) < 0)
2295 if (! target_is_430x ())
2297 as_bad (_("instruction %s requires MSP430X mcu"),
2308 /* If requested set the extended instruction repeat count. */
2311 if (repeat_count > 0)
2312 extended |= (repeat_count - 1);
2314 extended |= (1 << 7) | (- repeat_count);
2317 as_bad (_("unable to repeat %s insn"), opcode->name);
2324 case 0: /* Emulated. */
2325 switch (opcode->insn_opnumb)
2328 /* Set/clear bits instructions. */
2332 extended |= BYTE_OPERATION;
2334 /* Emit the extension word. */
2336 frag = frag_more (insn_length);
2337 bfd_putl16 (extended, frag);
2341 frag = frag_more (insn_length);
2342 bfd_putl16 ((bfd_vma) bin, frag);
2344 if (gen_interrupt_nops
2345 && (is_opcode ("eint") || is_opcode ("dint")))
2347 /* Emit a NOP following interrupt enable/disable.
2348 See 1.3.4.1 of the MSP430x5xx User Guide. */
2350 frag = frag_more (2);
2351 as_warn (_("a NOP instruction has been inserted after %s"),
2353 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2355 dwarf2_emit_insn (insn_length);
2359 /* Something which works with destination operand. */
2360 line = extract_operand (line, l1, sizeof (l1));
2361 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2365 /* Compute the entire instruction length, in bytes. */
2366 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2367 frag = frag_more (insn_length);
2368 where = frag - frag_now->fr_literal;
2373 extended |= BYTE_OPERATION;
2375 if (op1.ol != 0 && ((extended & 0xf) != 0))
2377 as_bad (_("repeat instruction used with non-register mode instruction"));
2381 if (op1.mode == OP_EXP)
2383 if (op1.exp.X_op == O_constant)
2384 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2386 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2387 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2388 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2390 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2391 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2394 /* Emit the extension word. */
2395 bfd_putl16 (extended, frag);
2400 bin |= (op1.reg | (op1.am << 7));
2401 bfd_putl16 ((bfd_vma) bin, frag);
2405 if (op1.mode == OP_EXP)
2407 if (op1.exp.X_op == O_constant)
2409 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2413 bfd_putl16 ((bfd_vma) ZEROS, frag);
2418 fix_new_exp (frag_now, where, 2,
2419 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2421 fix_new_exp (frag_now, where, 2,
2422 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2427 if (gen_interrupt_nops
2428 && is_opcode ("clr")
2429 && bin == 0x4302 /* CLR R2*/)
2431 /* Emit a NOP following interrupt enable/disable.
2432 See 1.3.4.1 of the MSP430x5xx User Guide. */
2434 frag = frag_more (2);
2435 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2436 as_warn (_("a NOP instruction has been inserted after %s"),
2440 dwarf2_emit_insn (insn_length);
2444 /* Shift instruction. */
2445 line = extract_operand (line, l1, sizeof (l1));
2446 strncpy (l2, l1, sizeof (l2));
2447 l2[sizeof (l2) - 1] = '\0';
2448 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2449 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2452 break; /* An error occurred. All warnings were done before. */
2454 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2455 frag = frag_more (insn_length);
2456 where = frag - frag_now->fr_literal;
2458 if (target_is_430xv2 ()
2459 && op1.mode == OP_REG
2461 && (is_opcode ("rlax")
2462 || is_opcode ("rlcx")
2463 || is_opcode ("rla")
2464 || is_opcode ("rlc")))
2466 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2473 extended |= BYTE_OPERATION;
2475 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2477 as_bad (_("repeat instruction used with non-register mode instruction"));
2481 if (op1.mode == OP_EXP)
2483 if (op1.exp.X_op == O_constant)
2484 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2486 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2487 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2488 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2490 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2491 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2494 if (op2.mode == OP_EXP)
2496 if (op2.exp.X_op == O_constant)
2497 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2499 else if (op1.mode == OP_EXP)
2500 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2501 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2502 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2504 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2505 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2506 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2509 /* Emit the extension word. */
2510 bfd_putl16 (extended, frag);
2515 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2516 bfd_putl16 ((bfd_vma) bin, frag);
2520 if (op1.mode == OP_EXP)
2522 if (op1.exp.X_op == O_constant)
2524 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2528 bfd_putl16 ((bfd_vma) ZEROS, frag);
2532 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2533 fix_new_exp (frag_now, where, 2,
2534 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2536 fix_new_exp (frag_now, where, 2,
2537 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2544 if (op2.mode == OP_EXP)
2546 if (op2.exp.X_op == O_constant)
2548 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2552 bfd_putl16 ((bfd_vma) ZEROS, frag);
2556 if (op2.reg) /* Not PC relative. */
2557 fix_new_exp (frag_now, where, 2,
2558 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2560 fix_new_exp (frag_now, where, 2,
2561 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2566 dwarf2_emit_insn (insn_length);
2570 /* Branch instruction => mov dst, r0. */
2573 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2577 line = extract_operand (line, l1, sizeof (l1));
2578 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2584 bin |= ((op1.reg << 8) | (op1.am << 4));
2585 op_length = 2 + 2 * op1.ol;
2586 frag = frag_more (op_length);
2587 where = frag - frag_now->fr_literal;
2588 bfd_putl16 ((bfd_vma) bin, frag);
2590 if (op1.mode == OP_EXP)
2592 if (op1.exp.X_op == O_constant)
2594 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2600 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2602 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2603 fix_new_exp (frag_now, where, 2,
2604 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2606 fix_new_exp (frag_now, where, 2,
2607 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2611 dwarf2_emit_insn (insn_length + op_length);
2615 /* CALLA instructions. */
2616 fix_emitted = FALSE;
2618 line = extract_operand (line, l1, sizeof (l1));
2621 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2622 extended_op, FALSE);
2628 op_length = 2 + 2 * op1.ol;
2629 frag = frag_more (op_length);
2630 where = frag - frag_now->fr_literal;
2638 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2639 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2642 else if (op1.am == 1)
2648 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2649 BFD_RELOC_MSP430X_PCR20_CALL);
2653 bin |= 0x50 | op1.reg;
2655 else if (op1.am == 0)
2656 bin |= 0x40 | op1.reg;
2658 else if (op1.am == 1)
2662 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2663 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2666 else if (op1.am == 2)
2667 bin |= 0x60 | op1.reg;
2668 else if (op1.am == 3)
2669 bin |= 0x70 | op1.reg;
2671 bfd_putl16 ((bfd_vma) bin, frag);
2673 if (op1.mode == OP_EXP)
2677 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2681 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2684 fix_new_exp (frag_now, where + 2, 2,
2685 &(op1.exp), FALSE, BFD_RELOC_16);
2688 dwarf2_emit_insn (insn_length + op_length);
2696 /* [POP|PUSH]M[.A] #N, Rd */
2697 line = extract_operand (line, l1, sizeof (l1));
2698 line = extract_operand (line, l2, sizeof (l2));
2702 as_bad (_("expected #n as first argument of %s"), opcode->name);
2705 parse_exp (l1 + 1, &(op1.exp));
2706 if (op1.exp.X_op != O_constant)
2708 as_bad (_("expected constant expression for first argument of %s"),
2713 if ((reg = check_reg (l2)) == -1)
2715 as_bad (_("expected register as second argument of %s"),
2721 frag = frag_more (op_length);
2722 where = frag - frag_now->fr_literal;
2723 bin = opcode->bin_opcode;
2726 n = op1.exp.X_add_number;
2727 bin |= (n - 1) << 4;
2728 if (is_opcode ("pushm"))
2732 if (reg - n + 1 < 0)
2734 as_bad (_("Too many registers popped"));
2738 /* CPU21 parts cannot use POPM to restore the SR register. */
2739 if (target_is_430xv2 ()
2740 && (reg - n + 1 < 3)
2742 && is_opcode ("popm"))
2744 as_bad (_("Cannot use POPM to restore the SR register"));
2748 bin |= (reg - n + 1);
2751 bfd_putl16 ((bfd_vma) bin, frag);
2752 dwarf2_emit_insn (op_length);
2761 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2762 if (extended & 0xff)
2764 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2768 line = extract_operand (line, l1, sizeof (l1));
2769 line = extract_operand (line, l2, sizeof (l2));
2773 as_bad (_("expected #n as first argument of %s"), opcode->name);
2776 parse_exp (l1 + 1, &(op1.exp));
2777 if (op1.exp.X_op != O_constant)
2779 as_bad (_("expected constant expression for first argument of %s"),
2783 n = op1.exp.X_add_number;
2786 as_bad (_("expected first argument of %s to be in the range 1-4"),
2791 if ((reg = check_reg (l2)) == -1)
2793 as_bad (_("expected register as second argument of %s"),
2798 if (target_is_430xv2 () && reg == 0)
2800 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2805 frag = frag_more (op_length);
2806 where = frag - frag_now->fr_literal;
2808 bin = opcode->bin_opcode;
2811 bin |= (n - 1) << 10;
2814 bfd_putl16 ((bfd_vma) bin, frag);
2815 dwarf2_emit_insn (op_length);
2823 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2824 if (extended & 0xff)
2826 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2830 line = extract_operand (line, l1, sizeof (l1));
2831 if ((reg = check_reg (l1)) == -1)
2833 as_bad (_("expected register as argument of %s"),
2838 if (target_is_430xv2 () && reg == 0)
2840 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2846 /* Tricky - there is no single instruction that will do this.
2847 Encode as: RRA.B rN { BIC.B #0x80, rN */
2849 frag = frag_more (op_length);
2850 where = frag - frag_now->fr_literal;
2852 bfd_putl16 ((bfd_vma) bin, frag);
2853 dwarf2_emit_insn (2);
2855 bfd_putl16 ((bfd_vma) bin, frag + 2);
2857 bfd_putl16 ((bfd_vma) bin, frag + 4);
2858 dwarf2_emit_insn (4);
2862 /* Encode as RRUM[.A] rN. */
2863 bin = opcode->bin_opcode;
2868 frag = frag_more (op_length);
2869 where = frag - frag_now->fr_literal;
2870 bfd_putl16 ((bfd_vma) bin, frag);
2871 dwarf2_emit_insn (op_length);
2878 bfd_boolean need_reloc = FALSE;
2882 /* ADDA, CMPA and SUBA address instructions. */
2883 if (extended & 0xff)
2885 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2889 line = extract_operand (line, l1, sizeof (l1));
2890 line = extract_operand (line, l2, sizeof (l2));
2892 bin = opcode->bin_opcode;
2896 parse_exp (l1 + 1, &(op1.exp));
2898 if (op1.exp.X_op == O_constant)
2900 n = op1.exp.X_add_number;
2901 if (n > 0xfffff || n < - (0x7ffff))
2903 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2908 bin |= ((n >> 16) & 0xf) << 8;
2920 if ((n = check_reg (l1)) == -1)
2922 as_bad (_("expected register name or constant as first argument of %s"),
2927 bin |= (n << 8) | (1 << 6);
2931 if ((reg = check_reg (l2)) == -1)
2933 as_bad (_("expected register as second argument of %s"),
2938 frag = frag_more (op_length);
2939 where = frag - frag_now->fr_literal;
2942 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2943 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2945 bfd_putl16 ((bfd_vma) bin, frag);
2947 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2948 dwarf2_emit_insn (op_length);
2952 case 9: /* MOVA, BRA, RETA. */
2954 bin = opcode->bin_opcode;
2956 if (is_opcode ("reta"))
2958 /* The RETA instruction does not take any arguments.
2959 The implicit first argument is @SP+.
2960 The implicit second argument is PC. */
2970 line = extract_operand (line, l1, sizeof (l1));
2971 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2972 &imm_op, extended_op, FALSE);
2974 if (is_opcode ("bra"))
2976 /* This is the BRA synthetic instruction.
2977 The second argument is always PC. */
2983 line = extract_operand (line, l2, sizeof (l2));
2984 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2989 break; /* Error occurred. All warnings were done before. */
2992 /* Only a restricted subset of the normal MSP430 addressing modes
2993 are supported here, so check for the ones that are allowed. */
2994 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2995 & error_message)) == 0)
2997 as_bad (error_message, opcode->name);
3000 dwarf2_emit_insn (op_length);
3004 line = extract_operand (line, l1, sizeof l1);
3005 /* The RPT instruction only accepted immediates and registers. */
3008 parse_exp (l1 + 1, &(op1.exp));
3009 if (op1.exp.X_op != O_constant)
3011 as_bad (_("expected constant value as argument to RPT"));
3014 if (op1.exp.X_add_number < 1
3015 || op1.exp.X_add_number > (1 << 4))
3017 as_bad (_("expected constant in the range 2..16"));
3021 /* We silently accept and ignore a repeat count of 1. */
3022 if (op1.exp.X_add_number > 1)
3023 repeat_count = op1.exp.X_add_number;
3029 if ((reg = check_reg (l1)) != -1)
3032 as_warn (_("PC used as an argument to RPT"));
3034 repeat_count = - reg;
3038 as_bad (_("expected constant or register name as argument to RPT insn"));
3045 as_bad (_("Illegal emulated instruction "));
3050 case 1: /* Format 1, double operand. */
3051 line = extract_operand (line, l1, sizeof (l1));
3052 line = extract_operand (line, l2, sizeof (l2));
3053 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3054 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3057 break; /* Error occurred. All warnings were done before. */
3060 && is_opcode ("movx")
3062 && msp430_enable_relax)
3064 /* This is the MOVX.A instruction. See if we can convert
3065 it into the MOVA instruction instead. This saves 2 bytes. */
3066 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3069 dwarf2_emit_insn (op_length);
3074 /* Compute the entire length of the instruction in bytes. */
3076 (extended_op ? 2 : 0) /* The extension word. */
3077 + 2 /* The opcode */
3078 + (2 * op1.ol) /* The first operand. */
3079 + (2 * op2.ol); /* The second operand. */
3081 frag = frag_more (insn_length);
3082 where = frag - frag_now->fr_literal;
3087 extended |= BYTE_OPERATION;
3089 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3091 as_bad (_("repeat instruction used with non-register mode instruction"));
3095 /* If necessary, emit a reloc to update the extension word. */
3096 if (op1.mode == OP_EXP)
3098 if (op1.exp.X_op == O_constant)
3099 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3101 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3102 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3103 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3105 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3106 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3109 if (op2.mode == OP_EXP)
3111 if (op2.exp.X_op == O_constant)
3112 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3114 else if (op1.mode == OP_EXP)
3115 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3116 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3117 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3120 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3121 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3122 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3125 /* Emit the extension word. */
3126 bfd_putl16 (extended, frag);
3131 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3132 bfd_putl16 ((bfd_vma) bin, frag);
3136 if (op1.mode == OP_EXP)
3138 if (op1.exp.X_op == O_constant)
3140 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3144 bfd_putl16 ((bfd_vma) ZEROS, frag);
3148 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3149 fix_new_exp (frag_now, where, 2,
3150 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3152 fix_new_exp (frag_now, where, 2,
3153 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3161 if (op2.mode == OP_EXP)
3163 if (op2.exp.X_op == O_constant)
3165 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3169 bfd_putl16 ((bfd_vma) ZEROS, frag);
3173 if (op2.reg) /* Not PC relative. */
3174 fix_new_exp (frag_now, where, 2,
3175 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3177 fix_new_exp (frag_now, where, 2,
3178 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3183 if (gen_interrupt_nops
3184 && ( (is_opcode ("bic") && bin == 0xc232)
3185 || (is_opcode ("bis") && bin == 0xd232)
3186 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
3188 /* Emit a NOP following interrupt enable/disable.
3189 See 1.3.4.1 of the MSP430x5xx User Guide. */
3191 frag = frag_more (2);
3192 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3193 as_warn (_("a NOP instruction has been inserted after %s"),
3197 dwarf2_emit_insn (insn_length);
3200 case 2: /* Single-operand mostly instr. */
3201 if (opcode->insn_opnumb == 0)
3203 /* reti instruction. */
3205 frag = frag_more (2);
3206 bfd_putl16 ((bfd_vma) bin, frag);
3207 dwarf2_emit_insn (insn_length);
3211 line = extract_operand (line, l1, sizeof (l1));
3212 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3213 &imm_op, extended_op, TRUE);
3215 break; /* Error in operand. */
3217 if (target_is_430xv2 ()
3218 && op1.mode == OP_REG
3220 && (is_opcode ("rrax")
3221 || is_opcode ("rrcx")
3222 || is_opcode ("rra")
3223 || is_opcode ("rrc")))
3225 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3229 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3230 frag = frag_more (insn_length);
3231 where = frag - frag_now->fr_literal;
3235 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3237 /* These two instructions use a special
3238 encoding of the A/L and B/W bits. */
3239 bin &= ~ BYTE_OPERATION;
3243 as_bad (_("%s instruction does not accept a .b suffix"),
3248 extended |= BYTE_OPERATION;
3251 extended |= BYTE_OPERATION;
3253 if (op1.ol != 0 && ((extended & 0xf) != 0))
3255 as_bad (_("repeat instruction used with non-register mode instruction"));
3259 if (op1.mode == OP_EXP)
3261 if (op1.exp.X_op == O_constant)
3262 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3264 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3265 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3266 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3268 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3269 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3272 /* Emit the extension word. */
3273 bfd_putl16 (extended, frag);
3278 bin |= op1.reg | (op1.am << 4);
3279 bfd_putl16 ((bfd_vma) bin, frag);
3283 if (op1.mode == OP_EXP)
3285 if (op1.exp.X_op == O_constant)
3287 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3291 bfd_putl16 ((bfd_vma) ZEROS, frag);
3295 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3296 fix_new_exp (frag_now, where, 2,
3297 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3299 fix_new_exp (frag_now, where, 2,
3300 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3305 dwarf2_emit_insn (insn_length);
3308 case 3: /* Conditional jumps instructions. */
3309 line = extract_operand (line, l1, sizeof (l1));
3310 /* l1 is a label. */
3319 parse_exp (m, &exp);
3321 /* In order to handle something like:
3325 jz 4 ; skip next 4 bytes
3328 nop ; will jump here if r5 positive or zero
3330 jCOND -n ;assumes jump n bytes backward:
3340 jCOND $n ; jump from PC in either direction. */
3342 if (exp.X_op == O_constant)
3344 int x = exp.X_add_number;
3348 as_warn (_("Even number required. Rounded to %d"), x + 1);
3352 if ((*l1 == '$' && x > 0) || x < 0)
3357 if (x > 512 || x < -511)
3359 as_bad (_("Wrong displacement %d"), x << 1);
3364 frag = frag_more (2); /* Instr size is 1 word. */
3367 bfd_putl16 ((bfd_vma) bin, frag);
3369 else if (exp.X_op == O_symbol && *l1 != '$')
3372 frag = frag_more (2); /* Instr size is 1 word. */
3373 where = frag - frag_now->fr_literal;
3374 fix_new_exp (frag_now, where, 2,
3375 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3377 bfd_putl16 ((bfd_vma) bin, frag);
3379 else if (*l1 == '$')
3381 as_bad (_("instruction requires label sans '$'"));
3385 ("instruction requires label or value in range -511:512"));
3386 dwarf2_emit_insn (insn_length);
3391 as_bad (_("instruction requires label"));
3396 case 4: /* Extended jumps. */
3397 if (!msp430_enable_polys)
3399 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3403 line = extract_operand (line, l1, sizeof (l1));
3409 /* Ignore absolute addressing. make it PC relative anyway. */
3410 if (*m == '#' || *m == '$')
3413 parse_exp (m, & exp);
3414 if (exp.X_op == O_symbol)
3416 /* Relaxation required. */
3417 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3419 if (target_is_430x ())
3420 rc = msp430x_rcodes[opcode->insn_opnumb];
3422 /* The parameter to dwarf2_emit_insn is actually the offset to
3423 the start of the insn from the fix piece of instruction that
3424 was emitted. Since next fragments may have variable size we
3425 tie debug info to the beginning of the instruction. */
3427 frag = frag_more (8);
3428 dwarf2_emit_insn (0);
3429 bfd_putl16 ((bfd_vma) rc.sop, frag);
3430 frag = frag_variant (rs_machine_dependent, 8, 2,
3432 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3434 0, /* Offset is zero if jump dist less than 1K. */
3440 as_bad (_("instruction requires label"));
3443 case 5: /* Emulated extended branches. */
3444 if (!msp430_enable_polys)
3446 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3449 line = extract_operand (line, l1, sizeof (l1));
3455 /* Ignore absolute addressing. make it PC relative anyway. */
3456 if (*m == '#' || *m == '$')
3459 parse_exp (m, & exp);
3460 if (exp.X_op == O_symbol)
3462 /* Relaxation required. */
3463 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3465 if (target_is_430x ())
3466 hc = msp430x_hcodes[opcode->insn_opnumb];
3469 frag = frag_more (8);
3470 dwarf2_emit_insn (0);
3471 bfd_putl16 ((bfd_vma) hc.op0, frag);
3472 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3474 frag = frag_variant (rs_machine_dependent, 8, 2,
3475 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3477 0, /* Offset is zero if jump dist less than 1K. */
3483 as_bad (_("instruction requires label"));
3487 as_bad (_("Illegal instruction or not implemented opcode."));
3490 input_line_pointer = line;
3495 md_assemble (char * str)
3497 struct msp430_opcode_s * opcode;
3501 str = skip_space (str); /* Skip leading spaces. */
3502 str = extract_cmd (str, cmd, sizeof (cmd));
3504 while (cmd[i] && i < sizeof (cmd))
3506 char a = TOLOWER (cmd[i]);
3513 as_bad (_("can't find opcode "));
3517 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3521 as_bad (_("unknown opcode `%s'"), cmd);
3526 char *__t = input_line_pointer;
3528 msp430_operands (opcode, str);
3529 input_line_pointer = __t;
3533 /* GAS will call this function for each section at the end of the assembly,
3534 to permit the CPU backend to adjust the alignment of a section. */
3537 md_section_align (asection * seg, valueT addr)
3539 int align = bfd_get_section_alignment (stdoutput, seg);
3541 return ((addr + (1 << align) - 1) & (-1 << align));
3544 /* If you define this macro, it should return the offset between the
3545 address of a PC relative fixup and the position from which the PC
3546 relative adjustment should be made. On many processors, the base
3547 of a PC relative instruction is the next instruction, so this
3548 macro would return the length of an instruction. */
3551 md_pcrel_from_section (fixS * fixp, segT sec)
3553 if (fixp->fx_addsy != (symbolS *) NULL
3554 && (!S_IS_DEFINED (fixp->fx_addsy)
3555 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3558 return fixp->fx_frag->fr_address + fixp->fx_where;
3561 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3562 Now it handles the situation when relocations
3563 have to be passed to linker. */
3565 msp430_force_relocation_local (fixS *fixp)
3567 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3571 if (msp430_enable_polys
3572 && !msp430_enable_relax)
3575 return (!fixp->fx_pcrel
3576 || generic_force_reloc (fixp));
3580 /* GAS will call this for each fixup. It should store the correct
3581 value in the object file. */
3583 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3585 unsigned char * where;
3589 if (fixp->fx_addsy == (symbolS *) NULL)
3594 else if (fixp->fx_pcrel)
3596 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3598 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3600 /* FIXME: We can appear here only in case if we perform a pc
3601 relative jump to the label which is i) global, ii) locally
3602 defined or this is a jump to an absolute symbol.
3603 If this is an absolute symbol -- everything is OK.
3604 If this is a global label, we've got a symbol value defined
3606 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3607 from this section start
3608 2. *valuep will contain the real offset from jump insn to the
3610 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3611 will be incorrect. Therefore remove s_get_value. */
3612 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3620 value = fixp->fx_offset;
3622 if (fixp->fx_subsy != (symbolS *) NULL)
3624 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3626 value -= S_GET_VALUE (fixp->fx_subsy);
3632 fixp->fx_no_overflow = 1;
3634 /* If polymorphs are enabled and relax disabled.
3635 do not kill any relocs and pass them to linker. */
3636 if (msp430_enable_polys
3637 && !msp430_enable_relax)
3639 if (!fixp->fx_addsy || (fixp->fx_addsy
3640 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
3641 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3648 /* Fetch the instruction, insert the fully resolved operand
3649 value, and stuff the instruction back again. */
3650 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3652 insn = bfd_getl16 (where);
3654 switch (fixp->fx_r_type)
3656 case BFD_RELOC_MSP430_10_PCREL:
3658 as_bad_where (fixp->fx_file, fixp->fx_line,
3659 _("odd address operand: %ld"), value);
3661 /* Jumps are in words. */
3663 --value; /* Correct PC. */
3665 if (value < -512 || value > 511)
3666 as_bad_where (fixp->fx_file, fixp->fx_line,
3667 _("operand out of range: %ld"), value);
3669 value &= 0x3ff; /* get rid of extended sign */
3670 bfd_putl16 ((bfd_vma) (value | insn), where);
3673 case BFD_RELOC_MSP430X_PCR16:
3674 case BFD_RELOC_MSP430_RL_PCREL:
3675 case BFD_RELOC_MSP430_16_PCREL:
3677 as_bad_where (fixp->fx_file, fixp->fx_line,
3678 _("odd address operand: %ld"), value);
3681 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3682 /* Nothing to be corrected here. */
3683 if (value < -32768 || value > 65536)
3684 as_bad_where (fixp->fx_file, fixp->fx_line,
3685 _("operand out of range: %ld"), value);
3688 case BFD_RELOC_MSP430X_ABS16:
3689 case BFD_RELOC_MSP430_16:
3691 case BFD_RELOC_MSP430_16_BYTE:
3692 value &= 0xffff; /* Get rid of extended sign. */
3693 bfd_putl16 ((bfd_vma) value, where);
3697 bfd_putl16 ((bfd_vma) value, where);
3700 case BFD_RELOC_MSP430_ABS8:
3702 bfd_put_8 (NULL, (bfd_vma) value, where);
3705 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3706 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3707 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3709 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3712 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3713 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3715 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3718 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3719 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3721 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3724 case BFD_RELOC_MSP430X_PCR20_CALL:
3725 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3727 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3730 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3731 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3732 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3734 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3737 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3738 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3740 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3743 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3744 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3746 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3750 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3751 fixp->fx_line, fixp->fx_r_type);
3757 fixp->fx_addnumber = value;
3762 S_IS_GAS_LOCAL (symbolS * s)
3769 name = S_GET_NAME (s);
3770 len = strlen (name) - 1;
3772 return name[len] == 1 || name[len] == 2;
3775 /* GAS will call this to generate a reloc, passing the resulting reloc
3776 to `bfd_install_relocation'. This currently works poorly, as
3777 `bfd_install_relocation' often does the wrong thing, and instances of
3778 `tc_gen_reloc' have been written to work around the problems, which
3779 in turns makes it difficult to fix `bfd_install_relocation'. */
3781 /* If while processing a fixup, a reloc really needs to be created
3782 then it is done here. */
3785 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
3787 static arelent * no_relocs = NULL;
3788 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3791 reloc = xmalloc (sizeof (arelent));
3792 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3793 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3795 if (reloc->howto == (reloc_howto_type *) NULL)
3797 as_bad_where (fixp->fx_file, fixp->fx_line,
3798 _("reloc %d not supported by object file format"),
3799 (int) fixp->fx_r_type);
3808 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3810 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3811 fixp->fx_subsy = NULL;
3814 if (fixp->fx_addsy && fixp->fx_subsy)
3816 asection *asec, *ssec;
3818 asec = S_GET_SEGMENT (fixp->fx_addsy);
3819 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3821 /* If we have a difference between two different, non-absolute symbols
3822 we must generate two relocs (one for each symbol) and allow the
3823 linker to resolve them - relaxation may change the distances between
3824 symbols, even local symbols defined in the same section.
3826 Unfortunately we cannot do this with assembler generated local labels
3827 because there can be multiple incarnations of the same label, with
3828 exactly the same name, in any given section and the linker will have
3829 no way to identify the correct one. Instead we just have to hope
3830 that no relaxtion will occur between the local label and the other
3831 symbol in the expression.
3833 Similarly we have to compute differences between symbols in the .eh_frame
3834 section as the linker is not smart enough to apply relocations there
3835 before attempting to process it. */
3836 if ((ssec != absolute_section || asec != absolute_section)
3837 && (fixp->fx_addsy != fixp->fx_subsy)
3838 && strcmp (ssec->name, ".eh_frame") != 0
3839 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3840 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3842 arelent * reloc2 = xmalloc (sizeof * reloc);
3847 reloc2->address = reloc->address;
3848 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3849 BFD_RELOC_MSP430_SYM_DIFF);
3850 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3852 if (ssec == absolute_section)
3853 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3856 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3857 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3860 reloc->addend = fixp->fx_offset;
3861 if (asec == absolute_section)
3863 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3864 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3868 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3869 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3878 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3880 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3881 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3883 switch (fixp->fx_r_type)
3886 md_number_to_chars (fixpos, reloc->addend, 1);
3890 md_number_to_chars (fixpos, reloc->addend, 2);
3894 md_number_to_chars (fixpos, reloc->addend, 3);
3898 md_number_to_chars (fixpos, reloc->addend, 4);
3903 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3914 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3915 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3917 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3918 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3920 md_number_to_chars (fixpos, amount, 2);
3925 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3926 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3927 reloc->addend = fixp->fx_offset;
3929 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3930 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3931 reloc->address = fixp->fx_offset;
3938 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3939 asection * segment_type ATTRIBUTE_UNUSED)
3941 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3943 /* This is a jump -> pcrel mode. Nothing to do much here.
3944 Return value == 2. */
3946 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3948 else if (fragP->fr_symbol)
3950 /* Its got a segment, but its not ours. Even if fr_symbol is in
3951 an absolute segment, we don't know a displacement until we link
3952 object files. So it will always be long. This also applies to
3953 labels in a subsegment of current. Liker may relax it to short
3954 jump later. Return value == 8. */
3956 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3960 /* We know the abs value. may be it is a jump to fixed address.
3961 Impossible in our case, cause all constants already handled. */
3963 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3966 return md_relax_table[fragP->fr_subtype].rlx_length;
3970 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3971 asection * sec ATTRIBUTE_UNUSED,
3977 struct rcodes_s * cc = NULL;
3978 struct hcodes_s * hc = NULL;
3980 switch (fragP->fr_subtype)
3982 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3983 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3984 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3985 /* We do not have to convert anything here.
3986 Just apply a fix. */
3987 rela = BFD_RELOC_MSP430_10_PCREL;
3990 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3991 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3992 /* Convert uncond branch jmp lab -> br lab. */
3993 if (target_is_430x ())
3994 cc = msp430x_rcodes + 7;
3996 cc = msp430_rcodes + 7;
3997 where = fragP->fr_literal + fragP->fr_fix;
3998 bfd_putl16 (cc->lop0, where);
3999 rela = BFD_RELOC_MSP430_RL_PCREL;
4003 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
4004 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
4006 /* Other simple branches. */
4007 int insn = bfd_getl16 (fragP->fr_opcode);
4010 /* Find actual instruction. */
4011 if (target_is_430x ())
4013 for (i = 0; i < 7 && !cc; i++)
4014 if (msp430x_rcodes[i].sop == insn)
4015 cc = msp430x_rcodes + i;
4019 for (i = 0; i < 7 && !cc; i++)
4020 if (msp430_rcodes[i].sop == insn)
4021 cc = & msp430_rcodes[i];
4024 if (!cc || !cc->name)
4025 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4026 __FUNCTION__, (long) insn);
4027 where = fragP->fr_literal + fragP->fr_fix;
4028 bfd_putl16 (cc->lop0, where);
4029 bfd_putl16 (cc->lop1, where + 2);
4030 rela = BFD_RELOC_MSP430_RL_PCREL;
4035 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
4036 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
4037 if (target_is_430x ())
4038 cc = msp430x_rcodes + 6;
4040 cc = msp430_rcodes + 6;
4041 where = fragP->fr_literal + fragP->fr_fix;
4042 bfd_putl16 (cc->lop0, where);
4043 bfd_putl16 (cc->lop1, where + 2);
4044 bfd_putl16 (cc->lop2, where + 4);
4045 rela = BFD_RELOC_MSP430_RL_PCREL;
4049 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4051 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4054 if (target_is_430x ())
4056 for (i = 0; i < 4 && !hc; i++)
4057 if (msp430x_hcodes[i].op1 == insn)
4058 hc = msp430x_hcodes + i;
4062 for (i = 0; i < 4 && !hc; i++)
4063 if (msp430_hcodes[i].op1 == insn)
4064 hc = &msp430_hcodes[i];
4066 if (!hc || !hc->name)
4067 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4068 __FUNCTION__, (long) insn);
4069 rela = BFD_RELOC_MSP430_10_PCREL;
4070 /* Apply a fix for a first label if necessary.
4071 another fix will be applied to the next word of insn anyway. */
4073 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4074 fragP->fr_offset, TRUE, rela);
4080 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4081 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4083 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4086 if (target_is_430x ())
4088 for (i = 0; i < 4 && !hc; i++)
4089 if (msp430x_hcodes[i].op1 == insn)
4090 hc = msp430x_hcodes + i;
4094 for (i = 0; i < 4 && !hc; i++)
4095 if (msp430_hcodes[i].op1 == insn)
4096 hc = & msp430_hcodes[i];
4098 if (!hc || !hc->name)
4099 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4100 __FUNCTION__, (long) insn);
4101 rela = BFD_RELOC_MSP430_RL_PCREL;
4102 where = fragP->fr_literal + fragP->fr_fix;
4103 bfd_putl16 (hc->lop0, where);
4104 bfd_putl16 (hc->lop1, where + 2);
4105 bfd_putl16 (hc->lop2, where + 4);
4111 as_fatal (_("internal inconsistency problem in %s: %lx"),
4112 __FUNCTION__, (long) fragP->fr_subtype);
4116 /* Now apply fix. */
4117 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4118 fragP->fr_offset, TRUE, rela);
4119 /* Just fixed 2 bytes. */
4123 /* Relax fragment. Mostly stolen from hc11 and mcore
4124 which arches I think I know. */
4127 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4128 long stretch ATTRIBUTE_UNUSED)
4133 const relax_typeS *this_type;
4134 const relax_typeS *start_type;
4135 relax_substateT next_state;
4136 relax_substateT this_state;
4137 const relax_typeS *table = md_relax_table;
4139 /* Nothing to be done if the frag has already max size. */
4140 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4141 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4144 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4146 symbolP = fragP->fr_symbol;
4147 if (symbol_resolved_p (symbolP))
4148 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4150 /* We know the offset. calculate a distance. */
4151 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4154 if (!msp430_enable_relax)
4156 /* Relaxation is not enabled. So, make all jump as long ones
4157 by setting 'aim' to quite high value. */
4161 this_state = fragP->fr_subtype;
4162 start_type = this_type = table + this_state;
4166 /* Look backwards. */
4167 for (next_state = this_type->rlx_more; next_state;)
4168 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4172 /* Grow to next state. */
4173 this_state = next_state;
4174 this_type = table + this_state;
4175 next_state = this_type->rlx_more;
4180 /* Look forwards. */
4181 for (next_state = this_type->rlx_more; next_state;)
4182 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4186 /* Grow to next state. */
4187 this_state = next_state;
4188 this_type = table + this_state;
4189 next_state = this_type->rlx_more;
4193 growth = this_type->rlx_length - start_type->rlx_length;
4195 fragP->fr_subtype = this_state;
4199 /* Return FALSE if the fixup in fixp should be left alone and not
4200 adjusted. We return FALSE here so that linker relaxation will
4204 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4206 /* If the symbol is in a non-code section then it should be OK. */
4208 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4214 /* Set the contents of the .MSP430.attributes section. */
4217 msp430_md_end (void)
4219 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4220 target_is_430x () ? 2 : 1);
4222 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4223 large_model ? 2 : 1);
4225 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4226 large_model ? 2 : 1);
4229 /* Returns FALSE if there is a msp430 specific reason why the
4230 subtraction of two same-section symbols cannot be computed by
4234 msp430_allow_local_subtract (expressionS * left,
4235 expressionS * right,
4238 /* If the symbols are not in a code section then they are OK. */
4239 if ((section->flags & SEC_CODE) == 0)
4242 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4245 if (left->X_add_symbol == right->X_add_symbol)
4248 /* We have to assume that there may be instructions between the
4249 two symbols and that relaxation may increase the distance between