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