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