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)
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. */
28 #define PUSH_1X_WORKAROUND
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
;
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
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
[] =
75 /* Unconditional jump. */
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. */
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 */
87 /* blt no overflow branch. */
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 */
93 /* Emulated branches. */
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 */
101 #define MAX_OP_LEN 256
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
},
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
219 .profiler flags,function_to_profile [, cycle_corrector, extra]
221 where 'flags' is a combination of the following chars:
224 i - function is in Init section
225 f - function is in Fini section
227 c - libC standard call
228 d - stack value Demand (saved at run-time in simulator)
229 I - Interrupt service routine
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.
245 ------------------------------
249 .LFrameOffset_fxx=0x08
250 .profiler "scdP", fxx ; function entry.
251 ; we also demand stack value to be displayed
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
261 .profiler cdE,fxx ; check stack
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
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 /* ? */
301 for (; x
; x
= x
>> 1)
308 /* Parse ordinary expression. */
311 parse_exp (char * s
, expressionS
* op
)
313 input_line_pointer
= s
;
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). */
324 del_spaces (char * s
)
332 while (ISSPACE (*m
) && *m
)
334 memmove (s
, m
, strlen (m
) + 1);
342 skip_space (char * s
)
349 /* Extract one word from FROM and copy it to TO. Delimeters are ",;\n" */
352 extract_operand (char * from
, char * to
, int limit
)
356 /* Drop leading whitespace. */
357 from
= skip_space (from
);
359 while (size
< limit
&& *from
)
361 *(to
+ size
) = *from
;
362 if (*from
== ',' || *from
== ';' || *from
== '\n')
377 msp430_profiler (int dummy ATTRIBUTE_UNUSED
)
394 s
= input_line_pointer
;
395 end
= input_line_pointer
;
397 while (*end
&& *end
!= '\n')
400 while (*s
&& *s
!= '\n')
411 as_bad (_(".profiler pseudo requires at least two operands."));
412 input_line_pointer
= end
;
416 input_line_pointer
= extract_operand (input_line_pointer
, flags
, 32);
425 p_flags
|= MSP430_PROFILER_FLAG_FRAGMENT
;
428 p_flags
|= MSP430_PROFILER_FLAG_JUMP
;
431 p_flags
|= MSP430_PROFILER_FLAG_PROLSTART
;
434 p_flags
|= MSP430_PROFILER_FLAG_PROLEND
;
437 p_flags
|= MSP430_PROFILER_FLAG_EPISTART
;
440 p_flags
|= MSP430_PROFILER_FLAG_EPIEND
;
443 p_flags
|= MSP430_PROFILER_FLAG_ENTRY
;
446 p_flags
|= MSP430_PROFILER_FLAG_EXIT
;
449 p_flags
|= MSP430_PROFILER_FLAG_INITSECT
;
452 p_flags
|= MSP430_PROFILER_FLAG_FINISECT
;
455 p_flags
|= MSP430_PROFILER_FLAG_LIBCALL
;
458 p_flags
|= MSP430_PROFILER_FLAG_STDCALL
;
461 p_flags
|= MSP430_PROFILER_FLAG_STACKDMD
;
464 p_flags
|= MSP430_PROFILER_FLAG_ISR
;
467 p_flags
|= MSP430_PROFILER_FLAG_EXTRA
;
470 as_warn (_("unknown profiling flag - ignored."));
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
;
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..."));
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. */
513 /* Now go to .profiler section. */
514 obj_elf_change_section (".profiler", SHT_PROGBITS
, 0, 0, 0, 0, 0);
517 emit_expr (& exp
, 2);
519 /* Save label value. */
520 emit_expr (& exp1
, 2);
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;
536 emit_expr (& exp
, 2);
538 /* Return to current section. */
539 subseg_set (seg
, subseg
);
543 extract_word (char * from
, char * to
, int limit
)
549 /* Drop leading whitespace. */
550 from
= skip_space (from
);
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
)
565 #define OPTION_MMCU 'm'
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
);
579 show_mcu_list (FILE * stream
)
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
)
599 for (i
= 0; mcu_types
[i
].name
; ++i
)
600 if (strcmp (mcu_types
[i
].name
, arg
) == 0)
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
];
612 as_fatal (_("redefinition of mcu type %s' to %s'"),
613 msp430_mcu
->name
, mcu_types
[i
].name
);
621 const pseudo_typeS md_pseudo_table
[] =
623 {"arch", msp430_set_arch
, 0},
624 {"profiler", msp430_profiler
, 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
);
639 md_show_usage (FILE * 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
);
669 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
675 extract_cmd (char * from
, char * to
, int limit
)
679 while (*from
&& ! ISSPACE (*from
) && *from
!= '.' && limit
> size
)
681 *(to
+ size
) = *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. */
697 md_atof (int type
, char * litP
, int * sizeP
)
700 LITTLENUM_TYPE words
[4];
701 LITTLENUM_TYPE
*wordP
;
714 return _("bad call to md_atof");
717 t
= atof_ieee (input_line_pointer
, type
, words
);
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
);
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
);
748 /* If this is a reg numb, str 't' must be a number from 0 - 15. */
750 if (strlen (t
) > 2 && *(t
+ 2) != '+')
755 if ((*t
< '0' || *t
> '9') && *t
!= '+')
768 msp430_srcoperand (struct msp430_operand_s
* op
,
769 char * l
, int bin
, int * imm_op
)
773 /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
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). */
789 if (strncasecmp (h
, "#llo(", 5) == 0)
794 else if (strncasecmp (h
, "#lhi(", 5) == 0)
799 else if (strncasecmp (h
, "#hlo(", 5) == 0)
804 else if (strncasecmp (h
, "#hhi(", 5) == 0)
809 else if (strncasecmp (h
, "#lo(", 4) == 0)
814 else if (strncasecmp (h
, "#hi(", 4) == 0)
820 op
->reg
= 0; /* Reg PC. */
822 op
->ol
= 1; /* Immediate will follow an instruction. */
826 parse_exp (__tl
, &(op
->exp
));
827 if (op
->exp
.X_op
== O_constant
)
829 int x
= op
->exp
.X_add_number
;
834 op
->exp
.X_add_number
= x
;
836 else if (vshift
== 1)
838 x
= (x
>> 16) & 0xffff;
839 op
->exp
.X_add_number
= x
;
844 op
->exp
.X_add_number
= -1;
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
);
856 /* Now check constants. */
857 /* Substitute register mode with a constant generator if applicable. */
859 x
= (short) x
; /* Extend sign. */
891 #ifdef PUSH_1X_WORKAROUND
894 /* Remove warning as confusing.
895 as_warn(_("Hardware push bug workaround")); */
908 #ifdef PUSH_1X_WORKAROUND
911 /* Remove warning as confusing.
912 as_warn(_("Hardware push bug workaround")); */
924 else if (op
->exp
.X_op
== O_symbol
)
928 else if (op
->exp
.X_op
== O_big
)
933 op
->exp
.X_op
= O_constant
;
934 op
->exp
.X_add_number
= 0xffff & generic_bignum
[vshift
];
935 x
= op
->exp
.X_add_number
;
940 ("unknown expression in operand %s. use #llo() #lhi() #hlo() #hhi() "),
988 /* Redudant (yet) check. */
989 else if (op
->exp
.X_op
== O_register
)
991 (_("Registers cannot be used within immediate expression [%s]"), l
);
993 as_bad (_("unknown operand %s"), l
);
998 /* Check if absolute &VALUE (assume that we can construct something like ((a&b)<<7 + 25). */
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. */
1007 parse_exp (__tl
, &(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
);
1019 else if (op
->exp
.X_op
== O_symbol
)
1023 /* Redudant (yet) check. */
1024 if (op
->exp
.X_op
== O_register
)
1026 (_("Registers cannot be used within absolute expression [%s]"), l
);
1028 as_bad (_("unknown expression in operand %s"), l
);
1034 /* Check if indirect register mode @Rn / postincrement @Rn+. */
1038 char *m
= strchr (l
, '+');
1042 as_bad (_("unknown addressing mode %s"), l
);
1047 if (*t
!= 'r' && *t
!= 'R')
1049 as_bad (_("unknown addressing mode %s"), l
);
1053 t
++; /* Points to the reg value. */
1057 as_bad (_("Bad register name r%s"), t
);
1065 *m
= 0; /* strip '+' */
1067 if (op
->reg
< 0 || op
->reg
> 15)
1069 as_bad (_("MSP430 does not have %d registers"), op
->reg
);
1076 /* Check if register indexed X(Rn). */
1079 char *h
= strrchr (l
, '(');
1080 char *m
= strrchr (l
, ')');
1089 as_bad (_("')' required"));
1096 /* Extract a register. */
1097 t
++; /* Advance pointer. */
1099 if (*t
!= 'r' && *t
!= 'R')
1102 ("unknown operator %s. Did you mean X(Rn) or #[hl][hl][oi](CONST) ?"),
1109 if (op
->reg
> 9 || op
->reg
< 0)
1111 as_bad (_("unknown operator (r%s substituded as a register name"),
1118 op
->reg
= op
->reg
* 10;
1119 op
->reg
+= *t
- '0';
1123 as_bad (_("unknown operator %s"), l
);
1128 as_bad (_("r2 should not be used in indexed addressing mode"));
1132 if (*(t
+ 1) != ')')
1134 as_bad (_("unknown operator %s"), l
);
1139 /* Extract constant. */
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
);
1162 else if (op
->exp
.X_op
== O_symbol
)
1166 /* Redudant (yet) check. */
1167 if (op
->exp
.X_op
== O_register
)
1169 (_("Registers cannot be used as a prefix of indexed expression [%s]"), l
);
1171 as_bad (_("unknown expression in operand %s"), l
);
1179 /* Register mode 'mov r1,r2'. */
1184 /* Operand should be a register. */
1185 if (*t
== 'r' || *t
== 'R')
1187 int x
= atoi (t
+ 1);
1189 if (check_reg (t
+ 1))
1192 if (x
< 0 || x
> 15)
1193 break; /* Symbolic mode. */
1204 /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */
1207 #if 0 /* Allow expression in operand like 'a+123*(1|2)'. */
1214 /* alpha/number underline dot for labels. */
1215 if (! ISALNUM (*t
) && *t
!= '_' && *t
!= '.')
1217 as_bad (_("unknown operand %s"), l
);
1224 op
->reg
= 0; /* PC relative... be careful. */
1228 parse_exp (__tl
, &(op
->exp
));
1234 as_bad (_("unknown addressing mode for operand %s"), l
);
1240 msp430_dstoperand (struct msp430_operand_s
* op
, char * l
, int bin
)
1243 int ret
= msp430_srcoperand (op
, l
, bin
, & dummy
);
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"),
1269 ("this addressing mode is not applicable for destination operand"));
1276 /* Parse instruction operands.
1277 Return binary opcode. */
1280 msp430_operands (struct msp430_opcode_s
* opcode
, char * line
)
1282 int bin
= opcode
->bin_opcode
; /* Opcode mask. */
1284 char l1
[MAX_OP_LEN
], l2
[MAX_OP_LEN
];
1287 struct msp430_operand_s op1
, op2
;
1289 static short ZEROS
= 0;
1290 int byte_op
, imm_op
;
1292 /* Opcode is the one from opcodes table
1293 line contains something like
1298 /* Check if byte or word operation. */
1299 if (*line
== '.' && TOLOWER (*(line
+ 1)) == 'b')
1301 bin
|= BYTE_OPERATION
;
1308 while (! ISSPACE (*line
) && *line
)
1311 if (opcode
->insn_opnumb
&& (!*line
|| *line
== '\n'))
1313 as_bad (_("instruction %s requires %d operand(s)"),
1314 opcode
->name
, opcode
->insn_opnumb
);
1318 memset (l1
, 0, sizeof (l1
));
1319 memset (l2
, 0, sizeof (l2
));
1320 memset (&op1
, 0, sizeof (op1
));
1321 memset (&op2
, 0, sizeof (op2
));
1325 switch (opcode
->fmt
)
1327 case 0: /* Emulated. */
1328 switch (opcode
->insn_opnumb
)
1331 /* Set/clear bits instructions. */
1333 frag
= frag_more (__is
);
1334 bfd_putl16 ((bfd_vma
) bin
, frag
);
1337 /* Something which works with destination operand. */
1338 line
= extract_operand (line
, l1
, sizeof (l1
));
1339 res
= msp430_dstoperand (&op1
, l1
, opcode
->bin_opcode
);
1343 bin
|= (op1
.reg
| (op1
.am
<< 7));
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
)
1352 bfd_putl16 ((bfd_vma
) ZEROS
, frag
+ 2);
1355 fix_new_exp (frag_now
, where
, 2,
1356 &(op1
.exp
), FALSE
, CHECK_RELOC_MSP430
);
1358 fix_new_exp (frag_now
, where
, 2,
1359 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
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
);
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
);
1391 fix_new_exp (frag_now
, where
, 2,
1392 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1395 if (op2
.mode
== OP_EXP
)
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
);
1404 fix_new_exp (frag_now
, where
+ 2, 2,
1405 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
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
);
1420 bin
|= ((op1
.reg
<< 8) | (op1
.am
<< 4));
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
)
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
);
1435 fix_new_exp (frag_now
, where
, 2,
1436 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
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
);
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
);
1467 fix_new_exp (frag_now
, where
, 2,
1468 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1471 if (op2
.mode
== OP_EXP
)
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
);
1480 fix_new_exp (frag_now
, where
+ 2, 2,
1481 &(op2
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
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
);
1494 line
= extract_operand (line
, l1
, sizeof (l1
));
1495 res
= msp430_srcoperand (&op1
, l1
, opcode
->bin_opcode
, &imm_op
);
1497 break; /* Error in operand. */
1499 bin
|= op1
.reg
| (op1
.am
<< 4);
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
);
1513 fix_new_exp (frag_now
, where
+ 2, 2,
1514 &(op1
.exp
), TRUE
, CHECK_RELOC_MSP430_PCREL
);
1518 case 3: /* Conditional jumps instructions. */
1519 line
= extract_operand (line
, l1
, sizeof (l1
));
1520 /* l1 is a label. */
1529 parse_exp (m
, &exp
);
1530 frag
= frag_more (2); /* Instr size is 1 word. */
1532 /* In order to handle something like:
1536 jz 4 ; skip next 4 bytes
1539 nop ; will jump here if r5 positive or zero
1541 jCOND -n ;assumes jump n bytes backward:
1551 jCOND $n ; jump from PC in either direction. */
1553 if (exp
.X_op
== O_constant
)
1555 int x
= exp
.X_add_number
;
1559 as_warn (_("Even number required. Rounded to %d"), x
+ 1);
1563 if ((*l1
== '$' && x
> 0) || x
< 0)
1568 if (x
> 512 || x
< -511)
1570 as_bad (_("Wrong displacement %d"), x
<< 1);
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 '$'"));
1593 ("instruction requires label or value in range -511:512"));
1599 as_bad (_("instruction requires label"));
1604 case 4: /* Extended jumps. */
1605 line
= extract_operand (line
, l1
, sizeof (l1
));
1611 /* Ignore absolute addressing. make it PC relative anyway. */
1612 if (*m
== '#' || *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. */
1626 0, /* Offset is zero if jump dist less than 1K. */
1632 as_bad (_("instruction requires label"));
1635 case 5: /* Emulated extended branches. */
1636 line
= extract_operand (line
, l1
, sizeof (l1
));
1642 /* Ignore absolute addressing. make it PC relative anyway. */
1643 if (*m
== '#' || *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. */
1658 0, /* Offset is zero if jump dist less than 1K. */
1664 as_bad (_("instruction requires label"));
1668 as_bad (_("Ilegal instruction or not implmented opcode."));
1671 input_line_pointer
= line
;
1676 md_assemble (char * str
)
1678 struct msp430_opcode_s
* opcode
;
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
]);
1694 as_bad (_("can't find opcode "));
1698 opcode
= (struct msp430_opcode_s
*) hash_find (msp430_hash
, cmd
);
1702 as_bad (_("unknown opcode `%s'"), cmd
);
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. */
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. */
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
)))
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. */
1746 md_apply_fix3 (fixS
* fixp
, valueT
* valuep
, segT seg
)
1748 unsigned char * where
;
1752 if (fixp
->fx_addsy
== (symbolS
*) NULL
)
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
;
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
);
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
)
1792 fixp
->fx_no_overflow
= 1;
1794 case BFD_RELOC_MSP430_10_PCREL
:
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
:
1811 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1812 _("odd address operand: %ld"), value
);
1814 /* Jumps are in words. */
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
);
1826 case BFD_RELOC_MSP430_RL_PCREL
:
1827 case BFD_RELOC_MSP430_16_PCREL
:
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
);
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
);
1852 bfd_putl16 ((bfd_vma
) value
, where
);
1855 case BFD_RELOC_MSP430_16
:
1857 case BFD_RELOC_MSP430_16_BYTE
:
1859 bfd_putl16 ((bfd_vma
) value
, where
);
1863 as_fatal (_("line %d: unknown relocation type: 0x%x"),
1864 fixp
->fx_line
, fixp
->fx_r_type
);
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. */
1885 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
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
);
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
;
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. */
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. */
1932 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_WORD
);
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. */
1939 ENCODE_RELAX (RELAX_LEN (fragP
->fr_subtype
), STATE_UNDEF
);
1942 return md_relax_table
[fragP
->fr_subtype
].rlx_length
;
1946 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1947 asection
* sec ATTRIBUTE_UNUSED
,
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
;
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
;
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
);
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
;
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
;
2009 case ENCODE_RELAX (STATE_EMUL_BRANCH
, STATE_BITS10
):
2011 int insn
= bfd_getl16 (fragP
->fr_opcode
+ 2);
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. */
2024 fix_new (fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
,
2025 fragP
->fr_offset
, TRUE
, rela
);
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);
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);
2053 as_fatal (_("internal inconsistency problem in %s: %lx"),
2054 __FUNCTION__
, (long) fragP
->fr_subtype
);
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. */
2065 /* Relax fragment. Mostly stolen from hc11 and mcore
2066 which arches I think I know. */
2069 msp430_relax_frag (segT seg ATTRIBUTE_UNUSED
, fragS
* fragP
,
2070 long stretch ATTRIBUTE_UNUSED
)
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
)
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"),
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
;
2101 /* Look backwards. */
2102 for (next_state
= this_type
->rlx_more
; next_state
;)
2103 if (aim
>= this_type
->rlx_backward
)
2107 /* Grow to next state. */
2108 this_state
= next_state
;
2109 this_type
= table
+ this_state
;
2110 next_state
= this_type
->rlx_more
;
2115 /* Look forwards. */
2116 for (next_state
= this_type
->rlx_more
; next_state
;)
2117 if (aim
<= this_type
->rlx_forward
)
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
;
2130 fragP
->fr_subtype
= this_state
;