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