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 {"msp430f5418", MSP_ISA_430Xv2},
532 {"msp430f5419", MSP_ISA_430Xv2},
533 {"msp430f5435", MSP_ISA_430Xv2},
534 {"msp430f5436", MSP_ISA_430Xv2},
535 {"msp430f5437", MSP_ISA_430Xv2},
536 {"msp430f5438", MSP_ISA_430Xv2},
537 {"msp430f5418a", MSP_ISA_430Xv2},
538 {"msp430f5419a", MSP_ISA_430Xv2},
539 {"msp430f5435a", MSP_ISA_430Xv2},
540 {"msp430f5436a", MSP_ISA_430Xv2},
541 {"msp430f5437a", MSP_ISA_430Xv2},
542 {"msp430f5438a", MSP_ISA_430Xv2},
543 {"msp430f5212", MSP_ISA_430Xv2},
544 {"msp430f5213", MSP_ISA_430Xv2},
545 {"msp430f5214", MSP_ISA_430Xv2},
546 {"msp430f5217", MSP_ISA_430Xv2},
547 {"msp430f5218", MSP_ISA_430Xv2},
548 {"msp430f5219", MSP_ISA_430Xv2},
549 {"msp430f5222", MSP_ISA_430Xv2},
550 {"msp430f5223", MSP_ISA_430Xv2},
551 {"msp430f5224", MSP_ISA_430Xv2},
552 {"msp430f5227", MSP_ISA_430Xv2},
553 {"msp430f5228", MSP_ISA_430Xv2},
554 {"msp430f5229", MSP_ISA_430Xv2},
555 {"msp430f5304", MSP_ISA_430Xv2},
556 {"msp430f5308", MSP_ISA_430Xv2},
557 {"msp430f5309", MSP_ISA_430Xv2},
558 {"msp430f5310", MSP_ISA_430Xv2},
559 {"msp430f5340", MSP_ISA_430Xv2},
560 {"msp430f5341", MSP_ISA_430Xv2},
561 {"msp430f5342", MSP_ISA_430Xv2},
562 {"msp430f5324", MSP_ISA_430Xv2},
563 {"msp430f5325", MSP_ISA_430Xv2},
564 {"msp430f5326", MSP_ISA_430Xv2},
565 {"msp430f5327", MSP_ISA_430Xv2},
566 {"msp430f5328", MSP_ISA_430Xv2},
567 {"msp430f5329", MSP_ISA_430Xv2},
568 {"msp430f5500", MSP_ISA_430Xv2},
569 {"msp430f5501", MSP_ISA_430Xv2},
570 {"msp430f5502", MSP_ISA_430Xv2},
571 {"msp430f5503", MSP_ISA_430Xv2},
572 {"msp430f5504", MSP_ISA_430Xv2},
573 {"msp430f5505", MSP_ISA_430Xv2},
574 {"msp430f5506", MSP_ISA_430Xv2},
575 {"msp430f5507", MSP_ISA_430Xv2},
576 {"msp430f5508", MSP_ISA_430Xv2},
577 {"msp430f5509", MSP_ISA_430Xv2},
578 {"msp430f5510", MSP_ISA_430Xv2},
579 {"msp430f5513", MSP_ISA_430Xv2},
580 {"msp430f5514", MSP_ISA_430Xv2},
581 {"msp430f5515", MSP_ISA_430Xv2},
582 {"msp430f5517", MSP_ISA_430Xv2},
583 {"msp430f5519", MSP_ISA_430Xv2},
584 {"msp430f5521", MSP_ISA_430Xv2},
585 {"msp430f5522", MSP_ISA_430Xv2},
586 {"msp430f5524", MSP_ISA_430Xv2},
587 {"msp430f5525", MSP_ISA_430Xv2},
588 {"msp430f5526", MSP_ISA_430Xv2},
589 {"msp430f5527", MSP_ISA_430Xv2},
590 {"msp430f5528", MSP_ISA_430Xv2},
591 {"msp430f5529", MSP_ISA_430Xv2},
592 {"cc430f5133", MSP_ISA_430Xv2},
593 {"cc430f5135", MSP_ISA_430Xv2},
594 {"cc430f5137", MSP_ISA_430Xv2},
595 {"cc430f6125", MSP_ISA_430Xv2},
596 {"cc430f6126", MSP_ISA_430Xv2},
597 {"cc430f6127", MSP_ISA_430Xv2},
598 {"cc430f6135", MSP_ISA_430Xv2},
599 {"cc430f6137", MSP_ISA_430Xv2},
600 {"cc430f5123", MSP_ISA_430Xv2},
601 {"cc430f5125", MSP_ISA_430Xv2},
602 {"cc430f5143", MSP_ISA_430Xv2},
603 {"cc430f5145", MSP_ISA_430Xv2},
604 {"cc430f5147", MSP_ISA_430Xv2},
605 {"cc430f6143", MSP_ISA_430Xv2},
606 {"cc430f6145", MSP_ISA_430Xv2},
607 {"cc430f6147", MSP_ISA_430Xv2},
608 {"msp430f5333", MSP_ISA_430Xv2},
609 {"msp430f5335", MSP_ISA_430Xv2},
610 {"msp430f5336", MSP_ISA_430Xv2},
611 {"msp430f5338", MSP_ISA_430Xv2},
612 {"msp430f5630", MSP_ISA_430Xv2},
613 {"msp430f5631", MSP_ISA_430Xv2},
614 {"msp430f5632", MSP_ISA_430Xv2},
615 {"msp430f5633", MSP_ISA_430Xv2},
616 {"msp430f5634", MSP_ISA_430Xv2},
617 {"msp430f5635", MSP_ISA_430Xv2},
618 {"msp430f5636", MSP_ISA_430Xv2},
619 {"msp430f5637", MSP_ISA_430Xv2},
620 {"msp430f5638", MSP_ISA_430Xv2},
621 {"msp430f6433", MSP_ISA_430Xv2},
622 {"msp430f6435", MSP_ISA_430Xv2},
623 {"msp430f6436", MSP_ISA_430Xv2},
624 {"msp430f6438", MSP_ISA_430Xv2},
625 {"msp430f6630", MSP_ISA_430Xv2},
626 {"msp430f6631", MSP_ISA_430Xv2},
627 {"msp430f6632", MSP_ISA_430Xv2},
628 {"msp430f6633", MSP_ISA_430Xv2},
629 {"msp430f6634", MSP_ISA_430Xv2},
630 {"msp430f6635", MSP_ISA_430Xv2},
631 {"msp430f6636", MSP_ISA_430Xv2},
632 {"msp430f6637", MSP_ISA_430Xv2},
633 {"msp430f6638", MSP_ISA_430Xv2},
634 {"msp430f5358", MSP_ISA_430Xv2},
635 {"msp430f5359", MSP_ISA_430Xv2},
636 {"msp430f5658", MSP_ISA_430Xv2},
637 {"msp430f5659", MSP_ISA_430Xv2},
638 {"msp430f6458", MSP_ISA_430Xv2},
639 {"msp430f6459", MSP_ISA_430Xv2},
640 {"msp430f6658", MSP_ISA_430Xv2},
641 {"msp430f6659", MSP_ISA_430Xv2},
642 {"msp430f5131", MSP_ISA_430Xv2},
643 {"msp430f5151", MSP_ISA_430Xv2},
644 {"msp430f5171", MSP_ISA_430Xv2},
645 {"msp430f5132", MSP_ISA_430Xv2},
646 {"msp430f5152", MSP_ISA_430Xv2},
647 {"msp430f5172", MSP_ISA_430Xv2},
648 {"msp430f6720", MSP_ISA_430Xv2},
649 {"msp430f6721", MSP_ISA_430Xv2},
650 {"msp430f6723", MSP_ISA_430Xv2},
651 {"msp430f6724", MSP_ISA_430Xv2},
652 {"msp430f6725", MSP_ISA_430Xv2},
653 {"msp430f6726", MSP_ISA_430Xv2},
654 {"msp430f6730", MSP_ISA_430Xv2},
655 {"msp430f6731", MSP_ISA_430Xv2},
656 {"msp430f6733", MSP_ISA_430Xv2},
657 {"msp430f6734", MSP_ISA_430Xv2},
658 {"msp430f6735", MSP_ISA_430Xv2},
659 {"msp430f6736", MSP_ISA_430Xv2},
660 {"msp430f67451", MSP_ISA_430Xv2},
661 {"msp430f67651", MSP_ISA_430Xv2},
662 {"msp430f67751", MSP_ISA_430Xv2},
663 {"msp430f67461", MSP_ISA_430Xv2},
664 {"msp430f67661", MSP_ISA_430Xv2},
665 {"msp430f67761", MSP_ISA_430Xv2},
666 {"msp430f67471", MSP_ISA_430Xv2},
667 {"msp430f67671", MSP_ISA_430Xv2},
668 {"msp430f67771", MSP_ISA_430Xv2},
669 {"msp430f67481", MSP_ISA_430Xv2},
670 {"msp430f67681", MSP_ISA_430Xv2},
671 {"msp430f67781", MSP_ISA_430Xv2},
672 {"msp430f67491", MSP_ISA_430Xv2},
673 {"msp430f67691", MSP_ISA_430Xv2},
674 {"msp430f67791", MSP_ISA_430Xv2},
675 {"msp430f6745", MSP_ISA_430Xv2},
676 {"msp430f6765", MSP_ISA_430Xv2},
677 {"msp430f6775", MSP_ISA_430Xv2},
678 {"msp430f6746", MSP_ISA_430Xv2},
679 {"msp430f6766", MSP_ISA_430Xv2},
680 {"msp430f6776", MSP_ISA_430Xv2},
681 {"msp430f6747", MSP_ISA_430Xv2},
682 {"msp430f6767", MSP_ISA_430Xv2},
683 {"msp430f6777", MSP_ISA_430Xv2},
684 {"msp430f6748", MSP_ISA_430Xv2},
685 {"msp430f6768", MSP_ISA_430Xv2},
686 {"msp430f6778", MSP_ISA_430Xv2},
687 {"msp430f6749", MSP_ISA_430Xv2},
688 {"msp430f6769", MSP_ISA_430Xv2},
689 {"msp430f6779", MSP_ISA_430Xv2},
690 {"msp430fr5720", MSP_ISA_430Xv2},
691 {"msp430fr5721", MSP_ISA_430Xv2},
692 {"msp430fr5722", MSP_ISA_430Xv2},
693 {"msp430fr5723", MSP_ISA_430Xv2},
694 {"msp430fr5724", MSP_ISA_430Xv2},
695 {"msp430fr5725", MSP_ISA_430Xv2},
696 {"msp430fr5726", MSP_ISA_430Xv2},
697 {"msp430fr5727", MSP_ISA_430Xv2},
698 {"msp430fr5728", MSP_ISA_430Xv2},
699 {"msp430fr5729", MSP_ISA_430Xv2},
700 {"msp430fr5730", MSP_ISA_430Xv2},
701 {"msp430fr5731", MSP_ISA_430Xv2},
702 {"msp430fr5732", MSP_ISA_430Xv2},
703 {"msp430fr5733", MSP_ISA_430Xv2},
704 {"msp430fr5734", MSP_ISA_430Xv2},
705 {"msp430fr5735", MSP_ISA_430Xv2},
706 {"msp430fr5736", MSP_ISA_430Xv2},
707 {"msp430fr5737", MSP_ISA_430Xv2},
708 {"msp430fr5738", MSP_ISA_430Xv2},
709 {"msp430fr5739", MSP_ISA_430Xv2},
710 {"msp430bt5190", MSP_ISA_430Xv2},
711 {"msp430fr5949", MSP_ISA_430Xv2},
712 {"msp430fr5969", MSP_ISA_430Xv2},
713 {"msp430sl5438a", MSP_ISA_430Xv2},
716 {"msp430", MSP_ISA_430},
717 {"msp430X", MSP_ISA_430X},
718 {"msp430Xv2", MSP_ISA_430Xv2},
723 static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
724 static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
725 static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
727 static struct mcu_type_s * msp430_mcu = & default_mcu;
729 static inline bfd_boolean
730 target_is_430x (void)
732 return msp430_mcu->isa >= MSP_ISA_430X;
735 static inline bfd_boolean
736 target_is_430xv2 (void)
738 return msp430_mcu->isa == MSP_ISA_430Xv2;
741 /* Generate a 16-bit relocation.
742 For the 430X we generate a relocation without linkwer range checking
743 if the value is being used in an extended (ie 20-bit) instruction.
744 For the 430 we generate a relocation without assembler range checking
745 if we are handling an immediate value or a byte-width instruction. */
746 #undef CHECK_RELOC_MSP430
747 #define CHECK_RELOC_MSP430 \
749 ? (extended_op ? BFD_RELOC_16 : BFD_RELOC_MSP430X_ABS16) \
750 : ((imm_op || byte_op) \
751 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
753 /* Generate a 16-bit pc-relative relocation.
754 For the 430X we generate a relocation without linkwer range checking.
755 For the 430 we generate a relocation without assembler range checking
756 if we are handling an immediate value or a byte-width instruction. */
757 #undef CHECK_RELOC_MSP430_PCREL
758 #define CHECK_RELOC_MSP430_PCREL \
760 ? BFD_RELOC_MSP430X_PCR16 \
761 : (imm_op || byte_op) \
762 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
764 /* Profiling capability:
765 It is a performance hit to use gcc's profiling approach for this tiny target.
766 Even more -- jtag hardware facility does not perform any profiling functions.
767 However we've got gdb's built-in simulator where we can do anything.
768 Therefore my suggestion is:
770 We define new section ".profiler" which holds all profiling information.
771 We define new pseudo operation .profiler which will instruct assembler to
772 add new profile entry to the object file. Profile should take place at the
777 .profiler flags,function_to_profile [, cycle_corrector, extra]
779 where 'flags' is a combination of the following chars:
782 i - function is in Init section
783 f - function is in Fini section
785 c - libC standard call
786 d - stack value Demand (saved at run-time in simulator)
787 I - Interrupt service routine
792 j - long Jump/ sjlj unwind
793 a - an Arbitrary code fragment
794 t - exTra parameter saved (constant value like frame size)
795 '""' optional: "sil" == sil
797 function_to_profile - function's address
798 cycle_corrector - a value which should be added to the cycle
799 counter, zero if omitted
800 extra - some extra parameter, zero if omitted.
803 ------------------------------
807 .LFrameOffset_fxx=0x08
808 .profiler "scdP", fxx ; function entry.
809 ; we also demand stack value to be displayed
814 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
815 ; (this is a prologue end)
816 ; note, that spare var filled with the frame size
819 .profiler cdE,fxx ; check stack
824 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
825 ret ; cause 'ret' insn takes 3 cycles
826 -------------------------------
828 This profiling approach does not produce any overhead and
830 So, even profiled code can be uploaded to the MCU. */
831 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
832 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
833 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
834 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
835 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
836 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
837 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
838 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
839 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
840 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
841 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
842 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
843 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
844 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
845 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
846 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
859 for (; x; x = x >> 1)
866 /* Parse ordinary expression. */
869 parse_exp (char * s, expressionS * op)
871 input_line_pointer = s;
873 if (op->X_op == O_absent)
874 as_bad (_("missing operand"));
875 return input_line_pointer;
879 /* Delete spaces from s: X ( r 1 2) => X(r12). */
882 del_spaces (char * s)
890 while (ISSPACE (*m) && *m)
892 memmove (s, m, strlen (m) + 1);
900 skip_space (char * s)
907 /* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
910 extract_operand (char * from, char * to, int limit)
914 /* Drop leading whitespace. */
915 from = skip_space (from);
917 while (size < limit && *from)
919 *(to + size) = *from;
920 if (*from == ',' || *from == ';' || *from == '\n')
935 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
952 s = input_line_pointer;
953 end = input_line_pointer;
955 while (*end && *end != '\n')
958 while (*s && *s != '\n')
969 as_bad (_(".profiler pseudo requires at least two operands."));
970 input_line_pointer = end;
974 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
983 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
986 p_flags |= MSP430_PROFILER_FLAG_JUMP;
989 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
992 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
995 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
998 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
1001 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
1004 p_flags |= MSP430_PROFILER_FLAG_EXIT;
1007 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
1010 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
1013 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
1016 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
1019 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
1022 p_flags |= MSP430_PROFILER_FLAG_ISR;
1025 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
1028 as_warn (_("unknown profiling flag - ignored."));
1035 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
1036 | MSP430_PROFILER_FLAG_EXIT))
1037 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
1038 | MSP430_PROFILER_FLAG_PROLEND
1039 | MSP430_PROFILER_FLAG_EPISTART
1040 | MSP430_PROFILER_FLAG_EPIEND))
1041 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
1042 | MSP430_PROFILER_FLAG_FINISECT))))
1044 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
1045 input_line_pointer = end;
1049 /* Generate temp symbol which denotes current location. */
1050 if (now_seg == absolute_section) /* Paranoia ? */
1052 exp1.X_op = O_constant;
1053 exp1.X_add_number = abs_section_offset;
1054 as_warn (_("profiling in absolute section?"));
1058 exp1.X_op = O_symbol;
1059 exp1.X_add_symbol = symbol_temp_new_now ();
1060 exp1.X_add_number = 0;
1063 /* Generate a symbol which holds flags value. */
1064 exp.X_op = O_constant;
1065 exp.X_add_number = p_flags;
1067 /* Save current section. */
1069 subseg = now_subseg;
1071 /* Now go to .profiler section. */
1072 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
1075 emit_expr (& exp, 2);
1077 /* Save label value. */
1078 emit_expr (& exp1, 2);
1082 /* Now get profiling info. */
1083 halt = extract_operand (input_line_pointer, str, 1024);
1084 /* Process like ".word xxx" directive. */
1085 parse_exp (str, & exp);
1086 emit_expr (& exp, 2);
1087 input_line_pointer = halt;
1090 /* Fill the rest with zeros. */
1091 exp.X_op = O_constant;
1092 exp.X_add_number = 0;
1094 emit_expr (& exp, 2);
1096 /* Return to current section. */
1097 subseg_set (seg, subseg);
1101 extract_word (char * from, char * to, int limit)
1106 /* Drop leading whitespace. */
1107 from = skip_space (from);
1110 /* Find the op code end. */
1111 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
1113 to[size++] = *op_end++;
1114 if (size + 1 >= limit)
1122 #define OPTION_MMCU 'm'
1123 #define OPTION_RELAX 'Q'
1124 #define OPTION_POLYMORPHS 'P'
1125 #define OPTION_LARGE 'l'
1126 static bfd_boolean large_model = FALSE;
1127 #define OPTION_NO_INTR_NOPS 'N'
1128 static bfd_boolean gen_interrupt_nops = TRUE;
1129 #define OPTION_MCPU 'c'
1130 #define OPTION_MOVE_DATA 'd'
1131 static bfd_boolean move_data = FALSE;
1134 msp430_set_arch (int option)
1136 char *str = (char *) alloca (32); /* 32 for good measure. */
1138 input_line_pointer = extract_word (input_line_pointer, str, 32);
1140 md_parse_option (option, str);
1141 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1142 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1146 show_mcu_list (FILE * stream)
1150 fprintf (stream, _("Known MCU names:\n"));
1152 for (i = 0; mcu_types[i].name; i++)
1154 fprintf (stream, "%14.14s", mcu_types[i].name);
1156 fprintf (stream, "\n");
1159 fprintf (stream, "\n");
1163 md_parse_option (int c, char * arg)
1171 as_fatal (_("MCU option requires a name\n"));
1173 for (i = 0; mcu_types[i].name; ++i)
1174 if (strcasecmp (mcu_types[i].name, arg) == 0)
1177 if (mcu_types[i].name == NULL)
1179 show_mcu_list (stderr);
1180 as_fatal (_("unknown MCU: %s\n"), arg);
1183 /* Allow switching to the same or a lesser architecture. */
1184 if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
1185 msp430_mcu = mcu_types + i;
1187 as_fatal (_("redefinition of mcu type '%s' to '%s'"),
1188 msp430_mcu->name, mcu_types[i].name);
1192 if (strcmp (arg, "430") == 0)
1193 msp430_mcu = & default_mcu;
1194 else if (strcmp (arg, "430x") == 0
1195 || strcmp (arg, "430X") == 0)
1196 msp430_mcu = & msp430x_mcu;
1197 else if (strcasecmp (arg, "430xv2") == 0)
1198 msp430_mcu = & msp430xv2_mcu;
1200 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1205 msp430_enable_relax = 1;
1208 case OPTION_POLYMORPHS:
1209 msp430_enable_polys = 1;
1216 case OPTION_NO_INTR_NOPS:
1217 gen_interrupt_nops = FALSE;
1220 case OPTION_MOVE_DATA:
1229 msp430_section (int arg)
1231 char * saved_ilp = input_line_pointer;
1232 char * name = obj_elf_section_name ();
1234 if (strncmp (name, ".bss", 4) == 0
1235 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1236 (void) symbol_find_or_make ("__crt0_init_bss");
1239 && (strncmp (name, ".data", 5) == 0
1240 || strncmp (name, ".gnu.linkonce.d.", 16) == 0))
1241 (void) symbol_find_or_make ("__crt0_movedata");
1243 input_line_pointer = saved_ilp;
1244 obj_elf_section (arg);
1247 const pseudo_typeS md_pseudo_table[] =
1249 {"arch", msp430_set_arch, OPTION_MMCU},
1250 {"cpu", msp430_set_arch, OPTION_MCPU},
1251 {"profiler", msp430_profiler, 0},
1252 {"section", msp430_section, 0},
1253 {"section.s", msp430_section, 0},
1254 {"sect", msp430_section, 0},
1255 {"sect.s", msp430_section, 0},
1256 {"pushsection", msp430_section, 1},
1260 const char *md_shortopts = "mm:,mP,mQ,ml,mN";
1262 struct option md_longopts[] =
1264 {"mmcu", required_argument, NULL, OPTION_MMCU},
1265 {"mcpu", required_argument, NULL, OPTION_MCPU},
1266 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1267 {"mQ", no_argument, NULL, OPTION_RELAX},
1268 {"ml", no_argument, NULL, OPTION_LARGE},
1269 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1270 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1271 {NULL, no_argument, NULL, 0}
1274 size_t md_longopts_size = sizeof (md_longopts);
1277 md_show_usage (FILE * stream)
1280 _("MSP430 options:\n"
1281 " -mmcu=<msp430-name> - select microcontroller type\n"
1282 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1284 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1285 " -mP - enable polymorph instructions\n"));
1287 _(" -ml - enable large code model\n"));
1289 _(" -mN - disable generation of NOP after changing interrupts\n"));
1291 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1293 show_mcu_list (stream);
1297 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1303 extract_cmd (char * from, char * to, int limit)
1307 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1309 *(to + size) = *from;
1320 md_atof (int type, char * litP, int * sizeP)
1322 return ieee_md_atof (type, litP, sizeP, FALSE);
1328 struct msp430_opcode_s * opcode;
1329 msp430_hash = hash_new ();
1331 for (opcode = msp430_opcodes; opcode->name; opcode++)
1332 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1334 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1335 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1338 /* Returns the register number equivalent to the string T.
1339 Returns -1 if there is no such register.
1340 Skips a leading 'r' or 'R' character if there is one.
1341 Handles the register aliases PC and SP. */
1344 check_reg (char * t)
1351 if (*t == 'r' || *t == 'R')
1354 if (strncasecmp (t, "pc", 2) == 0)
1357 if (strncasecmp (t, "sp", 2) == 0)
1360 if (strncasecmp (t, "sr", 2) == 0)
1368 if (val < 1 || val > 15)
1375 msp430_srcoperand (struct msp430_operand_s * op,
1379 bfd_boolean allow_20bit_values,
1380 bfd_boolean constants_allowed)
1384 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1391 /* Check if there is:
1392 llo(x) - least significant 16 bits, x &= 0xffff
1393 lhi(x) - x = (x >> 16) & 0xffff,
1394 hlo(x) - x = (x >> 32) & 0xffff,
1395 hhi(x) - x = (x >> 48) & 0xffff
1396 The value _MUST_ be constant expression: #hlo(1231231231). */
1400 if (strncasecmp (h, "#llo(", 5) == 0)
1405 else if (strncasecmp (h, "#lhi(", 5) == 0)
1410 else if (strncasecmp (h, "#hlo(", 5) == 0)
1415 else if (strncasecmp (h, "#hhi(", 5) == 0)
1420 else if (strncasecmp (h, "#lo(", 4) == 0)
1425 else if (strncasecmp (h, "#hi(", 4) == 0)
1431 op->reg = 0; /* Reg PC. */
1433 op->ol = 1; /* Immediate will follow an instruction. */
1434 __tl = h + 1 + rval;
1437 parse_exp (__tl, &(op->exp));
1438 if (op->exp.X_op == O_constant)
1440 int x = op->exp.X_add_number;
1445 op->exp.X_add_number = x;
1447 else if (vshift == 1)
1449 x = (x >> 16) & 0xffff;
1450 op->exp.X_add_number = x;
1452 else if (vshift > 1)
1455 op->exp.X_add_number = -1;
1457 op->exp.X_add_number = 0; /* Nothing left. */
1458 x = op->exp.X_add_number;
1461 if (allow_20bit_values)
1463 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < - (0x7ffff))
1465 as_bad (_("value 0x%x out of extended range."), x);
1469 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1471 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1475 /* Now check constants. */
1476 /* Substitute register mode with a constant generator if applicable. */
1478 if (!allow_20bit_values)
1479 x = (short) x; /* Extend sign. */
1481 if (! constants_allowed)
1513 #ifdef PUSH_1X_WORKAROUND
1516 /* Remove warning as confusing.
1517 as_warn (_("Hardware push bug workaround")); */
1530 #ifdef PUSH_1X_WORKAROUND
1533 /* Remove warning as confusing.
1534 as_warn (_("Hardware push bug workaround")); */
1546 else if (op->exp.X_op == O_symbol)
1550 else if (op->exp.X_op == O_big)
1555 op->exp.X_op = O_constant;
1556 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1557 x = op->exp.X_add_number;
1562 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1610 /* Redundant (yet) check. */
1611 else if (op->exp.X_op == O_register)
1613 (_("Registers cannot be used within immediate expression [%s]"), l);
1615 as_bad (_("unknown operand %s"), l);
1620 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1625 op->reg = 2; /* reg 2 in absolute addr mode. */
1626 op->am = 1; /* mode As == 01 bin. */
1627 op->ol = 1; /* Immediate value followed by instruction. */
1629 parse_exp (__tl, &(op->exp));
1631 if (op->exp.X_op == O_constant)
1633 int x = op->exp.X_add_number;
1635 if (allow_20bit_values)
1637 if (x > 0xfffff || x < -(0x7ffff))
1639 as_bad (_("value 0x%x out of extended range."), x);
1643 else if (x > 65535 || x < -32768)
1645 as_bad (_("value out of range: 0x%x"), x);
1649 else if (op->exp.X_op == O_symbol)
1653 /* Redundant (yet) check. */
1654 if (op->exp.X_op == O_register)
1656 (_("Registers cannot be used within absolute expression [%s]"), l);
1658 as_bad (_("unknown expression in operand %s"), l);
1664 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1668 char *m = strchr (l, '+');
1672 as_bad (_("unknown addressing mode %s"), l);
1678 if ((op->reg = check_reg (t)) == -1)
1680 as_bad (_("Bad register name %s"), t);
1688 /* PC cannot be used in indirect addressing. */
1689 if (target_is_430xv2 () && op->reg == 0)
1691 as_bad (_("cannot use indirect addressing with the PC"));
1697 /* Check if register indexed X(Rn). */
1700 char *h = strrchr (l, '(');
1701 char *m = strrchr (l, ')');
1710 as_bad (_("')' required"));
1718 /* Extract a register. */
1719 if ((op->reg = check_reg (t + 1)) == -1)
1722 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1729 as_bad (_("r2 should not be used in indexed addressing mode"));
1733 /* Extract constant. */
1737 parse_exp (__tl, &(op->exp));
1738 if (op->exp.X_op == O_constant)
1740 int x = op->exp.X_add_number;
1742 if (allow_20bit_values)
1744 if (x > 0xfffff || x < - (0x7ffff))
1746 as_bad (_("value 0x%x out of extended range."), x);
1750 else if (x > 65535 || x < -32768)
1752 as_bad (_("value out of range: 0x%x"), x);
1764 else if (op->exp.X_op == O_symbol)
1768 /* Redundant (yet) check. */
1769 if (op->exp.X_op == O_register)
1771 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1773 as_bad (_("unknown expression in operand %s"), l);
1781 /* Possibly register mode 'mov r1,r2'. */
1782 if ((op->reg = check_reg (l)) != -1)
1790 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1794 op->reg = 0; /* PC relative... be careful. */
1795 /* An expression starting with a minus sign is a constant, not an address. */
1796 op->am = (*l == '-' ? 3 : 1);
1799 parse_exp (__tl, &(op->exp));
1805 as_bad (_("unknown addressing mode for operand %s"), l);
1811 msp430_dstoperand (struct msp430_operand_s * op,
1814 bfd_boolean allow_20bit_values,
1815 bfd_boolean constants_allowed)
1818 int ret = msp430_srcoperand (op, l, bin, & dummy,
1832 parse_exp (__tl, &(op->exp));
1834 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1836 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1846 ("this addressing mode is not applicable for destination operand"));
1853 /* Attempt to encode a MOVA instruction with the given operands.
1854 Returns the length of the encoded instruction if successful
1855 or 0 upon failure. If the encoding fails, an error message
1856 will be returned if a pointer is provided. */
1859 try_encode_mova (bfd_boolean imm_op,
1861 struct msp430_operand_s * op1,
1862 struct msp430_operand_s * op2,
1863 const char ** error_message_return)
1869 /* Only a restricted subset of the normal MSP430 addressing modes
1870 are supported here, so check for the ones that are allowed. */
1873 if (op1->mode == OP_EXP)
1875 if (op2->mode != OP_REG)
1877 if (error_message_return != NULL)
1878 * error_message_return = _("expected register as second argument of %s");
1884 /* MOVA #imm20, Rdst. */
1885 bin |= 0x80 | op2->reg;
1886 frag = frag_more (4);
1887 where = frag - frag_now->fr_literal;
1888 if (op1->exp.X_op == O_constant)
1890 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
1891 bfd_putl16 ((bfd_vma) bin, frag);
1892 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1896 bfd_putl16 ((bfd_vma) bin, frag);
1897 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
1898 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
1899 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1904 else if (op1->am == 1)
1906 /* MOVA z16(Rsrc), Rdst. */
1907 bin |= 0x30 | (op1->reg << 8) | op2->reg;
1908 frag = frag_more (4);
1909 where = frag - frag_now->fr_literal;
1910 bfd_putl16 ((bfd_vma) bin, frag);
1911 if (op1->exp.X_op == O_constant)
1913 if (op1->exp.X_add_number > 0xffff
1914 || op1->exp.X_add_number < -(0x7fff))
1916 if (error_message_return != NULL)
1917 * error_message_return = _("index value too big for %s");
1920 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
1924 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1925 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
1927 BFD_RELOC_MSP430X_PCR16 :
1928 BFD_RELOC_MSP430X_ABS16);
1933 if (error_message_return != NULL)
1934 * error_message_return = _("unexpected addressing mode for %s");
1937 else if (op1->am == 0)
1939 /* MOVA Rsrc, ... */
1940 if (op2->mode == OP_REG)
1942 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
1943 frag = frag_more (2);
1944 where = frag - frag_now->fr_literal;
1945 bfd_putl16 ((bfd_vma) bin, frag);
1948 else if (op2->am == 1)
1952 /* MOVA Rsrc, &abs20. */
1953 bin |= 0x60 | (op1->reg << 8);
1954 frag = frag_more (4);
1955 where = frag - frag_now->fr_literal;
1956 if (op2->exp.X_op == O_constant)
1958 bin |= (op2->exp.X_add_number >> 16) & 0xf;
1959 bfd_putl16 ((bfd_vma) bin, frag);
1960 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1964 bfd_putl16 ((bfd_vma) bin, frag);
1965 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1966 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
1967 BFD_RELOC_MSP430X_ABS20_ADR_DST);
1972 /* MOVA Rsrc, z16(Rdst). */
1973 bin |= 0x70 | (op1->reg << 8) | op2->reg;
1974 frag = frag_more (4);
1975 where = frag - frag_now->fr_literal;
1976 bfd_putl16 ((bfd_vma) bin, frag);
1977 if (op2->exp.X_op == O_constant)
1979 if (op2->exp.X_add_number > 0xffff
1980 || op2->exp.X_add_number < -(0x7fff))
1982 if (error_message_return != NULL)
1983 * error_message_return = _("index value too big for %s");
1986 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
1990 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1991 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
1993 BFD_RELOC_MSP430X_PCR16 :
1994 BFD_RELOC_MSP430X_ABS16);
1999 if (error_message_return != NULL)
2000 * error_message_return = _("unexpected addressing mode for %s");
2005 /* imm_op == FALSE. */
2007 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2009 /* MOVA &abs20, Rdst. */
2010 if (op2->mode != OP_REG)
2012 if (error_message_return != NULL)
2013 * error_message_return = _("expected register as second argument of %s");
2017 if (op2->reg == 2 || op2->reg == 3)
2019 if (error_message_return != NULL)
2020 * error_message_return = _("constant generator destination register found in %s");
2024 bin |= 0x20 | op2->reg;
2025 frag = frag_more (4);
2026 where = frag - frag_now->fr_literal;
2027 if (op1->exp.X_op == O_constant)
2029 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2030 bfd_putl16 ((bfd_vma) bin, frag);
2031 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2035 bfd_putl16 ((bfd_vma) bin, frag);
2036 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2037 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2038 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2042 else if (op1->mode == OP_REG)
2046 /* MOVA @Rsrc+, Rdst. */
2047 if (op2->mode != OP_REG)
2049 if (error_message_return != NULL)
2050 * error_message_return = _("expected register as second argument of %s");
2054 if (op2->reg == 2 || op2->reg == 3)
2056 if (error_message_return != NULL)
2057 * error_message_return = _("constant generator destination register found in %s");
2061 if (op1->reg == 2 || op1->reg == 3)
2063 if (error_message_return != NULL)
2064 * error_message_return = _("constant generator source register found in %s");
2068 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2069 frag = frag_more (2);
2070 where = frag - frag_now->fr_literal;
2071 bfd_putl16 ((bfd_vma) bin, frag);
2074 else if (op1->am == 2)
2076 /* MOVA @Rsrc,Rdst */
2077 if (op2->mode != OP_REG)
2079 if (error_message_return != NULL)
2080 * error_message_return = _("expected register as second argument of %s");
2084 if (op2->reg == 2 || op2->reg == 3)
2086 if (error_message_return != NULL)
2087 * error_message_return = _("constant generator destination register found in %s");
2091 if (op1->reg == 2 || op1->reg == 3)
2093 if (error_message_return != NULL)
2094 * error_message_return = _("constant generator source register found in %s");
2098 bin |= (op1->reg << 8) | op2->reg;
2099 frag = frag_more (2);
2100 where = frag - frag_now->fr_literal;
2101 bfd_putl16 ((bfd_vma) bin, frag);
2106 if (error_message_return != NULL)
2107 * error_message_return = _("unexpected addressing mode for %s");
2112 #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2114 /* Parse instruction operands.
2115 Return binary opcode. */
2118 msp430_operands (struct msp430_opcode_s * opcode, char * line)
2120 int bin = opcode->bin_opcode; /* Opcode mask. */
2121 int insn_length = 0;
2122 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2125 struct msp430_operand_s op1, op2;
2127 static short ZEROS = 0;
2128 int byte_op, imm_op;
2131 int extended = 0x1800;
2132 bfd_boolean extended_op = FALSE;
2133 bfd_boolean addr_op;
2134 const char * error_message;
2135 static signed int repeat_count = 0;
2136 bfd_boolean fix_emitted;
2138 /* Opcode is the one from opcodes table
2139 line contains something like
2148 bfd_boolean check = FALSE;
2151 switch (TOLOWER (* line))
2154 /* Byte operation. */
2155 bin |= BYTE_OPERATION;
2161 /* "Address" ops work on 20-bit values. */
2163 bin |= BYTE_OPERATION;
2168 /* Word operation - this is the default. */
2176 as_warn (_("no size modifier after period, .w assumed"));
2180 as_bad (_("unrecognised instruction size modifier .%c"),
2192 if (*line && ! ISSPACE (*line))
2194 as_bad (_("junk found after instruction: %s.%s"),
2195 opcode->name, line);
2199 /* Catch the case where the programmer has used a ".a" size modifier on an
2200 instruction that does not support it. Look for an alternative extended
2201 instruction that has the same name without the period. Eg: "add.a"
2202 becomes "adda". Although this not an officially supported way of
2203 specifing instruction aliases other MSP430 assemblers allow it. So we
2204 support it for compatibility purposes. */
2205 if (addr_op && opcode->fmt >= 0)
2207 char * old_name = opcode->name;
2210 sprintf (real_name, "%sa", old_name);
2211 opcode = hash_find (msp430_hash, real_name);
2214 as_bad (_("instruction %s.a does not exist"), old_name);
2217 #if 0 /* Enable for debugging. */
2218 as_warn ("treating %s.a as %s", old_name, real_name);
2221 bin = opcode->bin_opcode;
2224 if (opcode->fmt != -1
2225 && opcode->insn_opnumb
2226 && (!*line || *line == '\n'))
2228 as_bad (_("instruction %s requires %d operand(s)"),
2229 opcode->name, opcode->insn_opnumb);
2233 memset (l1, 0, sizeof (l1));
2234 memset (l2, 0, sizeof (l2));
2235 memset (&op1, 0, sizeof (op1));
2236 memset (&op2, 0, sizeof (op2));
2240 if ((fmt = opcode->fmt) < 0)
2242 if (! target_is_430x ())
2244 as_bad (_("instruction %s requires MSP430X mcu"),
2255 /* If requested set the extended instruction repeat count. */
2258 if (repeat_count > 0)
2259 extended |= (repeat_count - 1);
2261 extended |= (1 << 7) | (- repeat_count);
2264 as_bad (_("unable to repeat %s insn"), opcode->name);
2271 case 0: /* Emulated. */
2272 switch (opcode->insn_opnumb)
2275 /* Set/clear bits instructions. */
2279 extended |= BYTE_OPERATION;
2281 /* Emit the extension word. */
2283 frag = frag_more (insn_length);
2284 bfd_putl16 (extended, frag);
2288 frag = frag_more (insn_length);
2289 bfd_putl16 ((bfd_vma) bin, frag);
2291 if (gen_interrupt_nops
2292 && target_is_430xv2 ()
2293 && (is_opcode ("eint") || is_opcode ("dint")))
2295 /* Emit a NOP following interrupt enable/disable.
2296 See 1.3.4.1 of the MSP430x5xx User Guide. */
2298 frag = frag_more (2);
2299 as_warn (_("a NOP instruction has been inserted after %s"),
2301 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2303 dwarf2_emit_insn (insn_length);
2307 /* Something which works with destination operand. */
2308 line = extract_operand (line, l1, sizeof (l1));
2309 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2313 /* Compute the entire instruction length, in bytes. */
2314 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2315 frag = frag_more (insn_length);
2316 where = frag - frag_now->fr_literal;
2321 extended |= BYTE_OPERATION;
2323 if (op1.ol != 0 && ((extended & 0xf) != 0))
2325 as_bad (_("repeat instruction used with non-register mode instruction"));
2329 if (op1.mode == OP_EXP)
2331 if (op1.exp.X_op == O_constant)
2332 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2334 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2335 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2336 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2338 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2339 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2342 /* Emit the extension word. */
2343 bfd_putl16 (extended, frag);
2348 bin |= (op1.reg | (op1.am << 7));
2349 bfd_putl16 ((bfd_vma) bin, frag);
2353 if (op1.mode == OP_EXP)
2355 if (op1.exp.X_op == O_constant)
2357 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2361 bfd_putl16 ((bfd_vma) ZEROS, frag);
2366 fix_new_exp (frag_now, where, 2,
2367 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2369 fix_new_exp (frag_now, where, 2,
2370 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2375 if (gen_interrupt_nops
2376 && target_is_430xv2 ()
2377 && is_opcode ("clr")
2378 && bin == 0x4302 /* CLR R2*/)
2380 /* Emit a NOP following interrupt enable/disable.
2381 See 1.3.4.1 of the MSP430x5xx User Guide. */
2383 frag = frag_more (2);
2384 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2385 as_warn (_("a NOP instruction has been inserted after %s"),
2389 dwarf2_emit_insn (insn_length);
2393 /* Shift instruction. */
2394 line = extract_operand (line, l1, sizeof (l1));
2395 strncpy (l2, l1, sizeof (l2));
2396 l2[sizeof (l2) - 1] = '\0';
2397 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2398 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2401 break; /* An error occurred. All warnings were done before. */
2403 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2404 frag = frag_more (insn_length);
2405 where = frag - frag_now->fr_literal;
2407 if (target_is_430xv2 ()
2408 && op1.mode == OP_REG
2410 && (is_opcode ("rlax")
2411 || is_opcode ("rlcx")
2412 || is_opcode ("rla")
2413 || is_opcode ("rlc")))
2415 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2422 extended |= BYTE_OPERATION;
2424 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2426 as_bad (_("repeat instruction used with non-register mode instruction"));
2430 if (op1.mode == OP_EXP)
2432 if (op1.exp.X_op == O_constant)
2433 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2435 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2436 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2437 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2439 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2440 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2443 if (op2.mode == OP_EXP)
2445 if (op2.exp.X_op == O_constant)
2446 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2448 else if (op1.mode == OP_EXP)
2449 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2450 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2451 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2453 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2454 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2455 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2458 /* Emit the extension word. */
2459 bfd_putl16 (extended, frag);
2464 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2465 bfd_putl16 ((bfd_vma) bin, frag);
2469 if (op1.mode == OP_EXP)
2471 if (op1.exp.X_op == O_constant)
2473 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2477 bfd_putl16 ((bfd_vma) ZEROS, frag);
2481 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2482 fix_new_exp (frag_now, where, 2,
2483 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2485 fix_new_exp (frag_now, where, 2,
2486 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2493 if (op2.mode == OP_EXP)
2495 if (op2.exp.X_op == O_constant)
2497 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2501 bfd_putl16 ((bfd_vma) ZEROS, frag);
2505 if (op2.reg) /* Not PC relative. */
2506 fix_new_exp (frag_now, where, 2,
2507 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
2509 fix_new_exp (frag_now, where, 2,
2510 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2515 dwarf2_emit_insn (insn_length);
2519 /* Branch instruction => mov dst, r0. */
2522 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2526 line = extract_operand (line, l1, sizeof (l1));
2527 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2533 bin |= ((op1.reg << 8) | (op1.am << 4));
2534 op_length = 2 + 2 * op1.ol;
2535 frag = frag_more (op_length);
2536 where = frag - frag_now->fr_literal;
2537 bfd_putl16 ((bfd_vma) bin, frag);
2539 if (op1.mode == OP_EXP)
2541 if (op1.exp.X_op == O_constant)
2543 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2549 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2551 if (op1.reg || (op1.reg == 0 && op1.am == 3))
2552 fix_new_exp (frag_now, where, 2,
2553 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2555 fix_new_exp (frag_now, where, 2,
2556 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2560 dwarf2_emit_insn (insn_length + op_length);
2564 /* CALLA instructions. */
2565 fix_emitted = FALSE;
2567 line = extract_operand (line, l1, sizeof (l1));
2570 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2571 extended_op, FALSE);
2577 op_length = 2 + 2 * op1.ol;
2578 frag = frag_more (op_length);
2579 where = frag - frag_now->fr_literal;
2587 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2588 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2591 else if (op1.am == 1)
2597 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2598 BFD_RELOC_MSP430X_PCR20_CALL);
2602 bin |= 0x50 | op1.reg;
2604 else if (op1.am == 0)
2605 bin |= 0x40 | op1.reg;
2607 else if (op1.am == 1)
2611 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2612 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2615 else if (op1.am == 2)
2616 bin |= 0x60 | op1.reg;
2617 else if (op1.am == 3)
2618 bin |= 0x70 | op1.reg;
2620 bfd_putl16 ((bfd_vma) bin, frag);
2622 if (op1.mode == OP_EXP)
2626 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2630 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2633 fix_new_exp (frag_now, where + 2, 2,
2634 &(op1.exp), FALSE, BFD_RELOC_16);
2637 dwarf2_emit_insn (insn_length + op_length);
2645 /* [POP|PUSH]M[.A] #N, Rd */
2646 line = extract_operand (line, l1, sizeof (l1));
2647 line = extract_operand (line, l2, sizeof (l2));
2651 as_bad (_("expected #n as first argument of %s"), opcode->name);
2654 parse_exp (l1 + 1, &(op1.exp));
2655 if (op1.exp.X_op != O_constant)
2657 as_bad (_("expected constant expression for first argument of %s"),
2662 if ((reg = check_reg (l2)) == -1)
2664 as_bad (_("expected register as second argument of %s"),
2670 frag = frag_more (op_length);
2671 where = frag - frag_now->fr_literal;
2672 bin = opcode->bin_opcode;
2675 n = op1.exp.X_add_number;
2676 bin |= (n - 1) << 4;
2677 if (is_opcode ("pushm"))
2681 if (reg - n + 1 < 0)
2683 as_bad (_("Too many registers popped"));
2687 /* CPU21 parts cannot use POPM to restore the SR register. */
2688 if (target_is_430xv2 ()
2689 && (reg - n + 1 < 3)
2691 && is_opcode ("popm"))
2693 as_bad (_("Cannot use POPM to restore the SR register"));
2697 bin |= (reg - n + 1);
2700 bfd_putl16 ((bfd_vma) bin, frag);
2701 dwarf2_emit_insn (op_length);
2710 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2711 if (extended & 0xff)
2713 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2717 line = extract_operand (line, l1, sizeof (l1));
2718 line = extract_operand (line, l2, sizeof (l2));
2722 as_bad (_("expected #n as first argument of %s"), opcode->name);
2725 parse_exp (l1 + 1, &(op1.exp));
2726 if (op1.exp.X_op != O_constant)
2728 as_bad (_("expected constant expression for first argument of %s"),
2732 n = op1.exp.X_add_number;
2735 as_bad (_("expected first argument of %s to be in the range 1-4"),
2740 if ((reg = check_reg (l2)) == -1)
2742 as_bad (_("expected register as second argument of %s"),
2747 if (target_is_430xv2 () && reg == 0)
2749 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2754 frag = frag_more (op_length);
2755 where = frag - frag_now->fr_literal;
2757 bin = opcode->bin_opcode;
2760 bin |= (n - 1) << 10;
2763 bfd_putl16 ((bfd_vma) bin, frag);
2764 dwarf2_emit_insn (op_length);
2772 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
2773 if (extended & 0xff)
2775 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2779 line = extract_operand (line, l1, sizeof (l1));
2780 if ((reg = check_reg (l1)) == -1)
2782 as_bad (_("expected register as argument of %s"),
2787 if (target_is_430xv2 () && reg == 0)
2789 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2795 /* Tricky - there is no single instruction that will do this.
2796 Encode as: RRA.B rN { BIC.B #0x80, rN */
2798 frag = frag_more (op_length);
2799 where = frag - frag_now->fr_literal;
2801 bfd_putl16 ((bfd_vma) bin, frag);
2802 dwarf2_emit_insn (2);
2804 bfd_putl16 ((bfd_vma) bin, frag + 2);
2806 bfd_putl16 ((bfd_vma) bin, frag + 4);
2807 dwarf2_emit_insn (4);
2811 /* Encode as RRUM[.A] rN. */
2812 bin = opcode->bin_opcode;
2817 frag = frag_more (op_length);
2818 where = frag - frag_now->fr_literal;
2819 bfd_putl16 ((bfd_vma) bin, frag);
2820 dwarf2_emit_insn (op_length);
2827 bfd_boolean need_reloc = FALSE;
2831 /* ADDA, CMPA and SUBA address instructions. */
2832 if (extended & 0xff)
2834 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2838 line = extract_operand (line, l1, sizeof (l1));
2839 line = extract_operand (line, l2, sizeof (l2));
2841 bin = opcode->bin_opcode;
2845 parse_exp (l1 + 1, &(op1.exp));
2847 if (op1.exp.X_op == O_constant)
2849 n = op1.exp.X_add_number;
2850 if (n > 0xfffff || n < - (0x7ffff))
2852 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
2857 bin |= ((n >> 16) & 0xf) << 8;
2869 if ((n = check_reg (l1)) == -1)
2871 as_bad (_("expected register name or constant as first argument of %s"),
2876 bin |= (n << 8) | (1 << 6);
2880 if ((reg = check_reg (l2)) == -1)
2882 as_bad (_("expected register as second argument of %s"),
2887 frag = frag_more (op_length);
2888 where = frag - frag_now->fr_literal;
2891 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2892 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2894 bfd_putl16 ((bfd_vma) bin, frag);
2896 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
2897 dwarf2_emit_insn (op_length);
2901 case 9: /* MOVA, BRA, RETA. */
2903 bin = opcode->bin_opcode;
2905 if (is_opcode ("reta"))
2907 /* The RETA instruction does not take any arguments.
2908 The implicit first argument is @SP+.
2909 The implicit second argument is PC. */
2919 line = extract_operand (line, l1, sizeof (l1));
2920 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
2921 &imm_op, extended_op, FALSE);
2923 if (is_opcode ("bra"))
2925 /* This is the BRA synthetic instruction.
2926 The second argument is always PC. */
2932 line = extract_operand (line, l2, sizeof (l2));
2933 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
2938 break; /* Error occurred. All warnings were done before. */
2941 /* Only a restricted subset of the normal MSP430 addressing modes
2942 are supported here, so check for the ones that are allowed. */
2943 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
2944 & error_message)) == 0)
2946 as_bad (error_message, opcode->name);
2949 dwarf2_emit_insn (op_length);
2953 line = extract_operand (line, l1, sizeof l1);
2954 /* The RPT instruction only accepted immediates and registers. */
2957 parse_exp (l1 + 1, &(op1.exp));
2958 if (op1.exp.X_op != O_constant)
2960 as_bad (_("expected constant value as argument to RPT"));
2963 if (op1.exp.X_add_number < 1
2964 || op1.exp.X_add_number > (1 << 4))
2966 as_bad (_("expected constant in the range 2..16"));
2970 /* We silently accept and ignore a repeat count of 1. */
2971 if (op1.exp.X_add_number > 1)
2972 repeat_count = op1.exp.X_add_number;
2978 if ((reg = check_reg (l1)) != -1)
2981 as_warn (_("PC used as an argument to RPT"));
2983 repeat_count = - reg;
2987 as_bad (_("expected constant or register name as argument to RPT insn"));
2994 as_bad (_("Illegal emulated instruction "));
2999 case 1: /* Format 1, double operand. */
3000 line = extract_operand (line, l1, sizeof (l1));
3001 line = extract_operand (line, l2, sizeof (l2));
3002 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3003 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3006 break; /* Error occurred. All warnings were done before. */
3009 && is_opcode ("movx")
3011 && msp430_enable_relax)
3013 /* This is the MOVX.A instruction. See if we can convert
3014 it into the MOVA instruction instead. This saves 2 bytes. */
3015 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3018 dwarf2_emit_insn (op_length);
3023 /* Compute the entire length of the instruction in bytes. */
3025 (extended_op ? 2 : 0) /* The extension word. */
3026 + 2 /* The opcode */
3027 + (2 * op1.ol) /* The first operand. */
3028 + (2 * op2.ol); /* The second operand. */
3030 frag = frag_more (insn_length);
3031 where = frag - frag_now->fr_literal;
3036 extended |= BYTE_OPERATION;
3038 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3040 as_bad (_("repeat instruction used with non-register mode instruction"));
3044 /* If necessary, emit a reloc to update the extension word. */
3045 if (op1.mode == OP_EXP)
3047 if (op1.exp.X_op == O_constant)
3048 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3050 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3051 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3052 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3054 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3055 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3058 if (op2.mode == OP_EXP)
3060 if (op2.exp.X_op == O_constant)
3061 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3063 else if (op1.mode == OP_EXP)
3064 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3065 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3066 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3069 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3070 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3071 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3074 /* Emit the extension word. */
3075 bfd_putl16 (extended, frag);
3080 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3081 bfd_putl16 ((bfd_vma) bin, frag);
3085 if (op1.mode == OP_EXP)
3087 if (op1.exp.X_op == O_constant)
3089 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3093 bfd_putl16 ((bfd_vma) ZEROS, frag);
3097 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3098 fix_new_exp (frag_now, where, 2,
3099 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3101 fix_new_exp (frag_now, where, 2,
3102 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3110 if (op2.mode == OP_EXP)
3112 if (op2.exp.X_op == O_constant)
3114 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3118 bfd_putl16 ((bfd_vma) ZEROS, frag);
3122 if (op2.reg) /* Not PC relative. */
3123 fix_new_exp (frag_now, where, 2,
3124 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
3126 fix_new_exp (frag_now, where, 2,
3127 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3132 if (gen_interrupt_nops
3133 && target_is_430xv2 ()
3134 && ( (is_opcode ("bic") && bin == 0xc232)
3135 || (is_opcode ("bis") && bin == 0xd232)
3136 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
3138 /* Emit a NOP following interrupt enable/disable.
3139 See 1.3.4.1 of the MSP430x5xx User Guide. */
3141 frag = frag_more (2);
3142 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3143 as_warn (_("a NOP instruction has been inserted after %s"),
3147 dwarf2_emit_insn (insn_length);
3150 case 2: /* Single-operand mostly instr. */
3151 if (opcode->insn_opnumb == 0)
3153 /* reti instruction. */
3155 frag = frag_more (2);
3156 bfd_putl16 ((bfd_vma) bin, frag);
3157 dwarf2_emit_insn (insn_length);
3161 line = extract_operand (line, l1, sizeof (l1));
3162 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3163 &imm_op, extended_op, TRUE);
3165 break; /* Error in operand. */
3167 if (target_is_430xv2 ()
3168 && op1.mode == OP_REG
3170 && (is_opcode ("rrax")
3171 || is_opcode ("rrcx")
3172 || is_opcode ("rra")
3173 || is_opcode ("rrc")))
3175 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3179 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3180 frag = frag_more (insn_length);
3181 where = frag - frag_now->fr_literal;
3185 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3187 /* These two instructions use a special
3188 encoding of the A/L and B/W bits. */
3189 bin &= ~ BYTE_OPERATION;
3193 as_bad (_("%s instruction does not accept a .b suffix"),
3198 extended |= BYTE_OPERATION;
3201 extended |= BYTE_OPERATION;
3203 if (op1.ol != 0 && ((extended & 0xf) != 0))
3205 as_bad (_("repeat instruction used with non-register mode instruction"));
3209 if (op1.mode == OP_EXP)
3211 if (op1.exp.X_op == O_constant)
3212 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3214 else if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3215 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3216 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3218 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3219 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3222 /* Emit the extension word. */
3223 bfd_putl16 (extended, frag);
3228 bin |= op1.reg | (op1.am << 4);
3229 bfd_putl16 ((bfd_vma) bin, frag);
3233 if (op1.mode == OP_EXP)
3235 if (op1.exp.X_op == O_constant)
3237 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3241 bfd_putl16 ((bfd_vma) ZEROS, frag);
3245 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3246 fix_new_exp (frag_now, where, 2,
3247 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
3249 fix_new_exp (frag_now, where, 2,
3250 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3255 dwarf2_emit_insn (insn_length);
3258 case 3: /* Conditional jumps instructions. */
3259 line = extract_operand (line, l1, sizeof (l1));
3260 /* l1 is a label. */
3269 parse_exp (m, &exp);
3271 /* In order to handle something like:
3275 jz 4 ; skip next 4 bytes
3278 nop ; will jump here if r5 positive or zero
3280 jCOND -n ;assumes jump n bytes backward:
3290 jCOND $n ; jump from PC in either direction. */
3292 if (exp.X_op == O_constant)
3294 int x = exp.X_add_number;
3298 as_warn (_("Even number required. Rounded to %d"), x + 1);
3302 if ((*l1 == '$' && x > 0) || x < 0)
3307 if (x > 512 || x < -511)
3309 as_bad (_("Wrong displacement %d"), x << 1);
3314 frag = frag_more (2); /* Instr size is 1 word. */
3317 bfd_putl16 ((bfd_vma) bin, frag);
3319 else if (exp.X_op == O_symbol && *l1 != '$')
3322 frag = frag_more (2); /* Instr size is 1 word. */
3323 where = frag - frag_now->fr_literal;
3324 fix_new_exp (frag_now, where, 2,
3325 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3327 bfd_putl16 ((bfd_vma) bin, frag);
3329 else if (*l1 == '$')
3331 as_bad (_("instruction requires label sans '$'"));
3335 ("instruction requires label or value in range -511:512"));
3336 dwarf2_emit_insn (insn_length);
3341 as_bad (_("instruction requires label"));
3346 case 4: /* Extended jumps. */
3347 if (!msp430_enable_polys)
3349 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3353 line = extract_operand (line, l1, sizeof (l1));
3359 /* Ignore absolute addressing. make it PC relative anyway. */
3360 if (*m == '#' || *m == '$')
3363 parse_exp (m, & exp);
3364 if (exp.X_op == O_symbol)
3366 /* Relaxation required. */
3367 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3369 if (target_is_430x ())
3370 rc = msp430x_rcodes[opcode->insn_opnumb];
3372 /* The parameter to dwarf2_emit_insn is actually the offset to
3373 the start of the insn from the fix piece of instruction that
3374 was emitted. Since next fragments may have variable size we
3375 tie debug info to the beginning of the instruction. */
3377 frag = frag_more (8);
3378 dwarf2_emit_insn (0);
3379 bfd_putl16 ((bfd_vma) rc.sop, frag);
3380 frag = frag_variant (rs_machine_dependent, 8, 2,
3382 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3384 0, /* Offset is zero if jump dist less than 1K. */
3390 as_bad (_("instruction requires label"));
3393 case 5: /* Emulated extended branches. */
3394 if (!msp430_enable_polys)
3396 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3399 line = extract_operand (line, l1, sizeof (l1));
3405 /* Ignore absolute addressing. make it PC relative anyway. */
3406 if (*m == '#' || *m == '$')
3409 parse_exp (m, & exp);
3410 if (exp.X_op == O_symbol)
3412 /* Relaxation required. */
3413 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3415 if (target_is_430x ())
3416 hc = msp430x_hcodes[opcode->insn_opnumb];
3419 frag = frag_more (8);
3420 dwarf2_emit_insn (0);
3421 bfd_putl16 ((bfd_vma) hc.op0, frag);
3422 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3424 frag = frag_variant (rs_machine_dependent, 8, 2,
3425 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3427 0, /* Offset is zero if jump dist less than 1K. */
3433 as_bad (_("instruction requires label"));
3437 as_bad (_("Illegal instruction or not implemented opcode."));
3440 input_line_pointer = line;
3445 md_assemble (char * str)
3447 struct msp430_opcode_s * opcode;
3451 str = skip_space (str); /* Skip leading spaces. */
3452 str = extract_cmd (str, cmd, sizeof (cmd));
3454 while (cmd[i] && i < sizeof (cmd))
3456 char a = TOLOWER (cmd[i]);
3463 as_bad (_("can't find opcode "));
3467 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3471 as_bad (_("unknown opcode `%s'"), cmd);
3476 char *__t = input_line_pointer;
3478 msp430_operands (opcode, str);
3479 input_line_pointer = __t;
3483 /* GAS will call this function for each section at the end of the assembly,
3484 to permit the CPU backend to adjust the alignment of a section. */
3487 md_section_align (asection * seg, valueT addr)
3489 int align = bfd_get_section_alignment (stdoutput, seg);
3491 return ((addr + (1 << align) - 1) & (-1 << align));
3494 /* If you define this macro, it should return the offset between the
3495 address of a PC relative fixup and the position from which the PC
3496 relative adjustment should be made. On many processors, the base
3497 of a PC relative instruction is the next instruction, so this
3498 macro would return the length of an instruction. */
3501 md_pcrel_from_section (fixS * fixp, segT sec)
3503 if (fixp->fx_addsy != (symbolS *) NULL
3504 && (!S_IS_DEFINED (fixp->fx_addsy)
3505 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3508 return fixp->fx_frag->fr_address + fixp->fx_where;
3511 /* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3512 Now it handles the situation when relocations
3513 have to be passed to linker. */
3515 msp430_force_relocation_local (fixS *fixp)
3517 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3521 if (msp430_enable_polys
3522 && !msp430_enable_relax)
3525 return (!fixp->fx_pcrel
3526 || generic_force_reloc (fixp));
3530 /* GAS will call this for each fixup. It should store the correct
3531 value in the object file. */
3533 md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3535 unsigned char * where;
3539 if (fixp->fx_addsy == (symbolS *) NULL)
3544 else if (fixp->fx_pcrel)
3546 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3548 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3550 /* FIXME: We can appear here only in case if we perform a pc
3551 relative jump to the label which is i) global, ii) locally
3552 defined or this is a jump to an absolute symbol.
3553 If this is an absolute symbol -- everything is OK.
3554 If this is a global label, we've got a symbol value defined
3556 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3557 from this section start
3558 2. *valuep will contain the real offset from jump insn to the
3560 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3561 will be incorrect. Therefore remove s_get_value. */
3562 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3570 value = fixp->fx_offset;
3572 if (fixp->fx_subsy != (symbolS *) NULL)
3574 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3576 value -= S_GET_VALUE (fixp->fx_subsy);
3582 fixp->fx_no_overflow = 1;
3584 /* If polymorphs are enabled and relax disabled.
3585 do not kill any relocs and pass them to linker. */
3586 if (msp430_enable_polys
3587 && !msp430_enable_relax)
3589 if (!fixp->fx_addsy || (fixp->fx_addsy
3590 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
3591 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3598 /* Fetch the instruction, insert the fully resolved operand
3599 value, and stuff the instruction back again. */
3600 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3602 insn = bfd_getl16 (where);
3604 switch (fixp->fx_r_type)
3606 case BFD_RELOC_MSP430_10_PCREL:
3608 as_bad_where (fixp->fx_file, fixp->fx_line,
3609 _("odd address operand: %ld"), value);
3611 /* Jumps are in words. */
3613 --value; /* Correct PC. */
3615 if (value < -512 || value > 511)
3616 as_bad_where (fixp->fx_file, fixp->fx_line,
3617 _("operand out of range: %ld"), value);
3619 value &= 0x3ff; /* get rid of extended sign */
3620 bfd_putl16 ((bfd_vma) (value | insn), where);
3623 case BFD_RELOC_MSP430X_PCR16:
3624 case BFD_RELOC_MSP430_RL_PCREL:
3625 case BFD_RELOC_MSP430_16_PCREL:
3627 as_bad_where (fixp->fx_file, fixp->fx_line,
3628 _("odd address operand: %ld"), value);
3631 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3632 /* Nothing to be corrected here. */
3633 if (value < -32768 || value > 65536)
3634 as_bad_where (fixp->fx_file, fixp->fx_line,
3635 _("operand out of range: %ld"), value);
3638 case BFD_RELOC_MSP430X_ABS16:
3639 case BFD_RELOC_MSP430_16:
3641 case BFD_RELOC_MSP430_16_BYTE:
3642 value &= 0xffff; /* Get rid of extended sign. */
3643 bfd_putl16 ((bfd_vma) value, where);
3647 bfd_putl16 ((bfd_vma) value, where);
3650 case BFD_RELOC_MSP430_ABS8:
3652 bfd_put_8 (NULL, (bfd_vma) value, where);
3655 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3656 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3657 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3659 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3662 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3663 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3665 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3668 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3669 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3671 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3674 case BFD_RELOC_MSP430X_PCR20_CALL:
3675 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3677 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3680 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3681 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3682 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3684 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3687 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3688 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3690 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3693 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3694 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3696 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3700 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3701 fixp->fx_line, fixp->fx_r_type);
3707 fixp->fx_addnumber = value;
3712 S_IS_GAS_LOCAL (symbolS * s)
3719 name = S_GET_NAME (s);
3720 len = strlen (name) - 1;
3722 return name[len] == 1 || name[len] == 2;
3725 /* GAS will call this to generate a reloc, passing the resulting reloc
3726 to `bfd_install_relocation'. This currently works poorly, as
3727 `bfd_install_relocation' often does the wrong thing, and instances of
3728 `tc_gen_reloc' have been written to work around the problems, which
3729 in turns makes it difficult to fix `bfd_install_relocation'. */
3731 /* If while processing a fixup, a reloc really needs to be created
3732 then it is done here. */
3735 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
3737 static arelent * no_relocs = NULL;
3738 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
3741 reloc = xmalloc (sizeof (arelent));
3742 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3743 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3745 if (reloc->howto == (reloc_howto_type *) NULL)
3747 as_bad_where (fixp->fx_file, fixp->fx_line,
3748 _("reloc %d not supported by object file format"),
3749 (int) fixp->fx_r_type);
3758 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3760 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
3761 fixp->fx_subsy = NULL;
3764 if (fixp->fx_addsy && fixp->fx_subsy)
3766 asection *asec, *ssec;
3768 asec = S_GET_SEGMENT (fixp->fx_addsy);
3769 ssec = S_GET_SEGMENT (fixp->fx_subsy);
3771 /* If we have a difference between two different, non-absolute symbols
3772 we must generate two relocs (one for each symbol) and allow the
3773 linker to resolve them - relaxation may change the distances between
3774 symbols, even local symbols defined in the same section.
3776 Unfortunately we cannot do this with assembler generated local labels
3777 because there can be multiple incarnations of the same label, with
3778 exactly the same name, in any given section and the linker will have
3779 no way to identify the correct one. Instead we just have to hope
3780 that no relaxtion will occur between the local label and the other
3781 symbol in the expression.
3783 Similarly we have to compute differences between symbols in the .eh_frame
3784 section as the linker is not smart enough to apply relocations there
3785 before attempting to process it. */
3786 if ((ssec != absolute_section || asec != absolute_section)
3787 && (fixp->fx_addsy != fixp->fx_subsy)
3788 && strcmp (ssec->name, ".eh_frame") != 0
3789 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
3790 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
3792 arelent * reloc2 = xmalloc (sizeof * reloc);
3797 reloc2->address = reloc->address;
3798 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
3799 BFD_RELOC_MSP430_SYM_DIFF);
3800 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
3802 if (ssec == absolute_section)
3803 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3806 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3807 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
3810 reloc->addend = fixp->fx_offset;
3811 if (asec == absolute_section)
3813 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
3814 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3818 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3819 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3828 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3830 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
3831 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
3833 switch (fixp->fx_r_type)
3836 md_number_to_chars (fixpos, reloc->addend, 1);
3840 md_number_to_chars (fixpos, reloc->addend, 2);
3844 md_number_to_chars (fixpos, reloc->addend, 3);
3848 md_number_to_chars (fixpos, reloc->addend, 4);
3853 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
3864 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
3865 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3867 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
3868 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
3870 md_number_to_chars (fixpos, amount, 2);
3875 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
3876 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3877 reloc->addend = fixp->fx_offset;
3879 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3880 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3881 reloc->address = fixp->fx_offset;
3888 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
3889 asection * segment_type ATTRIBUTE_UNUSED)
3891 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
3893 /* This is a jump -> pcrel mode. Nothing to do much here.
3894 Return value == 2. */
3896 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
3898 else if (fragP->fr_symbol)
3900 /* Its got a segment, but its not ours. Even if fr_symbol is in
3901 an absolute segment, we don't know a displacement until we link
3902 object files. So it will always be long. This also applies to
3903 labels in a subsegment of current. Liker may relax it to short
3904 jump later. Return value == 8. */
3906 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
3910 /* We know the abs value. may be it is a jump to fixed address.
3911 Impossible in our case, cause all constants already handled. */
3913 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
3916 return md_relax_table[fragP->fr_subtype].rlx_length;
3920 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
3921 asection * sec ATTRIBUTE_UNUSED,
3927 struct rcodes_s * cc = NULL;
3928 struct hcodes_s * hc = NULL;
3930 switch (fragP->fr_subtype)
3932 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
3933 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
3934 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
3935 /* We do not have to convert anything here.
3936 Just apply a fix. */
3937 rela = BFD_RELOC_MSP430_10_PCREL;
3940 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
3941 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
3942 /* Convert uncond branch jmp lab -> br lab. */
3943 if (target_is_430x ())
3944 cc = msp430x_rcodes + 7;
3946 cc = msp430_rcodes + 7;
3947 where = fragP->fr_literal + fragP->fr_fix;
3948 bfd_putl16 (cc->lop0, where);
3949 rela = BFD_RELOC_MSP430_RL_PCREL;
3953 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
3954 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
3956 /* Other simple branches. */
3957 int insn = bfd_getl16 (fragP->fr_opcode);
3960 /* Find actual instruction. */
3961 if (target_is_430x ())
3963 for (i = 0; i < 7 && !cc; i++)
3964 if (msp430x_rcodes[i].sop == insn)
3965 cc = msp430x_rcodes + i;
3969 for (i = 0; i < 7 && !cc; i++)
3970 if (msp430_rcodes[i].sop == insn)
3971 cc = & msp430_rcodes[i];
3974 if (!cc || !cc->name)
3975 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
3976 __FUNCTION__, (long) insn);
3977 where = fragP->fr_literal + fragP->fr_fix;
3978 bfd_putl16 (cc->lop0, where);
3979 bfd_putl16 (cc->lop1, where + 2);
3980 rela = BFD_RELOC_MSP430_RL_PCREL;
3985 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
3986 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
3987 if (target_is_430x ())
3988 cc = msp430x_rcodes + 6;
3990 cc = msp430_rcodes + 6;
3991 where = fragP->fr_literal + fragP->fr_fix;
3992 bfd_putl16 (cc->lop0, where);
3993 bfd_putl16 (cc->lop1, where + 2);
3994 bfd_putl16 (cc->lop2, where + 4);
3995 rela = BFD_RELOC_MSP430_RL_PCREL;
3999 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4001 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4004 if (target_is_430x ())
4006 for (i = 0; i < 4 && !hc; i++)
4007 if (msp430x_hcodes[i].op1 == insn)
4008 hc = msp430x_hcodes + i;
4012 for (i = 0; i < 4 && !hc; i++)
4013 if (msp430_hcodes[i].op1 == insn)
4014 hc = &msp430_hcodes[i];
4016 if (!hc || !hc->name)
4017 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4018 __FUNCTION__, (long) insn);
4019 rela = BFD_RELOC_MSP430_10_PCREL;
4020 /* Apply a fix for a first label if necessary.
4021 another fix will be applied to the next word of insn anyway. */
4023 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4024 fragP->fr_offset, TRUE, rela);
4030 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4031 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4033 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4036 if (target_is_430x ())
4038 for (i = 0; i < 4 && !hc; i++)
4039 if (msp430x_hcodes[i].op1 == insn)
4040 hc = msp430x_hcodes + i;
4044 for (i = 0; i < 4 && !hc; i++)
4045 if (msp430_hcodes[i].op1 == insn)
4046 hc = & msp430_hcodes[i];
4048 if (!hc || !hc->name)
4049 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4050 __FUNCTION__, (long) insn);
4051 rela = BFD_RELOC_MSP430_RL_PCREL;
4052 where = fragP->fr_literal + fragP->fr_fix;
4053 bfd_putl16 (hc->lop0, where);
4054 bfd_putl16 (hc->lop1, where + 2);
4055 bfd_putl16 (hc->lop2, where + 4);
4061 as_fatal (_("internal inconsistency problem in %s: %lx"),
4062 __FUNCTION__, (long) fragP->fr_subtype);
4066 /* Now apply fix. */
4067 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4068 fragP->fr_offset, TRUE, rela);
4069 /* Just fixed 2 bytes. */
4073 /* Relax fragment. Mostly stolen from hc11 and mcore
4074 which arches I think I know. */
4077 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4078 long stretch ATTRIBUTE_UNUSED)
4083 const relax_typeS *this_type;
4084 const relax_typeS *start_type;
4085 relax_substateT next_state;
4086 relax_substateT this_state;
4087 const relax_typeS *table = md_relax_table;
4089 /* Nothing to be done if the frag has already max size. */
4090 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4091 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4094 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4096 symbolP = fragP->fr_symbol;
4097 if (symbol_resolved_p (symbolP))
4098 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4100 /* We know the offset. calculate a distance. */
4101 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4104 if (!msp430_enable_relax)
4106 /* Relaxation is not enabled. So, make all jump as long ones
4107 by setting 'aim' to quite high value. */
4111 this_state = fragP->fr_subtype;
4112 start_type = this_type = table + this_state;
4116 /* Look backwards. */
4117 for (next_state = this_type->rlx_more; next_state;)
4118 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4122 /* Grow to next state. */
4123 this_state = next_state;
4124 this_type = table + this_state;
4125 next_state = this_type->rlx_more;
4130 /* Look forwards. */
4131 for (next_state = this_type->rlx_more; next_state;)
4132 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4136 /* Grow to next state. */
4137 this_state = next_state;
4138 this_type = table + this_state;
4139 next_state = this_type->rlx_more;
4143 growth = this_type->rlx_length - start_type->rlx_length;
4145 fragP->fr_subtype = this_state;
4149 /* Return FALSE if the fixup in fixp should be left alone and not
4150 adjusted. We return FALSE here so that linker relaxation will
4154 msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4156 /* If the symbol is in a non-code section then it should be OK. */
4158 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4164 /* Set the contents of the .MSP430.attributes section. */
4167 msp430_md_end (void)
4169 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4170 target_is_430x () ? 2 : 1);
4172 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4173 large_model ? 2 : 1);
4175 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4176 large_model ? 2 : 1);
4179 /* Returns FALSE if there is a msp430 specific reason why the
4180 subtraction of two same-section symbols cannot be computed by
4184 msp430_allow_local_subtract (expressionS * left,
4185 expressionS * right,
4188 /* If the symbols are not in a code section then they are OK. */
4189 if ((section->flags & SEC_CODE) == 0)
4192 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4195 if (left->X_add_symbol == right->X_add_symbol)
4198 /* We have to assume that there may be instructions between the
4199 two symbols and that relaxation may increase the distance between