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