[BINUTILS, AARCH64, 7/8] Add system registers for Memory Tagging Extension
[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
791755f5
NC
1675static inline bfd_boolean
1676is_regname_end (char c)
1677{
1678 return (c == 0 || ! ISALNUM (c));
1679}
1680
13761a11
NC
1681/* Returns the register number equivalent to the string T.
1682 Returns -1 if there is no such register.
1683 Skips a leading 'r' or 'R' character if there is one.
1684 Handles the register aliases PC and SP. */
1685
1686static signed int
b18c562e 1687check_reg (char * t)
2469cfa2 1688{
791755f5
NC
1689 char * endt;
1690 signed long int val;
2469cfa2 1691
791755f5 1692 if (t == NULL || t[0] == 0)
13761a11 1693 return -1;
2469cfa2 1694
13761a11
NC
1695 if (*t == 'r' || *t == 'R')
1696 ++t;
1697
791755f5 1698 if (strncasecmp (t, "pc", 2) == 0 && is_regname_end (t[2]))
13761a11 1699 return 0;
2469cfa2 1700
791755f5 1701 if (strncasecmp (t, "sp", 2) == 0 && is_regname_end (t[2]))
b18c562e 1702 return 1;
2469cfa2 1703
791755f5 1704 if (strncasecmp (t, "sr", 2) == 0 && is_regname_end (t[2]))
13761a11
NC
1705 return 2;
1706
791755f5 1707 if (*t == '0' && is_regname_end (t[1]))
13761a11 1708 return 0;
2469cfa2 1709
791755f5 1710 val = strtol (t, & endt, 0);
13761a11
NC
1711
1712 if (val < 1 || val > 15)
1713 return -1;
1714
791755f5
NC
1715 if (is_regname_end (*endt))
1716 return val;
1717
1718 return -1;
13761a11 1719}
2469cfa2 1720
b18c562e
NC
1721static int
1722msp430_srcoperand (struct msp430_operand_s * op,
13761a11
NC
1723 char * l,
1724 int bin,
00b32ff2 1725 bfd_boolean * imm_op,
13761a11
NC
1726 bfd_boolean allow_20bit_values,
1727 bfd_boolean constants_allowed)
2469cfa2 1728{
2bfa0cdf 1729 char * end;
b18c562e 1730 char *__tl = l;
2469cfa2 1731
b18c562e
NC
1732 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
1733 if (*l == '#')
2469cfa2 1734 {
b18c562e
NC
1735 char *h = l;
1736 int vshift = -1;
1737 int rval = 0;
2469cfa2 1738
b18c562e
NC
1739 /* Check if there is:
1740 llo(x) - least significant 16 bits, x &= 0xffff
1741 lhi(x) - x = (x >> 16) & 0xffff,
1742 hlo(x) - x = (x >> 32) & 0xffff,
1743 hhi(x) - x = (x >> 48) & 0xffff
1744 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 1745
00b32ff2 1746 *imm_op = TRUE;
2469cfa2 1747
b18c562e
NC
1748 if (strncasecmp (h, "#llo(", 5) == 0)
1749 {
1750 vshift = 0;
1751 rval = 3;
1752 }
1753 else if (strncasecmp (h, "#lhi(", 5) == 0)
1754 {
1755 vshift = 1;
1756 rval = 3;
1757 }
1758 else if (strncasecmp (h, "#hlo(", 5) == 0)
1759 {
1760 vshift = 2;
1761 rval = 3;
1762 }
1763 else if (strncasecmp (h, "#hhi(", 5) == 0)
1764 {
1765 vshift = 3;
1766 rval = 3;
1767 }
1768 else if (strncasecmp (h, "#lo(", 4) == 0)
1769 {
1770 vshift = 0;
1771 rval = 2;
1772 }
1773 else if (strncasecmp (h, "#hi(", 4) == 0)
1774 {
1775 vshift = 1;
1776 rval = 2;
1777 }
2469cfa2 1778
b18c562e
NC
1779 op->reg = 0; /* Reg PC. */
1780 op->am = 3;
65d7bab5 1781 op->ol = 1; /* Immediate will follow an instruction. */
b18c562e
NC
1782 __tl = h + 1 + rval;
1783 op->mode = OP_EXP;
00b32ff2 1784 op->vshift = vshift;
2469cfa2 1785
2bfa0cdf
NC
1786 end = parse_exp (__tl, &(op->exp));
1787 if (end != NULL && *end != 0 && *end != ')' )
1788 {
1789 as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end, l);
1790 return 1;
1791 }
b18c562e 1792 if (op->exp.X_op == O_constant)
2469cfa2 1793 {
b18c562e 1794 int x = op->exp.X_add_number;
2469cfa2 1795
b18c562e 1796 if (vshift == 0)
2469cfa2 1797 {
b18c562e
NC
1798 x = x & 0xffff;
1799 op->exp.X_add_number = x;
1800 }
1801 else if (vshift == 1)
1802 {
1803 x = (x >> 16) & 0xffff;
1804 op->exp.X_add_number = x;
00b32ff2 1805 op->vshift = 0;
b18c562e
NC
1806 }
1807 else if (vshift > 1)
1808 {
1809 if (x < 0)
1810 op->exp.X_add_number = -1;
2469cfa2 1811 else
b18c562e
NC
1812 op->exp.X_add_number = 0; /* Nothing left. */
1813 x = op->exp.X_add_number;
00b32ff2 1814 op->vshift = 0;
2469cfa2 1815 }
2469cfa2 1816
13761a11
NC
1817 if (allow_20bit_values)
1818 {
99b4a5a0 1819 if (op->exp.X_add_number > 0xfffff || op->exp.X_add_number < -524288)
13761a11
NC
1820 {
1821 as_bad (_("value 0x%x out of extended range."), x);
1822 return 1;
1823 }
1824 }
1825 else if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
b18c562e
NC
1826 {
1827 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1828 return 1;
1829 }
2469cfa2 1830
b18c562e
NC
1831 /* Now check constants. */
1832 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 1833
13761a11
NC
1834 if (!allow_20bit_values)
1835 x = (short) x; /* Extend sign. */
2469cfa2 1836
13761a11
NC
1837 if (! constants_allowed)
1838 ;
1839 else if (x == 0)
2469cfa2 1840 {
b18c562e
NC
1841 op->reg = 3;
1842 op->am = 0;
1843 op->ol = 0;
1844 op->mode = OP_REG;
1845 }
1846 else if (x == 1)
1847 {
1848 op->reg = 3;
1849 op->am = 1;
1850 op->ol = 0;
1851 op->mode = OP_REG;
1852 }
1853 else if (x == 2)
1854 {
1855 op->reg = 3;
1856 op->am = 2;
1857 op->ol = 0;
1858 op->mode = OP_REG;
1859 }
1860 else if (x == -1)
1861 {
1862 op->reg = 3;
1863 op->am = 3;
1864 op->ol = 0;
1865 op->mode = OP_REG;
1866 }
1867 else if (x == 4)
1868 {
2213f746 1869 if (bin == 0x1200 && ! target_is_430x ())
b18c562e 1870 {
2213f746
NC
1871 /* CPU4: The shorter form of PUSH #4 is not supported on MSP430. */
1872 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1873 as_warn (_("cpu4: not converting PUSH #4 to shorter form"));
1874 /* No need to check silicon_errata_fixes - this fix is always implemented. */
b18c562e
NC
1875 }
1876 else
b18c562e
NC
1877 {
1878 op->reg = 2;
1879 op->am = 2;
1880 op->ol = 0;
1881 op->mode = OP_REG;
1882 }
1883 }
1884 else if (x == 8)
1885 {
2213f746 1886 if (bin == 0x1200 && ! target_is_430x ())
b18c562e 1887 {
2213f746
NC
1888 /* CPU4: The shorter form of PUSH #8 is not supported on MSP430. */
1889 if (silicon_errata_warn & SILICON_ERRATA_CPU4)
1890 as_warn (_("cpu4: not converting PUSH #8 to shorter form"));
b18c562e
NC
1891 }
1892 else
b18c562e
NC
1893 {
1894 op->reg = 2;
1895 op->am = 3;
1896 op->ol = 0;
1897 op->mode = OP_REG;
1898 }
2469cfa2 1899 }
2469cfa2 1900 }
b18c562e
NC
1901 else if (op->exp.X_op == O_symbol)
1902 {
00b32ff2
NC
1903 if (vshift > 1)
1904 as_bad (_("error: unsupported #foo() directive used on symbol"));
b18c562e
NC
1905 op->mode = OP_EXP;
1906 }
1907 else if (op->exp.X_op == O_big)
1908 {
1909 short x;
65d7bab5 1910
b18c562e
NC
1911 if (vshift != -1)
1912 {
1913 op->exp.X_op = O_constant;
1914 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1915 x = op->exp.X_add_number;
00b32ff2 1916 op->vshift = 0;
b18c562e
NC
1917 }
1918 else
1919 {
1920 as_bad (_
33eaf5de 1921 ("unknown expression in operand %s. Use #llo(), #lhi(), #hlo() or #hhi()"),
b18c562e
NC
1922 l);
1923 return 1;
1924 }
2469cfa2 1925
b18c562e
NC
1926 if (x == 0)
1927 {
1928 op->reg = 3;
1929 op->am = 0;
1930 op->ol = 0;
1931 op->mode = OP_REG;
1932 }
1933 else if (x == 1)
1934 {
1935 op->reg = 3;
1936 op->am = 1;
1937 op->ol = 0;
1938 op->mode = OP_REG;
1939 }
1940 else if (x == 2)
1941 {
1942 op->reg = 3;
1943 op->am = 2;
1944 op->ol = 0;
1945 op->mode = OP_REG;
1946 }
1947 else if (x == -1)
1948 {
1949 op->reg = 3;
1950 op->am = 3;
1951 op->ol = 0;
1952 op->mode = OP_REG;
1953 }
1954 else if (x == 4)
1955 {
1956 op->reg = 2;
1957 op->am = 2;
1958 op->ol = 0;
1959 op->mode = OP_REG;
1960 }
1961 else if (x == 8)
1962 {
1963 op->reg = 2;
1964 op->am = 3;
1965 op->ol = 0;
1966 op->mode = OP_REG;
1967 }
1968 }
79cf5950 1969 /* Redundant (yet) check. */
b18c562e
NC
1970 else if (op->exp.X_op == O_register)
1971 as_bad
1972 (_("Registers cannot be used within immediate expression [%s]"), l);
1973 else
1974 as_bad (_("unknown operand %s"), l);
2469cfa2 1975
b18c562e
NC
1976 return 0;
1977 }
2469cfa2 1978
b18c562e
NC
1979 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1980 if (*l == '&')
1981 {
1982 char *h = l;
2469cfa2 1983
b18c562e
NC
1984 op->reg = 2; /* reg 2 in absolute addr mode. */
1985 op->am = 1; /* mode As == 01 bin. */
1986 op->ol = 1; /* Immediate value followed by instruction. */
1987 __tl = h + 1;
2bfa0cdf
NC
1988 end = parse_exp (__tl, &(op->exp));
1989 if (end != NULL && *end != 0)
1990 {
1991 as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end, l);
1992 return 1;
1993 }
b18c562e 1994 op->mode = OP_EXP;
00b32ff2 1995 op->vshift = 0;
b18c562e 1996 if (op->exp.X_op == O_constant)
2469cfa2 1997 {
b18c562e 1998 int x = op->exp.X_add_number;
2469cfa2 1999
13761a11
NC
2000 if (allow_20bit_values)
2001 {
2002 if (x > 0xfffff || x < -(0x7ffff))
2003 {
2004 as_bad (_("value 0x%x out of extended range."), x);
2005 return 1;
2006 }
2007 }
2008 else if (x > 65535 || x < -32768)
b18c562e 2009 {
13761a11 2010 as_bad (_("value out of range: 0x%x"), x);
b18c562e
NC
2011 return 1;
2012 }
2469cfa2 2013 }
b18c562e
NC
2014 else if (op->exp.X_op == O_symbol)
2015 ;
2016 else
2469cfa2 2017 {
79cf5950 2018 /* Redundant (yet) check. */
b18c562e
NC
2019 if (op->exp.X_op == O_register)
2020 as_bad
2021 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 2022 else
b18c562e
NC
2023 as_bad (_("unknown expression in operand %s"), l);
2024 return 1;
2469cfa2 2025 }
b18c562e
NC
2026 return 0;
2027 }
2469cfa2 2028
b18c562e
NC
2029 /* Check if indirect register mode @Rn / postincrement @Rn+. */
2030 if (*l == '@')
2031 {
2032 char *t = l;
2033 char *m = strchr (l, '+');
2034
2035 if (t != l)
2469cfa2 2036 {
b18c562e
NC
2037 as_bad (_("unknown addressing mode %s"), l);
2038 return 1;
2469cfa2
NC
2039 }
2040
b18c562e 2041 t++;
2469cfa2 2042
13761a11 2043 if ((op->reg = check_reg (t)) == -1)
2469cfa2 2044 {
13761a11 2045 as_bad (_("Bad register name %s"), t);
b18c562e 2046 return 1;
2469cfa2 2047 }
2469cfa2 2048
b18c562e
NC
2049 op->mode = OP_REG;
2050 op->am = m ? 3 : 2;
2051 op->ol = 0;
2469cfa2 2052
d1706f38
NC
2053 /* PC cannot be used in indirect addressing. */
2054 if (target_is_430xv2 () && op->reg == 0)
2055 {
2056 as_bad (_("cannot use indirect addressing with the PC"));
2057 return 1;
2058 }
65d7bab5 2059
b18c562e
NC
2060 return 0;
2061 }
2469cfa2 2062
b18c562e
NC
2063 /* Check if register indexed X(Rn). */
2064 do
2065 {
2066 char *h = strrchr (l, '(');
2067 char *m = strrchr (l, ')');
2068 char *t;
2469cfa2 2069
00b32ff2 2070 *imm_op = TRUE;
2469cfa2 2071
b18c562e
NC
2072 if (!h)
2073 break;
2074 if (!m)
2075 {
2076 as_bad (_("')' required"));
2077 return 1;
2078 }
2469cfa2 2079
b18c562e
NC
2080 t = h;
2081 op->am = 1;
2082 op->ol = 1;
2469cfa2 2083
13761a11
NC
2084 /* Extract a register. */
2085 if ((op->reg = check_reg (t + 1)) == -1)
b18c562e
NC
2086 {
2087 as_bad (_
2088 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
2089 l);
2090 return 1;
2091 }
2469cfa2 2092
13761a11 2093 if (op->reg == 2)
b18c562e 2094 {
13761a11 2095 as_bad (_("r2 should not be used in indexed addressing mode"));
b18c562e
NC
2096 return 1;
2097 }
b18c562e
NC
2098
2099 /* Extract constant. */
2100 __tl = l;
2101 *h = 0;
2102 op->mode = OP_EXP;
00b32ff2 2103 op->vshift = 0;
2bfa0cdf
NC
2104 end = parse_exp (__tl, &(op->exp));
2105 if (end != NULL && *end != 0)
2106 {
2107 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
2108 return 1;
2109 }
b18c562e
NC
2110 if (op->exp.X_op == O_constant)
2111 {
2112 int x = op->exp.X_add_number;
2113
13761a11
NC
2114 if (allow_20bit_values)
2115 {
2116 if (x > 0xfffff || x < - (0x7ffff))
2117 {
2118 as_bad (_("value 0x%x out of extended range."), x);
2119 return 1;
2120 }
2121 }
2122 else if (x > 65535 || x < -32768)
2469cfa2 2123 {
13761a11 2124 as_bad (_("value out of range: 0x%x"), x);
b18c562e 2125 return 1;
2469cfa2 2126 }
b18c562e
NC
2127
2128 if (x == 0)
2469cfa2 2129 {
b18c562e
NC
2130 op->mode = OP_REG;
2131 op->am = 2;
2132 op->ol = 0;
2133 return 0;
2469cfa2 2134 }
2213f746
NC
2135
2136 if (op->reg == 1 && (x & 1))
2137 {
2138 if (silicon_errata_fix & SILICON_ERRATA_CPU8)
2139 as_bad (_("CPU8: Stack pointer accessed with an odd offset"));
2140 else if (silicon_errata_warn & SILICON_ERRATA_CPU8)
2141 as_warn (_("CPU8: Stack pointer accessed with an odd offset"));
2142 }
2469cfa2 2143 }
b18c562e
NC
2144 else if (op->exp.X_op == O_symbol)
2145 ;
2469cfa2
NC
2146 else
2147 {
79cf5950 2148 /* Redundant (yet) check. */
b18c562e
NC
2149 if (op->exp.X_op == O_register)
2150 as_bad
2151 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
2152 else
2153 as_bad (_("unknown expression in operand %s"), l);
2154 return 1;
2469cfa2 2155 }
2469cfa2 2156
b18c562e 2157 return 0;
2469cfa2 2158 }
b18c562e 2159 while (0);
2469cfa2 2160
13761a11
NC
2161 /* Possibly register mode 'mov r1,r2'. */
2162 if ((op->reg = check_reg (l)) != -1)
b18c562e 2163 {
13761a11
NC
2164 op->mode = OP_REG;
2165 op->am = 0;
2166 op->ol = 0;
2167 return 0;
b18c562e 2168 }
b18c562e
NC
2169
2170 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
2bfa0cdf
NC
2171 op->mode = OP_EXP;
2172 op->reg = 0; /* PC relative... be careful. */
2173 /* An expression starting with a minus sign is a constant, not an address. */
2174 op->am = (*l == '-' ? 3 : 1);
2175 op->ol = 1;
2176 op->vshift = 0;
2177 __tl = l;
2178 end = parse_exp (__tl, &(op->exp));
2179 if (end != NULL && * end != 0)
b18c562e 2180 {
2bfa0cdf
NC
2181 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l);
2182 return 1;
b18c562e 2183 }
2bfa0cdf 2184 return 0;
2469cfa2
NC
2185}
2186
b18c562e 2187
2469cfa2 2188static int
13761a11
NC
2189msp430_dstoperand (struct msp430_operand_s * op,
2190 char * l,
2191 int bin,
2192 bfd_boolean allow_20bit_values,
2193 bfd_boolean constants_allowed)
2469cfa2
NC
2194{
2195 int dummy;
13761a11
NC
2196 int ret = msp430_srcoperand (op, l, bin, & dummy,
2197 allow_20bit_values,
2198 constants_allowed);
b18c562e 2199
2469cfa2
NC
2200 if (ret)
2201 return ret;
2202
2203 if (op->am == 2)
2204 {
47990a6a 2205 char *__tl = (char *) "0";
2469cfa2
NC
2206
2207 op->mode = OP_EXP;
2208 op->am = 1;
2209 op->ol = 1;
00b32ff2 2210 op->vshift = 0;
2bfa0cdf 2211 (void) parse_exp (__tl, &(op->exp));
b18c562e 2212
2469cfa2
NC
2213 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
2214 {
2215 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
2216 op->reg, op->reg);
2217 return 1;
2218 }
2219 return 0;
2220 }
2221
2222 if (op->am > 1)
2223 {
2224 as_bad (_
2225 ("this addressing mode is not applicable for destination operand"));
2226 return 1;
2227 }
2228 return 0;
2229}
2230
13761a11
NC
2231/* Attempt to encode a MOVA instruction with the given operands.
2232 Returns the length of the encoded instruction if successful
2233 or 0 upon failure. If the encoding fails, an error message
2234 will be returned if a pointer is provided. */
2235
2236static int
2237try_encode_mova (bfd_boolean imm_op,
2238 int bin,
2239 struct msp430_operand_s * op1,
2240 struct msp430_operand_s * op2,
2241 const char ** error_message_return)
2242{
2243 short ZEROS = 0;
2244 char *frag;
2245 int where;
2246
2247 /* Only a restricted subset of the normal MSP430 addressing modes
2248 are supported here, so check for the ones that are allowed. */
2249 if (imm_op)
2250 {
2251 if (op1->mode == OP_EXP)
2252 {
2253 if (op2->mode != OP_REG)
2254 {
2255 if (error_message_return != NULL)
2256 * error_message_return = _("expected register as second argument of %s");
2257 return 0;
2258 }
2259
2260 if (op1->am == 3)
2261 {
2262 /* MOVA #imm20, Rdst. */
2263 bin |= 0x80 | op2->reg;
2264 frag = frag_more (4);
2265 where = frag - frag_now->fr_literal;
2266 if (op1->exp.X_op == O_constant)
2267 {
2268 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2269 bfd_putl16 ((bfd_vma) bin, frag);
2270 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2271 }
2272 else
2273 {
2274 bfd_putl16 ((bfd_vma) bin, frag);
2275 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2276 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2277 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2278 }
2279
2280 return 4;
2281 }
2282 else if (op1->am == 1)
2283 {
2284 /* MOVA z16(Rsrc), Rdst. */
2285 bin |= 0x30 | (op1->reg << 8) | op2->reg;
2286 frag = frag_more (4);
2287 where = frag - frag_now->fr_literal;
2288 bfd_putl16 ((bfd_vma) bin, frag);
2289 if (op1->exp.X_op == O_constant)
2290 {
2291 if (op1->exp.X_add_number > 0xffff
2292 || op1->exp.X_add_number < -(0x7fff))
2293 {
2294 if (error_message_return != NULL)
2295 * error_message_return = _("index value too big for %s");
2296 return 0;
2297 }
2298 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2299 }
2300 else
2301 {
2302 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2303 fix_new_exp (frag_now, where + 2, 2, &(op1->exp), FALSE,
2304 op1->reg == 0 ?
2305 BFD_RELOC_MSP430X_PCR16 :
2306 BFD_RELOC_MSP430X_ABS16);
2307 }
2308 return 4;
2309 }
2310
2311 if (error_message_return != NULL)
2312 * error_message_return = _("unexpected addressing mode for %s");
2313 return 0;
2314 }
2315 else if (op1->am == 0)
2316 {
2317 /* MOVA Rsrc, ... */
2318 if (op2->mode == OP_REG)
2319 {
2320 bin |= 0xc0 | (op1->reg << 8) | op2->reg;
2321 frag = frag_more (2);
2322 where = frag - frag_now->fr_literal;
2323 bfd_putl16 ((bfd_vma) bin, frag);
2324 return 2;
2325 }
2326 else if (op2->am == 1)
2327 {
2328 if (op2->reg == 2)
2329 {
2330 /* MOVA Rsrc, &abs20. */
2331 bin |= 0x60 | (op1->reg << 8);
2332 frag = frag_more (4);
2333 where = frag - frag_now->fr_literal;
2334 if (op2->exp.X_op == O_constant)
2335 {
2336 bin |= (op2->exp.X_add_number >> 16) & 0xf;
2337 bfd_putl16 ((bfd_vma) bin, frag);
2338 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2339 }
2340 else
2341 {
2342 bfd_putl16 ((bfd_vma) bin, frag);
2343 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2344 fix_new_exp (frag_now, where, 4, &(op2->exp), FALSE,
2345 BFD_RELOC_MSP430X_ABS20_ADR_DST);
2346 }
2347 return 4;
2348 }
2349
2350 /* MOVA Rsrc, z16(Rdst). */
2351 bin |= 0x70 | (op1->reg << 8) | op2->reg;
2352 frag = frag_more (4);
2353 where = frag - frag_now->fr_literal;
2354 bfd_putl16 ((bfd_vma) bin, frag);
2355 if (op2->exp.X_op == O_constant)
2356 {
2357 if (op2->exp.X_add_number > 0xffff
2358 || op2->exp.X_add_number < -(0x7fff))
2359 {
2360 if (error_message_return != NULL)
2361 * error_message_return = _("index value too big for %s");
2362 return 0;
2363 }
2364 bfd_putl16 (op2->exp.X_add_number & 0xffff, frag + 2);
2365 }
2366 else
2367 {
2368 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2369 fix_new_exp (frag_now, where + 2, 2, &(op2->exp), FALSE,
2370 op2->reg == 0 ?
2371 BFD_RELOC_MSP430X_PCR16 :
2372 BFD_RELOC_MSP430X_ABS16);
2373 }
2374 return 4;
2375 }
2376
2377 if (error_message_return != NULL)
2378 * error_message_return = _("unexpected addressing mode for %s");
2379 return 0;
2380 }
2381 }
2382
2383 /* imm_op == FALSE. */
2384
2385 if (op1->reg == 2 && op1->am == 1 && op1->mode == OP_EXP)
2386 {
2387 /* MOVA &abs20, Rdst. */
2388 if (op2->mode != OP_REG)
2389 {
2390 if (error_message_return != NULL)
2391 * error_message_return = _("expected register as second argument of %s");
2392 return 0;
2393 }
2394
2395 if (op2->reg == 2 || op2->reg == 3)
2396 {
2397 if (error_message_return != NULL)
2398 * error_message_return = _("constant generator destination register found in %s");
2399 return 0;
2400 }
2401
2402 bin |= 0x20 | op2->reg;
2403 frag = frag_more (4);
2404 where = frag - frag_now->fr_literal;
2405 if (op1->exp.X_op == O_constant)
2406 {
2407 bin |= ((op1->exp.X_add_number >> 16) & 0xf) << 8;
2408 bfd_putl16 ((bfd_vma) bin, frag);
2409 bfd_putl16 (op1->exp.X_add_number & 0xffff, frag + 2);
2410 }
2411 else
2412 {
2413 bfd_putl16 ((bfd_vma) bin, frag);
2414 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2415 fix_new_exp (frag_now, where, 4, &(op1->exp), FALSE,
2416 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
2417 }
2418 return 4;
2419 }
2420 else if (op1->mode == OP_REG)
2421 {
2422 if (op1->am == 3)
2423 {
2424 /* MOVA @Rsrc+, Rdst. */
2425 if (op2->mode != OP_REG)
2426 {
2427 if (error_message_return != NULL)
2428 * error_message_return = _("expected register as second argument of %s");
2429 return 0;
2430 }
2431
2432 if (op2->reg == 2 || op2->reg == 3)
2433 {
2434 if (error_message_return != NULL)
2435 * error_message_return = _("constant generator destination register found in %s");
2436 return 0;
2437 }
2438
2439 if (op1->reg == 2 || op1->reg == 3)
2440 {
2441 if (error_message_return != NULL)
2442 * error_message_return = _("constant generator source register found in %s");
2443 return 0;
2444 }
2445
2446 bin |= 0x10 | (op1->reg << 8) | op2->reg;
2447 frag = frag_more (2);
2448 where = frag - frag_now->fr_literal;
2449 bfd_putl16 ((bfd_vma) bin, frag);
2450 return 2;
2451 }
2452 else if (op1->am == 2)
2453 {
2454 /* MOVA @Rsrc,Rdst */
2455 if (op2->mode != OP_REG)
2456 {
2457 if (error_message_return != NULL)
2458 * error_message_return = _("expected register as second argument of %s");
2459 return 0;
2460 }
2461
2462 if (op2->reg == 2 || op2->reg == 3)
2463 {
2464 if (error_message_return != NULL)
2465 * error_message_return = _("constant generator destination register found in %s");
2466 return 0;
2467 }
2468
2469 if (op1->reg == 2 || op1->reg == 3)
2470 {
2471 if (error_message_return != NULL)
2472 * error_message_return = _("constant generator source register found in %s");
2473 return 0;
2474 }
2475
2476 bin |= (op1->reg << 8) | op2->reg;
2477 frag = frag_more (2);
2478 where = frag - frag_now->fr_literal;
2479 bfd_putl16 ((bfd_vma) bin, frag);
2480 return 2;
2481 }
2482 }
2483
2484 if (error_message_return != NULL)
2485 * error_message_return = _("unexpected addressing mode for %s");
2486
2487 return 0;
2488}
2489
2213f746
NC
2490#define NOP_CHECK_INTERRUPT (1 << 0)
2491#define NOP_CHECK_CPU12 (1 << 1)
2492#define NOP_CHECK_CPU19 (1 << 2)
2493
2494static signed int check_for_nop = 0;
65d7bab5 2495
638d3803
NC
2496#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
2497
b18c562e
NC
2498/* Parse instruction operands.
2499 Return binary opcode. */
2500
2501static unsigned int
2502msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 2503{
b18c562e 2504 int bin = opcode->bin_opcode; /* Opcode mask. */
13761a11 2505 int insn_length = 0;
b18c562e
NC
2506 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2507 char *frag;
2bfa0cdf 2508 char *end;
b18c562e
NC
2509 int where;
2510 struct msp430_operand_s op1, op2;
2511 int res = 0;
2512 static short ZEROS = 0;
00b32ff2 2513 bfd_boolean byte_op, imm_op;
13761a11
NC
2514 int op_length = 0;
2515 int fmt;
2516 int extended = 0x1800;
2517 bfd_boolean extended_op = FALSE;
2518 bfd_boolean addr_op;
2519 const char * error_message;
2520 static signed int repeat_count = 0;
927f2d25 2521 static bfd_boolean prev_insn_is_nop = FALSE;
13761a11 2522 bfd_boolean fix_emitted;
2469cfa2 2523
b18c562e
NC
2524 /* Opcode is the one from opcodes table
2525 line contains something like
2526 [.w] @r2+, 5(R1)
2527 or
2528 .b @r2+, 5(R1). */
2469cfa2 2529
00b32ff2 2530 byte_op = FALSE;
38d77545
NC
2531 addr_op = FALSE;
2532 if (*line == '.')
2469cfa2 2533 {
38d77545
NC
2534 bfd_boolean check = FALSE;
2535 ++ line;
2536
2537 switch (TOLOWER (* line))
2538 {
2539 case 'b':
2540 /* Byte operation. */
2541 bin |= BYTE_OPERATION;
00b32ff2 2542 byte_op = TRUE;
38d77545
NC
2543 check = TRUE;
2544 break;
2545
2546 case 'a':
2547 /* "Address" ops work on 20-bit values. */
2548 addr_op = TRUE;
2549 bin |= BYTE_OPERATION;
2550 check = TRUE;
2551 break;
2552
2553 case 'w':
2554 /* Word operation - this is the default. */
2555 check = TRUE;
2556 break;
2557
2558 case 0:
2559 case ' ':
2560 case '\n':
2561 case '\r':
2562 as_warn (_("no size modifier after period, .w assumed"));
2563 break;
2564
2565 default:
2566 as_bad (_("unrecognised instruction size modifier .%c"),
2567 * line);
2568 return 0;
2569 }
2570
2571 if (check)
2572 {
2573 ++ line;
2574
2575 }
2469cfa2
NC
2576 }
2577
38d77545 2578 if (*line && ! ISSPACE (*line))
13761a11 2579 {
38d77545
NC
2580 as_bad (_("junk found after instruction: %s.%s"),
2581 opcode->name, line);
2582 return 0;
13761a11 2583 }
13761a11 2584
38d77545
NC
2585 /* Catch the case where the programmer has used a ".a" size modifier on an
2586 instruction that does not support it. Look for an alternative extended
2587 instruction that has the same name without the period. Eg: "add.a"
2588 becomes "adda". Although this not an officially supported way of
33eaf5de 2589 specifying instruction aliases other MSP430 assemblers allow it. So we
38d77545
NC
2590 support it for compatibility purposes. */
2591 if (addr_op && opcode->fmt >= 0)
2592 {
f86f5863 2593 const char * old_name = opcode->name;
38d77545
NC
2594 char real_name[32];
2595
2596 sprintf (real_name, "%sa", old_name);
2597 opcode = hash_find (msp430_hash, real_name);
2598 if (opcode == NULL)
2599 {
2600 as_bad (_("instruction %s.a does not exist"), old_name);
2601 return 0;
2602 }
2603#if 0 /* Enable for debugging. */
2604 as_warn ("treating %s.a as %s", old_name, real_name);
2605#endif
2606 addr_op = FALSE;
2607 bin = opcode->bin_opcode;
2608 }
2469cfa2 2609
13761a11
NC
2610 if (opcode->fmt != -1
2611 && opcode->insn_opnumb
2612 && (!*line || *line == '\n'))
2469cfa2 2613 {
992a06ee
AM
2614 as_bad (ngettext ("instruction %s requires %d operand",
2615 "instruction %s requires %d operands",
2616 opcode->insn_opnumb),
b18c562e
NC
2617 opcode->name, opcode->insn_opnumb);
2618 return 0;
2619 }
2469cfa2 2620
b18c562e
NC
2621 memset (l1, 0, sizeof (l1));
2622 memset (l2, 0, sizeof (l2));
2623 memset (&op1, 0, sizeof (op1));
2624 memset (&op2, 0, sizeof (op2));
2469cfa2 2625
00b32ff2 2626 imm_op = FALSE;
2469cfa2 2627
13761a11
NC
2628 if ((fmt = opcode->fmt) < 0)
2629 {
638d3803 2630 if (! target_is_430x ())
13761a11
NC
2631 {
2632 as_bad (_("instruction %s requires MSP430X mcu"),
2633 opcode->name);
2634 return 0;
2635 }
3739860c 2636
13761a11
NC
2637 fmt = (-fmt) - 1;
2638 extended_op = TRUE;
2639 }
2640
2641 if (repeat_count)
2642 {
2643 /* If requested set the extended instruction repeat count. */
2644 if (extended_op)
2645 {
2646 if (repeat_count > 0)
2647 extended |= (repeat_count - 1);
2648 else
2649 extended |= (1 << 7) | (- repeat_count);
2650 }
2651 else
2652 as_bad (_("unable to repeat %s insn"), opcode->name);
2653
2654 repeat_count = 0;
2655 }
2656
2213f746 2657 if (check_for_nop)
b18c562e 2658 {
2213f746 2659 if (! is_opcode ("nop"))
2469cfa2 2660 {
2213f746
NC
2661 bfd_boolean doit = FALSE;
2662
2663 do
65d7bab5 2664 {
2213f746 2665 switch (check_for_nop & - check_for_nop)
65d7bab5 2666 {
2213f746 2667 case NOP_CHECK_INTERRUPT:
ff1fe6fa 2668 if (warn_interrupt_nops)
65d7bab5
NC
2669 {
2670 if (gen_interrupt_nops)
2671 as_warn (_("NOP inserted between two instructions that change interrupt state"));
2672 else
2673 as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
2674 }
2675
ff1fe6fa 2676 if (gen_interrupt_nops)
2213f746
NC
2677 /* Emit a NOP between interrupt enable/disable.
2678 See 1.3.4.1 of the MSP430x5xx User Guide. */
2679 doit = TRUE;
2680 break;
2681
2682 case NOP_CHECK_CPU12:
2683 if (silicon_errata_warn & SILICON_ERRATA_CPU12)
de194d85 2684 as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction"));
2213f746
NC
2685
2686 if (silicon_errata_fix & SILICON_ERRATA_CPU12)
2687 doit = TRUE;
2688 break;
2689
2690 case NOP_CHECK_CPU19:
2691 if (silicon_errata_warn & SILICON_ERRATA_CPU19)
2692 as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP"));
65d7bab5 2693
2213f746
NC
2694 if (silicon_errata_fix & SILICON_ERRATA_CPU19)
2695 doit = TRUE;
2696 break;
2697
2698 default:
2699 as_bad (_("internal error: unknown nop check state"));
2700 break;
2701 }
2702 check_for_nop &= ~ (check_for_nop & - check_for_nop);
2703 }
2704 while (check_for_nop);
2705
2706 if (doit)
2707 {
2708 frag = frag_more (2);
2709 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2710 dwarf2_emit_insn (2);
65d7bab5 2711 }
2213f746
NC
2712 }
2713
2714 check_for_nop = 0;
2715 }
2716
2717 switch (fmt)
2718 {
2719 case 0: /* Emulated. */
2720 switch (opcode->insn_opnumb)
2721 {
2722 case 0:
927f2d25
NC
2723 if (is_opcode ("eint"))
2724 {
2725 if (! prev_insn_is_nop)
2726 {
2727 if (gen_interrupt_nops)
2728 {
2729 frag = frag_more (2);
2730 bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
2731 dwarf2_emit_insn (2);
2732
2733 if (warn_interrupt_nops)
2734 as_warn (_("inserting a NOP before EINT"));
2735 }
2736 else if (warn_interrupt_nops)
2737 as_warn (_("a NOP might be needed before the EINT"));
2738 }
2739 }
2740 else if (is_opcode ("dint"))
2213f746 2741 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5 2742
b18c562e 2743 /* Set/clear bits instructions. */
13761a11
NC
2744 if (extended_op)
2745 {
2746 if (!addr_op)
2747 extended |= BYTE_OPERATION;
2748
2749 /* Emit the extension word. */
2750 insn_length += 2;
65d7bab5 2751 frag = frag_more (2);
13761a11
NC
2752 bfd_putl16 (extended, frag);
2753 }
638d3803 2754
13761a11 2755 insn_length += 2;
65d7bab5 2756 frag = frag_more (2);
b18c562e 2757 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 2758 dwarf2_emit_insn (insn_length);
b18c562e 2759 break;
13761a11 2760
b18c562e
NC
2761 case 1:
2762 /* Something which works with destination operand. */
2763 line = extract_operand (line, l1, sizeof (l1));
13761a11 2764 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode, extended_op, TRUE);
b18c562e
NC
2765 if (res)
2766 break;
2469cfa2 2767
65d7bab5
NC
2768 bin |= (op1.reg | (op1.am << 7));
2769
2213f746
NC
2770 /* If the PC is the destination... */
2771 if (op1.am == 0 && op1.reg == 0
2772 /* ... and the opcode alters the SR. */
2773 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
2774 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
65d7bab5 2775 {
2213f746 2776 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
de194d85 2777 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2213f746 2778 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
de194d85 2779 as_warn (_("CPU11: PC is destination of SR altering instruction"));
65d7bab5 2780 }
2213f746
NC
2781
2782 /* If the status register is the destination... */
2783 if (op1.am == 0 && op1.reg == 2
2784 /* ... and the opcode alters the SR. */
2785 && (is_opcode ("adc") || is_opcode ("dec") || is_opcode ("decd")
2786 || is_opcode ("inc") || is_opcode ("incd") || is_opcode ("inv")
2787 || is_opcode ("sbc") || is_opcode ("sxt")
2788 || is_opcode ("adcx") || is_opcode ("decx") || is_opcode ("decdx")
2789 || is_opcode ("incx") || is_opcode ("incdx") || is_opcode ("invx")
2790 || is_opcode ("sbcx")
2791 ))
2792 {
2793 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
de194d85 2794 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2213f746 2795 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
de194d85 2796 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2213f746
NC
2797 }
2798
2799 if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
2800 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5 2801
13761a11 2802 /* Compute the entire instruction length, in bytes. */
65d7bab5
NC
2803 op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
2804 insn_length += op_length;
2805 frag = frag_more (op_length);
b18c562e 2806 where = frag - frag_now->fr_literal;
38d77545 2807
13761a11 2808 if (extended_op)
2469cfa2 2809 {
13761a11
NC
2810 if (!addr_op)
2811 extended |= BYTE_OPERATION;
2812
2813 if (op1.ol != 0 && ((extended & 0xf) != 0))
2814 {
2815 as_bad (_("repeat instruction used with non-register mode instruction"));
2816 extended &= ~ 0xf;
2817 }
38d77545 2818
13761a11
NC
2819 if (op1.mode == OP_EXP)
2820 {
2821 if (op1.exp.X_op == O_constant)
2822 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2823
e66c3c25 2824 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
2825 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2826 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2827 else
2828 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2829 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2830 }
38d77545 2831
13761a11
NC
2832 /* Emit the extension word. */
2833 bfd_putl16 (extended, frag);
2834 frag += 2;
2835 where += 2;
2836 }
2837
13761a11
NC
2838 bfd_putl16 ((bfd_vma) bin, frag);
2839 frag += 2;
2840 where += 2;
2841
2842 if (op1.mode == OP_EXP)
2843 {
2844 if (op1.exp.X_op == O_constant)
2845 {
2846 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2847 }
2469cfa2 2848 else
13761a11
NC
2849 {
2850 bfd_putl16 ((bfd_vma) ZEROS, frag);
2851
2852 if (!extended_op)
2853 {
2854 if (op1.reg)
2855 fix_new_exp (frag_now, where, 2,
00b32ff2 2856 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
2857 else
2858 fix_new_exp (frag_now, where, 2,
2859 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2860 }
2861 }
2862 }
2863
13761a11 2864 dwarf2_emit_insn (insn_length);
b18c562e 2865 break;
2469cfa2 2866
b18c562e 2867 case 2:
13761a11
NC
2868 /* Shift instruction. */
2869 line = extract_operand (line, l1, sizeof (l1));
2870 strncpy (l2, l1, sizeof (l2));
2871 l2[sizeof (l2) - 1] = '\0';
2872 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
2873 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2874
2875 if (res)
2876 break; /* An error occurred. All warnings were done before. */
2877
2878 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2) + (op2.ol * 2);
2879 frag = frag_more (insn_length);
2880 where = frag - frag_now->fr_literal;
2881
d1706f38
NC
2882 if (target_is_430xv2 ()
2883 && op1.mode == OP_REG
38d77545 2884 && op1.reg == 0
638d3803
NC
2885 && (is_opcode ("rlax")
2886 || is_opcode ("rlcx")
2887 || is_opcode ("rla")
2888 || is_opcode ("rlc")))
2889 {
2890 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 2891 break;
638d3803 2892 }
38d77545 2893
2213f746
NC
2894 /* If the status register is the destination... */
2895 if (op1.am == 0 && op1.reg == 2
2896 /* ... and the opcode alters the SR. */
2897 && (is_opcode ("rla") || is_opcode ("rlc")
2898 || is_opcode ("rlax") || is_opcode ("rlcx")
2899 ))
2900 {
2901 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
de194d85 2902 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2213f746 2903 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
de194d85 2904 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2213f746
NC
2905 }
2906
13761a11
NC
2907 if (extended_op)
2908 {
2909 if (!addr_op)
2910 extended |= BYTE_OPERATION;
2911
2912 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
2913 {
2914 as_bad (_("repeat instruction used with non-register mode instruction"));
2915 extended &= ~ 0xf;
2916 }
38d77545 2917
13761a11
NC
2918 if (op1.mode == OP_EXP)
2919 {
2920 if (op1.exp.X_op == O_constant)
2921 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
2922
e66c3c25 2923 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
2924 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2925 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
2926 else
2927 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
2928 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
2929 }
2930
2931 if (op2.mode == OP_EXP)
2932 {
2933 if (op2.exp.X_op == O_constant)
2934 extended |= (op2.exp.X_add_number >> 16) & 0xf;
2935
2936 else if (op1.mode == OP_EXP)
2937 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
2938 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
2939 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
2940 else
2941 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
2942 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
2943 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
2944 }
2945
2946 /* Emit the extension word. */
2947 bfd_putl16 (extended, frag);
2948 frag += 2;
2949 where += 2;
2950 }
2951
2952 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2953 bfd_putl16 ((bfd_vma) bin, frag);
2954 frag += 2;
2955 where += 2;
2956
2957 if (op1.mode == OP_EXP)
2958 {
2959 if (op1.exp.X_op == O_constant)
2960 {
2961 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
2962 }
2963 else
2964 {
2965 bfd_putl16 ((bfd_vma) ZEROS, frag);
2966
2967 if (!extended_op)
2968 {
e66c3c25 2969 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 2970 fix_new_exp (frag_now, where, 2,
00b32ff2 2971 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
2972 else
2973 fix_new_exp (frag_now, where, 2,
2974 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2975 }
2976 }
2977 frag += 2;
2978 where += 2;
2979 }
2980
2981 if (op2.mode == OP_EXP)
2982 {
2983 if (op2.exp.X_op == O_constant)
2984 {
2985 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
2986 }
2987 else
2988 {
2989 bfd_putl16 ((bfd_vma) ZEROS, frag);
2990
2991 if (!extended_op)
2992 {
2993 if (op2.reg) /* Not PC relative. */
2994 fix_new_exp (frag_now, where, 2,
00b32ff2 2995 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
13761a11
NC
2996 else
2997 fix_new_exp (frag_now, where, 2,
2998 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2999 }
3000 }
3001 }
3002
3003 dwarf2_emit_insn (insn_length);
3004 break;
3005
3006 case 3:
3007 /* Branch instruction => mov dst, r0. */
3008 if (extended_op)
3009 {
3010 as_bad ("Internal error: state 0/3 not coded for extended instructions");
65d7bab5 3011 break;
13761a11
NC
3012 }
3013
3014 line = extract_operand (line, l1, sizeof (l1));
3015 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, FALSE);
3016 if (res)
3017 break;
3018
00b32ff2
NC
3019 byte_op = FALSE;
3020 imm_op = FALSE;
13761a11
NC
3021 bin |= ((op1.reg << 8) | (op1.am << 4));
3022 op_length = 2 + 2 * op1.ol;
3023 frag = frag_more (op_length);
3024 where = frag - frag_now->fr_literal;
3025 bfd_putl16 ((bfd_vma) bin, frag);
3026
3027 if (op1.mode == OP_EXP)
3028 {
3029 if (op1.exp.X_op == O_constant)
3030 {
3031 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag + 2);
3032 }
3033 else
3034 {
3035 where += 2;
38d77545 3036
13761a11
NC
3037 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3038
e66c3c25 3039 if (op1.reg || op1.am == 3)
13761a11 3040 fix_new_exp (frag_now, where, 2,
00b32ff2 3041 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
3042 else
3043 fix_new_exp (frag_now, where, 2,
3044 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3045 }
3046 }
3047
3048 dwarf2_emit_insn (insn_length + op_length);
3049 break;
3050
3051 case 4:
3052 /* CALLA instructions. */
3053 fix_emitted = FALSE;
3054
3055 line = extract_operand (line, l1, sizeof (l1));
00b32ff2 3056 imm_op = FALSE;
13761a11
NC
3057
3058 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op,
3059 extended_op, FALSE);
3060 if (res)
3061 break;
3062
00b32ff2 3063 byte_op = FALSE;
13761a11
NC
3064
3065 op_length = 2 + 2 * op1.ol;
3066 frag = frag_more (op_length);
3067 where = frag - frag_now->fr_literal;
3068
3069 if (imm_op)
3070 {
3071 if (op1.am == 3)
3072 {
3073 bin |= 0xb0;
3074
3075 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3076 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3077 fix_emitted = TRUE;
3078 }
3079 else if (op1.am == 1)
3080 {
3081 if (op1.reg == 0)
3082 {
3083 bin |= 0x90;
3084
3085 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3086 BFD_RELOC_MSP430X_PCR20_CALL);
3087 fix_emitted = TRUE;
3088 }
3089 else
3090 bin |= 0x50 | op1.reg;
3091 }
3092 else if (op1.am == 0)
3093 bin |= 0x40 | op1.reg;
3094 }
3095 else if (op1.am == 1)
3096 {
3097 bin |= 0x80;
3098
3099 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3100 BFD_RELOC_MSP430X_ABS20_ADR_DST);
3101 fix_emitted = TRUE;
3102 }
3103 else if (op1.am == 2)
3104 bin |= 0x60 | op1.reg;
3105 else if (op1.am == 3)
3106 bin |= 0x70 | op1.reg;
38d77545 3107
13761a11
NC
3108 bfd_putl16 ((bfd_vma) bin, frag);
3109
3110 if (op1.mode == OP_EXP)
3111 {
3112 if (op1.ol != 1)
3113 {
3114 as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
65d7bab5 3115 break;
13761a11
NC
3116 }
3117
3118 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3119
3120 if (! fix_emitted)
3121 fix_new_exp (frag_now, where + 2, 2,
3122 &(op1.exp), FALSE, BFD_RELOC_16);
3123 }
3124
3125 dwarf2_emit_insn (insn_length + op_length);
3126 break;
3127
3128 case 5:
b18c562e 3129 {
13761a11
NC
3130 int n;
3131 int reg;
3132
3133 /* [POP|PUSH]M[.A] #N, Rd */
b18c562e 3134 line = extract_operand (line, l1, sizeof (l1));
13761a11 3135 line = extract_operand (line, l2, sizeof (l2));
2469cfa2 3136
13761a11
NC
3137 if (*l1 != '#')
3138 {
638d3803 3139 as_bad (_("expected #n as first argument of %s"), opcode->name);
65d7bab5 3140 break;
13761a11 3141 }
2bfa0cdf
NC
3142 end = parse_exp (l1 + 1, &(op1.exp));
3143 if (end != NULL && *end != 0)
3144 {
3145 as_bad (_("extra characters '%s' at end of constant expression '%s'"), end, l1);
3146 break;
3147 }
13761a11
NC
3148 if (op1.exp.X_op != O_constant)
3149 {
33eaf5de 3150 as_bad (_("expected constant expression as first argument of %s"),
13761a11 3151 opcode->name);
65d7bab5 3152 break;
13761a11 3153 }
2469cfa2 3154
13761a11
NC
3155 if ((reg = check_reg (l2)) == -1)
3156 {
3157 as_bad (_("expected register as second argument of %s"),
3158 opcode->name);
65d7bab5 3159 break;
13761a11 3160 }
2469cfa2 3161
13761a11
NC
3162 op_length = 2;
3163 frag = frag_more (op_length);
b18c562e 3164 where = frag - frag_now->fr_literal;
13761a11
NC
3165 bin = opcode->bin_opcode;
3166 if (! addr_op)
3167 bin |= 0x100;
3168 n = op1.exp.X_add_number;
3169 bin |= (n - 1) << 4;
638d3803 3170 if (is_opcode ("pushm"))
13761a11
NC
3171 bin |= reg;
3172 else
3173 {
3174 if (reg - n + 1 < 0)
3175 {
3176 as_bad (_("Too many registers popped"));
65d7bab5 3177 break;
13761a11 3178 }
638d3803 3179
65d7bab5 3180 /* CPU21 errata: cannot use POPM to restore the SR register. */
d1706f38 3181 if (target_is_430xv2 ()
638d3803
NC
3182 && (reg - n + 1 < 3)
3183 && reg >= 2
3184 && is_opcode ("popm"))
3185 {
3186 as_bad (_("Cannot use POPM to restore the SR register"));
65d7bab5 3187 break;
638d3803
NC
3188 }
3189
13761a11
NC
3190 bin |= (reg - n + 1);
3191 }
3192
b18c562e 3193 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3194 dwarf2_emit_insn (op_length);
3195 break;
3196 }
3197
3198 case 6:
3199 {
3200 int n;
3201 int reg;
3202
3203 /* Bit rotation instructions. RRCM, RRAM, RRUM, RLAM. */
3204 if (extended & 0xff)
3205 {
3206 as_bad (_("repeat count cannot be used with %s"), opcode->name);
65d7bab5 3207 break;
13761a11
NC
3208 }
3209
3210 line = extract_operand (line, l1, sizeof (l1));
3211 line = extract_operand (line, l2, sizeof (l2));
3212
3213 if (*l1 != '#')
3214 {
3215 as_bad (_("expected #n as first argument of %s"), opcode->name);
65d7bab5 3216 break;
13761a11 3217 }
2bfa0cdf
NC
3218 end = parse_exp (l1 + 1, &(op1.exp));
3219 if (end != NULL && *end != 0)
3220 {
3221 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3222 break;
3223 }
13761a11
NC
3224 if (op1.exp.X_op != O_constant)
3225 {
33eaf5de 3226 as_bad (_("expected constant expression as first argument of %s"),
13761a11 3227 opcode->name);
65d7bab5 3228 break;
13761a11
NC
3229 }
3230 n = op1.exp.X_add_number;
3231 if (n > 4 || n < 1)
b18c562e 3232 {
13761a11
NC
3233 as_bad (_("expected first argument of %s to be in the range 1-4"),
3234 opcode->name);
65d7bab5 3235 break;
13761a11 3236 }
b18c562e 3237
13761a11
NC
3238 if ((reg = check_reg (l2)) == -1)
3239 {
3240 as_bad (_("expected register as second argument of %s"),
3241 opcode->name);
65d7bab5 3242 break;
b18c562e
NC
3243 }
3244
d1706f38 3245 if (target_is_430xv2 () && reg == 0)
638d3803
NC
3246 {
3247 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 3248 break;
638d3803
NC
3249 }
3250
13761a11
NC
3251 op_length = 2;
3252 frag = frag_more (op_length);
3253 where = frag - frag_now->fr_literal;
3254
3255 bin = opcode->bin_opcode;
3256 if (! addr_op)
3257 bin |= 0x10;
3258 bin |= (n - 1) << 10;
3259 bin |= reg;
3260
3261 bfd_putl16 ((bfd_vma) bin, frag);
3262 dwarf2_emit_insn (op_length);
3263 break;
3264 }
3265
13761a11
NC
3266 case 8:
3267 {
3268 bfd_boolean need_reloc = FALSE;
3269 int n;
3270 int reg;
3271
3272 /* ADDA, CMPA and SUBA address instructions. */
3273 if (extended & 0xff)
3274 {
3275 as_bad (_("repeat count cannot be used with %s"), opcode->name);
65d7bab5 3276 break;
13761a11
NC
3277 }
3278
3279 line = extract_operand (line, l1, sizeof (l1));
3280 line = extract_operand (line, l2, sizeof (l2));
3281
3282 bin = opcode->bin_opcode;
3283
3284 if (*l1 == '#')
3285 {
2bfa0cdf
NC
3286 end = parse_exp (l1 + 1, &(op1.exp));
3287 if (end != NULL && *end != 0)
3288 {
3289 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3290 break;
3291 }
13761a11
NC
3292
3293 if (op1.exp.X_op == O_constant)
3294 {
3295 n = op1.exp.X_add_number;
3296 if (n > 0xfffff || n < - (0x7ffff))
3297 {
3298 as_bad (_("expected value of first argument of %s to fit into 20-bits"),
3299 opcode->name);
65d7bab5 3300 break;
13761a11
NC
3301 }
3302
3303 bin |= ((n >> 16) & 0xf) << 8;
3304 }
3305 else
3306 {
3307 n = 0;
3308 need_reloc = TRUE;
3309 }
3310
3311 op_length = 4;
3312 }
3313 else
3314 {
3315 if ((n = check_reg (l1)) == -1)
3316 {
3317 as_bad (_("expected register name or constant as first argument of %s"),
3318 opcode->name);
65d7bab5 3319 break;
13761a11
NC
3320 }
3321
3322 bin |= (n << 8) | (1 << 6);
3323 op_length = 2;
3324 }
3325
3326 if ((reg = check_reg (l2)) == -1)
3327 {
3328 as_bad (_("expected register as second argument of %s"),
3329 opcode->name);
65d7bab5 3330 break;
13761a11
NC
3331 }
3332
3333 frag = frag_more (op_length);
3334 where = frag - frag_now->fr_literal;
3335 bin |= reg;
3336 if (need_reloc)
3337 fix_new_exp (frag_now, where, 4, &(op1.exp), FALSE,
3338 BFD_RELOC_MSP430X_ABS20_ADR_SRC);
3339
3340 bfd_putl16 ((bfd_vma) bin, frag);
3341 if (op_length == 4)
3342 bfd_putl16 ((bfd_vma) (n & 0xffff), frag + 2);
3343 dwarf2_emit_insn (op_length);
b18c562e 3344 break;
13761a11 3345 }
38d77545 3346
13761a11 3347 case 9: /* MOVA, BRA, RETA. */
00b32ff2 3348 imm_op = FALSE;
13761a11 3349 bin = opcode->bin_opcode;
b18c562e 3350
638d3803 3351 if (is_opcode ("reta"))
13761a11
NC
3352 {
3353 /* The RETA instruction does not take any arguments.
3354 The implicit first argument is @SP+.
3355 The implicit second argument is PC. */
3356 op1.mode = OP_REG;
3357 op1.am = 3;
3358 op1.reg = 1;
3359
3360 op2.mode = OP_REG;
3361 op2.reg = 0;
3362 }
3363 else
3364 {
3365 line = extract_operand (line, l1, sizeof (l1));
3366 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3367 &imm_op, extended_op, FALSE);
b18c562e 3368
638d3803 3369 if (is_opcode ("bra"))
13761a11
NC
3370 {
3371 /* This is the BRA synthetic instruction.
3372 The second argument is always PC. */
3373 op2.mode = OP_REG;
3374 op2.reg = 0;
3375 }
3376 else
3377 {
3378 line = extract_operand (line, l2, sizeof (l2));
3379 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode,
3380 extended_op, TRUE);
3381 }
38d77545 3382
13761a11
NC
3383 if (res)
3384 break; /* Error occurred. All warnings were done before. */
3385 }
3386
3387 /* Only a restricted subset of the normal MSP430 addressing modes
3388 are supported here, so check for the ones that are allowed. */
3389 if ((op_length = try_encode_mova (imm_op, bin, & op1, & op2,
3390 & error_message)) == 0)
2469cfa2 3391 {
13761a11 3392 as_bad (error_message, opcode->name);
65d7bab5 3393 break;
13761a11
NC
3394 }
3395 dwarf2_emit_insn (op_length);
3396 break;
3397
3398 case 10: /* RPT */
3399 line = extract_operand (line, l1, sizeof l1);
3400 /* The RPT instruction only accepted immediates and registers. */
3401 if (*l1 == '#')
3402 {
2bfa0cdf
NC
3403 end = parse_exp (l1 + 1, &(op1.exp));
3404 if (end != NULL && *end != 0)
3405 {
3406 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3407 break;
3408 }
13761a11
NC
3409 if (op1.exp.X_op != O_constant)
3410 {
3411 as_bad (_("expected constant value as argument to RPT"));
65d7bab5 3412 break;
13761a11
NC
3413 }
3414 if (op1.exp.X_add_number < 1
3415 || op1.exp.X_add_number > (1 << 4))
3416 {
3417 as_bad (_("expected constant in the range 2..16"));
65d7bab5 3418 break;
13761a11
NC
3419 }
3420
3421 /* We silently accept and ignore a repeat count of 1. */
3422 if (op1.exp.X_add_number > 1)
3423 repeat_count = op1.exp.X_add_number;
3424 }
3425 else
3426 {
3427 int reg;
b18c562e 3428
13761a11
NC
3429 if ((reg = check_reg (l1)) != -1)
3430 {
3431 if (reg == 0)
3432 as_warn (_("PC used as an argument to RPT"));
3433 else
3434 repeat_count = - reg;
3435 }
2469cfa2 3436 else
13761a11
NC
3437 {
3438 as_bad (_("expected constant or register name as argument to RPT insn"));
65d7bab5 3439 break;
13761a11 3440 }
2469cfa2 3441 }
b18c562e 3442 break;
13761a11
NC
3443
3444 default:
33eaf5de 3445 as_bad (_("Illegal emulated instruction"));
13761a11 3446 break;
2469cfa2 3447 }
b18c562e 3448 break;
2469cfa2 3449
b18c562e
NC
3450 case 1: /* Format 1, double operand. */
3451 line = extract_operand (line, l1, sizeof (l1));
3452 line = extract_operand (line, l2, sizeof (l2));
13761a11
NC
3453 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op, extended_op, TRUE);
3454 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode, extended_op, TRUE);
2469cfa2 3455
b18c562e
NC
3456 if (res)
3457 break; /* Error occurred. All warnings were done before. */
2469cfa2 3458
13761a11 3459 if (extended_op
638d3803 3460 && is_opcode ("movx")
13761a11
NC
3461 && addr_op
3462 && msp430_enable_relax)
3463 {
3464 /* This is the MOVX.A instruction. See if we can convert
3465 it into the MOVA instruction instead. This saves 2 bytes. */
3466 if ((op_length = try_encode_mova (imm_op, 0x0000, & op1, & op2,
3467 NULL)) != 0)
3468 {
3469 dwarf2_emit_insn (op_length);
3470 break;
3471 }
3472 }
3473
65d7bab5
NC
3474 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
3475
2213f746
NC
3476 /* If the PC is the destination... */
3477 if (op2.am == 0 && op2.reg == 0
3478 /* ... and the opcode alters the SR. */
3479 && !(is_opcode ("bic") || is_opcode ("bis") || is_opcode ("mov")
3480 || is_opcode ("bicx") || is_opcode ("bisx") || is_opcode ("movx")))
3481 {
3482 if (silicon_errata_fix & SILICON_ERRATA_CPU11)
de194d85 3483 as_bad (_("CPU11: PC is destination of SR altering instruction"));
2213f746 3484 else if (silicon_errata_warn & SILICON_ERRATA_CPU11)
de194d85 3485 as_warn (_("CPU11: PC is destination of SR altering instruction"));
2213f746
NC
3486 }
3487
3488 /* If the status register is the destination... */
3489 if (op2.am == 0 && op2.reg == 2
3490 /* ... and the opcode alters the SR. */
3491 && (is_opcode ("add") || is_opcode ("addc") || is_opcode ("and")
3492 || is_opcode ("dadd") || is_opcode ("sub") || is_opcode ("subc")
3493 || is_opcode ("xor")
3494 || is_opcode ("addx") || is_opcode ("addcx") || is_opcode ("andx")
3495 || is_opcode ("daddx") || is_opcode ("subx") || is_opcode ("subcx")
3496 || is_opcode ("xorx")
3497 ))
3498 {
3499 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
de194d85 3500 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2213f746 3501 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
de194d85 3502 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2213f746
NC
3503 }
3504
65d7bab5
NC
3505 if ( (is_opcode ("bic") && bin == 0xc232)
3506 || (is_opcode ("bis") && bin == 0xd232)
3507 || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
3508 {
2213f746
NC
3509 /* Avoid false checks when a constant value is being put into the SR. */
3510 if (op1.mode == OP_EXP
3511 && op1.exp.X_op == O_constant
3512 && (op1.exp.X_add_number & 0x8) != 0x8)
3513 ;
3514 else
3515 check_for_nop |= NOP_CHECK_INTERRUPT;
65d7bab5
NC
3516 }
3517
2213f746
NC
3518 if (((is_opcode ("bis") && bin == 0xd032)
3519 || (is_opcode ("mov") && bin == 0x4032)
3520 || (is_opcode ("xor") && bin == 0xe032))
3521 && op1.mode == OP_EXP
3522 && op1.exp.X_op == O_constant
3523 && (op1.exp.X_add_number & 0x10) == 0x10)
3524 check_for_nop |= NOP_CHECK_CPU19;
3525
13761a11 3526 /* Compute the entire length of the instruction in bytes. */
65d7bab5 3527 op_length = (extended_op ? 2 : 0) /* The extension word. */
13761a11
NC
3528 + 2 /* The opcode */
3529 + (2 * op1.ol) /* The first operand. */
3530 + (2 * op2.ol); /* The second operand. */
b18c562e 3531
65d7bab5
NC
3532 insn_length += op_length;
3533 frag = frag_more (op_length);
b18c562e 3534 where = frag - frag_now->fr_literal;
38d77545 3535
13761a11
NC
3536 if (extended_op)
3537 {
3538 if (!addr_op)
3539 extended |= BYTE_OPERATION;
3540
3541 if ((op1.ol != 0 || op2.ol != 0) && ((extended & 0xf) != 0))
3542 {
3543 as_bad (_("repeat instruction used with non-register mode instruction"));
3544 extended &= ~ 0xf;
3545 }
3546
3547 /* If necessary, emit a reloc to update the extension word. */
3548 if (op1.mode == OP_EXP)
3549 {
3550 if (op1.exp.X_op == O_constant)
3551 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
3552
e66c3c25 3553 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
3554 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3555 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3556 else
3557 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3558 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3559 }
38d77545 3560
13761a11
NC
3561 if (op2.mode == OP_EXP)
3562 {
3563 if (op2.exp.X_op == O_constant)
3564 extended |= (op2.exp.X_add_number >> 16) & 0xf;
3565
3566 else if (op1.mode == OP_EXP)
3567 fix_new_exp (frag_now, where, 8, &(op2.exp), FALSE,
3568 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_ODST
3569 : BFD_RELOC_MSP430X_PCR20_EXT_ODST);
38d77545 3570
13761a11
NC
3571 else
3572 fix_new_exp (frag_now, where, 6, &(op2.exp), FALSE,
3573 op2.reg ? BFD_RELOC_MSP430X_ABS20_EXT_DST
3574 : BFD_RELOC_MSP430X_PCR20_EXT_DST);
3575 }
3576
3577 /* Emit the extension word. */
3578 bfd_putl16 (extended, frag);
3579 where += 2;
3580 frag += 2;
3581 }
3582
b18c562e 3583 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3584 where += 2;
3585 frag += 2;
b18c562e
NC
3586
3587 if (op1.mode == OP_EXP)
2469cfa2 3588 {
13761a11
NC
3589 if (op1.exp.X_op == O_constant)
3590 {
3591 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3592 }
b18c562e 3593 else
13761a11
NC
3594 {
3595 bfd_putl16 ((bfd_vma) ZEROS, frag);
3596
3597 if (!extended_op)
3598 {
e66c3c25 3599 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 3600 fix_new_exp (frag_now, where, 2,
00b32ff2 3601 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
3602 else
3603 fix_new_exp (frag_now, where, 2,
3604 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3605 }
3606 }
3607
3608 where += 2;
3609 frag += 2;
2469cfa2 3610 }
b18c562e
NC
3611
3612 if (op2.mode == OP_EXP)
2469cfa2 3613 {
13761a11
NC
3614 if (op2.exp.X_op == O_constant)
3615 {
3616 bfd_putl16 (op2.exp.X_add_number & 0xffff, frag);
3617 }
b18c562e 3618 else
13761a11
NC
3619 {
3620 bfd_putl16 ((bfd_vma) ZEROS, frag);
3621
3622 if (!extended_op)
3623 {
3624 if (op2.reg) /* Not PC relative. */
3625 fix_new_exp (frag_now, where, 2,
00b32ff2 3626 &(op2.exp), FALSE, CHECK_RELOC_MSP430 (op2));
13761a11
NC
3627 else
3628 fix_new_exp (frag_now, where, 2,
3629 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3630 }
3631 }
3632 }
3633
13761a11 3634 dwarf2_emit_insn (insn_length);
2213f746
NC
3635
3636 /* If the PC is the destination... */
3637 if (op2.am == 0 && op2.reg == 0
3638 /* ... but the opcode does not alter the destination. */
3639 && (is_opcode ("cmp") || is_opcode ("bit") || is_opcode ("cmpx")))
3640 check_for_nop |= NOP_CHECK_CPU12;
b18c562e
NC
3641 break;
3642
3643 case 2: /* Single-operand mostly instr. */
3644 if (opcode->insn_opnumb == 0)
2469cfa2 3645 {
b18c562e 3646 /* reti instruction. */
13761a11 3647 insn_length += 2;
b18c562e
NC
3648 frag = frag_more (2);
3649 bfd_putl16 ((bfd_vma) bin, frag);
13761a11 3650 dwarf2_emit_insn (insn_length);
b18c562e 3651 break;
2469cfa2 3652 }
2469cfa2 3653
b18c562e 3654 line = extract_operand (line, l1, sizeof (l1));
13761a11
NC
3655 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode,
3656 &imm_op, extended_op, TRUE);
b18c562e
NC
3657 if (res)
3658 break; /* Error in operand. */
2469cfa2 3659
d1706f38
NC
3660 if (target_is_430xv2 ()
3661 && op1.mode == OP_REG
38d77545 3662 && op1.reg == 0
638d3803
NC
3663 && (is_opcode ("rrax")
3664 || is_opcode ("rrcx")
3665 || is_opcode ("rra")
3666 || is_opcode ("rrc")))
3667 {
3668 as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
65d7bab5 3669 break;
638d3803 3670 }
38d77545 3671
2213f746
NC
3672 /* If the status register is the destination... */
3673 if (op1.am == 0 && op1.reg == 2
3674 /* ... and the opcode alters the SR. */
3675 && (is_opcode ("rra") || is_opcode ("rrc") || is_opcode ("sxt")))
3676 {
3677 if (silicon_errata_fix & SILICON_ERRATA_CPU13)
de194d85 3678 as_bad (_("CPU13: SR is destination of SR altering instruction"));
2213f746 3679 else if (silicon_errata_warn & SILICON_ERRATA_CPU13)
de194d85 3680 as_warn (_("CPU13: SR is destination of SR altering instruction"));
2213f746
NC
3681 }
3682
13761a11
NC
3683 insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
3684 frag = frag_more (insn_length);
b18c562e 3685 where = frag - frag_now->fr_literal;
38d77545 3686
13761a11
NC
3687 if (extended_op)
3688 {
638d3803 3689 if (is_opcode ("swpbx") || is_opcode ("sxtx"))
13761a11
NC
3690 {
3691 /* These two instructions use a special
3692 encoding of the A/L and B/W bits. */
3693 bin &= ~ BYTE_OPERATION;
3694
3695 if (byte_op)
3696 {
3697 as_bad (_("%s instruction does not accept a .b suffix"),
3698 opcode->name);
65d7bab5 3699 break;
13761a11
NC
3700 }
3701 else if (! addr_op)
3702 extended |= BYTE_OPERATION;
3703 }
3704 else if (! addr_op)
3705 extended |= BYTE_OPERATION;
3706
c1d9289f
NC
3707 if (is_opcode ("rrux"))
3708 extended |= IGNORE_CARRY_BIT;
3709
13761a11
NC
3710 if (op1.ol != 0 && ((extended & 0xf) != 0))
3711 {
3712 as_bad (_("repeat instruction used with non-register mode instruction"));
3713 extended &= ~ 0xf;
3714 }
3715
3716 if (op1.mode == OP_EXP)
3717 {
3718 if (op1.exp.X_op == O_constant)
3719 extended |= ((op1.exp.X_add_number >> 16) & 0xf) << 7;
38d77545 3720
e66c3c25 3721 else if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11
NC
3722 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3723 BFD_RELOC_MSP430X_ABS20_EXT_SRC);
3724 else
3725 fix_new_exp (frag_now, where, 6, &(op1.exp), FALSE,
3726 BFD_RELOC_MSP430X_PCR20_EXT_SRC);
3727 }
38d77545 3728
13761a11
NC
3729 /* Emit the extension word. */
3730 bfd_putl16 (extended, frag);
3731 frag += 2;
3732 where += 2;
3733 }
3734
3735 bin |= op1.reg | (op1.am << 4);
b18c562e 3736 bfd_putl16 ((bfd_vma) bin, frag);
13761a11
NC
3737 frag += 2;
3738 where += 2;
b18c562e
NC
3739
3740 if (op1.mode == OP_EXP)
2469cfa2 3741 {
13761a11
NC
3742 if (op1.exp.X_op == O_constant)
3743 {
3744 bfd_putl16 (op1.exp.X_add_number & 0xffff, frag);
3745 }
b18c562e 3746 else
13761a11
NC
3747 {
3748 bfd_putl16 ((bfd_vma) ZEROS, frag);
3749
3750 if (!extended_op)
3751 {
e66c3c25 3752 if (op1.reg || op1.am == 3) /* Not PC relative. */
13761a11 3753 fix_new_exp (frag_now, where, 2,
00b32ff2 3754 &(op1.exp), FALSE, CHECK_RELOC_MSP430 (op1));
13761a11
NC
3755 else
3756 fix_new_exp (frag_now, where, 2,
3757 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
3758 }
3759 }
2469cfa2 3760 }
13761a11
NC
3761
3762 dwarf2_emit_insn (insn_length);
b18c562e 3763 break;
2469cfa2 3764
b18c562e
NC
3765 case 3: /* Conditional jumps instructions. */
3766 line = extract_operand (line, l1, sizeof (l1));
3767 /* l1 is a label. */
3768 if (l1[0])
2469cfa2 3769 {
b18c562e
NC
3770 char *m = l1;
3771 expressionS exp;
2469cfa2 3772
b18c562e
NC
3773 if (*m == '$')
3774 m++;
2469cfa2 3775
2bfa0cdf
NC
3776 end = parse_exp (m, &exp);
3777 if (end != NULL && *end != 0)
3778 {
3779 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3780 break;
3781 }
2469cfa2 3782
b18c562e 3783 /* In order to handle something like:
2469cfa2 3784
b18c562e
NC
3785 and #0x8000, r5
3786 tst r5
3787 jz 4 ; skip next 4 bytes
3788 inv r5
3789 inc r5
3790 nop ; will jump here if r5 positive or zero
2469cfa2 3791
b18c562e 3792 jCOND -n ;assumes jump n bytes backward:
2469cfa2 3793
b18c562e
NC
3794 mov r5,r6
3795 jmp -2
2469cfa2 3796
b18c562e
NC
3797 is equal to:
3798 lab:
3799 mov r5,r6
3800 jmp lab
3801
3802 jCOND $n ; jump from PC in either direction. */
2469cfa2 3803
b18c562e
NC
3804 if (exp.X_op == O_constant)
3805 {
3806 int x = exp.X_add_number;
2469cfa2 3807
b18c562e
NC
3808 if (x & 1)
3809 {
3810 as_warn (_("Even number required. Rounded to %d"), x + 1);
3811 x++;
3812 }
2469cfa2 3813
b18c562e
NC
3814 if ((*l1 == '$' && x > 0) || x < 0)
3815 x -= 2;
2469cfa2 3816
b18c562e
NC
3817 x >>= 1;
3818
3819 if (x > 512 || x < -511)
3820 {
33eaf5de 3821 as_bad (_("Wrong displacement %d"), x << 1);
b18c562e
NC
3822 break;
3823 }
3824
13761a11
NC
3825 insn_length += 2;
3826 frag = frag_more (2); /* Instr size is 1 word. */
3827
b18c562e
NC
3828 bin |= x & 0x3ff;
3829 bfd_putl16 ((bfd_vma) bin, frag);
3830 }
3831 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 3832 {
13761a11
NC
3833 insn_length += 2;
3834 frag = frag_more (2); /* Instr size is 1 word. */
b18c562e
NC
3835 where = frag - frag_now->fr_literal;
3836 fix_new_exp (frag_now, where, 2,
3837 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
3838
3839 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 3840 }
b18c562e 3841 else if (*l1 == '$')
2469cfa2 3842 {
b18c562e 3843 as_bad (_("instruction requires label sans '$'"));
2469cfa2 3844 }
b18c562e 3845 else
13761a11
NC
3846 as_bad (_
3847 ("instruction requires label or value in range -511:512"));
3848 dwarf2_emit_insn (insn_length);
2a9a06c1 3849 break;
2469cfa2 3850 }
b18c562e
NC
3851 else
3852 {
3853 as_bad (_("instruction requires label"));
3854 break;
3855 }
3856 break;
2469cfa2 3857
b18c562e 3858 case 4: /* Extended jumps. */
77592908
DD
3859 if (!msp430_enable_polys)
3860 {
20203fb9 3861 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3862 break;
3863 }
3739860c 3864
b18c562e
NC
3865 line = extract_operand (line, l1, sizeof (l1));
3866 if (l1[0])
2469cfa2 3867 {
b18c562e
NC
3868 char *m = l1;
3869 expressionS exp;
2469cfa2 3870
b18c562e
NC
3871 /* Ignore absolute addressing. make it PC relative anyway. */
3872 if (*m == '#' || *m == '$')
3873 m++;
2469cfa2 3874
2bfa0cdf
NC
3875 end = parse_exp (m, & exp);
3876 if (end != NULL && *end != 0)
3877 {
3878 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3879 break;
3880 }
b18c562e 3881 if (exp.X_op == O_symbol)
2469cfa2 3882 {
b18c562e
NC
3883 /* Relaxation required. */
3884 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
3885
638d3803 3886 if (target_is_430x ())
13761a11
NC
3887 rc = msp430x_rcodes[opcode->insn_opnumb];
3888
3889 /* The parameter to dwarf2_emit_insn is actually the offset to
3890 the start of the insn from the fix piece of instruction that
3891 was emitted. Since next fragments may have variable size we
3892 tie debug info to the beginning of the instruction. */
3893 insn_length += 8;
3e470ab5 3894 frag = frag_more (8);
2a9a06c1 3895 dwarf2_emit_insn (0);
3e470ab5
DD
3896 bfd_putl16 ((bfd_vma) rc.sop, frag);
3897 frag = frag_variant (rs_machine_dependent, 8, 2,
13761a11
NC
3898 /* Wild guess. */
3899 ENCODE_RELAX (rc.lpos, STATE_BITS10),
b18c562e
NC
3900 exp.X_add_symbol,
3901 0, /* Offset is zero if jump dist less than 1K. */
3902 (char *) frag);
3903 break;
2469cfa2
NC
3904 }
3905 }
b18c562e
NC
3906
3907 as_bad (_("instruction requires label"));
3908 break;
3909
3910 case 5: /* Emulated extended branches. */
77592908
DD
3911 if (!msp430_enable_polys)
3912 {
20203fb9 3913 as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
77592908
DD
3914 break;
3915 }
b18c562e
NC
3916 line = extract_operand (line, l1, sizeof (l1));
3917 if (l1[0])
2469cfa2 3918 {
b18c562e
NC
3919 char * m = l1;
3920 expressionS exp;
3921
3922 /* Ignore absolute addressing. make it PC relative anyway. */
3923 if (*m == '#' || *m == '$')
3924 m++;
3925
2bfa0cdf
NC
3926 end = parse_exp (m, & exp);
3927 if (end != NULL && *end != 0)
3928 {
3929 as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1);
3930 break;
3931 }
b18c562e
NC
3932 if (exp.X_op == O_symbol)
3933 {
3934 /* Relaxation required. */
3935 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
3936
638d3803 3937 if (target_is_430x ())
13761a11
NC
3938 hc = msp430x_hcodes[opcode->insn_opnumb];
3939
3940 insn_length += 8;
3e470ab5 3941 frag = frag_more (8);
2a9a06c1 3942 dwarf2_emit_insn (0);
3e470ab5
DD
3943 bfd_putl16 ((bfd_vma) hc.op0, frag);
3944 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
3945
3946 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
3947 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
3948 exp.X_add_symbol,
3949 0, /* Offset is zero if jump dist less than 1K. */
3950 (char *) frag);
3951 break;
3952 }
2469cfa2
NC
3953 }
3954
b18c562e
NC
3955 as_bad (_("instruction requires label"));
3956 break;
2469cfa2 3957
b18c562e 3958 default:
79cf5950 3959 as_bad (_("Illegal instruction or not implemented opcode."));
b18c562e 3960 }
2469cfa2 3961
927f2d25
NC
3962 if (is_opcode ("nop"))
3963 prev_insn_is_nop = TRUE;
3964 else
3965 prev_insn_is_nop = FALSE;
3966
b18c562e
NC
3967 input_line_pointer = line;
3968 return 0;
3969}
2469cfa2 3970
b18c562e
NC
3971void
3972md_assemble (char * str)
3973{
3974 struct msp430_opcode_s * opcode;
3975 char cmd[32];
3976 unsigned int i = 0;
2469cfa2 3977
b18c562e 3978 str = skip_space (str); /* Skip leading spaces. */
64a81db0 3979 str = extract_cmd (str, cmd, sizeof (cmd) - 1);
2469cfa2 3980
64a81db0 3981 while (cmd[i])
b18c562e
NC
3982 {
3983 char a = TOLOWER (cmd[i]);
3984 cmd[i] = a;
3985 i++;
2469cfa2 3986 }
2469cfa2 3987
b18c562e 3988 if (!cmd[0])
2469cfa2 3989 {
33eaf5de 3990 as_bad (_("can't find opcode"));
b18c562e
NC
3991 return;
3992 }
2469cfa2 3993
b18c562e 3994 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 3995
b18c562e
NC
3996 if (opcode == NULL)
3997 {
3998 as_bad (_("unknown opcode `%s'"), cmd);
3999 return;
2469cfa2 4000 }
2469cfa2 4001
b18c562e
NC
4002 {
4003 char *__t = input_line_pointer;
2469cfa2 4004
b18c562e
NC
4005 msp430_operands (opcode, str);
4006 input_line_pointer = __t;
4007 }
4008}
2469cfa2
NC
4009
4010/* GAS will call this function for each section at the end of the assembly,
4011 to permit the CPU backend to adjust the alignment of a section. */
4012
4013valueT
b18c562e 4014md_section_align (asection * seg, valueT addr)
2469cfa2
NC
4015{
4016 int align = bfd_get_section_alignment (stdoutput, seg);
4017
8d3842cd 4018 return ((addr + (1 << align) - 1) & -(1 << align));
2469cfa2
NC
4019}
4020
4021/* If you define this macro, it should return the offset between the
4022 address of a PC relative fixup and the position from which the PC
4023 relative adjustment should be made. On many processors, the base
4024 of a PC relative instruction is the next instruction, so this
4025 macro would return the length of an instruction. */
4026
4027long
b18c562e 4028md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
4029{
4030 if (fixp->fx_addsy != (symbolS *) NULL
4031 && (!S_IS_DEFINED (fixp->fx_addsy)
4032 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
4033 return 0;
4034
4035 return fixp->fx_frag->fr_address + fixp->fx_where;
4036}
4037
91cb9803 4038/* Addition to the standard TC_FORCE_RELOCATION_LOCAL.
77592908 4039 Now it handles the situation when relocations
13761a11 4040 have to be passed to linker. */
77592908 4041int
13761a11 4042msp430_force_relocation_local (fixS *fixp)
77592908 4043{
13761a11
NC
4044 if (fixp->fx_r_type == BFD_RELOC_MSP430_10_PCREL)
4045 return 1;
13761a11
NC
4046 if (fixp->fx_pcrel)
4047 return 1;
77592908
DD
4048 if (msp430_enable_polys
4049 && !msp430_enable_relax)
4050 return 1;
13761a11 4051
91cb9803 4052 return 0;
77592908
DD
4053}
4054
4055
2469cfa2
NC
4056/* GAS will call this for each fixup. It should store the correct
4057 value in the object file. */
2469cfa2 4058void
55cf6793 4059md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 4060{
b18c562e 4061 unsigned char * where;
2469cfa2
NC
4062 unsigned long insn;
4063 long value;
4064
4065 if (fixp->fx_addsy == (symbolS *) NULL)
4066 {
4067 value = *valuep;
4068 fixp->fx_done = 1;
4069 }
4070 else if (fixp->fx_pcrel)
4071 {
4072 segT s = S_GET_SEGMENT (fixp->fx_addsy);
4073
4074 if (fixp->fx_addsy && (s == seg || s == absolute_section))
4075 {
18af0b39
NC
4076 /* FIXME: We can appear here only in case if we perform a pc
4077 relative jump to the label which is i) global, ii) locally
4078 defined or this is a jump to an absolute symbol.
4079 If this is an absolute symbol -- everything is OK.
4080 If this is a global label, we've got a symbol value defined
4081 twice:
4082 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
4083 from this section start
4084 2. *valuep will contain the real offset from jump insn to the
4085 label
4086 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
4087 will be incorrect. Therefore remove s_get_value. */
4088 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
4089 fixp->fx_done = 1;
4090 }
4091 else
4092 value = *valuep;
4093 }
4094 else
4095 {
4096 value = fixp->fx_offset;
4097
4098 if (fixp->fx_subsy != (symbolS *) NULL)
4099 {
4100 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4101 {
4102 value -= S_GET_VALUE (fixp->fx_subsy);
4103 fixp->fx_done = 1;
4104 }
2469cfa2
NC
4105 }
4106 }
4107
77592908
DD
4108 fixp->fx_no_overflow = 1;
4109
38d77545 4110 /* If polymorphs are enabled and relax disabled.
13761a11 4111 do not kill any relocs and pass them to linker. */
38d77545 4112 if (msp430_enable_polys
77592908 4113 && !msp430_enable_relax)
2469cfa2 4114 {
e66c3c25
NC
4115 if (!fixp->fx_addsy
4116 || S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
79cf5950 4117 fixp->fx_done = 1; /* It is ok to kill 'abs' reloc. */
77592908
DD
4118 else
4119 fixp->fx_done = 0;
2469cfa2
NC
4120 }
4121
4122 if (fixp->fx_done)
4123 {
4124 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 4125 value, and stuff the instruction back again. */
2132e3a3 4126 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
4127
4128 insn = bfd_getl16 (where);
4129
4130 switch (fixp->fx_r_type)
4131 {
4132 case BFD_RELOC_MSP430_10_PCREL:
4133 if (value & 1)
4134 as_bad_where (fixp->fx_file, fixp->fx_line,
4135 _("odd address operand: %ld"), value);
4136
4137 /* Jumps are in words. */
4138 value >>= 1;
4139 --value; /* Correct PC. */
4140
4141 if (value < -512 || value > 511)
4142 as_bad_where (fixp->fx_file, fixp->fx_line,
4143 _("operand out of range: %ld"), value);
4144
4145 value &= 0x3ff; /* get rid of extended sign */
4146 bfd_putl16 ((bfd_vma) (value | insn), where);
4147 break;
4148
13761a11 4149 case BFD_RELOC_MSP430X_PCR16:
b18c562e 4150 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
4151 case BFD_RELOC_MSP430_16_PCREL:
4152 if (value & 1)
4153 as_bad_where (fixp->fx_file, fixp->fx_line,
4154 _("odd address operand: %ld"), value);
13761a11 4155 /* Fall through. */
2469cfa2
NC
4156
4157 case BFD_RELOC_MSP430_16_PCREL_BYTE:
4158 /* Nothing to be corrected here. */
4159 if (value < -32768 || value > 65536)
4160 as_bad_where (fixp->fx_file, fixp->fx_line,
4161 _("operand out of range: %ld"), value);
13761a11 4162 /* Fall through. */
2469cfa2 4163
13761a11
NC
4164 case BFD_RELOC_MSP430X_ABS16:
4165 case BFD_RELOC_MSP430_16:
4166 case BFD_RELOC_16:
4167 case BFD_RELOC_MSP430_16_BYTE:
2469cfa2
NC
4168 value &= 0xffff; /* Get rid of extended sign. */
4169 bfd_putl16 ((bfd_vma) value, where);
4170 break;
4171
00b32ff2
NC
4172 case BFD_RELOC_MSP430_ABS_HI16:
4173 value >>= 16;
4174 value &= 0xffff; /* Get rid of extended sign. */
4175 bfd_putl16 ((bfd_vma) value, where);
4176 break;
3739860c 4177
2469cfa2
NC
4178 case BFD_RELOC_32:
4179 bfd_putl16 ((bfd_vma) value, where);
4180 break;
4181
13761a11
NC
4182 case BFD_RELOC_MSP430_ABS8:
4183 case BFD_RELOC_8:
4184 bfd_put_8 (NULL, (bfd_vma) value, where);
4185 break;
4186
4187 case BFD_RELOC_MSP430X_ABS20_EXT_SRC:
4188 case BFD_RELOC_MSP430X_PCR20_EXT_SRC:
4189 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
38d77545 4190 value >>= 16;
13761a11
NC
4191 bfd_putl16 ((bfd_vma) (((value & 0xf) << 7) | insn), where);
4192 break;
4193
4194 case BFD_RELOC_MSP430X_ABS20_ADR_SRC:
4195 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
38d77545 4196 value >>= 16;
13761a11
NC
4197 bfd_putl16 ((bfd_vma) (((value & 0xf) << 8) | insn), where);
4198 break;
4199
4200 case BFD_RELOC_MSP430X_ABS20_EXT_ODST:
4201 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4202 value >>= 16;
4203 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4204 break;
4205
4206 case BFD_RELOC_MSP430X_PCR20_CALL:
4207 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4208 value >>= 16;
4209 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4210 break;
4211
4212 case BFD_RELOC_MSP430X_ABS20_EXT_DST:
4213 case BFD_RELOC_MSP430X_PCR20_EXT_DST:
4214 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
4215 value >>= 16;
4216 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4217 break;
4218
4219 case BFD_RELOC_MSP430X_PCR20_EXT_ODST:
4220 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
4221 value >>= 16;
4222 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
4223 break;
4224
4225 case BFD_RELOC_MSP430X_ABS20_ADR_DST:
4226 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
4227 value >>= 16;
4228 bfd_putl16 ((bfd_vma) ((value & 0xf) | insn), where);
2469cfa2 4229 break;
38d77545 4230
2469cfa2
NC
4231 default:
4232 as_fatal (_("line %d: unknown relocation type: 0x%x"),
4233 fixp->fx_line, fixp->fx_r_type);
4234 break;
4235 }
4236 }
4237 else
4238 {
4239 fixp->fx_addnumber = value;
4240 }
2469cfa2
NC
4241}
4242
13761a11
NC
4243static bfd_boolean
4244S_IS_GAS_LOCAL (symbolS * s)
4245{
4246 const char * name;
4247 unsigned int len;
4248
4249 if (s == NULL)
4250 return FALSE;
4251 name = S_GET_NAME (s);
4252 len = strlen (name) - 1;
38d77545 4253
13761a11
NC
4254 return name[len] == 1 || name[len] == 2;
4255}
4256
7be1c489
AM
4257/* GAS will call this to generate a reloc, passing the resulting reloc
4258 to `bfd_install_relocation'. This currently works poorly, as
4259 `bfd_install_relocation' often does the wrong thing, and instances of
4260 `tc_gen_reloc' have been written to work around the problems, which
4261 in turns makes it difficult to fix `bfd_install_relocation'. */
2469cfa2
NC
4262
4263/* If while processing a fixup, a reloc really needs to be created
4264 then it is done here. */
4265
13761a11 4266arelent **
b18c562e 4267tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 4268{
13761a11
NC
4269 static arelent * no_relocs = NULL;
4270 static arelent * relocs[MAX_RELOC_EXPANSION + 1];
4271 arelent *reloc;
2469cfa2 4272
325801bd 4273 reloc = XNEW (arelent);
2469cfa2
NC
4274 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4275 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
13761a11 4276
2469cfa2
NC
4277 if (reloc->howto == (reloc_howto_type *) NULL)
4278 {
4279 as_bad_where (fixp->fx_file, fixp->fx_line,
4280 _("reloc %d not supported by object file format"),
4281 (int) fixp->fx_r_type);
13761a11
NC
4282 free (reloc);
4283 return & no_relocs;
4284 }
4285
4286 relocs[0] = reloc;
4287 relocs[1] = NULL;
4288
4289 if (fixp->fx_subsy
4290 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
4291 {
4292 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
4293 fixp->fx_subsy = NULL;
2469cfa2
NC
4294 }
4295
13761a11
NC
4296 if (fixp->fx_addsy && fixp->fx_subsy)
4297 {
4298 asection *asec, *ssec;
4299
4300 asec = S_GET_SEGMENT (fixp->fx_addsy);
4301 ssec = S_GET_SEGMENT (fixp->fx_subsy);
4302
4303 /* If we have a difference between two different, non-absolute symbols
4304 we must generate two relocs (one for each symbol) and allow the
4305 linker to resolve them - relaxation may change the distances between
4306 symbols, even local symbols defined in the same section.
4307
4308 Unfortunately we cannot do this with assembler generated local labels
4309 because there can be multiple incarnations of the same label, with
4310 exactly the same name, in any given section and the linker will have
4311 no way to identify the correct one. Instead we just have to hope
33eaf5de 4312 that no relaxation will occur between the local label and the other
13761a11
NC
4313 symbol in the expression.
4314
4315 Similarly we have to compute differences between symbols in the .eh_frame
4316 section as the linker is not smart enough to apply relocations there
4317 before attempting to process it. */
4318 if ((ssec != absolute_section || asec != absolute_section)
4319 && (fixp->fx_addsy != fixp->fx_subsy)
4320 && strcmp (ssec->name, ".eh_frame") != 0
4321 && ! S_IS_GAS_LOCAL (fixp->fx_addsy)
4322 && ! S_IS_GAS_LOCAL (fixp->fx_subsy))
4323 {
325801bd 4324 arelent * reloc2 = XNEW (arelent);
2469cfa2 4325
13761a11
NC
4326 relocs[0] = reloc2;
4327 relocs[1] = reloc;
2469cfa2 4328
13761a11
NC
4329 reloc2->address = reloc->address;
4330 reloc2->howto = bfd_reloc_type_lookup (stdoutput,
4331 BFD_RELOC_MSP430_SYM_DIFF);
4332 reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
4333
4334 if (ssec == absolute_section)
4335 reloc2->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4336 else
4337 {
325801bd 4338 reloc2->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4339 *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
4340 }
4341
38d77545 4342 reloc->addend = fixp->fx_offset;
13761a11
NC
4343 if (asec == absolute_section)
4344 {
4345 reloc->addend += S_GET_VALUE (fixp->fx_addsy);
4346 reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4347 }
4348 else
4349 {
325801bd 4350 reloc->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4351 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4352 }
4353
4354 fixp->fx_pcrel = 0;
4355 fixp->fx_done = 1;
4356 return relocs;
4357 }
4358 else
4359 {
4360 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4361
4362 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
4363 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
4364
4365 switch (fixp->fx_r_type)
4366 {
4367 case BFD_RELOC_8:
4368 md_number_to_chars (fixpos, reloc->addend, 1);
4369 break;
4370
4371 case BFD_RELOC_16:
4372 md_number_to_chars (fixpos, reloc->addend, 2);
4373 break;
4374
4375 case BFD_RELOC_24:
4376 md_number_to_chars (fixpos, reloc->addend, 3);
4377 break;
4378
4379 case BFD_RELOC_32:
4380 md_number_to_chars (fixpos, reloc->addend, 4);
4381 break;
4382
4383 default:
4384 reloc->sym_ptr_ptr
4385 = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
4386 return relocs;
4387 }
4388
4389 free (reloc);
4390 return & no_relocs;
4391 }
4392 }
4393 else
4394 {
4395#if 0
4396 if (fixp->fx_r_type == BFD_RELOC_MSP430X_ABS16
4397 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section)
4398 {
4399 bfd_vma amount = S_GET_VALUE (fixp->fx_addsy);
4400 char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
4401
4402 md_number_to_chars (fixpos, amount, 2);
4403 free (reloc);
4404 return & no_relocs;
4405 }
4406#endif
325801bd 4407 reloc->sym_ptr_ptr = XNEW (asymbol *);
13761a11
NC
4408 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4409 reloc->addend = fixp->fx_offset;
4410
4411 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
4412 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
4413 reloc->address = fixp->fx_offset;
4414 }
4415
4416 return relocs;
2469cfa2
NC
4417}
4418
b18c562e
NC
4419int
4420md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
4421 asection * segment_type ATTRIBUTE_UNUSED)
4422{
4423 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
4424 {
4425 /* This is a jump -> pcrel mode. Nothing to do much here.
4426 Return value == 2. */
4427 fragP->fr_subtype =
4428 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
4429 }
4430 else if (fragP->fr_symbol)
4431 {
33eaf5de 4432 /* It's got a segment, but it's not ours. Even if fr_symbol is in
79cf5950 4433 an absolute segment, we don't know a displacement until we link
b18c562e
NC
4434 object files. So it will always be long. This also applies to
4435 labels in a subsegment of current. Liker may relax it to short
4436 jump later. Return value == 8. */
4437 fragP->fr_subtype =
4438 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
4439 }
4440 else
4441 {
4442 /* We know the abs value. may be it is a jump to fixed address.
79cf5950 4443 Impossible in our case, cause all constants already handled. */
b18c562e
NC
4444 fragP->fr_subtype =
4445 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
4446 }
2469cfa2 4447
b18c562e
NC
4448 return md_relax_table[fragP->fr_subtype].rlx_length;
4449}
4450
4451void
4452md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
4453 asection * sec ATTRIBUTE_UNUSED,
4454 fragS * fragP)
2469cfa2 4455{
b18c562e
NC
4456 char * where = 0;
4457 int rela = -1;
4458 int i;
4459 struct rcodes_s * cc = NULL;
4460 struct hcodes_s * hc = NULL;
4461
4462 switch (fragP->fr_subtype)
4463 {
4464 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
4465 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
4466 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
4467 /* We do not have to convert anything here.
4468 Just apply a fix. */
4469 rela = BFD_RELOC_MSP430_10_PCREL;
4470 break;
4471
4472 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
4473 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
4474 /* Convert uncond branch jmp lab -> br lab. */
638d3803 4475 if (target_is_430x ())
13761a11 4476 cc = msp430x_rcodes + 7;
638d3803
NC
4477 else
4478 cc = msp430_rcodes + 7;
b18c562e
NC
4479 where = fragP->fr_literal + fragP->fr_fix;
4480 bfd_putl16 (cc->lop0, where);
4481 rela = BFD_RELOC_MSP430_RL_PCREL;
4482 fragP->fr_fix += 2;
4483 break;
4484
4485 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
4486 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
4487 {
4488 /* Other simple branches. */
4489 int insn = bfd_getl16 (fragP->fr_opcode);
4490
4491 insn &= 0xffff;
4492 /* Find actual instruction. */
638d3803 4493 if (target_is_430x ())
13761a11
NC
4494 {
4495 for (i = 0; i < 7 && !cc; i++)
4496 if (msp430x_rcodes[i].sop == insn)
4497 cc = msp430x_rcodes + i;
4498 }
4499 else
4500 {
4501 for (i = 0; i < 7 && !cc; i++)
4502 if (msp430_rcodes[i].sop == insn)
4503 cc = & msp430_rcodes[i];
4504 }
4505
b18c562e
NC
4506 if (!cc || !cc->name)
4507 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
4508 __FUNCTION__, (long) insn);
4509 where = fragP->fr_literal + fragP->fr_fix;
4510 bfd_putl16 (cc->lop0, where);
4511 bfd_putl16 (cc->lop1, where + 2);
4512 rela = BFD_RELOC_MSP430_RL_PCREL;
4513 fragP->fr_fix += 4;
4514 }
4515 break;
4516
4517 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
4518 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
638d3803 4519 if (target_is_430x ())
13761a11 4520 cc = msp430x_rcodes + 6;
638d3803
NC
4521 else
4522 cc = msp430_rcodes + 6;
b18c562e
NC
4523 where = fragP->fr_literal + fragP->fr_fix;
4524 bfd_putl16 (cc->lop0, where);
4525 bfd_putl16 (cc->lop1, where + 2);
4526 bfd_putl16 (cc->lop2, where + 4);
4527 rela = BFD_RELOC_MSP430_RL_PCREL;
4528 fragP->fr_fix += 6;
4529 break;
4530
4531 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
4532 {
4533 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4534
4535 insn &= 0xffff;
638d3803 4536 if (target_is_430x ())
13761a11
NC
4537 {
4538 for (i = 0; i < 4 && !hc; i++)
4539 if (msp430x_hcodes[i].op1 == insn)
4540 hc = msp430x_hcodes + i;
4541 }
4542 else
4543 {
4544 for (i = 0; i < 4 && !hc; i++)
4545 if (msp430_hcodes[i].op1 == insn)
4546 hc = &msp430_hcodes[i];
4547 }
b18c562e
NC
4548 if (!hc || !hc->name)
4549 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4550 __FUNCTION__, (long) insn);
4551 rela = BFD_RELOC_MSP430_10_PCREL;
4552 /* Apply a fix for a first label if necessary.
4553 another fix will be applied to the next word of insn anyway. */
4554 if (hc->tlab == 2)
4555 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
13761a11 4556 fragP->fr_offset, TRUE, rela);
b18c562e
NC
4557 fragP->fr_fix += 2;
4558 }
4559
4560 break;
4561
4562 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
4563 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
4564 {
4565 int insn = bfd_getl16 (fragP->fr_opcode + 2);
4566
4567 insn &= 0xffff;
638d3803 4568 if (target_is_430x ())
13761a11
NC
4569 {
4570 for (i = 0; i < 4 && !hc; i++)
4571 if (msp430x_hcodes[i].op1 == insn)
4572 hc = msp430x_hcodes + i;
4573 }
4574 else
4575 {
4576 for (i = 0; i < 4 && !hc; i++)
4577 if (msp430_hcodes[i].op1 == insn)
4578 hc = & msp430_hcodes[i];
4579 }
b18c562e
NC
4580 if (!hc || !hc->name)
4581 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
4582 __FUNCTION__, (long) insn);
4583 rela = BFD_RELOC_MSP430_RL_PCREL;
4584 where = fragP->fr_literal + fragP->fr_fix;
4585 bfd_putl16 (hc->lop0, where);
4586 bfd_putl16 (hc->lop1, where + 2);
4587 bfd_putl16 (hc->lop2, where + 4);
4588 fragP->fr_fix += 6;
4589 }
4590 break;
4591
4592 default:
33eaf5de 4593 as_fatal (_("internal inconsistency problem in %s: %lx"),
b18c562e
NC
4594 __FUNCTION__, (long) fragP->fr_subtype);
4595 break;
4596 }
4597
4598 /* Now apply fix. */
4599 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
4600 fragP->fr_offset, TRUE, rela);
4601 /* Just fixed 2 bytes. */
4602 fragP->fr_fix += 2;
2469cfa2
NC
4603}
4604
b18c562e
NC
4605/* Relax fragment. Mostly stolen from hc11 and mcore
4606 which arches I think I know. */
2469cfa2 4607
b18c562e
NC
4608long
4609msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
4610 long stretch ATTRIBUTE_UNUSED)
2469cfa2 4611{
b18c562e
NC
4612 long growth;
4613 offsetT aim = 0;
4614 symbolS *symbolP;
4615 const relax_typeS *this_type;
4616 const relax_typeS *start_type;
4617 relax_substateT next_state;
4618 relax_substateT this_state;
4619 const relax_typeS *table = md_relax_table;
4620
4621 /* Nothing to be done if the frag has already max size. */
4622 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
4623 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
4624 return 0;
4625
4626 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
4627 {
4628 symbolP = fragP->fr_symbol;
4629 if (symbol_resolved_p (symbolP))
4630 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
4631 __FUNCTION__);
4632 /* We know the offset. calculate a distance. */
4633 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
4634 }
4635
77592908
DD
4636 if (!msp430_enable_relax)
4637 {
4638 /* Relaxation is not enabled. So, make all jump as long ones
13761a11 4639 by setting 'aim' to quite high value. */
77592908
DD
4640 aim = 0x7fff;
4641 }
38d77545 4642
b18c562e
NC
4643 this_state = fragP->fr_subtype;
4644 start_type = this_type = table + this_state;
4645
4646 if (aim < 0)
4647 {
4648 /* Look backwards. */
4649 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4650 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
b18c562e
NC
4651 next_state = 0;
4652 else
4653 {
4654 /* Grow to next state. */
4655 this_state = next_state;
4656 this_type = table + this_state;
4657 next_state = this_type->rlx_more;
4658 }
4659 }
4660 else
4661 {
4662 /* Look forwards. */
4663 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 4664 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
b18c562e
NC
4665 next_state = 0;
4666 else
4667 {
4668 /* Grow to next state. */
4669 this_state = next_state;
4670 this_type = table + this_state;
4671 next_state = this_type->rlx_more;
4672 }
4673 }
4674
4675 growth = this_type->rlx_length - start_type->rlx_length;
4676 if (growth != 0)
4677 fragP->fr_subtype = this_state;
4678 return growth;
2469cfa2 4679}
13761a11
NC
4680
4681/* Return FALSE if the fixup in fixp should be left alone and not
4682 adjusted. We return FALSE here so that linker relaxation will
4683 work. */
4684
4685bfd_boolean
4686msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
4687{
4688 /* If the symbol is in a non-code section then it should be OK. */
4689 if (fixp->fx_addsy
4690 && ((S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE) == 0))
4691 return TRUE;
38d77545 4692
13761a11
NC
4693 return FALSE;
4694}
4695
4696/* Set the contents of the .MSP430.attributes section. */
4697
4698void
4699msp430_md_end (void)
4700{
2213f746
NC
4701 if (check_for_nop)
4702 as_warn ("assembly finished without a possibly needed NOP instruction");
65d7bab5 4703
13761a11 4704 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
638d3803 4705 target_is_430x () ? 2 : 1);
13761a11
NC
4706
4707 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model,
4708 large_model ? 2 : 1);
4709
4710 bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model,
4711 large_model ? 2 : 1);
4712}
4713
4714/* Returns FALSE if there is a msp430 specific reason why the
4715 subtraction of two same-section symbols cannot be computed by
4716 the assembler. */
4717
4718bfd_boolean
4719msp430_allow_local_subtract (expressionS * left,
4720 expressionS * right,
4721 segT section)
4722{
4723 /* If the symbols are not in a code section then they are OK. */
4724 if ((section->flags & SEC_CODE) == 0)
4725 return TRUE;
4726
4727 if (S_IS_GAS_LOCAL (left->X_add_symbol) || S_IS_GAS_LOCAL (right->X_add_symbol))
4728 return TRUE;
4729
4730 if (left->X_add_symbol == right->X_add_symbol)
4731 return TRUE;
4732
4733 /* We have to assume that there may be instructions between the
4734 two symbols and that relaxation may increase the distance between
4735 them. */
4736 return FALSE;
4737}
This page took 0.954947 seconds and 4 git commands to generate.