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