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