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