Bump version to 2.28.51
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
CommitLineData
2469cfa2
NC
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
6f2750fe 3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
2469cfa2
NC
4 Contributed by Dmitry Diky <diwil@mail.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
2469cfa2
NC
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
2469cfa2 22
df7b86aa 23#include "as.h"
2469cfa2 24#include <limits.h>
2469cfa2
NC
25#include "subsegs.h"
26#include "opcode/msp430.h"
27#include "safe-ctype.h"
2a9a06c1 28#include "dwarf2dbg.h"
13761a11 29#include "elf/msp430.h"
ede77e69 30#include "libiberty.h"
2469cfa2 31
79cf5950 32/* We will disable polymorphs by default because it is dangerous.
708587a4 33 The potential problem here is the following: assume we got the
77592908
DD
34 following code:
35
36 jump .l1
37 nop
38 jump subroutine ; external symbol
39 .l1:
40 nop
41 ret
13761a11 42
77592908
DD
43 In case of assembly time relaxation we'll get:
44 0: jmp .l1 <.text +0x08> (reloc deleted)
45 2: nop
46 4: br subroutine
47 .l1:
48 8: nop
49 10: ret
50
79cf5950
NC
51 If the 'subroutine' is within +-1024 bytes range then linker
52 will produce:
77592908
DD
53 0: jmp .text +0x08
54 2: nop
55 4: jmp subroutine
56 .l1:
57 6: nop
58 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
59
77592908 60 The workaround is the following:
79cf5950 61 1. Declare global var enable_polymorphs which set to 1 via option -mp.
77592908
DD
62 2. Declare global var enable_relax which set to 1 via option -mQ.
63
64 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
65 do not delete any relocs and leave them for linker.
13761a11 66
79cf5950 67 If relax is enabled, relax at assembly time and kill relocs as necessary. */
77592908
DD
68
69int msp430_enable_relax;
70int msp430_enable_polys;
71
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.
297 For the 430X we generate a relocation without linkwer range checking.
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. */
615 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
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.
709 The data in this structure has been extracted from the devices.csv file
b27c40ec 710 released by TI, updated as of March 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 },
b27c40ec
NC
1136 { "msp430fr2310",2,0 },
1137 { "msp430fr2311",2,0 },
ede77e69 1138 { "msp430fr2433",2,8 },
b27c40ec
NC
1139 { "msp430fr2532",2,8 },
1140 { "msp430fr2533",2,8 },
1141 { "msp430fr2632",2,8 },
1142 { "msp430fr2633",2,8 },
ede77e69
NC
1143 { "msp430fr2xx_4xxgeneric",2,8 },
1144 { "msp430fr4131",2,0 },
1145 { "msp430fr4132",2,0 },
1146 { "msp430fr4133",2,0 },
1147 { "msp430fr5720",2,8 },
1148 { "msp430fr5721",2,8 },
1149 { "msp430fr5722",2,8 },
1150 { "msp430fr5723",2,8 },
1151 { "msp430fr5724",2,8 },
1152 { "msp430fr5725",2,8 },
1153 { "msp430fr5726",2,8 },
1154 { "msp430fr5727",2,8 },
1155 { "msp430fr5728",2,8 },
1156 { "msp430fr5729",2,8 },
1157 { "msp430fr5730",2,8 },
1158 { "msp430fr5731",2,8 },
1159 { "msp430fr5732",2,8 },
1160 { "msp430fr5733",2,8 },
1161 { "msp430fr5734",2,8 },
1162 { "msp430fr5735",2,8 },
1163 { "msp430fr5736",2,8 },
1164 { "msp430fr5737",2,8 },
1165 { "msp430fr5738",2,8 },
1166 { "msp430fr5739",2,8 },
1167 { "msp430fr57xxgeneric",2,8 },
1168 { "msp430fr5847",2,8 },
1169 { "msp430fr58471",2,8 },
1170 { "msp430fr5848",2,8 },
1171 { "msp430fr5849",2,8 },
1172 { "msp430fr5857",2,8 },
1173 { "msp430fr5858",2,8 },
1174 { "msp430fr5859",2,8 },
1175 { "msp430fr5867",2,8 },
b27c40ec
NC
1176 { "msp430fr5862",2,8 },
1177 { "msp430fr5864",2,8 },
ede77e69
NC
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 },
b27c40ec
NC
1188 { "msp430fr5892",2,8 },
1189 { "msp430fr5894",2,8 },
ede77e69
NC
1190 { "msp430fr5922",2,8 },
1191 { "msp430fr59221",2,8 },
1192 { "msp430fr5947",2,8 },
1193 { "msp430fr59471",2,8 },
1194 { "msp430fr5948",2,8 },
1195 { "msp430fr5949",2,8 },
1196 { "msp430fr5957",2,8 },
1197 { "msp430fr5958",2,8 },
1198 { "msp430fr5959",2,8 },
b27c40ec
NC
1199 { "msp430fr5962",2,8 },
1200 { "msp430fr5964",2,8 },
ede77e69
NC
1201 { "msp430fr5967",2,8 },
1202 { "msp430fr5968",2,8 },
1203 { "msp430fr5969",2,8 },
1204 { "msp430fr59691",2,8 },
1205 { "msp430fr5970",2,8 },
1206 { "msp430fr5972",2,8 },
1207 { "msp430fr59721",2,8 },
1208 { "msp430fr5986",2,8 },
1209 { "msp430fr5987",2,8 },
1210 { "msp430fr5988",2,8 },
1211 { "msp430fr5989",2,8 },
1212 { "msp430fr59891",2,8 },
b27c40ec
NC
1213 { "msp430fr5992",2,8 },
1214 { "msp430fr5994",2,8 },
ede77e69
NC
1215 { "msp430fr5xx_6xxgeneric",2,8 },
1216 { "msp430fr6820",2,8 },
1217 { "msp430fr6822",2,8 },
1218 { "msp430fr68221",2,8 },
1219 { "msp430fr6870",2,8 },
1220 { "msp430fr6872",2,8 },
1221 { "msp430fr68721",2,8 },
1222 { "msp430fr6877",2,8 },
1223 { "msp430fr6879",2,8 },
1224 { "msp430fr68791",2,8 },
1225 { "msp430fr6887",2,8 },
1226 { "msp430fr6888",2,8 },
1227 { "msp430fr6889",2,8 },
1228 { "msp430fr68891",2,8 },
1229 { "msp430fr6920",2,8 },
1230 { "msp430fr6922",2,8 },
1231 { "msp430fr69221",2,8 },
1232 { "msp430fr6927",2,8 },
1233 { "msp430fr69271",2,8 },
1234 { "msp430fr6928",2,8 },
1235 { "msp430fr6970",2,8 },
1236 { "msp430fr6972",2,8 },
1237 { "msp430fr69721",2,8 },
1238 { "msp430fr6977",2,8 },
1239 { "msp430fr6979",2,8 },
1240 { "msp430fr69791",2,8 },
1241 { "msp430fr6987",2,8 },
1242 { "msp430fr6988",2,8 },
1243 { "msp430fr6989",2,8 },
1244 { "msp430fr69891",2,8 },
1245 { "msp430fw423",0,0 },
1246 { "msp430fw425",0,0 },
1247 { "msp430fw427",0,0 },
1248 { "msp430fw428",0,0 },
1249 { "msp430fw429",0,0 },
1250 { "msp430g2001",0,0 },
1251 { "msp430g2101",0,0 },
1252 { "msp430g2102",0,0 },
1253 { "msp430g2111",0,0 },
1254 { "msp430g2112",0,0 },
1255 { "msp430g2113",0,0 },
1256 { "msp430g2121",0,0 },
1257 { "msp430g2131",0,0 },
1258 { "msp430g2132",0,0 },
1259 { "msp430g2152",0,0 },
1260 { "msp430g2153",0,0 },
1261 { "msp430g2201",0,0 },
1262 { "msp430g2202",0,0 },
1263 { "msp430g2203",0,0 },
1264 { "msp430g2210",0,0 },
1265 { "msp430g2211",0,0 },
1266 { "msp430g2212",0,0 },
1267 { "msp430g2213",0,0 },
1268 { "msp430g2221",0,0 },
1269 { "msp430g2230",0,0 },
1270 { "msp430g2231",0,0 },
1271 { "msp430g2232",0,0 },
1272 { "msp430g2233",0,0 },
1273 { "msp430g2252",0,0 },
1274 { "msp430g2253",0,0 },
1275 { "msp430g2302",0,0 },
1276 { "msp430g2303",0,0 },
1277 { "msp430g2312",0,0 },
1278 { "msp430g2313",0,0 },
1279 { "msp430g2332",0,0 },
1280 { "msp430g2333",0,0 },
1281 { "msp430g2352",0,0 },
1282 { "msp430g2353",0,0 },
1283 { "msp430g2402",0,0 },
1284 { "msp430g2403",0,0 },
1285 { "msp430g2412",0,0 },
1286 { "msp430g2413",0,0 },
1287 { "msp430g2432",0,0 },
1288 { "msp430g2433",0,0 },
1289 { "msp430g2444",0,0 },
1290 { "msp430g2452",0,0 },
1291 { "msp430g2453",0,0 },
1292 { "msp430g2513",0,0 },
1293 { "msp430g2533",0,0 },
1294 { "msp430g2544",0,0 },
1295 { "msp430g2553",0,0 },
1296 { "msp430g2744",0,0 },
1297 { "msp430g2755",0,0 },
1298 { "msp430g2855",0,0 },
1299 { "msp430g2955",0,0 },
1300 { "msp430i2020",0,2 },
1301 { "msp430i2021",0,2 },
1302 { "msp430i2030",0,2 },
1303 { "msp430i2031",0,2 },
1304 { "msp430i2040",0,2 },
1305 { "msp430i2041",0,2 },
1306 { "msp430i2xxgeneric",0,2 },
1307 { "msp430l092",0,0 },
1308 { "msp430p112",0,0 },
1309 { "msp430p313",0,0 },
1310 { "msp430p315",0,0 },
1311 { "msp430p315s",0,0 },
1312 { "msp430p325",0,0 },
1313 { "msp430p337",0,1 },
1314 { "msp430sl5438a",2,8 },
1315 { "msp430tch5e",0,0 },
1316 { "msp430xgeneric",2,8 },
1317 { "rf430f5144",2,8 },
1318 { "rf430f5155",2,8 },
1319 { "rf430f5175",2,8 },
1320 { "rf430frl152h",0,0 },
1321 { "rf430frl152h_rom",0,0 },
1322 { "rf430frl153h",0,0 },
1323 { "rf430frl153h_rom",0,0 },
1324 { "rf430frl154h",0,0 },
1325 { "rf430frl154h_rom",0,0 }
1326};
65d7bab5 1327
2469cfa2 1328int
17b9d67d 1329md_parse_option (int c, const char * arg)
2469cfa2 1330{
2469cfa2
NC
1331 switch (c)
1332 {
2213f746
NC
1333 case OPTION_SILICON_ERRATA:
1334 case OPTION_SILICON_ERRATA_WARN:
1335 {
1336 signed int i;
1337 const struct
1338 {
e0471c16 1339 const char * name;
2213f746
NC
1340 unsigned int length;
1341 unsigned int bitfield;
1342 } erratas[] =
1343 {
1344 { STRING_COMMA_LEN ("cpu4"), SILICON_ERRATA_CPU4 },
1345 { STRING_COMMA_LEN ("cpu8"), SILICON_ERRATA_CPU8 },
1346 { STRING_COMMA_LEN ("cpu11"), SILICON_ERRATA_CPU11 },
1347 { STRING_COMMA_LEN ("cpu12"), SILICON_ERRATA_CPU12 },
1348 { STRING_COMMA_LEN ("cpu13"), SILICON_ERRATA_CPU13 },
1349 { STRING_COMMA_LEN ("cpu19"), SILICON_ERRATA_CPU19 },
2213f746
NC
1350 };
1351
1352 do
1353 {
1354 for (i = ARRAY_SIZE (erratas); i--;)
1355 if (strncasecmp (arg, erratas[i].name, erratas[i].length) == 0)
1356 {
1357 if (c == OPTION_SILICON_ERRATA)
1358 silicon_errata_fix |= erratas[i].bitfield;
1359 else
1360 silicon_errata_warn |= erratas[i].bitfield;
1361 arg += erratas[i].length;
1362 break;
1363 }
1364 if (i < 0)
1365 {
1366 as_warn (_("Unrecognised CPU errata name starting here: %s"), arg);
1367 break;
1368 }
1369 if (*arg == 0)
1370 break;
1371 if (*arg != ',')
1372 as_warn (_("Expecting comma after CPU errata name, not: %s"), arg);
1373 else
1374 arg ++;
1375 }
1376 while (*arg != 0);
1377 }
1378 return 1;
1379
2469cfa2 1380 case OPTION_MMCU:
638d3803
NC
1381 if (arg == NULL)
1382 as_fatal (_("MCU option requires a name\n"));
1383
65d7bab5
NC
1384 if (strcasecmp ("msp430", arg) == 0)
1385 selected_isa = MSP_ISA_430;
1386 else if (strcasecmp ("msp430xv2", arg) == 0)
1387 selected_isa = MSP_ISA_430Xv2;
1388 else if (strcasecmp ("msp430x", arg) == 0)
1389 selected_isa = MSP_ISA_430X;
1390 else
2469cfa2 1391 {
65d7bab5
NC
1392 int i;
1393
ede77e69
NC
1394 for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
1395 if (strcasecmp (msp430_mcu_data[i].name, arg) == 0)
65d7bab5 1396 {
ede77e69
NC
1397 switch (msp430_mcu_data[i].revision)
1398 {
1399 case 0: selected_isa = MSP_ISA_430; break;
1400 case 1: selected_isa = MSP_ISA_430X; break;
1401 case 2: selected_isa = MSP_ISA_430Xv2; break;
1402 }
65d7bab5
NC
1403 break;
1404 }
2469cfa2 1405 }
8e75a78f 1406 /* It is not an error if we do not match the MCU name. */
2469cfa2 1407 return 1;
65d7bab5 1408
638d3803 1409 case OPTION_MCPU:
8e75a78f
NC
1410 if (strcmp (arg, "430") == 0
1411 || strcasecmp (arg, "msp430") == 0)
65d7bab5 1412 selected_isa = MSP_ISA_430;
8e75a78f
NC
1413 else if (strcasecmp (arg, "430x") == 0
1414 || strcasecmp (arg, "msp430x") == 0)
65d7bab5 1415 selected_isa = MSP_ISA_430X;
8e75a78f
NC
1416 else if (strcasecmp (arg, "430xv2") == 0
1417 || strcasecmp (arg, "msp430xv2") == 0)
65d7bab5 1418 selected_isa = MSP_ISA_430Xv2;
638d3803
NC
1419 else
1420 as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
638d3803 1421 return 1;
38d77545 1422
77592908 1423 case OPTION_RELAX:
13761a11 1424 msp430_enable_relax = 1;
77592908 1425 return 1;
13761a11 1426
77592908
DD
1427 case OPTION_POLYMORPHS:
1428 msp430_enable_polys = 1;
1429 return 1;
13761a11
NC
1430
1431 case OPTION_LARGE:
1432 large_model = TRUE;
1433 return 1;
1434
1435 case OPTION_NO_INTR_NOPS:
1436 gen_interrupt_nops = FALSE;
1437 return 1;
a75555d1
NC
1438 case OPTION_INTR_NOPS:
1439 gen_interrupt_nops = TRUE;
1440 return 1;
ab905915 1441
65d7bab5
NC
1442 case OPTION_WARN_INTR_NOPS:
1443 warn_interrupt_nops = TRUE;
1444 return 1;
1445 case OPTION_NO_WARN_INTR_NOPS:
1446 warn_interrupt_nops = FALSE;
1447 return 1;
1448
ab905915
NC
1449 case OPTION_MOVE_DATA:
1450 move_data = TRUE;
1451 return 1;
2469cfa2
NC
1452 }
1453
1454 return 0;
1455}
1456
34b822e3
DD
1457/* The intention here is to have the mere presence of these sections
1458 cause the object to have a reference to a well-known symbol. This
1459 reference pulls in the bits of the runtime (crt0) that initialize
1460 these sections. Thus, for example, the startup code to call
1461 memset() to initialize .bss will only be linked in when there is a
1462 non-empty .bss section. Otherwise, the call would exist but have a
1463 zero length parameter, which is a waste of memory and cycles.
1464
1465 The code which initializes these sections should have a global
1466 label for these symbols, and should be marked with KEEP() in the
837a17b3
NC
1467 linker script. */
1468
ab905915 1469static void
837a17b3 1470msp430_make_init_symbols (const char * name)
ab905915 1471{
ab905915
NC
1472 if (strncmp (name, ".bss", 4) == 0
1473 || strncmp (name, ".gnu.linkonce.b.", 16) == 0)
1474 (void) symbol_find_or_make ("__crt0_init_bss");
1475
34b822e3
DD
1476 if (strncmp (name, ".data", 5) == 0
1477 || strncmp (name, ".gnu.linkonce.d.", 16) == 0)
ab905915
NC
1478 (void) symbol_find_or_make ("__crt0_movedata");
1479
837a17b3
NC
1480 /* Note - data assigned to the .either.data section may end up being
1481 placed in the .upper.data section if the .lower.data section is
1482 full. Hence the need to define the crt0 symbol. */
1483 if (strncmp (name, ".either.data", 12) == 0
1484 || strncmp (name, ".upper.data", 11) == 0)
1485 (void) symbol_find_or_make ("__crt0_move_highdata");
1486
1487 /* See note about .either.data above. */
1488 if (strncmp (name, ".upper.bss", 10) == 0
1489 || strncmp (name, ".either.bss", 11) == 0)
1490 (void) symbol_find_or_make ("__crt0_init_highbss");
1491}
1492
1493static void
1494msp430_section (int arg)
1495{
1496 char * saved_ilp = input_line_pointer;
b9bb4a93 1497 const char * name = obj_elf_section_name ();
837a17b3
NC
1498
1499 msp430_make_init_symbols (name);
3739860c 1500
ab905915
NC
1501 input_line_pointer = saved_ilp;
1502 obj_elf_section (arg);
1503}
1504
34b822e3
DD
1505void
1506msp430_frob_section (asection *sec)
1507{
1508 const char *name = sec->name;
1509
1510 if (sec->size == 0)
1511 return;
1512
837a17b3 1513 msp430_make_init_symbols (name);
34b822e3
DD
1514}
1515
1516static void
1517msp430_lcomm (int ignore ATTRIBUTE_UNUSED)
1518{
1519 symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
1520
1521 if (symbolP)
1522 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
1523 (void) symbol_find_or_make ("__crt0_init_bss");
1524}
1525
1526static void
1527msp430_comm (int needs_align)
1528{
1529 s_comm_internal (needs_align, elf_common_parse);
1530 (void) symbol_find_or_make ("__crt0_init_bss");
1531}
1532
96b96102
DD
1533static void
1534msp430_refsym (int arg ATTRIBUTE_UNUSED)
1535{
1536 char sym_name[1024];
1537 input_line_pointer = extract_word (input_line_pointer, sym_name, 1024);
1538
1539 (void) symbol_find_or_make (sym_name);
1540}
1541
b18c562e 1542const pseudo_typeS md_pseudo_table[] =
2469cfa2 1543{
638d3803
NC
1544 {"arch", msp430_set_arch, OPTION_MMCU},
1545 {"cpu", msp430_set_arch, OPTION_MCPU},
b18c562e 1546 {"profiler", msp430_profiler, 0},
ab905915
NC
1547 {"section", msp430_section, 0},
1548 {"section.s", msp430_section, 0},
1549 {"sect", msp430_section, 0},
1550 {"sect.s", msp430_section, 0},
1551 {"pushsection", msp430_section, 1},
96b96102 1552 {"refsym", msp430_refsym, 0},
34b822e3
DD
1553 {"comm", msp430_comm, 0},
1554 {"lcomm", msp430_lcomm, 0},
b18c562e
NC
1555 {NULL, NULL, 0}
1556};
2469cfa2 1557
69227609 1558const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,my,mY";
2469cfa2 1559
b18c562e 1560struct option md_longopts[] =
2469cfa2 1561{
2213f746
NC
1562 {"msilicon-errata", required_argument, NULL, OPTION_SILICON_ERRATA},
1563 {"msilicon-errata-warn", required_argument, NULL, OPTION_SILICON_ERRATA_WARN},
b18c562e 1564 {"mmcu", required_argument, NULL, OPTION_MMCU},
638d3803 1565 {"mcpu", required_argument, NULL, OPTION_MCPU},
77592908
DD
1566 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
1567 {"mQ", no_argument, NULL, OPTION_RELAX},
13761a11
NC
1568 {"ml", no_argument, NULL, OPTION_LARGE},
1569 {"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
a75555d1 1570 {"mn", no_argument, NULL, OPTION_INTR_NOPS},
69227609
NC
1571 {"mY", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
1572 {"my", no_argument, NULL, OPTION_WARN_INTR_NOPS},
ab905915 1573 {"md", no_argument, NULL, OPTION_MOVE_DATA},
b18c562e
NC
1574 {NULL, no_argument, NULL, 0}
1575};
2469cfa2 1576
b18c562e 1577size_t md_longopts_size = sizeof (md_longopts);
2469cfa2 1578
b18c562e
NC
1579void
1580md_show_usage (FILE * stream)
2469cfa2 1581{
b18c562e
NC
1582 fprintf (stream,
1583 _("MSP430 options:\n"
638d3803
NC
1584 " -mmcu=<msp430-name> - select microcontroller type\n"
1585 " -mcpu={430|430x|430xv2} - select microcontroller architecture\n"));
2213f746
NC
1586 fprintf (stream,
1587 _(" -msilicon-errata=<name>[,<name>...] - enable fixups for silicon errata\n"
1588 " -msilicon-errata-warn=<name>[,<name>...] - warn when a fixup might be needed\n"
ff1fe6fa 1589 " supported errata names: cpu4, cpu8, cpu11, cpu12, cpu13, cpu19\n"));
77592908
DD
1590 fprintf (stream,
1591 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
1592 " -mP - enable polymorph instructions\n"));
13761a11
NC
1593 fprintf (stream,
1594 _(" -ml - enable large code model\n"));
1595 fprintf (stream,
65d7bab5 1596 _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
a75555d1 1597 fprintf (stream,
65d7bab5
NC
1598 _(" -mn - insert a NOP after changing interrupts\n"));
1599 fprintf (stream,
69227609 1600 _(" -mY - do not warn about missing NOPs after changing interrupts\n"));
65d7bab5 1601 fprintf (stream,
69227609 1602 _(" -my - warn about missing NOPs after changing interrupts (default)\n"));
ab905915
NC
1603 fprintf (stream,
1604 _(" -md - Force copying of data from ROM to RAM at startup\n"));
b18c562e 1605}
2469cfa2 1606
b18c562e
NC
1607symbolS *
1608md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1609{
13761a11 1610 return NULL;
2469cfa2
NC
1611}
1612
1613static char *
b18c562e 1614extract_cmd (char * from, char * to, int limit)
2469cfa2
NC
1615{
1616 int size = 0;
1617
1618 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
1619 {
1620 *(to + size) = *from;
1621 from++;
1622 size++;
1623 }
1624
1625 *(to + size) = 0;
1626
1627 return from;
1628}
1629
6d4af3c2 1630const char *
b18c562e 1631md_atof (int type, char * litP, int * sizeP)
2469cfa2 1632{
499ac353 1633 return ieee_md_atof (type, litP, sizeP, FALSE);
2469cfa2
NC
1634}
1635
1636void
b18c562e 1637md_begin (void)
2469cfa2 1638{
b18c562e 1639 struct msp430_opcode_s * opcode;
2469cfa2
NC
1640 msp430_hash = hash_new ();
1641
1642 for (opcode = msp430_opcodes; opcode->name; opcode++)
1643 hash_insert (msp430_hash, opcode->name, (char *) opcode);
1644
638d3803
NC
1645 bfd_set_arch_mach (stdoutput, TARGET_ARCH,
1646 target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
9117cd3e
TS
1647
1648 /* Set linkrelax here to avoid fixups in most sections. */
1649 linkrelax = 1;
2469cfa2
NC
1650}
1651
13761a11
NC
1652/* Returns the register number equivalent to the string T.
1653 Returns -1 if there is no such register.
1654 Skips a leading 'r' or 'R' character if there is one.
1655 Handles the register aliases PC and SP. */
1656
1657static signed int
b18c562e 1658check_reg (char * t)
2469cfa2 1659{
13761a11 1660 signed int val;
2469cfa2 1661
13761a11
NC
1662 if (t == NULL)
1663 return -1;
2469cfa2 1664
13761a11
NC
1665 if (*t == 'r' || *t == 'R')
1666 ++t;
1667
1668 if (strncasecmp (t, "pc", 2) == 0)
1669 return 0;
2469cfa2 1670
13761a11 1671 if (strncasecmp (t, "sp", 2) == 0)
b18c562e 1672 return 1;
2469cfa2 1673
13761a11
NC
1674 if (strncasecmp (t, "sr", 2) == 0)
1675 return 2;
1676
1677 if (*t == '0')
1678 return 0;
2469cfa2 1679
13761a11
NC
1680 val = atoi (t);
1681
1682 if (val < 1 || val > 15)
1683 return -1;
1684
1685 return val;
1686}
2469cfa2 1687
b18c562e
NC
1688static int
1689msp430_srcoperand (struct msp430_operand_s * op,
13761a11
NC
1690 char * l,
1691 int bin,
00b32ff2 1692 bfd_boolean * imm_op,
13761a11
NC
1693 bfd_boolean allow_20bit_values,
1694 bfd_boolean constants_allowed)
2469cfa2 1695{
b18c562e 1696 char *__tl = l;
2469cfa2 1697
b18c562e
NC
1698 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1699 if (*l == '#')
2469cfa2 1700 {
b18c562e
NC
1701 char *h = l;
1702 int vshift = -1;
1703 int rval = 0;
2469cfa2 1704
b18c562e
NC
1705 /* Check if there is:
1706 llo(x) - least significant 16 bits, x &= 0xffff
1707 lhi(x) - x = (x >> 16) & 0xffff,
1708 hlo(x) - x = (x >> 32) & 0xffff,
1709 hhi(x) - x = (x >> 48) & 0xffff
1710 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 1711
00b32ff2 1712 *imm_op = TRUE;
2469cfa2 1713
b18c562e
NC
1714 if (strncasecmp (h, "#llo(", 5) == 0)
1715 {
1716 vshift = 0;
1717 rval = 3;
1718 }
1719 else if (strncasecmp (h, "#lhi(", 5) == 0)
1720 {
1721 vshift = 1;
1722 rval = 3;
1723 }
1724 else if (strncasecmp (h, "#hlo(", 5) == 0)
1725 {
1726 vshift = 2;
1727 rval = 3;
1728 }
1729 else if (strncasecmp (h, "#hhi(", 5) == 0)
1730 {
1731 vshift = 3;
1732 rval = 3;
1733 }
1734 else if (strncasecmp (h, "#lo(", 4) == 0)
1735 {
1736 vshift = 0;
1737 rval = 2;
1738 }
1739 else if (strncasecmp (h, "#hi(", 4) == 0)
1740 {
1741 vshift = 1;
1742 rval = 2;
1743 }
2469cfa2 1744
b18c562e
NC
1745 op->reg = 0; /* Reg PC. */
1746 op->am = 3;
65d7bab5 1747 op->ol = 1; /* Immediate will follow an instruction. */
b18c562e
NC
1748 __tl = h + 1 + rval;
1749 op->mode = OP_EXP;
00b32ff2 1750 op->vshift = vshift;
2469cfa2 1751
b18c562e
NC
1752 parse_exp (__tl, &(op->exp));
1753 if (op->exp.X_op == O_constant)
2469cfa2 1754 {
b18c562e 1755 int x = op->exp.X_add_number;
2469cfa2 1756
b18c562e 1757 if (vshift == 0)
2469cfa2 1758 {
b18c562e
NC
1759 x = x & 0xffff;
1760 op->exp.X_add_number = x;
1761 }
1762 else if (vshift == 1)
1763 {
1764 x = (x >> 16) & 0xffff;
1765 op->exp.X_add_number = x;
00b32ff2 1766 op->vshift = 0;
b18c562e
NC
1767 }
1768 else if (vshift > 1)
1769 {
1770 if (x < 0)
1771 op->exp.X_add_number = -1;
2469cfa2 1772 else
b18c562e
NC
1773 op->exp.X_add_number = 0; /* Nothing left. */
1774 x = op->exp.X_add_number;
00b32ff2 1775 op->vshift = 0;
2469cfa2 1776 }
2469cfa2 1777
13761a11
NC
1778 if (allow_20bit_values)
1779 {
99b4a5a0 1780 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
13761a11
NC
1781 {
1782 as_bad (_("value 0x%x out of extended range."), x);
1783 return 1;
1784 }
1785 }
1786 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
b18c562e
NC
1787 {
1788 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1789 return 1;
1790 }
2469cfa2 1791
b18c562e
NC
1792 /* Now check constants. */
1793 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 1794
13761a11
NC
1795 if (!allow_20bit_values)
1796 x = (short) x; /* Extend sign. */
2469cfa2 1797
13761a11
NC
1798 if (! constants_allowed)
1799 ;
1800 else if (x == 0)
2469cfa2 1801 {
b18c562e
NC
1802 op->reg = 3;
1803 op->am = 0;
1804 op->ol = 0;
1805 op->mode = OP_REG;
1806 }
1807 else if (x == 1)
1808 {
1809 op->reg = 3;
1810 op->am = 1;
1811 op->ol = 0;
1812 op->mode = OP_REG;
1813 }
1814 else if (x == 2)
1815 {
1816 op->reg = 3;
1817 op->am = 2;
1818 op->ol = 0;
1819 op->mode = OP_REG;
1820 }
1821 else if (x == -1)
1822 {
1823 op->reg = 3;
1824 op->am = 3;
1825 op->ol = 0;
1826 op->mode = OP_REG;
1827 }
1828 else if (x == 4)
1829 {
2213f746 1830 if (bin == 0x1200 && ! target_is_430x ())
b18c562e 1831 {
2213f746
NC
1832 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1833 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1834 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1835 /* No need to check silicon_errata_fixes - this fix is always implemented. */
b18c562e
NC
1836 }
1837 else
b18c562e
NC
1838 {
1839 op->reg = 2;
1840 op->am = 2;
1841 op->ol = 0;
1842 op->mode = OP_REG;
1843 }
1844 }
1845 else if (x == 8)
1846 {
2213f746 1847 if (bin == 0x1200 && ! target_is_430x ())
b18c562e 1848 {
2213f746
NC
1849 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1850 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1851 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
b18c562e
NC
1852 }
1853 else
b18c562e
NC
1854 {
1855 op->reg = 2;
1856 op->am = 3;
1857 op->ol = 0;
1858 op->mode = OP_REG;
1859 }
2469cfa2 1860 }
2469cfa2 1861 }
b18c562e
NC
1862 else if (op->exp.X_op == O_symbol)
1863 {
00b32ff2
NC
1864 if (vshift > 1)
1865 as_bad (_("error: unsupported #foo() directive used on symbol"));
b18c562e
NC
1866 op->mode = OP_EXP;
1867 }
1868 else if (op->exp.X_op == O_big)
1869 {
1870 short x;
65d7bab5 1871
b18c562e
NC
1872 if (vshift != -1)
1873 {
1874 op->exp.X_op = O_constant;
1875 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1876 x = op->exp.X_add_number;
00b32ff2 1877 op->vshift = 0;
b18c562e
NC
1878 }
1879 else
1880 {
1881 as_bad (_
1882 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1883 l);
1884 return 1;
1885 }
2469cfa2 1886
b18c562e
NC
1887 if (x == 0)
1888 {
1889 op->reg = 3;
1890 op->am = 0;
1891 op->ol = 0;
1892 op->mode = OP_REG;
1893 }
1894 else if (x == 1)
1895 {
1896 op->reg = 3;
1897 op->am = 1;
1898 op->ol = 0;
1899 op->mode = OP_REG;
1900 }
1901 else if (x == 2)
1902 {
1903 op->reg = 3;
1904 op->am = 2;
1905 op->ol = 0;
1906 op->mode = OP_REG;
1907 }
1908 else if (x == -1)
1909 {
1910 op->reg = 3;
1911 op->am = 3;
1912 op->ol = 0;
1913 op->mode = OP_REG;
1914 }
1915 else if (x == 4)
1916 {
1917 op->reg = 2;
1918 op->am = 2;
1919 op->ol = 0;
1920 op->mode = OP_REG;
1921 }
1922 else if (x == 8)
1923 {
1924 op->reg = 2;
1925 op->am = 3;
1926 op->ol = 0;
1927 op->mode = OP_REG;
1928 }
1929 }
79cf5950 1930 /* Redundant (yet) check. */
b18c562e
NC
1931 else if (op->exp.X_op == O_register)
1932 as_bad
1933 (_("Registers cannot be used within immediate expression [%s]"), l);
1934 else
1935 as_bad (_("unknown operand %s"), l);
2469cfa2 1936
b18c562e
NC
1937 return 0;
1938 }
2469cfa2 1939
b18c562e
NC
1940 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1941 if (*l == '&')
1942 {
1943 char *h = l;
2469cfa2 1944
b18c562e
NC
1945 op->reg = 2; /* reg 2 in absolute addr mode. */
1946 op->am = 1; /* mode As == 01 bin. */
1947 op->ol = 1; /* Immediate value followed by instruction. */
1948 __tl = h + 1;
1949 parse_exp (__tl, &(op->exp));
1950 op->mode = OP_EXP;
00b32ff2 1951 op->vshift = 0;
b18c562e 1952 if (op->exp.X_op == O_constant)
2469cfa2 1953 {
b18c562e 1954 int x = op->exp.X_add_number;
2469cfa2 1955
13761a11
NC
1956 if (allow_20bit_values)
1957 {
1958 if (x > 0xfffff || x < -(0x7ffff))
1959 {
1960 as_bad (_("value 0x%x out of extended range."), x);
1961 return 1;
1962 }
1963 }
1964 else if (x > 65535 || x < -32768)
b18c562e 1965 {
13761a11 1966 as_bad (_("value out of range: 0x%x"), x);
b18c562e
NC
1967 return 1;
1968 }
2469cfa2 1969 }
b18c562e
NC
1970 else if (op->exp.X_op == O_symbol)
1971 ;
1972 else
2469cfa2 1973 {
79cf5950 1974 /* Redundant (yet) check. */
b18c562e
NC
1975 if (op->exp.X_op == O_register)
1976 as_bad
1977 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 1978 else
b18c562e
NC
1979 as_bad (_("unknown expression in operand %s"), l);
1980 return 1;
2469cfa2 1981 }
b18c562e
NC
1982 return 0;
1983 }
2469cfa2 1984
b18c562e
NC
1985 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1986 if (*l == '@')
1987 {
1988 char *t = l;
1989 char *m = strchr (l, '+');
1990
1991 if (t != l)
2469cfa2 1992 {
b18c562e
NC
1993 as_bad (_("unknown addressing mode %s"), l);
1994 return 1;
2469cfa2
NC
1995 }
1996
b18c562e 1997 t++;
2469cfa2 1998
13761a11 1999 if ((op->reg = check_reg (t)) == -1)
2469cfa2 2000 {
13761a11 2001 as_bad (_("Bad register name %s"), t);
b18c562e 2002 return 1;
2469cfa2 2003 }
2469cfa2 2004
b18c562e
NC
2005 op->mode = OP_REG;
2006 op->am = m ? 3 : 2;
2007 op->ol = 0;
2469cfa2 2008
d1706f38
NC
2009 /* PC cannot be used in indirect addressing. */
2010 if (target_is_430xv2 () && op->reg == 0)
2011 {
2012 as_bad (_("cannot use indirect addressing with the PC"));
2013 return 1;
2014 }
65d7bab5 2015
b18c562e
NC
2016 return 0;
2017 }
2469cfa2 2018
b18c562e
NC
2019 /* Check if register indexed X(Rn). */
2020 do
2021 {
2022 char *h = strrchr (l, '(');
2023 char *m = strrchr (l, ')');
2024 char *t;
2469cfa2 2025
00b32ff2 2026 *imm_op = TRUE;
2469cfa2 2027
b18c562e
NC
2028 if (!h)
2029 break;
2030 if (!m)
2031 {
2032 as_bad (_("')' required"));
2033 return 1;
2034 }
2469cfa2 2035
b18c562e
NC
2036 t = h;
2037 op->am = 1;
2038 op->ol = 1;
2469cfa2 2039
13761a11
NC
2040 /* Extract a register. */
2041 if ((op->reg = check_reg (t + 1)) == -1)
b18c562e
NC
2042 {
2043 as_bad (_
2044 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2045 l);
2046 return 1;
2047 }
2469cfa2 2048
13761a11 2049 if (op->reg == 2)
b18c562e 2050 {
13761a11 2051 as_bad (_("r2 should not be used in indexed addressing mode"));
b18c562e
NC
2052 return 1;
2053 }
b18c562e
NC
2054
2055 /* Extract constant. */
2056 __tl = l;
2057 *h = 0;
2058 op->mode = OP_EXP;
00b32ff2 2059 op->vshift = 0;
b18c562e
NC
2060 parse_exp (__tl, &(op->exp));
2061 if (op->exp.X_op == O_constant)
2062 {
2063 int x = op->exp.X_add_number;
2064
13761a11
NC
2065 if (allow_20bit_values)
2066 {
2067 if (x > 0xfffff || x < - (0x7ffff))
2068 {
2069 as_bad (_("value 0x%x out of extended range."), x);
2070 return 1;
2071 }
2072 }
2073 else if (x > 65535 || x < -32768)
2469cfa2 2074 {
13761a11 2075 as_bad (_("value out of range: 0x%x"), x);
b18c562e 2076 return 1;
2469cfa2 2077 }
b18c562e
NC
2078
2079 if (x == 0)
2469cfa2 2080 {
b18c562e
NC
2081 op->mode = OP_REG;
2082 op->am = 2;
2083 op->ol = 0;
2084 return 0;
2469cfa2 2085 }
2213f746
NC
2086
2087 if (op->reg == 1 && (x & 1))
2088 {
2089 if (silicon_errata_fix & SILICON_ERRATA_CPU8)
2090 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2091 else if (silicon_errata_warn & SILICON_ERRATA_CPU8)
2092 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2093 }
2469cfa2 2094 }
b18c562e
NC
2095 else if (op->exp.X_op == O_symbol)
2096 ;
2469cfa2
NC
2097 else
2098 {
79cf5950 2099 /* Redundant (yet) check. */
b18c562e
NC
2100 if (op->exp.X_op == O_register)
2101 as_bad
2102 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
2103 else
2104 as_bad (_("unknown expression in operand %s"), l);
2105 return 1;
2469cfa2 2106 }
2469cfa2 2107
b18c562e 2108 return 0;
2469cfa2 2109 }
b18c562e 2110 while (0);
2469cfa2 2111
13761a11
NC
2112 /* Possibly register mode 'mov r1,r2'. */
2113 if ((op->reg = check_reg (l)) != -1)
b18c562e 2114 {
13761a11
NC
2115 op->mode = OP_REG;
2116 op->am = 0;
2117 op->ol = 0;
2118 return 0;
b18c562e 2119 }
b18c562e
NC
2120
2121 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2122 do
2123 {
b18c562e
NC
2124 op->mode = OP_EXP;
2125 op->reg = 0; /* PC relative... be careful. */
13761a11
NC
2126 /* An expression starting with a minus sign is a constant, not an address. */
2127 op->am = (*l == '-' ? 3 : 1);
b18c562e 2128 op->ol = 1;
00b32ff2 2129 op->vshift = 0;
b18c562e
NC
2130 __tl = l;
2131 parse_exp (__tl, &(op->exp));
2132 return 0;
2133 }
2134 while (0);
2135
2136 /* Unreachable. */
2137 as_bad (_("unknown addressing mode for operand %s"), l);
2138 return 1;
2469cfa2
NC
2139}
2140
b18c562e 2141
2469cfa2 2142static int
13761a11
NC
2143msp430_dstoperand (struct msp430_operand_s * op,
2144 char * l,
2145 int bin,
2146 bfd_boolean allow_20bit_values,
2147 bfd_boolean constants_allowed)
2469cfa2
NC
2148{
2149 int dummy;
13761a11
NC
2150 int ret = msp430_srcoperand (op, l, bin, & dummy,
2151 allow_20bit_values,
2152 constants_allowed);
b18c562e 2153
2469cfa2
NC
2154 if (ret)
2155 return ret;
2156
2157 if (op->am == 2)
2158 {
47990a6a 2159 char *__tl = (char *) "0";
2469cfa2
NC
2160
2161 op->mode = OP_EXP;
2162 op->am = 1;
2163 op->ol = 1;
00b32ff2 2164 op->vshift = 0;
2469cfa2 2165 parse_exp (__tl, &(op->exp));
b18c562e 2166
2469cfa2
NC
2167 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
2168 {
2169 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2170 op->reg, op->reg);
2171 return 1;
2172 }
2173 return 0;
2174 }
2175
2176 if (op->am > 1)
2177 {
2178 as_bad (_
2179 ("this addressing mode is not applicable for destination operand"));
2180 return 1;
2181 }
2182 return 0;
2183}
2184
13761a11
NC
2185/* Attempt to encode a MOVA instruction with the given operands.
2186 Returns the length of the encoded instruction if successful
2187 or 0 upon failure. If the encoding fails, an error message
2188 will be returned if a pointer is provided. */
2189
2190static int
2191try_encode_mova (bfd_boolean imm_op,
2192 int bin,
2193 struct msp430_operand_s * op1,
2194 struct msp430_operand_s * op2,
2195 const char ** error_message_return)
2196{
2197 short ZEROS = 0;
2198 char *frag;
2199 int where;
2200
2201 /* Only a restricted subset of the normal MSP430 addressing modes
2202 are supported here, so check for the ones that are allowed. */
2203 if (imm_op)
2204 {
2205 if (op1->mode == OP_EXP)
2206 {
2207 if (op2->mode != OP_REG)
2208 {
2209 if (error_message_return != NULL)
2210 * error_message_return = _("expected register as second argument of %s");
2211 return 0;
2212 }
2213
2214 if (op1->am == 3)
2215 {
2216 /* MOVA #imm20, Rdst. */
2217 bin |= 0x80 | op2->reg;
2218 frag = frag_more (4);
2219 where = frag - frag_now->fr_literal;
2220 if (op1->exp.X_op == O_constant)
2221 {
2222 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2223 bfd_putl16 ((bfd_vma) bin, frag);
2224 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2225 }
2226 else
2227 {
2228 bfd_putl16 ((bfd_vma) bin, frag);
2229 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2230 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2231 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2232 }
2233
2234 return 4;
2235 }
2236 else if (op1->am == 1)
2237 {
2238 /* MOVA z16(Rsrc), Rdst. */
2239 bin |= 0x30 | (op1->reg << 8) | op2->reg;
2240 frag = frag_more (4);
2241 where = frag - frag_now->fr_literal;
2242 bfd_putl16 ((bfd_vma) bin, frag);
2243 if (op1->exp.X_op == O_constant)
2244 {
2245 if (op1->exp.X_add_number > 0xffff
2246 || op1->exp.X_add_number < -(0x7fff))
2247 {
2248 if (error_message_return != NULL)
2249 * error_message_return = _("index value too big for %s");
2250 return 0;
2251 }
2252 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2253 }
2254 else
2255 {
2256 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2257 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
2258 op1->reg == 0 ?
2259 BFD_RELOC_MSP430X_PCR16 :
2260 BFD_RELOC_MSP430X_ABS16);
2261 }
2262 return 4;
2263 }
2264
2265 if (error_message_return != NULL)
2266 * error_message_return = _("unexpected addressing mode for %s");
2267 return 0;
2268 }
2269 else if (op1->am == 0)
2270 {
2271 /* MOVA Rsrc, ... */
2272 if (op2->mode == OP_REG)
2273 {
2274 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
2275 frag = frag_more (2);
2276 where = frag - frag_now->fr_literal;
2277 bfd_putl16 ((bfd_vma) bin, frag);
2278 return 2;
2279 }
2280 else if (op2->am == 1)
2281 {
2282 if (op2->reg == 2)
2283 {
2284 /* MOVA Rsrc, &abs20. */
2285 bin |= 0x60 | (op1->reg << 8);
2286 frag = frag_more (4);
2287 where = frag - frag_now->fr_literal;
2288 if (op2->exp.X_op == O_constant)
2289 {
2290 bin |= (op2->exp.X_add_number >> 16) & 0xf;
2291 bfd_putl16 ((bfd_vma) bin, frag);
2292 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2293 }
2294 else
2295 {
2296 bfd_putl16 ((bfd_vma) bin, frag);
2297 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2298 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
2299 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2300 }
2301 return 4;
2302 }
2303
2304 /* MOVA Rsrc, z16(Rdst). */
2305 bin |= 0x70 | (op1->reg << 8) | op2->reg;
2306 frag = frag_more (4);
2307 where = frag - frag_now->fr_literal;
2308 bfd_putl16 ((bfd_vma) bin, frag);
2309 if (op2->exp.X_op == O_constant)
2310 {
2311 if (op2->exp.X_add_number > 0xffff
2312 || op2->exp.X_add_number < -(0x7fff))
2313 {
2314 if (error_message_return != NULL)
2315 * error_message_return = _("index value too big for %s");
2316 return 0;
2317 }
2318 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2319 }
2320 else
2321 {
2322 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2323 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2324 op2->reg == 0 ?
2325 BFD_RELOC_MSP430X_PCR16 :
2326 BFD_RELOC_MSP430X_ABS16);
2327 }
2328 return 4;
2329 }
2330
2331 if (error_message_return != NULL)
2332 * error_message_return = _("unexpected addressing mode for %s");
2333 return 0;
2334 }
2335 }
2336
2337 /* imm_op == FALSE. */
2338
2339 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2340 {
2341 /* MOVA &abs20, Rdst. */
2342 if (op2->mode != OP_REG)
2343 {
2344 if (error_message_return != NULL)
2345 * error_message_return = _("expected register as second argument of %s");
2346 return 0;
2347 }
2348
2349 if (op2->reg == 2 || op2->reg == 3)
2350 {
2351 if (error_message_return != NULL)
2352 * error_message_return = _("constant generator destination register found in %s");
2353 return 0;
2354 }
2355
2356 bin |= 0x20 | op2->reg;
2357 frag = frag_more (4);
2358 where = frag - frag_now->fr_literal;
2359 if (op1->exp.X_op == O_constant)
2360 {
2361 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2362 bfd_putl16 ((bfd_vma) bin, frag);
2363 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2364 }
2365 else
2366 {
2367 bfd_putl16 ((bfd_vma) bin, frag);
2368 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2369 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2370 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2371 }
2372 return 4;
2373 }
2374 else if (op1->mode == OP_REG)
2375 {
2376 if (op1->am == 3)
2377 {
2378 /* MOVA @Rsrc+, Rdst. */
2379 if (op2->mode != OP_REG)
2380 {
2381 if (error_message_return != NULL)
2382 * error_message_return = _("expected register as second argument of %s");
2383 return 0;
2384 }
2385
2386 if (op2->reg == 2 || op2->reg == 3)
2387 {
2388 if (error_message_return != NULL)
2389 * error_message_return = _("constant generator destination register found in %s");
2390 return 0;
2391 }
2392
2393 if (op1->reg == 2 || op1->reg == 3)
2394 {
2395 if (error_message_return != NULL)
2396 * error_message_return = _("constant generator source register found in %s");
2397 return 0;
2398 }
2399
2400 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2401 frag = frag_more (2);
2402 where = frag - frag_now->fr_literal;
2403 bfd_putl16 ((bfd_vma) bin, frag);
2404 return 2;
2405 }
2406 else if (op1->am == 2)
2407 {
2408 /* MOVA @Rsrc,Rdst */
2409 if (op2->mode != OP_REG)
2410 {
2411 if (error_message_return != NULL)
2412 * error_message_return = _("expected register as second argument of %s");
2413 return 0;
2414 }
2415
2416 if (op2->reg == 2 || op2->reg == 3)
2417 {
2418 if (error_message_return != NULL)
2419 * error_message_return = _("constant generator destination register found in %s");
2420 return 0;
2421 }
2422
2423 if (op1->reg == 2 || op1->reg == 3)
2424 {
2425 if (error_message_return != NULL)
2426 * error_message_return = _("constant generator source register found in %s");
2427 return 0;
2428 }
2429
2430 bin |= (op1->reg << 8) | op2->reg;
2431 frag = frag_more (2);
2432 where = frag - frag_now->fr_literal;
2433 bfd_putl16 ((bfd_vma) bin, frag);
2434 return 2;
2435 }
2436 }
2437
2438 if (error_message_return != NULL)
2439 * error_message_return = _("unexpected addressing mode for %s");
2440
2441 return 0;
2442}
2443
2213f746
NC
2444#define NOP_CHECK_INTERRUPT (1 << 0)
2445#define NOP_CHECK_CPU12 (1 << 1)
2446#define NOP_CHECK_CPU19 (1 << 2)
2447
2448static signed int check_for_nop = 0;
65d7bab5 2449
638d3803
NC
2450#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2451
b18c562e
NC
2452/* Parse instruction operands.
2453 Return binary opcode. */
2454
2455static unsigned int
2456msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 2457{
b18c562e 2458 int bin = opcode->bin_opcode; /* Opcode mask. */
13761a11 2459 int insn_length = 0;
b18c562e
NC
2460 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2461 char *frag;
2462 int where;
2463 struct msp430_operand_s op1, op2;
2464 int res = 0;
2465 static short ZEROS = 0;
00b32ff2 2466 bfd_boolean byte_op, imm_op;
13761a11
NC
2467 int op_length = 0;
2468 int fmt;
2469 int extended = 0x1800;
2470 bfd_boolean extended_op = FALSE;
2471 bfd_boolean addr_op;
2472 const char * error_message;
2473 static signed int repeat_count = 0;
927f2d25 2474 static bfd_boolean prev_insn_is_nop = FALSE;
13761a11 2475 bfd_boolean fix_emitted;
2469cfa2 2476
b18c562e
NC
2477 /* Opcode is the one from opcodes table
2478 line contains something like
2479 [.w] @r2+, 5(R1)
2480 or
2481 .b @r2+, 5(R1). */
2469cfa2 2482
00b32ff2 2483 byte_op = FALSE;
38d77545
NC
2484 addr_op = FALSE;
2485 if (*line == '.')
2469cfa2 2486 {
38d77545
NC
2487 bfd_boolean check = FALSE;
2488 ++ line;
2489
2490 switch (TOLOWER (* line))
2491 {
2492 case 'b':
2493 /* Byte operation. */
2494 bin |= BYTE_OPERATION;
00b32ff2 2495 byte_op = TRUE;
38d77545
NC
2496 check = TRUE;
2497 break;
2498
2499 case 'a':
2500 /* "Address" ops work on 20-bit values. */
2501 addr_op = TRUE;
2502 bin |= BYTE_OPERATION;
2503 check = TRUE;
2504 break;
2505
2506 case 'w':
2507 /* Word operation - this is the default. */
2508 check = TRUE;
2509 break;
2510
2511 case 0:
2512 case ' ':
2513 case '\n':
2514 case '\r':
2515 as_warn (_("no size modifier after period, .w assumed"));
2516 break;
2517
2518 default:
2519 as_bad (_("unrecognised instruction size modifier .%c"),
2520 * line);
2521 return 0;
2522 }
2523
2524 if (check)
2525 {
2526 ++ line;
2527
2528 }
2469cfa2
NC
2529 }
2530
38d77545 2531 if (*line && ! ISSPACE (*line))
13761a11 2532 {
38d77545
NC
2533 as_bad (_("junk found after instruction: %s.%s"),
2534 opcode->name, line);
2535 return 0;
13761a11 2536 }
13761a11 2537
38d77545
NC
2538 /* Catch the case where the programmer has used a ".a" size modifier on an
2539 instruction that does not support it. Look for an alternative extended
2540 instruction that has the same name without the period. Eg: "add.a"
2541 becomes "adda". Although this not an officially supported way of
2542 specifing instruction aliases other MSP430 assemblers allow it. So we
2543 support it for compatibility purposes. */
2544 if (addr_op && opcode->fmt >= 0)
2545 {
f86f5863 2546 const char * old_name = opcode->name;
38d77545
NC
2547 char real_name[32];
2548
2549 sprintf (real_name, "%sa", old_name);
2550 opcode = hash_find (msp430_hash, real_name);
2551 if (opcode == NULL)
2552 {
2553 as_bad (_("instruction %s.a does not exist"), old_name);
2554 return 0;
2555 }
2556#if 0 /* Enable for debugging. */
2557 as_warn ("treating %s.a as %s", old_name, real_name);
2558#endif
2559 addr_op = FALSE;
2560 bin = opcode->bin_opcode;
2561 }
2469cfa2 2562
13761a11
NC
2563 if (opcode->fmt != -1
2564 && opcode->insn_opnumb
2565 && (!*line || *line == '\n'))
2469cfa2 2566 {
b18c562e
NC
2567 as_bad (_("instruction %s requires %d operand(s)"),
2568 opcode->name, opcode->insn_opnumb);
2569 return 0;
2570 }
2469cfa2 2571
b18c562e
NC
2572 memset (l1, 0, sizeof (l1));
2573 memset (l2, 0, sizeof (l2));
2574 memset (&op1, 0, sizeof (op1));
2575 memset (&op2, 0, sizeof (op2));
2469cfa2 2576
00b32ff2 2577 imm_op = FALSE;
2469cfa2 2578
13761a11
NC
2579 if ((fmt = opcode->fmt) < 0)
2580 {
638d3803 2581 if (! target_is_430x ())
13761a11
NC
2582 {
2583 as_bad (_("instruction %s requires MSP430X mcu"),
2584 opcode->name);
2585 return 0;
2586 }
3739860c 2587
13761a11
NC
2588 fmt = (-fmt) - 1;
2589 extended_op = TRUE;
2590 }
2591
2592 if (repeat_count)
2593 {
2594 /* If requested set the extended instruction repeat count. */
2595 if (extended_op)
2596 {
2597 if (repeat_count > 0)
2598 extended |= (repeat_count - 1);
2599 else
2600 extended |= (1 << 7) | (- repeat_count);
2601 }
2602 else
2603 as_bad (_("unable to repeat %s insn"), opcode->name);
2604
2605 repeat_count = 0;
2606 }
2607
2213f746 2608 if (check_for_nop)
b18c562e 2609 {
2213f746 2610 if (! is_opcode ("nop"))
2469cfa2 2611 {
2213f746
NC
2612 bfd_boolean doit = FALSE;
2613
2614 do
65d7bab5 2615 {
2213f746 2616 switch (check_for_nop & - check_for_nop)
65d7bab5 2617 {
2213f746 2618 case NOP_CHECK_INTERRUPT:
ff1fe6fa 2619 if (warn_interrupt_nops)
65d7bab5
NC
2620 {
2621 if (gen_interrupt_nops)
2622 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2623 else
2624 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2625 }
2626
ff1fe6fa 2627 if (gen_interrupt_nops)
2213f746
NC
2628 /* Emit a NOP between interrupt enable/disable.
2629 See 1.3.4.1 of the MSP430x5xx User Guide. */
2630 doit = TRUE;
2631 break;
2632
2633 case NOP_CHECK_CPU12:
2634 if (silicon_errata_warn & SILICON_ERRATA_CPU12)
2635 as_warn (_("CPU12: CMP/BIT with PC destinstion ignores next instruction"));
2636
2637 if (silicon_errata_fix & SILICON_ERRATA_CPU12)
2638 doit = TRUE;
2639 break;
2640
2641 case NOP_CHECK_CPU19:
2642 if (silicon_errata_warn & SILICON_ERRATA_CPU19)
2643 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
65d7bab5 2644
2213f746
NC
2645 if (silicon_errata_fix & SILICON_ERRATA_CPU19)
2646 doit = TRUE;
2647 break;
2648
2649 default:
2650 as_bad (_("internal error: unknown nop check state"));
2651 break;
2652 }
2653 check_for_nop &= ~ (check_for_nop & - check_for_nop);
2654 }
2655 while (check_for_nop);
2656
2657 if (doit)
2658 {
2659 frag = frag_more (2);
2660 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2661 dwarf2_emit_insn (2);
65d7bab5 2662 }
2213f746
NC
2663 }
2664
2665 check_for_nop = 0;
2666 }
2667
2668 switch (fmt)
2669 {
2670 case 0: /* Emulated. */
2671 switch (opcode->insn_opnumb)
2672 {
2673 case 0:
927f2d25
NC
2674 if (is_opcode ("eint"))
2675 {
2676 if (! prev_insn_is_nop)
2677 {
2678 if (gen_interrupt_nops)
2679 {
2680 frag = frag_more (2);
2681 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2682 dwarf2_emit_insn (2);
2683
2684 if (warn_interrupt_nops)
2685 as_warn (_("inserting a NOP before EINT"));
2686 }
2687 else if (warn_interrupt_nops)
2688 as_warn (_("a NOP might be needed before the EINT"));
2689 }
2690 }
2691 else if (is_opcode ("dint"))
2213f746 2692 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5 2693
b18c562e 2694 /* Set/clear bits instructions. */
13761a11
NC
2695 if (extended_op)
2696 {
2697 if (!addr_op)
2698 extended |= BYTE_OPERATION;
2699
2700 /* Emit the extension word. */
2701 insn_length += 2;
65d7bab5 2702 frag = frag_more (2);
13761a11
NC
2703 bfd_putl16 (extended, frag);
2704 }
638d3803 2705
13761a11 2706 insn_length += 2;
65d7bab5 2707 frag = frag_more (2);
b18c562e 2708 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 2709 dwarf2_emit_insn (insn_length);
b18c562e 2710 break;
13761a11 2711
b18c562e
NC
2712 case 1:
2713 /* Something which works with destination operand. */
2714 line = extract_operand (line, l1, sizeof (l1));
13761a11 2715 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
b18c562e
NC
2716 if (res)
2717 break;
2469cfa2 2718
65d7bab5
NC
2719 bin |= (op1.reg | (op1.am << 7));
2720
2213f746
NC
2721 /* If the PC is the destination... */
2722 if (op1.am == 0 && op1.reg == 0
2723 /* ... and the opcode alters the SR. */
2724 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2725 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
65d7bab5 2726 {
2213f746
NC
2727 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
2728 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
2729 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
2730 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
65d7bab5 2731 }
2213f746
NC
2732
2733 /* If the status register is the destination... */
2734 if (op1.am == 0 && op1.reg == 2
2735 /* ... and the opcode alters the SR. */
2736 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2737 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2738 || is_opcode ("sbc") || is_opcode ("sxt")
2739 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2740 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2741 || is_opcode ("sbcx")
2742 ))
2743 {
2744 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
2745 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2746 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
2747 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2748 }
2749
2750 if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
2751 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5 2752
13761a11 2753 /* Compute the entire instruction length, in bytes. */
65d7bab5
NC
2754 op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2755 insn_length += op_length;
2756 frag = frag_more (op_length);
b18c562e 2757 where = frag - frag_now->fr_literal;
38d77545 2758
13761a11 2759 if (extended_op)
2469cfa2 2760 {
13761a11
NC
2761 if (!addr_op)
2762 extended |= BYTE_OPERATION;
2763
2764 if (op1.ol != 0 && ((extended & 0xf) != 0))
2765 {
2766 as_bad (_("repeat instruction used with non-register mode instruction"));
2767 extended &= ~ 0xf;
2768 }
38d77545 2769
13761a11
NC
2770 if (op1.mode == OP_EXP)
2771 {
2772 if (op1.exp.X_op == O_constant)
2773 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2774
e66c3c25 2775 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
2776 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2777 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2778 else
2779 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2780 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2781 }
38d77545 2782
13761a11
NC
2783 /* Emit the extension word. */
2784 bfd_putl16 (extended, frag);
2785 frag += 2;
2786 where += 2;
2787 }
2788
13761a11
NC
2789 bfd_putl16 ((bfd_vma) bin, frag);
2790 frag += 2;
2791 where += 2;
2792
2793 if (op1.mode == OP_EXP)
2794 {
2795 if (op1.exp.X_op == O_constant)
2796 {
2797 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2798 }
2469cfa2 2799 else
13761a11
NC
2800 {
2801 bfd_putl16 ((bfd_vma) ZEROS, frag);
2802
2803 if (!extended_op)
2804 {
2805 if (op1.reg)
2806 fix_new_exp (frag_now, where, 2,
00b32ff2 2807 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
2808 else
2809 fix_new_exp (frag_now, where, 2,
2810 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2811 }
2812 }
2813 }
2814
13761a11 2815 dwarf2_emit_insn (insn_length);
b18c562e 2816 break;
2469cfa2 2817
b18c562e 2818 case 2:
13761a11
NC
2819 /* Shift instruction. */
2820 line = extract_operand (line, l1, sizeof (l1));
2821 strncpy (l2, l1, sizeof (l2));
2822 l2[sizeof (l2) - 1] = '\0';
2823 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2824 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2825
2826 if (res)
2827 break; /* An error occurred. All warnings were done before. */
2828
2829 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2830 frag = frag_more (insn_length);
2831 where = frag - frag_now->fr_literal;
2832
d1706f38
NC
2833 if (target_is_430xv2 ()
2834 && op1.mode == OP_REG
38d77545 2835 && op1.reg == 0
638d3803
NC
2836 && (is_opcode ("rlax")
2837 || is_opcode ("rlcx")
2838 || is_opcode ("rla")
2839 || is_opcode ("rlc")))
2840 {
2841 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 2842 break;
638d3803 2843 }
38d77545 2844
2213f746
NC
2845 /* If the status register is the destination... */
2846 if (op1.am == 0 && op1.reg == 2
2847 /* ... and the opcode alters the SR. */
2848 && (is_opcode ("rla") || is_opcode ("rlc")
2849 || is_opcode ("rlax") || is_opcode ("rlcx")
2850 ))
2851 {
2852 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
2853 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
2854 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
2855 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
2856 }
2857
13761a11
NC
2858 if (extended_op)
2859 {
2860 if (!addr_op)
2861 extended |= BYTE_OPERATION;
2862
2863 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2864 {
2865 as_bad (_("repeat instruction used with non-register mode instruction"));
2866 extended &= ~ 0xf;
2867 }
38d77545 2868
13761a11
NC
2869 if (op1.mode == OP_EXP)
2870 {
2871 if (op1.exp.X_op == O_constant)
2872 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2873
e66c3c25 2874 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
2875 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2876 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2877 else
2878 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2879 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2880 }
2881
2882 if (op2.mode == OP_EXP)
2883 {
2884 if (op2.exp.X_op == O_constant)
2885 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2886
2887 else if (op1.mode == OP_EXP)
2888 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2889 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2890 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2891 else
2892 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2893 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2894 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2895 }
2896
2897 /* Emit the extension word. */
2898 bfd_putl16 (extended, frag);
2899 frag += 2;
2900 where += 2;
2901 }
2902
2903 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2904 bfd_putl16 ((bfd_vma) bin, frag);
2905 frag += 2;
2906 where += 2;
2907
2908 if (op1.mode == OP_EXP)
2909 {
2910 if (op1.exp.X_op == O_constant)
2911 {
2912 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2913 }
2914 else
2915 {
2916 bfd_putl16 ((bfd_vma) ZEROS, frag);
2917
2918 if (!extended_op)
2919 {
e66c3c25 2920 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 2921 fix_new_exp (frag_now, where, 2,
00b32ff2 2922 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
2923 else
2924 fix_new_exp (frag_now, where, 2,
2925 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2926 }
2927 }
2928 frag += 2;
2929 where += 2;
2930 }
2931
2932 if (op2.mode == OP_EXP)
2933 {
2934 if (op2.exp.X_op == O_constant)
2935 {
2936 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2937 }
2938 else
2939 {
2940 bfd_putl16 ((bfd_vma) ZEROS, frag);
2941
2942 if (!extended_op)
2943 {
2944 if (op2.reg) /* Not PC relative. */
2945 fix_new_exp (frag_now, where, 2,
00b32ff2 2946 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
13761a11
NC
2947 else
2948 fix_new_exp (frag_now, where, 2,
2949 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2950 }
2951 }
2952 }
2953
2954 dwarf2_emit_insn (insn_length);
2955 break;
2956
2957 case 3:
2958 /* Branch instruction => mov dst, r0. */
2959 if (extended_op)
2960 {
2961 as_bad ("Internal error: state 0/3 not coded for extended instructions");
65d7bab5 2962 break;
13761a11
NC
2963 }
2964
2965 line = extract_operand (line, l1, sizeof (l1));
2966 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
2967 if (res)
2968 break;
2969
00b32ff2
NC
2970 byte_op = FALSE;
2971 imm_op = FALSE;
13761a11
NC
2972 bin |= ((op1.reg << 8) | (op1.am << 4));
2973 op_length = 2 + 2 * op1.ol;
2974 frag = frag_more (op_length);
2975 where = frag - frag_now->fr_literal;
2976 bfd_putl16 ((bfd_vma) bin, frag);
2977
2978 if (op1.mode == OP_EXP)
2979 {
2980 if (op1.exp.X_op == O_constant)
2981 {
2982 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
2983 }
2984 else
2985 {
2986 where += 2;
38d77545 2987
13761a11
NC
2988 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2989
e66c3c25 2990 if (op1.reg || op1.am == 3)
13761a11 2991 fix_new_exp (frag_now, where, 2,
00b32ff2 2992 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
2993 else
2994 fix_new_exp (frag_now, where, 2,
2995 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2996 }
2997 }
2998
2999 dwarf2_emit_insn (insn_length + op_length);
3000 break;
3001
3002 case 4:
3003 /* CALLA instructions. */
3004 fix_emitted = FALSE;
3005
3006 line = extract_operand (line, l1, sizeof (l1));
00b32ff2 3007 imm_op = FALSE;
13761a11
NC
3008
3009 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
3010 extended_op, FALSE);
3011 if (res)
3012 break;
3013
00b32ff2 3014 byte_op = FALSE;
13761a11
NC
3015
3016 op_length = 2 + 2 * op1.ol;
3017 frag = frag_more (op_length);
3018 where = frag - frag_now->fr_literal;
3019
3020 if (imm_op)
3021 {
3022 if (op1.am == 3)
3023 {
3024 bin |= 0xb0;
3025
3026 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3027 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3028 fix_emitted = TRUE;
3029 }
3030 else if (op1.am == 1)
3031 {
3032 if (op1.reg == 0)
3033 {
3034 bin |= 0x90;
3035
3036 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3037 BFD_RELOC_MSP430X_PCR20_CALL);
3038 fix_emitted = TRUE;
3039 }
3040 else
3041 bin |= 0x50 | op1.reg;
3042 }
3043 else if (op1.am == 0)
3044 bin |= 0x40 | op1.reg;
3045 }
3046 else if (op1.am == 1)
3047 {
3048 bin |= 0x80;
3049
3050 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3051 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3052 fix_emitted = TRUE;
3053 }
3054 else if (op1.am == 2)
3055 bin |= 0x60 | op1.reg;
3056 else if (op1.am == 3)
3057 bin |= 0x70 | op1.reg;
38d77545 3058
13761a11
NC
3059 bfd_putl16 ((bfd_vma) bin, frag);
3060
3061 if (op1.mode == OP_EXP)
3062 {
3063 if (op1.ol != 1)
3064 {
3065 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
65d7bab5 3066 break;
13761a11
NC
3067 }
3068
3069 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3070
3071 if (! fix_emitted)
3072 fix_new_exp (frag_now, where + 2, 2,
3073 &(op1.exp), FALSE, BFD_RELOC_16);
3074 }
3075
3076 dwarf2_emit_insn (insn_length + op_length);
3077 break;
3078
3079 case 5:
b18c562e 3080 {
13761a11
NC
3081 int n;
3082 int reg;
3083
3084 /* [POP|PUSH]M[.A] #N, Rd */
b18c562e 3085 line = extract_operand (line, l1, sizeof (l1));
13761a11 3086 line = extract_operand (line, l2, sizeof (l2));
2469cfa2 3087
13761a11
NC
3088 if (*l1 != '#')
3089 {
638d3803 3090 as_bad (_("expected #n as first argument of %s"), opcode->name);
65d7bab5 3091 break;
13761a11
NC
3092 }
3093 parse_exp (l1 + 1, &(op1.exp));
3094 if (op1.exp.X_op != O_constant)
3095 {
3096 as_bad (_("expected constant expression for first argument of %s"),
3097 opcode->name);
65d7bab5 3098 break;
13761a11 3099 }
2469cfa2 3100
13761a11
NC
3101 if ((reg = check_reg (l2)) == -1)
3102 {
3103 as_bad (_("expected register as second argument of %s"),
3104 opcode->name);
65d7bab5 3105 break;
13761a11 3106 }
2469cfa2 3107
13761a11
NC
3108 op_length = 2;
3109 frag = frag_more (op_length);
b18c562e 3110 where = frag - frag_now->fr_literal;
13761a11
NC
3111 bin = opcode->bin_opcode;
3112 if (! addr_op)
3113 bin |= 0x100;
3114 n = op1.exp.X_add_number;
3115 bin |= (n - 1) << 4;
638d3803 3116 if (is_opcode ("pushm"))
13761a11
NC
3117 bin |= reg;
3118 else
3119 {
3120 if (reg - n + 1 < 0)
3121 {
3122 as_bad (_("Too many registers popped"));
65d7bab5 3123 break;
13761a11 3124 }
638d3803 3125
65d7bab5 3126 /* CPU21 errata: cannot use POPM to restore the SR register. */
d1706f38 3127 if (target_is_430xv2 ()
638d3803
NC
3128 && (reg - n + 1 < 3)
3129 && reg >= 2
3130 && is_opcode ("popm"))
3131 {
3132 as_bad (_("Cannot use POPM to restore the SR register"));
65d7bab5 3133 break;
638d3803
NC
3134 }
3135
13761a11
NC
3136 bin |= (reg - n + 1);
3137 }
3138
b18c562e 3139 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3140 dwarf2_emit_insn (op_length);
3141 break;
3142 }
3143
3144 case 6:
3145 {
3146 int n;
3147 int reg;
3148
3149 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3150 if (extended & 0xff)
3151 {
3152 as_bad (_("repeat count cannot be used with %s"), opcode->name);
65d7bab5 3153 break;
13761a11
NC
3154 }
3155
3156 line = extract_operand (line, l1, sizeof (l1));
3157 line = extract_operand (line, l2, sizeof (l2));
3158
3159 if (*l1 != '#')
3160 {
3161 as_bad (_("expected #n as first argument of %s"), opcode->name);
65d7bab5 3162 break;
13761a11
NC
3163 }
3164 parse_exp (l1 + 1, &(op1.exp));
3165 if (op1.exp.X_op != O_constant)
3166 {
3167 as_bad (_("expected constant expression for first argument of %s"),
3168 opcode->name);
65d7bab5 3169 break;
13761a11
NC
3170 }
3171 n = op1.exp.X_add_number;
3172 if (n > 4 || n < 1)
b18c562e 3173 {
13761a11
NC
3174 as_bad (_("expected first argument of %s to be in the range 1-4"),
3175 opcode->name);
65d7bab5 3176 break;
13761a11 3177 }
b18c562e 3178
13761a11
NC
3179 if ((reg = check_reg (l2)) == -1)
3180 {
3181 as_bad (_("expected register as second argument of %s"),
3182 opcode->name);
65d7bab5 3183 break;
b18c562e
NC
3184 }
3185
d1706f38 3186 if (target_is_430xv2 () && reg == 0)
638d3803
NC
3187 {
3188 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 3189 break;
638d3803
NC
3190 }
3191
13761a11
NC
3192 op_length = 2;
3193 frag = frag_more (op_length);
3194 where = frag - frag_now->fr_literal;
3195
3196 bin = opcode->bin_opcode;
3197 if (! addr_op)
3198 bin |= 0x10;
3199 bin |= (n - 1) << 10;
3200 bin |= reg;
3201
3202 bfd_putl16 ((bfd_vma) bin, frag);
3203 dwarf2_emit_insn (op_length);
3204 break;
3205 }
3206
13761a11
NC
3207 case 8:
3208 {
3209 bfd_boolean need_reloc = FALSE;
3210 int n;
3211 int reg;
3212
3213 /* ADDA, CMPA and SUBA address instructions. */
3214 if (extended & 0xff)
3215 {
3216 as_bad (_("repeat count cannot be used with %s"), opcode->name);
65d7bab5 3217 break;
13761a11
NC
3218 }
3219
3220 line = extract_operand (line, l1, sizeof (l1));
3221 line = extract_operand (line, l2, sizeof (l2));
3222
3223 bin = opcode->bin_opcode;
3224
3225 if (*l1 == '#')
3226 {
3227 parse_exp (l1 + 1, &(op1.exp));
3228
3229 if (op1.exp.X_op == O_constant)
3230 {
3231 n = op1.exp.X_add_number;
3232 if (n > 0xfffff || n < - (0x7ffff))
3233 {
3234 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3235 opcode->name);
65d7bab5 3236 break;
13761a11
NC
3237 }
3238
3239 bin |= ((n >> 16) & 0xf) << 8;
3240 }
3241 else
3242 {
3243 n = 0;
3244 need_reloc = TRUE;
3245 }
3246
3247 op_length = 4;
3248 }
3249 else
3250 {
3251 if ((n = check_reg (l1)) == -1)
3252 {
3253 as_bad (_("expected register name or constant as first argument of %s"),
3254 opcode->name);
65d7bab5 3255 break;
13761a11
NC
3256 }
3257
3258 bin |= (n << 8) | (1 << 6);
3259 op_length = 2;
3260 }
3261
3262 if ((reg = check_reg (l2)) == -1)
3263 {
3264 as_bad (_("expected register as second argument of %s"),
3265 opcode->name);
65d7bab5 3266 break;
13761a11
NC
3267 }
3268
3269 frag = frag_more (op_length);
3270 where = frag - frag_now->fr_literal;
3271 bin |= reg;
3272 if (need_reloc)
3273 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3274 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
3275
3276 bfd_putl16 ((bfd_vma) bin, frag);
3277 if (op_length == 4)
3278 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
3279 dwarf2_emit_insn (op_length);
b18c562e 3280 break;
13761a11 3281 }
38d77545 3282
13761a11 3283 case 9: /* MOVA, BRA, RETA. */
00b32ff2 3284 imm_op = FALSE;
13761a11 3285 bin = opcode->bin_opcode;
b18c562e 3286
638d3803 3287 if (is_opcode ("reta"))
13761a11
NC
3288 {
3289 /* The RETA instruction does not take any arguments.
3290 The implicit first argument is @SP+.
3291 The implicit second argument is PC. */
3292 op1.mode = OP_REG;
3293 op1.am = 3;
3294 op1.reg = 1;
3295
3296 op2.mode = OP_REG;
3297 op2.reg = 0;
3298 }
3299 else
3300 {
3301 line = extract_operand (line, l1, sizeof (l1));
3302 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3303 &imm_op, extended_op, FALSE);
b18c562e 3304
638d3803 3305 if (is_opcode ("bra"))
13761a11
NC
3306 {
3307 /* This is the BRA synthetic instruction.
3308 The second argument is always PC. */
3309 op2.mode = OP_REG;
3310 op2.reg = 0;
3311 }
3312 else
3313 {
3314 line = extract_operand (line, l2, sizeof (l2));
3315 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
3316 extended_op, TRUE);
3317 }
38d77545 3318
13761a11
NC
3319 if (res)
3320 break; /* Error occurred. All warnings were done before. */
3321 }
3322
3323 /* Only a restricted subset of the normal MSP430 addressing modes
3324 are supported here, so check for the ones that are allowed. */
3325 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
3326 & error_message)) == 0)
2469cfa2 3327 {
13761a11 3328 as_bad (error_message, opcode->name);
65d7bab5 3329 break;
13761a11
NC
3330 }
3331 dwarf2_emit_insn (op_length);
3332 break;
3333
3334 case 10: /* RPT */
3335 line = extract_operand (line, l1, sizeof l1);
3336 /* The RPT instruction only accepted immediates and registers. */
3337 if (*l1 == '#')
3338 {
3339 parse_exp (l1 + 1, &(op1.exp));
3340 if (op1.exp.X_op != O_constant)
3341 {
3342 as_bad (_("expected constant value as argument to RPT"));
65d7bab5 3343 break;
13761a11
NC
3344 }
3345 if (op1.exp.X_add_number < 1
3346 || op1.exp.X_add_number > (1 << 4))
3347 {
3348 as_bad (_("expected constant in the range 2..16"));
65d7bab5 3349 break;
13761a11
NC
3350 }
3351
3352 /* We silently accept and ignore a repeat count of 1. */
3353 if (op1.exp.X_add_number > 1)
3354 repeat_count = op1.exp.X_add_number;
3355 }
3356 else
3357 {
3358 int reg;
b18c562e 3359
13761a11
NC
3360 if ((reg = check_reg (l1)) != -1)
3361 {
3362 if (reg == 0)
3363 as_warn (_("PC used as an argument to RPT"));
3364 else
3365 repeat_count = - reg;
3366 }
2469cfa2 3367 else
13761a11
NC
3368 {
3369 as_bad (_("expected constant or register name as argument to RPT insn"));
65d7bab5 3370 break;
13761a11 3371 }
2469cfa2 3372 }
b18c562e 3373 break;
13761a11
NC
3374
3375 default:
3376 as_bad (_("Illegal emulated instruction "));
3377 break;
2469cfa2 3378 }
b18c562e 3379 break;
2469cfa2 3380
b18c562e
NC
3381 case 1: /* Format 1, double operand. */
3382 line = extract_operand (line, l1, sizeof (l1));
3383 line = extract_operand (line, l2, sizeof (l2));
13761a11
NC
3384 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3385 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2469cfa2 3386
b18c562e
NC
3387 if (res)
3388 break; /* Error occurred. All warnings were done before. */
2469cfa2 3389
13761a11 3390 if (extended_op
638d3803 3391 && is_opcode ("movx")
13761a11
NC
3392 && addr_op
3393 && msp430_enable_relax)
3394 {
3395 /* This is the MOVX.A instruction. See if we can convert
3396 it into the MOVA instruction instead. This saves 2 bytes. */
3397 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3398 NULL)) != 0)
3399 {
3400 dwarf2_emit_insn (op_length);
3401 break;
3402 }
3403 }
3404
65d7bab5
NC
3405 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3406
2213f746
NC
3407 /* If the PC is the destination... */
3408 if (op2.am == 0 && op2.reg == 0
3409 /* ... and the opcode alters the SR. */
3410 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3411 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3412 {
3413 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
3414 as_bad (_("CPU11: PC is destinstion of SR altering instruction"));
3415 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
3416 as_warn (_("CPU11: PC is destinstion of SR altering instruction"));
3417 }
3418
3419 /* If the status register is the destination... */
3420 if (op2.am == 0 && op2.reg == 2
3421 /* ... and the opcode alters the SR. */
3422 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3423 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3424 || is_opcode ("xor")
3425 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3426 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3427 || is_opcode ("xorx")
3428 ))
3429 {
3430 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
3431 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3432 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
3433 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3434 }
3435
65d7bab5
NC
3436 if ( (is_opcode ("bic") && bin == 0xc232)
3437 || (is_opcode ("bis") && bin == 0xd232)
3438 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
3439 {
2213f746
NC
3440 /* Avoid false checks when a constant value is being put into the SR. */
3441 if (op1.mode == OP_EXP
3442 && op1.exp.X_op == O_constant
3443 && (op1.exp.X_add_number & 0x8) != 0x8)
3444 ;
3445 else
3446 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5
NC
3447 }
3448
2213f746
NC
3449 if (((is_opcode ("bis") && bin == 0xd032)
3450 || (is_opcode ("mov") && bin == 0x4032)
3451 || (is_opcode ("xor") && bin == 0xe032))
3452 && op1.mode == OP_EXP
3453 && op1.exp.X_op == O_constant
3454 && (op1.exp.X_add_number & 0x10) == 0x10)
3455 check_for_nop |= NOP_CHECK_CPU19;
3456
13761a11 3457 /* Compute the entire length of the instruction in bytes. */
65d7bab5 3458 op_length = (extended_op ? 2 : 0) /* The extension word. */
13761a11
NC
3459 + 2 /* The opcode */
3460 + (2 * op1.ol) /* The first operand. */
3461 + (2 * op2.ol); /* The second operand. */
b18c562e 3462
65d7bab5
NC
3463 insn_length += op_length;
3464 frag = frag_more (op_length);
b18c562e 3465 where = frag - frag_now->fr_literal;
38d77545 3466
13761a11
NC
3467 if (extended_op)
3468 {
3469 if (!addr_op)
3470 extended |= BYTE_OPERATION;
3471
3472 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3473 {
3474 as_bad (_("repeat instruction used with non-register mode instruction"));
3475 extended &= ~ 0xf;
3476 }
3477
3478 /* If necessary, emit a reloc to update the extension word. */
3479 if (op1.mode == OP_EXP)
3480 {
3481 if (op1.exp.X_op == O_constant)
3482 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3483
e66c3c25 3484 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
3485 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3486 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3487 else
3488 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3489 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3490 }
38d77545 3491
13761a11
NC
3492 if (op2.mode == OP_EXP)
3493 {
3494 if (op2.exp.X_op == O_constant)
3495 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3496
3497 else if (op1.mode == OP_EXP)
3498 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3499 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3500 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
38d77545 3501
13761a11
NC
3502 else
3503 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3504 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3505 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3506 }
3507
3508 /* Emit the extension word. */
3509 bfd_putl16 (extended, frag);
3510 where += 2;
3511 frag += 2;
3512 }
3513
b18c562e 3514 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3515 where += 2;
3516 frag += 2;
b18c562e
NC
3517
3518 if (op1.mode == OP_EXP)
2469cfa2 3519 {
13761a11
NC
3520 if (op1.exp.X_op == O_constant)
3521 {
3522 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3523 }
b18c562e 3524 else
13761a11
NC
3525 {
3526 bfd_putl16 ((bfd_vma) ZEROS, frag);
3527
3528 if (!extended_op)
3529 {
e66c3c25 3530 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 3531 fix_new_exp (frag_now, where, 2,
00b32ff2 3532 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
3533 else
3534 fix_new_exp (frag_now, where, 2,
3535 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3536 }
3537 }
3538
3539 where += 2;
3540 frag += 2;
2469cfa2 3541 }
b18c562e
NC
3542
3543 if (op2.mode == OP_EXP)
2469cfa2 3544 {
13761a11
NC
3545 if (op2.exp.X_op == O_constant)
3546 {
3547 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3548 }
b18c562e 3549 else
13761a11
NC
3550 {
3551 bfd_putl16 ((bfd_vma) ZEROS, frag);
3552
3553 if (!extended_op)
3554 {
3555 if (op2.reg) /* Not PC relative. */
3556 fix_new_exp (frag_now, where, 2,
00b32ff2 3557 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
13761a11
NC
3558 else
3559 fix_new_exp (frag_now, where, 2,
3560 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3561 }
3562 }
3563 }
3564
13761a11 3565 dwarf2_emit_insn (insn_length);
2213f746
NC
3566
3567 /* If the PC is the destination... */
3568 if (op2.am == 0 && op2.reg == 0
3569 /* ... but the opcode does not alter the destination. */
3570 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3571 check_for_nop |= NOP_CHECK_CPU12;
b18c562e
NC
3572 break;
3573
3574 case 2: /* Single-operand mostly instr. */
3575 if (opcode->insn_opnumb == 0)
2469cfa2 3576 {
b18c562e 3577 /* reti instruction. */
13761a11 3578 insn_length += 2;
b18c562e
NC
3579 frag = frag_more (2);
3580 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 3581 dwarf2_emit_insn (insn_length);
b18c562e 3582 break;
2469cfa2 3583 }
2469cfa2 3584
b18c562e 3585 line = extract_operand (line, l1, sizeof (l1));
13761a11
NC
3586 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3587 &imm_op, extended_op, TRUE);
b18c562e
NC
3588 if (res)
3589 break; /* Error in operand. */
2469cfa2 3590
d1706f38
NC
3591 if (target_is_430xv2 ()
3592 && op1.mode == OP_REG
38d77545 3593 && op1.reg == 0
638d3803
NC
3594 && (is_opcode ("rrax")
3595 || is_opcode ("rrcx")
3596 || is_opcode ("rra")
3597 || is_opcode ("rrc")))
3598 {
3599 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 3600 break;
638d3803 3601 }
38d77545 3602
2213f746
NC
3603 /* If the status register is the destination... */
3604 if (op1.am == 0 && op1.reg == 2
3605 /* ... and the opcode alters the SR. */
3606 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3607 {
3608 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
3609 as_bad (_("CPU13: SR is destinstion of SR altering instruction"));
3610 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
3611 as_warn (_("CPU13: SR is destinstion of SR altering instruction"));
3612 }
3613
13761a11
NC
3614 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3615 frag = frag_more (insn_length);
b18c562e 3616 where = frag - frag_now->fr_literal;
38d77545 3617
13761a11
NC
3618 if (extended_op)
3619 {
638d3803 3620 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
13761a11
NC
3621 {
3622 /* These two instructions use a special
3623 encoding of the A/L and B/W bits. */
3624 bin &= ~ BYTE_OPERATION;
3625
3626 if (byte_op)
3627 {
3628 as_bad (_("%s instruction does not accept a .b suffix"),
3629 opcode->name);
65d7bab5 3630 break;
13761a11
NC
3631 }
3632 else if (! addr_op)
3633 extended |= BYTE_OPERATION;
3634 }
3635 else if (! addr_op)
3636 extended |= BYTE_OPERATION;
3637
c1d9289f
NC
3638 if (is_opcode ("rrux"))
3639 extended |= IGNORE_CARRY_BIT;
3640
13761a11
NC
3641 if (op1.ol != 0 && ((extended & 0xf) != 0))
3642 {
3643 as_bad (_("repeat instruction used with non-register mode instruction"));
3644 extended &= ~ 0xf;
3645 }
3646
3647 if (op1.mode == OP_EXP)
3648 {
3649 if (op1.exp.X_op == O_constant)
3650 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
38d77545 3651
e66c3c25 3652 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
3653 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3654 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3655 else
3656 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3657 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3658 }
38d77545 3659
13761a11
NC
3660 /* Emit the extension word. */
3661 bfd_putl16 (extended, frag);
3662 frag += 2;
3663 where += 2;
3664 }
3665
3666 bin |= op1.reg | (op1.am << 4);
b18c562e 3667 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3668 frag += 2;
3669 where += 2;
b18c562e
NC
3670
3671 if (op1.mode == OP_EXP)
2469cfa2 3672 {
13761a11
NC
3673 if (op1.exp.X_op == O_constant)
3674 {
3675 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3676 }
b18c562e 3677 else
13761a11
NC
3678 {
3679 bfd_putl16 ((bfd_vma) ZEROS, frag);
3680
3681 if (!extended_op)
3682 {
e66c3c25 3683 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 3684 fix_new_exp (frag_now, where, 2,
00b32ff2 3685 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
3686 else
3687 fix_new_exp (frag_now, where, 2,
3688 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3689 }
3690 }
2469cfa2 3691 }
13761a11
NC
3692
3693 dwarf2_emit_insn (insn_length);
b18c562e 3694 break;
2469cfa2 3695
b18c562e
NC
3696 case 3: /* Conditional jumps instructions. */
3697 line = extract_operand (line, l1, sizeof (l1));
3698 /* l1 is a label. */
3699 if (l1[0])
2469cfa2 3700 {
b18c562e
NC
3701 char *m = l1;
3702 expressionS exp;
2469cfa2 3703
b18c562e
NC
3704 if (*m == '$')
3705 m++;
2469cfa2 3706
b18c562e 3707 parse_exp (m, &exp);
2469cfa2 3708
b18c562e 3709 /* In order to handle something like:
2469cfa2 3710
b18c562e
NC
3711 and #0x8000, r5
3712 tst r5
3713 jz 4 ; skip next 4 bytes
3714 inv r5
3715 inc r5
3716 nop ; will jump here if r5 positive or zero
2469cfa2 3717
b18c562e 3718 jCOND -n ;assumes jump n bytes backward:
2469cfa2 3719
b18c562e
NC
3720 mov r5,r6
3721 jmp -2
2469cfa2 3722
b18c562e
NC
3723 is equal to:
3724 lab:
3725 mov r5,r6
3726 jmp lab
3727
3728 jCOND $n ; jump from PC in either direction. */
2469cfa2 3729
b18c562e
NC
3730 if (exp.X_op == O_constant)
3731 {
3732 int x = exp.X_add_number;
2469cfa2 3733
b18c562e
NC
3734 if (x & 1)
3735 {
3736 as_warn (_("Even number required. Rounded to %d"), x + 1);
3737 x++;
3738 }
2469cfa2 3739
b18c562e
NC
3740 if ((*l1 == '$' && x > 0) || x < 0)
3741 x -= 2;
2469cfa2 3742
b18c562e
NC
3743 x >>= 1;
3744
3745 if (x > 512 || x < -511)
3746 {
3747 as_bad (_("Wrong displacement %d"), x << 1);
3748 break;
3749 }
3750
13761a11
NC
3751 insn_length += 2;
3752 frag = frag_more (2); /* Instr size is 1 word. */
3753
b18c562e
NC
3754 bin |= x & 0x3ff;
3755 bfd_putl16 ((bfd_vma) bin, frag);
3756 }
3757 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 3758 {
13761a11
NC
3759 insn_length += 2;
3760 frag = frag_more (2); /* Instr size is 1 word. */
b18c562e
NC
3761 where = frag - frag_now->fr_literal;
3762 fix_new_exp (frag_now, where, 2,
3763 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3764
3765 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 3766 }
b18c562e 3767 else if (*l1 == '$')
2469cfa2 3768 {
b18c562e 3769 as_bad (_("instruction requires label sans '$'"));
2469cfa2 3770 }
b18c562e 3771 else
13761a11
NC
3772 as_bad (_
3773 ("instruction requires label or value in range -511:512"));
3774 dwarf2_emit_insn (insn_length);
2a9a06c1 3775 break;
2469cfa2 3776 }
b18c562e
NC
3777 else
3778 {
3779 as_bad (_("instruction requires label"));
3780 break;
3781 }
3782 break;
2469cfa2 3783
b18c562e 3784 case 4: /* Extended jumps. */
77592908
DD
3785 if (!msp430_enable_polys)
3786 {
20203fb9 3787 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3788 break;
3789 }
3739860c 3790
b18c562e
NC
3791 line = extract_operand (line, l1, sizeof (l1));
3792 if (l1[0])
2469cfa2 3793 {
b18c562e
NC
3794 char *m = l1;
3795 expressionS exp;
2469cfa2 3796
b18c562e
NC
3797 /* Ignore absolute addressing. make it PC relative anyway. */
3798 if (*m == '#' || *m == '$')
3799 m++;
2469cfa2 3800
b18c562e
NC
3801 parse_exp (m, & exp);
3802 if (exp.X_op == O_symbol)
2469cfa2 3803 {
b18c562e
NC
3804 /* Relaxation required. */
3805 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3806
638d3803 3807 if (target_is_430x ())
13761a11
NC
3808 rc = msp430x_rcodes[opcode->insn_opnumb];
3809
3810 /* The parameter to dwarf2_emit_insn is actually the offset to
3811 the start of the insn from the fix piece of instruction that
3812 was emitted. Since next fragments may have variable size we
3813 tie debug info to the beginning of the instruction. */
3814 insn_length += 8;
3e470ab5 3815 frag = frag_more (8);
2a9a06c1 3816 dwarf2_emit_insn (0);
3e470ab5
DD
3817 bfd_putl16 ((bfd_vma) rc.sop, frag);
3818 frag = frag_variant (rs_machine_dependent, 8, 2,
13761a11
NC
3819 /* Wild guess. */
3820 ENCODE_RELAX (rc.lpos, STATE_BITS10),
b18c562e
NC
3821 exp.X_add_symbol,
3822 0, /* Offset is zero if jump dist less than 1K. */
3823 (char *) frag);
3824 break;
2469cfa2
NC
3825 }
3826 }
b18c562e
NC
3827
3828 as_bad (_("instruction requires label"));
3829 break;
3830
3831 case 5: /* Emulated extended branches. */
77592908
DD
3832 if (!msp430_enable_polys)
3833 {
20203fb9 3834 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3835 break;
3836 }
b18c562e
NC
3837 line = extract_operand (line, l1, sizeof (l1));
3838 if (l1[0])
2469cfa2 3839 {
b18c562e
NC
3840 char * m = l1;
3841 expressionS exp;
3842
3843 /* Ignore absolute addressing. make it PC relative anyway. */
3844 if (*m == '#' || *m == '$')
3845 m++;
3846
3847 parse_exp (m, & exp);
3848 if (exp.X_op == O_symbol)
3849 {
3850 /* Relaxation required. */
3851 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3852
638d3803 3853 if (target_is_430x ())
13761a11
NC
3854 hc = msp430x_hcodes[opcode->insn_opnumb];
3855
3856 insn_length += 8;
3e470ab5 3857 frag = frag_more (8);
2a9a06c1 3858 dwarf2_emit_insn (0);
3e470ab5
DD
3859 bfd_putl16 ((bfd_vma) hc.op0, frag);
3860 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3861
3862 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
3863 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3864 exp.X_add_symbol,
3865 0, /* Offset is zero if jump dist less than 1K. */
3866 (char *) frag);
3867 break;
3868 }
2469cfa2
NC
3869 }
3870
b18c562e
NC
3871 as_bad (_("instruction requires label"));
3872 break;
2469cfa2 3873
b18c562e 3874 default:
79cf5950 3875 as_bad (_("Illegal instruction or not implemented opcode."));
b18c562e 3876 }
2469cfa2 3877
927f2d25
NC
3878 if (is_opcode ("nop"))
3879 prev_insn_is_nop = TRUE;
3880 else
3881 prev_insn_is_nop = FALSE;
3882
b18c562e
NC
3883 input_line_pointer = line;
3884 return 0;
3885}
2469cfa2 3886
b18c562e
NC
3887void
3888md_assemble (char * str)
3889{
3890 struct msp430_opcode_s * opcode;
3891 char cmd[32];
3892 unsigned int i = 0;
2469cfa2 3893
b18c562e 3894 str = skip_space (str); /* Skip leading spaces. */
64a81db0 3895 str = extract_cmd (str, cmd, sizeof (cmd) - 1);
2469cfa2 3896
64a81db0 3897 while (cmd[i])
b18c562e
NC
3898 {
3899 char a = TOLOWER (cmd[i]);
3900 cmd[i] = a;
3901 i++;
2469cfa2 3902 }
2469cfa2 3903
b18c562e 3904 if (!cmd[0])
2469cfa2 3905 {
b18c562e
NC
3906 as_bad (_("can't find opcode "));
3907 return;
3908 }
2469cfa2 3909
b18c562e 3910 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 3911
b18c562e
NC
3912 if (opcode == NULL)
3913 {
3914 as_bad (_("unknown opcode `%s'"), cmd);
3915 return;
2469cfa2 3916 }
2469cfa2 3917
b18c562e
NC
3918 {
3919 char *__t = input_line_pointer;
2469cfa2 3920
b18c562e
NC
3921 msp430_operands (opcode, str);
3922 input_line_pointer = __t;
3923 }
3924}
2469cfa2
NC
3925
3926/* GAS will call this function for each section at the end of the assembly,
3927 to permit the CPU backend to adjust the alignment of a section. */
3928
3929valueT
b18c562e 3930md_section_align (asection * seg, valueT addr)
2469cfa2
NC
3931{
3932 int align = bfd_get_section_alignment (stdoutput, seg);
3933
8d3842cd 3934 return ((addr + (1 << align) - 1) & -(1 << align));
2469cfa2
NC
3935}
3936
3937/* If you define this macro, it should return the offset between the
3938 address of a PC relative fixup and the position from which the PC
3939 relative adjustment should be made. On many processors, the base
3940 of a PC relative instruction is the next instruction, so this
3941 macro would return the length of an instruction. */
3942
3943long
b18c562e 3944md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
3945{
3946 if (fixp->fx_addsy != (symbolS *) NULL
3947 && (!S_IS_DEFINED (fixp->fx_addsy)
3948 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
3949 return 0;
3950
3951 return fixp->fx_frag->fr_address + fixp->fx_where;
3952}
3953
77592908
DD
3954/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
3955 Now it handles the situation when relocations
13761a11 3956 have to be passed to linker. */
77592908 3957int
13761a11 3958msp430_force_relocation_local (fixS *fixp)
77592908 3959{
13761a11
NC
3960 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
3961 return 1;
13761a11
NC
3962 if (fixp->fx_pcrel)
3963 return 1;
77592908
DD
3964 if (msp430_enable_polys
3965 && !msp430_enable_relax)
3966 return 1;
13761a11
NC
3967
3968 return (!fixp->fx_pcrel
3969 || generic_force_reloc (fixp));
77592908
DD
3970}
3971
3972
2469cfa2
NC
3973/* GAS will call this for each fixup. It should store the correct
3974 value in the object file. */
2469cfa2 3975void
55cf6793 3976md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 3977{
b18c562e 3978 unsigned char * where;
2469cfa2
NC
3979 unsigned long insn;
3980 long value;
3981
3982 if (fixp->fx_addsy == (symbolS *) NULL)
3983 {
3984 value = *valuep;
3985 fixp->fx_done = 1;
3986 }
3987 else if (fixp->fx_pcrel)
3988 {
3989 segT s = S_GET_SEGMENT (fixp->fx_addsy);
3990
3991 if (fixp->fx_addsy && (s == seg || s == absolute_section))
3992 {
18af0b39
NC
3993 /* FIXME: We can appear here only in case if we perform a pc
3994 relative jump to the label which is i) global, ii) locally
3995 defined or this is a jump to an absolute symbol.
3996 If this is an absolute symbol -- everything is OK.
3997 If this is a global label, we've got a symbol value defined
3998 twice:
3999 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4000 from this section start
4001 2. *valuep will contain the real offset from jump insn to the
4002 label
4003 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4004 will be incorrect. Therefore remove s_get_value. */
4005 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
4006 fixp->fx_done = 1;
4007 }
4008 else
4009 value = *valuep;
4010 }
4011 else
4012 {
4013 value = fixp->fx_offset;
4014
4015 if (fixp->fx_subsy != (symbolS *) NULL)
4016 {
4017 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4018 {
4019 value -= S_GET_VALUE (fixp->fx_subsy);
4020 fixp->fx_done = 1;
4021 }
2469cfa2
NC
4022 }
4023 }
4024
77592908
DD
4025 fixp->fx_no_overflow = 1;
4026
38d77545 4027 /* If polymorphs are enabled and relax disabled.
13761a11 4028 do not kill any relocs and pass them to linker. */
38d77545 4029 if (msp430_enable_polys
77592908 4030 && !msp430_enable_relax)
2469cfa2 4031 {
e66c3c25
NC
4032 if (!fixp->fx_addsy
4033 || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
79cf5950 4034 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
77592908
DD
4035 else
4036 fixp->fx_done = 0;
2469cfa2
NC
4037 }
4038
4039 if (fixp->fx_done)
4040 {
4041 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 4042 value, and stuff the instruction back again. */
2132e3a3 4043 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
4044
4045 insn = bfd_getl16 (where);
4046
4047 switch (fixp->fx_r_type)
4048 {
4049 case BFD_RELOC_MSP430_10_PCREL:
4050 if (value & 1)
4051 as_bad_where (fixp->fx_file, fixp->fx_line,
4052 _("odd address operand: %ld"), value);
4053
4054 /* Jumps are in words. */
4055 value >>= 1;
4056 --value; /* Correct PC. */
4057
4058 if (value < -512 || value > 511)
4059 as_bad_where (fixp->fx_file, fixp->fx_line,
4060 _("operand out of range: %ld"), value);
4061
4062 value &= 0x3ff; /* get rid of extended sign */
4063 bfd_putl16 ((bfd_vma) (value | insn), where);
4064 break;
4065
13761a11 4066 case BFD_RELOC_MSP430X_PCR16:
b18c562e 4067 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
4068 case BFD_RELOC_MSP430_16_PCREL:
4069 if (value & 1)
4070 as_bad_where (fixp->fx_file, fixp->fx_line,
4071 _("odd address operand: %ld"), value);
13761a11 4072 /* Fall through. */
2469cfa2
NC
4073
4074 case BFD_RELOC_MSP430_16_PCREL_BYTE:
4075 /* Nothing to be corrected here. */
4076 if (value < -32768 || value > 65536)
4077 as_bad_where (fixp->fx_file, fixp->fx_line,
4078 _("operand out of range: %ld"), value);
13761a11 4079 /* Fall through. */
2469cfa2 4080
13761a11
NC
4081 case BFD_RELOC_MSP430X_ABS16:
4082 case BFD_RELOC_MSP430_16:
4083 case BFD_RELOC_16:
4084 case BFD_RELOC_MSP430_16_BYTE:
2469cfa2
NC
4085 value &= 0xffff; /* Get rid of extended sign. */
4086 bfd_putl16 ((bfd_vma) value, where);
4087 break;
4088
00b32ff2
NC
4089 case BFD_RELOC_MSP430_ABS_HI16:
4090 value >>= 16;
4091 value &= 0xffff; /* Get rid of extended sign. */
4092 bfd_putl16 ((bfd_vma) value, where);
4093 break;
3739860c 4094
2469cfa2
NC
4095 case BFD_RELOC_32:
4096 bfd_putl16 ((bfd_vma) value, where);
4097 break;
4098
13761a11
NC
4099 case BFD_RELOC_MSP430_ABS8:
4100 case BFD_RELOC_8:
4101 bfd_put_8 (NULL, (bfd_vma) value, where);
4102 break;
4103
4104 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
4105 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
4106 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
38d77545 4107 value >>= 16;
13761a11
NC
4108 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
4109 break;
4110
4111 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
4112 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
38d77545 4113 value >>= 16;
13761a11
NC
4114 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
4115 break;
4116
4117 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
4118 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4119 value >>= 16;
4120 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4121 break;
4122
4123 case BFD_RELOC_MSP430X_PCR20_CALL:
4124 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4125 value >>= 16;
4126 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4127 break;
4128
4129 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
4130 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
4131 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
4132 value >>= 16;
4133 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4134 break;
4135
4136 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
4137 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4138 value >>= 16;
4139 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4140 break;
4141
4142 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
4143 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4144 value >>= 16;
4145 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
2469cfa2 4146 break;
38d77545 4147
2469cfa2
NC
4148 default:
4149 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4150 fixp->fx_line, fixp->fx_r_type);
4151 break;
4152 }
4153 }
4154 else
4155 {
4156 fixp->fx_addnumber = value;
4157 }
2469cfa2
NC
4158}
4159
13761a11
NC
4160static bfd_boolean
4161S_IS_GAS_LOCAL (symbolS * s)
4162{
4163 const char * name;
4164 unsigned int len;
4165
4166 if (s == NULL)
4167 return FALSE;
4168 name = S_GET_NAME (s);
4169 len = strlen (name) - 1;
38d77545 4170
13761a11
NC
4171 return name[len] == 1 || name[len] == 2;
4172}
4173
7be1c489
AM
4174/* GAS will call this to generate a reloc, passing the resulting reloc
4175 to `bfd_install_relocation'. This currently works poorly, as
4176 `bfd_install_relocation' often does the wrong thing, and instances of
4177 `tc_gen_reloc' have been written to work around the problems, which
4178 in turns makes it difficult to fix `bfd_install_relocation'. */
2469cfa2
NC
4179
4180/* If while processing a fixup, a reloc really needs to be created
4181 then it is done here. */
4182
13761a11 4183arelent **
b18c562e 4184tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 4185{
13761a11
NC
4186 static arelent * no_relocs = NULL;
4187 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
4188 arelent *reloc;
2469cfa2 4189
325801bd 4190 reloc = XNEW (arelent);
2469cfa2
NC
4191 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4192 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
13761a11 4193
2469cfa2
NC
4194 if (reloc->howto == (reloc_howto_type *) NULL)
4195 {
4196 as_bad_where (fixp->fx_file, fixp->fx_line,
4197 _("reloc %d not supported by object file format"),
4198 (int) fixp->fx_r_type);
13761a11
NC
4199 free (reloc);
4200 return & no_relocs;
4201 }
4202
4203 relocs[0] = reloc;
4204 relocs[1] = NULL;
4205
4206 if (fixp->fx_subsy
4207 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4208 {
4209 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
4210 fixp->fx_subsy = NULL;
2469cfa2
NC
4211 }
4212
13761a11
NC
4213 if (fixp->fx_addsy && fixp->fx_subsy)
4214 {
4215 asection *asec, *ssec;
4216
4217 asec = S_GET_SEGMENT (fixp->fx_addsy);
4218 ssec = S_GET_SEGMENT (fixp->fx_subsy);
4219
4220 /* If we have a difference between two different, non-absolute symbols
4221 we must generate two relocs (one for each symbol) and allow the
4222 linker to resolve them - relaxation may change the distances between
4223 symbols, even local symbols defined in the same section.
4224
4225 Unfortunately we cannot do this with assembler generated local labels
4226 because there can be multiple incarnations of the same label, with
4227 exactly the same name, in any given section and the linker will have
4228 no way to identify the correct one. Instead we just have to hope
4229 that no relaxtion will occur between the local label and the other
4230 symbol in the expression.
4231
4232 Similarly we have to compute differences between symbols in the .eh_frame
4233 section as the linker is not smart enough to apply relocations there
4234 before attempting to process it. */
4235 if ((ssec != absolute_section || asec != absolute_section)
4236 && (fixp->fx_addsy != fixp->fx_subsy)
4237 && strcmp (ssec->name, ".eh_frame") != 0
4238 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
4239 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
4240 {
325801bd 4241 arelent * reloc2 = XNEW (arelent);
2469cfa2 4242
13761a11
NC
4243 relocs[0] = reloc2;
4244 relocs[1] = reloc;
2469cfa2 4245
13761a11
NC
4246 reloc2->address = reloc->address;
4247 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
4248 BFD_RELOC_MSP430_SYM_DIFF);
4249 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
4250
4251 if (ssec == absolute_section)
4252 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4253 else
4254 {
325801bd 4255 reloc2->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4256 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
4257 }
4258
38d77545 4259 reloc->addend = fixp->fx_offset;
13761a11
NC
4260 if (asec == absolute_section)
4261 {
4262 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
4263 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4264 }
4265 else
4266 {
325801bd 4267 reloc->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4268 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4269 }
4270
4271 fixp->fx_pcrel = 0;
4272 fixp->fx_done = 1;
4273 return relocs;
4274 }
4275 else
4276 {
4277 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4278
4279 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
4280 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
4281
4282 switch (fixp->fx_r_type)
4283 {
4284 case BFD_RELOC_8:
4285 md_number_to_chars (fixpos, reloc->addend, 1);
4286 break;
4287
4288 case BFD_RELOC_16:
4289 md_number_to_chars (fixpos, reloc->addend, 2);
4290 break;
4291
4292 case BFD_RELOC_24:
4293 md_number_to_chars (fixpos, reloc->addend, 3);
4294 break;
4295
4296 case BFD_RELOC_32:
4297 md_number_to_chars (fixpos, reloc->addend, 4);
4298 break;
4299
4300 default:
4301 reloc->sym_ptr_ptr
4302 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
4303 return relocs;
4304 }
4305
4306 free (reloc);
4307 return & no_relocs;
4308 }
4309 }
4310 else
4311 {
4312#if 0
4313 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
4314 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
4315 {
4316 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
4317 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4318
4319 md_number_to_chars (fixpos, amount, 2);
4320 free (reloc);
4321 return & no_relocs;
4322 }
4323#endif
325801bd 4324 reloc->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4325 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4326 reloc->addend = fixp->fx_offset;
4327
4328 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
4329 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
4330 reloc->address = fixp->fx_offset;
4331 }
4332
4333 return relocs;
2469cfa2
NC
4334}
4335
b18c562e
NC
4336int
4337md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
4338 asection * segment_type ATTRIBUTE_UNUSED)
4339{
4340 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
4341 {
4342 /* This is a jump -> pcrel mode. Nothing to do much here.
4343 Return value == 2. */
4344 fragP->fr_subtype =
4345 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
4346 }
4347 else if (fragP->fr_symbol)
4348 {
4349 /* Its got a segment, but its not ours. Even if fr_symbol is in
79cf5950 4350 an absolute segment, we don't know a displacement until we link
b18c562e
NC
4351 object files. So it will always be long. This also applies to
4352 labels in a subsegment of current. Liker may relax it to short
4353 jump later. Return value == 8. */
4354 fragP->fr_subtype =
4355 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
4356 }
4357 else
4358 {
4359 /* We know the abs value. may be it is a jump to fixed address.
79cf5950 4360 Impossible in our case, cause all constants already handled. */
b18c562e
NC
4361 fragP->fr_subtype =
4362 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
4363 }
2469cfa2 4364
b18c562e
NC
4365 return md_relax_table[fragP->fr_subtype].rlx_length;
4366}
4367
4368void
4369md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
4370 asection * sec ATTRIBUTE_UNUSED,
4371 fragS * fragP)
2469cfa2 4372{
b18c562e
NC
4373 char * where = 0;
4374 int rela = -1;
4375 int i;
4376 struct rcodes_s * cc = NULL;
4377 struct hcodes_s * hc = NULL;
4378
4379 switch (fragP->fr_subtype)
4380 {
4381 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
4382 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
4383 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
4384 /* We do not have to convert anything here.
4385 Just apply a fix. */
4386 rela = BFD_RELOC_MSP430_10_PCREL;
4387 break;
4388
4389 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
4390 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
4391 /* Convert uncond branch jmp lab -> br lab. */
638d3803 4392 if (target_is_430x ())
13761a11 4393 cc = msp430x_rcodes + 7;
638d3803
NC
4394 else
4395 cc = msp430_rcodes + 7;
b18c562e
NC
4396 where = fragP->fr_literal + fragP->fr_fix;
4397 bfd_putl16 (cc->lop0, where);
4398 rela = BFD_RELOC_MSP430_RL_PCREL;
4399 fragP->fr_fix += 2;
4400 break;
4401
4402 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
4403 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
4404 {
4405 /* Other simple branches. */
4406 int insn = bfd_getl16 (fragP->fr_opcode);
4407
4408 insn &= 0xffff;
4409 /* Find actual instruction. */
638d3803 4410 if (target_is_430x ())
13761a11
NC
4411 {
4412 for (i = 0; i < 7 && !cc; i++)
4413 if (msp430x_rcodes[i].sop == insn)
4414 cc = msp430x_rcodes + i;
4415 }
4416 else
4417 {
4418 for (i = 0; i < 7 && !cc; i++)
4419 if (msp430_rcodes[i].sop == insn)
4420 cc = & msp430_rcodes[i];
4421 }
4422
b18c562e
NC
4423 if (!cc || !cc->name)
4424 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4425 __FUNCTION__, (long) insn);
4426 where = fragP->fr_literal + fragP->fr_fix;
4427 bfd_putl16 (cc->lop0, where);
4428 bfd_putl16 (cc->lop1, where + 2);
4429 rela = BFD_RELOC_MSP430_RL_PCREL;
4430 fragP->fr_fix += 4;
4431 }
4432 break;
4433
4434 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
4435 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
638d3803 4436 if (target_is_430x ())
13761a11 4437 cc = msp430x_rcodes + 6;
638d3803
NC
4438 else
4439 cc = msp430_rcodes + 6;
b18c562e
NC
4440 where = fragP->fr_literal + fragP->fr_fix;
4441 bfd_putl16 (cc->lop0, where);
4442 bfd_putl16 (cc->lop1, where + 2);
4443 bfd_putl16 (cc->lop2, where + 4);
4444 rela = BFD_RELOC_MSP430_RL_PCREL;
4445 fragP->fr_fix += 6;
4446 break;
4447
4448 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4449 {
4450 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4451
4452 insn &= 0xffff;
638d3803 4453 if (target_is_430x ())
13761a11
NC
4454 {
4455 for (i = 0; i < 4 && !hc; i++)
4456 if (msp430x_hcodes[i].op1 == insn)
4457 hc = msp430x_hcodes + i;
4458 }
4459 else
4460 {
4461 for (i = 0; i < 4 && !hc; i++)
4462 if (msp430_hcodes[i].op1 == insn)
4463 hc = &msp430_hcodes[i];
4464 }
b18c562e
NC
4465 if (!hc || !hc->name)
4466 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4467 __FUNCTION__, (long) insn);
4468 rela = BFD_RELOC_MSP430_10_PCREL;
4469 /* Apply a fix for a first label if necessary.
4470 another fix will be applied to the next word of insn anyway. */
4471 if (hc->tlab == 2)
4472 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
13761a11 4473 fragP->fr_offset, TRUE, rela);
b18c562e
NC
4474 fragP->fr_fix += 2;
4475 }
4476
4477 break;
4478
4479 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4480 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4481 {
4482 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4483
4484 insn &= 0xffff;
638d3803 4485 if (target_is_430x ())
13761a11
NC
4486 {
4487 for (i = 0; i < 4 && !hc; i++)
4488 if (msp430x_hcodes[i].op1 == insn)
4489 hc = msp430x_hcodes + i;
4490 }
4491 else
4492 {
4493 for (i = 0; i < 4 && !hc; i++)
4494 if (msp430_hcodes[i].op1 == insn)
4495 hc = & msp430_hcodes[i];
4496 }
b18c562e
NC
4497 if (!hc || !hc->name)
4498 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4499 __FUNCTION__, (long) insn);
4500 rela = BFD_RELOC_MSP430_RL_PCREL;
4501 where = fragP->fr_literal + fragP->fr_fix;
4502 bfd_putl16 (hc->lop0, where);
4503 bfd_putl16 (hc->lop1, where + 2);
4504 bfd_putl16 (hc->lop2, where + 4);
4505 fragP->fr_fix += 6;
4506 }
4507 break;
4508
4509 default:
4510 as_fatal (_("internal inconsistency problem in %s: %lx"),
4511 __FUNCTION__, (long) fragP->fr_subtype);
4512 break;
4513 }
4514
4515 /* Now apply fix. */
4516 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4517 fragP->fr_offset, TRUE, rela);
4518 /* Just fixed 2 bytes. */
4519 fragP->fr_fix += 2;
2469cfa2
NC
4520}
4521
b18c562e
NC
4522/* Relax fragment. Mostly stolen from hc11 and mcore
4523 which arches I think I know. */
2469cfa2 4524
b18c562e
NC
4525long
4526msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4527 long stretch ATTRIBUTE_UNUSED)
2469cfa2 4528{
b18c562e
NC
4529 long growth;
4530 offsetT aim = 0;
4531 symbolS *symbolP;
4532 const relax_typeS *this_type;
4533 const relax_typeS *start_type;
4534 relax_substateT next_state;
4535 relax_substateT this_state;
4536 const relax_typeS *table = md_relax_table;
4537
4538 /* Nothing to be done if the frag has already max size. */
4539 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4540 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4541 return 0;
4542
4543 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4544 {
4545 symbolP = fragP->fr_symbol;
4546 if (symbol_resolved_p (symbolP))
4547 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4548 __FUNCTION__);
4549 /* We know the offset. calculate a distance. */
4550 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4551 }
4552
77592908
DD
4553 if (!msp430_enable_relax)
4554 {
4555 /* Relaxation is not enabled. So, make all jump as long ones
13761a11 4556 by setting 'aim' to quite high value. */
77592908
DD
4557 aim = 0x7fff;
4558 }
38d77545 4559
b18c562e
NC
4560 this_state = fragP->fr_subtype;
4561 start_type = this_type = table + this_state;
4562
4563 if (aim < 0)
4564 {
4565 /* Look backwards. */
4566 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4567 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
b18c562e
NC
4568 next_state = 0;
4569 else
4570 {
4571 /* Grow to next state. */
4572 this_state = next_state;
4573 this_type = table + this_state;
4574 next_state = this_type->rlx_more;
4575 }
4576 }
4577 else
4578 {
4579 /* Look forwards. */
4580 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4581 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
b18c562e
NC
4582 next_state = 0;
4583 else
4584 {
4585 /* Grow to next state. */
4586 this_state = next_state;
4587 this_type = table + this_state;
4588 next_state = this_type->rlx_more;
4589 }
4590 }
4591
4592 growth = this_type->rlx_length - start_type->rlx_length;
4593 if (growth != 0)
4594 fragP->fr_subtype = this_state;
4595 return growth;
2469cfa2 4596}
13761a11
NC
4597
4598/* Return FALSE if the fixup in fixp should be left alone and not
4599 adjusted. We return FALSE here so that linker relaxation will
4600 work. */
4601
4602bfd_boolean
4603msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4604{
4605 /* If the symbol is in a non-code section then it should be OK. */
4606 if (fixp->fx_addsy
4607 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4608 return TRUE;
38d77545 4609
13761a11
NC
4610 return FALSE;
4611}
4612
4613/* Set the contents of the .MSP430.attributes section. */
4614
4615void
4616msp430_md_end (void)
4617{
2213f746
NC
4618 if (check_for_nop)
4619 as_warn ("assembly finished without a possibly needed NOP instruction");
65d7bab5 4620
13761a11 4621 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
638d3803 4622 target_is_430x () ? 2 : 1);
13761a11
NC
4623
4624 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4625 large_model ? 2 : 1);
4626
4627 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4628 large_model ? 2 : 1);
4629}
4630
4631/* Returns FALSE if there is a msp430 specific reason why the
4632 subtraction of two same-section symbols cannot be computed by
4633 the assembler. */
4634
4635bfd_boolean
4636msp430_allow_local_subtract (expressionS * left,
4637 expressionS * right,
4638 segT section)
4639{
4640 /* If the symbols are not in a code section then they are OK. */
4641 if ((section->flags & SEC_CODE) == 0)
4642 return TRUE;
4643
4644 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4645 return TRUE;
4646
4647 if (left->X_add_symbol == right->X_add_symbol)
4648 return TRUE;
4649
4650 /* We have to assume that there may be instructions between the
4651 two symbols and that relaxation may increase the distance between
4652 them. */
4653 return FALSE;
4654}
This page took 0.859624 seconds and 4 git commands to generate.