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