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