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