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