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