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