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