1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002-2013 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
25 #define PUSH_1X_WORKAROUND
27 #include "opcode/msp430.h"
28 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
30 #include "elf/msp430.h"
32 /* We will disable polymorphs by default because it is dangerous.
33 The potential problem here is the following: assume we got the
38 jump subroutine ; external symbol
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
51 If the 'subroutine' is within +-1024 bytes range then linker
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60 The workaround is the following:
61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
62 2. Declare global var enable_relax which set to 1 via option -mQ.
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69 int msp430_enable_relax;
70 int msp430_enable_polys;
72 /* Set linkrelax here to avoid fixups in most sections. */
75 /* GCC uses the some condition codes which we'll
76 implement as new polymorph instructions.
78 COND EXPL SHORT JUMP LONG JUMP
79 ===============================================
80 eq == jeq jne +4; br lab
81 ne != jne jeq +4; br lab
83 ltn honours no-overflow flag
84 ltn < jn jn +2; jmp +4; br lab
86 lt < jl jge +4; br lab
87 ltu < jlo lhs +4; br lab
93 ge >= jge jl +4; br lab
94 geu >= jhs jlo +4; br lab
95 ===============================================
97 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
98 beq,bne,blt,bltn,bltu,bge,bgeu
99 'u' means unsigned compares
101 Also, we add 'jump' instruction:
102 jump UNCOND -> jmp br lab
104 They will have fmt == 4, and insn_opnumb == number of instruction. */
109 int index; /* Corresponding insn_opnumb. */
110 int sop; /* Opcode if jump length is short. */
111 long lpos; /* Label position. */
112 long lop0; /* Opcode 1 _word_ (16 bits). */
113 long lop1; /* Opcode second word. */
114 long lop2; /* Opcode third word. */
117 #define MSP430_RLC(n,i,sop,o1) \
118 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
120 static struct rcodes_s msp430_rcodes[] =
122 MSP430_RLC (beq, 0, 0x2400, 0x2000),
123 MSP430_RLC (bne, 1, 0x2000, 0x2400),
124 MSP430_RLC (blt, 2, 0x3800, 0x3400),
125 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
126 MSP430_RLC (bge, 4, 0x3400, 0x3800),
127 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
128 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
129 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
134 #define MSP430_RLC(n,i,sop,o1) \
135 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
137 static struct rcodes_s msp430x_rcodes[] =
139 MSP430_RLC (beq, 0, 0x2400, 0x2000),
140 MSP430_RLC (bne, 1, 0x2000, 0x2400),
141 MSP430_RLC (blt, 2, 0x3800, 0x3400),
142 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
143 MSP430_RLC (bge, 4, 0x3400, 0x3800),
144 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
145 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
146 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
151 /* More difficult than above and they have format 5.
154 =================================================================
155 gt > jeq +2; jge label jeq +6; jl +4; br label
156 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
157 leu <= jeq label; jlo label jeq +2; jhs +4; br label
158 le <= jeq label; jl label jeq +2; jge +4; br label
159 ================================================================= */
164 int index; /* Corresponding insn_opnumb. */
165 int tlab; /* Number of labels in short mode. */
166 int op0; /* Opcode for first word of short jump. */
167 int op1; /* Opcode for second word of short jump. */
168 int lop0; /* Opcodes for long jump mode. */
173 static struct hcodes_s msp430_hcodes[] =
175 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
176 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
177 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
178 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
182 static struct hcodes_s msp430x_hcodes[] =
184 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
185 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
186 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
187 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
191 const char comment_chars[] = ";";
192 const char line_comment_chars[] = "#";
193 const char line_separator_chars[] = "{";
194 const char EXP_CHARS[] = "eE";
195 const char FLT_CHARS[] = "dD";
197 /* Handle long expressions. */
198 extern LITTLENUM_TYPE generic_bignum[];
200 static struct hash_control *msp430_hash;
203 #define STATE_UNCOND_BRANCH 1 /* jump */
204 #define STATE_NOOV_BRANCH 3 /* bltn */
205 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
206 #define STATE_EMUL_BRANCH 4
215 #define STATE_BITS10 1 /* wild guess. short jump */
216 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
217 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
219 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
220 #define RELAX_STATE(s) ((s) & 3)
221 #define RELAX_LEN(s) ((s) >> 2)
222 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
224 relax_typeS md_relax_table[] =
232 /* Unconditional jump. */
234 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
235 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
236 {1, 1, CUBL, 0}, /* state undef */
238 /* Simple branches. */
240 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
241 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
244 /* blt no overflow branch. */
246 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
247 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
250 /* Emulated branches. */
252 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
253 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
258 #define MAX_OP_LEN 256
273 static struct mcu_type_s mcu_types[] =
275 {"msp430afe221", MSP_ISA_430},
276 {"msp430afe222", MSP_ISA_430},
277 {"msp430afe223", MSP_ISA_430},
278 {"msp430afe231", MSP_ISA_430},
279 {"msp430afe232", MSP_ISA_430},
280 {"msp430afe233", MSP_ISA_430},
281 {"msp430afe251", MSP_ISA_430},
282 {"msp430afe252", MSP_ISA_430},
283 {"msp430afe253", MSP_ISA_430},
284 {"msp430c091", MSP_ISA_430},
285 {"msp430c092", MSP_ISA_430},
286 {"msp430c111", MSP_ISA_430},
287 {"msp430c1111", MSP_ISA_430},
288 {"msp430c112", MSP_ISA_430},
289 {"msp430c1121", MSP_ISA_430},
290 {"msp430e112", MSP_ISA_430},
291 {"msp430c1331", MSP_ISA_430},
292 {"msp430c1351", MSP_ISA_430},
293 {"msp430c311s", MSP_ISA_430},
294 {"msp430c312", MSP_ISA_430},
295 {"msp430c313", MSP_ISA_430},
296 {"msp430c314", MSP_ISA_430},
297 {"msp430c315", MSP_ISA_430},
298 {"msp430c323", MSP_ISA_430},
299 {"msp430c325", MSP_ISA_430},
300 {"msp430c336", MSP_ISA_430},
301 {"msp430c337", MSP_ISA_430},
302 {"msp430c412", MSP_ISA_430},
303 {"msp430c413", MSP_ISA_430},
304 {"msp430e313", MSP_ISA_430},
305 {"msp430e315", MSP_ISA_430},
306 {"msp430e325", MSP_ISA_430},
307 {"msp430e337", MSP_ISA_430},
308 {"msp430f110", MSP_ISA_430},
309 {"msp430f1101", MSP_ISA_430},
310 {"msp430f1101a", MSP_ISA_430},
311 {"msp430f1111", MSP_ISA_430},
312 {"msp430f1111a", MSP_ISA_430},
313 {"msp430f112", MSP_ISA_430},
314 {"msp430f1121", MSP_ISA_430},
315 {"msp430f1121a", MSP_ISA_430},
316 {"msp430f1122", MSP_ISA_430},
317 {"msp430f1132", MSP_ISA_430},
318 {"msp430f122", MSP_ISA_430},
319 {"msp430f1222", MSP_ISA_430},
320 {"msp430f123", MSP_ISA_430},
321 {"msp430f1232", MSP_ISA_430},
322 {"msp430f133", MSP_ISA_430},
323 {"msp430f135", MSP_ISA_430},
324 {"msp430f147", MSP_ISA_430},
325 {"msp430f1471", MSP_ISA_430},
326 {"msp430f148", MSP_ISA_430},
327 {"msp430f1481", MSP_ISA_430},
328 {"msp430f149", MSP_ISA_430},
329 {"msp430f1491", MSP_ISA_430},
330 {"msp430f155", MSP_ISA_430},
331 {"msp430f156", MSP_ISA_430},
332 {"msp430f157", MSP_ISA_430},
333 {"msp430f1610", MSP_ISA_430},
334 {"msp430f1611", MSP_ISA_430},
335 {"msp430f1612", MSP_ISA_430},
336 {"msp430f167", MSP_ISA_430},
337 {"msp430f168", MSP_ISA_430},
338 {"msp430f169", MSP_ISA_430},
339 {"msp430f2001", MSP_ISA_430},
340 {"msp430f2002", MSP_ISA_430},
341 {"msp430f2003", MSP_ISA_430},
342 {"msp430f2011", MSP_ISA_430},
343 {"msp430f2012", MSP_ISA_430},
344 {"msp430f2013", MSP_ISA_430},
345 {"msp430f2101", MSP_ISA_430},
346 {"msp430f2111", MSP_ISA_430},
347 {"msp430f2112", MSP_ISA_430},
348 {"msp430f2121", MSP_ISA_430},
349 {"msp430f2122", MSP_ISA_430},
350 {"msp430f2131", MSP_ISA_430},
351 {"msp430f2132", MSP_ISA_430},
352 {"msp430f2232", MSP_ISA_430},
353 {"msp430f2234", MSP_ISA_430},
354 {"msp430f2252", MSP_ISA_430},
355 {"msp430f2254", MSP_ISA_430},
356 {"msp430f2272", MSP_ISA_430},
357 {"msp430f2274", MSP_ISA_430},
358 {"msp430f233", MSP_ISA_430},
359 {"msp430f2330", MSP_ISA_430},
360 {"msp430f235", MSP_ISA_430},
361 {"msp430f2350", MSP_ISA_430},
362 {"msp430f2370", MSP_ISA_430},
363 {"msp430f2410", MSP_ISA_430},
364 {"msp430f247", MSP_ISA_430},
365 {"msp430f2471", MSP_ISA_430},
366 {"msp430f248", MSP_ISA_430},
367 {"msp430f2481", MSP_ISA_430},
368 {"msp430f249", MSP_ISA_430},
369 {"msp430f2491", MSP_ISA_430},
370 {"msp430f412", MSP_ISA_430},
371 {"msp430f413", MSP_ISA_430},
372 {"msp430f4132", MSP_ISA_430},
373 {"msp430f415", MSP_ISA_430},
374 {"msp430f4152", MSP_ISA_430},
375 {"msp430f417", MSP_ISA_430},
376 {"msp430f423", MSP_ISA_430},
377 {"msp430f423a", MSP_ISA_430},
378 {"msp430f425", MSP_ISA_430},
379 {"msp430f4250", MSP_ISA_430},
380 {"msp430f425a", MSP_ISA_430},
381 {"msp430f4260", MSP_ISA_430},
382 {"msp430f427", MSP_ISA_430},
383 {"msp430f4270", MSP_ISA_430},
384 {"msp430f427a", MSP_ISA_430},
385 {"msp430f435", MSP_ISA_430},
386 {"msp430f4351", MSP_ISA_430},
387 {"msp430f436", MSP_ISA_430},
388 {"msp430f4361", MSP_ISA_430},
389 {"msp430f437", MSP_ISA_430},
390 {"msp430f4371", MSP_ISA_430},
391 {"msp430f438", MSP_ISA_430},
392 {"msp430f439", MSP_ISA_430},
393 {"msp430f447", MSP_ISA_430},
394 {"msp430f448", MSP_ISA_430},
395 {"msp430f4481", MSP_ISA_430},
396 {"msp430f449", MSP_ISA_430},
397 {"msp430f4491", MSP_ISA_430},
398 {"msp430f477", MSP_ISA_430},
399 {"msp430f478", MSP_ISA_430},
400 {"msp430f4783", MSP_ISA_430},
401 {"msp430f4784", MSP_ISA_430},
402 {"msp430f479", MSP_ISA_430},
403 {"msp430f4793", MSP_ISA_430},
404 {"msp430f4794", MSP_ISA_430},
405 {"msp430fe423", MSP_ISA_430},
406 {"msp430fe4232", MSP_ISA_430},
407 {"msp430fe423a", MSP_ISA_430},
408 {"msp430fe4242", MSP_ISA_430},
409 {"msp430fe425", MSP_ISA_430},
410 {"msp430fe4252", MSP_ISA_430},
411 {"msp430fe425a", MSP_ISA_430},
412 {"msp430fe427", MSP_ISA_430},
413 {"msp430fe4272", MSP_ISA_430},
414 {"msp430fe427a", MSP_ISA_430},
415 {"msp430fg4250", MSP_ISA_430},
416 {"msp430fg4260", MSP_ISA_430},
417 {"msp430fg4270", MSP_ISA_430},
418 {"msp430fg437", MSP_ISA_430},
419 {"msp430fg438", MSP_ISA_430},
420 {"msp430fg439", MSP_ISA_430},
421 {"msp430fg477", MSP_ISA_430},
422 {"msp430fg478", MSP_ISA_430},
423 {"msp430fg479", MSP_ISA_430},
424 {"msp430fw423", MSP_ISA_430},
425 {"msp430fw425", MSP_ISA_430},
426 {"msp430fw427", MSP_ISA_430},
427 {"msp430fw428", MSP_ISA_430},
428 {"msp430fw429", MSP_ISA_430},
429 {"msp430g2001", MSP_ISA_430},
430 {"msp430g2101", MSP_ISA_430},
431 {"msp430g2102", MSP_ISA_430},
432 {"msp430g2111", MSP_ISA_430},
433 {"msp430g2112", MSP_ISA_430},
434 {"msp430g2113", MSP_ISA_430},
435 {"msp430g2121", MSP_ISA_430},
436 {"msp430g2131", MSP_ISA_430},
437 {"msp430g2132", MSP_ISA_430},
438 {"msp430g2152", MSP_ISA_430},
439 {"msp430g2153", MSP_ISA_430},
440 {"msp430g2201", MSP_ISA_430},
441 {"msp430g2202", MSP_ISA_430},
442 {"msp430g2203", MSP_ISA_430},
443 {"msp430g2210", MSP_ISA_430},
444 {"msp430g2211", MSP_ISA_430},
445 {"msp430g2212", MSP_ISA_430},
446 {"msp430g2213", MSP_ISA_430},
447 {"msp430g2221", MSP_ISA_430},
448 {"msp430g2230", MSP_ISA_430},
449 {"msp430g2231", MSP_ISA_430},
450 {"msp430g2232", MSP_ISA_430},
451 {"msp430g2233", MSP_ISA_430},
452 {"msp430g2252", MSP_ISA_430},
453 {"msp430g2253", MSP_ISA_430},
454 {"msp430g2302", MSP_ISA_430},
455 {"msp430g2303", MSP_ISA_430},
456 {"msp430g2312", MSP_ISA_430},
457 {"msp430g2313", MSP_ISA_430},
458 {"msp430g2332", MSP_ISA_430},
459 {"msp430g2333", MSP_ISA_430},
460 {"msp430g2352", MSP_ISA_430},
461 {"msp430g2353", MSP_ISA_430},
462 {"msp430g2402", MSP_ISA_430},
463 {"msp430g2403", MSP_ISA_430},
464 {"msp430g2412", MSP_ISA_430},
465 {"msp430g2413", MSP_ISA_430},
466 {"msp430g2432", MSP_ISA_430},
467 {"msp430g2433", MSP_ISA_430},
468 {"msp430g2444", MSP_ISA_430},
469 {"msp430g2452", MSP_ISA_430},
470 {"msp430g2453", MSP_ISA_430},
471 {"msp430g2513", MSP_ISA_430},
472 {"msp430g2533", MSP_ISA_430},
473 {"msp430g2544", MSP_ISA_430},
474 {"msp430g2553", MSP_ISA_430},
475 {"msp430g2744", MSP_ISA_430},
476 {"msp430g2755", MSP_ISA_430},
477 {"msp430g2855", MSP_ISA_430},
478 {"msp430g2955", MSP_ISA_430},
479 {"msp430l092", MSP_ISA_430},
480 {"msp430p112", MSP_ISA_430},
481 {"msp430p313", MSP_ISA_430},
482 {"msp430p315", MSP_ISA_430},
483 {"msp430p315s", MSP_ISA_430},
484 {"msp430p325", MSP_ISA_430},
485 {"msp430p337", MSP_ISA_430},
486 {"msp430tch5e", MSP_ISA_430},
488 /* 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 show_mcu_list (FILE * stream)
1160 fprintf (stream, _("Known MCU names:\n"));
1162 for (i = 0; mcu_types[i].name; i++)
1164 fprintf (stream, "%14.14s", mcu_types[i].name);
1166 fprintf (stream, "\n");
1169 fprintf (stream, "\n");
1173 md_parse_option (int c, char * arg)
1181 as_fatal (_("MCU option requires a name\n"));
1183 for (i = 0; mcu_types[i].name; ++i)
1184 if (strcasecmp (mcu_types[i].name, arg) == 0)
1187 if (mcu_types[i].name == NULL)
1189 show_mcu_list (stderr);
1190 as_fatal (_("unknown MCU: %s\n"), arg);
1193 /* Allow switching to the same or a lesser architecture. */
1194 if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
1195 msp430_mcu = mcu_types + i;
1197 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1198 msp430_mcu->name, mcu_types[i].name);
1202 if (strcmp (arg, "430") == 0)
1203 msp430_mcu = & default_mcu;
1204 else if (strcmp (arg, "430x") == 0
1205 || strcmp (arg, "430X") == 0)
1206 msp430_mcu = & msp430x_mcu;
1207 else if (strcasecmp (arg, "430xv2") == 0)
1208 msp430_mcu = & msp430xv2_mcu;
1210 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1215 msp430_enable_relax = 1;
1218 case OPTION_POLYMORPHS:
1219 msp430_enable_polys = 1;
1226 case OPTION_NO_INTR_NOPS:
1227 gen_interrupt_nops = FALSE;
1229 case OPTION_INTR_NOPS:
1230 gen_interrupt_nops = TRUE;
1233 case OPTION_MOVE_DATA:
1242 msp430_section (int arg)
1244 char * saved_ilp = input_line_pointer;
1245 char * name = obj_elf_section_name ();
1247 if (strncmp (name, ".bss", 4) == 0
1248 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1249 (void) symbol_find_or_make ("__crt0_init_bss");
1252 && (strncmp (name, ".data", 5) == 0
1253 || strncmp (name, ".gnu.linkonce.d.", 16) == 0))
1254 (void) symbol_find_or_make ("__crt0_movedata");
1256 input_line_pointer = saved_ilp;
1257 obj_elf_section (arg);
1260 const pseudo_typeS md_pseudo_table[] =
1262 {"arch", msp430_set_arch, OPTION_MMCU},
1263 {"cpu", msp430_set_arch, OPTION_MCPU},
1264 {"profiler", msp430_profiler, 0},
1265 {"section", msp430_section, 0},
1266 {"section.s", msp430_section, 0},
1267 {"sect", msp430_section, 0},
1268 {"sect.s", msp430_section, 0},
1269 {"pushsection", msp430_section, 1},
1273 const char *md_shortopts = "mm:,mP,mQ,ml,mN";
1275 struct option md_longopts[] =
1277 {"mmcu", required_argument, NULL, OPTION_MMCU},
1278 {"mcpu", required_argument, NULL, OPTION_MCPU},
1279 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1280 {"mQ", no_argument, NULL, OPTION_RELAX},
1281 {"ml", no_argument, NULL, OPTION_LARGE},
1282 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1283 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1284 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1285 {NULL, no_argument, NULL, 0}
1288 size_t md_longopts_size = sizeof (md_longopts);
1291 md_show_usage (FILE * stream)
1294 _("MSP430 options:\n"
1295 " -mmcu=<msp430-name> - select microcontroller type\n"
1296 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1298 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1299 " -mP - enable polymorph instructions\n"));
1301 _(" -ml - enable large code model\n"));
1303 _(" -mN - disable generation of NOP after changing interrupts\n"));
1305 _(" -mn - enable generation of NOP after changing interrupts\n"));
1307 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1309 show_mcu_list (stream);
1313 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1319 extract_cmd (char * from, char * to, int limit)
1323 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1325 *(to + size) = *from;
1336 md_atof (int type, char * litP, int * sizeP)
1338 return ieee_md_atof (type, litP, sizeP, FALSE);
1344 struct msp430_opcode_s * opcode;
1345 msp430_hash = hash_new ();
1347 for (opcode = msp430_opcodes; opcode->name; opcode++)
1348 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1350 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1351 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1354 /* Returns the register number equivalent to the string T.
1355 Returns -1 if there is no such register.
1356 Skips a leading 'r' or 'R' character if there is one.
1357 Handles the register aliases PC and SP. */
1360 check_reg (char * t)
1367 if (*t == 'r' || *t == 'R')
1370 if (strncasecmp (t, "pc", 2) == 0)
1373 if (strncasecmp (t, "sp", 2) == 0)
1376 if (strncasecmp (t, "sr", 2) == 0)
1384 if (val < 1 || val > 15)
1391 msp430_srcoperand (struct msp430_operand_s * op,
1395 bfd_boolean allow_20bit_values,
1396 bfd_boolean constants_allowed)
1400 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1407 /* Check if there is:
1408 llo(x) - least significant 16 bits, x &= 0xffff
1409 lhi(x) - x = (x >> 16) & 0xffff,
1410 hlo(x) - x = (x >> 32) & 0xffff,
1411 hhi(x) - x = (x >> 48) & 0xffff
1412 The value _MUST_ be constant expression: #hlo(1231231231). */
1416 if (strncasecmp (h, "#llo(", 5) == 0)
1421 else if (strncasecmp (h, "#lhi(", 5) == 0)
1426 else if (strncasecmp (h, "#hlo(", 5) == 0)
1431 else if (strncasecmp (h, "#hhi(", 5) == 0)
1436 else if (strncasecmp (h, "#lo(", 4) == 0)
1441 else if (strncasecmp (h, "#hi(", 4) == 0)
1447 op->reg = 0; /* Reg PC. */
1449 op->ol = 1; /* Immediate will follow an instruction. */
1450 __tl = h + 1 + rval;
1453 parse_exp (__tl, &(op->exp));
1454 if (op->exp.X_op == O_constant)
1456 int x = op->exp.X_add_number;
1461 op->exp.X_add_number = x;
1463 else if (vshift == 1)
1465 x = (x >> 16) & 0xffff;
1466 op->exp.X_add_number = x;
1468 else if (vshift > 1)
1471 op->exp.X_add_number = -1;
1473 op->exp.X_add_number = 0; /* Nothing left. */
1474 x = op->exp.X_add_number;
1477 if (allow_20bit_values)
1479 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1481 as_bad (_("value 0x%x out of extended range."), x);
1485 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1487 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1491 /* Now check constants. */
1492 /* Substitute register mode with a constant generator if applicable. */
1494 if (!allow_20bit_values)
1495 x = (short) x; /* Extend sign. */
1497 if (! constants_allowed)
1529 #ifdef PUSH_1X_WORKAROUND
1532 /* Remove warning as confusing.
1533 as_warn (_("Hardware push bug workaround")); */
1546 #ifdef PUSH_1X_WORKAROUND
1549 /* Remove warning as confusing.
1550 as_warn (_("Hardware push bug workaround")); */
1562 else if (op->exp.X_op == O_symbol)
1566 else if (op->exp.X_op == O_big)
1571 op->exp.X_op = O_constant;
1572 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1573 x = op->exp.X_add_number;
1578 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1626 /* Redundant (yet) check. */
1627 else if (op->exp.X_op == O_register)
1629 (_("Registers cannot be used within immediate expression [%s]"), l);
1631 as_bad (_("unknown operand %s"), l);
1636 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1641 op->reg = 2; /* reg 2 in absolute addr mode. */
1642 op->am = 1; /* mode As == 01 bin. */
1643 op->ol = 1; /* Immediate value followed by instruction. */
1645 parse_exp (__tl, &(op->exp));
1647 if (op->exp.X_op == O_constant)
1649 int x = op->exp.X_add_number;
1651 if (allow_20bit_values)
1653 if (x > 0xfffff || x < -(0x7ffff))
1655 as_bad (_("value 0x%x out of extended range."), x);
1659 else if (x > 65535 || x < -32768)
1661 as_bad (_("value out of range: 0x%x"), x);
1665 else if (op->exp.X_op == O_symbol)
1669 /* Redundant (yet) check. */
1670 if (op->exp.X_op == O_register)
1672 (_("Registers cannot be used within absolute expression [%s]"), l);
1674 as_bad (_("unknown expression in operand %s"), l);
1680 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1684 char *m = strchr (l, '+');
1688 as_bad (_("unknown addressing mode %s"), l);
1694 if ((op->reg = check_reg (t)) == -1)
1696 as_bad (_("Bad register name %s"), t);
1704 /* PC cannot be used in indirect addressing. */
1705 if (target_is_430xv2 () && op->reg == 0)
1707 as_bad (_("cannot use indirect addressing with the PC"));
1713 /* Check if register indexed X(Rn). */
1716 char *h = strrchr (l, '(');
1717 char *m = strrchr (l, ')');
1726 as_bad (_("')' required"));
1734 /* Extract a register. */
1735 if ((op->reg = check_reg (t + 1)) == -1)
1738 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1745 as_bad (_("r2 should not be used in indexed addressing mode"));
1749 /* Extract constant. */
1753 parse_exp (__tl, &(op->exp));
1754 if (op->exp.X_op == O_constant)
1756 int x = op->exp.X_add_number;
1758 if (allow_20bit_values)
1760 if (x > 0xfffff || x < - (0x7ffff))
1762 as_bad (_("value 0x%x out of extended range."), x);
1766 else if (x > 65535 || x < -32768)
1768 as_bad (_("value out of range: 0x%x"), x);
1780 else if (op->exp.X_op == O_symbol)
1784 /* Redundant (yet) check. */
1785 if (op->exp.X_op == O_register)
1787 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1789 as_bad (_("unknown expression in operand %s"), l);
1797 /* Possibly register mode 'mov r1,r2'. */
1798 if ((op->reg = check_reg (l)) != -1)
1806 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1810 op->reg = 0; /* PC relative... be careful. */
1811 /* An expression starting with a minus sign is a constant, not an address. */
1812 op->am = (*l == '-' ? 3 : 1);
1815 parse_exp (__tl, &(op->exp));
1821 as_bad (_("unknown addressing mode for operand %s"), l);
1827 msp430_dstoperand (struct msp430_operand_s * op,
1830 bfd_boolean allow_20bit_values,
1831 bfd_boolean constants_allowed)
1834 int ret = msp430_srcoperand (op, l, bin, & dummy,
1848 parse_exp (__tl, &(op->exp));
1850 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1852 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1862 ("this addressing mode is not applicable for destination operand"));
1869 /* Attempt to encode a MOVA instruction with the given operands.
1870 Returns the length of the encoded instruction if successful
1871 or 0 upon failure. If the encoding fails, an error message
1872 will be returned if a pointer is provided. */
1875 try_encode_mova (bfd_boolean imm_op,
1877 struct msp430_operand_s * op1,
1878 struct msp430_operand_s * op2,
1879 const char ** error_message_return)
1885 /* Only a restricted subset of the normal MSP430 addressing modes
1886 are supported here, so check for the ones that are allowed. */
1889 if (op1->mode == OP_EXP)
1891 if (op2->mode != OP_REG)
1893 if (error_message_return != NULL)
1894 * error_message_return = _("expected register as second argument of %s");
1900 /* MOVA #imm20, Rdst. */
1901 bin |= 0x80 | op2->reg;
1902 frag = frag_more (4);
1903 where = frag - frag_now->fr_literal;
1904 if (op1->exp.X_op == O_constant)
1906 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1907 bfd_putl16 ((bfd_vma) bin, frag);
1908 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1912 bfd_putl16 ((bfd_vma) bin, frag);
1913 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1914 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1915 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1920 else if (op1->am == 1)
1922 /* MOVA z16(Rsrc), Rdst. */
1923 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1924 frag = frag_more (4);
1925 where = frag - frag_now->fr_literal;
1926 bfd_putl16 ((bfd_vma) bin, frag);
1927 if (op1->exp.X_op == O_constant)
1929 if (op1->exp.X_add_number > 0xffff
1930 || op1->exp.X_add_number < -(0x7fff))
1932 if (error_message_return != NULL)
1933 * error_message_return = _("index value too big for %s");
1936 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1940 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1941 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1943 BFD_RELOC_MSP430X_PCR16 :
1944 BFD_RELOC_MSP430X_ABS16);
1949 if (error_message_return != NULL)
1950 * error_message_return = _("unexpected addressing mode for %s");
1953 else if (op1->am == 0)
1955 /* MOVA Rsrc, ... */
1956 if (op2->mode == OP_REG)
1958 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1959 frag = frag_more (2);
1960 where = frag - frag_now->fr_literal;
1961 bfd_putl16 ((bfd_vma) bin, frag);
1964 else if (op2->am == 1)
1968 /* MOVA Rsrc, &abs20. */
1969 bin |= 0x60 | (op1->reg << 8);
1970 frag = frag_more (4);
1971 where = frag - frag_now->fr_literal;
1972 if (op2->exp.X_op == O_constant)
1974 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1975 bfd_putl16 ((bfd_vma) bin, frag);
1976 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1980 bfd_putl16 ((bfd_vma) bin, frag);
1981 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1982 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1983 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1988 /* MOVA Rsrc, z16(Rdst). */
1989 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1990 frag = frag_more (4);
1991 where = frag - frag_now->fr_literal;
1992 bfd_putl16 ((bfd_vma) bin, frag);
1993 if (op2->exp.X_op == O_constant)
1995 if (op2->exp.X_add_number > 0xffff
1996 || op2->exp.X_add_number < -(0x7fff))
1998 if (error_message_return != NULL)
1999 * error_message_return = _("index value too big for %s");
2002 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2006 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2007 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2009 BFD_RELOC_MSP430X_PCR16 :
2010 BFD_RELOC_MSP430X_ABS16);
2015 if (error_message_return != NULL)
2016 * error_message_return = _("unexpected addressing mode for %s");
2021 /* imm_op == FALSE. */
2023 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2025 /* MOVA &abs20, Rdst. */
2026 if (op2->mode != OP_REG)
2028 if (error_message_return != NULL)
2029 * error_message_return = _("expected register as second argument of %s");
2033 if (op2->reg == 2 || op2->reg == 3)
2035 if (error_message_return != NULL)
2036 * error_message_return = _("constant generator destination register found in %s");
2040 bin |= 0x20 | op2->reg;
2041 frag = frag_more (4);
2042 where = frag - frag_now->fr_literal;
2043 if (op1->exp.X_op == O_constant)
2045 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2046 bfd_putl16 ((bfd_vma) bin, frag);
2047 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2051 bfd_putl16 ((bfd_vma) bin, frag);
2052 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2053 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2054 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2058 else if (op1->mode == OP_REG)
2062 /* MOVA @Rsrc+, 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 if (op1->reg == 2 || op1->reg == 3)
2079 if (error_message_return != NULL)
2080 * error_message_return = _("constant generator source register found in %s");
2084 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2085 frag = frag_more (2);
2086 where = frag - frag_now->fr_literal;
2087 bfd_putl16 ((bfd_vma) bin, frag);
2090 else if (op1->am == 2)
2092 /* MOVA @Rsrc,Rdst */
2093 if (op2->mode != OP_REG)
2095 if (error_message_return != NULL)
2096 * error_message_return = _("expected register as second argument of %s");
2100 if (op2->reg == 2 || op2->reg == 3)
2102 if (error_message_return != NULL)
2103 * error_message_return = _("constant generator destination register found in %s");
2107 if (op1->reg == 2 || op1->reg == 3)
2109 if (error_message_return != NULL)
2110 * error_message_return = _("constant generator source register found in %s");
2114 bin |= (op1->reg << 8) | op2->reg;
2115 frag = frag_more (2);
2116 where = frag - frag_now->fr_literal;
2117 bfd_putl16 ((bfd_vma) bin, frag);
2122 if (error_message_return != NULL)
2123 * error_message_return = _("unexpected addressing mode for %s");
2128 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2130 /* Parse instruction operands.
2131 Return binary opcode. */
2134 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2136 int bin = opcode->bin_opcode; /* Opcode mask. */
2137 int insn_length = 0;
2138 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2141 struct msp430_operand_s op1, op2;
2143 static short ZEROS = 0;
2144 int byte_op, imm_op;
2147 int extended = 0x1800;
2148 bfd_boolean extended_op = FALSE;
2149 bfd_boolean addr_op;
2150 const char * error_message;
2151 static signed int repeat_count = 0;
2152 bfd_boolean fix_emitted;
2154 /* Opcode is the one from opcodes table
2155 line contains something like
2164 bfd_boolean check = FALSE;
2167 switch (TOLOWER (* line))
2170 /* Byte operation. */
2171 bin |= BYTE_OPERATION;
2177 /* "Address" ops work on 20-bit values. */
2179 bin |= BYTE_OPERATION;
2184 /* Word operation - this is the default. */
2192 as_warn (_("no size modifier after period, .w assumed"));
2196 as_bad (_("unrecognised instruction size modifier .%c"),
2208 if (*line && ! ISSPACE (*line))
2210 as_bad (_("junk found after instruction: %s.%s"),
2211 opcode->name, line);
2215 /* Catch the case where the programmer has used a ".a" size modifier on an
2216 instruction that does not support it. Look for an alternative extended
2217 instruction that has the same name without the period. Eg: "add.a"
2218 becomes "adda". Although this not an officially supported way of
2219 specifing instruction aliases other MSP430 assemblers allow it. So we
2220 support it for compatibility purposes. */
2221 if (addr_op && opcode->fmt >= 0)
2223 char * old_name = opcode->name;
2226 sprintf (real_name, "%sa", old_name);
2227 opcode = hash_find (msp430_hash, real_name);
2230 as_bad (_("instruction %s.a does not exist"), old_name);
2233 #if 0 /* Enable for debugging. */
2234 as_warn ("treating %s.a as %s", old_name, real_name);
2237 bin = opcode->bin_opcode;
2240 if (opcode->fmt != -1
2241 && opcode->insn_opnumb
2242 && (!*line || *line == '\n'))
2244 as_bad (_("instruction %s requires %d operand(s)"),
2245 opcode->name, opcode->insn_opnumb);
2249 memset (l1, 0, sizeof (l1));
2250 memset (l2, 0, sizeof (l2));
2251 memset (&op1, 0, sizeof (op1));
2252 memset (&op2, 0, sizeof (op2));
2256 if ((fmt = opcode->fmt) < 0)
2258 if (! target_is_430x ())
2260 as_bad (_("instruction %s requires MSP430X mcu"),
2271 /* If requested set the extended instruction repeat count. */
2274 if (repeat_count > 0)
2275 extended |= (repeat_count - 1);
2277 extended |= (1 << 7) | (- repeat_count);
2280 as_bad (_("unable to repeat %s insn"), opcode->name);
2287 case 0: /* Emulated. */
2288 switch (opcode->insn_opnumb)
2291 /* Set/clear bits instructions. */
2295 extended |= BYTE_OPERATION;
2297 /* Emit the extension word. */
2299 frag = frag_more (insn_length);
2300 bfd_putl16 (extended, frag);
2304 frag = frag_more (insn_length);
2305 bfd_putl16 ((bfd_vma) bin, frag);
2307 if (gen_interrupt_nops
2308 && (is_opcode ("eint") || is_opcode ("dint")))
2310 /* Emit a NOP following interrupt enable/disable.
2311 See 1.3.4.1 of the MSP430x5xx User Guide. */
2313 frag = frag_more (2);
2314 as_warn (_("a NOP instruction has been inserted after %s"),
2316 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2318 dwarf2_emit_insn (insn_length);
2322 /* Something which works with destination operand. */
2323 line = extract_operand (line, l1, sizeof (l1));
2324 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2328 /* Compute the entire instruction length, in bytes. */
2329 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2330 frag = frag_more (insn_length);
2331 where = frag - frag_now->fr_literal;
2336 extended |= BYTE_OPERATION;
2338 if (op1.ol != 0 && ((extended & 0xf) != 0))
2340 as_bad (_("repeat instruction used with non-register mode instruction"));
2344 if (op1.mode == OP_EXP)
2346 if (op1.exp.X_op == O_constant)
2347 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2349 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2350 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2351 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2353 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2354 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2357 /* Emit the extension word. */
2358 bfd_putl16 (extended, frag);
2363 bin |= (op1.reg | (op1.am << 7));
2364 bfd_putl16 ((bfd_vma) bin, frag);
2368 if (op1.mode == OP_EXP)
2370 if (op1.exp.X_op == O_constant)
2372 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2376 bfd_putl16 ((bfd_vma) ZEROS, frag);
2381 fix_new_exp (frag_now, where, 2,
2382 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2384 fix_new_exp (frag_now, where, 2,
2385 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2390 if (gen_interrupt_nops
2391 && is_opcode ("clr")
2392 && bin == 0x4302 /* CLR R2*/)
2394 /* Emit a NOP following interrupt enable/disable.
2395 See 1.3.4.1 of the MSP430x5xx User Guide. */
2397 frag = frag_more (2);
2398 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2399 as_warn (_("a NOP instruction has been inserted after %s"),
2403 dwarf2_emit_insn (insn_length);
2407 /* Shift instruction. */
2408 line = extract_operand (line, l1, sizeof (l1));
2409 strncpy (l2, l1, sizeof (l2));
2410 l2[sizeof (l2) - 1] = '\0';
2411 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2412 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2415 break; /* An error occurred. All warnings were done before. */
2417 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2418 frag = frag_more (insn_length);
2419 where = frag - frag_now->fr_literal;
2421 if (target_is_430xv2 ()
2422 && op1.mode == OP_REG
2424 && (is_opcode ("rlax")
2425 || is_opcode ("rlcx")
2426 || is_opcode ("rla")
2427 || is_opcode ("rlc")))
2429 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2436 extended |= BYTE_OPERATION;
2438 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2440 as_bad (_("repeat instruction used with non-register mode instruction"));
2444 if (op1.mode == OP_EXP)
2446 if (op1.exp.X_op == O_constant)
2447 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2449 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2450 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2451 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2453 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2454 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2457 if (op2.mode == OP_EXP)
2459 if (op2.exp.X_op == O_constant)
2460 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2462 else if (op1.mode == OP_EXP)
2463 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2464 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2465 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2467 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2468 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2469 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2472 /* Emit the extension word. */
2473 bfd_putl16 (extended, frag);
2478 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2479 bfd_putl16 ((bfd_vma) bin, frag);
2483 if (op1.mode == OP_EXP)
2485 if (op1.exp.X_op == O_constant)
2487 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2491 bfd_putl16 ((bfd_vma) ZEROS, frag);
2495 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2496 fix_new_exp (frag_now, where, 2,
2497 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2499 fix_new_exp (frag_now, where, 2,
2500 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2507 if (op2.mode == OP_EXP)
2509 if (op2.exp.X_op == O_constant)
2511 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2515 bfd_putl16 ((bfd_vma) ZEROS, frag);
2519 if (op2.reg) /* Not PC relative. */
2520 fix_new_exp (frag_now, where, 2,
2521 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2523 fix_new_exp (frag_now, where, 2,
2524 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2529 dwarf2_emit_insn (insn_length);
2533 /* Branch instruction => mov dst, r0. */
2536 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2540 line = extract_operand (line, l1, sizeof (l1));
2541 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2547 bin |= ((op1.reg << 8) | (op1.am << 4));
2548 op_length = 2 + 2 * op1.ol;
2549 frag = frag_more (op_length);
2550 where = frag - frag_now->fr_literal;
2551 bfd_putl16 ((bfd_vma) bin, frag);
2553 if (op1.mode == OP_EXP)
2555 if (op1.exp.X_op == O_constant)
2557 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2563 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2565 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2566 fix_new_exp (frag_now, where, 2,
2567 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2569 fix_new_exp (frag_now, where, 2,
2570 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2574 dwarf2_emit_insn (insn_length + op_length);
2578 /* CALLA instructions. */
2579 fix_emitted = FALSE;
2581 line = extract_operand (line, l1, sizeof (l1));
2584 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2585 extended_op, FALSE);
2591 op_length = 2 + 2 * op1.ol;
2592 frag = frag_more (op_length);
2593 where = frag - frag_now->fr_literal;
2601 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2602 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2605 else if (op1.am == 1)
2611 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2612 BFD_RELOC_MSP430X_PCR20_CALL);
2616 bin |= 0x50 | op1.reg;
2618 else if (op1.am == 0)
2619 bin |= 0x40 | op1.reg;
2621 else if (op1.am == 1)
2625 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2626 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2629 else if (op1.am == 2)
2630 bin |= 0x60 | op1.reg;
2631 else if (op1.am == 3)
2632 bin |= 0x70 | op1.reg;
2634 bfd_putl16 ((bfd_vma) bin, frag);
2636 if (op1.mode == OP_EXP)
2640 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2644 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2647 fix_new_exp (frag_now, where + 2, 2,
2648 &(op1.exp), FALSE, BFD_RELOC_16);
2651 dwarf2_emit_insn (insn_length + op_length);
2659 /* [POP|PUSH]M[.A] #N, Rd */
2660 line = extract_operand (line, l1, sizeof (l1));
2661 line = extract_operand (line, l2, sizeof (l2));
2665 as_bad (_("expected #n as first argument of %s"), opcode->name);
2668 parse_exp (l1 + 1, &(op1.exp));
2669 if (op1.exp.X_op != O_constant)
2671 as_bad (_("expected constant expression for first argument of %s"),
2676 if ((reg = check_reg (l2)) == -1)
2678 as_bad (_("expected register as second argument of %s"),
2684 frag = frag_more (op_length);
2685 where = frag - frag_now->fr_literal;
2686 bin = opcode->bin_opcode;
2689 n = op1.exp.X_add_number;
2690 bin |= (n - 1) << 4;
2691 if (is_opcode ("pushm"))
2695 if (reg - n + 1 < 0)
2697 as_bad (_("Too many registers popped"));
2701 /* CPU21 parts cannot use POPM to restore the SR register. */
2702 if (target_is_430xv2 ()
2703 && (reg - n + 1 < 3)
2705 && is_opcode ("popm"))
2707 as_bad (_("Cannot use POPM to restore the SR register"));
2711 bin |= (reg - n + 1);
2714 bfd_putl16 ((bfd_vma) bin, frag);
2715 dwarf2_emit_insn (op_length);
2724 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2725 if (extended & 0xff)
2727 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2731 line = extract_operand (line, l1, sizeof (l1));
2732 line = extract_operand (line, l2, sizeof (l2));
2736 as_bad (_("expected #n as first argument of %s"), opcode->name);
2739 parse_exp (l1 + 1, &(op1.exp));
2740 if (op1.exp.X_op != O_constant)
2742 as_bad (_("expected constant expression for first argument of %s"),
2746 n = op1.exp.X_add_number;
2749 as_bad (_("expected first argument of %s to be in the range 1-4"),
2754 if ((reg = check_reg (l2)) == -1)
2756 as_bad (_("expected register as second argument of %s"),
2761 if (target_is_430xv2 () && reg == 0)
2763 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2768 frag = frag_more (op_length);
2769 where = frag - frag_now->fr_literal;
2771 bin = opcode->bin_opcode;
2774 bin |= (n - 1) << 10;
2777 bfd_putl16 ((bfd_vma) bin, frag);
2778 dwarf2_emit_insn (op_length);
2786 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2787 if (extended & 0xff)
2789 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2793 line = extract_operand (line, l1, sizeof (l1));
2794 if ((reg = check_reg (l1)) == -1)
2796 as_bad (_("expected register as argument of %s"),
2801 if (target_is_430xv2 () && reg == 0)
2803 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2809 /* Tricky - there is no single instruction that will do this.
2810 Encode as: RRA.B rN { BIC.B #0x80, rN */
2812 frag = frag_more (op_length);
2813 where = frag - frag_now->fr_literal;
2815 bfd_putl16 ((bfd_vma) bin, frag);
2816 dwarf2_emit_insn (2);
2818 bfd_putl16 ((bfd_vma) bin, frag + 2);
2820 bfd_putl16 ((bfd_vma) bin, frag + 4);
2821 dwarf2_emit_insn (4);
2825 /* Encode as RRUM[.A] rN. */
2826 bin = opcode->bin_opcode;
2831 frag = frag_more (op_length);
2832 where = frag - frag_now->fr_literal;
2833 bfd_putl16 ((bfd_vma) bin, frag);
2834 dwarf2_emit_insn (op_length);
2841 bfd_boolean need_reloc = FALSE;
2845 /* ADDA, CMPA and SUBA address instructions. */
2846 if (extended & 0xff)
2848 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2852 line = extract_operand (line, l1, sizeof (l1));
2853 line = extract_operand (line, l2, sizeof (l2));
2855 bin = opcode->bin_opcode;
2859 parse_exp (l1 + 1, &(op1.exp));
2861 if (op1.exp.X_op == O_constant)
2863 n = op1.exp.X_add_number;
2864 if (n > 0xfffff || n < - (0x7ffff))
2866 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2871 bin |= ((n >> 16) & 0xf) << 8;
2883 if ((n = check_reg (l1)) == -1)
2885 as_bad (_("expected register name or constant as first argument of %s"),
2890 bin |= (n << 8) | (1 << 6);
2894 if ((reg = check_reg (l2)) == -1)
2896 as_bad (_("expected register as second argument of %s"),
2901 frag = frag_more (op_length);
2902 where = frag - frag_now->fr_literal;
2905 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2906 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2908 bfd_putl16 ((bfd_vma) bin, frag);
2910 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2911 dwarf2_emit_insn (op_length);
2915 case 9: /* MOVA, BRA, RETA. */
2917 bin = opcode->bin_opcode;
2919 if (is_opcode ("reta"))
2921 /* The RETA instruction does not take any arguments.
2922 The implicit first argument is @SP+.
2923 The implicit second argument is PC. */
2933 line = extract_operand (line, l1, sizeof (l1));
2934 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2935 &imm_op, extended_op, FALSE);
2937 if (is_opcode ("bra"))
2939 /* This is the BRA synthetic instruction.
2940 The second argument is always PC. */
2946 line = extract_operand (line, l2, sizeof (l2));
2947 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2952 break; /* Error occurred. All warnings were done before. */
2955 /* Only a restricted subset of the normal MSP430 addressing modes
2956 are supported here, so check for the ones that are allowed. */
2957 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2958 & error_message)) == 0)
2960 as_bad (error_message, opcode->name);
2963 dwarf2_emit_insn (op_length);
2967 line = extract_operand (line, l1, sizeof l1);
2968 /* The RPT instruction only accepted immediates and registers. */
2971 parse_exp (l1 + 1, &(op1.exp));
2972 if (op1.exp.X_op != O_constant)
2974 as_bad (_("expected constant value as argument to RPT"));
2977 if (op1.exp.X_add_number < 1
2978 || op1.exp.X_add_number > (1 << 4))
2980 as_bad (_("expected constant in the range 2..16"));
2984 /* We silently accept and ignore a repeat count of 1. */
2985 if (op1.exp.X_add_number > 1)
2986 repeat_count = op1.exp.X_add_number;
2992 if ((reg = check_reg (l1)) != -1)
2995 as_warn (_("PC used as an argument to RPT"));
2997 repeat_count = - reg;
3001 as_bad (_("expected constant or register name as argument to RPT insn"));
3008 as_bad (_("Illegal emulated instruction "));
3013 case 1: /* Format 1, double operand. */
3014 line = extract_operand (line, l1, sizeof (l1));
3015 line = extract_operand (line, l2, sizeof (l2));
3016 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3017 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3020 break; /* Error occurred. All warnings were done before. */
3023 && is_opcode ("movx")
3025 && msp430_enable_relax)
3027 /* This is the MOVX.A instruction. See if we can convert
3028 it into the MOVA instruction instead. This saves 2 bytes. */
3029 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3032 dwarf2_emit_insn (op_length);
3037 /* Compute the entire length of the instruction in bytes. */
3039 (extended_op ? 2 : 0) /* The extension word. */
3040 + 2 /* The opcode */
3041 + (2 * op1.ol) /* The first operand. */
3042 + (2 * op2.ol); /* The second operand. */
3044 frag = frag_more (insn_length);
3045 where = frag - frag_now->fr_literal;
3050 extended |= BYTE_OPERATION;
3052 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3054 as_bad (_("repeat instruction used with non-register mode instruction"));
3058 /* If necessary, emit a reloc to update the extension word. */
3059 if (op1.mode == OP_EXP)
3061 if (op1.exp.X_op == O_constant)
3062 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3064 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3065 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3066 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3068 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3069 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3072 if (op2.mode == OP_EXP)
3074 if (op2.exp.X_op == O_constant)
3075 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3077 else if (op1.mode == OP_EXP)
3078 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3079 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3080 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3083 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3084 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3085 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3088 /* Emit the extension word. */
3089 bfd_putl16 (extended, frag);
3094 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3095 bfd_putl16 ((bfd_vma) bin, frag);
3099 if (op1.mode == OP_EXP)
3101 if (op1.exp.X_op == O_constant)
3103 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3107 bfd_putl16 ((bfd_vma) ZEROS, frag);
3111 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3112 fix_new_exp (frag_now, where, 2,
3113 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3115 fix_new_exp (frag_now, where, 2,
3116 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3124 if (op2.mode == OP_EXP)
3126 if (op2.exp.X_op == O_constant)
3128 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3132 bfd_putl16 ((bfd_vma) ZEROS, frag);
3136 if (op2.reg) /* Not PC relative. */
3137 fix_new_exp (frag_now, where, 2,
3138 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3140 fix_new_exp (frag_now, where, 2,
3141 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3146 if (gen_interrupt_nops
3147 && ( (is_opcode ("bic") && bin == 0xc232)
3148 || (is_opcode ("bis") && bin == 0xd232)
3149 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
3151 /* Emit a NOP following interrupt enable/disable.
3152 See 1.3.4.1 of the MSP430x5xx User Guide. */
3154 frag = frag_more (2);
3155 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3156 as_warn (_("a NOP instruction has been inserted after %s"),
3160 dwarf2_emit_insn (insn_length);
3163 case 2: /* Single-operand mostly instr. */
3164 if (opcode->insn_opnumb == 0)
3166 /* reti instruction. */
3168 frag = frag_more (2);
3169 bfd_putl16 ((bfd_vma) bin, frag);
3170 dwarf2_emit_insn (insn_length);
3174 line = extract_operand (line, l1, sizeof (l1));
3175 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3176 &imm_op, extended_op, TRUE);
3178 break; /* Error in operand. */
3180 if (target_is_430xv2 ()
3181 && op1.mode == OP_REG
3183 && (is_opcode ("rrax")
3184 || is_opcode ("rrcx")
3185 || is_opcode ("rra")
3186 || is_opcode ("rrc")))
3188 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3192 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3193 frag = frag_more (insn_length);
3194 where = frag - frag_now->fr_literal;
3198 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3200 /* These two instructions use a special
3201 encoding of the A/L and B/W bits. */
3202 bin &= ~ BYTE_OPERATION;
3206 as_bad (_("%s instruction does not accept a .b suffix"),
3211 extended |= BYTE_OPERATION;
3214 extended |= BYTE_OPERATION;
3216 if (op1.ol != 0 && ((extended & 0xf) != 0))
3218 as_bad (_("repeat instruction used with non-register mode instruction"));
3222 if (op1.mode == OP_EXP)
3224 if (op1.exp.X_op == O_constant)
3225 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3227 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3228 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3229 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3231 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3232 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3235 /* Emit the extension word. */
3236 bfd_putl16 (extended, frag);
3241 bin |= op1.reg | (op1.am << 4);
3242 bfd_putl16 ((bfd_vma) bin, frag);
3246 if (op1.mode == OP_EXP)
3248 if (op1.exp.X_op == O_constant)
3250 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3254 bfd_putl16 ((bfd_vma) ZEROS, frag);
3258 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3259 fix_new_exp (frag_now, where, 2,
3260 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3262 fix_new_exp (frag_now, where, 2,
3263 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3268 dwarf2_emit_insn (insn_length);
3271 case 3: /* Conditional jumps instructions. */
3272 line = extract_operand (line, l1, sizeof (l1));
3273 /* l1 is a label. */
3282 parse_exp (m, &exp);
3284 /* In order to handle something like:
3288 jz 4 ; skip next 4 bytes
3291 nop ; will jump here if r5 positive or zero
3293 jCOND -n ;assumes jump n bytes backward:
3303 jCOND $n ; jump from PC in either direction. */
3305 if (exp.X_op == O_constant)
3307 int x = exp.X_add_number;
3311 as_warn (_("Even number required. Rounded to %d"), x + 1);
3315 if ((*l1 == '$' && x > 0) || x < 0)
3320 if (x > 512 || x < -511)
3322 as_bad (_("Wrong displacement %d"), x << 1);
3327 frag = frag_more (2); /* Instr size is 1 word. */
3330 bfd_putl16 ((bfd_vma) bin, frag);
3332 else if (exp.X_op == O_symbol && *l1 != '$')
3335 frag = frag_more (2); /* Instr size is 1 word. */
3336 where = frag - frag_now->fr_literal;
3337 fix_new_exp (frag_now, where, 2,
3338 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3340 bfd_putl16 ((bfd_vma) bin, frag);
3342 else if (*l1 == '$')
3344 as_bad (_("instruction requires label sans '$'"));
3348 ("instruction requires label or value in range -511:512"));
3349 dwarf2_emit_insn (insn_length);
3354 as_bad (_("instruction requires label"));
3359 case 4: /* Extended jumps. */
3360 if (!msp430_enable_polys)
3362 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3366 line = extract_operand (line, l1, sizeof (l1));
3372 /* Ignore absolute addressing. make it PC relative anyway. */
3373 if (*m == '#' || *m == '$')
3376 parse_exp (m, & exp);
3377 if (exp.X_op == O_symbol)
3379 /* Relaxation required. */
3380 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3382 if (target_is_430x ())
3383 rc = msp430x_rcodes[opcode->insn_opnumb];
3385 /* The parameter to dwarf2_emit_insn is actually the offset to
3386 the start of the insn from the fix piece of instruction that
3387 was emitted. Since next fragments may have variable size we
3388 tie debug info to the beginning of the instruction. */
3390 frag = frag_more (8);
3391 dwarf2_emit_insn (0);
3392 bfd_putl16 ((bfd_vma) rc.sop, frag);
3393 frag = frag_variant (rs_machine_dependent, 8, 2,
3395 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3397 0, /* Offset is zero if jump dist less than 1K. */
3403 as_bad (_("instruction requires label"));
3406 case 5: /* Emulated extended branches. */
3407 if (!msp430_enable_polys)
3409 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3412 line = extract_operand (line, l1, sizeof (l1));
3418 /* Ignore absolute addressing. make it PC relative anyway. */
3419 if (*m == '#' || *m == '$')
3422 parse_exp (m, & exp);
3423 if (exp.X_op == O_symbol)
3425 /* Relaxation required. */
3426 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3428 if (target_is_430x ())
3429 hc = msp430x_hcodes[opcode->insn_opnumb];
3432 frag = frag_more (8);
3433 dwarf2_emit_insn (0);
3434 bfd_putl16 ((bfd_vma) hc.op0, frag);
3435 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3437 frag = frag_variant (rs_machine_dependent, 8, 2,
3438 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3440 0, /* Offset is zero if jump dist less than 1K. */
3446 as_bad (_("instruction requires label"));
3450 as_bad (_("Illegal instruction or not implemented opcode."));
3453 input_line_pointer = line;
3458 md_assemble (char * str)
3460 struct msp430_opcode_s * opcode;
3464 str = skip_space (str); /* Skip leading spaces. */
3465 str = extract_cmd (str, cmd, sizeof (cmd));
3467 while (cmd[i] && i < sizeof (cmd))
3469 char a = TOLOWER (cmd[i]);
3476 as_bad (_("can't find opcode "));
3480 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3484 as_bad (_("unknown opcode `%s'"), cmd);
3489 char *__t = input_line_pointer;
3491 msp430_operands (opcode, str);
3492 input_line_pointer = __t;
3496 /* GAS will call this function for each section at the end of the assembly,
3497 to permit the CPU backend to adjust the alignment of a section. */
3500 md_section_align (asection * seg, valueT addr)
3502 int align = bfd_get_section_alignment (stdoutput, seg);
3504 return ((addr + (1 << align) - 1) & (-1 << align));
3507 /* If you define this macro, it should return the offset between the
3508 address of a PC relative fixup and the position from which the PC
3509 relative adjustment should be made. On many processors, the base
3510 of a PC relative instruction is the next instruction, so this
3511 macro would return the length of an instruction. */
3514 md_pcrel_from_section (fixS * fixp, segT sec)
3516 if (fixp->fx_addsy != (symbolS *) NULL
3517 && (!S_IS_DEFINED (fixp->fx_addsy)
3518 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3521 return fixp->fx_frag->fr_address + fixp->fx_where;
3524 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3525 Now it handles the situation when relocations
3526 have to be passed to linker. */
3528 msp430_force_relocation_local (fixS *fixp)
3530 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3534 if (msp430_enable_polys
3535 && !msp430_enable_relax)
3538 return (!fixp->fx_pcrel
3539 || generic_force_reloc (fixp));
3543 /* GAS will call this for each fixup. It should store the correct
3544 value in the object file. */
3546 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3548 unsigned char * where;
3552 if (fixp->fx_addsy == (symbolS *) NULL)
3557 else if (fixp->fx_pcrel)
3559 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3561 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3563 /* FIXME: We can appear here only in case if we perform a pc
3564 relative jump to the label which is i) global, ii) locally
3565 defined or this is a jump to an absolute symbol.
3566 If this is an absolute symbol -- everything is OK.
3567 If this is a global label, we've got a symbol value defined
3569 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3570 from this section start
3571 2. *valuep will contain the real offset from jump insn to the
3573 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3574 will be incorrect. Therefore remove s_get_value. */
3575 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3583 value = fixp->fx_offset;
3585 if (fixp->fx_subsy != (symbolS *) NULL)
3587 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3589 value -= S_GET_VALUE (fixp->fx_subsy);
3595 fixp->fx_no_overflow = 1;
3597 /* If polymorphs are enabled and relax disabled.
3598 do not kill any relocs and pass them to linker. */
3599 if (msp430_enable_polys
3600 && !msp430_enable_relax)
3602 if (!fixp->fx_addsy || (fixp->fx_addsy
3603 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
3604 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3611 /* Fetch the instruction, insert the fully resolved operand
3612 value, and stuff the instruction back again. */
3613 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3615 insn = bfd_getl16 (where);
3617 switch (fixp->fx_r_type)
3619 case BFD_RELOC_MSP430_10_PCREL:
3621 as_bad_where (fixp->fx_file, fixp->fx_line,
3622 _("odd address operand: %ld"), value);
3624 /* Jumps are in words. */
3626 --value; /* Correct PC. */
3628 if (value < -512 || value > 511)
3629 as_bad_where (fixp->fx_file, fixp->fx_line,
3630 _("operand out of range: %ld"), value);
3632 value &= 0x3ff; /* get rid of extended sign */
3633 bfd_putl16 ((bfd_vma) (value | insn), where);
3636 case BFD_RELOC_MSP430X_PCR16:
3637 case BFD_RELOC_MSP430_RL_PCREL:
3638 case BFD_RELOC_MSP430_16_PCREL:
3640 as_bad_where (fixp->fx_file, fixp->fx_line,
3641 _("odd address operand: %ld"), value);
3644 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3645 /* Nothing to be corrected here. */
3646 if (value < -32768 || value > 65536)
3647 as_bad_where (fixp->fx_file, fixp->fx_line,
3648 _("operand out of range: %ld"), value);
3651 case BFD_RELOC_MSP430X_ABS16:
3652 case BFD_RELOC_MSP430_16:
3654 case BFD_RELOC_MSP430_16_BYTE:
3655 value &= 0xffff; /* Get rid of extended sign. */
3656 bfd_putl16 ((bfd_vma) value, where);
3660 bfd_putl16 ((bfd_vma) value, where);
3663 case BFD_RELOC_MSP430_ABS8:
3665 bfd_put_8 (NULL, (bfd_vma) value, where);
3668 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3669 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3670 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3672 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3675 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3676 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3678 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3681 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3682 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3684 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3687 case BFD_RELOC_MSP430X_PCR20_CALL:
3688 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3690 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3693 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3694 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3695 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3697 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3700 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3701 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3703 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3706 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3707 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3709 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3713 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3714 fixp->fx_line, fixp->fx_r_type);
3720 fixp->fx_addnumber = value;
3725 S_IS_GAS_LOCAL (symbolS * s)
3732 name = S_GET_NAME (s);
3733 len = strlen (name) - 1;
3735 return name[len] == 1 || name[len] == 2;
3738 /* GAS will call this to generate a reloc, passing the resulting reloc
3739 to `bfd_install_relocation'. This currently works poorly, as
3740 `bfd_install_relocation' often does the wrong thing, and instances of
3741 `tc_gen_reloc' have been written to work around the problems, which
3742 in turns makes it difficult to fix `bfd_install_relocation'. */
3744 /* If while processing a fixup, a reloc really needs to be created
3745 then it is done here. */
3748 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
3750 static arelent * no_relocs = NULL;
3751 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3754 reloc = xmalloc (sizeof (arelent));
3755 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3756 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3758 if (reloc->howto == (reloc_howto_type *) NULL)
3760 as_bad_where (fixp->fx_file, fixp->fx_line,
3761 _("reloc %d not supported by object file format"),
3762 (int) fixp->fx_r_type);
3771 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3773 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3774 fixp->fx_subsy = NULL;
3777 if (fixp->fx_addsy && fixp->fx_subsy)
3779 asection *asec, *ssec;
3781 asec = S_GET_SEGMENT (fixp->fx_addsy);
3782 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3784 /* If we have a difference between two different, non-absolute symbols
3785 we must generate two relocs (one for each symbol) and allow the
3786 linker to resolve them - relaxation may change the distances between
3787 symbols, even local symbols defined in the same section.
3789 Unfortunately we cannot do this with assembler generated local labels
3790 because there can be multiple incarnations of the same label, with
3791 exactly the same name, in any given section and the linker will have
3792 no way to identify the correct one. Instead we just have to hope
3793 that no relaxtion will occur between the local label and the other
3794 symbol in the expression.
3796 Similarly we have to compute differences between symbols in the .eh_frame
3797 section as the linker is not smart enough to apply relocations there
3798 before attempting to process it. */
3799 if ((ssec != absolute_section || asec != absolute_section)
3800 && (fixp->fx_addsy != fixp->fx_subsy)
3801 && strcmp (ssec->name, ".eh_frame") != 0
3802 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3803 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3805 arelent * reloc2 = xmalloc (sizeof * reloc);
3810 reloc2->address = reloc->address;
3811 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3812 BFD_RELOC_MSP430_SYM_DIFF);
3813 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3815 if (ssec == absolute_section)
3816 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3819 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3820 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3823 reloc->addend = fixp->fx_offset;
3824 if (asec == absolute_section)
3826 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3827 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3831 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3832 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3841 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3843 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3844 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3846 switch (fixp->fx_r_type)
3849 md_number_to_chars (fixpos, reloc->addend, 1);
3853 md_number_to_chars (fixpos, reloc->addend, 2);
3857 md_number_to_chars (fixpos, reloc->addend, 3);
3861 md_number_to_chars (fixpos, reloc->addend, 4);
3866 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3877 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3878 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3880 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3881 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3883 md_number_to_chars (fixpos, amount, 2);
3888 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3889 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3890 reloc->addend = fixp->fx_offset;
3892 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3893 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3894 reloc->address = fixp->fx_offset;
3901 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3902 asection * segment_type ATTRIBUTE_UNUSED)
3904 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3906 /* This is a jump -> pcrel mode. Nothing to do much here.
3907 Return value == 2. */
3909 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3911 else if (fragP->fr_symbol)
3913 /* Its got a segment, but its not ours. Even if fr_symbol is in
3914 an absolute segment, we don't know a displacement until we link
3915 object files. So it will always be long. This also applies to
3916 labels in a subsegment of current. Liker may relax it to short
3917 jump later. Return value == 8. */
3919 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3923 /* We know the abs value. may be it is a jump to fixed address.
3924 Impossible in our case, cause all constants already handled. */
3926 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3929 return md_relax_table[fragP->fr_subtype].rlx_length;
3933 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3934 asection * sec ATTRIBUTE_UNUSED,
3940 struct rcodes_s * cc = NULL;
3941 struct hcodes_s * hc = NULL;
3943 switch (fragP->fr_subtype)
3945 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3946 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3947 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3948 /* We do not have to convert anything here.
3949 Just apply a fix. */
3950 rela = BFD_RELOC_MSP430_10_PCREL;
3953 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3954 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3955 /* Convert uncond branch jmp lab -> br lab. */
3956 if (target_is_430x ())
3957 cc = msp430x_rcodes + 7;
3959 cc = msp430_rcodes + 7;
3960 where = fragP->fr_literal + fragP->fr_fix;
3961 bfd_putl16 (cc->lop0, where);
3962 rela = BFD_RELOC_MSP430_RL_PCREL;
3966 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3967 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3969 /* Other simple branches. */
3970 int insn = bfd_getl16 (fragP->fr_opcode);
3973 /* Find actual instruction. */
3974 if (target_is_430x ())
3976 for (i = 0; i < 7 && !cc; i++)
3977 if (msp430x_rcodes[i].sop == insn)
3978 cc = msp430x_rcodes + i;
3982 for (i = 0; i < 7 && !cc; i++)
3983 if (msp430_rcodes[i].sop == insn)
3984 cc = & msp430_rcodes[i];
3987 if (!cc || !cc->name)
3988 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3989 __FUNCTION__, (long) insn);
3990 where = fragP->fr_literal + fragP->fr_fix;
3991 bfd_putl16 (cc->lop0, where);
3992 bfd_putl16 (cc->lop1, where + 2);
3993 rela = BFD_RELOC_MSP430_RL_PCREL;
3998 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3999 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
4000 if (target_is_430x ())
4001 cc = msp430x_rcodes + 6;
4003 cc = msp430_rcodes + 6;
4004 where = fragP->fr_literal + fragP->fr_fix;
4005 bfd_putl16 (cc->lop0, where);
4006 bfd_putl16 (cc->lop1, where + 2);
4007 bfd_putl16 (cc->lop2, where + 4);
4008 rela = BFD_RELOC_MSP430_RL_PCREL;
4012 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4014 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4017 if (target_is_430x ())
4019 for (i = 0; i < 4 && !hc; i++)
4020 if (msp430x_hcodes[i].op1 == insn)
4021 hc = msp430x_hcodes + i;
4025 for (i = 0; i < 4 && !hc; i++)
4026 if (msp430_hcodes[i].op1 == insn)
4027 hc = &msp430_hcodes[i];
4029 if (!hc || !hc->name)
4030 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4031 __FUNCTION__, (long) insn);
4032 rela = BFD_RELOC_MSP430_10_PCREL;
4033 /* Apply a fix for a first label if necessary.
4034 another fix will be applied to the next word of insn anyway. */
4036 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4037 fragP->fr_offset, TRUE, rela);
4043 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4044 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4046 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4049 if (target_is_430x ())
4051 for (i = 0; i < 4 && !hc; i++)
4052 if (msp430x_hcodes[i].op1 == insn)
4053 hc = msp430x_hcodes + i;
4057 for (i = 0; i < 4 && !hc; i++)
4058 if (msp430_hcodes[i].op1 == insn)
4059 hc = & msp430_hcodes[i];
4061 if (!hc || !hc->name)
4062 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4063 __FUNCTION__, (long) insn);
4064 rela = BFD_RELOC_MSP430_RL_PCREL;
4065 where = fragP->fr_literal + fragP->fr_fix;
4066 bfd_putl16 (hc->lop0, where);
4067 bfd_putl16 (hc->lop1, where + 2);
4068 bfd_putl16 (hc->lop2, where + 4);
4074 as_fatal (_("internal inconsistency problem in %s: %lx"),
4075 __FUNCTION__, (long) fragP->fr_subtype);
4079 /* Now apply fix. */
4080 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4081 fragP->fr_offset, TRUE, rela);
4082 /* Just fixed 2 bytes. */
4086 /* Relax fragment. Mostly stolen from hc11 and mcore
4087 which arches I think I know. */
4090 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4091 long stretch ATTRIBUTE_UNUSED)
4096 const relax_typeS *this_type;
4097 const relax_typeS *start_type;
4098 relax_substateT next_state;
4099 relax_substateT this_state;
4100 const relax_typeS *table = md_relax_table;
4102 /* Nothing to be done if the frag has already max size. */
4103 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4104 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4107 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4109 symbolP = fragP->fr_symbol;
4110 if (symbol_resolved_p (symbolP))
4111 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4113 /* We know the offset. calculate a distance. */
4114 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4117 if (!msp430_enable_relax)
4119 /* Relaxation is not enabled. So, make all jump as long ones
4120 by setting 'aim' to quite high value. */
4124 this_state = fragP->fr_subtype;
4125 start_type = this_type = table + this_state;
4129 /* Look backwards. */
4130 for (next_state = this_type->rlx_more; next_state;)
4131 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4135 /* Grow to next state. */
4136 this_state = next_state;
4137 this_type = table + this_state;
4138 next_state = this_type->rlx_more;
4143 /* Look forwards. */
4144 for (next_state = this_type->rlx_more; next_state;)
4145 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4149 /* Grow to next state. */
4150 this_state = next_state;
4151 this_type = table + this_state;
4152 next_state = this_type->rlx_more;
4156 growth = this_type->rlx_length - start_type->rlx_length;
4158 fragP->fr_subtype = this_state;
4162 /* Return FALSE if the fixup in fixp should be left alone and not
4163 adjusted. We return FALSE here so that linker relaxation will
4167 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4169 /* If the symbol is in a non-code section then it should be OK. */
4171 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4177 /* Set the contents of the .MSP430.attributes section. */
4180 msp430_md_end (void)
4182 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4183 target_is_430x () ? 2 : 1);
4185 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4186 large_model ? 2 : 1);
4188 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4189 large_model ? 2 : 1);
4192 /* Returns FALSE if there is a msp430 specific reason why the
4193 subtraction of two same-section symbols cannot be computed by
4197 msp430_allow_local_subtract (expressionS * left,
4198 expressionS * right,
4201 /* If the symbols are not in a code section then they are OK. */
4202 if ((section->flags & SEC_CODE) == 0)
4205 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4208 if (left->X_add_symbol == right->X_add_symbol)
4211 /* We have to assume that there may be instructions between the
4212 two symbols and that relaxation may increase the distance between