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