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