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:
1224 msp430_section (int arg)
1226 char * saved_ilp = input_line_pointer;
1227 char * name = obj_elf_section_name ();
1229 if (strncmp (name, ".bss", 4) == 0
1230 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1231 (void) symbol_find_or_make ("__crt0_init_bss");
1234 && (strncmp (name, ".data", 5) == 0
1235 || strncmp (name, ".gnu.linkonce.d.", 16) == 0))
1236 (void) symbol_find_or_make ("__crt0_movedata");
1238 input_line_pointer = saved_ilp;
1239 obj_elf_section (arg);
1243 msp430_refsym (int arg ATTRIBUTE_UNUSED)
1245 char sym_name[1024];
1246 input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
1248 (void) symbol_find_or_make (sym_name);
1251 const pseudo_typeS md_pseudo_table[] =
1253 {"arch", msp430_set_arch, OPTION_MMCU},
1254 {"cpu", msp430_set_arch, OPTION_MCPU},
1255 {"profiler", msp430_profiler, 0},
1256 {"section", msp430_section, 0},
1257 {"section.s", msp430_section, 0},
1258 {"sect", msp430_section, 0},
1259 {"sect.s", msp430_section, 0},
1260 {"pushsection", msp430_section, 1},
1261 {"refsym", msp430_refsym, 0},
1265 const char *md_shortopts = "mm:,mP,mQ,ml,mN";
1267 struct option md_longopts[] =
1269 {"mmcu", required_argument, NULL, OPTION_MMCU},
1270 {"mcpu", required_argument, NULL, OPTION_MCPU},
1271 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1272 {"mQ", no_argument, NULL, OPTION_RELAX},
1273 {"ml", no_argument, NULL, OPTION_LARGE},
1274 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1275 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1276 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1277 {NULL, no_argument, NULL, 0}
1280 size_t md_longopts_size = sizeof (md_longopts);
1283 md_show_usage (FILE * stream)
1286 _("MSP430 options:\n"
1287 " -mmcu=<msp430-name> - select microcontroller type\n"
1288 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1290 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1291 " -mP - enable polymorph instructions\n"));
1293 _(" -ml - enable large code model\n"));
1295 _(" -mN - disable generation of NOP after changing interrupts\n"));
1297 _(" -mn - enable generation of NOP after changing interrupts\n"));
1299 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1303 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1309 extract_cmd (char * from, char * to, int limit)
1313 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1315 *(to + size) = *from;
1326 md_atof (int type, char * litP, int * sizeP)
1328 return ieee_md_atof (type, litP, sizeP, FALSE);
1334 struct msp430_opcode_s * opcode;
1335 msp430_hash = hash_new ();
1337 for (opcode = msp430_opcodes; opcode->name; opcode++)
1338 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1340 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1341 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1344 /* Returns the register number equivalent to the string T.
1345 Returns -1 if there is no such register.
1346 Skips a leading 'r' or 'R' character if there is one.
1347 Handles the register aliases PC and SP. */
1350 check_reg (char * t)
1357 if (*t == 'r' || *t == 'R')
1360 if (strncasecmp (t, "pc", 2) == 0)
1363 if (strncasecmp (t, "sp", 2) == 0)
1366 if (strncasecmp (t, "sr", 2) == 0)
1374 if (val < 1 || val > 15)
1381 msp430_srcoperand (struct msp430_operand_s * op,
1385 bfd_boolean allow_20bit_values,
1386 bfd_boolean constants_allowed)
1390 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1397 /* Check if there is:
1398 llo(x) - least significant 16 bits, x &= 0xffff
1399 lhi(x) - x = (x >> 16) & 0xffff,
1400 hlo(x) - x = (x >> 32) & 0xffff,
1401 hhi(x) - x = (x >> 48) & 0xffff
1402 The value _MUST_ be constant expression: #hlo(1231231231). */
1406 if (strncasecmp (h, "#llo(", 5) == 0)
1411 else if (strncasecmp (h, "#lhi(", 5) == 0)
1416 else if (strncasecmp (h, "#hlo(", 5) == 0)
1421 else if (strncasecmp (h, "#hhi(", 5) == 0)
1426 else if (strncasecmp (h, "#lo(", 4) == 0)
1431 else if (strncasecmp (h, "#hi(", 4) == 0)
1437 op->reg = 0; /* Reg PC. */
1439 op->ol = 1; /* Immediate will follow an instruction. */
1440 __tl = h + 1 + rval;
1443 parse_exp (__tl, &(op->exp));
1444 if (op->exp.X_op == O_constant)
1446 int x = op->exp.X_add_number;
1451 op->exp.X_add_number = x;
1453 else if (vshift == 1)
1455 x = (x >> 16) & 0xffff;
1456 op->exp.X_add_number = x;
1458 else if (vshift > 1)
1461 op->exp.X_add_number = -1;
1463 op->exp.X_add_number = 0; /* Nothing left. */
1464 x = op->exp.X_add_number;
1467 if (allow_20bit_values)
1469 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1471 as_bad (_("value 0x%x out of extended range."), x);
1475 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1477 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1481 /* Now check constants. */
1482 /* Substitute register mode with a constant generator if applicable. */
1484 if (!allow_20bit_values)
1485 x = (short) x; /* Extend sign. */
1487 if (! constants_allowed)
1519 #ifdef PUSH_1X_WORKAROUND
1522 /* Remove warning as confusing.
1523 as_warn (_("Hardware push bug workaround")); */
1536 #ifdef PUSH_1X_WORKAROUND
1539 /* Remove warning as confusing.
1540 as_warn (_("Hardware push bug workaround")); */
1552 else if (op->exp.X_op == O_symbol)
1556 else if (op->exp.X_op == O_big)
1561 op->exp.X_op = O_constant;
1562 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1563 x = op->exp.X_add_number;
1568 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1616 /* Redundant (yet) check. */
1617 else if (op->exp.X_op == O_register)
1619 (_("Registers cannot be used within immediate expression [%s]"), l);
1621 as_bad (_("unknown operand %s"), l);
1626 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1631 op->reg = 2; /* reg 2 in absolute addr mode. */
1632 op->am = 1; /* mode As == 01 bin. */
1633 op->ol = 1; /* Immediate value followed by instruction. */
1635 parse_exp (__tl, &(op->exp));
1637 if (op->exp.X_op == O_constant)
1639 int x = op->exp.X_add_number;
1641 if (allow_20bit_values)
1643 if (x > 0xfffff || x < -(0x7ffff))
1645 as_bad (_("value 0x%x out of extended range."), x);
1649 else if (x > 65535 || x < -32768)
1651 as_bad (_("value out of range: 0x%x"), x);
1655 else if (op->exp.X_op == O_symbol)
1659 /* Redundant (yet) check. */
1660 if (op->exp.X_op == O_register)
1662 (_("Registers cannot be used within absolute expression [%s]"), l);
1664 as_bad (_("unknown expression in operand %s"), l);
1670 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1674 char *m = strchr (l, '+');
1678 as_bad (_("unknown addressing mode %s"), l);
1684 if ((op->reg = check_reg (t)) == -1)
1686 as_bad (_("Bad register name %s"), t);
1694 /* PC cannot be used in indirect addressing. */
1695 if (target_is_430xv2 () && op->reg == 0)
1697 as_bad (_("cannot use indirect addressing with the PC"));
1703 /* Check if register indexed X(Rn). */
1706 char *h = strrchr (l, '(');
1707 char *m = strrchr (l, ')');
1716 as_bad (_("')' required"));
1724 /* Extract a register. */
1725 if ((op->reg = check_reg (t + 1)) == -1)
1728 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1735 as_bad (_("r2 should not be used in indexed addressing mode"));
1739 /* Extract constant. */
1743 parse_exp (__tl, &(op->exp));
1744 if (op->exp.X_op == O_constant)
1746 int x = op->exp.X_add_number;
1748 if (allow_20bit_values)
1750 if (x > 0xfffff || x < - (0x7ffff))
1752 as_bad (_("value 0x%x out of extended range."), x);
1756 else if (x > 65535 || x < -32768)
1758 as_bad (_("value out of range: 0x%x"), x);
1770 else if (op->exp.X_op == O_symbol)
1774 /* Redundant (yet) check. */
1775 if (op->exp.X_op == O_register)
1777 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1779 as_bad (_("unknown expression in operand %s"), l);
1787 /* Possibly register mode 'mov r1,r2'. */
1788 if ((op->reg = check_reg (l)) != -1)
1796 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1800 op->reg = 0; /* PC relative... be careful. */
1801 /* An expression starting with a minus sign is a constant, not an address. */
1802 op->am = (*l == '-' ? 3 : 1);
1805 parse_exp (__tl, &(op->exp));
1811 as_bad (_("unknown addressing mode for operand %s"), l);
1817 msp430_dstoperand (struct msp430_operand_s * op,
1820 bfd_boolean allow_20bit_values,
1821 bfd_boolean constants_allowed)
1824 int ret = msp430_srcoperand (op, l, bin, & dummy,
1838 parse_exp (__tl, &(op->exp));
1840 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1842 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1852 ("this addressing mode is not applicable for destination operand"));
1859 /* Attempt to encode a MOVA instruction with the given operands.
1860 Returns the length of the encoded instruction if successful
1861 or 0 upon failure. If the encoding fails, an error message
1862 will be returned if a pointer is provided. */
1865 try_encode_mova (bfd_boolean imm_op,
1867 struct msp430_operand_s * op1,
1868 struct msp430_operand_s * op2,
1869 const char ** error_message_return)
1875 /* Only a restricted subset of the normal MSP430 addressing modes
1876 are supported here, so check for the ones that are allowed. */
1879 if (op1->mode == OP_EXP)
1881 if (op2->mode != OP_REG)
1883 if (error_message_return != NULL)
1884 * error_message_return = _("expected register as second argument of %s");
1890 /* MOVA #imm20, Rdst. */
1891 bin |= 0x80 | op2->reg;
1892 frag = frag_more (4);
1893 where = frag - frag_now->fr_literal;
1894 if (op1->exp.X_op == O_constant)
1896 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1897 bfd_putl16 ((bfd_vma) bin, frag);
1898 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1902 bfd_putl16 ((bfd_vma) bin, frag);
1903 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1904 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1905 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1910 else if (op1->am == 1)
1912 /* MOVA z16(Rsrc), Rdst. */
1913 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1914 frag = frag_more (4);
1915 where = frag - frag_now->fr_literal;
1916 bfd_putl16 ((bfd_vma) bin, frag);
1917 if (op1->exp.X_op == O_constant)
1919 if (op1->exp.X_add_number > 0xffff
1920 || op1->exp.X_add_number < -(0x7fff))
1922 if (error_message_return != NULL)
1923 * error_message_return = _("index value too big for %s");
1926 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1930 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1931 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1933 BFD_RELOC_MSP430X_PCR16 :
1934 BFD_RELOC_MSP430X_ABS16);
1939 if (error_message_return != NULL)
1940 * error_message_return = _("unexpected addressing mode for %s");
1943 else if (op1->am == 0)
1945 /* MOVA Rsrc, ... */
1946 if (op2->mode == OP_REG)
1948 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1949 frag = frag_more (2);
1950 where = frag - frag_now->fr_literal;
1951 bfd_putl16 ((bfd_vma) bin, frag);
1954 else if (op2->am == 1)
1958 /* MOVA Rsrc, &abs20. */
1959 bin |= 0x60 | (op1->reg << 8);
1960 frag = frag_more (4);
1961 where = frag - frag_now->fr_literal;
1962 if (op2->exp.X_op == O_constant)
1964 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1965 bfd_putl16 ((bfd_vma) bin, frag);
1966 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1970 bfd_putl16 ((bfd_vma) bin, frag);
1971 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1972 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1973 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1978 /* MOVA Rsrc, z16(Rdst). */
1979 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1980 frag = frag_more (4);
1981 where = frag - frag_now->fr_literal;
1982 bfd_putl16 ((bfd_vma) bin, frag);
1983 if (op2->exp.X_op == O_constant)
1985 if (op2->exp.X_add_number > 0xffff
1986 || op2->exp.X_add_number < -(0x7fff))
1988 if (error_message_return != NULL)
1989 * error_message_return = _("index value too big for %s");
1992 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1996 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1997 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
1999 BFD_RELOC_MSP430X_PCR16 :
2000 BFD_RELOC_MSP430X_ABS16);
2005 if (error_message_return != NULL)
2006 * error_message_return = _("unexpected addressing mode for %s");
2011 /* imm_op == FALSE. */
2013 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2015 /* MOVA &abs20, Rdst. */
2016 if (op2->mode != OP_REG)
2018 if (error_message_return != NULL)
2019 * error_message_return = _("expected register as second argument of %s");
2023 if (op2->reg == 2 || op2->reg == 3)
2025 if (error_message_return != NULL)
2026 * error_message_return = _("constant generator destination register found in %s");
2030 bin |= 0x20 | op2->reg;
2031 frag = frag_more (4);
2032 where = frag - frag_now->fr_literal;
2033 if (op1->exp.X_op == O_constant)
2035 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2036 bfd_putl16 ((bfd_vma) bin, frag);
2037 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2041 bfd_putl16 ((bfd_vma) bin, frag);
2042 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2043 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2044 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2048 else if (op1->mode == OP_REG)
2052 /* MOVA @Rsrc+, Rdst. */
2053 if (op2->mode != OP_REG)
2055 if (error_message_return != NULL)
2056 * error_message_return = _("expected register as second argument of %s");
2060 if (op2->reg == 2 || op2->reg == 3)
2062 if (error_message_return != NULL)
2063 * error_message_return = _("constant generator destination register found in %s");
2067 if (op1->reg == 2 || op1->reg == 3)
2069 if (error_message_return != NULL)
2070 * error_message_return = _("constant generator source register found in %s");
2074 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2075 frag = frag_more (2);
2076 where = frag - frag_now->fr_literal;
2077 bfd_putl16 ((bfd_vma) bin, frag);
2080 else if (op1->am == 2)
2082 /* MOVA @Rsrc,Rdst */
2083 if (op2->mode != OP_REG)
2085 if (error_message_return != NULL)
2086 * error_message_return = _("expected register as second argument of %s");
2090 if (op2->reg == 2 || op2->reg == 3)
2092 if (error_message_return != NULL)
2093 * error_message_return = _("constant generator destination register found in %s");
2097 if (op1->reg == 2 || op1->reg == 3)
2099 if (error_message_return != NULL)
2100 * error_message_return = _("constant generator source register found in %s");
2104 bin |= (op1->reg << 8) | op2->reg;
2105 frag = frag_more (2);
2106 where = frag - frag_now->fr_literal;
2107 bfd_putl16 ((bfd_vma) bin, frag);
2112 if (error_message_return != NULL)
2113 * error_message_return = _("unexpected addressing mode for %s");
2118 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2120 /* Parse instruction operands.
2121 Return binary opcode. */
2124 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2126 int bin = opcode->bin_opcode; /* Opcode mask. */
2127 int insn_length = 0;
2128 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2131 struct msp430_operand_s op1, op2;
2133 static short ZEROS = 0;
2134 int byte_op, imm_op;
2137 int extended = 0x1800;
2138 bfd_boolean extended_op = FALSE;
2139 bfd_boolean addr_op;
2140 const char * error_message;
2141 static signed int repeat_count = 0;
2142 bfd_boolean fix_emitted;
2144 /* Opcode is the one from opcodes table
2145 line contains something like
2154 bfd_boolean check = FALSE;
2157 switch (TOLOWER (* line))
2160 /* Byte operation. */
2161 bin |= BYTE_OPERATION;
2167 /* "Address" ops work on 20-bit values. */
2169 bin |= BYTE_OPERATION;
2174 /* Word operation - this is the default. */
2182 as_warn (_("no size modifier after period, .w assumed"));
2186 as_bad (_("unrecognised instruction size modifier .%c"),
2198 if (*line && ! ISSPACE (*line))
2200 as_bad (_("junk found after instruction: %s.%s"),
2201 opcode->name, line);
2205 /* Catch the case where the programmer has used a ".a" size modifier on an
2206 instruction that does not support it. Look for an alternative extended
2207 instruction that has the same name without the period. Eg: "add.a"
2208 becomes "adda". Although this not an officially supported way of
2209 specifing instruction aliases other MSP430 assemblers allow it. So we
2210 support it for compatibility purposes. */
2211 if (addr_op && opcode->fmt >= 0)
2213 char * old_name = opcode->name;
2216 sprintf (real_name, "%sa", old_name);
2217 opcode = hash_find (msp430_hash, real_name);
2220 as_bad (_("instruction %s.a does not exist"), old_name);
2223 #if 0 /* Enable for debugging. */
2224 as_warn ("treating %s.a as %s", old_name, real_name);
2227 bin = opcode->bin_opcode;
2230 if (opcode->fmt != -1
2231 && opcode->insn_opnumb
2232 && (!*line || *line == '\n'))
2234 as_bad (_("instruction %s requires %d operand(s)"),
2235 opcode->name, opcode->insn_opnumb);
2239 memset (l1, 0, sizeof (l1));
2240 memset (l2, 0, sizeof (l2));
2241 memset (&op1, 0, sizeof (op1));
2242 memset (&op2, 0, sizeof (op2));
2246 if ((fmt = opcode->fmt) < 0)
2248 if (! target_is_430x ())
2250 as_bad (_("instruction %s requires MSP430X mcu"),
2261 /* If requested set the extended instruction repeat count. */
2264 if (repeat_count > 0)
2265 extended |= (repeat_count - 1);
2267 extended |= (1 << 7) | (- repeat_count);
2270 as_bad (_("unable to repeat %s insn"), opcode->name);
2277 case 0: /* Emulated. */
2278 switch (opcode->insn_opnumb)
2281 /* Set/clear bits instructions. */
2285 extended |= BYTE_OPERATION;
2287 /* Emit the extension word. */
2289 frag = frag_more (insn_length);
2290 bfd_putl16 (extended, frag);
2294 frag = frag_more (insn_length);
2295 bfd_putl16 ((bfd_vma) bin, frag);
2297 if (gen_interrupt_nops
2298 && (is_opcode ("eint") || is_opcode ("dint")))
2300 /* Emit a NOP following interrupt enable/disable.
2301 See 1.3.4.1 of the MSP430x5xx User Guide. */
2303 frag = frag_more (2);
2304 as_warn (_("a NOP instruction has been inserted after %s"),
2306 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2308 dwarf2_emit_insn (insn_length);
2312 /* Something which works with destination operand. */
2313 line = extract_operand (line, l1, sizeof (l1));
2314 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2318 /* Compute the entire instruction length, in bytes. */
2319 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2320 frag = frag_more (insn_length);
2321 where = frag - frag_now->fr_literal;
2326 extended |= BYTE_OPERATION;
2328 if (op1.ol != 0 && ((extended & 0xf) != 0))
2330 as_bad (_("repeat instruction used with non-register mode instruction"));
2334 if (op1.mode == OP_EXP)
2336 if (op1.exp.X_op == O_constant)
2337 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2339 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2340 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2341 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2343 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2344 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2347 /* Emit the extension word. */
2348 bfd_putl16 (extended, frag);
2353 bin |= (op1.reg | (op1.am << 7));
2354 bfd_putl16 ((bfd_vma) bin, frag);
2358 if (op1.mode == OP_EXP)
2360 if (op1.exp.X_op == O_constant)
2362 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2366 bfd_putl16 ((bfd_vma) ZEROS, frag);
2371 fix_new_exp (frag_now, where, 2,
2372 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2374 fix_new_exp (frag_now, where, 2,
2375 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2380 if (gen_interrupt_nops
2381 && is_opcode ("clr")
2382 && bin == 0x4302 /* CLR R2*/)
2384 /* Emit a NOP following interrupt enable/disable.
2385 See 1.3.4.1 of the MSP430x5xx User Guide. */
2387 frag = frag_more (2);
2388 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2389 as_warn (_("a NOP instruction has been inserted after %s"),
2393 dwarf2_emit_insn (insn_length);
2397 /* Shift instruction. */
2398 line = extract_operand (line, l1, sizeof (l1));
2399 strncpy (l2, l1, sizeof (l2));
2400 l2[sizeof (l2) - 1] = '\0';
2401 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2402 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2405 break; /* An error occurred. All warnings were done before. */
2407 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2408 frag = frag_more (insn_length);
2409 where = frag - frag_now->fr_literal;
2411 if (target_is_430xv2 ()
2412 && op1.mode == OP_REG
2414 && (is_opcode ("rlax")
2415 || is_opcode ("rlcx")
2416 || is_opcode ("rla")
2417 || is_opcode ("rlc")))
2419 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2426 extended |= BYTE_OPERATION;
2428 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2430 as_bad (_("repeat instruction used with non-register mode instruction"));
2434 if (op1.mode == OP_EXP)
2436 if (op1.exp.X_op == O_constant)
2437 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2439 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2440 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2441 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2443 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2444 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2447 if (op2.mode == OP_EXP)
2449 if (op2.exp.X_op == O_constant)
2450 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2452 else if (op1.mode == OP_EXP)
2453 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2454 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2455 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2457 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2458 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2459 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2462 /* Emit the extension word. */
2463 bfd_putl16 (extended, frag);
2468 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2469 bfd_putl16 ((bfd_vma) bin, frag);
2473 if (op1.mode == OP_EXP)
2475 if (op1.exp.X_op == O_constant)
2477 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2481 bfd_putl16 ((bfd_vma) ZEROS, frag);
2485 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2486 fix_new_exp (frag_now, where, 2,
2487 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2489 fix_new_exp (frag_now, where, 2,
2490 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2497 if (op2.mode == OP_EXP)
2499 if (op2.exp.X_op == O_constant)
2501 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2505 bfd_putl16 ((bfd_vma) ZEROS, frag);
2509 if (op2.reg) /* Not PC relative. */
2510 fix_new_exp (frag_now, where, 2,
2511 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2513 fix_new_exp (frag_now, where, 2,
2514 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2519 dwarf2_emit_insn (insn_length);
2523 /* Branch instruction => mov dst, r0. */
2526 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2530 line = extract_operand (line, l1, sizeof (l1));
2531 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2537 bin |= ((op1.reg << 8) | (op1.am << 4));
2538 op_length = 2 + 2 * op1.ol;
2539 frag = frag_more (op_length);
2540 where = frag - frag_now->fr_literal;
2541 bfd_putl16 ((bfd_vma) bin, frag);
2543 if (op1.mode == OP_EXP)
2545 if (op1.exp.X_op == O_constant)
2547 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2553 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2555 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2556 fix_new_exp (frag_now, where, 2,
2557 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2559 fix_new_exp (frag_now, where, 2,
2560 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2564 dwarf2_emit_insn (insn_length + op_length);
2568 /* CALLA instructions. */
2569 fix_emitted = FALSE;
2571 line = extract_operand (line, l1, sizeof (l1));
2574 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2575 extended_op, FALSE);
2581 op_length = 2 + 2 * op1.ol;
2582 frag = frag_more (op_length);
2583 where = frag - frag_now->fr_literal;
2591 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2592 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2595 else if (op1.am == 1)
2601 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2602 BFD_RELOC_MSP430X_PCR20_CALL);
2606 bin |= 0x50 | op1.reg;
2608 else if (op1.am == 0)
2609 bin |= 0x40 | op1.reg;
2611 else if (op1.am == 1)
2615 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2616 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2619 else if (op1.am == 2)
2620 bin |= 0x60 | op1.reg;
2621 else if (op1.am == 3)
2622 bin |= 0x70 | op1.reg;
2624 bfd_putl16 ((bfd_vma) bin, frag);
2626 if (op1.mode == OP_EXP)
2630 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2634 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2637 fix_new_exp (frag_now, where + 2, 2,
2638 &(op1.exp), FALSE, BFD_RELOC_16);
2641 dwarf2_emit_insn (insn_length + op_length);
2649 /* [POP|PUSH]M[.A] #N, Rd */
2650 line = extract_operand (line, l1, sizeof (l1));
2651 line = extract_operand (line, l2, sizeof (l2));
2655 as_bad (_("expected #n as first argument of %s"), opcode->name);
2658 parse_exp (l1 + 1, &(op1.exp));
2659 if (op1.exp.X_op != O_constant)
2661 as_bad (_("expected constant expression for first argument of %s"),
2666 if ((reg = check_reg (l2)) == -1)
2668 as_bad (_("expected register as second argument of %s"),
2674 frag = frag_more (op_length);
2675 where = frag - frag_now->fr_literal;
2676 bin = opcode->bin_opcode;
2679 n = op1.exp.X_add_number;
2680 bin |= (n - 1) << 4;
2681 if (is_opcode ("pushm"))
2685 if (reg - n + 1 < 0)
2687 as_bad (_("Too many registers popped"));
2691 /* CPU21 parts cannot use POPM to restore the SR register. */
2692 if (target_is_430xv2 ()
2693 && (reg - n + 1 < 3)
2695 && is_opcode ("popm"))
2697 as_bad (_("Cannot use POPM to restore the SR register"));
2701 bin |= (reg - n + 1);
2704 bfd_putl16 ((bfd_vma) bin, frag);
2705 dwarf2_emit_insn (op_length);
2714 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2715 if (extended & 0xff)
2717 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2721 line = extract_operand (line, l1, sizeof (l1));
2722 line = extract_operand (line, l2, sizeof (l2));
2726 as_bad (_("expected #n as first argument of %s"), opcode->name);
2729 parse_exp (l1 + 1, &(op1.exp));
2730 if (op1.exp.X_op != O_constant)
2732 as_bad (_("expected constant expression for first argument of %s"),
2736 n = op1.exp.X_add_number;
2739 as_bad (_("expected first argument of %s to be in the range 1-4"),
2744 if ((reg = check_reg (l2)) == -1)
2746 as_bad (_("expected register as second argument of %s"),
2751 if (target_is_430xv2 () && reg == 0)
2753 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2758 frag = frag_more (op_length);
2759 where = frag - frag_now->fr_literal;
2761 bin = opcode->bin_opcode;
2764 bin |= (n - 1) << 10;
2767 bfd_putl16 ((bfd_vma) bin, frag);
2768 dwarf2_emit_insn (op_length);
2776 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2777 if (extended & 0xff)
2779 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2783 line = extract_operand (line, l1, sizeof (l1));
2784 if ((reg = check_reg (l1)) == -1)
2786 as_bad (_("expected register as argument of %s"),
2791 if (target_is_430xv2 () && reg == 0)
2793 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2799 /* Tricky - there is no single instruction that will do this.
2800 Encode as: RRA.B rN { BIC.B #0x80, rN */
2802 frag = frag_more (op_length);
2803 where = frag - frag_now->fr_literal;
2805 bfd_putl16 ((bfd_vma) bin, frag);
2806 dwarf2_emit_insn (2);
2808 bfd_putl16 ((bfd_vma) bin, frag + 2);
2810 bfd_putl16 ((bfd_vma) bin, frag + 4);
2811 dwarf2_emit_insn (4);
2815 /* Encode as RRUM[.A] rN. */
2816 bin = opcode->bin_opcode;
2821 frag = frag_more (op_length);
2822 where = frag - frag_now->fr_literal;
2823 bfd_putl16 ((bfd_vma) bin, frag);
2824 dwarf2_emit_insn (op_length);
2831 bfd_boolean need_reloc = FALSE;
2835 /* ADDA, CMPA and SUBA address instructions. */
2836 if (extended & 0xff)
2838 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2842 line = extract_operand (line, l1, sizeof (l1));
2843 line = extract_operand (line, l2, sizeof (l2));
2845 bin = opcode->bin_opcode;
2849 parse_exp (l1 + 1, &(op1.exp));
2851 if (op1.exp.X_op == O_constant)
2853 n = op1.exp.X_add_number;
2854 if (n > 0xfffff || n < - (0x7ffff))
2856 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2861 bin |= ((n >> 16) & 0xf) << 8;
2873 if ((n = check_reg (l1)) == -1)
2875 as_bad (_("expected register name or constant as first argument of %s"),
2880 bin |= (n << 8) | (1 << 6);
2884 if ((reg = check_reg (l2)) == -1)
2886 as_bad (_("expected register as second argument of %s"),
2891 frag = frag_more (op_length);
2892 where = frag - frag_now->fr_literal;
2895 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2896 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2898 bfd_putl16 ((bfd_vma) bin, frag);
2900 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2901 dwarf2_emit_insn (op_length);
2905 case 9: /* MOVA, BRA, RETA. */
2907 bin = opcode->bin_opcode;
2909 if (is_opcode ("reta"))
2911 /* The RETA instruction does not take any arguments.
2912 The implicit first argument is @SP+.
2913 The implicit second argument is PC. */
2923 line = extract_operand (line, l1, sizeof (l1));
2924 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2925 &imm_op, extended_op, FALSE);
2927 if (is_opcode ("bra"))
2929 /* This is the BRA synthetic instruction.
2930 The second argument is always PC. */
2936 line = extract_operand (line, l2, sizeof (l2));
2937 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2942 break; /* Error occurred. All warnings were done before. */
2945 /* Only a restricted subset of the normal MSP430 addressing modes
2946 are supported here, so check for the ones that are allowed. */
2947 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2948 & error_message)) == 0)
2950 as_bad (error_message, opcode->name);
2953 dwarf2_emit_insn (op_length);
2957 line = extract_operand (line, l1, sizeof l1);
2958 /* The RPT instruction only accepted immediates and registers. */
2961 parse_exp (l1 + 1, &(op1.exp));
2962 if (op1.exp.X_op != O_constant)
2964 as_bad (_("expected constant value as argument to RPT"));
2967 if (op1.exp.X_add_number < 1
2968 || op1.exp.X_add_number > (1 << 4))
2970 as_bad (_("expected constant in the range 2..16"));
2974 /* We silently accept and ignore a repeat count of 1. */
2975 if (op1.exp.X_add_number > 1)
2976 repeat_count = op1.exp.X_add_number;
2982 if ((reg = check_reg (l1)) != -1)
2985 as_warn (_("PC used as an argument to RPT"));
2987 repeat_count = - reg;
2991 as_bad (_("expected constant or register name as argument to RPT insn"));
2998 as_bad (_("Illegal emulated instruction "));
3003 case 1: /* Format 1, double operand. */
3004 line = extract_operand (line, l1, sizeof (l1));
3005 line = extract_operand (line, l2, sizeof (l2));
3006 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3007 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3010 break; /* Error occurred. All warnings were done before. */
3013 && is_opcode ("movx")
3015 && msp430_enable_relax)
3017 /* This is the MOVX.A instruction. See if we can convert
3018 it into the MOVA instruction instead. This saves 2 bytes. */
3019 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3022 dwarf2_emit_insn (op_length);
3027 /* Compute the entire length of the instruction in bytes. */
3029 (extended_op ? 2 : 0) /* The extension word. */
3030 + 2 /* The opcode */
3031 + (2 * op1.ol) /* The first operand. */
3032 + (2 * op2.ol); /* The second operand. */
3034 frag = frag_more (insn_length);
3035 where = frag - frag_now->fr_literal;
3040 extended |= BYTE_OPERATION;
3042 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3044 as_bad (_("repeat instruction used with non-register mode instruction"));
3048 /* If necessary, emit a reloc to update the extension word. */
3049 if (op1.mode == OP_EXP)
3051 if (op1.exp.X_op == O_constant)
3052 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3054 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3055 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3056 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3058 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3059 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3062 if (op2.mode == OP_EXP)
3064 if (op2.exp.X_op == O_constant)
3065 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3067 else if (op1.mode == OP_EXP)
3068 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3069 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3070 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3073 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3074 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3075 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3078 /* Emit the extension word. */
3079 bfd_putl16 (extended, frag);
3084 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3085 bfd_putl16 ((bfd_vma) bin, frag);
3089 if (op1.mode == OP_EXP)
3091 if (op1.exp.X_op == O_constant)
3093 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3097 bfd_putl16 ((bfd_vma) ZEROS, frag);
3101 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3102 fix_new_exp (frag_now, where, 2,
3103 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3105 fix_new_exp (frag_now, where, 2,
3106 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3114 if (op2.mode == OP_EXP)
3116 if (op2.exp.X_op == O_constant)
3118 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3122 bfd_putl16 ((bfd_vma) ZEROS, frag);
3126 if (op2.reg) /* Not PC relative. */
3127 fix_new_exp (frag_now, where, 2,
3128 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3130 fix_new_exp (frag_now, where, 2,
3131 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3136 if (gen_interrupt_nops
3137 && ( (is_opcode ("bic") && bin == 0xc232)
3138 || (is_opcode ("bis") && bin == 0xd232)
3139 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
3141 /* Emit a NOP following interrupt enable/disable.
3142 See 1.3.4.1 of the MSP430x5xx User Guide. */
3144 frag = frag_more (2);
3145 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3146 as_warn (_("a NOP instruction has been inserted after %s"),
3150 dwarf2_emit_insn (insn_length);
3153 case 2: /* Single-operand mostly instr. */
3154 if (opcode->insn_opnumb == 0)
3156 /* reti instruction. */
3158 frag = frag_more (2);
3159 bfd_putl16 ((bfd_vma) bin, frag);
3160 dwarf2_emit_insn (insn_length);
3164 line = extract_operand (line, l1, sizeof (l1));
3165 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3166 &imm_op, extended_op, TRUE);
3168 break; /* Error in operand. */
3170 if (target_is_430xv2 ()
3171 && op1.mode == OP_REG
3173 && (is_opcode ("rrax")
3174 || is_opcode ("rrcx")
3175 || is_opcode ("rra")
3176 || is_opcode ("rrc")))
3178 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3182 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3183 frag = frag_more (insn_length);
3184 where = frag - frag_now->fr_literal;
3188 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3190 /* These two instructions use a special
3191 encoding of the A/L and B/W bits. */
3192 bin &= ~ BYTE_OPERATION;
3196 as_bad (_("%s instruction does not accept a .b suffix"),
3201 extended |= BYTE_OPERATION;
3204 extended |= BYTE_OPERATION;
3206 if (op1.ol != 0 && ((extended & 0xf) != 0))
3208 as_bad (_("repeat instruction used with non-register mode instruction"));
3212 if (op1.mode == OP_EXP)
3214 if (op1.exp.X_op == O_constant)
3215 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3217 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3218 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3219 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3221 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3222 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3225 /* Emit the extension word. */
3226 bfd_putl16 (extended, frag);
3231 bin |= op1.reg | (op1.am << 4);
3232 bfd_putl16 ((bfd_vma) bin, frag);
3236 if (op1.mode == OP_EXP)
3238 if (op1.exp.X_op == O_constant)
3240 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3244 bfd_putl16 ((bfd_vma) ZEROS, frag);
3248 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3249 fix_new_exp (frag_now, where, 2,
3250 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3252 fix_new_exp (frag_now, where, 2,
3253 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3258 dwarf2_emit_insn (insn_length);
3261 case 3: /* Conditional jumps instructions. */
3262 line = extract_operand (line, l1, sizeof (l1));
3263 /* l1 is a label. */
3272 parse_exp (m, &exp);
3274 /* In order to handle something like:
3278 jz 4 ; skip next 4 bytes
3281 nop ; will jump here if r5 positive or zero
3283 jCOND -n ;assumes jump n bytes backward:
3293 jCOND $n ; jump from PC in either direction. */
3295 if (exp.X_op == O_constant)
3297 int x = exp.X_add_number;
3301 as_warn (_("Even number required. Rounded to %d"), x + 1);
3305 if ((*l1 == '$' && x > 0) || x < 0)
3310 if (x > 512 || x < -511)
3312 as_bad (_("Wrong displacement %d"), x << 1);
3317 frag = frag_more (2); /* Instr size is 1 word. */
3320 bfd_putl16 ((bfd_vma) bin, frag);
3322 else if (exp.X_op == O_symbol && *l1 != '$')
3325 frag = frag_more (2); /* Instr size is 1 word. */
3326 where = frag - frag_now->fr_literal;
3327 fix_new_exp (frag_now, where, 2,
3328 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3330 bfd_putl16 ((bfd_vma) bin, frag);
3332 else if (*l1 == '$')
3334 as_bad (_("instruction requires label sans '$'"));
3338 ("instruction requires label or value in range -511:512"));
3339 dwarf2_emit_insn (insn_length);
3344 as_bad (_("instruction requires label"));
3349 case 4: /* Extended jumps. */
3350 if (!msp430_enable_polys)
3352 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3356 line = extract_operand (line, l1, sizeof (l1));
3362 /* Ignore absolute addressing. make it PC relative anyway. */
3363 if (*m == '#' || *m == '$')
3366 parse_exp (m, & exp);
3367 if (exp.X_op == O_symbol)
3369 /* Relaxation required. */
3370 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3372 if (target_is_430x ())
3373 rc = msp430x_rcodes[opcode->insn_opnumb];
3375 /* The parameter to dwarf2_emit_insn is actually the offset to
3376 the start of the insn from the fix piece of instruction that
3377 was emitted. Since next fragments may have variable size we
3378 tie debug info to the beginning of the instruction. */
3380 frag = frag_more (8);
3381 dwarf2_emit_insn (0);
3382 bfd_putl16 ((bfd_vma) rc.sop, frag);
3383 frag = frag_variant (rs_machine_dependent, 8, 2,
3385 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3387 0, /* Offset is zero if jump dist less than 1K. */
3393 as_bad (_("instruction requires label"));
3396 case 5: /* Emulated extended branches. */
3397 if (!msp430_enable_polys)
3399 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3402 line = extract_operand (line, l1, sizeof (l1));
3408 /* Ignore absolute addressing. make it PC relative anyway. */
3409 if (*m == '#' || *m == '$')
3412 parse_exp (m, & exp);
3413 if (exp.X_op == O_symbol)
3415 /* Relaxation required. */
3416 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3418 if (target_is_430x ())
3419 hc = msp430x_hcodes[opcode->insn_opnumb];
3422 frag = frag_more (8);
3423 dwarf2_emit_insn (0);
3424 bfd_putl16 ((bfd_vma) hc.op0, frag);
3425 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3427 frag = frag_variant (rs_machine_dependent, 8, 2,
3428 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3430 0, /* Offset is zero if jump dist less than 1K. */
3436 as_bad (_("instruction requires label"));
3440 as_bad (_("Illegal instruction or not implemented opcode."));
3443 input_line_pointer = line;
3448 md_assemble (char * str)
3450 struct msp430_opcode_s * opcode;
3454 str = skip_space (str); /* Skip leading spaces. */
3455 str = extract_cmd (str, cmd, sizeof (cmd));
3457 while (cmd[i] && i < sizeof (cmd))
3459 char a = TOLOWER (cmd[i]);
3466 as_bad (_("can't find opcode "));
3470 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3474 as_bad (_("unknown opcode `%s'"), cmd);
3479 char *__t = input_line_pointer;
3481 msp430_operands (opcode, str);
3482 input_line_pointer = __t;
3486 /* GAS will call this function for each section at the end of the assembly,
3487 to permit the CPU backend to adjust the alignment of a section. */
3490 md_section_align (asection * seg, valueT addr)
3492 int align = bfd_get_section_alignment (stdoutput, seg);
3494 return ((addr + (1 << align) - 1) & (-1 << align));
3497 /* If you define this macro, it should return the offset between the
3498 address of a PC relative fixup and the position from which the PC
3499 relative adjustment should be made. On many processors, the base
3500 of a PC relative instruction is the next instruction, so this
3501 macro would return the length of an instruction. */
3504 md_pcrel_from_section (fixS * fixp, segT sec)
3506 if (fixp->fx_addsy != (symbolS *) NULL
3507 && (!S_IS_DEFINED (fixp->fx_addsy)
3508 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3511 return fixp->fx_frag->fr_address + fixp->fx_where;
3514 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3515 Now it handles the situation when relocations
3516 have to be passed to linker. */
3518 msp430_force_relocation_local (fixS *fixp)
3520 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3524 if (msp430_enable_polys
3525 && !msp430_enable_relax)
3528 return (!fixp->fx_pcrel
3529 || generic_force_reloc (fixp));
3533 /* GAS will call this for each fixup. It should store the correct
3534 value in the object file. */
3536 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3538 unsigned char * where;
3542 if (fixp->fx_addsy == (symbolS *) NULL)
3547 else if (fixp->fx_pcrel)
3549 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3551 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3553 /* FIXME: We can appear here only in case if we perform a pc
3554 relative jump to the label which is i) global, ii) locally
3555 defined or this is a jump to an absolute symbol.
3556 If this is an absolute symbol -- everything is OK.
3557 If this is a global label, we've got a symbol value defined
3559 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3560 from this section start
3561 2. *valuep will contain the real offset from jump insn to the
3563 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3564 will be incorrect. Therefore remove s_get_value. */
3565 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3573 value = fixp->fx_offset;
3575 if (fixp->fx_subsy != (symbolS *) NULL)
3577 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3579 value -= S_GET_VALUE (fixp->fx_subsy);
3585 fixp->fx_no_overflow = 1;
3587 /* If polymorphs are enabled and relax disabled.
3588 do not kill any relocs and pass them to linker. */
3589 if (msp430_enable_polys
3590 && !msp430_enable_relax)
3592 if (!fixp->fx_addsy || (fixp->fx_addsy
3593 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
3594 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3601 /* Fetch the instruction, insert the fully resolved operand
3602 value, and stuff the instruction back again. */
3603 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3605 insn = bfd_getl16 (where);
3607 switch (fixp->fx_r_type)
3609 case BFD_RELOC_MSP430_10_PCREL:
3611 as_bad_where (fixp->fx_file, fixp->fx_line,
3612 _("odd address operand: %ld"), value);
3614 /* Jumps are in words. */
3616 --value; /* Correct PC. */
3618 if (value < -512 || value > 511)
3619 as_bad_where (fixp->fx_file, fixp->fx_line,
3620 _("operand out of range: %ld"), value);
3622 value &= 0x3ff; /* get rid of extended sign */
3623 bfd_putl16 ((bfd_vma) (value | insn), where);
3626 case BFD_RELOC_MSP430X_PCR16:
3627 case BFD_RELOC_MSP430_RL_PCREL:
3628 case BFD_RELOC_MSP430_16_PCREL:
3630 as_bad_where (fixp->fx_file, fixp->fx_line,
3631 _("odd address operand: %ld"), value);
3634 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3635 /* Nothing to be corrected here. */
3636 if (value < -32768 || value > 65536)
3637 as_bad_where (fixp->fx_file, fixp->fx_line,
3638 _("operand out of range: %ld"), value);
3641 case BFD_RELOC_MSP430X_ABS16:
3642 case BFD_RELOC_MSP430_16:
3644 case BFD_RELOC_MSP430_16_BYTE:
3645 value &= 0xffff; /* Get rid of extended sign. */
3646 bfd_putl16 ((bfd_vma) value, where);
3650 bfd_putl16 ((bfd_vma) value, where);
3653 case BFD_RELOC_MSP430_ABS8:
3655 bfd_put_8 (NULL, (bfd_vma) value, where);
3658 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3659 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3660 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3662 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3665 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3666 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3668 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3671 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3672 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3674 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3677 case BFD_RELOC_MSP430X_PCR20_CALL:
3678 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3680 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3683 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3684 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3685 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3687 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3690 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3691 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3693 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3696 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3697 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3699 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3703 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3704 fixp->fx_line, fixp->fx_r_type);
3710 fixp->fx_addnumber = value;
3715 S_IS_GAS_LOCAL (symbolS * s)
3722 name = S_GET_NAME (s);
3723 len = strlen (name) - 1;
3725 return name[len] == 1 || name[len] == 2;
3728 /* GAS will call this to generate a reloc, passing the resulting reloc
3729 to `bfd_install_relocation'. This currently works poorly, as
3730 `bfd_install_relocation' often does the wrong thing, and instances of
3731 `tc_gen_reloc' have been written to work around the problems, which
3732 in turns makes it difficult to fix `bfd_install_relocation'. */
3734 /* If while processing a fixup, a reloc really needs to be created
3735 then it is done here. */
3738 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
3740 static arelent * no_relocs = NULL;
3741 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3744 reloc = xmalloc (sizeof (arelent));
3745 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3746 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3748 if (reloc->howto == (reloc_howto_type *) NULL)
3750 as_bad_where (fixp->fx_file, fixp->fx_line,
3751 _("reloc %d not supported by object file format"),
3752 (int) fixp->fx_r_type);
3761 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3763 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3764 fixp->fx_subsy = NULL;
3767 if (fixp->fx_addsy && fixp->fx_subsy)
3769 asection *asec, *ssec;
3771 asec = S_GET_SEGMENT (fixp->fx_addsy);
3772 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3774 /* If we have a difference between two different, non-absolute symbols
3775 we must generate two relocs (one for each symbol) and allow the
3776 linker to resolve them - relaxation may change the distances between
3777 symbols, even local symbols defined in the same section.
3779 Unfortunately we cannot do this with assembler generated local labels
3780 because there can be multiple incarnations of the same label, with
3781 exactly the same name, in any given section and the linker will have
3782 no way to identify the correct one. Instead we just have to hope
3783 that no relaxtion will occur between the local label and the other
3784 symbol in the expression.
3786 Similarly we have to compute differences between symbols in the .eh_frame
3787 section as the linker is not smart enough to apply relocations there
3788 before attempting to process it. */
3789 if ((ssec != absolute_section || asec != absolute_section)
3790 && (fixp->fx_addsy != fixp->fx_subsy)
3791 && strcmp (ssec->name, ".eh_frame") != 0
3792 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3793 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3795 arelent * reloc2 = xmalloc (sizeof * reloc);
3800 reloc2->address = reloc->address;
3801 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3802 BFD_RELOC_MSP430_SYM_DIFF);
3803 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3805 if (ssec == absolute_section)
3806 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3809 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3810 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3813 reloc->addend = fixp->fx_offset;
3814 if (asec == absolute_section)
3816 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3817 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3821 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3822 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3831 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3833 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3834 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3836 switch (fixp->fx_r_type)
3839 md_number_to_chars (fixpos, reloc->addend, 1);
3843 md_number_to_chars (fixpos, reloc->addend, 2);
3847 md_number_to_chars (fixpos, reloc->addend, 3);
3851 md_number_to_chars (fixpos, reloc->addend, 4);
3856 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3867 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3868 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3870 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3871 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3873 md_number_to_chars (fixpos, amount, 2);
3878 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3879 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3880 reloc->addend = fixp->fx_offset;
3882 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3883 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3884 reloc->address = fixp->fx_offset;
3891 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3892 asection * segment_type ATTRIBUTE_UNUSED)
3894 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3896 /* This is a jump -> pcrel mode. Nothing to do much here.
3897 Return value == 2. */
3899 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3901 else if (fragP->fr_symbol)
3903 /* Its got a segment, but its not ours. Even if fr_symbol is in
3904 an absolute segment, we don't know a displacement until we link
3905 object files. So it will always be long. This also applies to
3906 labels in a subsegment of current. Liker may relax it to short
3907 jump later. Return value == 8. */
3909 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3913 /* We know the abs value. may be it is a jump to fixed address.
3914 Impossible in our case, cause all constants already handled. */
3916 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3919 return md_relax_table[fragP->fr_subtype].rlx_length;
3923 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3924 asection * sec ATTRIBUTE_UNUSED,
3930 struct rcodes_s * cc = NULL;
3931 struct hcodes_s * hc = NULL;
3933 switch (fragP->fr_subtype)
3935 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3936 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3937 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3938 /* We do not have to convert anything here.
3939 Just apply a fix. */
3940 rela = BFD_RELOC_MSP430_10_PCREL;
3943 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3944 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3945 /* Convert uncond branch jmp lab -> br lab. */
3946 if (target_is_430x ())
3947 cc = msp430x_rcodes + 7;
3949 cc = msp430_rcodes + 7;
3950 where = fragP->fr_literal + fragP->fr_fix;
3951 bfd_putl16 (cc->lop0, where);
3952 rela = BFD_RELOC_MSP430_RL_PCREL;
3956 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3957 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3959 /* Other simple branches. */
3960 int insn = bfd_getl16 (fragP->fr_opcode);
3963 /* Find actual instruction. */
3964 if (target_is_430x ())
3966 for (i = 0; i < 7 && !cc; i++)
3967 if (msp430x_rcodes[i].sop == insn)
3968 cc = msp430x_rcodes + i;
3972 for (i = 0; i < 7 && !cc; i++)
3973 if (msp430_rcodes[i].sop == insn)
3974 cc = & msp430_rcodes[i];
3977 if (!cc || !cc->name)
3978 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3979 __FUNCTION__, (long) insn);
3980 where = fragP->fr_literal + fragP->fr_fix;
3981 bfd_putl16 (cc->lop0, where);
3982 bfd_putl16 (cc->lop1, where + 2);
3983 rela = BFD_RELOC_MSP430_RL_PCREL;
3988 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3989 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
3990 if (target_is_430x ())
3991 cc = msp430x_rcodes + 6;
3993 cc = msp430_rcodes + 6;
3994 where = fragP->fr_literal + fragP->fr_fix;
3995 bfd_putl16 (cc->lop0, where);
3996 bfd_putl16 (cc->lop1, where + 2);
3997 bfd_putl16 (cc->lop2, where + 4);
3998 rela = BFD_RELOC_MSP430_RL_PCREL;
4002 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4004 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4007 if (target_is_430x ())
4009 for (i = 0; i < 4 && !hc; i++)
4010 if (msp430x_hcodes[i].op1 == insn)
4011 hc = msp430x_hcodes + i;
4015 for (i = 0; i < 4 && !hc; i++)
4016 if (msp430_hcodes[i].op1 == insn)
4017 hc = &msp430_hcodes[i];
4019 if (!hc || !hc->name)
4020 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4021 __FUNCTION__, (long) insn);
4022 rela = BFD_RELOC_MSP430_10_PCREL;
4023 /* Apply a fix for a first label if necessary.
4024 another fix will be applied to the next word of insn anyway. */
4026 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4027 fragP->fr_offset, TRUE, rela);
4033 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4034 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4036 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4039 if (target_is_430x ())
4041 for (i = 0; i < 4 && !hc; i++)
4042 if (msp430x_hcodes[i].op1 == insn)
4043 hc = msp430x_hcodes + i;
4047 for (i = 0; i < 4 && !hc; i++)
4048 if (msp430_hcodes[i].op1 == insn)
4049 hc = & msp430_hcodes[i];
4051 if (!hc || !hc->name)
4052 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4053 __FUNCTION__, (long) insn);
4054 rela = BFD_RELOC_MSP430_RL_PCREL;
4055 where = fragP->fr_literal + fragP->fr_fix;
4056 bfd_putl16 (hc->lop0, where);
4057 bfd_putl16 (hc->lop1, where + 2);
4058 bfd_putl16 (hc->lop2, where + 4);
4064 as_fatal (_("internal inconsistency problem in %s: %lx"),
4065 __FUNCTION__, (long) fragP->fr_subtype);
4069 /* Now apply fix. */
4070 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4071 fragP->fr_offset, TRUE, rela);
4072 /* Just fixed 2 bytes. */
4076 /* Relax fragment. Mostly stolen from hc11 and mcore
4077 which arches I think I know. */
4080 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4081 long stretch ATTRIBUTE_UNUSED)
4086 const relax_typeS *this_type;
4087 const relax_typeS *start_type;
4088 relax_substateT next_state;
4089 relax_substateT this_state;
4090 const relax_typeS *table = md_relax_table;
4092 /* Nothing to be done if the frag has already max size. */
4093 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4094 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4097 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4099 symbolP = fragP->fr_symbol;
4100 if (symbol_resolved_p (symbolP))
4101 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4103 /* We know the offset. calculate a distance. */
4104 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4107 if (!msp430_enable_relax)
4109 /* Relaxation is not enabled. So, make all jump as long ones
4110 by setting 'aim' to quite high value. */
4114 this_state = fragP->fr_subtype;
4115 start_type = this_type = table + this_state;
4119 /* Look backwards. */
4120 for (next_state = this_type->rlx_more; next_state;)
4121 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4125 /* Grow to next state. */
4126 this_state = next_state;
4127 this_type = table + this_state;
4128 next_state = this_type->rlx_more;
4133 /* Look forwards. */
4134 for (next_state = this_type->rlx_more; next_state;)
4135 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4139 /* Grow to next state. */
4140 this_state = next_state;
4141 this_type = table + this_state;
4142 next_state = this_type->rlx_more;
4146 growth = this_type->rlx_length - start_type->rlx_length;
4148 fragP->fr_subtype = this_state;
4152 /* Return FALSE if the fixup in fixp should be left alone and not
4153 adjusted. We return FALSE here so that linker relaxation will
4157 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4159 /* If the symbol is in a non-code section then it should be OK. */
4161 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4167 /* Set the contents of the .MSP430.attributes section. */
4170 msp430_md_end (void)
4172 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4173 target_is_430x () ? 2 : 1);
4175 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4176 large_model ? 2 : 1);
4178 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4179 large_model ? 2 : 1);
4182 /* Returns FALSE if there is a msp430 specific reason why the
4183 subtraction of two same-section symbols cannot be computed by
4187 msp430_allow_local_subtract (expressionS * left,
4188 expressionS * right,
4191 /* If the symbols are not in a code section then they are OK. */
4192 if ((section->flags & SEC_CODE) == 0)
4195 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4198 if (left->X_add_symbol == right->X_add_symbol)
4201 /* We have to assume that there may be instructions between the
4202 two symbols and that relaxation may increase the distance between