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