Properly check --enable-compressed-debug-sections={yes,all}
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
... / ...
CommitLineData
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
3 Copyright (C) 2002-2015 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
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)
11 any later version.
12
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.
17
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. */
22
23#include "as.h"
24#include <limits.h>
25#define PUSH_1X_WORKAROUND
26#include "subsegs.h"
27#include "opcode/msp430.h"
28#include "safe-ctype.h"
29#include "dwarf2dbg.h"
30#include "elf/msp430.h"
31#include "libiberty.h"
32
33/* We will disable polymorphs by default because it is dangerous.
34 The potential problem here is the following: assume we got the
35 following code:
36
37 jump .l1
38 nop
39 jump subroutine ; external symbol
40 .l1:
41 nop
42 ret
43
44 In case of assembly time relaxation we'll get:
45 0: jmp .l1 <.text +0x08> (reloc deleted)
46 2: nop
47 4: br subroutine
48 .l1:
49 8: nop
50 10: ret
51
52 If the 'subroutine' is within +-1024 bytes range then linker
53 will produce:
54 0: jmp .text +0x08
55 2: nop
56 4: jmp subroutine
57 .l1:
58 6: nop
59 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
60
61 The workaround is the following:
62 1. Declare global var enable_polymorphs which set to 1 via option -mp.
63 2. Declare global var enable_relax which set to 1 via option -mQ.
64
65 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
66 do not delete any relocs and leave them for linker.
67
68 If relax is enabled, relax at assembly time and kill relocs as necessary. */
69
70int msp430_enable_relax;
71int msp430_enable_polys;
72
73/* Set linkrelax here to avoid fixups in most sections. */
74int linkrelax = 1;
75
76/* GCC uses the some condition codes which we'll
77 implement as new polymorph instructions.
78
79 COND EXPL SHORT JUMP LONG JUMP
80 ===============================================
81 eq == jeq jne +4; br lab
82 ne != jne jeq +4; br lab
83
84 ltn honours no-overflow flag
85 ltn < jn jn +2; jmp +4; br lab
86
87 lt < jl jge +4; br lab
88 ltu < jlo lhs +4; br lab
89 le <= see below
90 leu <= see below
91
92 gt > see below
93 gtu > see below
94 ge >= jge jl +4; br lab
95 geu >= jhs jlo +4; br lab
96 ===============================================
97
98 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
99 beq,bne,blt,bltn,bltu,bge,bgeu
100 'u' means unsigned compares
101
102 Also, we add 'jump' instruction:
103 jump UNCOND -> jmp br lab
104
105 They will have fmt == 4, and insn_opnumb == number of instruction. */
106
107struct rcodes_s
108{
109 char * name;
110 int index; /* Corresponding insn_opnumb. */
111 int sop; /* Opcode if jump length is short. */
112 long lpos; /* Label position. */
113 long lop0; /* Opcode 1 _word_ (16 bits). */
114 long lop1; /* Opcode second word. */
115 long lop2; /* Opcode third word. */
116};
117
118#define MSP430_RLC(n,i,sop,o1) \
119 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
120
121static struct rcodes_s msp430_rcodes[] =
122{
123 MSP430_RLC (beq, 0, 0x2400, 0x2000),
124 MSP430_RLC (bne, 1, 0x2000, 0x2400),
125 MSP430_RLC (blt, 2, 0x3800, 0x3400),
126 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
127 MSP430_RLC (bge, 4, 0x3400, 0x3800),
128 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
129 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
130 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
131 {0,0,0,0,0,0,0}
132};
133
134#undef MSP430_RLC
135#define MSP430_RLC(n,i,sop,o1) \
136 {#n, i, sop, 2, (o1 + 2), 0x0030, 0}
137
138static struct rcodes_s msp430x_rcodes[] =
139{
140 MSP430_RLC (beq, 0, 0x2400, 0x2000),
141 MSP430_RLC (bne, 1, 0x2000, 0x2400),
142 MSP430_RLC (blt, 2, 0x3800, 0x3400),
143 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
144 MSP430_RLC (bge, 4, 0x3400, 0x3800),
145 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
146 {"bltn", 6, 0x3000, 3, 0x0030 + 1, 0x3c00 + 2, 0x3000},
147 {"jump", 7, 0x3c00, 1, 0x0030, 0, 0},
148 {0,0,0,0,0,0,0}
149};
150#undef MSP430_RLC
151
152/* More difficult than above and they have format 5.
153
154 COND EXPL SHORT LONG
155 =================================================================
156 gt > jeq +2; jge label jeq +6; jl +4; br label
157 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
158 leu <= jeq label; jlo label jeq +2; jhs +4; br label
159 le <= jeq label; jl label jeq +2; jge +4; br label
160 ================================================================= */
161
162struct hcodes_s
163{
164 char * name;
165 int index; /* Corresponding insn_opnumb. */
166 int tlab; /* Number of labels in short mode. */
167 int op0; /* Opcode for first word of short jump. */
168 int op1; /* Opcode for second word of short jump. */
169 int lop0; /* Opcodes for long jump mode. */
170 int lop1;
171 int lop2;
172};
173
174static struct hcodes_s msp430_hcodes[] =
175{
176 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
177 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
178 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
179 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
180 {0,0,0,0,0,0,0,0}
181};
182
183static struct hcodes_s msp430x_hcodes[] =
184{
185 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x0030 },
186 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x0030 },
187 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x0030 },
188 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x0030 },
189 {0,0,0,0,0,0,0,0}
190};
191
192const char comment_chars[] = ";";
193const char line_comment_chars[] = "#";
194const char line_separator_chars[] = "{";
195const char EXP_CHARS[] = "eE";
196const char FLT_CHARS[] = "dD";
197
198/* Handle long expressions. */
199extern LITTLENUM_TYPE generic_bignum[];
200
201static struct hash_control *msp430_hash;
202
203/* Relaxations. */
204#define STATE_UNCOND_BRANCH 1 /* jump */
205#define STATE_NOOV_BRANCH 3 /* bltn */
206#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
207#define STATE_EMUL_BRANCH 4
208
209#define CNRL 2
210#define CUBL 4
211#define CNOL 8
212#define CSBL 6
213#define CEBL 4
214
215/* Length. */
216#define STATE_BITS10 1 /* wild guess. short jump */
217#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
218#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
219
220#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
221#define RELAX_STATE(s) ((s) & 3)
222#define RELAX_LEN(s) ((s) >> 2)
223#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
224
225relax_typeS md_relax_table[] =
226{
227 /* Unused. */
228 {1, 1, 0, 0},
229 {1, 1, 0, 0},
230 {1, 1, 0, 0},
231 {1, 1, 0, 0},
232
233 /* Unconditional jump. */
234 {1, 1, 8, 5},
235 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
236 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
237 {1, 1, CUBL, 0}, /* state undef */
238
239 /* Simple branches. */
240 {0, 0, 8, 9},
241 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
242 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
243 {1, 1, CSBL, 0},
244
245 /* blt no overflow branch. */
246 {1, 1, 8, 13},
247 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
248 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
249 {1, 1, CNOL, 0},
250
251 /* Emulated branches. */
252 {1, 1, 8, 17},
253 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
254 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
255 {1, 1, CNOL, 0}
256};
257
258
259#define MAX_OP_LEN 4096
260
261typedef enum msp_isa
262{
263 MSP_ISA_430,
264 MSP_ISA_430X,
265 MSP_ISA_430Xv2
266} msp_isa;
267
268static enum msp_isa selected_isa = MSP_ISA_430Xv2;
269
270static inline bfd_boolean
271target_is_430x (void)
272{
273 return selected_isa >= MSP_ISA_430X;
274}
275
276static inline bfd_boolean
277target_is_430xv2 (void)
278{
279 return selected_isa == MSP_ISA_430Xv2;
280}
281
282/* Generate an absolute 16-bit relocation.
283 For the 430X we generate a relocation without linker range checking
284 if the value is being used in an extended (ie 20-bit) instruction,
285 otherwise if have a shifted expression we use a HI reloc.
286 For the 430 we generate a relocation without assembler range checking
287 if we are handling an immediate value or a byte-width instruction. */
288
289#undef CHECK_RELOC_MSP430
290#define CHECK_RELOC_MSP430(OP) \
291 (target_is_430x () \
292 ? (extended_op \
293 ? BFD_RELOC_16 \
294 : ((OP).vshift == 1) \
295 ? BFD_RELOC_MSP430_ABS_HI16 \
296 : BFD_RELOC_MSP430X_ABS16) \
297 : ((imm_op || byte_op) \
298 ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16))
299
300/* Generate a 16-bit pc-relative relocation.
301 For the 430X we generate a relocation without linkwer range checking.
302 For the 430 we generate a relocation without assembler range checking
303 if we are handling an immediate value or a byte-width instruction. */
304#undef CHECK_RELOC_MSP430_PCREL
305#define CHECK_RELOC_MSP430_PCREL \
306 (target_is_430x () \
307 ? BFD_RELOC_MSP430X_PCR16 \
308 : (imm_op || byte_op) \
309 ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
310
311/* Profiling capability:
312 It is a performance hit to use gcc's profiling approach for this tiny target.
313 Even more -- jtag hardware facility does not perform any profiling functions.
314 However we've got gdb's built-in simulator where we can do anything.
315 Therefore my suggestion is:
316
317 We define new section ".profiler" which holds all profiling information.
318 We define new pseudo operation .profiler which will instruct assembler to
319 add new profile entry to the object file. Profile should take place at the
320 present address.
321
322 Pseudo-op format:
323
324 .profiler flags,function_to_profile [, cycle_corrector, extra]
325
326 where 'flags' is a combination of the following chars:
327 s - function Start
328 x - function eXit
329 i - function is in Init section
330 f - function is in Fini section
331 l - Library call
332 c - libC standard call
333 d - stack value Demand (saved at run-time in simulator)
334 I - Interrupt service routine
335 P - Prologue start
336 p - Prologue end
337 E - Epilogue start
338 e - Epilogue end
339 j - long Jump/ sjlj unwind
340 a - an Arbitrary code fragment
341 t - exTra parameter saved (constant value like frame size)
342 '""' optional: "sil" == sil
343
344 function_to_profile - function's address
345 cycle_corrector - a value which should be added to the cycle
346 counter, zero if omitted
347 extra - some extra parameter, zero if omitted.
348
349 For example:
350 ------------------------------
351 .global fxx
352 .type fxx,@function
353 fxx:
354 .LFrameOffset_fxx=0x08
355 .profiler "scdP", fxx ; function entry.
356 ; we also demand stack value to be displayed
357 push r11
358 push r10
359 push r9
360 push r8
361 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
362 ; (this is a prologue end)
363 ; note, that spare var filled with the frame size
364 mov r15,r8
365 ....
366 .profiler cdE,fxx ; check stack
367 pop r8
368 pop r9
369 pop r10
370 pop r11
371 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
372 ret ; cause 'ret' insn takes 3 cycles
373 -------------------------------
374
375 This profiling approach does not produce any overhead and
376 absolutely harmless.
377 So, even profiled code can be uploaded to the MCU. */
378#define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
379#define MSP430_PROFILER_FLAG_EXIT 2 /* x */
380#define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
381#define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
382#define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
383#define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
384#define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
385#define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
386#define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
387#define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
388#define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
389#define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
390#define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
391#define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
392#define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
393#define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
394
395static int
396pow2value (int y)
397{
398 int n = 0;
399 unsigned int x;
400
401 x = y;
402
403 if (!x)
404 return 1;
405
406 for (; x; x = x >> 1)
407 if (x & 1)
408 n++;
409
410 return n == 1;
411}
412
413/* Parse ordinary expression. */
414
415static char *
416parse_exp (char * s, expressionS * op)
417{
418 input_line_pointer = s;
419 expression (op);
420 if (op->X_op == O_absent)
421 as_bad (_("missing operand"));
422 return input_line_pointer;
423}
424
425
426/* Delete spaces from s: X ( r 1 2) => X(r12). */
427
428static void
429del_spaces (char * s)
430{
431 while (*s)
432 {
433 if (ISSPACE (*s))
434 {
435 char *m = s + 1;
436
437 while (ISSPACE (*m) && *m)
438 m++;
439 memmove (s, m, strlen (m) + 1);
440 }
441 else
442 s++;
443 }
444}
445
446static inline char *
447skip_space (char * s)
448{
449 while (ISSPACE (*s))
450 ++s;
451 return s;
452}
453
454/* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
455
456static char *
457extract_operand (char * from, char * to, int limit)
458{
459 int size = 0;
460
461 /* Drop leading whitespace. */
462 from = skip_space (from);
463
464 while (size < limit && *from)
465 {
466 *(to + size) = *from;
467 if (*from == ',' || *from == ';' || *from == '\n')
468 break;
469 from++;
470 size++;
471 }
472
473 *(to + size) = 0;
474 del_spaces (to);
475
476 from++;
477
478 return from;
479}
480
481static void
482msp430_profiler (int dummy ATTRIBUTE_UNUSED)
483{
484 char buffer[1024];
485 char f[32];
486 char * str = buffer;
487 char * flags = f;
488 int p_flags = 0;
489 char * halt;
490 int ops = 0;
491 int left;
492 char * s;
493 segT seg;
494 int subseg;
495 char * end = 0;
496 expressionS exp;
497 expressionS exp1;
498
499 s = input_line_pointer;
500 end = input_line_pointer;
501
502 while (*end && *end != '\n')
503 end++;
504
505 while (*s && *s != '\n')
506 {
507 if (*s == ',')
508 ops++;
509 s++;
510 }
511
512 left = 3 - ops;
513
514 if (ops < 1)
515 {
516 as_bad (_(".profiler pseudo requires at least two operands."));
517 input_line_pointer = end;
518 return;
519 }
520
521 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
522
523 while (*flags)
524 {
525 switch (*flags)
526 {
527 case '"':
528 break;
529 case 'a':
530 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
531 break;
532 case 'j':
533 p_flags |= MSP430_PROFILER_FLAG_JUMP;
534 break;
535 case 'P':
536 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
537 break;
538 case 'p':
539 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
540 break;
541 case 'E':
542 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
543 break;
544 case 'e':
545 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
546 break;
547 case 's':
548 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
549 break;
550 case 'x':
551 p_flags |= MSP430_PROFILER_FLAG_EXIT;
552 break;
553 case 'i':
554 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
555 break;
556 case 'f':
557 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
558 break;
559 case 'l':
560 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
561 break;
562 case 'c':
563 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
564 break;
565 case 'd':
566 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
567 break;
568 case 'I':
569 p_flags |= MSP430_PROFILER_FLAG_ISR;
570 break;
571 case 't':
572 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
573 break;
574 default:
575 as_warn (_("unknown profiling flag - ignored."));
576 break;
577 }
578 flags++;
579 }
580
581 if (p_flags
582 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
583 | MSP430_PROFILER_FLAG_EXIT))
584 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
585 | MSP430_PROFILER_FLAG_PROLEND
586 | MSP430_PROFILER_FLAG_EPISTART
587 | MSP430_PROFILER_FLAG_EPIEND))
588 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
589 | MSP430_PROFILER_FLAG_FINISECT))))
590 {
591 as_bad (_("ambiguous flags combination - '.profiler' directive ignored."));
592 input_line_pointer = end;
593 return;
594 }
595
596 /* Generate temp symbol which denotes current location. */
597 if (now_seg == absolute_section) /* Paranoia ? */
598 {
599 exp1.X_op = O_constant;
600 exp1.X_add_number = abs_section_offset;
601 as_warn (_("profiling in absolute section?"));
602 }
603 else
604 {
605 exp1.X_op = O_symbol;
606 exp1.X_add_symbol = symbol_temp_new_now ();
607 exp1.X_add_number = 0;
608 }
609
610 /* Generate a symbol which holds flags value. */
611 exp.X_op = O_constant;
612 exp.X_add_number = p_flags;
613
614 /* Save current section. */
615 seg = now_seg;
616 subseg = now_subseg;
617
618 /* Now go to .profiler section. */
619 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
620
621 /* Save flags. */
622 emit_expr (& exp, 2);
623
624 /* Save label value. */
625 emit_expr (& exp1, 2);
626
627 while (ops--)
628 {
629 /* Now get profiling info. */
630 halt = extract_operand (input_line_pointer, str, 1024);
631 /* Process like ".word xxx" directive. */
632 parse_exp (str, & exp);
633 emit_expr (& exp, 2);
634 input_line_pointer = halt;
635 }
636
637 /* Fill the rest with zeros. */
638 exp.X_op = O_constant;
639 exp.X_add_number = 0;
640 while (left--)
641 emit_expr (& exp, 2);
642
643 /* Return to current section. */
644 subseg_set (seg, subseg);
645}
646
647static char *
648extract_word (char * from, char * to, int limit)
649{
650 char *op_end;
651 int size = 0;
652
653 /* Drop leading whitespace. */
654 from = skip_space (from);
655 *to = 0;
656
657 /* Find the op code end. */
658 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
659 {
660 to[size++] = *op_end++;
661 if (size + 1 >= limit)
662 break;
663 }
664
665 to[size] = 0;
666 return op_end;
667}
668
669#define OPTION_MMCU 'm'
670#define OPTION_RELAX 'Q'
671#define OPTION_POLYMORPHS 'P'
672#define OPTION_LARGE 'l'
673static bfd_boolean large_model = FALSE;
674#define OPTION_NO_INTR_NOPS 'N'
675#define OPTION_INTR_NOPS 'n'
676static bfd_boolean gen_interrupt_nops = FALSE;
677#define OPTION_WARN_INTR_NOPS 'y'
678#define OPTION_NO_WARN_INTR_NOPS 'Y'
679static bfd_boolean warn_interrupt_nops = TRUE;
680#define OPTION_MCPU 'c'
681#define OPTION_MOVE_DATA 'd'
682static bfd_boolean move_data = FALSE;
683
684static void
685msp430_set_arch (int option)
686{
687 char *str = (char *) alloca (32); /* 32 for good measure. */
688
689 input_line_pointer = extract_word (input_line_pointer, str, 32);
690
691 md_parse_option (option, str);
692 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
693 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
694}
695
696/* This is a copy of the same data structure found in gcc/config/msp430/msp430.c
697 Keep these two structures in sync.
698 The data in this structure has been extracted from the devices.csv file
699 released by TI, updated as of 8 October 2015. */
700
701struct msp430_mcu_data
702{
703 const char * name;
704 unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
705 unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
706}
707msp430_mcu_data [] =
708{
709 { "cc430f5123",2,8 },
710 { "cc430f5125",2,8 },
711 { "cc430f5133",2,8 },
712 { "cc430f5135",2,8 },
713 { "cc430f5137",2,8 },
714 { "cc430f5143",2,8 },
715 { "cc430f5145",2,8 },
716 { "cc430f5147",2,8 },
717 { "cc430f6125",2,8 },
718 { "cc430f6126",2,8 },
719 { "cc430f6127",2,8 },
720 { "cc430f6135",2,8 },
721 { "cc430f6137",2,8 },
722 { "cc430f6143",2,8 },
723 { "cc430f6145",2,8 },
724 { "cc430f6147",2,8 },
725 { "msp430afe221",0,2 },
726 { "msp430afe222",0,2 },
727 { "msp430afe223",0,2 },
728 { "msp430afe231",0,2 },
729 { "msp430afe232",0,2 },
730 { "msp430afe233",0,2 },
731 { "msp430afe251",0,2 },
732 { "msp430afe252",0,2 },
733 { "msp430afe253",0,2 },
734 { "msp430bt5190",2,8 },
735 { "msp430c091",0,0 },
736 { "msp430c092",0,0 },
737 { "msp430c111",0,0 },
738 { "msp430c1111",0,0 },
739 { "msp430c112",0,0 },
740 { "msp430c1121",0,0 },
741 { "msp430c1331",0,0 },
742 { "msp430c1351",0,0 },
743 { "msp430c311s",0,0 },
744 { "msp430c312",0,0 },
745 { "msp430c313",0,0 },
746 { "msp430c314",0,0 },
747 { "msp430c315",0,0 },
748 { "msp430c323",0,0 },
749 { "msp430c325",0,0 },
750 { "msp430c336",0,1 },
751 { "msp430c337",0,1 },
752 { "msp430c412",0,0 },
753 { "msp430c413",0,0 },
754 { "msp430cg4616",1,1 },
755 { "msp430cg4617",1,1 },
756 { "msp430cg4618",1,1 },
757 { "msp430cg4619",1,1 },
758 { "msp430e112",0,0 },
759 { "msp430e313",0,0 },
760 { "msp430e315",0,0 },
761 { "msp430e325",0,0 },
762 { "msp430e337",0,1 },
763 { "msp430f110",0,0 },
764 { "msp430f1101",0,0 },
765 { "msp430f1101a",0,0 },
766 { "msp430f1111",0,0 },
767 { "msp430f1111a",0,0 },
768 { "msp430f112",0,0 },
769 { "msp430f1121",0,0 },
770 { "msp430f1121a",0,0 },
771 { "msp430f1122",0,0 },
772 { "msp430f1132",0,0 },
773 { "msp430f122",0,0 },
774 { "msp430f1222",0,0 },
775 { "msp430f123",0,0 },
776 { "msp430f1232",0,0 },
777 { "msp430f133",0,0 },
778 { "msp430f135",0,0 },
779 { "msp430f147",0,1 },
780 { "msp430f1471",0,1 },
781 { "msp430f148",0,1 },
782 { "msp430f1481",0,1 },
783 { "msp430f149",0,1 },
784 { "msp430f1491",0,1 },
785 { "msp430f155",0,0 },
786 { "msp430f156",0,0 },
787 { "msp430f157",0,0 },
788 { "msp430f1610",0,1 },
789 { "msp430f1611",0,1 },
790 { "msp430f1612",0,1 },
791 { "msp430f167",0,1 },
792 { "msp430f168",0,1 },
793 { "msp430f169",0,1 },
794 { "msp430f2001",0,0 },
795 { "msp430f2002",0,0 },
796 { "msp430f2003",0,0 },
797 { "msp430f2011",0,0 },
798 { "msp430f2012",0,0 },
799 { "msp430f2013",0,0 },
800 { "msp430f2101",0,0 },
801 { "msp430f2111",0,0 },
802 { "msp430f2112",0,0 },
803 { "msp430f2121",0,0 },
804 { "msp430f2122",0,0 },
805 { "msp430f2131",0,0 },
806 { "msp430f2132",0,0 },
807 { "msp430f2232",0,0 },
808 { "msp430f2234",0,0 },
809 { "msp430f2252",0,0 },
810 { "msp430f2254",0,0 },
811 { "msp430f2272",0,0 },
812 { "msp430f2274",0,0 },
813 { "msp430f233",0,2 },
814 { "msp430f2330",0,2 },
815 { "msp430f235",0,2 },
816 { "msp430f2350",0,2 },
817 { "msp430f2370",0,2 },
818 { "msp430f2410",0,2 },
819 { "msp430f2416",1,2 },
820 { "msp430f2417",1,2 },
821 { "msp430f2418",1,2 },
822 { "msp430f2419",1,2 },
823 { "msp430f247",0,2 },
824 { "msp430f2471",0,2 },
825 { "msp430f248",0,2 },
826 { "msp430f2481",0,2 },
827 { "msp430f249",0,2 },
828 { "msp430f2491",0,2 },
829 { "msp430f2616",1,2 },
830 { "msp430f2617",1,2 },
831 { "msp430f2618",1,2 },
832 { "msp430f2619",1,2 },
833 { "msp430f412",0,0 },
834 { "msp430f413",0,0 },
835 { "msp430f4132",0,0 },
836 { "msp430f415",0,0 },
837 { "msp430f4152",0,0 },
838 { "msp430f417",0,0 },
839 { "msp430f423",0,1 },
840 { "msp430f423a",0,1 },
841 { "msp430f425",0,1 },
842 { "msp430f4250",0,0 },
843 { "msp430f425a",0,1 },
844 { "msp430f4260",0,0 },
845 { "msp430f427",0,1 },
846 { "msp430f4270",0,0 },
847 { "msp430f427a",0,1 },
848 { "msp430f435",0,0 },
849 { "msp430f4351",0,0 },
850 { "msp430f436",0,0 },
851 { "msp430f4361",0,0 },
852 { "msp430f437",0,0 },
853 { "msp430f4371",0,0 },
854 { "msp430f438",0,0 },
855 { "msp430f439",0,0 },
856 { "msp430f447",0,1 },
857 { "msp430f448",0,1 },
858 { "msp430f4481",0,1 },
859 { "msp430f449",0,1 },
860 { "msp430f4491",0,1 },
861 { "msp430f4616",1,1 },
862 { "msp430f46161",1,1 },
863 { "msp430f4617",1,1 },
864 { "msp430f46171",1,1 },
865 { "msp430f4618",1,1 },
866 { "msp430f46181",1,1 },
867 { "msp430f4619",1,1 },
868 { "msp430f46191",1,1 },
869 { "msp430f47126",1,4 },
870 { "msp430f47127",1,4 },
871 { "msp430f47163",1,4 },
872 { "msp430f47166",1,4 },
873 { "msp430f47167",1,4 },
874 { "msp430f47173",1,4 },
875 { "msp430f47176",1,4 },
876 { "msp430f47177",1,4 },
877 { "msp430f47183",1,4 },
878 { "msp430f47186",1,4 },
879 { "msp430f47187",1,4 },
880 { "msp430f47193",1,4 },
881 { "msp430f47196",1,4 },
882 { "msp430f47197",1,4 },
883 { "msp430f477",0,0 },
884 { "msp430f478",0,0 },
885 { "msp430f4783",0,4 },
886 { "msp430f4784",0,4 },
887 { "msp430f479",0,0 },
888 { "msp430f4793",0,4 },
889 { "msp430f4794",0,4 },
890 { "msp430f5131",2,8 },
891 { "msp430f5132",2,8 },
892 { "msp430f5151",2,8 },
893 { "msp430f5152",2,8 },
894 { "msp430f5171",2,8 },
895 { "msp430f5172",2,8 },
896 { "msp430f5212",2,8 },
897 { "msp430f5213",2,8 },
898 { "msp430f5214",2,8 },
899 { "msp430f5217",2,8 },
900 { "msp430f5218",2,8 },
901 { "msp430f5219",2,8 },
902 { "msp430f5222",2,8 },
903 { "msp430f5223",2,8 },
904 { "msp430f5224",2,8 },
905 { "msp430f5227",2,8 },
906 { "msp430f5228",2,8 },
907 { "msp430f5229",2,8 },
908 { "msp430f5232",2,8 },
909 { "msp430f5234",2,8 },
910 { "msp430f5237",2,8 },
911 { "msp430f5239",2,8 },
912 { "msp430f5242",2,8 },
913 { "msp430f5244",2,8 },
914 { "msp430f5247",2,8 },
915 { "msp430f5249",2,8 },
916 { "msp430f5252",2,8 },
917 { "msp430f5253",2,8 },
918 { "msp430f5254",2,8 },
919 { "msp430f5255",2,8 },
920 { "msp430f5256",2,8 },
921 { "msp430f5257",2,8 },
922 { "msp430f5258",2,8 },
923 { "msp430f5259",2,8 },
924 { "msp430f5304",2,8 },
925 { "msp430f5308",2,8 },
926 { "msp430f5309",2,8 },
927 { "msp430f5310",2,8 },
928 { "msp430f5324",2,8 },
929 { "msp430f5325",2,8 },
930 { "msp430f5326",2,8 },
931 { "msp430f5327",2,8 },
932 { "msp430f5328",2,8 },
933 { "msp430f5329",2,8 },
934 { "msp430f5333",2,8 },
935 { "msp430f5335",2,8 },
936 { "msp430f5336",2,8 },
937 { "msp430f5338",2,8 },
938 { "msp430f5340",2,8 },
939 { "msp430f5341",2,8 },
940 { "msp430f5342",2,8 },
941 { "msp430f5358",2,8 },
942 { "msp430f5359",2,8 },
943 { "msp430f5418",2,8 },
944 { "msp430f5418a",2,8 },
945 { "msp430f5419",2,8 },
946 { "msp430f5419a",2,8 },
947 { "msp430f5435",2,8 },
948 { "msp430f5435a",2,8 },
949 { "msp430f5436",2,8 },
950 { "msp430f5436a",2,8 },
951 { "msp430f5437",2,8 },
952 { "msp430f5437a",2,8 },
953 { "msp430f5438",2,8 },
954 { "msp430f5438a",2,8 },
955 { "msp430f5500",2,8 },
956 { "msp430f5501",2,8 },
957 { "msp430f5502",2,8 },
958 { "msp430f5503",2,8 },
959 { "msp430f5504",2,8 },
960 { "msp430f5505",2,8 },
961 { "msp430f5506",2,8 },
962 { "msp430f5507",2,8 },
963 { "msp430f5508",2,8 },
964 { "msp430f5509",2,8 },
965 { "msp430f5510",2,8 },
966 { "msp430f5513",2,8 },
967 { "msp430f5514",2,8 },
968 { "msp430f5515",2,8 },
969 { "msp430f5517",2,8 },
970 { "msp430f5519",2,8 },
971 { "msp430f5521",2,8 },
972 { "msp430f5522",2,8 },
973 { "msp430f5524",2,8 },
974 { "msp430f5525",2,8 },
975 { "msp430f5526",2,8 },
976 { "msp430f5527",2,8 },
977 { "msp430f5528",2,8 },
978 { "msp430f5529",2,8 },
979 { "msp430f5630",2,8 },
980 { "msp430f5631",2,8 },
981 { "msp430f5632",2,8 },
982 { "msp430f5633",2,8 },
983 { "msp430f5634",2,8 },
984 { "msp430f5635",2,8 },
985 { "msp430f5636",2,8 },
986 { "msp430f5637",2,8 },
987 { "msp430f5638",2,8 },
988 { "msp430f5658",2,8 },
989 { "msp430f5659",2,8 },
990 { "msp430f5xx_6xxgeneric",2,8 },
991 { "msp430f6433",2,8 },
992 { "msp430f6435",2,8 },
993 { "msp430f6436",2,8 },
994 { "msp430f6438",2,8 },
995 { "msp430f6458",2,8 },
996 { "msp430f6459",2,8 },
997 { "msp430f6630",2,8 },
998 { "msp430f6631",2,8 },
999 { "msp430f6632",2,8 },
1000 { "msp430f6633",2,8 },
1001 { "msp430f6634",2,8 },
1002 { "msp430f6635",2,8 },
1003 { "msp430f6636",2,8 },
1004 { "msp430f6637",2,8 },
1005 { "msp430f6638",2,8 },
1006 { "msp430f6658",2,8 },
1007 { "msp430f6659",2,8 },
1008 { "msp430f6720",2,8 },
1009 { "msp430f6720a",2,8 },
1010 { "msp430f6721",2,8 },
1011 { "msp430f6721a",2,8 },
1012 { "msp430f6723",2,8 },
1013 { "msp430f6723a",2,8 },
1014 { "msp430f6724",2,8 },
1015 { "msp430f6724a",2,8 },
1016 { "msp430f6725",2,8 },
1017 { "msp430f6725a",2,8 },
1018 { "msp430f6726",2,8 },
1019 { "msp430f6726a",2,8 },
1020 { "msp430f6730",2,8 },
1021 { "msp430f6730a",2,8 },
1022 { "msp430f6731",2,8 },
1023 { "msp430f6731a",2,8 },
1024 { "msp430f6733",2,8 },
1025 { "msp430f6733a",2,8 },
1026 { "msp430f6734",2,8 },
1027 { "msp430f6734a",2,8 },
1028 { "msp430f6735",2,8 },
1029 { "msp430f6735a",2,8 },
1030 { "msp430f6736",2,8 },
1031 { "msp430f6736a",2,8 },
1032 { "msp430f6745",2,8 },
1033 { "msp430f67451",2,8 },
1034 { "msp430f67451a",2,8 },
1035 { "msp430f6745a",2,8 },
1036 { "msp430f6746",2,8 },
1037 { "msp430f67461",2,8 },
1038 { "msp430f67461a",2,8 },
1039 { "msp430f6746a",2,8 },
1040 { "msp430f6747",2,8 },
1041 { "msp430f67471",2,8 },
1042 { "msp430f67471a",2,8 },
1043 { "msp430f6747a",2,8 },
1044 { "msp430f6748",2,8 },
1045 { "msp430f67481",2,8 },
1046 { "msp430f67481a",2,8 },
1047 { "msp430f6748a",2,8 },
1048 { "msp430f6749",2,8 },
1049 { "msp430f67491",2,8 },
1050 { "msp430f67491a",2,8 },
1051 { "msp430f6749a",2,8 },
1052 { "msp430f67621",2,8 },
1053 { "msp430f67621a",2,8 },
1054 { "msp430f67641",2,8 },
1055 { "msp430f67641a",2,8 },
1056 { "msp430f6765",2,8 },
1057 { "msp430f67651",2,8 },
1058 { "msp430f67651a",2,8 },
1059 { "msp430f6765a",2,8 },
1060 { "msp430f6766",2,8 },
1061 { "msp430f67661",2,8 },
1062 { "msp430f67661a",2,8 },
1063 { "msp430f6766a",2,8 },
1064 { "msp430f6767",2,8 },
1065 { "msp430f67671",2,8 },
1066 { "msp430f67671a",2,8 },
1067 { "msp430f6767a",2,8 },
1068 { "msp430f6768",2,8 },
1069 { "msp430f67681",2,8 },
1070 { "msp430f67681a",2,8 },
1071 { "msp430f6768a",2,8 },
1072 { "msp430f6769",2,8 },
1073 { "msp430f67691",2,8 },
1074 { "msp430f67691a",2,8 },
1075 { "msp430f6769a",2,8 },
1076 { "msp430f6775",2,8 },
1077 { "msp430f67751",2,8 },
1078 { "msp430f67751a",2,8 },
1079 { "msp430f6775a",2,8 },
1080 { "msp430f6776",2,8 },
1081 { "msp430f67761",2,8 },
1082 { "msp430f67761a",2,8 },
1083 { "msp430f6776a",2,8 },
1084 { "msp430f6777",2,8 },
1085 { "msp430f67771",2,8 },
1086 { "msp430f67771a",2,8 },
1087 { "msp430f6777a",2,8 },
1088 { "msp430f6778",2,8 },
1089 { "msp430f67781",2,8 },
1090 { "msp430f67781a",2,8 },
1091 { "msp430f6778a",2,8 },
1092 { "msp430f6779",2,8 },
1093 { "msp430f67791",2,8 },
1094 { "msp430f67791a",2,8 },
1095 { "msp430f6779a",2,8 },
1096 { "msp430fe423",0,0 },
1097 { "msp430fe4232",0,0 },
1098 { "msp430fe423a",0,0 },
1099 { "msp430fe4242",0,0 },
1100 { "msp430fe425",0,0 },
1101 { "msp430fe4252",0,0 },
1102 { "msp430fe425a",0,0 },
1103 { "msp430fe427",0,0 },
1104 { "msp430fe4272",0,0 },
1105 { "msp430fe427a",0,0 },
1106 { "msp430fg4250",0,0 },
1107 { "msp430fg4260",0,0 },
1108 { "msp430fg4270",0,0 },
1109 { "msp430fg437",0,0 },
1110 { "msp430fg438",0,0 },
1111 { "msp430fg439",0,0 },
1112 { "msp430fg4616",1,1 },
1113 { "msp430fg4617",1,1 },
1114 { "msp430fg4618",1,1 },
1115 { "msp430fg4619",1,1 },
1116 { "msp430fg477",0,0 },
1117 { "msp430fg478",0,0 },
1118 { "msp430fg479",0,0 },
1119 { "msp430fg6425",2,8 },
1120 { "msp430fg6426",2,8 },
1121 { "msp430fg6625",2,8 },
1122 { "msp430fg6626",2,8 },
1123 { "msp430fr2032",2,0 },
1124 { "msp430fr2033",2,0 },
1125 { "msp430fr2433",2,8 },
1126 { "msp430fr2xx_4xxgeneric",2,8 },
1127 { "msp430fr4131",2,0 },
1128 { "msp430fr4132",2,0 },
1129 { "msp430fr4133",2,0 },
1130 { "msp430fr5720",2,8 },
1131 { "msp430fr5721",2,8 },
1132 { "msp430fr5722",2,8 },
1133 { "msp430fr5723",2,8 },
1134 { "msp430fr5724",2,8 },
1135 { "msp430fr5725",2,8 },
1136 { "msp430fr5726",2,8 },
1137 { "msp430fr5727",2,8 },
1138 { "msp430fr5728",2,8 },
1139 { "msp430fr5729",2,8 },
1140 { "msp430fr5730",2,8 },
1141 { "msp430fr5731",2,8 },
1142 { "msp430fr5732",2,8 },
1143 { "msp430fr5733",2,8 },
1144 { "msp430fr5734",2,8 },
1145 { "msp430fr5735",2,8 },
1146 { "msp430fr5736",2,8 },
1147 { "msp430fr5737",2,8 },
1148 { "msp430fr5738",2,8 },
1149 { "msp430fr5739",2,8 },
1150 { "msp430fr57xxgeneric",2,8 },
1151 { "msp430fr5847",2,8 },
1152 { "msp430fr58471",2,8 },
1153 { "msp430fr5848",2,8 },
1154 { "msp430fr5849",2,8 },
1155 { "msp430fr5857",2,8 },
1156 { "msp430fr5858",2,8 },
1157 { "msp430fr5859",2,8 },
1158 { "msp430fr5867",2,8 },
1159 { "msp430fr58671",2,8 },
1160 { "msp430fr5868",2,8 },
1161 { "msp430fr5869",2,8 },
1162 { "msp430fr5870",2,8 },
1163 { "msp430fr5872",2,8 },
1164 { "msp430fr58721",2,8 },
1165 { "msp430fr5887",2,8 },
1166 { "msp430fr5888",2,8 },
1167 { "msp430fr5889",2,8 },
1168 { "msp430fr58891",2,8 },
1169 { "msp430fr5922",2,8 },
1170 { "msp430fr59221",2,8 },
1171 { "msp430fr5947",2,8 },
1172 { "msp430fr59471",2,8 },
1173 { "msp430fr5948",2,8 },
1174 { "msp430fr5949",2,8 },
1175 { "msp430fr5957",2,8 },
1176 { "msp430fr5958",2,8 },
1177 { "msp430fr5959",2,8 },
1178 { "msp430fr5967",2,8 },
1179 { "msp430fr5968",2,8 },
1180 { "msp430fr5969",2,8 },
1181 { "msp430fr59691",2,8 },
1182 { "msp430fr5970",2,8 },
1183 { "msp430fr5972",2,8 },
1184 { "msp430fr59721",2,8 },
1185 { "msp430fr5986",2,8 },
1186 { "msp430fr5987",2,8 },
1187 { "msp430fr5988",2,8 },
1188 { "msp430fr5989",2,8 },
1189 { "msp430fr59891",2,8 },
1190 { "msp430fr5xx_6xxgeneric",2,8 },
1191 { "msp430fr6820",2,8 },
1192 { "msp430fr6822",2,8 },
1193 { "msp430fr68221",2,8 },
1194 { "msp430fr6870",2,8 },
1195 { "msp430fr6872",2,8 },
1196 { "msp430fr68721",2,8 },
1197 { "msp430fr6877",2,8 },
1198 { "msp430fr6879",2,8 },
1199 { "msp430fr68791",2,8 },
1200 { "msp430fr6887",2,8 },
1201 { "msp430fr6888",2,8 },
1202 { "msp430fr6889",2,8 },
1203 { "msp430fr68891",2,8 },
1204 { "msp430fr6920",2,8 },
1205 { "msp430fr6922",2,8 },
1206 { "msp430fr69221",2,8 },
1207 { "msp430fr6927",2,8 },
1208 { "msp430fr69271",2,8 },
1209 { "msp430fr6928",2,8 },
1210 { "msp430fr6970",2,8 },
1211 { "msp430fr6972",2,8 },
1212 { "msp430fr69721",2,8 },
1213 { "msp430fr6977",2,8 },
1214 { "msp430fr6979",2,8 },
1215 { "msp430fr69791",2,8 },
1216 { "msp430fr6987",2,8 },
1217 { "msp430fr6988",2,8 },
1218 { "msp430fr6989",2,8 },
1219 { "msp430fr69891",2,8 },
1220 { "msp430fw423",0,0 },
1221 { "msp430fw425",0,0 },
1222 { "msp430fw427",0,0 },
1223 { "msp430fw428",0,0 },
1224 { "msp430fw429",0,0 },
1225 { "msp430g2001",0,0 },
1226 { "msp430g2101",0,0 },
1227 { "msp430g2102",0,0 },
1228 { "msp430g2111",0,0 },
1229 { "msp430g2112",0,0 },
1230 { "msp430g2113",0,0 },
1231 { "msp430g2121",0,0 },
1232 { "msp430g2131",0,0 },
1233 { "msp430g2132",0,0 },
1234 { "msp430g2152",0,0 },
1235 { "msp430g2153",0,0 },
1236 { "msp430g2201",0,0 },
1237 { "msp430g2202",0,0 },
1238 { "msp430g2203",0,0 },
1239 { "msp430g2210",0,0 },
1240 { "msp430g2211",0,0 },
1241 { "msp430g2212",0,0 },
1242 { "msp430g2213",0,0 },
1243 { "msp430g2221",0,0 },
1244 { "msp430g2230",0,0 },
1245 { "msp430g2231",0,0 },
1246 { "msp430g2232",0,0 },
1247 { "msp430g2233",0,0 },
1248 { "msp430g2252",0,0 },
1249 { "msp430g2253",0,0 },
1250 { "msp430g2302",0,0 },
1251 { "msp430g2303",0,0 },
1252 { "msp430g2312",0,0 },
1253 { "msp430g2313",0,0 },
1254 { "msp430g2332",0,0 },
1255 { "msp430g2333",0,0 },
1256 { "msp430g2352",0,0 },
1257 { "msp430g2353",0,0 },
1258 { "msp430g2402",0,0 },
1259 { "msp430g2403",0,0 },
1260 { "msp430g2412",0,0 },
1261 { "msp430g2413",0,0 },
1262 { "msp430g2432",0,0 },
1263 { "msp430g2433",0,0 },
1264 { "msp430g2444",0,0 },
1265 { "msp430g2452",0,0 },
1266 { "msp430g2453",0,0 },
1267 { "msp430g2513",0,0 },
1268 { "msp430g2533",0,0 },
1269 { "msp430g2544",0,0 },
1270 { "msp430g2553",0,0 },
1271 { "msp430g2744",0,0 },
1272 { "msp430g2755",0,0 },
1273 { "msp430g2855",0,0 },
1274 { "msp430g2955",0,0 },
1275 { "msp430i2020",0,2 },
1276 { "msp430i2021",0,2 },
1277 { "msp430i2030",0,2 },
1278 { "msp430i2031",0,2 },
1279 { "msp430i2040",0,2 },
1280 { "msp430i2041",0,2 },
1281 { "msp430i2xxgeneric",0,2 },
1282 { "msp430l092",0,0 },
1283 { "msp430p112",0,0 },
1284 { "msp430p313",0,0 },
1285 { "msp430p315",0,0 },
1286 { "msp430p315s",0,0 },
1287 { "msp430p325",0,0 },
1288 { "msp430p337",0,1 },
1289 { "msp430sl5438a",2,8 },
1290 { "msp430tch5e",0,0 },
1291 { "msp430xgeneric",2,8 },
1292 { "rf430f5144",2,8 },
1293 { "rf430f5155",2,8 },
1294 { "rf430f5175",2,8 },
1295 { "rf430frl152h",0,0 },
1296 { "rf430frl152h_rom",0,0 },
1297 { "rf430frl153h",0,0 },
1298 { "rf430frl153h_rom",0,0 },
1299 { "rf430frl154h",0,0 },
1300 { "rf430frl154h_rom",0,0 }
1301};
1302
1303int
1304md_parse_option (int c, char * arg)
1305{
1306 switch (c)
1307 {
1308 case OPTION_MMCU:
1309 if (arg == NULL)
1310 as_fatal (_("MCU option requires a name\n"));
1311
1312 if (strcasecmp ("msp430", arg) == 0)
1313 selected_isa = MSP_ISA_430;
1314 else if (strcasecmp ("msp430xv2", arg) == 0)
1315 selected_isa = MSP_ISA_430Xv2;
1316 else if (strcasecmp ("msp430x", arg) == 0)
1317 selected_isa = MSP_ISA_430X;
1318 else
1319 {
1320 int i;
1321
1322 for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
1323 if (strcasecmp (msp430_mcu_data[i].name, arg) == 0)
1324 {
1325 switch (msp430_mcu_data[i].revision)
1326 {
1327 case 0: selected_isa = MSP_ISA_430; break;
1328 case 1: selected_isa = MSP_ISA_430X; break;
1329 case 2: selected_isa = MSP_ISA_430Xv2; break;
1330 }
1331 break;
1332 }
1333 }
1334 /* It is not an error if we do not match the MCU name. */
1335 return 1;
1336
1337 case OPTION_MCPU:
1338 if (strcmp (arg, "430") == 0
1339 || strcasecmp (arg, "msp430") == 0)
1340 selected_isa = MSP_ISA_430;
1341 else if (strcasecmp (arg, "430x") == 0
1342 || strcasecmp (arg, "msp430x") == 0)
1343 selected_isa = MSP_ISA_430X;
1344 else if (strcasecmp (arg, "430xv2") == 0
1345 || strcasecmp (arg, "msp430xv2") == 0)
1346 selected_isa = MSP_ISA_430Xv2;
1347 else
1348 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
1349 return 1;
1350
1351 case OPTION_RELAX:
1352 msp430_enable_relax = 1;
1353 return 1;
1354
1355 case OPTION_POLYMORPHS:
1356 msp430_enable_polys = 1;
1357 return 1;
1358
1359 case OPTION_LARGE:
1360 large_model = TRUE;
1361 return 1;
1362
1363 case OPTION_NO_INTR_NOPS:
1364 gen_interrupt_nops = FALSE;
1365 return 1;
1366 case OPTION_INTR_NOPS:
1367 gen_interrupt_nops = TRUE;
1368 return 1;
1369
1370 case OPTION_WARN_INTR_NOPS:
1371 warn_interrupt_nops = TRUE;
1372 return 1;
1373 case OPTION_NO_WARN_INTR_NOPS:
1374 warn_interrupt_nops = FALSE;
1375 return 1;
1376
1377 case OPTION_MOVE_DATA:
1378 move_data = TRUE;
1379 return 1;
1380 }
1381
1382 return 0;
1383}
1384
1385/* The intention here is to have the mere presence of these sections
1386 cause the object to have a reference to a well-known symbol. This
1387 reference pulls in the bits of the runtime (crt0) that initialize
1388 these sections. Thus, for example, the startup code to call
1389 memset() to initialize .bss will only be linked in when there is a
1390 non-empty .bss section. Otherwise, the call would exist but have a
1391 zero length parameter, which is a waste of memory and cycles.
1392
1393 The code which initializes these sections should have a global
1394 label for these symbols, and should be marked with KEEP() in the
1395 linker script. */
1396
1397static void
1398msp430_make_init_symbols (const char * name)
1399{
1400 if (strncmp (name, ".bss", 4) == 0
1401 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1402 (void) symbol_find_or_make ("__crt0_init_bss");
1403
1404 if (strncmp (name, ".data", 5) == 0
1405 || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
1406 (void) symbol_find_or_make ("__crt0_movedata");
1407
1408 /* Note - data assigned to the .either.data section may end up being
1409 placed in the .upper.data section if the .lower.data section is
1410 full. Hence the need to define the crt0 symbol. */
1411 if (strncmp (name, ".either.data", 12) == 0
1412 || strncmp (name, ".upper.data", 11) == 0)
1413 (void) symbol_find_or_make ("__crt0_move_highdata");
1414
1415 /* See note about .either.data above. */
1416 if (strncmp (name, ".upper.bss", 10) == 0
1417 || strncmp (name, ".either.bss", 11) == 0)
1418 (void) symbol_find_or_make ("__crt0_init_highbss");
1419}
1420
1421static void
1422msp430_section (int arg)
1423{
1424 char * saved_ilp = input_line_pointer;
1425 char * name = obj_elf_section_name ();
1426
1427 msp430_make_init_symbols (name);
1428
1429 input_line_pointer = saved_ilp;
1430 obj_elf_section (arg);
1431}
1432
1433void
1434msp430_frob_section (asection *sec)
1435{
1436 const char *name = sec->name;
1437
1438 if (sec->size == 0)
1439 return;
1440
1441 msp430_make_init_symbols (name);
1442}
1443
1444static void
1445msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
1446{
1447 symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
1448
1449 if (symbolP)
1450 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
1451 (void) symbol_find_or_make ("__crt0_init_bss");
1452}
1453
1454static void
1455msp430_comm (int needs_align)
1456{
1457 s_comm_internal (needs_align, elf_common_parse);
1458 (void) symbol_find_or_make ("__crt0_init_bss");
1459}
1460
1461static void
1462msp430_refsym (int arg ATTRIBUTE_UNUSED)
1463{
1464 char sym_name[1024];
1465 input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
1466
1467 (void) symbol_find_or_make (sym_name);
1468}
1469
1470const pseudo_typeS md_pseudo_table[] =
1471{
1472 {"arch", msp430_set_arch, OPTION_MMCU},
1473 {"cpu", msp430_set_arch, OPTION_MCPU},
1474 {"profiler", msp430_profiler, 0},
1475 {"section", msp430_section, 0},
1476 {"section.s", msp430_section, 0},
1477 {"sect", msp430_section, 0},
1478 {"sect.s", msp430_section, 0},
1479 {"pushsection", msp430_section, 1},
1480 {"refsym", msp430_refsym, 0},
1481 {"comm", msp430_comm, 0},
1482 {"lcomm", msp430_lcomm, 0},
1483 {NULL, NULL, 0}
1484};
1485
1486const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,my,mY";
1487
1488struct option md_longopts[] =
1489{
1490 {"mmcu", required_argument, NULL, OPTION_MMCU},
1491 {"mcpu", required_argument, NULL, OPTION_MCPU},
1492 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1493 {"mQ", no_argument, NULL, OPTION_RELAX},
1494 {"ml", no_argument, NULL, OPTION_LARGE},
1495 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
1496 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
1497 {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
1498 {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
1499 {"md", no_argument, NULL, OPTION_MOVE_DATA},
1500 {NULL, no_argument, NULL, 0}
1501};
1502
1503size_t md_longopts_size = sizeof (md_longopts);
1504
1505void
1506md_show_usage (FILE * stream)
1507{
1508 fprintf (stream,
1509 _("MSP430 options:\n"
1510 " -mmcu=<msp430-name> - select microcontroller type\n"
1511 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
1512 fprintf (stream,
1513 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1514 " -mP - enable polymorph instructions\n"));
1515 fprintf (stream,
1516 _(" -ml - enable large code model\n"));
1517 fprintf (stream,
1518 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
1519 fprintf (stream,
1520 _(" -mn - insert a NOP after changing interrupts\n"));
1521 fprintf (stream,
1522 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
1523 fprintf (stream,
1524 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
1525 fprintf (stream,
1526 _(" -md - Force copying of data from ROM to RAM at startup\n"));
1527}
1528
1529symbolS *
1530md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1531{
1532 return NULL;
1533}
1534
1535static char *
1536extract_cmd (char * from, char * to, int limit)
1537{
1538 int size = 0;
1539
1540 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1541 {
1542 *(to + size) = *from;
1543 from++;
1544 size++;
1545 }
1546
1547 *(to + size) = 0;
1548
1549 return from;
1550}
1551
1552char *
1553md_atof (int type, char * litP, int * sizeP)
1554{
1555 return ieee_md_atof (type, litP, sizeP, FALSE);
1556}
1557
1558void
1559md_begin (void)
1560{
1561 struct msp430_opcode_s * opcode;
1562 msp430_hash = hash_new ();
1563
1564 for (opcode = msp430_opcodes; opcode->name; opcode++)
1565 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1566
1567 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1568 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
1569}
1570
1571/* Returns the register number equivalent to the string T.
1572 Returns -1 if there is no such register.
1573 Skips a leading 'r' or 'R' character if there is one.
1574 Handles the register aliases PC and SP. */
1575
1576static signed int
1577check_reg (char * t)
1578{
1579 signed int val;
1580
1581 if (t == NULL)
1582 return -1;
1583
1584 if (*t == 'r' || *t == 'R')
1585 ++t;
1586
1587 if (strncasecmp (t, "pc", 2) == 0)
1588 return 0;
1589
1590 if (strncasecmp (t, "sp", 2) == 0)
1591 return 1;
1592
1593 if (strncasecmp (t, "sr", 2) == 0)
1594 return 2;
1595
1596 if (*t == '0')
1597 return 0;
1598
1599 val = atoi (t);
1600
1601 if (val < 1 || val > 15)
1602 return -1;
1603
1604 return val;
1605}
1606
1607static int
1608msp430_srcoperand (struct msp430_operand_s * op,
1609 char * l,
1610 int bin,
1611 bfd_boolean * imm_op,
1612 bfd_boolean allow_20bit_values,
1613 bfd_boolean constants_allowed)
1614{
1615 char *__tl = l;
1616
1617 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1618 if (*l == '#')
1619 {
1620 char *h = l;
1621 int vshift = -1;
1622 int rval = 0;
1623
1624 /* Check if there is:
1625 llo(x) - least significant 16 bits, x &= 0xffff
1626 lhi(x) - x = (x >> 16) & 0xffff,
1627 hlo(x) - x = (x >> 32) & 0xffff,
1628 hhi(x) - x = (x >> 48) & 0xffff
1629 The value _MUST_ be constant expression: #hlo(1231231231). */
1630
1631 *imm_op = TRUE;
1632
1633 if (strncasecmp (h, "#llo(", 5) == 0)
1634 {
1635 vshift = 0;
1636 rval = 3;
1637 }
1638 else if (strncasecmp (h, "#lhi(", 5) == 0)
1639 {
1640 vshift = 1;
1641 rval = 3;
1642 }
1643 else if (strncasecmp (h, "#hlo(", 5) == 0)
1644 {
1645 vshift = 2;
1646 rval = 3;
1647 }
1648 else if (strncasecmp (h, "#hhi(", 5) == 0)
1649 {
1650 vshift = 3;
1651 rval = 3;
1652 }
1653 else if (strncasecmp (h, "#lo(", 4) == 0)
1654 {
1655 vshift = 0;
1656 rval = 2;
1657 }
1658 else if (strncasecmp (h, "#hi(", 4) == 0)
1659 {
1660 vshift = 1;
1661 rval = 2;
1662 }
1663
1664 op->reg = 0; /* Reg PC. */
1665 op->am = 3;
1666 op->ol = 1; /* Immediate will follow an instruction. */
1667 __tl = h + 1 + rval;
1668 op->mode = OP_EXP;
1669 op->vshift = vshift;
1670
1671 parse_exp (__tl, &(op->exp));
1672 if (op->exp.X_op == O_constant)
1673 {
1674 int x = op->exp.X_add_number;
1675
1676 if (vshift == 0)
1677 {
1678 x = x & 0xffff;
1679 op->exp.X_add_number = x;
1680 }
1681 else if (vshift == 1)
1682 {
1683 x = (x >> 16) & 0xffff;
1684 op->exp.X_add_number = x;
1685 op->vshift = 0;
1686 }
1687 else if (vshift > 1)
1688 {
1689 if (x < 0)
1690 op->exp.X_add_number = -1;
1691 else
1692 op->exp.X_add_number = 0; /* Nothing left. */
1693 x = op->exp.X_add_number;
1694 op->vshift = 0;
1695 }
1696
1697 if (allow_20bit_values)
1698 {
1699 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
1700 {
1701 as_bad (_("value 0x%x out of extended range."), x);
1702 return 1;
1703 }
1704 }
1705 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1706 {
1707 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1708 return 1;
1709 }
1710
1711 /* Now check constants. */
1712 /* Substitute register mode with a constant generator if applicable. */
1713
1714 if (!allow_20bit_values)
1715 x = (short) x; /* Extend sign. */
1716
1717 if (! constants_allowed)
1718 ;
1719 else if (x == 0)
1720 {
1721 op->reg = 3;
1722 op->am = 0;
1723 op->ol = 0;
1724 op->mode = OP_REG;
1725 }
1726 else if (x == 1)
1727 {
1728 op->reg = 3;
1729 op->am = 1;
1730 op->ol = 0;
1731 op->mode = OP_REG;
1732 }
1733 else if (x == 2)
1734 {
1735 op->reg = 3;
1736 op->am = 2;
1737 op->ol = 0;
1738 op->mode = OP_REG;
1739 }
1740 else if (x == -1)
1741 {
1742 op->reg = 3;
1743 op->am = 3;
1744 op->ol = 0;
1745 op->mode = OP_REG;
1746 }
1747 else if (x == 4)
1748 {
1749#ifdef PUSH_1X_WORKAROUND
1750 if (bin == 0x1200)
1751 {
1752 /* Remove warning as confusing.
1753 as_warn (_("Hardware push bug workaround")); */
1754 }
1755 else
1756#endif
1757 {
1758 op->reg = 2;
1759 op->am = 2;
1760 op->ol = 0;
1761 op->mode = OP_REG;
1762 }
1763 }
1764 else if (x == 8)
1765 {
1766#ifdef PUSH_1X_WORKAROUND
1767 if (bin == 0x1200)
1768 {
1769 /* Remove warning as confusing.
1770 as_warn (_("Hardware push bug workaround")); */
1771 }
1772 else
1773#endif
1774 {
1775 op->reg = 2;
1776 op->am = 3;
1777 op->ol = 0;
1778 op->mode = OP_REG;
1779 }
1780 }
1781 }
1782 else if (op->exp.X_op == O_symbol)
1783 {
1784 if (vshift > 1)
1785 as_bad (_("error: unsupported #foo() directive used on symbol"));
1786 op->mode = OP_EXP;
1787 }
1788 else if (op->exp.X_op == O_big)
1789 {
1790 short x;
1791
1792 if (vshift != -1)
1793 {
1794 op->exp.X_op = O_constant;
1795 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1796 x = op->exp.X_add_number;
1797 op->vshift = 0;
1798 }
1799 else
1800 {
1801 as_bad (_
1802 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1803 l);
1804 return 1;
1805 }
1806
1807 if (x == 0)
1808 {
1809 op->reg = 3;
1810 op->am = 0;
1811 op->ol = 0;
1812 op->mode = OP_REG;
1813 }
1814 else if (x == 1)
1815 {
1816 op->reg = 3;
1817 op->am = 1;
1818 op->ol = 0;
1819 op->mode = OP_REG;
1820 }
1821 else if (x == 2)
1822 {
1823 op->reg = 3;
1824 op->am = 2;
1825 op->ol = 0;
1826 op->mode = OP_REG;
1827 }
1828 else if (x == -1)
1829 {
1830 op->reg = 3;
1831 op->am = 3;
1832 op->ol = 0;
1833 op->mode = OP_REG;
1834 }
1835 else if (x == 4)
1836 {
1837 op->reg = 2;
1838 op->am = 2;
1839 op->ol = 0;
1840 op->mode = OP_REG;
1841 }
1842 else if (x == 8)
1843 {
1844 op->reg = 2;
1845 op->am = 3;
1846 op->ol = 0;
1847 op->mode = OP_REG;
1848 }
1849 }
1850 /* Redundant (yet) check. */
1851 else if (op->exp.X_op == O_register)
1852 as_bad
1853 (_("Registers cannot be used within immediate expression [%s]"), l);
1854 else
1855 as_bad (_("unknown operand %s"), l);
1856
1857 return 0;
1858 }
1859
1860 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1861 if (*l == '&')
1862 {
1863 char *h = l;
1864
1865 op->reg = 2; /* reg 2 in absolute addr mode. */
1866 op->am = 1; /* mode As == 01 bin. */
1867 op->ol = 1; /* Immediate value followed by instruction. */
1868 __tl = h + 1;
1869 parse_exp (__tl, &(op->exp));
1870 op->mode = OP_EXP;
1871 op->vshift = 0;
1872 if (op->exp.X_op == O_constant)
1873 {
1874 int x = op->exp.X_add_number;
1875
1876 if (allow_20bit_values)
1877 {
1878 if (x > 0xfffff || x < -(0x7ffff))
1879 {
1880 as_bad (_("value 0x%x out of extended range."), x);
1881 return 1;
1882 }
1883 }
1884 else if (x > 65535 || x < -32768)
1885 {
1886 as_bad (_("value out of range: 0x%x"), x);
1887 return 1;
1888 }
1889 }
1890 else if (op->exp.X_op == O_symbol)
1891 ;
1892 else
1893 {
1894 /* Redundant (yet) check. */
1895 if (op->exp.X_op == O_register)
1896 as_bad
1897 (_("Registers cannot be used within absolute expression [%s]"), l);
1898 else
1899 as_bad (_("unknown expression in operand %s"), l);
1900 return 1;
1901 }
1902 return 0;
1903 }
1904
1905 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1906 if (*l == '@')
1907 {
1908 char *t = l;
1909 char *m = strchr (l, '+');
1910
1911 if (t != l)
1912 {
1913 as_bad (_("unknown addressing mode %s"), l);
1914 return 1;
1915 }
1916
1917 t++;
1918
1919 if ((op->reg = check_reg (t)) == -1)
1920 {
1921 as_bad (_("Bad register name %s"), t);
1922 return 1;
1923 }
1924
1925 op->mode = OP_REG;
1926 op->am = m ? 3 : 2;
1927 op->ol = 0;
1928
1929 /* PC cannot be used in indirect addressing. */
1930 if (target_is_430xv2 () && op->reg == 0)
1931 {
1932 as_bad (_("cannot use indirect addressing with the PC"));
1933 return 1;
1934 }
1935
1936 return 0;
1937 }
1938
1939 /* Check if register indexed X(Rn). */
1940 do
1941 {
1942 char *h = strrchr (l, '(');
1943 char *m = strrchr (l, ')');
1944 char *t;
1945
1946 *imm_op = TRUE;
1947
1948 if (!h)
1949 break;
1950 if (!m)
1951 {
1952 as_bad (_("')' required"));
1953 return 1;
1954 }
1955
1956 t = h;
1957 op->am = 1;
1958 op->ol = 1;
1959
1960 /* Extract a register. */
1961 if ((op->reg = check_reg (t + 1)) == -1)
1962 {
1963 as_bad (_
1964 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1965 l);
1966 return 1;
1967 }
1968
1969 if (op->reg == 2)
1970 {
1971 as_bad (_("r2 should not be used in indexed addressing mode"));
1972 return 1;
1973 }
1974
1975 /* Extract constant. */
1976 __tl = l;
1977 *h = 0;
1978 op->mode = OP_EXP;
1979 op->vshift = 0;
1980 parse_exp (__tl, &(op->exp));
1981 if (op->exp.X_op == O_constant)
1982 {
1983 int x = op->exp.X_add_number;
1984
1985 if (allow_20bit_values)
1986 {
1987 if (x > 0xfffff || x < - (0x7ffff))
1988 {
1989 as_bad (_("value 0x%x out of extended range."), x);
1990 return 1;
1991 }
1992 }
1993 else if (x > 65535 || x < -32768)
1994 {
1995 as_bad (_("value out of range: 0x%x"), x);
1996 return 1;
1997 }
1998
1999 if (x == 0)
2000 {
2001 op->mode = OP_REG;
2002 op->am = 2;
2003 op->ol = 0;
2004 return 0;
2005 }
2006 }
2007 else if (op->exp.X_op == O_symbol)
2008 ;
2009 else
2010 {
2011 /* Redundant (yet) check. */
2012 if (op->exp.X_op == O_register)
2013 as_bad
2014 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
2015 else
2016 as_bad (_("unknown expression in operand %s"), l);
2017 return 1;
2018 }
2019
2020 return 0;
2021 }
2022 while (0);
2023
2024 /* Possibly register mode 'mov r1,r2'. */
2025 if ((op->reg = check_reg (l)) != -1)
2026 {
2027 op->mode = OP_REG;
2028 op->am = 0;
2029 op->ol = 0;
2030 return 0;
2031 }
2032
2033 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2034 do
2035 {
2036 op->mode = OP_EXP;
2037 op->reg = 0; /* PC relative... be careful. */
2038 /* An expression starting with a minus sign is a constant, not an address. */
2039 op->am = (*l == '-' ? 3 : 1);
2040 op->ol = 1;
2041 op->vshift = 0;
2042 __tl = l;
2043 parse_exp (__tl, &(op->exp));
2044 return 0;
2045 }
2046 while (0);
2047
2048 /* Unreachable. */
2049 as_bad (_("unknown addressing mode for operand %s"), l);
2050 return 1;
2051}
2052
2053
2054static int
2055msp430_dstoperand (struct msp430_operand_s * op,
2056 char * l,
2057 int bin,
2058 bfd_boolean allow_20bit_values,
2059 bfd_boolean constants_allowed)
2060{
2061 int dummy;
2062 int ret = msp430_srcoperand (op, l, bin, & dummy,
2063 allow_20bit_values,
2064 constants_allowed);
2065
2066 if (ret)
2067 return ret;
2068
2069 if (op->am == 2)
2070 {
2071 char *__tl = "0";
2072
2073 op->mode = OP_EXP;
2074 op->am = 1;
2075 op->ol = 1;
2076 op->vshift = 0;
2077 parse_exp (__tl, &(op->exp));
2078
2079 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
2080 {
2081 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2082 op->reg, op->reg);
2083 return 1;
2084 }
2085 return 0;
2086 }
2087
2088 if (op->am > 1)
2089 {
2090 as_bad (_
2091 ("this addressing mode is not applicable for destination operand"));
2092 return 1;
2093 }
2094 return 0;
2095}
2096
2097/* Attempt to encode a MOVA instruction with the given operands.
2098 Returns the length of the encoded instruction if successful
2099 or 0 upon failure. If the encoding fails, an error message
2100 will be returned if a pointer is provided. */
2101
2102static int
2103try_encode_mova (bfd_boolean imm_op,
2104 int bin,
2105 struct msp430_operand_s * op1,
2106 struct msp430_operand_s * op2,
2107 const char ** error_message_return)
2108{
2109 short ZEROS = 0;
2110 char *frag;
2111 int where;
2112
2113 /* Only a restricted subset of the normal MSP430 addressing modes
2114 are supported here, so check for the ones that are allowed. */
2115 if (imm_op)
2116 {
2117 if (op1->mode == OP_EXP)
2118 {
2119 if (op2->mode != OP_REG)
2120 {
2121 if (error_message_return != NULL)
2122 * error_message_return = _("expected register as second argument of %s");
2123 return 0;
2124 }
2125
2126 if (op1->am == 3)
2127 {
2128 /* MOVA #imm20, Rdst. */
2129 bin |= 0x80 | op2->reg;
2130 frag = frag_more (4);
2131 where = frag - frag_now->fr_literal;
2132 if (op1->exp.X_op == O_constant)
2133 {
2134 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2135 bfd_putl16 ((bfd_vma) bin, frag);
2136 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2137 }
2138 else
2139 {
2140 bfd_putl16 ((bfd_vma) bin, frag);
2141 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2142 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2143 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2144 }
2145
2146 return 4;
2147 }
2148 else if (op1->am == 1)
2149 {
2150 /* MOVA z16(Rsrc), Rdst. */
2151 bin |= 0x30 | (op1->reg << 8) | op2->reg;
2152 frag = frag_more (4);
2153 where = frag - frag_now->fr_literal;
2154 bfd_putl16 ((bfd_vma) bin, frag);
2155 if (op1->exp.X_op == O_constant)
2156 {
2157 if (op1->exp.X_add_number > 0xffff
2158 || op1->exp.X_add_number < -(0x7fff))
2159 {
2160 if (error_message_return != NULL)
2161 * error_message_return = _("index value too big for %s");
2162 return 0;
2163 }
2164 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2165 }
2166 else
2167 {
2168 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2169 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
2170 op1->reg == 0 ?
2171 BFD_RELOC_MSP430X_PCR16 :
2172 BFD_RELOC_MSP430X_ABS16);
2173 }
2174 return 4;
2175 }
2176
2177 if (error_message_return != NULL)
2178 * error_message_return = _("unexpected addressing mode for %s");
2179 return 0;
2180 }
2181 else if (op1->am == 0)
2182 {
2183 /* MOVA Rsrc, ... */
2184 if (op2->mode == OP_REG)
2185 {
2186 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
2187 frag = frag_more (2);
2188 where = frag - frag_now->fr_literal;
2189 bfd_putl16 ((bfd_vma) bin, frag);
2190 return 2;
2191 }
2192 else if (op2->am == 1)
2193 {
2194 if (op2->reg == 2)
2195 {
2196 /* MOVA Rsrc, &abs20. */
2197 bin |= 0x60 | (op1->reg << 8);
2198 frag = frag_more (4);
2199 where = frag - frag_now->fr_literal;
2200 if (op2->exp.X_op == O_constant)
2201 {
2202 bin |= (op2->exp.X_add_number >> 16) & 0xf;
2203 bfd_putl16 ((bfd_vma) bin, frag);
2204 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2205 }
2206 else
2207 {
2208 bfd_putl16 ((bfd_vma) bin, frag);
2209 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2210 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
2211 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2212 }
2213 return 4;
2214 }
2215
2216 /* MOVA Rsrc, z16(Rdst). */
2217 bin |= 0x70 | (op1->reg << 8) | op2->reg;
2218 frag = frag_more (4);
2219 where = frag - frag_now->fr_literal;
2220 bfd_putl16 ((bfd_vma) bin, frag);
2221 if (op2->exp.X_op == O_constant)
2222 {
2223 if (op2->exp.X_add_number > 0xffff
2224 || op2->exp.X_add_number < -(0x7fff))
2225 {
2226 if (error_message_return != NULL)
2227 * error_message_return = _("index value too big for %s");
2228 return 0;
2229 }
2230 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2231 }
2232 else
2233 {
2234 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2235 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2236 op2->reg == 0 ?
2237 BFD_RELOC_MSP430X_PCR16 :
2238 BFD_RELOC_MSP430X_ABS16);
2239 }
2240 return 4;
2241 }
2242
2243 if (error_message_return != NULL)
2244 * error_message_return = _("unexpected addressing mode for %s");
2245 return 0;
2246 }
2247 }
2248
2249 /* imm_op == FALSE. */
2250
2251 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2252 {
2253 /* MOVA &abs20, Rdst. */
2254 if (op2->mode != OP_REG)
2255 {
2256 if (error_message_return != NULL)
2257 * error_message_return = _("expected register as second argument of %s");
2258 return 0;
2259 }
2260
2261 if (op2->reg == 2 || op2->reg == 3)
2262 {
2263 if (error_message_return != NULL)
2264 * error_message_return = _("constant generator destination register found in %s");
2265 return 0;
2266 }
2267
2268 bin |= 0x20 | op2->reg;
2269 frag = frag_more (4);
2270 where = frag - frag_now->fr_literal;
2271 if (op1->exp.X_op == O_constant)
2272 {
2273 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2274 bfd_putl16 ((bfd_vma) bin, frag);
2275 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2276 }
2277 else
2278 {
2279 bfd_putl16 ((bfd_vma) bin, frag);
2280 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2281 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2282 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2283 }
2284 return 4;
2285 }
2286 else if (op1->mode == OP_REG)
2287 {
2288 if (op1->am == 3)
2289 {
2290 /* MOVA @Rsrc+, Rdst. */
2291 if (op2->mode != OP_REG)
2292 {
2293 if (error_message_return != NULL)
2294 * error_message_return = _("expected register as second argument of %s");
2295 return 0;
2296 }
2297
2298 if (op2->reg == 2 || op2->reg == 3)
2299 {
2300 if (error_message_return != NULL)
2301 * error_message_return = _("constant generator destination register found in %s");
2302 return 0;
2303 }
2304
2305 if (op1->reg == 2 || op1->reg == 3)
2306 {
2307 if (error_message_return != NULL)
2308 * error_message_return = _("constant generator source register found in %s");
2309 return 0;
2310 }
2311
2312 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2313 frag = frag_more (2);
2314 where = frag - frag_now->fr_literal;
2315 bfd_putl16 ((bfd_vma) bin, frag);
2316 return 2;
2317 }
2318 else if (op1->am == 2)
2319 {
2320 /* MOVA @Rsrc,Rdst */
2321 if (op2->mode != OP_REG)
2322 {
2323 if (error_message_return != NULL)
2324 * error_message_return = _("expected register as second argument of %s");
2325 return 0;
2326 }
2327
2328 if (op2->reg == 2 || op2->reg == 3)
2329 {
2330 if (error_message_return != NULL)
2331 * error_message_return = _("constant generator destination register found in %s");
2332 return 0;
2333 }
2334
2335 if (op1->reg == 2 || op1->reg == 3)
2336 {
2337 if (error_message_return != NULL)
2338 * error_message_return = _("constant generator source register found in %s");
2339 return 0;
2340 }
2341
2342 bin |= (op1->reg << 8) | op2->reg;
2343 frag = frag_more (2);
2344 where = frag - frag_now->fr_literal;
2345 bfd_putl16 ((bfd_vma) bin, frag);
2346 return 2;
2347 }
2348 }
2349
2350 if (error_message_return != NULL)
2351 * error_message_return = _("unexpected addressing mode for %s");
2352
2353 return 0;
2354}
2355
2356static bfd_boolean check_for_nop = FALSE;
2357
2358#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2359
2360/* Parse instruction operands.
2361 Return binary opcode. */
2362
2363static unsigned int
2364msp430_operands (struct msp430_opcode_s * opcode, char * line)
2365{
2366 int bin = opcode->bin_opcode; /* Opcode mask. */
2367 int insn_length = 0;
2368 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2369 char *frag;
2370 int where;
2371 struct msp430_operand_s op1, op2;
2372 int res = 0;
2373 static short ZEROS = 0;
2374 bfd_boolean byte_op, imm_op;
2375 int op_length = 0;
2376 int fmt;
2377 int extended = 0x1800;
2378 bfd_boolean extended_op = FALSE;
2379 bfd_boolean addr_op;
2380 const char * error_message;
2381 static signed int repeat_count = 0;
2382 bfd_boolean fix_emitted;
2383 bfd_boolean nop_check_needed = FALSE;
2384
2385 /* Opcode is the one from opcodes table
2386 line contains something like
2387 [.w] @r2+, 5(R1)
2388 or
2389 .b @r2+, 5(R1). */
2390
2391 byte_op = FALSE;
2392 addr_op = FALSE;
2393 if (*line == '.')
2394 {
2395 bfd_boolean check = FALSE;
2396 ++ line;
2397
2398 switch (TOLOWER (* line))
2399 {
2400 case 'b':
2401 /* Byte operation. */
2402 bin |= BYTE_OPERATION;
2403 byte_op = TRUE;
2404 check = TRUE;
2405 break;
2406
2407 case 'a':
2408 /* "Address" ops work on 20-bit values. */
2409 addr_op = TRUE;
2410 bin |= BYTE_OPERATION;
2411 check = TRUE;
2412 break;
2413
2414 case 'w':
2415 /* Word operation - this is the default. */
2416 check = TRUE;
2417 break;
2418
2419 case 0:
2420 case ' ':
2421 case '\n':
2422 case '\r':
2423 as_warn (_("no size modifier after period, .w assumed"));
2424 break;
2425
2426 default:
2427 as_bad (_("unrecognised instruction size modifier .%c"),
2428 * line);
2429 return 0;
2430 }
2431
2432 if (check)
2433 {
2434 ++ line;
2435
2436 }
2437 }
2438
2439 if (*line && ! ISSPACE (*line))
2440 {
2441 as_bad (_("junk found after instruction: %s.%s"),
2442 opcode->name, line);
2443 return 0;
2444 }
2445
2446 /* Catch the case where the programmer has used a ".a" size modifier on an
2447 instruction that does not support it. Look for an alternative extended
2448 instruction that has the same name without the period. Eg: "add.a"
2449 becomes "adda". Although this not an officially supported way of
2450 specifing instruction aliases other MSP430 assemblers allow it. So we
2451 support it for compatibility purposes. */
2452 if (addr_op && opcode->fmt >= 0)
2453 {
2454 char * old_name = opcode->name;
2455 char real_name[32];
2456
2457 sprintf (real_name, "%sa", old_name);
2458 opcode = hash_find (msp430_hash, real_name);
2459 if (opcode == NULL)
2460 {
2461 as_bad (_("instruction %s.a does not exist"), old_name);
2462 return 0;
2463 }
2464#if 0 /* Enable for debugging. */
2465 as_warn ("treating %s.a as %s", old_name, real_name);
2466#endif
2467 addr_op = FALSE;
2468 bin = opcode->bin_opcode;
2469 }
2470
2471 if (opcode->fmt != -1
2472 && opcode->insn_opnumb
2473 && (!*line || *line == '\n'))
2474 {
2475 as_bad (_("instruction %s requires %d operand(s)"),
2476 opcode->name, opcode->insn_opnumb);
2477 return 0;
2478 }
2479
2480 memset (l1, 0, sizeof (l1));
2481 memset (l2, 0, sizeof (l2));
2482 memset (&op1, 0, sizeof (op1));
2483 memset (&op2, 0, sizeof (op2));
2484
2485 imm_op = FALSE;
2486
2487 if ((fmt = opcode->fmt) < 0)
2488 {
2489 if (! target_is_430x ())
2490 {
2491 as_bad (_("instruction %s requires MSP430X mcu"),
2492 opcode->name);
2493 return 0;
2494 }
2495
2496 fmt = (-fmt) - 1;
2497 extended_op = TRUE;
2498 }
2499
2500 if (repeat_count)
2501 {
2502 /* If requested set the extended instruction repeat count. */
2503 if (extended_op)
2504 {
2505 if (repeat_count > 0)
2506 extended |= (repeat_count - 1);
2507 else
2508 extended |= (1 << 7) | (- repeat_count);
2509 }
2510 else
2511 as_bad (_("unable to repeat %s insn"), opcode->name);
2512
2513 repeat_count = 0;
2514 }
2515
2516 if (check_for_nop && is_opcode ("nop"))
2517 check_for_nop = FALSE;
2518
2519 switch (fmt)
2520 {
2521 case 0: /* Emulated. */
2522 switch (opcode->insn_opnumb)
2523 {
2524 case 0:
2525 if (is_opcode ("eint") || is_opcode ("dint"))
2526 {
2527 if (check_for_nop)
2528 {
2529 if (warn_interrupt_nops)
2530 {
2531 if (gen_interrupt_nops)
2532 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2533 else
2534 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2535 }
2536
2537 if (gen_interrupt_nops)
2538 {
2539 /* Emit a NOP between interrupt enable/disable.
2540 See 1.3.4.1 of the MSP430x5xx User Guide. */
2541 insn_length += 2;
2542 frag = frag_more (2);
2543 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2544 }
2545 }
2546
2547 nop_check_needed = TRUE;
2548 }
2549
2550 /* Set/clear bits instructions. */
2551 if (extended_op)
2552 {
2553 if (!addr_op)
2554 extended |= BYTE_OPERATION;
2555
2556 /* Emit the extension word. */
2557 insn_length += 2;
2558 frag = frag_more (2);
2559 bfd_putl16 (extended, frag);
2560 }
2561
2562 insn_length += 2;
2563 frag = frag_more (2);
2564 bfd_putl16 ((bfd_vma) bin, frag);
2565 dwarf2_emit_insn (insn_length);
2566 break;
2567
2568 case 1:
2569 /* Something which works with destination operand. */
2570 line = extract_operand (line, l1, sizeof (l1));
2571 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
2572 if (res)
2573 break;
2574
2575 bin |= (op1.reg | (op1.am << 7));
2576
2577 if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
2578 {
2579 if (check_for_nop)
2580 {
2581 if (warn_interrupt_nops)
2582 {
2583 if (gen_interrupt_nops)
2584 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2585 else
2586 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2587 }
2588
2589 if (gen_interrupt_nops)
2590 {
2591 /* Emit a NOP between interrupt enable/disable.
2592 See 1.3.4.1 of the MSP430x5xx User Guide. */
2593 insn_length += 2;
2594 frag = frag_more (2);
2595 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2596 }
2597 }
2598
2599 nop_check_needed = TRUE;
2600 }
2601
2602 /* Compute the entire instruction length, in bytes. */
2603 op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2604 insn_length += op_length;
2605 frag = frag_more (op_length);
2606 where = frag - frag_now->fr_literal;
2607
2608 if (extended_op)
2609 {
2610 if (!addr_op)
2611 extended |= BYTE_OPERATION;
2612
2613 if (op1.ol != 0 && ((extended & 0xf) != 0))
2614 {
2615 as_bad (_("repeat instruction used with non-register mode instruction"));
2616 extended &= ~ 0xf;
2617 }
2618
2619 if (op1.mode == OP_EXP)
2620 {
2621 if (op1.exp.X_op == O_constant)
2622 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2623
2624 else if (op1.reg || op1.am == 3) /* Not PC relative. */
2625 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2626 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2627 else
2628 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2629 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2630 }
2631
2632 /* Emit the extension word. */
2633 bfd_putl16 (extended, frag);
2634 frag += 2;
2635 where += 2;
2636 }
2637
2638 bfd_putl16 ((bfd_vma) bin, frag);
2639 frag += 2;
2640 where += 2;
2641
2642 if (op1.mode == OP_EXP)
2643 {
2644 if (op1.exp.X_op == O_constant)
2645 {
2646 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2647 }
2648 else
2649 {
2650 bfd_putl16 ((bfd_vma) ZEROS, frag);
2651
2652 if (!extended_op)
2653 {
2654 if (op1.reg)
2655 fix_new_exp (frag_now, where, 2,
2656 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
2657 else
2658 fix_new_exp (frag_now, where, 2,
2659 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2660 }
2661 }
2662 }
2663
2664 dwarf2_emit_insn (insn_length);
2665 break;
2666
2667 case 2:
2668 /* Shift instruction. */
2669 line = extract_operand (line, l1, sizeof (l1));
2670 strncpy (l2, l1, sizeof (l2));
2671 l2[sizeof (l2) - 1] = '\0';
2672 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2673 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2674
2675 if (res)
2676 break; /* An error occurred. All warnings were done before. */
2677
2678 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2679 frag = frag_more (insn_length);
2680 where = frag - frag_now->fr_literal;
2681
2682 if (target_is_430xv2 ()
2683 && op1.mode == OP_REG
2684 && op1.reg == 0
2685 && (is_opcode ("rlax")
2686 || is_opcode ("rlcx")
2687 || is_opcode ("rla")
2688 || is_opcode ("rlc")))
2689 {
2690 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
2691 break;
2692 }
2693
2694 if (extended_op)
2695 {
2696 if (!addr_op)
2697 extended |= BYTE_OPERATION;
2698
2699 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2700 {
2701 as_bad (_("repeat instruction used with non-register mode instruction"));
2702 extended &= ~ 0xf;
2703 }
2704
2705 if (op1.mode == OP_EXP)
2706 {
2707 if (op1.exp.X_op == O_constant)
2708 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2709
2710 else if (op1.reg || op1.am == 3) /* Not PC relative. */
2711 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2712 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2713 else
2714 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2715 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2716 }
2717
2718 if (op2.mode == OP_EXP)
2719 {
2720 if (op2.exp.X_op == O_constant)
2721 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2722
2723 else if (op1.mode == OP_EXP)
2724 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2725 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2726 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2727 else
2728 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2729 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2730 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2731 }
2732
2733 /* Emit the extension word. */
2734 bfd_putl16 (extended, frag);
2735 frag += 2;
2736 where += 2;
2737 }
2738
2739 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2740 bfd_putl16 ((bfd_vma) bin, frag);
2741 frag += 2;
2742 where += 2;
2743
2744 if (op1.mode == OP_EXP)
2745 {
2746 if (op1.exp.X_op == O_constant)
2747 {
2748 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2749 }
2750 else
2751 {
2752 bfd_putl16 ((bfd_vma) ZEROS, frag);
2753
2754 if (!extended_op)
2755 {
2756 if (op1.reg || op1.am == 3) /* Not PC relative. */
2757 fix_new_exp (frag_now, where, 2,
2758 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
2759 else
2760 fix_new_exp (frag_now, where, 2,
2761 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2762 }
2763 }
2764 frag += 2;
2765 where += 2;
2766 }
2767
2768 if (op2.mode == OP_EXP)
2769 {
2770 if (op2.exp.X_op == O_constant)
2771 {
2772 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2773 }
2774 else
2775 {
2776 bfd_putl16 ((bfd_vma) ZEROS, frag);
2777
2778 if (!extended_op)
2779 {
2780 if (op2.reg) /* Not PC relative. */
2781 fix_new_exp (frag_now, where, 2,
2782 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
2783 else
2784 fix_new_exp (frag_now, where, 2,
2785 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2786 }
2787 }
2788 }
2789
2790 dwarf2_emit_insn (insn_length);
2791 break;
2792
2793 case 3:
2794 /* Branch instruction => mov dst, r0. */
2795 if (extended_op)
2796 {
2797 as_bad ("Internal error: state 0/3 not coded for extended instructions");
2798 break;
2799 }
2800
2801 line = extract_operand (line, l1, sizeof (l1));
2802 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2803 if (res)
2804 break;
2805
2806 byte_op = FALSE;
2807 imm_op = FALSE;
2808 bin |= ((op1.reg << 8) | (op1.am << 4));
2809 op_length = 2 + 2 * op1.ol;
2810 frag = frag_more (op_length);
2811 where = frag - frag_now->fr_literal;
2812 bfd_putl16 ((bfd_vma) bin, frag);
2813
2814 if (op1.mode == OP_EXP)
2815 {
2816 if (op1.exp.X_op == O_constant)
2817 {
2818 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2819 }
2820 else
2821 {
2822 where += 2;
2823
2824 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2825
2826 if (op1.reg || op1.am == 3)
2827 fix_new_exp (frag_now, where, 2,
2828 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
2829 else
2830 fix_new_exp (frag_now, where, 2,
2831 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2832 }
2833 }
2834
2835 dwarf2_emit_insn (insn_length + op_length);
2836 break;
2837
2838 case 4:
2839 /* CALLA instructions. */
2840 fix_emitted = FALSE;
2841
2842 line = extract_operand (line, l1, sizeof (l1));
2843 imm_op = FALSE;
2844
2845 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
2846 extended_op, FALSE);
2847 if (res)
2848 break;
2849
2850 byte_op = FALSE;
2851
2852 op_length = 2 + 2 * op1.ol;
2853 frag = frag_more (op_length);
2854 where = frag - frag_now->fr_literal;
2855
2856 if (imm_op)
2857 {
2858 if (op1.am == 3)
2859 {
2860 bin |= 0xb0;
2861
2862 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2863 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2864 fix_emitted = TRUE;
2865 }
2866 else if (op1.am == 1)
2867 {
2868 if (op1.reg == 0)
2869 {
2870 bin |= 0x90;
2871
2872 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2873 BFD_RELOC_MSP430X_PCR20_CALL);
2874 fix_emitted = TRUE;
2875 }
2876 else
2877 bin |= 0x50 | op1.reg;
2878 }
2879 else if (op1.am == 0)
2880 bin |= 0x40 | op1.reg;
2881 }
2882 else if (op1.am == 1)
2883 {
2884 bin |= 0x80;
2885
2886 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
2887 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2888 fix_emitted = TRUE;
2889 }
2890 else if (op1.am == 2)
2891 bin |= 0x60 | op1.reg;
2892 else if (op1.am == 3)
2893 bin |= 0x70 | op1.reg;
2894
2895 bfd_putl16 ((bfd_vma) bin, frag);
2896
2897 if (op1.mode == OP_EXP)
2898 {
2899 if (op1.ol != 1)
2900 {
2901 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
2902 break;
2903 }
2904
2905 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2906
2907 if (! fix_emitted)
2908 fix_new_exp (frag_now, where + 2, 2,
2909 &(op1.exp), FALSE, BFD_RELOC_16);
2910 }
2911
2912 dwarf2_emit_insn (insn_length + op_length);
2913 break;
2914
2915 case 5:
2916 {
2917 int n;
2918 int reg;
2919
2920 /* [POP|PUSH]M[.A] #N, Rd */
2921 line = extract_operand (line, l1, sizeof (l1));
2922 line = extract_operand (line, l2, sizeof (l2));
2923
2924 if (*l1 != '#')
2925 {
2926 as_bad (_("expected #n as first argument of %s"), opcode->name);
2927 break;
2928 }
2929 parse_exp (l1 + 1, &(op1.exp));
2930 if (op1.exp.X_op != O_constant)
2931 {
2932 as_bad (_("expected constant expression for first argument of %s"),
2933 opcode->name);
2934 break;
2935 }
2936
2937 if ((reg = check_reg (l2)) == -1)
2938 {
2939 as_bad (_("expected register as second argument of %s"),
2940 opcode->name);
2941 break;
2942 }
2943
2944 op_length = 2;
2945 frag = frag_more (op_length);
2946 where = frag - frag_now->fr_literal;
2947 bin = opcode->bin_opcode;
2948 if (! addr_op)
2949 bin |= 0x100;
2950 n = op1.exp.X_add_number;
2951 bin |= (n - 1) << 4;
2952 if (is_opcode ("pushm"))
2953 bin |= reg;
2954 else
2955 {
2956 if (reg - n + 1 < 0)
2957 {
2958 as_bad (_("Too many registers popped"));
2959 break;
2960 }
2961
2962 /* CPU21 errata: cannot use POPM to restore the SR register. */
2963 if (target_is_430xv2 ()
2964 && (reg - n + 1 < 3)
2965 && reg >= 2
2966 && is_opcode ("popm"))
2967 {
2968 as_bad (_("Cannot use POPM to restore the SR register"));
2969 break;
2970 }
2971
2972 bin |= (reg - n + 1);
2973 }
2974
2975 bfd_putl16 ((bfd_vma) bin, frag);
2976 dwarf2_emit_insn (op_length);
2977 break;
2978 }
2979
2980 case 6:
2981 {
2982 int n;
2983 int reg;
2984
2985 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
2986 if (extended & 0xff)
2987 {
2988 as_bad (_("repeat count cannot be used with %s"), opcode->name);
2989 break;
2990 }
2991
2992 line = extract_operand (line, l1, sizeof (l1));
2993 line = extract_operand (line, l2, sizeof (l2));
2994
2995 if (*l1 != '#')
2996 {
2997 as_bad (_("expected #n as first argument of %s"), opcode->name);
2998 break;
2999 }
3000 parse_exp (l1 + 1, &(op1.exp));
3001 if (op1.exp.X_op != O_constant)
3002 {
3003 as_bad (_("expected constant expression for first argument of %s"),
3004 opcode->name);
3005 break;
3006 }
3007 n = op1.exp.X_add_number;
3008 if (n > 4 || n < 1)
3009 {
3010 as_bad (_("expected first argument of %s to be in the range 1-4"),
3011 opcode->name);
3012 break;
3013 }
3014
3015 if ((reg = check_reg (l2)) == -1)
3016 {
3017 as_bad (_("expected register as second argument of %s"),
3018 opcode->name);
3019 break;
3020 }
3021
3022 if (target_is_430xv2 () && reg == 0)
3023 {
3024 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3025 break;
3026 }
3027
3028 op_length = 2;
3029 frag = frag_more (op_length);
3030 where = frag - frag_now->fr_literal;
3031
3032 bin = opcode->bin_opcode;
3033 if (! addr_op)
3034 bin |= 0x10;
3035 bin |= (n - 1) << 10;
3036 bin |= reg;
3037
3038 bfd_putl16 ((bfd_vma) bin, frag);
3039 dwarf2_emit_insn (op_length);
3040 break;
3041 }
3042
3043 case 7:
3044 {
3045 int reg;
3046
3047 /* RRUX: Synthetic unsigned right shift of a register by one bit. */
3048 if (extended & 0xff)
3049 {
3050 as_bad (_("repeat count cannot be used with %s"), opcode->name);
3051 break;
3052 }
3053
3054 line = extract_operand (line, l1, sizeof (l1));
3055 if ((reg = check_reg (l1)) == -1)
3056 {
3057 as_bad (_("expected register as argument of %s"),
3058 opcode->name);
3059 break;
3060 }
3061
3062 if (target_is_430xv2 () && reg == 0)
3063 {
3064 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3065 break;
3066 }
3067
3068 if (byte_op)
3069 {
3070 /* Tricky - there is no single instruction that will do this.
3071 Encode as: RRA.B rN { BIC.B #0x80, rN */
3072 op_length = 6;
3073 frag = frag_more (op_length);
3074 where = frag - frag_now->fr_literal;
3075 bin = 0x1140 | reg;
3076 bfd_putl16 ((bfd_vma) bin, frag);
3077 dwarf2_emit_insn (2);
3078 bin = 0xc070 | reg;
3079 bfd_putl16 ((bfd_vma) bin, frag + 2);
3080 bin = 0x0080;
3081 bfd_putl16 ((bfd_vma) bin, frag + 4);
3082 dwarf2_emit_insn (4);
3083 }
3084 else
3085 {
3086 /* Encode as RRUM[.A] rN. */
3087 bin = opcode->bin_opcode;
3088 if (! addr_op)
3089 bin |= 0x10;
3090 bin |= reg;
3091 op_length = 2;
3092 frag = frag_more (op_length);
3093 where = frag - frag_now->fr_literal;
3094 bfd_putl16 ((bfd_vma) bin, frag);
3095 dwarf2_emit_insn (op_length);
3096 }
3097 break;
3098 }
3099
3100 case 8:
3101 {
3102 bfd_boolean need_reloc = FALSE;
3103 int n;
3104 int reg;
3105
3106 /* ADDA, CMPA and SUBA address instructions. */
3107 if (extended & 0xff)
3108 {
3109 as_bad (_("repeat count cannot be used with %s"), opcode->name);
3110 break;
3111 }
3112
3113 line = extract_operand (line, l1, sizeof (l1));
3114 line = extract_operand (line, l2, sizeof (l2));
3115
3116 bin = opcode->bin_opcode;
3117
3118 if (*l1 == '#')
3119 {
3120 parse_exp (l1 + 1, &(op1.exp));
3121
3122 if (op1.exp.X_op == O_constant)
3123 {
3124 n = op1.exp.X_add_number;
3125 if (n > 0xfffff || n < - (0x7ffff))
3126 {
3127 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3128 opcode->name);
3129 break;
3130 }
3131
3132 bin |= ((n >> 16) & 0xf) << 8;
3133 }
3134 else
3135 {
3136 n = 0;
3137 need_reloc = TRUE;
3138 }
3139
3140 op_length = 4;
3141 }
3142 else
3143 {
3144 if ((n = check_reg (l1)) == -1)
3145 {
3146 as_bad (_("expected register name or constant as first argument of %s"),
3147 opcode->name);
3148 break;
3149 }
3150
3151 bin |= (n << 8) | (1 << 6);
3152 op_length = 2;
3153 }
3154
3155 if ((reg = check_reg (l2)) == -1)
3156 {
3157 as_bad (_("expected register as second argument of %s"),
3158 opcode->name);
3159 break;
3160 }
3161
3162 frag = frag_more (op_length);
3163 where = frag - frag_now->fr_literal;
3164 bin |= reg;
3165 if (need_reloc)
3166 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3167 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
3168
3169 bfd_putl16 ((bfd_vma) bin, frag);
3170 if (op_length == 4)
3171 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
3172 dwarf2_emit_insn (op_length);
3173 break;
3174 }
3175
3176 case 9: /* MOVA, BRA, RETA. */
3177 imm_op = FALSE;
3178 bin = opcode->bin_opcode;
3179
3180 if (is_opcode ("reta"))
3181 {
3182 /* The RETA instruction does not take any arguments.
3183 The implicit first argument is @SP+.
3184 The implicit second argument is PC. */
3185 op1.mode = OP_REG;
3186 op1.am = 3;
3187 op1.reg = 1;
3188
3189 op2.mode = OP_REG;
3190 op2.reg = 0;
3191 }
3192 else
3193 {
3194 line = extract_operand (line, l1, sizeof (l1));
3195 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3196 &imm_op, extended_op, FALSE);
3197
3198 if (is_opcode ("bra"))
3199 {
3200 /* This is the BRA synthetic instruction.
3201 The second argument is always PC. */
3202 op2.mode = OP_REG;
3203 op2.reg = 0;
3204 }
3205 else
3206 {
3207 line = extract_operand (line, l2, sizeof (l2));
3208 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
3209 extended_op, TRUE);
3210 }
3211
3212 if (res)
3213 break; /* Error occurred. All warnings were done before. */
3214 }
3215
3216 /* Only a restricted subset of the normal MSP430 addressing modes
3217 are supported here, so check for the ones that are allowed. */
3218 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
3219 & error_message)) == 0)
3220 {
3221 as_bad (error_message, opcode->name);
3222 break;
3223 }
3224 dwarf2_emit_insn (op_length);
3225 break;
3226
3227 case 10: /* RPT */
3228 line = extract_operand (line, l1, sizeof l1);
3229 /* The RPT instruction only accepted immediates and registers. */
3230 if (*l1 == '#')
3231 {
3232 parse_exp (l1 + 1, &(op1.exp));
3233 if (op1.exp.X_op != O_constant)
3234 {
3235 as_bad (_("expected constant value as argument to RPT"));
3236 break;
3237 }
3238 if (op1.exp.X_add_number < 1
3239 || op1.exp.X_add_number > (1 << 4))
3240 {
3241 as_bad (_("expected constant in the range 2..16"));
3242 break;
3243 }
3244
3245 /* We silently accept and ignore a repeat count of 1. */
3246 if (op1.exp.X_add_number > 1)
3247 repeat_count = op1.exp.X_add_number;
3248 }
3249 else
3250 {
3251 int reg;
3252
3253 if ((reg = check_reg (l1)) != -1)
3254 {
3255 if (reg == 0)
3256 as_warn (_("PC used as an argument to RPT"));
3257 else
3258 repeat_count = - reg;
3259 }
3260 else
3261 {
3262 as_bad (_("expected constant or register name as argument to RPT insn"));
3263 break;
3264 }
3265 }
3266 break;
3267
3268 default:
3269 as_bad (_("Illegal emulated instruction "));
3270 break;
3271 }
3272 break;
3273
3274 case 1: /* Format 1, double operand. */
3275 line = extract_operand (line, l1, sizeof (l1));
3276 line = extract_operand (line, l2, sizeof (l2));
3277 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3278 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
3279
3280 if (res)
3281 break; /* Error occurred. All warnings were done before. */
3282
3283 if (extended_op
3284 && is_opcode ("movx")
3285 && addr_op
3286 && msp430_enable_relax)
3287 {
3288 /* This is the MOVX.A instruction. See if we can convert
3289 it into the MOVA instruction instead. This saves 2 bytes. */
3290 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3291 NULL)) != 0)
3292 {
3293 dwarf2_emit_insn (op_length);
3294 break;
3295 }
3296 }
3297
3298 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3299
3300 if ( (is_opcode ("bic") && bin == 0xc232)
3301 || (is_opcode ("bis") && bin == 0xd232)
3302 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
3303 {
3304 if (check_for_nop)
3305 {
3306 if (warn_interrupt_nops)
3307 {
3308 if (gen_interrupt_nops)
3309 as_warn (_("NOP inserted between two instructions that change interrupt state"));
3310 else
3311 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
3312 }
3313
3314 if (gen_interrupt_nops)
3315 {
3316 /* Emit a NOP between interrupt enable/disable.
3317 See 1.3.4.1 of the MSP430x5xx User Guide. */
3318 insn_length += 2;
3319 frag = frag_more (2);
3320 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
3321 }
3322 }
3323
3324 nop_check_needed = TRUE;
3325 }
3326
3327 /* Compute the entire length of the instruction in bytes. */
3328 op_length = (extended_op ? 2 : 0) /* The extension word. */
3329 + 2 /* The opcode */
3330 + (2 * op1.ol) /* The first operand. */
3331 + (2 * op2.ol); /* The second operand. */
3332
3333 insn_length += op_length;
3334 frag = frag_more (op_length);
3335 where = frag - frag_now->fr_literal;
3336
3337 if (extended_op)
3338 {
3339 if (!addr_op)
3340 extended |= BYTE_OPERATION;
3341
3342 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3343 {
3344 as_bad (_("repeat instruction used with non-register mode instruction"));
3345 extended &= ~ 0xf;
3346 }
3347
3348 /* If necessary, emit a reloc to update the extension word. */
3349 if (op1.mode == OP_EXP)
3350 {
3351 if (op1.exp.X_op == O_constant)
3352 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3353
3354 else if (op1.reg || op1.am == 3) /* Not PC relative. */
3355 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3356 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3357 else
3358 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3359 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3360 }
3361
3362 if (op2.mode == OP_EXP)
3363 {
3364 if (op2.exp.X_op == O_constant)
3365 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3366
3367 else if (op1.mode == OP_EXP)
3368 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3369 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3370 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
3371
3372 else
3373 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3374 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3375 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3376 }
3377
3378 /* Emit the extension word. */
3379 bfd_putl16 (extended, frag);
3380 where += 2;
3381 frag += 2;
3382 }
3383
3384 bfd_putl16 ((bfd_vma) bin, frag);
3385 where += 2;
3386 frag += 2;
3387
3388 if (op1.mode == OP_EXP)
3389 {
3390 if (op1.exp.X_op == O_constant)
3391 {
3392 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3393 }
3394 else
3395 {
3396 bfd_putl16 ((bfd_vma) ZEROS, frag);
3397
3398 if (!extended_op)
3399 {
3400 if (op1.reg || op1.am == 3) /* Not PC relative. */
3401 fix_new_exp (frag_now, where, 2,
3402 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3403 else
3404 fix_new_exp (frag_now, where, 2,
3405 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3406 }
3407 }
3408
3409 where += 2;
3410 frag += 2;
3411 }
3412
3413 if (op2.mode == OP_EXP)
3414 {
3415 if (op2.exp.X_op == O_constant)
3416 {
3417 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3418 }
3419 else
3420 {
3421 bfd_putl16 ((bfd_vma) ZEROS, frag);
3422
3423 if (!extended_op)
3424 {
3425 if (op2.reg) /* Not PC relative. */
3426 fix_new_exp (frag_now, where, 2,
3427 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
3428 else
3429 fix_new_exp (frag_now, where, 2,
3430 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3431 }
3432 }
3433 }
3434
3435 dwarf2_emit_insn (insn_length);
3436 break;
3437
3438 case 2: /* Single-operand mostly instr. */
3439 if (opcode->insn_opnumb == 0)
3440 {
3441 /* reti instruction. */
3442 insn_length += 2;
3443 frag = frag_more (2);
3444 bfd_putl16 ((bfd_vma) bin, frag);
3445 dwarf2_emit_insn (insn_length);
3446 break;
3447 }
3448
3449 line = extract_operand (line, l1, sizeof (l1));
3450 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3451 &imm_op, extended_op, TRUE);
3452 if (res)
3453 break; /* Error in operand. */
3454
3455 if (target_is_430xv2 ()
3456 && op1.mode == OP_REG
3457 && op1.reg == 0
3458 && (is_opcode ("rrax")
3459 || is_opcode ("rrcx")
3460 || is_opcode ("rra")
3461 || is_opcode ("rrc")))
3462 {
3463 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
3464 break;
3465 }
3466
3467 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3468 frag = frag_more (insn_length);
3469 where = frag - frag_now->fr_literal;
3470
3471 if (extended_op)
3472 {
3473 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
3474 {
3475 /* These two instructions use a special
3476 encoding of the A/L and B/W bits. */
3477 bin &= ~ BYTE_OPERATION;
3478
3479 if (byte_op)
3480 {
3481 as_bad (_("%s instruction does not accept a .b suffix"),
3482 opcode->name);
3483 break;
3484 }
3485 else if (! addr_op)
3486 extended |= BYTE_OPERATION;
3487 }
3488 else if (! addr_op)
3489 extended |= BYTE_OPERATION;
3490
3491 if (op1.ol != 0 && ((extended & 0xf) != 0))
3492 {
3493 as_bad (_("repeat instruction used with non-register mode instruction"));
3494 extended &= ~ 0xf;
3495 }
3496
3497 if (op1.mode == OP_EXP)
3498 {
3499 if (op1.exp.X_op == O_constant)
3500 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3501
3502 else if (op1.reg || op1.am == 3) /* Not PC relative. */
3503 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3504 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3505 else
3506 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3507 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3508 }
3509
3510 /* Emit the extension word. */
3511 bfd_putl16 (extended, frag);
3512 frag += 2;
3513 where += 2;
3514 }
3515
3516 bin |= op1.reg | (op1.am << 4);
3517 bfd_putl16 ((bfd_vma) bin, frag);
3518 frag += 2;
3519 where += 2;
3520
3521 if (op1.mode == OP_EXP)
3522 {
3523 if (op1.exp.X_op == O_constant)
3524 {
3525 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3526 }
3527 else
3528 {
3529 bfd_putl16 ((bfd_vma) ZEROS, frag);
3530
3531 if (!extended_op)
3532 {
3533 if (op1.reg || op1.am == 3) /* Not PC relative. */
3534 fix_new_exp (frag_now, where, 2,
3535 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
3536 else
3537 fix_new_exp (frag_now, where, 2,
3538 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3539 }
3540 }
3541 }
3542
3543 dwarf2_emit_insn (insn_length);
3544 break;
3545
3546 case 3: /* Conditional jumps instructions. */
3547 line = extract_operand (line, l1, sizeof (l1));
3548 /* l1 is a label. */
3549 if (l1[0])
3550 {
3551 char *m = l1;
3552 expressionS exp;
3553
3554 if (*m == '$')
3555 m++;
3556
3557 parse_exp (m, &exp);
3558
3559 /* In order to handle something like:
3560
3561 and #0x8000, r5
3562 tst r5
3563 jz 4 ; skip next 4 bytes
3564 inv r5
3565 inc r5
3566 nop ; will jump here if r5 positive or zero
3567
3568 jCOND -n ;assumes jump n bytes backward:
3569
3570 mov r5,r6
3571 jmp -2
3572
3573 is equal to:
3574 lab:
3575 mov r5,r6
3576 jmp lab
3577
3578 jCOND $n ; jump from PC in either direction. */
3579
3580 if (exp.X_op == O_constant)
3581 {
3582 int x = exp.X_add_number;
3583
3584 if (x & 1)
3585 {
3586 as_warn (_("Even number required. Rounded to %d"), x + 1);
3587 x++;
3588 }
3589
3590 if ((*l1 == '$' && x > 0) || x < 0)
3591 x -= 2;
3592
3593 x >>= 1;
3594
3595 if (x > 512 || x < -511)
3596 {
3597 as_bad (_("Wrong displacement %d"), x << 1);
3598 break;
3599 }
3600
3601 insn_length += 2;
3602 frag = frag_more (2); /* Instr size is 1 word. */
3603
3604 bin |= x & 0x3ff;
3605 bfd_putl16 ((bfd_vma) bin, frag);
3606 }
3607 else if (exp.X_op == O_symbol && *l1 != '$')
3608 {
3609 insn_length += 2;
3610 frag = frag_more (2); /* Instr size is 1 word. */
3611 where = frag - frag_now->fr_literal;
3612 fix_new_exp (frag_now, where, 2,
3613 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3614
3615 bfd_putl16 ((bfd_vma) bin, frag);
3616 }
3617 else if (*l1 == '$')
3618 {
3619 as_bad (_("instruction requires label sans '$'"));
3620 }
3621 else
3622 as_bad (_
3623 ("instruction requires label or value in range -511:512"));
3624 dwarf2_emit_insn (insn_length);
3625 break;
3626 }
3627 else
3628 {
3629 as_bad (_("instruction requires label"));
3630 break;
3631 }
3632 break;
3633
3634 case 4: /* Extended jumps. */
3635 if (!msp430_enable_polys)
3636 {
3637 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3638 break;
3639 }
3640
3641 line = extract_operand (line, l1, sizeof (l1));
3642 if (l1[0])
3643 {
3644 char *m = l1;
3645 expressionS exp;
3646
3647 /* Ignore absolute addressing. make it PC relative anyway. */
3648 if (*m == '#' || *m == '$')
3649 m++;
3650
3651 parse_exp (m, & exp);
3652 if (exp.X_op == O_symbol)
3653 {
3654 /* Relaxation required. */
3655 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3656
3657 if (target_is_430x ())
3658 rc = msp430x_rcodes[opcode->insn_opnumb];
3659
3660 /* The parameter to dwarf2_emit_insn is actually the offset to
3661 the start of the insn from the fix piece of instruction that
3662 was emitted. Since next fragments may have variable size we
3663 tie debug info to the beginning of the instruction. */
3664 insn_length += 8;
3665 frag = frag_more (8);
3666 dwarf2_emit_insn (0);
3667 bfd_putl16 ((bfd_vma) rc.sop, frag);
3668 frag = frag_variant (rs_machine_dependent, 8, 2,
3669 /* Wild guess. */
3670 ENCODE_RELAX (rc.lpos, STATE_BITS10),
3671 exp.X_add_symbol,
3672 0, /* Offset is zero if jump dist less than 1K. */
3673 (char *) frag);
3674 break;
3675 }
3676 }
3677
3678 as_bad (_("instruction requires label"));
3679 break;
3680
3681 case 5: /* Emulated extended branches. */
3682 if (!msp430_enable_polys)
3683 {
3684 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
3685 break;
3686 }
3687 line = extract_operand (line, l1, sizeof (l1));
3688 if (l1[0])
3689 {
3690 char * m = l1;
3691 expressionS exp;
3692
3693 /* Ignore absolute addressing. make it PC relative anyway. */
3694 if (*m == '#' || *m == '$')
3695 m++;
3696
3697 parse_exp (m, & exp);
3698 if (exp.X_op == O_symbol)
3699 {
3700 /* Relaxation required. */
3701 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3702
3703 if (target_is_430x ())
3704 hc = msp430x_hcodes[opcode->insn_opnumb];
3705
3706 insn_length += 8;
3707 frag = frag_more (8);
3708 dwarf2_emit_insn (0);
3709 bfd_putl16 ((bfd_vma) hc.op0, frag);
3710 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3711
3712 frag = frag_variant (rs_machine_dependent, 8, 2,
3713 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3714 exp.X_add_symbol,
3715 0, /* Offset is zero if jump dist less than 1K. */
3716 (char *) frag);
3717 break;
3718 }
3719 }
3720
3721 as_bad (_("instruction requires label"));
3722 break;
3723
3724 default:
3725 as_bad (_("Illegal instruction or not implemented opcode."));
3726 }
3727
3728 input_line_pointer = line;
3729 check_for_nop = nop_check_needed;
3730 return 0;
3731}
3732
3733void
3734md_assemble (char * str)
3735{
3736 struct msp430_opcode_s * opcode;
3737 char cmd[32];
3738 unsigned int i = 0;
3739
3740 str = skip_space (str); /* Skip leading spaces. */
3741 str = extract_cmd (str, cmd, sizeof (cmd) - 1);
3742
3743 while (cmd[i])
3744 {
3745 char a = TOLOWER (cmd[i]);
3746 cmd[i] = a;
3747 i++;
3748 }
3749
3750 if (!cmd[0])
3751 {
3752 as_bad (_("can't find opcode "));
3753 return;
3754 }
3755
3756 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3757
3758 if (opcode == NULL)
3759 {
3760 as_bad (_("unknown opcode `%s'"), cmd);
3761 return;
3762 }
3763
3764 {
3765 char *__t = input_line_pointer;
3766
3767 msp430_operands (opcode, str);
3768 input_line_pointer = __t;
3769 }
3770}
3771
3772/* GAS will call this function for each section at the end of the assembly,
3773 to permit the CPU backend to adjust the alignment of a section. */
3774
3775valueT
3776md_section_align (asection * seg, valueT addr)
3777{
3778 int align = bfd_get_section_alignment (stdoutput, seg);
3779
3780 return ((addr + (1 << align) - 1) & (-1 << align));
3781}
3782
3783/* If you define this macro, it should return the offset between the
3784 address of a PC relative fixup and the position from which the PC
3785 relative adjustment should be made. On many processors, the base
3786 of a PC relative instruction is the next instruction, so this
3787 macro would return the length of an instruction. */
3788
3789long
3790md_pcrel_from_section (fixS * fixp, segT sec)
3791{
3792 if (fixp->fx_addsy != (symbolS *) NULL
3793 && (!S_IS_DEFINED (fixp->fx_addsy)
3794 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3795 return 0;
3796
3797 return fixp->fx_frag->fr_address + fixp->fx_where;
3798}
3799
3800/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3801 Now it handles the situation when relocations
3802 have to be passed to linker. */
3803int
3804msp430_force_relocation_local (fixS *fixp)
3805{
3806 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3807 return 1;
3808 if (fixp->fx_pcrel)
3809 return 1;
3810 if (msp430_enable_polys
3811 && !msp430_enable_relax)
3812 return 1;
3813
3814 return (!fixp->fx_pcrel
3815 || generic_force_reloc (fixp));
3816}
3817
3818
3819/* GAS will call this for each fixup. It should store the correct
3820 value in the object file. */
3821void
3822md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3823{
3824 unsigned char * where;
3825 unsigned long insn;
3826 long value;
3827
3828 if (fixp->fx_addsy == (symbolS *) NULL)
3829 {
3830 value = *valuep;
3831 fixp->fx_done = 1;
3832 }
3833 else if (fixp->fx_pcrel)
3834 {
3835 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3836
3837 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3838 {
3839 /* FIXME: We can appear here only in case if we perform a pc
3840 relative jump to the label which is i) global, ii) locally
3841 defined or this is a jump to an absolute symbol.
3842 If this is an absolute symbol -- everything is OK.
3843 If this is a global label, we've got a symbol value defined
3844 twice:
3845 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
3846 from this section start
3847 2. *valuep will contain the real offset from jump insn to the
3848 label
3849 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
3850 will be incorrect. Therefore remove s_get_value. */
3851 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
3852 fixp->fx_done = 1;
3853 }
3854 else
3855 value = *valuep;
3856 }
3857 else
3858 {
3859 value = fixp->fx_offset;
3860
3861 if (fixp->fx_subsy != (symbolS *) NULL)
3862 {
3863 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
3864 {
3865 value -= S_GET_VALUE (fixp->fx_subsy);
3866 fixp->fx_done = 1;
3867 }
3868 }
3869 }
3870
3871 fixp->fx_no_overflow = 1;
3872
3873 /* If polymorphs are enabled and relax disabled.
3874 do not kill any relocs and pass them to linker. */
3875 if (msp430_enable_polys
3876 && !msp430_enable_relax)
3877 {
3878 if (!fixp->fx_addsy
3879 || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
3880 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
3881 else
3882 fixp->fx_done = 0;
3883 }
3884
3885 if (fixp->fx_done)
3886 {
3887 /* Fetch the instruction, insert the fully resolved operand
3888 value, and stuff the instruction back again. */
3889 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
3890
3891 insn = bfd_getl16 (where);
3892
3893 switch (fixp->fx_r_type)
3894 {
3895 case BFD_RELOC_MSP430_10_PCREL:
3896 if (value & 1)
3897 as_bad_where (fixp->fx_file, fixp->fx_line,
3898 _("odd address operand: %ld"), value);
3899
3900 /* Jumps are in words. */
3901 value >>= 1;
3902 --value; /* Correct PC. */
3903
3904 if (value < -512 || value > 511)
3905 as_bad_where (fixp->fx_file, fixp->fx_line,
3906 _("operand out of range: %ld"), value);
3907
3908 value &= 0x3ff; /* get rid of extended sign */
3909 bfd_putl16 ((bfd_vma) (value | insn), where);
3910 break;
3911
3912 case BFD_RELOC_MSP430X_PCR16:
3913 case BFD_RELOC_MSP430_RL_PCREL:
3914 case BFD_RELOC_MSP430_16_PCREL:
3915 if (value & 1)
3916 as_bad_where (fixp->fx_file, fixp->fx_line,
3917 _("odd address operand: %ld"), value);
3918 /* Fall through. */
3919
3920 case BFD_RELOC_MSP430_16_PCREL_BYTE:
3921 /* Nothing to be corrected here. */
3922 if (value < -32768 || value > 65536)
3923 as_bad_where (fixp->fx_file, fixp->fx_line,
3924 _("operand out of range: %ld"), value);
3925 /* Fall through. */
3926
3927 case BFD_RELOC_MSP430X_ABS16:
3928 case BFD_RELOC_MSP430_16:
3929 case BFD_RELOC_16:
3930 case BFD_RELOC_MSP430_16_BYTE:
3931 value &= 0xffff; /* Get rid of extended sign. */
3932 bfd_putl16 ((bfd_vma) value, where);
3933 break;
3934
3935 case BFD_RELOC_MSP430_ABS_HI16:
3936 value >>= 16;
3937 value &= 0xffff; /* Get rid of extended sign. */
3938 bfd_putl16 ((bfd_vma) value, where);
3939 break;
3940
3941 case BFD_RELOC_32:
3942 bfd_putl16 ((bfd_vma) value, where);
3943 break;
3944
3945 case BFD_RELOC_MSP430_ABS8:
3946 case BFD_RELOC_8:
3947 bfd_put_8 (NULL, (bfd_vma) value, where);
3948 break;
3949
3950 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
3951 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
3952 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3953 value >>= 16;
3954 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
3955 break;
3956
3957 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
3958 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3959 value >>= 16;
3960 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
3961 break;
3962
3963 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
3964 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3965 value >>= 16;
3966 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3967 break;
3968
3969 case BFD_RELOC_MSP430X_PCR20_CALL:
3970 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3971 value >>= 16;
3972 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3973 break;
3974
3975 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
3976 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
3977 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3978 value >>= 16;
3979 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3980 break;
3981
3982 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
3983 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3984 value >>= 16;
3985 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3986 break;
3987
3988 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
3989 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3990 value >>= 16;
3991 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
3992 break;
3993
3994 default:
3995 as_fatal (_("line %d: unknown relocation type: 0x%x"),
3996 fixp->fx_line, fixp->fx_r_type);
3997 break;
3998 }
3999 }
4000 else
4001 {
4002 fixp->fx_addnumber = value;
4003 }
4004}
4005
4006static bfd_boolean
4007S_IS_GAS_LOCAL (symbolS * s)
4008{
4009 const char * name;
4010 unsigned int len;
4011
4012 if (s == NULL)
4013 return FALSE;
4014 name = S_GET_NAME (s);
4015 len = strlen (name) - 1;
4016
4017 return name[len] == 1 || name[len] == 2;
4018}
4019
4020/* GAS will call this to generate a reloc, passing the resulting reloc
4021 to `bfd_install_relocation'. This currently works poorly, as
4022 `bfd_install_relocation' often does the wrong thing, and instances of
4023 `tc_gen_reloc' have been written to work around the problems, which
4024 in turns makes it difficult to fix `bfd_install_relocation'. */
4025
4026/* If while processing a fixup, a reloc really needs to be created
4027 then it is done here. */
4028
4029arelent **
4030tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
4031{
4032 static arelent * no_relocs = NULL;
4033 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
4034 arelent *reloc;
4035
4036 reloc = xmalloc (sizeof (arelent));
4037 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4038 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
4039
4040 if (reloc->howto == (reloc_howto_type *) NULL)
4041 {
4042 as_bad_where (fixp->fx_file, fixp->fx_line,
4043 _("reloc %d not supported by object file format"),
4044 (int) fixp->fx_r_type);
4045 free (reloc);
4046 return & no_relocs;
4047 }
4048
4049 relocs[0] = reloc;
4050 relocs[1] = NULL;
4051
4052 if (fixp->fx_subsy
4053 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4054 {
4055 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
4056 fixp->fx_subsy = NULL;
4057 }
4058
4059 if (fixp->fx_addsy && fixp->fx_subsy)
4060 {
4061 asection *asec, *ssec;
4062
4063 asec = S_GET_SEGMENT (fixp->fx_addsy);
4064 ssec = S_GET_SEGMENT (fixp->fx_subsy);
4065
4066 /* If we have a difference between two different, non-absolute symbols
4067 we must generate two relocs (one for each symbol) and allow the
4068 linker to resolve them - relaxation may change the distances between
4069 symbols, even local symbols defined in the same section.
4070
4071 Unfortunately we cannot do this with assembler generated local labels
4072 because there can be multiple incarnations of the same label, with
4073 exactly the same name, in any given section and the linker will have
4074 no way to identify the correct one. Instead we just have to hope
4075 that no relaxtion will occur between the local label and the other
4076 symbol in the expression.
4077
4078 Similarly we have to compute differences between symbols in the .eh_frame
4079 section as the linker is not smart enough to apply relocations there
4080 before attempting to process it. */
4081 if ((ssec != absolute_section || asec != absolute_section)
4082 && (fixp->fx_addsy != fixp->fx_subsy)
4083 && strcmp (ssec->name, ".eh_frame") != 0
4084 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
4085 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
4086 {
4087 arelent * reloc2 = xmalloc (sizeof * reloc);
4088
4089 relocs[0] = reloc2;
4090 relocs[1] = reloc;
4091
4092 reloc2->address = reloc->address;
4093 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
4094 BFD_RELOC_MSP430_SYM_DIFF);
4095 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
4096
4097 if (ssec == absolute_section)
4098 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4099 else
4100 {
4101 reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
4102 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
4103 }
4104
4105 reloc->addend = fixp->fx_offset;
4106 if (asec == absolute_section)
4107 {
4108 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
4109 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4110 }
4111 else
4112 {
4113 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
4114 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4115 }
4116
4117 fixp->fx_pcrel = 0;
4118 fixp->fx_done = 1;
4119 return relocs;
4120 }
4121 else
4122 {
4123 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4124
4125 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
4126 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
4127
4128 switch (fixp->fx_r_type)
4129 {
4130 case BFD_RELOC_8:
4131 md_number_to_chars (fixpos, reloc->addend, 1);
4132 break;
4133
4134 case BFD_RELOC_16:
4135 md_number_to_chars (fixpos, reloc->addend, 2);
4136 break;
4137
4138 case BFD_RELOC_24:
4139 md_number_to_chars (fixpos, reloc->addend, 3);
4140 break;
4141
4142 case BFD_RELOC_32:
4143 md_number_to_chars (fixpos, reloc->addend, 4);
4144 break;
4145
4146 default:
4147 reloc->sym_ptr_ptr
4148 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
4149 return relocs;
4150 }
4151
4152 free (reloc);
4153 return & no_relocs;
4154 }
4155 }
4156 else
4157 {
4158#if 0
4159 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
4160 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
4161 {
4162 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
4163 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4164
4165 md_number_to_chars (fixpos, amount, 2);
4166 free (reloc);
4167 return & no_relocs;
4168 }
4169#endif
4170 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
4171 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4172 reloc->addend = fixp->fx_offset;
4173
4174 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
4175 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
4176 reloc->address = fixp->fx_offset;
4177 }
4178
4179 return relocs;
4180}
4181
4182int
4183md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
4184 asection * segment_type ATTRIBUTE_UNUSED)
4185{
4186 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
4187 {
4188 /* This is a jump -> pcrel mode. Nothing to do much here.
4189 Return value == 2. */
4190 fragP->fr_subtype =
4191 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
4192 }
4193 else if (fragP->fr_symbol)
4194 {
4195 /* Its got a segment, but its not ours. Even if fr_symbol is in
4196 an absolute segment, we don't know a displacement until we link
4197 object files. So it will always be long. This also applies to
4198 labels in a subsegment of current. Liker may relax it to short
4199 jump later. Return value == 8. */
4200 fragP->fr_subtype =
4201 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
4202 }
4203 else
4204 {
4205 /* We know the abs value. may be it is a jump to fixed address.
4206 Impossible in our case, cause all constants already handled. */
4207 fragP->fr_subtype =
4208 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
4209 }
4210
4211 return md_relax_table[fragP->fr_subtype].rlx_length;
4212}
4213
4214void
4215md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
4216 asection * sec ATTRIBUTE_UNUSED,
4217 fragS * fragP)
4218{
4219 char * where = 0;
4220 int rela = -1;
4221 int i;
4222 struct rcodes_s * cc = NULL;
4223 struct hcodes_s * hc = NULL;
4224
4225 switch (fragP->fr_subtype)
4226 {
4227 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
4228 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
4229 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
4230 /* We do not have to convert anything here.
4231 Just apply a fix. */
4232 rela = BFD_RELOC_MSP430_10_PCREL;
4233 break;
4234
4235 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
4236 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
4237 /* Convert uncond branch jmp lab -> br lab. */
4238 if (target_is_430x ())
4239 cc = msp430x_rcodes + 7;
4240 else
4241 cc = msp430_rcodes + 7;
4242 where = fragP->fr_literal + fragP->fr_fix;
4243 bfd_putl16 (cc->lop0, where);
4244 rela = BFD_RELOC_MSP430_RL_PCREL;
4245 fragP->fr_fix += 2;
4246 break;
4247
4248 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
4249 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
4250 {
4251 /* Other simple branches. */
4252 int insn = bfd_getl16 (fragP->fr_opcode);
4253
4254 insn &= 0xffff;
4255 /* Find actual instruction. */
4256 if (target_is_430x ())
4257 {
4258 for (i = 0; i < 7 && !cc; i++)
4259 if (msp430x_rcodes[i].sop == insn)
4260 cc = msp430x_rcodes + i;
4261 }
4262 else
4263 {
4264 for (i = 0; i < 7 && !cc; i++)
4265 if (msp430_rcodes[i].sop == insn)
4266 cc = & msp430_rcodes[i];
4267 }
4268
4269 if (!cc || !cc->name)
4270 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4271 __FUNCTION__, (long) insn);
4272 where = fragP->fr_literal + fragP->fr_fix;
4273 bfd_putl16 (cc->lop0, where);
4274 bfd_putl16 (cc->lop1, where + 2);
4275 rela = BFD_RELOC_MSP430_RL_PCREL;
4276 fragP->fr_fix += 4;
4277 }
4278 break;
4279
4280 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
4281 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
4282 if (target_is_430x ())
4283 cc = msp430x_rcodes + 6;
4284 else
4285 cc = msp430_rcodes + 6;
4286 where = fragP->fr_literal + fragP->fr_fix;
4287 bfd_putl16 (cc->lop0, where);
4288 bfd_putl16 (cc->lop1, where + 2);
4289 bfd_putl16 (cc->lop2, where + 4);
4290 rela = BFD_RELOC_MSP430_RL_PCREL;
4291 fragP->fr_fix += 6;
4292 break;
4293
4294 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4295 {
4296 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4297
4298 insn &= 0xffff;
4299 if (target_is_430x ())
4300 {
4301 for (i = 0; i < 4 && !hc; i++)
4302 if (msp430x_hcodes[i].op1 == insn)
4303 hc = msp430x_hcodes + i;
4304 }
4305 else
4306 {
4307 for (i = 0; i < 4 && !hc; i++)
4308 if (msp430_hcodes[i].op1 == insn)
4309 hc = &msp430_hcodes[i];
4310 }
4311 if (!hc || !hc->name)
4312 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4313 __FUNCTION__, (long) insn);
4314 rela = BFD_RELOC_MSP430_10_PCREL;
4315 /* Apply a fix for a first label if necessary.
4316 another fix will be applied to the next word of insn anyway. */
4317 if (hc->tlab == 2)
4318 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4319 fragP->fr_offset, TRUE, rela);
4320 fragP->fr_fix += 2;
4321 }
4322
4323 break;
4324
4325 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4326 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4327 {
4328 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4329
4330 insn &= 0xffff;
4331 if (target_is_430x ())
4332 {
4333 for (i = 0; i < 4 && !hc; i++)
4334 if (msp430x_hcodes[i].op1 == insn)
4335 hc = msp430x_hcodes + i;
4336 }
4337 else
4338 {
4339 for (i = 0; i < 4 && !hc; i++)
4340 if (msp430_hcodes[i].op1 == insn)
4341 hc = & msp430_hcodes[i];
4342 }
4343 if (!hc || !hc->name)
4344 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4345 __FUNCTION__, (long) insn);
4346 rela = BFD_RELOC_MSP430_RL_PCREL;
4347 where = fragP->fr_literal + fragP->fr_fix;
4348 bfd_putl16 (hc->lop0, where);
4349 bfd_putl16 (hc->lop1, where + 2);
4350 bfd_putl16 (hc->lop2, where + 4);
4351 fragP->fr_fix += 6;
4352 }
4353 break;
4354
4355 default:
4356 as_fatal (_("internal inconsistency problem in %s: %lx"),
4357 __FUNCTION__, (long) fragP->fr_subtype);
4358 break;
4359 }
4360
4361 /* Now apply fix. */
4362 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4363 fragP->fr_offset, TRUE, rela);
4364 /* Just fixed 2 bytes. */
4365 fragP->fr_fix += 2;
4366}
4367
4368/* Relax fragment. Mostly stolen from hc11 and mcore
4369 which arches I think I know. */
4370
4371long
4372msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4373 long stretch ATTRIBUTE_UNUSED)
4374{
4375 long growth;
4376 offsetT aim = 0;
4377 symbolS *symbolP;
4378 const relax_typeS *this_type;
4379 const relax_typeS *start_type;
4380 relax_substateT next_state;
4381 relax_substateT this_state;
4382 const relax_typeS *table = md_relax_table;
4383
4384 /* Nothing to be done if the frag has already max size. */
4385 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4386 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4387 return 0;
4388
4389 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4390 {
4391 symbolP = fragP->fr_symbol;
4392 if (symbol_resolved_p (symbolP))
4393 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4394 __FUNCTION__);
4395 /* We know the offset. calculate a distance. */
4396 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4397 }
4398
4399 if (!msp430_enable_relax)
4400 {
4401 /* Relaxation is not enabled. So, make all jump as long ones
4402 by setting 'aim' to quite high value. */
4403 aim = 0x7fff;
4404 }
4405
4406 this_state = fragP->fr_subtype;
4407 start_type = this_type = table + this_state;
4408
4409 if (aim < 0)
4410 {
4411 /* Look backwards. */
4412 for (next_state = this_type->rlx_more; next_state;)
4413 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
4414 next_state = 0;
4415 else
4416 {
4417 /* Grow to next state. */
4418 this_state = next_state;
4419 this_type = table + this_state;
4420 next_state = this_type->rlx_more;
4421 }
4422 }
4423 else
4424 {
4425 /* Look forwards. */
4426 for (next_state = this_type->rlx_more; next_state;)
4427 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
4428 next_state = 0;
4429 else
4430 {
4431 /* Grow to next state. */
4432 this_state = next_state;
4433 this_type = table + this_state;
4434 next_state = this_type->rlx_more;
4435 }
4436 }
4437
4438 growth = this_type->rlx_length - start_type->rlx_length;
4439 if (growth != 0)
4440 fragP->fr_subtype = this_state;
4441 return growth;
4442}
4443
4444/* Return FALSE if the fixup in fixp should be left alone and not
4445 adjusted. We return FALSE here so that linker relaxation will
4446 work. */
4447
4448bfd_boolean
4449msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4450{
4451 /* If the symbol is in a non-code section then it should be OK. */
4452 if (fixp->fx_addsy
4453 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4454 return TRUE;
4455
4456 return FALSE;
4457}
4458
4459/* Set the contents of the .MSP430.attributes section. */
4460
4461void
4462msp430_md_end (void)
4463{
4464 if (check_for_nop == TRUE && warn_interrupt_nops)
4465 as_warn ("assembly finished with the last instruction changing interrupt state - a NOP might be needed");
4466
4467 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
4468 target_is_430x () ? 2 : 1);
4469
4470 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4471 large_model ? 2 : 1);
4472
4473 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4474 large_model ? 2 : 1);
4475}
4476
4477/* Returns FALSE if there is a msp430 specific reason why the
4478 subtraction of two same-section symbols cannot be computed by
4479 the assembler. */
4480
4481bfd_boolean
4482msp430_allow_local_subtract (expressionS * left,
4483 expressionS * right,
4484 segT section)
4485{
4486 /* If the symbols are not in a code section then they are OK. */
4487 if ((section->flags & SEC_CODE) == 0)
4488 return TRUE;
4489
4490 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4491 return TRUE;
4492
4493 if (left->X_add_symbol == right->X_add_symbol)
4494 return TRUE;
4495
4496 /* We have to assume that there may be instructions between the
4497 two symbols and that relaxation may increase the distance between
4498 them. */
4499 return FALSE;
4500}
This page took 0.036795 seconds and 4 git commands to generate.