2004-08-26 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / gas / config / tc-msp430.c
blob03346f6075b26ae7376db214e998baa1b4a8d4a2
1 /* tc-msp430.c -- Assembler code for the Texas Instruments MSP430
3 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Dmitry Diky <diwil@mail.ru>
6 This file is part of GAS, the GNU Assembler.
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.
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.
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
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <limits.h>
28 #define PUSH_1X_WORKAROUND
29 #include "as.h"
30 #include "subsegs.h"
31 #include "opcode/msp430.h"
32 #include "safe-ctype.h"
34 const char comment_chars[] = ";";
35 const char line_comment_chars[] = "#";
36 const char line_separator_chars[] = "";
37 const char EXP_CHARS[] = "eE";
38 const char FLT_CHARS[] = "dD";
40 /* Handle long expressions. */
41 extern LITTLENUM_TYPE generic_bignum[];
43 static struct hash_control *msp430_hash;
45 /* Relaxations. */
46 #define STATE_UNCOND_BRANCH 1 /* jump */
47 #define STATE_NOOV_BRANCH 3 /* bltn */
48 #define STATE_SIMPLE_BRANCH 2 /* bne, beq, etc... */
49 #define STATE_EMUL_BRANCH 4
51 #define CNRL 2
52 #define CUBL 4
53 #define CNOL 8
54 #define CSBL 6
55 #define CEBL 4
57 /* Length. */
58 #define STATE_BITS10 1 /* wild guess. short jump */
59 #define STATE_WORD 2 /* 2 bytes pc rel. addr. more */
60 #define STATE_UNDEF 3 /* cannot handle this yet. convert to word mode */
62 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
63 #define RELAX_STATE(s) ((s) & 3)
64 #define RELAX_LEN(s) ((s) >> 2)
65 #define RELAX_NEXT(a,b) ENCODE_RELAX (a, b + 1)
67 relax_typeS md_relax_table[] =
69 /* Unused. */
70 {1, 1, 0, 0},
71 {1, 1, 0, 0},
72 {1, 1, 0, 0},
73 {1, 1, 0, 0},
75 /* Unconditional jump. */
76 {1, 1, 8, 5},
77 {1024, -1024, CNRL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
78 {0, 0, CUBL, RELAX_NEXT (STATE_UNCOND_BRANCH, STATE_WORD)}, /* state word */
79 {1, 1, CUBL, 0}, /* state undef */
81 /* Simple branches. */
82 {0, 0, 8, 9},
83 {1024, -1024, CNRL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
84 {0, 0, CSBL, RELAX_NEXT (STATE_SIMPLE_BRANCH, STATE_WORD)}, /* state word */
85 {1, 1, CSBL, 0},
87 /* blt no overflow branch. */
88 {1, 1, 8, 13},
89 {1024, -1024, CNRL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
90 {0, 0, CNOL, RELAX_NEXT (STATE_NOOV_BRANCH, STATE_WORD)}, /* state word */
91 {1, 1, CNOL, 0},
93 /* Emulated branches. */
94 {1, 1, 8, 17},
95 {1020, -1020, CEBL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_BITS10)}, /* state 10 bits displ */
96 {0, 0, CNOL, RELAX_NEXT (STATE_EMUL_BRANCH, STATE_WORD)}, /* state word */
97 {1, 1, CNOL, 0}
101 #define MAX_OP_LEN 256
103 struct mcu_type_s
105 char * name;
106 int isa;
107 int mach;
110 #define MSP430_ISA_11 11
111 #define MSP430_ISA_110 110
112 #define MSP430_ISA_12 12
113 #define MSP430_ISA_13 13
114 #define MSP430_ISA_14 14
115 #define MSP430_ISA_15 15
116 #define MSP430_ISA_16 16
117 #define MSP430_ISA_31 31
118 #define MSP430_ISA_32 32
119 #define MSP430_ISA_33 33
120 #define MSP430_ISA_41 41
121 #define MSP430_ISA_42 42
122 #define MSP430_ISA_43 43
123 #define MSP430_ISA_44 44
125 #define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
126 #define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
128 static struct mcu_type_s mcu_types[] =
130 {"msp1", MSP430_ISA_11, bfd_mach_msp11},
131 {"msp2", MSP430_ISA_14, bfd_mach_msp14},
132 {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
133 {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
134 {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
135 {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
136 {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
137 {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
138 {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
140 {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
141 {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
142 {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
143 {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
145 {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
146 {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
147 {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
148 {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
149 {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
150 {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
151 {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
153 {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
154 {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
155 {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
156 {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
157 {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
158 {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
159 {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
160 {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
161 {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
163 {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
164 {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
165 {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
166 {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
167 {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
168 {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
169 {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
170 {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
171 {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
173 {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
174 {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
175 {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
176 {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
178 {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
179 {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
180 {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
182 {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
183 {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
184 {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
186 {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
187 {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
188 {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
190 {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
191 {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
192 {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
193 {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
194 {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
195 {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
197 {NULL, 0, 0}
201 static struct mcu_type_s default_mcu =
202 { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
204 static struct mcu_type_s * msp430_mcu = & default_mcu;
206 /* Profiling capability:
207 It is a performance hit to use gcc's profiling approach for this tiny target.
208 Even more -- jtag hardware facility does not perform any profiling functions.
209 However we've got gdb's built-in simulator where we can do anything.
210 Therefore my suggestion is:
212 We define new section ".profiler" which holds all profiling information.
213 We define new pseudo operation .profiler which will instruct assembler to
214 add new profile entry to the object file. Profile should take place at the
215 present address.
217 Pseudo-op format:
219 .profiler flags,function_to_profile [, cycle_corrector, extra]
221 where 'flags' is a combination of the following chars:
222 s - function Start
223 x - function eXit
224 i - function is in Init section
225 f - function is in Fini section
226 l - Library call
227 c - libC standard call
228 d - stack value Demand (saved at run-time in simulator)
229 I - Interrupt service routine
230 P - Prologue start
231 p - Prologue end
232 E - Epilogue start
233 e - Epilogue end
234 j - long Jump/ sjlj unwind
235 a - an Arbitrary code fragment
236 t - exTra parameter saved (constant value like frame size)
237 '""' optional: "sil" == sil
239 function_to_profile - function's address
240 cycle_corrector - a value which should be added to the cycle
241 counter, zero if omitted
242 extra - some extra parameter, zero if omitted.
244 For example:
245 ------------------------------
246 .global fxx
247 .type fxx,@function
248 fxx:
249 .LFrameOffset_fxx=0x08
250 .profiler "scdP", fxx ; function entry.
251 ; we also demand stack value to be displayed
252 push r11
253 push r10
254 push r9
255 push r8
256 .profiler "cdp",fxx,0, .LFrameOffset_fxx ; check stack value at this point
257 ; (this is a prologue end)
258 ; note, that spare var filled with the farme size
259 mov r15,r8
260 ....
261 .profiler cdE,fxx ; check stack
262 pop r8
263 pop r9
264 pop r10
265 pop r11
266 .profiler xcde,fxx,3 ; exit adds 3 to the cycle counter
267 ret ; cause 'ret' insn takes 3 cycles
268 -------------------------------
270 This profiling approach does not produce any overhead and
271 absolutely harmless.
272 So, even profiled code can be uploaded to the MCU. */
273 #define MSP430_PROFILER_FLAG_ENTRY 1 /* s */
274 #define MSP430_PROFILER_FLAG_EXIT 2 /* x */
275 #define MSP430_PROFILER_FLAG_INITSECT 4 /* i */
276 #define MSP430_PROFILER_FLAG_FINISECT 8 /* f */
277 #define MSP430_PROFILER_FLAG_LIBCALL 0x10 /* l */
278 #define MSP430_PROFILER_FLAG_STDCALL 0x20 /* c */
279 #define MSP430_PROFILER_FLAG_STACKDMD 0x40 /* d */
280 #define MSP430_PROFILER_FLAG_ISR 0x80 /* I */
281 #define MSP430_PROFILER_FLAG_PROLSTART 0x100 /* P */
282 #define MSP430_PROFILER_FLAG_PROLEND 0x200 /* p */
283 #define MSP430_PROFILER_FLAG_EPISTART 0x400 /* E */
284 #define MSP430_PROFILER_FLAG_EPIEND 0x800 /* e */
285 #define MSP430_PROFILER_FLAG_JUMP 0x1000 /* j */
286 #define MSP430_PROFILER_FLAG_FRAGMENT 0x2000 /* a */
287 #define MSP430_PROFILER_FLAG_EXTRA 0x4000 /* t */
288 #define MSP430_PROFILER_FLAG_notyet 0x8000 /* ? */
290 static int
291 pow2value (int y)
293 int n = 0;
294 unsigned int x;
296 x = y;
298 if (!x)
299 return 1;
301 for (; x; x = x >> 1)
302 if (x & 1)
303 n++;
305 return n == 1;
308 /* Parse ordinary expression. */
310 static char *
311 parse_exp (char * s, expressionS * op)
313 input_line_pointer = s;
314 expression (op);
315 if (op->X_op == O_absent)
316 as_bad (_("missing operand"));
317 return input_line_pointer;
321 /* Delete spaces from s: X ( r 1 2) => X(r12). */
323 static void
324 del_spaces (char * s)
326 while (*s)
328 if (ISSPACE (*s))
330 char *m = s + 1;
332 while (ISSPACE (*m) && *m)
333 m++;
334 memmove (s, m, strlen (m) + 1);
336 else
337 s++;
341 static inline char *
342 skip_space (char * s)
344 while (ISSPACE (*s))
345 ++s;
346 return s;
349 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
351 static char *
352 extract_operand (char * from, char * to, int limit)
354 int size = 0;
356 /* Drop leading whitespace. */
357 from = skip_space (from);
359 while (size < limit && *from)
361 *(to + size) = *from;
362 if (*from == ',' || *from == ';' || *from == '\n')
363 break;
364 from++;
365 size++;
368 *(to + size) = 0;
369 del_spaces (to);
371 from++;
373 return from;
376 static void
377 msp430_profiler (int dummy ATTRIBUTE_UNUSED)
379 char buffer[1024];
380 char f[32];
381 char * str = buffer;
382 char * flags = f;
383 int p_flags = 0;
384 char * halt;
385 int ops = 0;
386 int left;
387 char * s;
388 segT seg;
389 int subseg;
390 char * end = 0;
391 expressionS exp;
392 expressionS exp1;
394 s = input_line_pointer;
395 end = input_line_pointer;
397 while (*end && *end != '\n')
398 end++;
400 while (*s && *s != '\n')
402 if (*s == ',')
403 ops++;
404 s++;
407 left = 3 - ops;
409 if (ops < 1)
411 as_bad (_(".profiler pseudo requires at least two operands."));
412 input_line_pointer = end;
413 return;
416 input_line_pointer = extract_operand (input_line_pointer, flags, 32);
418 while (*flags)
420 switch (*flags)
422 case '"':
423 break;
424 case 'a':
425 p_flags |= MSP430_PROFILER_FLAG_FRAGMENT;
426 break;
427 case 'j':
428 p_flags |= MSP430_PROFILER_FLAG_JUMP;
429 break;
430 case 'P':
431 p_flags |= MSP430_PROFILER_FLAG_PROLSTART;
432 break;
433 case 'p':
434 p_flags |= MSP430_PROFILER_FLAG_PROLEND;
435 break;
436 case 'E':
437 p_flags |= MSP430_PROFILER_FLAG_EPISTART;
438 break;
439 case 'e':
440 p_flags |= MSP430_PROFILER_FLAG_EPIEND;
441 break;
442 case 's':
443 p_flags |= MSP430_PROFILER_FLAG_ENTRY;
444 break;
445 case 'x':
446 p_flags |= MSP430_PROFILER_FLAG_EXIT;
447 break;
448 case 'i':
449 p_flags |= MSP430_PROFILER_FLAG_INITSECT;
450 break;
451 case 'f':
452 p_flags |= MSP430_PROFILER_FLAG_FINISECT;
453 break;
454 case 'l':
455 p_flags |= MSP430_PROFILER_FLAG_LIBCALL;
456 break;
457 case 'c':
458 p_flags |= MSP430_PROFILER_FLAG_STDCALL;
459 break;
460 case 'd':
461 p_flags |= MSP430_PROFILER_FLAG_STACKDMD;
462 break;
463 case 'I':
464 p_flags |= MSP430_PROFILER_FLAG_ISR;
465 break;
466 case 't':
467 p_flags |= MSP430_PROFILER_FLAG_EXTRA;
468 break;
469 default:
470 as_warn (_("unknown profiling flag - ignored."));
471 break;
473 flags++;
476 if (p_flags
477 && ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
478 | MSP430_PROFILER_FLAG_EXIT))
479 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_PROLSTART
480 | MSP430_PROFILER_FLAG_PROLEND
481 | MSP430_PROFILER_FLAG_EPISTART
482 | MSP430_PROFILER_FLAG_EPIEND))
483 || ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_INITSECT
484 | MSP430_PROFILER_FLAG_FINISECT))))
486 as_bad (_("ambigious flags combination - '.profiler' directive ignored."));
487 input_line_pointer = end;
488 return;
491 /* Generate temp symbol which denotes current location. */
492 if (now_seg == absolute_section) /* Paranoja ? */
494 exp1.X_op = O_constant;
495 exp1.X_add_number = abs_section_offset;
496 as_warn (_("profiling in absolute section? Hm..."));
498 else
500 exp1.X_op = O_symbol;
501 exp1.X_add_symbol = symbol_temp_new_now ();
502 exp1.X_add_number = 0;
505 /* Generate a symbol which holds flags value. */
506 exp.X_op = O_constant;
507 exp.X_add_number = p_flags;
509 /* Save current section. */
510 seg = now_seg;
511 subseg = now_subseg;
513 /* Now go to .profiler section. */
514 obj_elf_change_section (".profiler", SHT_PROGBITS, 0, 0, 0, 0, 0);
516 /* Save flags. */
517 emit_expr (& exp, 2);
519 /* Save label value. */
520 emit_expr (& exp1, 2);
522 while (ops--)
524 /* Now get profiling info. */
525 halt = extract_operand (input_line_pointer, str, 1024);
526 /* Process like ".word xxx" directive. */
527 parse_exp (str, & exp);
528 emit_expr (& exp, 2);
529 input_line_pointer = halt;
532 /* Fill the rest with zeros. */
533 exp.X_op = O_constant;
534 exp.X_add_number = 0;
535 while (left--)
536 emit_expr (& exp, 2);
538 /* Return to current section. */
539 subseg_set (seg, subseg);
542 static char *
543 extract_word (char * from, char * to, int limit)
545 char *op_start;
546 char *op_end;
547 int size = 0;
549 /* Drop leading whitespace. */
550 from = skip_space (from);
551 *to = 0;
553 /* Find the op code end. */
554 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
556 to[size++] = *op_end++;
557 if (size + 1 >= limit)
558 break;
561 to[size] = 0;
562 return op_end;
565 #define OPTION_MMCU 'm'
567 static void
568 msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
570 char *str = (char *) alloca (32); /* 32 for good measure. */
572 input_line_pointer = extract_word (input_line_pointer, str, 32);
574 md_parse_option (OPTION_MMCU, str);
575 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
578 static void
579 show_mcu_list (FILE * stream)
581 int i;
583 fprintf (stream, _("Known MCU names:\n"));
585 for (i = 0; mcu_types[i].name; i++)
586 fprintf (stream, _("\t %s\n"), mcu_types[i].name);
588 fprintf (stream, "\n");
592 md_parse_option (int c, char * arg)
594 int i;
596 switch (c)
598 case OPTION_MMCU:
599 for (i = 0; mcu_types[i].name; ++i)
600 if (strcmp (mcu_types[i].name, arg) == 0)
601 break;
603 if (!mcu_types[i].name)
605 show_mcu_list (stderr);
606 as_fatal (_("unknown MCU: %s\n"), arg);
609 if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
610 msp430_mcu = &mcu_types[i];
611 else
612 as_fatal (_("redefinition of mcu type %s' to %s'"),
613 msp430_mcu->name, mcu_types[i].name);
614 return 1;
617 return 0;
621 const pseudo_typeS md_pseudo_table[] =
623 {"arch", msp430_set_arch, 0},
624 {"profiler", msp430_profiler, 0},
625 {NULL, NULL, 0}
628 const char *md_shortopts = "m:";
630 struct option md_longopts[] =
632 {"mmcu", required_argument, NULL, OPTION_MMCU},
633 {NULL, no_argument, NULL, 0}
636 size_t md_longopts_size = sizeof (md_longopts);
638 void
639 md_show_usage (FILE * stream)
641 fprintf (stream,
642 _("MSP430 options:\n"
643 " -mmcu=[msp430-name] select microcontroller type\n"
644 " msp430x110 msp430x112\n"
645 " msp430x1101 msp430x1111\n"
646 " msp430x1121 msp430x1122 msp430x1132\n"
647 " msp430x122 msp430x123\n"
648 " msp430x1222 msp430x1232\n"
649 " msp430x133 msp430x135\n"
650 " msp430x1331 msp430x1351\n"
651 " msp430x147 msp430x148 msp430x149\n"
652 " msp430x155 msp430x156 msp430x157\n"
653 " msp430x167 msp430x168 msp430x169\n"
654 " msp430x1610 msp430x1611 msp430x1612\n"
655 " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
656 " msp430x323 msp430x325\n"
657 " msp430x336 msp430x337\n"
658 " msp430x412 msp430x413 msp430x415 msp430x417\n"
659 " msp430xE423 msp430xE425 msp430E427\n"
660 " msp430xW423 msp430xW425 msp430W427\n"
661 " msp430xG437 msp430xG438 msp430G439\n"
662 " msp430x435 msp430x436 msp430x437\n"
663 " msp430x447 msp430x448 msp430x449\n"));
665 show_mcu_list (stream);
668 symbolS *
669 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
671 return 0;
674 static char *
675 extract_cmd (char * from, char * to, int limit)
677 int size = 0;
679 while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
681 *(to + size) = *from;
682 from++;
683 size++;
686 *(to + size) = 0;
688 return from;
691 /* Turn a string in input_line_pointer into a floating point constant
692 of type TYPE, and store the appropriate bytes in *LITP. The number
693 of LITTLENUMS emitted is stored in *SIZEP. An error message is
694 returned, or NULL on OK. */
696 char *
697 md_atof (int type, char * litP, int * sizeP)
699 int prec;
700 LITTLENUM_TYPE words[4];
701 LITTLENUM_TYPE *wordP;
702 char *t;
704 switch (type)
706 case 'f':
707 prec = 2;
708 break;
709 case 'd':
710 prec = 4;
711 break;
712 default:
713 *sizeP = 0;
714 return _("bad call to md_atof");
717 t = atof_ieee (input_line_pointer, type, words);
718 if (t)
719 input_line_pointer = t;
721 *sizeP = prec * sizeof (LITTLENUM_TYPE);
723 /* This loop outputs the LITTLENUMs in REVERSE order. */
724 for (wordP = words + prec - 1; prec--;)
726 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
727 litP += sizeof (LITTLENUM_TYPE);
730 return NULL;
733 void
734 md_begin (void)
736 struct msp430_opcode_s * opcode;
737 msp430_hash = hash_new ();
739 for (opcode = msp430_opcodes; opcode->name; opcode++)
740 hash_insert (msp430_hash, opcode->name, (char *) opcode);
742 bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
745 static int
746 check_reg (char * t)
748 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
750 if (strlen (t) > 2 && *(t + 2) != '+')
751 return 1;
753 while (*t)
755 if ((*t < '0' || *t > '9') && *t != '+')
756 break;
757 t++;
760 if (*t)
761 return 1;
763 return 0;
767 static int
768 msp430_srcoperand (struct msp430_operand_s * op,
769 char * l, int bin, int * imm_op)
771 char *__tl = l;
773 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
774 if (*l == '#')
776 char *h = l;
777 int vshift = -1;
778 int rval = 0;
780 /* Check if there is:
781 llo(x) - least significant 16 bits, x &= 0xffff
782 lhi(x) - x = (x >> 16) & 0xffff,
783 hlo(x) - x = (x >> 32) & 0xffff,
784 hhi(x) - x = (x >> 48) & 0xffff
785 The value _MUST_ be constant expression: #hlo(1231231231). */
787 *imm_op = 1;
789 if (strncasecmp (h, "#llo(", 5) == 0)
791 vshift = 0;
792 rval = 3;
794 else if (strncasecmp (h, "#lhi(", 5) == 0)
796 vshift = 1;
797 rval = 3;
799 else if (strncasecmp (h, "#hlo(", 5) == 0)
801 vshift = 2;
802 rval = 3;
804 else if (strncasecmp (h, "#hhi(", 5) == 0)
806 vshift = 3;
807 rval = 3;
809 else if (strncasecmp (h, "#lo(", 4) == 0)
811 vshift = 0;
812 rval = 2;
814 else if (strncasecmp (h, "#hi(", 4) == 0)
816 vshift = 1;
817 rval = 2;
820 op->reg = 0; /* Reg PC. */
821 op->am = 3;
822 op->ol = 1; /* Immediate will follow an instruction. */
823 __tl = h + 1 + rval;
824 op->mode = OP_EXP;
826 parse_exp (__tl, &(op->exp));
827 if (op->exp.X_op == O_constant)
829 int x = op->exp.X_add_number;
831 if (vshift == 0)
833 x = x & 0xffff;
834 op->exp.X_add_number = x;
836 else if (vshift == 1)
838 x = (x >> 16) & 0xffff;
839 op->exp.X_add_number = x;
841 else if (vshift > 1)
843 if (x < 0)
844 op->exp.X_add_number = -1;
845 else
846 op->exp.X_add_number = 0; /* Nothing left. */
847 x = op->exp.X_add_number;
850 if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
852 as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
853 return 1;
856 /* Now check constants. */
857 /* Substitute register mode with a constant generator if applicable. */
859 x = (short) x; /* Extend sign. */
861 if (x == 0)
863 op->reg = 3;
864 op->am = 0;
865 op->ol = 0;
866 op->mode = OP_REG;
868 else if (x == 1)
870 op->reg = 3;
871 op->am = 1;
872 op->ol = 0;
873 op->mode = OP_REG;
875 else if (x == 2)
877 op->reg = 3;
878 op->am = 2;
879 op->ol = 0;
880 op->mode = OP_REG;
882 else if (x == -1)
884 op->reg = 3;
885 op->am = 3;
886 op->ol = 0;
887 op->mode = OP_REG;
889 else if (x == 4)
891 #ifdef PUSH_1X_WORKAROUND
892 if (bin == 0x1200)
894 /* Remove warning as confusing.
895 as_warn(_("Hardware push bug workaround")); */
897 else
898 #endif
900 op->reg = 2;
901 op->am = 2;
902 op->ol = 0;
903 op->mode = OP_REG;
906 else if (x == 8)
908 #ifdef PUSH_1X_WORKAROUND
909 if (bin == 0x1200)
911 /* Remove warning as confusing.
912 as_warn(_("Hardware push bug workaround")); */
914 else
915 #endif
917 op->reg = 2;
918 op->am = 3;
919 op->ol = 0;
920 op->mode = OP_REG;
924 else if (op->exp.X_op == O_symbol)
926 op->mode = OP_EXP;
928 else if (op->exp.X_op == O_big)
930 short x;
931 if (vshift != -1)
933 op->exp.X_op = O_constant;
934 op->exp.X_add_number = 0xffff & generic_bignum[vshift];
935 x = op->exp.X_add_number;
937 else
939 as_bad (_
940 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
942 return 1;
945 if (x == 0)
947 op->reg = 3;
948 op->am = 0;
949 op->ol = 0;
950 op->mode = OP_REG;
952 else if (x == 1)
954 op->reg = 3;
955 op->am = 1;
956 op->ol = 0;
957 op->mode = OP_REG;
959 else if (x == 2)
961 op->reg = 3;
962 op->am = 2;
963 op->ol = 0;
964 op->mode = OP_REG;
966 else if (x == -1)
968 op->reg = 3;
969 op->am = 3;
970 op->ol = 0;
971 op->mode = OP_REG;
973 else if (x == 4)
975 op->reg = 2;
976 op->am = 2;
977 op->ol = 0;
978 op->mode = OP_REG;
980 else if (x == 8)
982 op->reg = 2;
983 op->am = 3;
984 op->ol = 0;
985 op->mode = OP_REG;
988 /* Redudant (yet) check. */
989 else if (op->exp.X_op == O_register)
990 as_bad
991 (_("Registers cannot be used within immediate expression [%s]"), l);
992 else
993 as_bad (_("unknown operand %s"), l);
995 return 0;
998 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
999 if (*l == '&')
1001 char *h = l;
1003 op->reg = 2; /* reg 2 in absolute addr mode. */
1004 op->am = 1; /* mode As == 01 bin. */
1005 op->ol = 1; /* Immediate value followed by instruction. */
1006 __tl = h + 1;
1007 parse_exp (__tl, &(op->exp));
1008 op->mode = OP_EXP;
1009 if (op->exp.X_op == O_constant)
1011 int x = op->exp.X_add_number;
1013 if (x > 65535 || x < -32768)
1015 as_bad (_("value out of range: %d"), x);
1016 return 1;
1019 else if (op->exp.X_op == O_symbol)
1021 else
1023 /* Redudant (yet) check. */
1024 if (op->exp.X_op == O_register)
1025 as_bad
1026 (_("Registers cannot be used within absolute expression [%s]"), l);
1027 else
1028 as_bad (_("unknown expression in operand %s"), l);
1029 return 1;
1031 return 0;
1034 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1035 if (*l == '@')
1037 char *t = l;
1038 char *m = strchr (l, '+');
1040 if (t != l)
1042 as_bad (_("unknown addressing mode %s"), l);
1043 return 1;
1046 t++;
1047 if (*t != 'r' && *t != 'R')
1049 as_bad (_("unknown addressing mode %s"), l);
1050 return 1;
1053 t++; /* Points to the reg value. */
1055 if (check_reg (t))
1057 as_bad (_("Bad register name r%s"), t);
1058 return 1;
1061 op->mode = OP_REG;
1062 op->am = m ? 3 : 2;
1063 op->ol = 0;
1064 if (m)
1065 *m = 0; /* strip '+' */
1066 op->reg = atoi (t);
1067 if (op->reg < 0 || op->reg > 15)
1069 as_bad (_("MSP430 does not have %d registers"), op->reg);
1070 return 1;
1073 return 0;
1076 /* Check if register indexed X(Rn). */
1079 char *h = strrchr (l, '(');
1080 char *m = strrchr (l, ')');
1081 char *t;
1083 *imm_op = 1;
1085 if (!h)
1086 break;
1087 if (!m)
1089 as_bad (_("')' required"));
1090 return 1;
1093 t = h;
1094 op->am = 1;
1095 op->ol = 1;
1096 /* Extract a register. */
1097 t++; /* Advance pointer. */
1099 if (*t != 'r' && *t != 'R')
1101 as_bad (_
1102 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1104 return 1;
1106 t++;
1108 op->reg = *t - '0';
1109 if (op->reg > 9 || op->reg < 0)
1111 as_bad (_("unknown operator (r%s substituded as a register name"),
1113 return 1;
1115 t++;
1116 if (*t != ')')
1118 op->reg = op->reg * 10;
1119 op->reg += *t - '0';
1121 if (op->reg > 15)
1123 as_bad (_("unknown operator %s"), l);
1124 return 1;
1126 if (op->reg == 2)
1128 as_bad (_("r2 should not be used in indexed addressing mode"));
1129 return 1;
1132 if (*(t + 1) != ')')
1134 as_bad (_("unknown operator %s"), l);
1135 return 1;
1139 /* Extract constant. */
1140 __tl = l;
1141 *h = 0;
1142 op->mode = OP_EXP;
1143 parse_exp (__tl, &(op->exp));
1144 if (op->exp.X_op == O_constant)
1146 int x = op->exp.X_add_number;
1148 if (x > 65535 || x < -32768)
1150 as_bad (_("value out of range: %d"), x);
1151 return 1;
1154 if (x == 0)
1156 op->mode = OP_REG;
1157 op->am = 2;
1158 op->ol = 0;
1159 return 0;
1162 else if (op->exp.X_op == O_symbol)
1164 else
1166 /* Redudant (yet) check. */
1167 if (op->exp.X_op == O_register)
1168 as_bad
1169 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l);
1170 else
1171 as_bad (_("unknown expression in operand %s"), l);
1172 return 1;
1175 return 0;
1177 while (0);
1179 /* Register mode 'mov r1,r2'. */
1182 char *t = l;
1184 /* Operand should be a register. */
1185 if (*t == 'r' || *t == 'R')
1187 int x = atoi (t + 1);
1189 if (check_reg (t + 1))
1190 break;
1192 if (x < 0 || x > 15)
1193 break; /* Symbolic mode. */
1195 op->mode = OP_REG;
1196 op->am = 0;
1197 op->ol = 0;
1198 op->reg = x;
1199 return 0;
1202 while (0);
1204 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1207 #if 0 /* Allow expression in operand like 'a+123*(1|2)'. */
1208 char *t = l;
1210 __tl = l;
1212 while (*t)
1214 /* alpha/number underline dot for labels. */
1215 if (! ISALNUM (*t) && *t != '_' && *t != '.')
1217 as_bad (_("unknown operand %s"), l);
1218 return 1;
1220 t++;
1222 #endif
1223 op->mode = OP_EXP;
1224 op->reg = 0; /* PC relative... be careful. */
1225 op->am = 1;
1226 op->ol = 1;
1227 __tl = l;
1228 parse_exp (__tl, &(op->exp));
1229 return 0;
1231 while (0);
1233 /* Unreachable. */
1234 as_bad (_("unknown addressing mode for operand %s"), l);
1235 return 1;
1239 static int
1240 msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
1242 int dummy;
1243 int ret = msp430_srcoperand (op, l, bin, & dummy);
1245 if (ret)
1246 return ret;
1248 if (op->am == 2)
1250 char *__tl = "0";
1252 op->mode = OP_EXP;
1253 op->am = 1;
1254 op->ol = 1;
1255 parse_exp (__tl, &(op->exp));
1257 if (op->exp.X_op != O_constant || op->exp.X_add_number != 0)
1259 as_bad (_("Internal bug. Try to use 0(r%d) instead of @r%d"),
1260 op->reg, op->reg);
1261 return 1;
1263 return 0;
1266 if (op->am > 1)
1268 as_bad (_
1269 ("this addressing mode is not applicable for destination operand"));
1270 return 1;
1272 return 0;
1276 /* Parse instruction operands.
1277 Return binary opcode. */
1279 static unsigned int
1280 msp430_operands (struct msp430_opcode_s * opcode, char * line)
1282 int bin = opcode->bin_opcode; /* Opcode mask. */
1283 int __is;
1284 char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
1285 char *frag;
1286 int where;
1287 struct msp430_operand_s op1, op2;
1288 int res = 0;
1289 static short ZEROS = 0;
1290 int byte_op, imm_op;
1292 /* Opcode is the one from opcodes table
1293 line contains something like
1294 [.w] @r2+, 5(R1)
1296 .b @r2+, 5(R1). */
1298 /* Check if byte or word operation. */
1299 if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
1301 bin |= BYTE_OPERATION;
1302 byte_op = 1;
1304 else
1305 byte_op = 0;
1307 /* skip .[bwBW]. */
1308 while (! ISSPACE (*line) && *line)
1309 line++;
1311 if (opcode->insn_opnumb && (!*line || *line == '\n'))
1313 as_bad (_("instruction %s requires %d operand(s)"),
1314 opcode->name, opcode->insn_opnumb);
1315 return 0;
1318 memset (l1, 0, sizeof (l1));
1319 memset (l2, 0, sizeof (l2));
1320 memset (&op1, 0, sizeof (op1));
1321 memset (&op2, 0, sizeof (op2));
1323 imm_op = 0;
1325 switch (opcode->fmt)
1327 case 0: /* Emulated. */
1328 switch (opcode->insn_opnumb)
1330 case 0:
1331 /* Set/clear bits instructions. */
1332 __is = 2;
1333 frag = frag_more (__is);
1334 bfd_putl16 ((bfd_vma) bin, frag);
1335 break;
1336 case 1:
1337 /* Something which works with destination operand. */
1338 line = extract_operand (line, l1, sizeof (l1));
1339 res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
1340 if (res)
1341 break;
1343 bin |= (op1.reg | (op1.am << 7));
1344 __is = 1 + op1.ol;
1345 frag = frag_more (2 * __is);
1346 where = frag - frag_now->fr_literal;
1347 bfd_putl16 ((bfd_vma) bin, frag);
1349 if (op1.mode == OP_EXP)
1351 where += 2;
1352 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1354 if (op1.reg)
1355 fix_new_exp (frag_now, where, 2,
1356 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1357 else
1358 fix_new_exp (frag_now, where, 2,
1359 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1361 break;
1363 case 2:
1365 /* Shift instruction. */
1366 line = extract_operand (line, l1, sizeof (l1));
1367 strncpy (l2, l1, sizeof (l2));
1368 l2[sizeof (l2) - 1] = '\0';
1369 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1370 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1372 if (res)
1373 break; /* An error occurred. All warnings were done before. */
1375 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1377 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1378 frag = frag_more (2 * __is);
1379 where = frag - frag_now->fr_literal;
1380 bfd_putl16 ((bfd_vma) bin, frag);
1382 if (op1.mode == OP_EXP)
1384 where += 2; /* Advance 'where' as we do not know _where_. */
1385 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1387 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1388 fix_new_exp (frag_now, where, 2,
1389 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1390 else
1391 fix_new_exp (frag_now, where, 2,
1392 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1395 if (op2.mode == OP_EXP)
1397 imm_op = 0;
1398 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1400 if (op2.reg) /* Not PC relative. */
1401 fix_new_exp (frag_now, where + 2, 2,
1402 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1403 else
1404 fix_new_exp (frag_now, where + 2, 2,
1405 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1407 break;
1409 case 3:
1410 /* Branch instruction => mov dst, r0. */
1411 line = extract_operand (line, l1, sizeof (l1));
1413 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1414 if (res)
1415 break;
1417 byte_op = 0;
1418 imm_op = 0;
1420 bin |= ((op1.reg << 8) | (op1.am << 4));
1421 __is = 1 + op1.ol;
1422 frag = frag_more (2 * __is);
1423 where = frag - frag_now->fr_literal;
1424 bfd_putl16 ((bfd_vma) bin, frag);
1426 if (op1.mode == OP_EXP)
1428 where += 2;
1429 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1431 if (op1.reg || (op1.reg == 0 && op1.am == 3))
1432 fix_new_exp (frag_now, where, 2,
1433 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1434 else
1435 fix_new_exp (frag_now, where, 2,
1436 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1438 break;
1440 break;
1442 case 1: /* Format 1, double operand. */
1443 line = extract_operand (line, l1, sizeof (l1));
1444 line = extract_operand (line, l2, sizeof (l2));
1445 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1446 res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
1448 if (res)
1449 break; /* Error occurred. All warnings were done before. */
1451 bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
1453 __is = 1 + op1.ol + op2.ol; /* insn size in words. */
1454 frag = frag_more (2 * __is);
1455 where = frag - frag_now->fr_literal;
1456 bfd_putl16 ((bfd_vma) bin, frag);
1458 if (op1.mode == OP_EXP)
1460 where += 2; /* Advance where as we do not know _where_. */
1461 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1463 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1464 fix_new_exp (frag_now, where, 2,
1465 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1466 else
1467 fix_new_exp (frag_now, where, 2,
1468 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1471 if (op2.mode == OP_EXP)
1473 imm_op = 0;
1474 bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
1476 if (op2.reg) /* Not PC relative. */
1477 fix_new_exp (frag_now, where + 2, 2,
1478 &(op2.exp), FALSE, CHECK_RELOC_MSP430);
1479 else
1480 fix_new_exp (frag_now, where + 2, 2,
1481 &(op2.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1483 break;
1485 case 2: /* Single-operand mostly instr. */
1486 if (opcode->insn_opnumb == 0)
1488 /* reti instruction. */
1489 frag = frag_more (2);
1490 bfd_putl16 ((bfd_vma) bin, frag);
1491 break;
1494 line = extract_operand (line, l1, sizeof (l1));
1495 res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
1496 if (res)
1497 break; /* Error in operand. */
1499 bin |= op1.reg | (op1.am << 4);
1500 __is = 1 + op1.ol;
1501 frag = frag_more (2 * __is);
1502 where = frag - frag_now->fr_literal;
1503 bfd_putl16 ((bfd_vma) bin, frag);
1505 if (op1.mode == OP_EXP)
1507 bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
1509 if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
1510 fix_new_exp (frag_now, where + 2, 2,
1511 &(op1.exp), FALSE, CHECK_RELOC_MSP430);
1512 else
1513 fix_new_exp (frag_now, where + 2, 2,
1514 &(op1.exp), TRUE, CHECK_RELOC_MSP430_PCREL);
1516 break;
1518 case 3: /* Conditional jumps instructions. */
1519 line = extract_operand (line, l1, sizeof (l1));
1520 /* l1 is a label. */
1521 if (l1[0])
1523 char *m = l1;
1524 expressionS exp;
1526 if (*m == '$')
1527 m++;
1529 parse_exp (m, &exp);
1530 frag = frag_more (2); /* Instr size is 1 word. */
1532 /* In order to handle something like:
1534 and #0x8000, r5
1535 tst r5
1536 jz 4 ; skip next 4 bytes
1537 inv r5
1538 inc r5
1539 nop ; will jump here if r5 positive or zero
1541 jCOND -n ;assumes jump n bytes backward:
1543 mov r5,r6
1544 jmp -2
1546 is equal to:
1547 lab:
1548 mov r5,r6
1549 jmp lab
1551 jCOND $n ; jump from PC in either direction. */
1553 if (exp.X_op == O_constant)
1555 int x = exp.X_add_number;
1557 if (x & 1)
1559 as_warn (_("Even number required. Rounded to %d"), x + 1);
1560 x++;
1563 if ((*l1 == '$' && x > 0) || x < 0)
1564 x -= 2;
1566 x >>= 1;
1568 if (x > 512 || x < -511)
1570 as_bad (_("Wrong displacement %d"), x << 1);
1571 break;
1574 bin |= x & 0x3ff;
1575 bfd_putl16 ((bfd_vma) bin, frag);
1577 else if (exp.X_op == O_symbol && *l1 != '$')
1579 where = frag - frag_now->fr_literal;
1580 fix_new_exp (frag_now, where, 2,
1581 &exp, TRUE, BFD_RELOC_MSP430_10_PCREL);
1583 bfd_putl16 ((bfd_vma) bin, frag);
1585 else if (*l1 == '$')
1587 as_bad (_("instruction requires label sans '$'"));
1588 break;
1590 else
1592 as_bad (_
1593 ("instruction requires label or value in range -511:512"));
1594 break;
1597 else
1599 as_bad (_("instruction requires label"));
1600 break;
1602 break;
1604 case 4: /* Extended jumps. */
1605 line = extract_operand (line, l1, sizeof (l1));
1606 if (l1[0])
1608 char *m = l1;
1609 expressionS exp;
1611 /* Ignore absolute addressing. make it PC relative anyway. */
1612 if (*m == '#' || *m == '$')
1613 m++;
1615 parse_exp (m, & exp);
1616 if (exp.X_op == O_symbol)
1618 /* Relaxation required. */
1619 struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
1621 frag = frag_more (8);
1622 bfd_putl16 ((bfd_vma) rc.sop, frag);
1623 frag = frag_variant (rs_machine_dependent, 8, 2,
1624 ENCODE_RELAX (rc.lpos, STATE_BITS10), /* Wild guess. */
1625 exp.X_add_symbol,
1626 0, /* Offset is zero if jump dist less than 1K. */
1627 (char *) frag);
1628 break;
1632 as_bad (_("instruction requires label"));
1633 break;
1635 case 5: /* Emulated extended branches. */
1636 line = extract_operand (line, l1, sizeof (l1));
1637 if (l1[0])
1639 char * m = l1;
1640 expressionS exp;
1642 /* Ignore absolute addressing. make it PC relative anyway. */
1643 if (*m == '#' || *m == '$')
1644 m++;
1646 parse_exp (m, & exp);
1647 if (exp.X_op == O_symbol)
1649 /* Relaxation required. */
1650 struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
1652 frag = frag_more (8);
1653 bfd_putl16 ((bfd_vma) hc.op0, frag);
1654 bfd_putl16 ((bfd_vma) hc.op1, frag+2);
1655 frag = frag_variant (rs_machine_dependent, 8, 2,
1656 ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10), /* Wild guess. */
1657 exp.X_add_symbol,
1658 0, /* Offset is zero if jump dist less than 1K. */
1659 (char *) frag);
1660 break;
1664 as_bad (_("instruction requires label"));
1665 break;
1667 default:
1668 as_bad (_("Ilegal instruction or not implmented opcode."));
1671 input_line_pointer = line;
1672 return 0;
1675 void
1676 md_assemble (char * str)
1678 struct msp430_opcode_s * opcode;
1679 char cmd[32];
1680 unsigned int i = 0;
1682 str = skip_space (str); /* Skip leading spaces. */
1683 str = extract_cmd (str, cmd, sizeof (cmd));
1685 while (cmd[i] && i < sizeof (cmd))
1687 char a = TOLOWER (cmd[i]);
1688 cmd[i] = a;
1689 i++;
1692 if (!cmd[0])
1694 as_bad (_("can't find opcode "));
1695 return;
1698 opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
1700 if (opcode == NULL)
1702 as_bad (_("unknown opcode `%s'"), cmd);
1703 return;
1707 char *__t = input_line_pointer;
1709 msp430_operands (opcode, str);
1710 input_line_pointer = __t;
1714 /* GAS will call this function for each section at the end of the assembly,
1715 to permit the CPU backend to adjust the alignment of a section. */
1717 valueT
1718 md_section_align (asection * seg, valueT addr)
1720 int align = bfd_get_section_alignment (stdoutput, seg);
1722 return ((addr + (1 << align) - 1) & (-1 << align));
1725 /* If you define this macro, it should return the offset between the
1726 address of a PC relative fixup and the position from which the PC
1727 relative adjustment should be made. On many processors, the base
1728 of a PC relative instruction is the next instruction, so this
1729 macro would return the length of an instruction. */
1731 long
1732 md_pcrel_from_section (fixS * fixp, segT sec)
1734 if (fixp->fx_addsy != (symbolS *) NULL
1735 && (!S_IS_DEFINED (fixp->fx_addsy)
1736 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1737 return 0;
1739 return fixp->fx_frag->fr_address + fixp->fx_where;
1742 /* GAS will call this for each fixup. It should store the correct
1743 value in the object file. */
1745 void
1746 md_apply_fix3 (fixS * fixp, valueT * valuep, segT seg)
1748 unsigned char * where;
1749 unsigned long insn;
1750 long value;
1752 if (fixp->fx_addsy == (symbolS *) NULL)
1754 value = *valuep;
1755 fixp->fx_done = 1;
1757 else if (fixp->fx_pcrel)
1759 segT s = S_GET_SEGMENT (fixp->fx_addsy);
1761 if (fixp->fx_addsy && (s == seg || s == absolute_section))
1763 value = S_GET_VALUE (fixp->fx_addsy) + *valuep;
1764 fixp->fx_done = 1;
1766 else
1767 value = *valuep;
1769 else
1771 value = fixp->fx_offset;
1773 if (fixp->fx_subsy != (symbolS *) NULL)
1775 if (S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1777 value -= S_GET_VALUE (fixp->fx_subsy);
1778 fixp->fx_done = 1;
1780 else
1782 /* We don't actually support subtracting a symbol. */
1783 as_bad_where (fixp->fx_file, fixp->fx_line,
1784 _("expression too complex"));
1789 switch (fixp->fx_r_type)
1791 default:
1792 fixp->fx_no_overflow = 1;
1793 break;
1794 case BFD_RELOC_MSP430_10_PCREL:
1795 break;
1798 if (fixp->fx_done)
1800 /* Fetch the instruction, insert the fully resolved operand
1801 value, and stuff the instruction back again. */
1803 where = fixp->fx_frag->fr_literal + fixp->fx_where;
1805 insn = bfd_getl16 (where);
1807 switch (fixp->fx_r_type)
1809 case BFD_RELOC_MSP430_10_PCREL:
1810 if (value & 1)
1811 as_bad_where (fixp->fx_file, fixp->fx_line,
1812 _("odd address operand: %ld"), value);
1814 /* Jumps are in words. */
1815 value >>= 1;
1816 --value; /* Correct PC. */
1818 if (value < -512 || value > 511)
1819 as_bad_where (fixp->fx_file, fixp->fx_line,
1820 _("operand out of range: %ld"), value);
1822 value &= 0x3ff; /* get rid of extended sign */
1823 bfd_putl16 ((bfd_vma) (value | insn), where);
1824 break;
1826 case BFD_RELOC_MSP430_RL_PCREL:
1827 case BFD_RELOC_MSP430_16_PCREL:
1828 if (value & 1)
1829 as_bad_where (fixp->fx_file, fixp->fx_line,
1830 _("odd address operand: %ld"), value);
1832 /* Nothing to be corrected here. */
1833 if (value < -32768 || value > 65536)
1834 as_bad_where (fixp->fx_file, fixp->fx_line,
1835 _("operand out of range: %ld"), value);
1837 value &= 0xffff; /* Get rid of extended sign. */
1838 bfd_putl16 ((bfd_vma) value, where);
1839 break;
1841 case BFD_RELOC_MSP430_16_PCREL_BYTE:
1842 /* Nothing to be corrected here. */
1843 if (value < -32768 || value > 65536)
1844 as_bad_where (fixp->fx_file, fixp->fx_line,
1845 _("operand out of range: %ld"), value);
1847 value &= 0xffff; /* Get rid of extended sign. */
1848 bfd_putl16 ((bfd_vma) value, where);
1849 break;
1851 case BFD_RELOC_32:
1852 bfd_putl16 ((bfd_vma) value, where);
1853 break;
1855 case BFD_RELOC_MSP430_16:
1856 case BFD_RELOC_16:
1857 case BFD_RELOC_MSP430_16_BYTE:
1858 value &= 0xffff;
1859 bfd_putl16 ((bfd_vma) value, where);
1860 break;
1862 default:
1863 as_fatal (_("line %d: unknown relocation type: 0x%x"),
1864 fixp->fx_line, fixp->fx_r_type);
1865 break;
1868 else
1870 fixp->fx_addnumber = value;
1874 /* A `BFD_ASSEMBLER' GAS will call this to generate a reloc. GAS
1875 will pass the resulting reloc to `bfd_install_relocation'. This
1876 currently works poorly, as `bfd_install_relocation' often does the
1877 wrong thing, and instances of `tc_gen_reloc' have been written to
1878 work around the problems, which in turns makes it difficult to fix
1879 `bfd_install_relocation'. */
1881 /* If while processing a fixup, a reloc really needs to be created
1882 then it is done here. */
1884 arelent *
1885 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1887 arelent * reloc;
1889 reloc = xmalloc (sizeof (arelent));
1891 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1892 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1894 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1895 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1896 if (reloc->howto == (reloc_howto_type *) NULL)
1898 as_bad_where (fixp->fx_file, fixp->fx_line,
1899 _("reloc %d not supported by object file format"),
1900 (int) fixp->fx_r_type);
1901 return NULL;
1904 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1905 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1906 reloc->address = fixp->fx_offset;
1908 reloc->addend = fixp->fx_offset;
1910 return reloc;
1914 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
1915 asection * segment_type ATTRIBUTE_UNUSED)
1917 if (fragP->fr_symbol && S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1919 /* This is a jump -> pcrel mode. Nothing to do much here.
1920 Return value == 2. */
1921 fragP->fr_subtype =
1922 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_BITS10);
1924 else if (fragP->fr_symbol)
1926 /* Its got a segment, but its not ours. Even if fr_symbol is in
1927 an absolute segment, we dont know a displacement until we link
1928 object files. So it will always be long. This also applies to
1929 labels in a subsegment of current. Liker may relax it to short
1930 jump later. Return value == 8. */
1931 fragP->fr_subtype =
1932 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_WORD);
1934 else
1936 /* We know the abs value. may be it is a jump to fixed address.
1937 Impossible in our case, cause all constants already handeled. */
1938 fragP->fr_subtype =
1939 ENCODE_RELAX (RELAX_LEN (fragP->fr_subtype), STATE_UNDEF);
1942 return md_relax_table[fragP->fr_subtype].rlx_length;
1945 void
1946 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1947 asection * sec ATTRIBUTE_UNUSED,
1948 fragS * fragP)
1950 char * where = 0;
1951 int rela = -1;
1952 int i;
1953 struct rcodes_s * cc = NULL;
1954 struct hcodes_s * hc = NULL;
1956 switch (fragP->fr_subtype)
1958 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_BITS10):
1959 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_BITS10):
1960 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_BITS10):
1961 /* We do not have to convert anything here.
1962 Just apply a fix. */
1963 rela = BFD_RELOC_MSP430_10_PCREL;
1964 break;
1966 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_WORD):
1967 case ENCODE_RELAX (STATE_UNCOND_BRANCH, STATE_UNDEF):
1968 /* Convert uncond branch jmp lab -> br lab. */
1969 cc = & msp430_rcodes[7];
1970 where = fragP->fr_literal + fragP->fr_fix;
1971 bfd_putl16 (cc->lop0, where);
1972 rela = BFD_RELOC_MSP430_RL_PCREL;
1973 fragP->fr_fix += 2;
1974 break;
1976 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_WORD):
1977 case ENCODE_RELAX (STATE_SIMPLE_BRANCH, STATE_UNDEF):
1979 /* Other simple branches. */
1980 int insn = bfd_getl16 (fragP->fr_opcode);
1982 insn &= 0xffff;
1983 /* Find actual instruction. */
1984 for (i = 0; i < 7 && !cc; i++)
1985 if (msp430_rcodes[i].sop == insn)
1986 cc = & msp430_rcodes[i];
1987 if (!cc || !cc->name)
1988 as_fatal (_("internal inconsistency problem in %s: insn %04lx"),
1989 __FUNCTION__, (long) insn);
1990 where = fragP->fr_literal + fragP->fr_fix;
1991 bfd_putl16 (cc->lop0, where);
1992 bfd_putl16 (cc->lop1, where + 2);
1993 rela = BFD_RELOC_MSP430_RL_PCREL;
1994 fragP->fr_fix += 4;
1996 break;
1998 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_WORD):
1999 case ENCODE_RELAX (STATE_NOOV_BRANCH, STATE_UNDEF):
2000 cc = & msp430_rcodes[6];
2001 where = fragP->fr_literal + fragP->fr_fix;
2002 bfd_putl16 (cc->lop0, where);
2003 bfd_putl16 (cc->lop1, where + 2);
2004 bfd_putl16 (cc->lop2, where + 4);
2005 rela = BFD_RELOC_MSP430_RL_PCREL;
2006 fragP->fr_fix += 6;
2007 break;
2009 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_BITS10):
2011 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2013 insn &= 0xffff;
2014 for (i = 0; i < 4 && !hc; i++)
2015 if (msp430_hcodes[i].op1 == insn)
2016 hc = &msp430_hcodes[i];
2017 if (!hc || !hc->name)
2018 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2019 __FUNCTION__, (long) insn);
2020 rela = BFD_RELOC_MSP430_10_PCREL;
2021 /* Apply a fix for a first label if necessary.
2022 another fix will be applied to the next word of insn anyway. */
2023 if (hc->tlab == 2)
2024 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2025 fragP->fr_offset, TRUE, rela);
2026 fragP->fr_fix += 2;
2029 break;
2031 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_WORD):
2032 case ENCODE_RELAX (STATE_EMUL_BRANCH, STATE_UNDEF):
2034 int insn = bfd_getl16 (fragP->fr_opcode + 2);
2036 insn &= 0xffff;
2037 for (i = 0; i < 4 && !hc; i++)
2038 if (msp430_hcodes[i].op1 == insn)
2039 hc = & msp430_hcodes[i];
2040 if (!hc || !hc->name)
2041 as_fatal (_("internal inconsistency problem in %s: ext. insn %04lx"),
2042 __FUNCTION__, (long) insn);
2043 rela = BFD_RELOC_MSP430_RL_PCREL;
2044 where = fragP->fr_literal + fragP->fr_fix;
2045 bfd_putl16 (hc->lop0, where);
2046 bfd_putl16 (hc->lop1, where + 2);
2047 bfd_putl16 (hc->lop2, where + 4);
2048 fragP->fr_fix += 6;
2050 break;
2052 default:
2053 as_fatal (_("internal inconsistency problem in %s: %lx"),
2054 __FUNCTION__, (long) fragP->fr_subtype);
2055 break;
2058 /* Now apply fix. */
2059 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
2060 fragP->fr_offset, TRUE, rela);
2061 /* Just fixed 2 bytes. */
2062 fragP->fr_fix += 2;
2065 /* Relax fragment. Mostly stolen from hc11 and mcore
2066 which arches I think I know. */
2068 long
2069 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED, fragS * fragP,
2070 long stretch ATTRIBUTE_UNUSED)
2072 long growth;
2073 offsetT aim = 0;
2074 symbolS *symbolP;
2075 const relax_typeS *this_type;
2076 const relax_typeS *start_type;
2077 relax_substateT next_state;
2078 relax_substateT this_state;
2079 const relax_typeS *table = md_relax_table;
2081 /* Nothing to be done if the frag has already max size. */
2082 if (RELAX_STATE (fragP->fr_subtype) == STATE_UNDEF
2083 || RELAX_STATE (fragP->fr_subtype) == STATE_WORD)
2084 return 0;
2086 if (RELAX_STATE (fragP->fr_subtype) == STATE_BITS10)
2088 symbolP = fragP->fr_symbol;
2089 if (symbol_resolved_p (symbolP))
2090 as_fatal (_("internal inconsistency problem in %s: resolved symbol"),
2091 __FUNCTION__);
2092 /* We know the offset. calculate a distance. */
2093 aim = S_GET_VALUE (symbolP) - fragP->fr_address - fragP->fr_fix;
2096 this_state = fragP->fr_subtype;
2097 start_type = this_type = table + this_state;
2099 if (aim < 0)
2101 /* Look backwards. */
2102 for (next_state = this_type->rlx_more; next_state;)
2103 if (aim >= this_type->rlx_backward)
2104 next_state = 0;
2105 else
2107 /* Grow to next state. */
2108 this_state = next_state;
2109 this_type = table + this_state;
2110 next_state = this_type->rlx_more;
2113 else
2115 /* Look forwards. */
2116 for (next_state = this_type->rlx_more; next_state;)
2117 if (aim <= this_type->rlx_forward)
2118 next_state = 0;
2119 else
2121 /* Grow to next state. */
2122 this_state = next_state;
2123 this_type = table + this_state;
2124 next_state = this_type->rlx_more;
2128 growth = this_type->rlx_length - start_type->rlx_length;
2129 if (growth != 0)
2130 fragP->fr_subtype = this_state;
2131 return growth;