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