This adjusts equate handling by
[deliverable/binutils-gdb.git] / gas / config / tc-msp430.c
CommitLineData
2469cfa2
NC
1/* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
2
18af0b39 3 Copyright (C) 2002, 2003, 2004, 2005 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
10 the Free Software Foundation; either version 2, or (at your option)
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
NC
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include <limits.h>
27
28#define PUSH_1X_WORKAROUND
29#include "as.h"
30#include "subsegs.h"
31#include "opcode/msp430.h"
32#include "safe-ctype.h"
2a9a06c1 33#include "dwarf2dbg.h"
2469cfa2 34
77592908
DD
35/*
36 We will disable polymorphs by default because it is dangerous.
37 The potencial problem here is the following: assume we got the
38 following code:
39
40 jump .l1
41 nop
42 jump subroutine ; external symbol
43 .l1:
44 nop
45 ret
46
47 In case of assembly time relaxation we'll get:
48 0: jmp .l1 <.text +0x08> (reloc deleted)
49 2: nop
50 4: br subroutine
51 .l1:
52 8: nop
53 10: ret
54
55 If the 'subroutine' wiys thin +-1024 bytes range then linker
56 will produce
57 0: jmp .text +0x08
58 2: nop
59 4: jmp subroutine
60 .l1:
61 6: nop
62 8: ret ; 'jmp .text +0x08' will land here. WRONG!!!
63
64
65 The workaround is the following:
66 1. Declare global var enable_polymorphs which set to 1 via option -mP.
67 2. Declare global var enable_relax which set to 1 via option -mQ.
68
69 If polymorphs are enabled, and relax isn't, treat all jumps as long jumps,
70 do not delete any relocs and leave them for linker.
71
72 If relax is enabled, relax at assembly time and kill relocs as necessary.
73 */
74
75int msp430_enable_relax;
76int msp430_enable_polys;
77
f5c7edf4
AM
78/* GCC uses the some condition codes which we'll
79 implement as new polymorph instructions.
80
81 COND EXPL SHORT JUMP LONG JUMP
82 ===============================================
83 eq == jeq jne +4; br lab
84 ne != jne jeq +4; br lab
85
86 ltn honours no-overflow flag
87 ltn < jn jn +2; jmp +4; br lab
88
89 lt < jl jge +4; br lab
90 ltu < jlo lhs +4; br lab
91 le <= see below
92 leu <= see below
93
94 gt > see below
95 gtu > see below
96 ge >= jge jl +4; br lab
97 geu >= jhs jlo +4; br lab
98 ===============================================
99
100 Therefore, new opcodes are (BranchEQ -> beq; and so on...)
101 beq,bne,blt,bltn,bltu,bge,bgeu
102 'u' means unsigned compares
103
104 Also, we add 'jump' instruction:
105 jump UNCOND -> jmp br lab
106
107 They will have fmt == 4, and insn_opnumb == number of instruction. */
108
109struct rcodes_s
110{
111 char * name;
112 int index; /* Corresponding insn_opnumb. */
113 int sop; /* Opcode if jump length is short. */
114 long lpos; /* Label position. */
115 long lop0; /* Opcode 1 _word_ (16 bits). */
116 long lop1; /* Opcode second word. */
117 long lop2; /* Opcode third word. */
118};
119
120#define MSP430_RLC(n,i,sop,o1) \
121 {#n, i, sop, 2, (o1 + 2), 0x4010, 0}
122
123static struct rcodes_s msp430_rcodes[] =
124{
125 MSP430_RLC (beq, 0, 0x2400, 0x2000),
126 MSP430_RLC (bne, 1, 0x2000, 0x2400),
127 MSP430_RLC (blt, 2, 0x3800, 0x3400),
128 MSP430_RLC (bltu, 3, 0x2800, 0x2c00),
129 MSP430_RLC (bge, 4, 0x3400, 0x3800),
130 MSP430_RLC (bgeu, 5, 0x2c00, 0x2800),
131 {"bltn", 6, 0x3000, 3, 0x3000 + 1, 0x3c00 + 2,0x4010},
132 {"jump", 7, 0x3c00, 1, 0x4010, 0, 0},
133 {0,0,0,0,0,0,0}
134};
135#undef MSP430_RLC
136
137
138/* More difficult than above and they have format 5.
139
140 COND EXPL SHORT LONG
141 =================================================================
142 gt > jeq +2; jge label jeq +6; jl +4; br label
143 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
144 leu <= jeq label; jlo label jeq +2; jhs +4; br label
145 le <= jeq label; jl label jeq +2; jge +4; br label
146 ================================================================= */
147
148struct hcodes_s
149{
150 char * name;
151 int index; /* Corresponding insn_opnumb. */
152 int tlab; /* Number of labels in short mode. */
153 int op0; /* Opcode for first word of short jump. */
154 int op1; /* Opcode for second word of short jump. */
155 int lop0; /* Opcodes for long jump mode. */
156 int lop1;
157 int lop2;
158};
159
160static struct hcodes_s msp430_hcodes[] =
161{
162 {"bgt", 0, 1, 0x2401, 0x3400, 0x2403, 0x3802, 0x4010 },
163 {"bgtu", 1, 1, 0x2401, 0x2c00, 0x2403, 0x2802, 0x4010 },
164 {"bleu", 2, 2, 0x2400, 0x2800, 0x2401, 0x2c02, 0x4010 },
165 {"ble", 3, 2, 0x2400, 0x3800, 0x2401, 0x3402, 0x4010 },
166 {0,0,0,0,0,0,0,0}
167};
168
2469cfa2
NC
169const char comment_chars[] = ";";
170const char line_comment_chars[] = "#";
171const char line_separator_chars[] = "";
172const char EXP_CHARS[] = "eE";
173const char FLT_CHARS[] = "dD";
174
175/* Handle long expressions. */
176extern LITTLENUM_TYPE generic_bignum[];
177
178static struct hash_control *msp430_hash;
179
b18c562e
NC
180/* Relaxations. */
181#define STATE_UNCOND_BRANCH 1 /* jump */
182#define STATE_NOOV_BRANCH 3 /* bltn */
183#define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
184#define STATE_EMUL_BRANCH 4
185
186#define CNRL 2
187#define CUBL 4
188#define CNOL 8
189#define CSBL 6
190#define CEBL 4
191
192/* Length. */
193#define STATE_BITS10 1 /* wild guess. short jump */
194#define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
195#define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
196
197#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
198#define RELAX_STATE(s) ((s) & 3)
199#define RELAX_LEN(s) ((s) >> 2)
200#define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
201
202relax_typeS md_relax_table[] =
203{
204 /* Unused. */
205 {1, 1, 0, 0},
206 {1, 1, 0, 0},
207 {1, 1, 0, 0},
208 {1, 1, 0, 0},
209
210 /* Unconditional jump. */
211 {1, 1, 8, 5},
212 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
213 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
214 {1, 1, CUBL, 0}, /* state undef */
215
216 /* Simple branches. */
217 {0, 0, 8, 9},
218 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
219 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
220 {1, 1, CSBL, 0},
221
222 /* blt no overflow branch. */
223 {1, 1, 8, 13},
224 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
225 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
226 {1, 1, CNOL, 0},
227
228 /* Emulated branches. */
229 {1, 1, 8, 17},
230 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
231 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
232 {1, 1, CNOL, 0}
233};
234
2469cfa2 235
8cd5b113 236#define MAX_OP_LEN 256
2469cfa2
NC
237
238struct mcu_type_s
239{
b18c562e 240 char * name;
2469cfa2
NC
241 int isa;
242 int mach;
243};
244
245#define MSP430_ISA_11 11
3b260895 246#define MSP430_ISA_110 110
2469cfa2
NC
247#define MSP430_ISA_12 12
248#define MSP430_ISA_13 13
249#define MSP430_ISA_14 14
3b260895
NC
250#define MSP430_ISA_15 15
251#define MSP430_ISA_16 16
44c86e8c 252#define MSP430_ISA_21 21
2469cfa2
NC
253#define MSP430_ISA_31 31
254#define MSP430_ISA_32 32
255#define MSP430_ISA_33 33
3b260895
NC
256#define MSP430_ISA_41 41
257#define MSP430_ISA_42 42
2469cfa2
NC
258#define MSP430_ISA_43 43
259#define MSP430_ISA_44 44
2469cfa2
NC
260
261#define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
262#define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
263
264static struct mcu_type_s mcu_types[] =
265{
b18c562e
NC
266 {"msp1", MSP430_ISA_11, bfd_mach_msp11},
267 {"msp2", MSP430_ISA_14, bfd_mach_msp14},
268 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
269 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
270 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
271 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
272 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
273 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
274 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
275
276 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
277 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
278 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
279 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
280
281 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
282 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
283 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
284 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
285 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
286 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
287 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
288
289 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
290 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
291 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
292 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
293 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
294 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
c05e9f04
NC
295 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
296 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
297 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
3b260895 298
44c86e8c
NC
299 {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
300 {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
301 {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
302 {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
303
b18c562e
NC
304 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
305 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
306 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
307 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
308 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
309 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
310 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
311 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
312 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
313
314 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
315 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
316 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
317 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
3b260895
NC
318
319 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
320 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
321 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
c05e9f04 322
3b260895
NC
323 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
324 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
325 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
326
c05e9f04
NC
327 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
328 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
329 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
330
b18c562e
NC
331 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
332 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
333 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
334 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
335 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
336 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
2469cfa2
NC
337
338 {NULL, 0, 0}
339};
340
341
342static struct mcu_type_s default_mcu =
343 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
344
b18c562e
NC
345static struct mcu_type_s * msp430_mcu = & default_mcu;
346
347/* Profiling capability:
348 It is a performance hit to use gcc's profiling approach for this tiny target.
349 Even more -- jtag hardware facility does not perform any profiling functions.
350 However we've got gdb's built-in simulator where we can do anything.
351 Therefore my suggestion is:
352
353 We define new section ".profiler" which holds all profiling information.
354 We define new pseudo operation .profiler which will instruct assembler to
355 add new profile entry to the object file. Profile should take place at the
356 present address.
357
358 Pseudo-op format:
359
360 .profiler flags,function_to_profile [, cycle_corrector, extra]
361
362 where 'flags' is a combination of the following chars:
363 s - function Start
364 x - function eXit
365 i - function is in Init section
366 f - function is in Fini section
367 l - Library call
368 c - libC standard call
369 d - stack value Demand (saved at run-time in simulator)
370 I - Interrupt service routine
371 P - Prologue start
372 p - Prologue end
373 E - Epilogue start
374 e - Epilogue end
375 j - long Jump/ sjlj unwind
376 a - an Arbitrary code fragment
377 t - exTra parameter saved (constant value like frame size)
378 '""' optional: "sil" == sil
379
380 function_to_profile - function's address
381 cycle_corrector - a value which should be added to the cycle
382 counter, zero if omitted
383 extra - some extra parameter, zero if omitted.
384
385 For example:
386 ------------------------------
387 .global fxx
388 .type fxx,@function
389 fxx:
390 .LFrameOffset_fxx=0x08
391 .profiler "scdP", fxx ; function entry.
392 ; we also demand stack value to be displayed
393 push r11
394 push r10
395 push r9
396 push r8
397 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
398 ; (this is a prologue end)
399 ; note, that spare var filled with the farme size
400 mov r15,r8
401 ....
402 .profiler cdE,fxx ; check stack
403 pop r8
404 pop r9
405 pop r10
406 pop r11
407 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
408 ret ; cause 'ret' insn takes 3 cycles
409 -------------------------------
410
411 This profiling approach does not produce any overhead and
412 absolutely harmless.
413 So, even profiled code can be uploaded to the MCU. */
414#define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
415#define MSP430_PROFILER_FLAG_EXIT 2 /* x */
416#define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
417#define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
418#define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
419#define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
420#define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
421#define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
422#define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
423#define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
424#define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
425#define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
426#define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
427#define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
428#define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
429#define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
2469cfa2 430
b18c562e
NC
431static int
432pow2value (int y)
2469cfa2 433{
b18c562e
NC
434 int n = 0;
435 unsigned int x;
2469cfa2 436
b18c562e 437 x = y;
2469cfa2 438
b18c562e
NC
439 if (!x)
440 return 1;
2469cfa2 441
b18c562e
NC
442 for (; x; x = x >> 1)
443 if (x & 1)
444 n++;
445
446 return n == 1;
447}
448
449/* Parse ordinary expression. */
450
451static char *
452parse_exp (char * s, expressionS * op)
2469cfa2 453{
b18c562e
NC
454 input_line_pointer = s;
455 expression (op);
456 if (op->X_op == O_absent)
457 as_bad (_("missing operand"));
458 return input_line_pointer;
459}
2469cfa2 460
b18c562e
NC
461
462/* Delete spaces from s: X ( r 1 2) => X(r12). */
2469cfa2
NC
463
464static void
b18c562e 465del_spaces (char * s)
2469cfa2 466{
b18c562e
NC
467 while (*s)
468 {
469 if (ISSPACE (*s))
470 {
471 char *m = s + 1;
2469cfa2 472
b18c562e
NC
473 while (ISSPACE (*m) && *m)
474 m++;
475 memmove (s, m, strlen (m) + 1);
476 }
477 else
478 s++;
479 }
480}
2469cfa2 481
b18c562e
NC
482static inline char *
483skip_space (char * s)
484{
485 while (ISSPACE (*s))
486 ++s;
487 return s;
488}
2469cfa2 489
b18c562e
NC
490/* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
491
492static char *
493extract_operand (char * from, char * to, int limit)
494{
495 int size = 0;
496
497 /* Drop leading whitespace. */
498 from = skip_space (from);
499
500 while (size < limit && *from)
501 {
502 *(to + size) = *from;
503 if (*from == ',' || *from == ';' || *from == '\n')
504 break;
505 from++;
506 size++;
507 }
508
509 *(to + size) = 0;
510 del_spaces (to);
511
512 from++;
513
514 return from;
2469cfa2
NC
515}
516
b18c562e
NC
517static void
518msp430_profiler (int dummy ATTRIBUTE_UNUSED)
2469cfa2 519{
b18c562e
NC
520 char buffer[1024];
521 char f[32];
522 char * str = buffer;
523 char * flags = f;
524 int p_flags = 0;
525 char * halt;
526 int ops = 0;
527 int left;
528 char * s;
529 segT seg;
530 int subseg;
531 char * end = 0;
532 expressionS exp;
533 expressionS exp1;
534
535 s = input_line_pointer;
536 end = input_line_pointer;
537
538 while (*end && *end != '\n')
539 end++;
540
541 while (*s && *s != '\n')
542 {
543 if (*s == ',')
544 ops++;
545 s++;
546 }
2469cfa2 547
b18c562e
NC
548 left = 3 - ops;
549
550 if (ops < 1)
551 {
552 as_bad (_(".profiler pseudo requires at least two operands."));
553 input_line_pointer = end;
554 return;
555 }
556
557 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
558
559 while (*flags)
560 {
561 switch (*flags)
562 {
563 case '"':
564 break;
565 case 'a':
566 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
567 break;
568 case 'j':
569 p_flags |= MSP430_PROFILER_FLAG_JUMP;
570 break;
571 case 'P':
572 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
573 break;
574 case 'p':
575 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
576 break;
577 case 'E':
578 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
579 break;
580 case 'e':
581 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
582 break;
583 case 's':
584 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
585 break;
586 case 'x':
587 p_flags |= MSP430_PROFILER_FLAG_EXIT;
588 break;
589 case 'i':
590 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
591 break;
592 case 'f':
593 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
594 break;
595 case 'l':
596 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
597 break;
598 case 'c':
599 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
600 break;
601 case 'd':
602 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
603 break;
604 case 'I':
605 p_flags |= MSP430_PROFILER_FLAG_ISR;
606 break;
607 case 't':
608 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
609 break;
610 default:
611 as_warn (_("unknown profiling flag - ignored."));
612 break;
613 }
614 flags++;
615 }
616
617 if (p_flags
618 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
619 | MSP430_PROFILER_FLAG_EXIT))
620 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
621 | MSP430_PROFILER_FLAG_PROLEND
622 | MSP430_PROFILER_FLAG_EPISTART
623 | MSP430_PROFILER_FLAG_EPIEND))
624 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
625 | MSP430_PROFILER_FLAG_FINISECT))))
626 {
627 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
628 input_line_pointer = end;
629 return;
630 }
631
632 /* Generate temp symbol which denotes current location. */
633 if (now_seg == absolute_section) /* Paranoja ? */
634 {
635 exp1.X_op = O_constant;
636 exp1.X_add_number = abs_section_offset;
637 as_warn (_("profiling in absolute section? Hm..."));
638 }
639 else
640 {
641 exp1.X_op = O_symbol;
642 exp1.X_add_symbol = symbol_temp_new_now ();
643 exp1.X_add_number = 0;
644 }
645
646 /* Generate a symbol which holds flags value. */
647 exp.X_op = O_constant;
648 exp.X_add_number = p_flags;
649
650 /* Save current section. */
651 seg = now_seg;
652 subseg = now_subseg;
653
654 /* Now go to .profiler section. */
655 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
656
657 /* Save flags. */
658 emit_expr (& exp, 2);
659
660 /* Save label value. */
661 emit_expr (& exp1, 2);
662
663 while (ops--)
664 {
665 /* Now get profiling info. */
666 halt = extract_operand (input_line_pointer, str, 1024);
667 /* Process like ".word xxx" directive. */
668 parse_exp (str, & exp);
669 emit_expr (& exp, 2);
670 input_line_pointer = halt;
671 }
672
673 /* Fill the rest with zeros. */
674 exp.X_op = O_constant;
675 exp.X_add_number = 0;
676 while (left--)
677 emit_expr (& exp, 2);
678
679 /* Return to current section. */
680 subseg_set (seg, subseg);
2469cfa2
NC
681}
682
683static char *
b18c562e 684extract_word (char * from, char * to, int limit)
2469cfa2
NC
685{
686 char *op_start;
687 char *op_end;
688 int size = 0;
689
690 /* Drop leading whitespace. */
691 from = skip_space (from);
692 *to = 0;
693
694 /* Find the op code end. */
695 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
696 {
697 to[size++] = *op_end++;
698 if (size + 1 >= limit)
699 break;
700 }
701
702 to[size] = 0;
703 return op_end;
704}
705
b18c562e 706#define OPTION_MMCU 'm'
77592908
DD
707#define OPTION_RELAX 'Q'
708#define OPTION_POLYMORPHS 'P'
b18c562e 709
2469cfa2 710static void
b18c562e 711msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
2469cfa2
NC
712{
713 char *str = (char *) alloca (32); /* 32 for good measure. */
714
715 input_line_pointer = extract_word (input_line_pointer, str, 32);
716
717 md_parse_option (OPTION_MMCU, str);
718 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
719}
720
b18c562e
NC
721static void
722show_mcu_list (FILE * stream)
723{
724 int i;
725
726 fprintf (stream, _("Known MCU names:\n"));
727
728 for (i = 0; mcu_types[i].name; i++)
729 fprintf (stream, _("\t %s\n"), mcu_types[i].name);
730
731 fprintf (stream, "\n");
732}
733
2469cfa2 734int
b18c562e 735md_parse_option (int c, char * arg)
2469cfa2
NC
736{
737 int i;
738
739 switch (c)
740 {
741 case OPTION_MMCU:
742 for (i = 0; mcu_types[i].name; ++i)
743 if (strcmp (mcu_types[i].name, arg) == 0)
744 break;
745
746 if (!mcu_types[i].name)
747 {
748 show_mcu_list (stderr);
749 as_fatal (_("unknown MCU: %s\n"), arg);
750 }
751
752 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
753 msp430_mcu = &mcu_types[i];
754 else
755 as_fatal (_("redefinition of mcu type %s' to %s'"),
756 msp430_mcu->name, mcu_types[i].name);
757 return 1;
77592908
DD
758 break;
759
760 case OPTION_RELAX:
761 msp430_enable_relax = 1;
762 return 1;
763 break;
764
765 case OPTION_POLYMORPHS:
766 msp430_enable_polys = 1;
767 return 1;
768 break;
2469cfa2
NC
769 }
770
771 return 0;
772}
773
2469cfa2 774
b18c562e 775const pseudo_typeS md_pseudo_table[] =
2469cfa2 776{
b18c562e
NC
777 {"arch", msp430_set_arch, 0},
778 {"profiler", msp430_profiler, 0},
779 {NULL, NULL, 0}
780};
2469cfa2 781
b18c562e 782const char *md_shortopts = "m:";
2469cfa2 783
b18c562e 784struct option md_longopts[] =
2469cfa2 785{
b18c562e 786 {"mmcu", required_argument, NULL, OPTION_MMCU},
77592908
DD
787 {"mP", no_argument, NULL, OPTION_POLYMORPHS},
788 {"mQ", no_argument, NULL, OPTION_RELAX},
b18c562e
NC
789 {NULL, no_argument, NULL, 0}
790};
2469cfa2 791
b18c562e 792size_t md_longopts_size = sizeof (md_longopts);
2469cfa2 793
b18c562e
NC
794void
795md_show_usage (FILE * stream)
2469cfa2 796{
b18c562e
NC
797 fprintf (stream,
798 _("MSP430 options:\n"
799 " -mmcu=[msp430-name] select microcontroller type\n"
800 " msp430x110 msp430x112\n"
801 " msp430x1101 msp430x1111\n"
802 " msp430x1121 msp430x1122 msp430x1132\n"
803 " msp430x122 msp430x123\n"
804 " msp430x1222 msp430x1232\n"
805 " msp430x133 msp430x135\n"
806 " msp430x1331 msp430x1351\n"
807 " msp430x147 msp430x148 msp430x149\n"
808 " msp430x155 msp430x156 msp430x157\n"
809 " msp430x167 msp430x168 msp430x169\n"
810 " msp430x1610 msp430x1611 msp430x1612\n"
811 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
812 " msp430x323 msp430x325\n"
813 " msp430x336 msp430x337\n"
814 " msp430x412 msp430x413 msp430x415 msp430x417\n"
815 " msp430xE423 msp430xE425 msp430E427\n"
816 " msp430xW423 msp430xW425 msp430W427\n"
817 " msp430xG437 msp430xG438 msp430G439\n"
818 " msp430x435 msp430x436 msp430x437\n"
819 " msp430x447 msp430x448 msp430x449\n"));
77592908
DD
820 fprintf (stream,
821 _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
822 " -mP - enable polymorph instructions\n"));
2469cfa2 823
b18c562e
NC
824 show_mcu_list (stream);
825}
2469cfa2 826
b18c562e
NC
827symbolS *
828md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
829{
830 return 0;
2469cfa2
NC
831}
832
833static char *
b18c562e 834extract_cmd (char * from, char * to, int limit)
2469cfa2
NC
835{
836 int size = 0;
837
838 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
839 {
840 *(to + size) = *from;
841 from++;
842 size++;
843 }
844
845 *(to + size) = 0;
846
847 return from;
848}
849
850/* Turn a string in input_line_pointer into a floating point constant
851 of type TYPE, and store the appropriate bytes in *LITP. The number
852 of LITTLENUMS emitted is stored in *SIZEP. An error message is
853 returned, or NULL on OK. */
854
855char *
b18c562e 856md_atof (int type, char * litP, int * sizeP)
2469cfa2
NC
857{
858 int prec;
859 LITTLENUM_TYPE words[4];
860 LITTLENUM_TYPE *wordP;
861 char *t;
862
863 switch (type)
864 {
865 case 'f':
866 prec = 2;
867 break;
868 case 'd':
869 prec = 4;
870 break;
871 default:
872 *sizeP = 0;
873 return _("bad call to md_atof");
874 }
875
876 t = atof_ieee (input_line_pointer, type, words);
877 if (t)
878 input_line_pointer = t;
879
880 *sizeP = prec * sizeof (LITTLENUM_TYPE);
881
882 /* This loop outputs the LITTLENUMs in REVERSE order. */
883 for (wordP = words + prec - 1; prec--;)
884 {
885 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
886 litP += sizeof (LITTLENUM_TYPE);
887 }
888
889 return NULL;
890}
891
892void
b18c562e 893md_begin (void)
2469cfa2 894{
b18c562e 895 struct msp430_opcode_s * opcode;
2469cfa2
NC
896 msp430_hash = hash_new ();
897
898 for (opcode = msp430_opcodes; opcode->name; opcode++)
899 hash_insert (msp430_hash, opcode->name, (char *) opcode);
900
901 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
902}
903
b18c562e
NC
904static int
905check_reg (char * t)
2469cfa2 906{
b18c562e 907 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
2469cfa2 908
b18c562e
NC
909 if (strlen (t) > 2 && *(t + 2) != '+')
910 return 1;
2469cfa2 911
b18c562e 912 while (*t)
2469cfa2 913 {
b18c562e
NC
914 if ((*t < '0' || *t > '9') && *t != '+')
915 break;
916 t++;
2469cfa2
NC
917 }
918
b18c562e
NC
919 if (*t)
920 return 1;
2469cfa2 921
b18c562e 922 return 0;
2469cfa2
NC
923}
924
2469cfa2 925
b18c562e
NC
926static int
927msp430_srcoperand (struct msp430_operand_s * op,
928 char * l, int bin, int * imm_op)
2469cfa2 929{
b18c562e 930 char *__tl = l;
2469cfa2 931
b18c562e
NC
932 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
933 if (*l == '#')
2469cfa2 934 {
b18c562e
NC
935 char *h = l;
936 int vshift = -1;
937 int rval = 0;
2469cfa2 938
b18c562e
NC
939 /* Check if there is:
940 llo(x) - least significant 16 bits, x &= 0xffff
941 lhi(x) - x = (x >> 16) & 0xffff,
942 hlo(x) - x = (x >> 32) & 0xffff,
943 hhi(x) - x = (x >> 48) & 0xffff
944 The value _MUST_ be constant expression: #hlo(1231231231). */
2469cfa2 945
b18c562e 946 *imm_op = 1;
2469cfa2 947
b18c562e
NC
948 if (strncasecmp (h, "#llo(", 5) == 0)
949 {
950 vshift = 0;
951 rval = 3;
952 }
953 else if (strncasecmp (h, "#lhi(", 5) == 0)
954 {
955 vshift = 1;
956 rval = 3;
957 }
958 else if (strncasecmp (h, "#hlo(", 5) == 0)
959 {
960 vshift = 2;
961 rval = 3;
962 }
963 else if (strncasecmp (h, "#hhi(", 5) == 0)
964 {
965 vshift = 3;
966 rval = 3;
967 }
968 else if (strncasecmp (h, "#lo(", 4) == 0)
969 {
970 vshift = 0;
971 rval = 2;
972 }
973 else if (strncasecmp (h, "#hi(", 4) == 0)
974 {
975 vshift = 1;
976 rval = 2;
977 }
2469cfa2 978
b18c562e
NC
979 op->reg = 0; /* Reg PC. */
980 op->am = 3;
981 op->ol = 1; /* Immediate will follow an instruction. */
982 __tl = h + 1 + rval;
983 op->mode = OP_EXP;
2469cfa2 984
b18c562e
NC
985 parse_exp (__tl, &(op->exp));
986 if (op->exp.X_op == O_constant)
2469cfa2 987 {
b18c562e 988 int x = op->exp.X_add_number;
2469cfa2 989
b18c562e 990 if (vshift == 0)
2469cfa2 991 {
b18c562e
NC
992 x = x & 0xffff;
993 op->exp.X_add_number = x;
994 }
995 else if (vshift == 1)
996 {
997 x = (x >> 16) & 0xffff;
998 op->exp.X_add_number = x;
999 }
1000 else if (vshift > 1)
1001 {
1002 if (x < 0)
1003 op->exp.X_add_number = -1;
2469cfa2 1004 else
b18c562e
NC
1005 op->exp.X_add_number = 0; /* Nothing left. */
1006 x = op->exp.X_add_number;
2469cfa2 1007 }
2469cfa2 1008
b18c562e
NC
1009 if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
1010 {
1011 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
1012 return 1;
1013 }
2469cfa2 1014
b18c562e
NC
1015 /* Now check constants. */
1016 /* Substitute register mode with a constant generator if applicable. */
2469cfa2 1017
b18c562e 1018 x = (short) x; /* Extend sign. */
2469cfa2 1019
b18c562e 1020 if (x == 0)
2469cfa2 1021 {
b18c562e
NC
1022 op->reg = 3;
1023 op->am = 0;
1024 op->ol = 0;
1025 op->mode = OP_REG;
1026 }
1027 else if (x == 1)
1028 {
1029 op->reg = 3;
1030 op->am = 1;
1031 op->ol = 0;
1032 op->mode = OP_REG;
1033 }
1034 else if (x == 2)
1035 {
1036 op->reg = 3;
1037 op->am = 2;
1038 op->ol = 0;
1039 op->mode = OP_REG;
1040 }
1041 else if (x == -1)
1042 {
1043 op->reg = 3;
1044 op->am = 3;
1045 op->ol = 0;
1046 op->mode = OP_REG;
1047 }
1048 else if (x == 4)
1049 {
1050#ifdef PUSH_1X_WORKAROUND
1051 if (bin == 0x1200)
1052 {
1053 /* Remove warning as confusing.
1054 as_warn(_("Hardware push bug workaround")); */
1055 }
1056 else
1057#endif
1058 {
1059 op->reg = 2;
1060 op->am = 2;
1061 op->ol = 0;
1062 op->mode = OP_REG;
1063 }
1064 }
1065 else if (x == 8)
1066 {
1067#ifdef PUSH_1X_WORKAROUND
1068 if (bin == 0x1200)
1069 {
1070 /* Remove warning as confusing.
1071 as_warn(_("Hardware push bug workaround")); */
1072 }
1073 else
1074#endif
1075 {
1076 op->reg = 2;
1077 op->am = 3;
1078 op->ol = 0;
1079 op->mode = OP_REG;
1080 }
2469cfa2 1081 }
2469cfa2 1082 }
b18c562e
NC
1083 else if (op->exp.X_op == O_symbol)
1084 {
1085 op->mode = OP_EXP;
1086 }
1087 else if (op->exp.X_op == O_big)
1088 {
1089 short x;
1090 if (vshift != -1)
1091 {
1092 op->exp.X_op = O_constant;
1093 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
1094 x = op->exp.X_add_number;
1095 }
1096 else
1097 {
1098 as_bad (_
1099 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
1100 l);
1101 return 1;
1102 }
2469cfa2 1103
b18c562e
NC
1104 if (x == 0)
1105 {
1106 op->reg = 3;
1107 op->am = 0;
1108 op->ol = 0;
1109 op->mode = OP_REG;
1110 }
1111 else if (x == 1)
1112 {
1113 op->reg = 3;
1114 op->am = 1;
1115 op->ol = 0;
1116 op->mode = OP_REG;
1117 }
1118 else if (x == 2)
1119 {
1120 op->reg = 3;
1121 op->am = 2;
1122 op->ol = 0;
1123 op->mode = OP_REG;
1124 }
1125 else if (x == -1)
1126 {
1127 op->reg = 3;
1128 op->am = 3;
1129 op->ol = 0;
1130 op->mode = OP_REG;
1131 }
1132 else if (x == 4)
1133 {
1134 op->reg = 2;
1135 op->am = 2;
1136 op->ol = 0;
1137 op->mode = OP_REG;
1138 }
1139 else if (x == 8)
1140 {
1141 op->reg = 2;
1142 op->am = 3;
1143 op->ol = 0;
1144 op->mode = OP_REG;
1145 }
1146 }
1147 /* Redudant (yet) check. */
1148 else if (op->exp.X_op == O_register)
1149 as_bad
1150 (_("Registers cannot be used within immediate expression [%s]"), l);
1151 else
1152 as_bad (_("unknown operand %s"), l);
2469cfa2 1153
b18c562e
NC
1154 return 0;
1155 }
2469cfa2 1156
b18c562e
NC
1157 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
1158 if (*l == '&')
1159 {
1160 char *h = l;
2469cfa2 1161
b18c562e
NC
1162 op->reg = 2; /* reg 2 in absolute addr mode. */
1163 op->am = 1; /* mode As == 01 bin. */
1164 op->ol = 1; /* Immediate value followed by instruction. */
1165 __tl = h + 1;
1166 parse_exp (__tl, &(op->exp));
1167 op->mode = OP_EXP;
1168 if (op->exp.X_op == O_constant)
2469cfa2 1169 {
b18c562e 1170 int x = op->exp.X_add_number;
2469cfa2 1171
b18c562e
NC
1172 if (x > 65535 || x < -32768)
1173 {
1174 as_bad (_("value out of range: %d"), x);
1175 return 1;
1176 }
2469cfa2 1177 }
b18c562e
NC
1178 else if (op->exp.X_op == O_symbol)
1179 ;
1180 else
2469cfa2 1181 {
b18c562e
NC
1182 /* Redudant (yet) check. */
1183 if (op->exp.X_op == O_register)
1184 as_bad
1185 (_("Registers cannot be used within absolute expression [%s]"), l);
2469cfa2 1186 else
b18c562e
NC
1187 as_bad (_("unknown expression in operand %s"), l);
1188 return 1;
2469cfa2 1189 }
b18c562e
NC
1190 return 0;
1191 }
2469cfa2 1192
b18c562e
NC
1193 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1194 if (*l == '@')
1195 {
1196 char *t = l;
1197 char *m = strchr (l, '+');
1198
1199 if (t != l)
2469cfa2 1200 {
b18c562e
NC
1201 as_bad (_("unknown addressing mode %s"), l);
1202 return 1;
2469cfa2
NC
1203 }
1204
b18c562e
NC
1205 t++;
1206 if (*t != 'r' && *t != 'R')
1207 {
1208 as_bad (_("unknown addressing mode %s"), l);
1209 return 1;
1210 }
2469cfa2 1211
b18c562e 1212 t++; /* Points to the reg value. */
2469cfa2 1213
b18c562e 1214 if (check_reg (t))
2469cfa2 1215 {
b18c562e
NC
1216 as_bad (_("Bad register name r%s"), t);
1217 return 1;
2469cfa2 1218 }
2469cfa2 1219
b18c562e
NC
1220 op->mode = OP_REG;
1221 op->am = m ? 3 : 2;
1222 op->ol = 0;
1223 if (m)
1224 *m = 0; /* strip '+' */
1225 op->reg = atoi (t);
1226 if (op->reg < 0 || op->reg > 15)
2469cfa2 1227 {
b18c562e
NC
1228 as_bad (_("MSP430 does not have %d registers"), op->reg);
1229 return 1;
1230 }
2469cfa2 1231
b18c562e
NC
1232 return 0;
1233 }
2469cfa2 1234
b18c562e
NC
1235 /* Check if register indexed X(Rn). */
1236 do
1237 {
1238 char *h = strrchr (l, '(');
1239 char *m = strrchr (l, ')');
1240 char *t;
2469cfa2 1241
b18c562e 1242 *imm_op = 1;
2469cfa2 1243
b18c562e
NC
1244 if (!h)
1245 break;
1246 if (!m)
1247 {
1248 as_bad (_("')' required"));
1249 return 1;
1250 }
2469cfa2 1251
b18c562e
NC
1252 t = h;
1253 op->am = 1;
1254 op->ol = 1;
1255 /* Extract a register. */
1256 t++; /* Advance pointer. */
2469cfa2 1257
b18c562e
NC
1258 if (*t != 'r' && *t != 'R')
1259 {
1260 as_bad (_
1261 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1262 l);
1263 return 1;
1264 }
1265 t++;
2469cfa2 1266
b18c562e
NC
1267 op->reg = *t - '0';
1268 if (op->reg > 9 || op->reg < 0)
1269 {
1270 as_bad (_("unknown operator (r%s substituded as a register name"),
1271 t);
1272 return 1;
1273 }
1274 t++;
1275 if (*t != ')')
1276 {
1277 op->reg = op->reg * 10;
1278 op->reg += *t - '0';
2469cfa2 1279
b18c562e 1280 if (op->reg > 15)
2469cfa2 1281 {
b18c562e
NC
1282 as_bad (_("unknown operator %s"), l);
1283 return 1;
2469cfa2 1284 }
b18c562e 1285 if (op->reg == 2)
2469cfa2 1286 {
b18c562e
NC
1287 as_bad (_("r2 should not be used in indexed addressing mode"));
1288 return 1;
1289 }
2469cfa2 1290
b18c562e
NC
1291 if (*(t + 1) != ')')
1292 {
1293 as_bad (_("unknown operator %s"), l);
1294 return 1;
2469cfa2 1295 }
b18c562e
NC
1296 }
1297
1298 /* Extract constant. */
1299 __tl = l;
1300 *h = 0;
1301 op->mode = OP_EXP;
1302 parse_exp (__tl, &(op->exp));
1303 if (op->exp.X_op == O_constant)
1304 {
1305 int x = op->exp.X_add_number;
1306
1307 if (x > 65535 || x < -32768)
2469cfa2 1308 {
b18c562e
NC
1309 as_bad (_("value out of range: %d"), x);
1310 return 1;
2469cfa2 1311 }
b18c562e
NC
1312
1313 if (x == 0)
2469cfa2 1314 {
b18c562e
NC
1315 op->mode = OP_REG;
1316 op->am = 2;
1317 op->ol = 0;
1318 return 0;
2469cfa2
NC
1319 }
1320 }
b18c562e
NC
1321 else if (op->exp.X_op == O_symbol)
1322 ;
2469cfa2
NC
1323 else
1324 {
b18c562e
NC
1325 /* Redudant (yet) check. */
1326 if (op->exp.X_op == O_register)
1327 as_bad
1328 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1329 else
1330 as_bad (_("unknown expression in operand %s"), l);
1331 return 1;
2469cfa2 1332 }
2469cfa2 1333
b18c562e 1334 return 0;
2469cfa2 1335 }
b18c562e 1336 while (0);
2469cfa2 1337
b18c562e
NC
1338 /* Register mode 'mov r1,r2'. */
1339 do
1340 {
1341 char *t = l;
1342
1343 /* Operand should be a register. */
1344 if (*t == 'r' || *t == 'R')
1345 {
1346 int x = atoi (t + 1);
1347
1348 if (check_reg (t + 1))
1349 break;
1350
1351 if (x < 0 || x > 15)
1352 break; /* Symbolic mode. */
1353
1354 op->mode = OP_REG;
1355 op->am = 0;
1356 op->ol = 0;
1357 op->reg = x;
1358 return 0;
1359 }
1360 }
1361 while (0);
1362
1363 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1364 do
1365 {
b18c562e
NC
1366 op->mode = OP_EXP;
1367 op->reg = 0; /* PC relative... be careful. */
1368 op->am = 1;
1369 op->ol = 1;
1370 __tl = l;
1371 parse_exp (__tl, &(op->exp));
1372 return 0;
1373 }
1374 while (0);
1375
1376 /* Unreachable. */
1377 as_bad (_("unknown addressing mode for operand %s"), l);
1378 return 1;
2469cfa2
NC
1379}
1380
b18c562e 1381
2469cfa2 1382static int
b18c562e 1383msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
2469cfa2
NC
1384{
1385 int dummy;
b18c562e
NC
1386 int ret = msp430_srcoperand (op, l, bin, & dummy);
1387
2469cfa2
NC
1388 if (ret)
1389 return ret;
1390
1391 if (op->am == 2)
1392 {
1393 char *__tl = "0";
1394
1395 op->mode = OP_EXP;
1396 op->am = 1;
1397 op->ol = 1;
1398 parse_exp (__tl, &(op->exp));
b18c562e 1399
2469cfa2
NC
1400 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1401 {
1402 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1403 op->reg, op->reg);
1404 return 1;
1405 }
1406 return 0;
1407 }
1408
1409 if (op->am > 1)
1410 {
1411 as_bad (_
1412 ("this addressing mode is not applicable for destination operand"));
1413 return 1;
1414 }
1415 return 0;
1416}
1417
1418
b18c562e
NC
1419/* Parse instruction operands.
1420 Return binary opcode. */
1421
1422static unsigned int
1423msp430_operands (struct msp430_opcode_s * opcode, char * line)
2469cfa2 1424{
b18c562e 1425 int bin = opcode->bin_opcode; /* Opcode mask. */
2a9a06c1 1426 int __is = 0;
b18c562e
NC
1427 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1428 char *frag;
1429 int where;
1430 struct msp430_operand_s op1, op2;
1431 int res = 0;
1432 static short ZEROS = 0;
1433 int byte_op, imm_op;
2469cfa2 1434
b18c562e
NC
1435 /* Opcode is the one from opcodes table
1436 line contains something like
1437 [.w] @r2+, 5(R1)
1438 or
1439 .b @r2+, 5(R1). */
2469cfa2 1440
b18c562e
NC
1441 /* Check if byte or word operation. */
1442 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
2469cfa2 1443 {
b18c562e
NC
1444 bin |= BYTE_OPERATION;
1445 byte_op = 1;
2469cfa2 1446 }
b18c562e
NC
1447 else
1448 byte_op = 0;
2469cfa2 1449
b18c562e
NC
1450 /* skip .[bwBW]. */
1451 while (! ISSPACE (*line) && *line)
1452 line++;
2469cfa2 1453
b18c562e 1454 if (opcode->insn_opnumb && (!*line || *line == '\n'))
2469cfa2 1455 {
b18c562e
NC
1456 as_bad (_("instruction %s requires %d operand(s)"),
1457 opcode->name, opcode->insn_opnumb);
1458 return 0;
1459 }
2469cfa2 1460
b18c562e
NC
1461 memset (l1, 0, sizeof (l1));
1462 memset (l2, 0, sizeof (l2));
1463 memset (&op1, 0, sizeof (op1));
1464 memset (&op2, 0, sizeof (op2));
2469cfa2 1465
b18c562e 1466 imm_op = 0;
2469cfa2 1467
b18c562e
NC
1468 switch (opcode->fmt)
1469 {
1470 case 0: /* Emulated. */
1471 switch (opcode->insn_opnumb)
2469cfa2 1472 {
b18c562e
NC
1473 case 0:
1474 /* Set/clear bits instructions. */
1475 __is = 2;
1476 frag = frag_more (__is);
1477 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1478 dwarf2_emit_insn (__is);
b18c562e
NC
1479 break;
1480 case 1:
1481 /* Something which works with destination operand. */
1482 line = extract_operand (line, l1, sizeof (l1));
1483 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1484 if (res)
1485 break;
2469cfa2 1486
b18c562e
NC
1487 bin |= (op1.reg | (op1.am << 7));
1488 __is = 1 + op1.ol;
1489 frag = frag_more (2 * __is);
1490 where = frag - frag_now->fr_literal;
1491 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1492 dwarf2_emit_insn (2 * __is);
2469cfa2 1493
b18c562e 1494 if (op1.mode == OP_EXP)
2469cfa2 1495 {
b18c562e
NC
1496 where += 2;
1497 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1498
1499 if (op1.reg)
1500 fix_new_exp (frag_now, where, 2,
1501 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2469cfa2 1502 else
b18c562e
NC
1503 fix_new_exp (frag_now, where, 2,
1504 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1505 }
b18c562e 1506 break;
2469cfa2 1507
b18c562e
NC
1508 case 2:
1509 {
1510 /* Shift instruction. */
1511 line = extract_operand (line, l1, sizeof (l1));
1512 strncpy (l2, l1, sizeof (l2));
1513 l2[sizeof (l2) - 1] = '\0';
1514 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1515 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2469cfa2 1516
b18c562e
NC
1517 if (res)
1518 break; /* An error occurred. All warnings were done before. */
2469cfa2 1519
b18c562e 1520 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
2469cfa2 1521
b18c562e
NC
1522 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1523 frag = frag_more (2 * __is);
1524 where = frag - frag_now->fr_literal;
1525 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1
DD
1526 dwarf2_emit_insn (2 * __is);
1527
b18c562e
NC
1528 if (op1.mode == OP_EXP)
1529 {
1530 where += 2; /* Advance 'where' as we do not know _where_. */
1531 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1532
1533 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1534 fix_new_exp (frag_now, where, 2,
1535 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1536 else
1537 fix_new_exp (frag_now, where, 2,
1538 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1539 }
1540
1541 if (op2.mode == OP_EXP)
1542 {
1543 imm_op = 0;
1544 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1545
1546 if (op2.reg) /* Not PC relative. */
1547 fix_new_exp (frag_now, where + 2, 2,
1548 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1549 else
1550 fix_new_exp (frag_now, where + 2, 2,
1551 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1552 }
1553 break;
1554 }
1555 case 3:
1556 /* Branch instruction => mov dst, r0. */
1557 line = extract_operand (line, l1, sizeof (l1));
1558
1559 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1560 if (res)
1561 break;
1562
1563 byte_op = 0;
1564 imm_op = 0;
1565
1566 bin |= ((op1.reg << 8) | (op1.am << 4));
1567 __is = 1 + op1.ol;
1568 frag = frag_more (2 * __is);
1569 where = frag - frag_now->fr_literal;
1570 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1571 dwarf2_emit_insn (2 * __is);
b18c562e
NC
1572
1573 if (op1.mode == OP_EXP)
2469cfa2 1574 {
b18c562e
NC
1575 where += 2;
1576 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1577
1578 if (op1.reg || (op1.reg == 0 && op1.am == 3))
1579 fix_new_exp (frag_now, where, 2,
1580 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
2469cfa2 1581 else
b18c562e
NC
1582 fix_new_exp (frag_now, where, 2,
1583 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1584 }
b18c562e 1585 break;
2469cfa2 1586 }
b18c562e 1587 break;
2469cfa2 1588
b18c562e
NC
1589 case 1: /* Format 1, double operand. */
1590 line = extract_operand (line, l1, sizeof (l1));
1591 line = extract_operand (line, l2, sizeof (l2));
1592 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1593 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2469cfa2 1594
b18c562e
NC
1595 if (res)
1596 break; /* Error occurred. All warnings were done before. */
2469cfa2 1597
b18c562e
NC
1598 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1599
1600 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1601 frag = frag_more (2 * __is);
1602 where = frag - frag_now->fr_literal;
1603 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1604 dwarf2_emit_insn (2 * __is);
b18c562e
NC
1605
1606 if (op1.mode == OP_EXP)
2469cfa2 1607 {
b18c562e
NC
1608 where += 2; /* Advance where as we do not know _where_. */
1609 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1610
1611 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1612 fix_new_exp (frag_now, where, 2,
1613 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1614 else
1615 fix_new_exp (frag_now, where, 2,
1616 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1617 }
b18c562e
NC
1618
1619 if (op2.mode == OP_EXP)
2469cfa2 1620 {
b18c562e
NC
1621 imm_op = 0;
1622 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1623
1624 if (op2.reg) /* Not PC relative. */
1625 fix_new_exp (frag_now, where + 2, 2,
1626 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1627 else
1628 fix_new_exp (frag_now, where + 2, 2,
1629 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1630 }
b18c562e
NC
1631 break;
1632
1633 case 2: /* Single-operand mostly instr. */
1634 if (opcode->insn_opnumb == 0)
2469cfa2 1635 {
b18c562e
NC
1636 /* reti instruction. */
1637 frag = frag_more (2);
1638 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1639 dwarf2_emit_insn (2);
b18c562e 1640 break;
2469cfa2 1641 }
2469cfa2 1642
b18c562e
NC
1643 line = extract_operand (line, l1, sizeof (l1));
1644 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1645 if (res)
1646 break; /* Error in operand. */
2469cfa2 1647
b18c562e
NC
1648 bin |= op1.reg | (op1.am << 4);
1649 __is = 1 + op1.ol;
1650 frag = frag_more (2 * __is);
1651 where = frag - frag_now->fr_literal;
1652 bfd_putl16 ((bfd_vma) bin, frag);
2a9a06c1 1653 dwarf2_emit_insn (2 * __is);
b18c562e
NC
1654
1655 if (op1.mode == OP_EXP)
2469cfa2 1656 {
b18c562e
NC
1657 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1658
1659 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1660 fix_new_exp (frag_now, where + 2, 2,
1661 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1662 else
1663 fix_new_exp (frag_now, where + 2, 2,
1664 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
2469cfa2 1665 }
b18c562e 1666 break;
2469cfa2 1667
b18c562e
NC
1668 case 3: /* Conditional jumps instructions. */
1669 line = extract_operand (line, l1, sizeof (l1));
1670 /* l1 is a label. */
1671 if (l1[0])
2469cfa2 1672 {
b18c562e
NC
1673 char *m = l1;
1674 expressionS exp;
2469cfa2 1675
b18c562e
NC
1676 if (*m == '$')
1677 m++;
2469cfa2 1678
b18c562e
NC
1679 parse_exp (m, &exp);
1680 frag = frag_more (2); /* Instr size is 1 word. */
2469cfa2 1681
b18c562e 1682 /* In order to handle something like:
2469cfa2 1683
b18c562e
NC
1684 and #0x8000, r5
1685 tst r5
1686 jz 4 ; skip next 4 bytes
1687 inv r5
1688 inc r5
1689 nop ; will jump here if r5 positive or zero
2469cfa2 1690
b18c562e 1691 jCOND -n ;assumes jump n bytes backward:
2469cfa2 1692
b18c562e
NC
1693 mov r5,r6
1694 jmp -2
2469cfa2 1695
b18c562e
NC
1696 is equal to:
1697 lab:
1698 mov r5,r6
1699 jmp lab
1700
1701 jCOND $n ; jump from PC in either direction. */
2469cfa2 1702
b18c562e
NC
1703 if (exp.X_op == O_constant)
1704 {
1705 int x = exp.X_add_number;
2469cfa2 1706
b18c562e
NC
1707 if (x & 1)
1708 {
1709 as_warn (_("Even number required. Rounded to %d"), x + 1);
1710 x++;
1711 }
2469cfa2 1712
b18c562e
NC
1713 if ((*l1 == '$' && x > 0) || x < 0)
1714 x -= 2;
2469cfa2 1715
b18c562e
NC
1716 x >>= 1;
1717
1718 if (x > 512 || x < -511)
1719 {
1720 as_bad (_("Wrong displacement %d"), x << 1);
1721 break;
1722 }
1723
1724 bin |= x & 0x3ff;
1725 bfd_putl16 ((bfd_vma) bin, frag);
1726 }
1727 else if (exp.X_op == O_symbol && *l1 != '$')
2469cfa2 1728 {
b18c562e
NC
1729 where = frag - frag_now->fr_literal;
1730 fix_new_exp (frag_now, where, 2,
1731 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1732
1733 bfd_putl16 ((bfd_vma) bin, frag);
2469cfa2 1734 }
b18c562e 1735 else if (*l1 == '$')
2469cfa2 1736 {
b18c562e 1737 as_bad (_("instruction requires label sans '$'"));
2469cfa2 1738 }
b18c562e 1739 else
2469cfa2 1740 {
b18c562e
NC
1741 as_bad (_
1742 ("instruction requires label or value in range -511:512"));
2469cfa2 1743 }
2a9a06c1
DD
1744 dwarf2_emit_insn (2 * __is);
1745 break;
2469cfa2 1746 }
b18c562e
NC
1747 else
1748 {
1749 as_bad (_("instruction requires label"));
1750 break;
1751 }
1752 break;
2469cfa2 1753
b18c562e 1754 case 4: /* Extended jumps. */
77592908
DD
1755 if (!msp430_enable_polys)
1756 {
1757 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1758 break;
1759 }
1760
b18c562e
NC
1761 line = extract_operand (line, l1, sizeof (l1));
1762 if (l1[0])
2469cfa2 1763 {
b18c562e
NC
1764 char *m = l1;
1765 expressionS exp;
2469cfa2 1766
b18c562e
NC
1767 /* Ignore absolute addressing. make it PC relative anyway. */
1768 if (*m == '#' || *m == '$')
1769 m++;
2469cfa2 1770
b18c562e
NC
1771 parse_exp (m, & exp);
1772 if (exp.X_op == O_symbol)
2469cfa2 1773 {
b18c562e
NC
1774 /* Relaxation required. */
1775 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1776
2a9a06c1
DD
1777 /* The parameter to dwarf2_emit_insn is actually the offset to the start
1778 of the insn from the fix piece of instruction that was emitted.
1779 Since next fragments may have variable size we tie debug info
1780 to the beginning of the instruction. */
3e470ab5 1781 frag = frag_more (8);
2a9a06c1 1782 dwarf2_emit_insn (0);
3e470ab5
DD
1783 bfd_putl16 ((bfd_vma) rc.sop, frag);
1784 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
1785 ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
1786 exp.X_add_symbol,
1787 0, /* Offset is zero if jump dist less than 1K. */
1788 (char *) frag);
1789 break;
2469cfa2
NC
1790 }
1791 }
b18c562e
NC
1792
1793 as_bad (_("instruction requires label"));
1794 break;
1795
1796 case 5: /* Emulated extended branches. */
77592908
DD
1797 if (!msp430_enable_polys)
1798 {
1799 as_bad(_("polymorphs are not enabled. Use -mP option to enable."));
1800 break;
1801 }
b18c562e
NC
1802 line = extract_operand (line, l1, sizeof (l1));
1803 if (l1[0])
2469cfa2 1804 {
b18c562e
NC
1805 char * m = l1;
1806 expressionS exp;
1807
1808 /* Ignore absolute addressing. make it PC relative anyway. */
1809 if (*m == '#' || *m == '$')
1810 m++;
1811
1812 parse_exp (m, & exp);
1813 if (exp.X_op == O_symbol)
1814 {
1815 /* Relaxation required. */
1816 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1817
3e470ab5 1818 frag = frag_more (8);
2a9a06c1 1819 dwarf2_emit_insn (0);
3e470ab5
DD
1820 bfd_putl16 ((bfd_vma) hc.op0, frag);
1821 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1822
1823 frag = frag_variant (rs_machine_dependent, 8, 2,
b18c562e
NC
1824 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
1825 exp.X_add_symbol,
1826 0, /* Offset is zero if jump dist less than 1K. */
1827 (char *) frag);
1828 break;
1829 }
2469cfa2
NC
1830 }
1831
b18c562e
NC
1832 as_bad (_("instruction requires label"));
1833 break;
2469cfa2 1834
b18c562e
NC
1835 default:
1836 as_bad (_("Ilegal instruction or not implmented opcode."));
1837 }
2469cfa2 1838
b18c562e
NC
1839 input_line_pointer = line;
1840 return 0;
1841}
2469cfa2 1842
b18c562e
NC
1843void
1844md_assemble (char * str)
1845{
1846 struct msp430_opcode_s * opcode;
1847 char cmd[32];
1848 unsigned int i = 0;
2469cfa2 1849
b18c562e
NC
1850 str = skip_space (str); /* Skip leading spaces. */
1851 str = extract_cmd (str, cmd, sizeof (cmd));
2469cfa2 1852
b18c562e
NC
1853 while (cmd[i] && i < sizeof (cmd))
1854 {
1855 char a = TOLOWER (cmd[i]);
1856 cmd[i] = a;
1857 i++;
2469cfa2 1858 }
2469cfa2 1859
b18c562e 1860 if (!cmd[0])
2469cfa2 1861 {
b18c562e
NC
1862 as_bad (_("can't find opcode "));
1863 return;
1864 }
2469cfa2 1865
b18c562e 1866 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
2469cfa2 1867
b18c562e
NC
1868 if (opcode == NULL)
1869 {
1870 as_bad (_("unknown opcode `%s'"), cmd);
1871 return;
2469cfa2 1872 }
2469cfa2 1873
b18c562e
NC
1874 {
1875 char *__t = input_line_pointer;
2469cfa2 1876
b18c562e
NC
1877 msp430_operands (opcode, str);
1878 input_line_pointer = __t;
1879 }
1880}
2469cfa2
NC
1881
1882/* GAS will call this function for each section at the end of the assembly,
1883 to permit the CPU backend to adjust the alignment of a section. */
1884
1885valueT
b18c562e 1886md_section_align (asection * seg, valueT addr)
2469cfa2
NC
1887{
1888 int align = bfd_get_section_alignment (stdoutput, seg);
1889
1890 return ((addr + (1 << align) - 1) & (-1 << align));
1891}
1892
1893/* If you define this macro, it should return the offset between the
1894 address of a PC relative fixup and the position from which the PC
1895 relative adjustment should be made. On many processors, the base
1896 of a PC relative instruction is the next instruction, so this
1897 macro would return the length of an instruction. */
1898
1899long
b18c562e 1900md_pcrel_from_section (fixS * fixp, segT sec)
2469cfa2
NC
1901{
1902 if (fixp->fx_addsy != (symbolS *) NULL
1903 && (!S_IS_DEFINED (fixp->fx_addsy)
1904 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1905 return 0;
1906
1907 return fixp->fx_frag->fr_address + fixp->fx_where;
1908}
1909
77592908
DD
1910/* Replaces standard TC_FORCE_RELOCATION_LOCAL.
1911 Now it handles the situation when relocations
1912 have to be passed to linker. */
1913int
1914msp430_force_relocation_local(fixS *fixp)
1915{
1916 if (msp430_enable_polys
1917 && !msp430_enable_relax)
1918 return 1;
1919 else
1920 return (!fixp->fx_pcrel
1921 || fixp->fx_plt
1922 || generic_force_reloc(fixp));
1923}
1924
1925
2469cfa2
NC
1926/* GAS will call this for each fixup. It should store the correct
1927 value in the object file. */
2469cfa2 1928void
55cf6793 1929md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
2469cfa2 1930{
b18c562e 1931 unsigned char * where;
2469cfa2
NC
1932 unsigned long insn;
1933 long value;
1934
1935 if (fixp->fx_addsy == (symbolS *) NULL)
1936 {
1937 value = *valuep;
1938 fixp->fx_done = 1;
1939 }
1940 else if (fixp->fx_pcrel)
1941 {
1942 segT s = S_GET_SEGMENT (fixp->fx_addsy);
1943
1944 if (fixp->fx_addsy && (s == seg || s == absolute_section))
1945 {
18af0b39
NC
1946 /* FIXME: We can appear here only in case if we perform a pc
1947 relative jump to the label which is i) global, ii) locally
1948 defined or this is a jump to an absolute symbol.
1949 If this is an absolute symbol -- everything is OK.
1950 If this is a global label, we've got a symbol value defined
1951 twice:
1952 1. S_GET_VALUE (fixp->fx_addsy) will contain a symbol offset
1953 from this section start
1954 2. *valuep will contain the real offset from jump insn to the
1955 label
1956 So, the result of S_GET_VALUE (fixp->fx_addsy) + (* valuep);
1957 will be incorrect. Therefore remove s_get_value. */
1958 value = /* S_GET_VALUE (fixp->fx_addsy) + */ * valuep;
2469cfa2
NC
1959 fixp->fx_done = 1;
1960 }
1961 else
1962 value = *valuep;
1963 }
1964 else
1965 {
1966 value = fixp->fx_offset;
1967
1968 if (fixp->fx_subsy != (symbolS *) NULL)
1969 {
1970 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1971 {
1972 value -= S_GET_VALUE (fixp->fx_subsy);
1973 fixp->fx_done = 1;
1974 }
1975 else
1976 {
1977 /* We don't actually support subtracting a symbol. */
1978 as_bad_where (fixp->fx_file, fixp->fx_line,
1979 _("expression too complex"));
1980 }
1981 }
1982 }
1983
77592908
DD
1984 fixp->fx_no_overflow = 1;
1985
1986 /* if polymorphs are enabled and relax disabled.
1987 do not kill any relocs and pass them to linker. */
1988 if (msp430_enable_polys
1989 && !msp430_enable_relax)
2469cfa2 1990 {
77592908
DD
1991 if (!fixp->fx_addsy || (fixp->fx_addsy
1992 && S_GET_SEGMENT (fixp->fx_addsy) == absolute_section))
1993 fixp->fx_done = 1; /* it is ok to kill 'abs' reloc */
1994 else
1995 fixp->fx_done = 0;
2469cfa2
NC
1996 }
1997
1998 if (fixp->fx_done)
1999 {
2000 /* Fetch the instruction, insert the fully resolved operand
8cd5b113 2001 value, and stuff the instruction back again. */
2469cfa2 2002
2132e3a3 2003 where = (unsigned char *) fixp->fx_frag->fr_literal + fixp->fx_where;
2469cfa2
NC
2004
2005 insn = bfd_getl16 (where);
2006
2007 switch (fixp->fx_r_type)
2008 {
2009 case BFD_RELOC_MSP430_10_PCREL:
2010 if (value & 1)
2011 as_bad_where (fixp->fx_file, fixp->fx_line,
2012 _("odd address operand: %ld"), value);
2013
2014 /* Jumps are in words. */
2015 value >>= 1;
2016 --value; /* Correct PC. */
2017
2018 if (value < -512 || value > 511)
2019 as_bad_where (fixp->fx_file, fixp->fx_line,
2020 _("operand out of range: %ld"), value);
2021
2022 value &= 0x3ff; /* get rid of extended sign */
2023 bfd_putl16 ((bfd_vma) (value | insn), where);
2024 break;
2025
b18c562e 2026 case BFD_RELOC_MSP430_RL_PCREL:
2469cfa2
NC
2027 case BFD_RELOC_MSP430_16_PCREL:
2028 if (value & 1)
2029 as_bad_where (fixp->fx_file, fixp->fx_line,
2030 _("odd address operand: %ld"), value);
2031
2032 /* Nothing to be corrected here. */
2033 if (value < -32768 || value > 65536)
2034 as_bad_where (fixp->fx_file, fixp->fx_line,
2035 _("operand out of range: %ld"), value);
2036
2037 value &= 0xffff; /* Get rid of extended sign. */
2038 bfd_putl16 ((bfd_vma) value, where);
2039 break;
2040
2041 case BFD_RELOC_MSP430_16_PCREL_BYTE:
2042 /* Nothing to be corrected here. */
2043 if (value < -32768 || value > 65536)
2044 as_bad_where (fixp->fx_file, fixp->fx_line,
2045 _("operand out of range: %ld"), value);
2046
2047 value &= 0xffff; /* Get rid of extended sign. */
2048 bfd_putl16 ((bfd_vma) value, where);
2049 break;
2050
2051 case BFD_RELOC_32:
2052 bfd_putl16 ((bfd_vma) value, where);
2053 break;
2054
2055 case BFD_RELOC_MSP430_16:
2056 case BFD_RELOC_16:
2057 case BFD_RELOC_MSP430_16_BYTE:
2058 value &= 0xffff;
2059 bfd_putl16 ((bfd_vma) value, where);
2060 break;
2061
2062 default:
2063 as_fatal (_("line %d: unknown relocation type: 0x%x"),
2064 fixp->fx_line, fixp->fx_r_type);
2065 break;
2066 }
2067 }
2068 else
2069 {
2070 fixp->fx_addnumber = value;
2071 }
2469cfa2
NC
2072}
2073
7be1c489
AM
2074/* GAS will call this to generate a reloc, passing the resulting reloc
2075 to `bfd_install_relocation'. This currently works poorly, as
2076 `bfd_install_relocation' often does the wrong thing, and instances of
2077 `tc_gen_reloc' have been written to work around the problems, which
2078 in turns makes it difficult to fix `bfd_install_relocation'. */
2469cfa2
NC
2079
2080/* If while processing a fixup, a reloc really needs to be created
2081 then it is done here. */
2082
2083arelent *
b18c562e 2084tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2469cfa2 2085{
b18c562e 2086 arelent * reloc;
2469cfa2 2087
b18c562e 2088 reloc = xmalloc (sizeof (arelent));
2469cfa2 2089
b18c562e 2090 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2469cfa2
NC
2091 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2092
2093 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2094 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2095 if (reloc->howto == (reloc_howto_type *) NULL)
2096 {
2097 as_bad_where (fixp->fx_file, fixp->fx_line,
2098 _("reloc %d not supported by object file format"),
2099 (int) fixp->fx_r_type);
2100 return NULL;
2101 }
2102
2103 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2104 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2105 reloc->address = fixp->fx_offset;
2106
2107 reloc->addend = fixp->fx_offset;
2108
2109 return reloc;
2110}
2111
b18c562e
NC
2112int
2113md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
2114 asection * segment_type ATTRIBUTE_UNUSED)
2115{
2116 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
2117 {
2118 /* This is a jump -> pcrel mode. Nothing to do much here.
2119 Return value == 2. */
2120 fragP->fr_subtype =
2121 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
2122 }
2123 else if (fragP->fr_symbol)
2124 {
2125 /* Its got a segment, but its not ours. Even if fr_symbol is in
2126 an absolute segment, we dont know a displacement until we link
2127 object files. So it will always be long. This also applies to
2128 labels in a subsegment of current. Liker may relax it to short
2129 jump later. Return value == 8. */
2130 fragP->fr_subtype =
2131 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
2132 }
2133 else
2134 {
2135 /* We know the abs value. may be it is a jump to fixed address.
2136 Impossible in our case, cause all constants already handeled. */
2137 fragP->fr_subtype =
2138 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
2139 }
2469cfa2 2140
b18c562e
NC
2141 return md_relax_table[fragP->fr_subtype].rlx_length;
2142}
2143
2144void
2145md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
2146 asection * sec ATTRIBUTE_UNUSED,
2147 fragS * fragP)
2469cfa2 2148{
b18c562e
NC
2149 char * where = 0;
2150 int rela = -1;
2151 int i;
2152 struct rcodes_s * cc = NULL;
2153 struct hcodes_s * hc = NULL;
2154
2155 switch (fragP->fr_subtype)
2156 {
2157 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
2158 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
2159 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
2160 /* We do not have to convert anything here.
2161 Just apply a fix. */
2162 rela = BFD_RELOC_MSP430_10_PCREL;
2163 break;
2164
2165 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
2166 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
2167 /* Convert uncond branch jmp lab -> br lab. */
2168 cc = & msp430_rcodes[7];
2169 where = fragP->fr_literal + fragP->fr_fix;
2170 bfd_putl16 (cc->lop0, where);
2171 rela = BFD_RELOC_MSP430_RL_PCREL;
2172 fragP->fr_fix += 2;
2173 break;
2174
2175 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
2176 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
2177 {
2178 /* Other simple branches. */
2179 int insn = bfd_getl16 (fragP->fr_opcode);
2180
2181 insn &= 0xffff;
2182 /* Find actual instruction. */
2183 for (i = 0; i < 7 && !cc; i++)
2184 if (msp430_rcodes[i].sop == insn)
2185 cc = & msp430_rcodes[i];
2186 if (!cc || !cc->name)
2187 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
2188 __FUNCTION__, (long) insn);
2189 where = fragP->fr_literal + fragP->fr_fix;
2190 bfd_putl16 (cc->lop0, where);
2191 bfd_putl16 (cc->lop1, where + 2);
2192 rela = BFD_RELOC_MSP430_RL_PCREL;
2193 fragP->fr_fix += 4;
2194 }
2195 break;
2196
2197 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
2198 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2199 cc = & msp430_rcodes[6];
2200 where = fragP->fr_literal + fragP->fr_fix;
2201 bfd_putl16 (cc->lop0, where);
2202 bfd_putl16 (cc->lop1, where + 2);
2203 bfd_putl16 (cc->lop2, where + 4);
2204 rela = BFD_RELOC_MSP430_RL_PCREL;
2205 fragP->fr_fix += 6;
2206 break;
2207
2208 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2209 {
2210 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2211
2212 insn &= 0xffff;
2213 for (i = 0; i < 4 && !hc; i++)
2214 if (msp430_hcodes[i].op1 == insn)
2215 hc = &msp430_hcodes[i];
2216 if (!hc || !hc->name)
2217 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2218 __FUNCTION__, (long) insn);
2219 rela = BFD_RELOC_MSP430_10_PCREL;
2220 /* Apply a fix for a first label if necessary.
2221 another fix will be applied to the next word of insn anyway. */
2222 if (hc->tlab == 2)
2223 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2224 fragP->fr_offset, TRUE, rela);
2225 fragP->fr_fix += 2;
2226 }
2227
2228 break;
2229
2230 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2231 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2232 {
2233 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2234
2235 insn &= 0xffff;
2236 for (i = 0; i < 4 && !hc; i++)
2237 if (msp430_hcodes[i].op1 == insn)
2238 hc = & msp430_hcodes[i];
2239 if (!hc || !hc->name)
2240 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2241 __FUNCTION__, (long) insn);
2242 rela = BFD_RELOC_MSP430_RL_PCREL;
2243 where = fragP->fr_literal + fragP->fr_fix;
2244 bfd_putl16 (hc->lop0, where);
2245 bfd_putl16 (hc->lop1, where + 2);
2246 bfd_putl16 (hc->lop2, where + 4);
2247 fragP->fr_fix += 6;
2248 }
2249 break;
2250
2251 default:
2252 as_fatal (_("internal inconsistency problem in %s: %lx"),
2253 __FUNCTION__, (long) fragP->fr_subtype);
2254 break;
2255 }
2256
2257 /* Now apply fix. */
2258 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2259 fragP->fr_offset, TRUE, rela);
2260 /* Just fixed 2 bytes. */
2261 fragP->fr_fix += 2;
2469cfa2
NC
2262}
2263
b18c562e
NC
2264/* Relax fragment. Mostly stolen from hc11 and mcore
2265 which arches I think I know. */
2469cfa2 2266
b18c562e
NC
2267long
2268msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2269 long stretch ATTRIBUTE_UNUSED)
2469cfa2 2270{
b18c562e
NC
2271 long growth;
2272 offsetT aim = 0;
2273 symbolS *symbolP;
2274 const relax_typeS *this_type;
2275 const relax_typeS *start_type;
2276 relax_substateT next_state;
2277 relax_substateT this_state;
2278 const relax_typeS *table = md_relax_table;
2279
2280 /* Nothing to be done if the frag has already max size. */
2281 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2282 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2283 return 0;
2284
2285 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2286 {
2287 symbolP = fragP->fr_symbol;
2288 if (symbol_resolved_p (symbolP))
2289 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2290 __FUNCTION__);
2291 /* We know the offset. calculate a distance. */
2292 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2293 }
2294
77592908
DD
2295 if (!msp430_enable_relax)
2296 {
2297 /* Relaxation is not enabled. So, make all jump as long ones
2298 by setting 'aim' to quite high value. */
2299 aim = 0x7fff;
2300 }
2301
b18c562e
NC
2302 this_state = fragP->fr_subtype;
2303 start_type = this_type = table + this_state;
2304
2305 if (aim < 0)
2306 {
2307 /* Look backwards. */
2308 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 2309 if (aim >= this_type->rlx_backward || !this_type->rlx_backward)
b18c562e
NC
2310 next_state = 0;
2311 else
2312 {
2313 /* Grow to next state. */
2314 this_state = next_state;
2315 this_type = table + this_state;
2316 next_state = this_type->rlx_more;
2317 }
2318 }
2319 else
2320 {
2321 /* Look forwards. */
2322 for (next_state = this_type->rlx_more; next_state;)
3e470ab5 2323 if (aim <= this_type->rlx_forward || !this_type->rlx_forward)
b18c562e
NC
2324 next_state = 0;
2325 else
2326 {
2327 /* Grow to next state. */
2328 this_state = next_state;
2329 this_type = table + this_state;
2330 next_state = this_type->rlx_more;
2331 }
2332 }
2333
2334 growth = this_type->rlx_length - start_type->rlx_length;
2335 if (growth != 0)
2336 fragP->fr_subtype = this_state;
2337 return growth;
2469cfa2 2338}
This page took 0.246385 seconds and 4 git commands to generate.