x86: fix Solaris gas testsuite run
[binutils-gdb.git] / gas / config / tc-m32c.c
blobc29f754d4b2d499d4894c1b0fa2127389afe1515
1 /* tc-m32c.c -- Assembler for the Renesas M32C.
2 Copyright (C) 2005-2024 Free Software Foundation, Inc.
3 Contributed by RedHat.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "as.h"
23 #include "subsegs.h"
24 #include "symcat.h"
25 #include "opcodes/m32c-desc.h"
26 #include "opcodes/m32c-opc.h"
27 #include "cgen.h"
28 #include "elf/common.h"
29 #include "elf/m32c.h"
30 #include "safe-ctype.h"
32 /* Structure to hold all of the different components
33 describing an individual instruction. */
34 typedef struct
36 const CGEN_INSN * insn;
37 const CGEN_INSN * orig_insn;
38 CGEN_FIELDS fields;
39 #if CGEN_INT_INSN_P
40 CGEN_INSN_INT buffer [1];
41 #define INSN_VALUE(buf) (*(buf))
42 #else
43 unsigned char buffer [CGEN_MAX_INSN_SIZE];
44 #define INSN_VALUE(buf) (buf)
45 #endif
46 char * addr;
47 fragS * frag;
48 int num_fixups;
49 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
50 int indices [MAX_OPERAND_INSTANCES];
52 m32c_insn;
54 #define rl_for(_insn) (CGEN_ATTR_CGEN_INSN_RL_TYPE_VALUE (&((_insn).insn->base->attrs)))
55 #define relaxable(_insn) (CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE (&((_insn).insn->base->attrs)))
57 const char comment_chars[] = ";";
58 const char line_comment_chars[] = "#";
59 const char line_separator_chars[] = "|";
60 const char EXP_CHARS[] = "eE";
61 const char FLT_CHARS[] = "dD";
63 #define M32C_SHORTOPTS ""
64 const char * md_shortopts = M32C_SHORTOPTS;
66 /* assembler options */
67 #define OPTION_CPU_M16C (OPTION_MD_BASE)
68 #define OPTION_CPU_M32C (OPTION_MD_BASE + 1)
69 #define OPTION_LINKRELAX (OPTION_MD_BASE + 2)
70 #define OPTION_H_TICK_HEX (OPTION_MD_BASE + 3)
72 struct option md_longopts[] =
74 { "m16c", no_argument, NULL, OPTION_CPU_M16C },
75 { "m32c", no_argument, NULL, OPTION_CPU_M32C },
76 { "relax", no_argument, NULL, OPTION_LINKRELAX },
77 { "h-tick-hex", no_argument, NULL, OPTION_H_TICK_HEX },
78 {NULL, no_argument, NULL, 0}
80 size_t md_longopts_size = sizeof (md_longopts);
82 /* Default machine */
84 #define DEFAULT_MACHINE bfd_mach_m16c
85 #define DEFAULT_FLAGS EF_M32C_CPU_M16C
87 static unsigned long m32c_mach = bfd_mach_m16c;
88 static int cpu_mach = (1 << MACH_M16C);
89 static int m32c_relax = 0;
91 /* Flags to set in the elf header */
92 static flagword m32c_flags = DEFAULT_FLAGS;
94 static char default_isa = 1 << (7 - ISA_M16C);
95 static CGEN_BITSET m32c_isa = {1, & default_isa};
97 static void
98 set_isa (enum isa_attr isa_num)
100 cgen_bitset_set (& m32c_isa, isa_num);
104 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
106 switch (c)
108 case OPTION_CPU_M16C:
109 m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M16C;
110 m32c_mach = bfd_mach_m16c;
111 cpu_mach = (1 << MACH_M16C);
112 set_isa (ISA_M16C);
113 break;
115 case OPTION_CPU_M32C:
116 m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M32C;
117 m32c_mach = bfd_mach_m32c;
118 cpu_mach = (1 << MACH_M32C);
119 set_isa (ISA_M32C);
120 break;
122 case OPTION_LINKRELAX:
123 m32c_relax = 1;
124 break;
126 case OPTION_H_TICK_HEX:
127 enable_h_tick_hex = 1;
128 break;
130 default:
131 return 0;
133 return 1;
136 void
137 md_show_usage (FILE * stream)
139 fprintf (stream, _(" M32C specific command line options:\n"));
142 /* The target specific pseudo-ops which we support. */
143 const pseudo_typeS md_pseudo_table[] =
145 { "3byte", cons, 3 },
146 { "word", cons, 4 },
147 { NULL, NULL, 0 }
151 void
152 md_begin (void)
154 /* Initialize the `cgen' interface. */
156 /* Set the machine number and endian. */
157 gas_cgen_cpu_desc = m32c_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
158 CGEN_CPU_OPEN_ENDIAN,
159 CGEN_ENDIAN_BIG,
160 CGEN_CPU_OPEN_ISAS, & m32c_isa,
161 CGEN_CPU_OPEN_END);
163 m32c_cgen_init_asm (gas_cgen_cpu_desc);
165 /* This is a callback from cgen to gas to parse operands. */
166 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
168 /* Set the ELF flags if desired. */
169 if (m32c_flags)
170 bfd_set_private_flags (stdoutput, m32c_flags);
172 /* Set the machine type */
173 bfd_default_set_arch_mach (stdoutput, bfd_arch_m32c, m32c_mach);
176 void
177 m32c_start_line_hook (void)
179 #if 0 /* not necessary....handled in the .cpu file */
180 char *s = input_line_pointer;
181 char *sg;
183 for (s = input_line_pointer ; s && s[0] != '\n'; s++)
185 if (s[0] == ':')
187 /* Remove :g suffix. Squeeze out blanks. */
188 if (s[1] == 'g')
190 for (sg = s - 1; sg && sg >= input_line_pointer; sg--)
192 sg[2] = sg[0];
194 sg[1] = ' ';
195 sg[2] = ' ';
196 input_line_pointer += 2;
200 #endif
203 /* Process [[indirect-operands]] in instruction str. */
205 static bool
206 m32c_indirect_operand (char *str)
208 char *new_str;
209 char *s;
210 char *ns;
211 int ns_len;
212 char *ns_end;
213 enum indirect_type {none, relative, absolute} ;
214 enum indirect_type indirection [3] = { none, none, none };
215 int brace_n [3] = { 0, 0, 0 };
216 int operand;
218 s = str;
219 operand = 1;
220 for (s = str; *s; s++)
222 if (s[0] == ',')
223 operand = 2;
224 /* [abs] where abs is not a0 or a1 */
225 if (s[1] == '[' && ! (s[2] == 'a' && (s[3] == '0' || s[3] == '1'))
226 && (ISBLANK (s[0]) || s[0] == ','))
227 indirection[operand] = absolute;
228 if (s[0] == ']' && s[1] == ']')
229 indirection[operand] = relative;
230 if (s[0] == '[' && s[1] == '[')
231 indirection[operand] = relative;
234 if (indirection[1] == none && indirection[2] == none)
235 return false;
237 operand = 1;
238 ns_len = strlen (str);
239 new_str = XNEWVEC (char, ns_len);
240 ns = new_str;
241 ns_end = ns + ns_len;
243 for (s = str; *s; s++)
245 if (s[0] == ',')
246 operand = 2;
248 if (s[0] == '[' && ! brace_n[operand])
250 brace_n[operand] += 1;
251 /* Squeeze [[ to [ if this is an indirect operand. */
252 if (indirection[operand] != none)
253 continue;
256 else if (s[0] == '[' && brace_n[operand])
258 brace_n[operand] += 1;
260 else if (s[0] == ']' && s[1] == ']' && indirection[operand] == relative)
262 s += 1; /* skip one ]. */
263 brace_n[operand] -= 2; /* allow for 2 [. */
265 else if (s[0] == ']' && indirection[operand] == absolute)
267 brace_n[operand] -= 1;
268 continue; /* skip closing ]. */
270 else if (s[0] == ']')
272 brace_n[operand] -= 1;
274 *ns = s[0];
275 ns += 1;
276 if (ns >= ns_end)
277 return false;
278 if (s[0] == 0)
279 break;
281 *ns = '\0';
282 for (operand = 1; operand <= 2; operand++)
283 if (brace_n[operand])
285 fprintf (stderr, "Unmatched [[operand-%d]] %d\n", operand, brace_n[operand]);
288 if (indirection[1] != none && indirection[2] != none)
289 md_assemble ((char *) "src-dest-indirect");
290 else if (indirection[1] != none)
291 md_assemble ((char *) "src-indirect");
292 else if (indirection[2] != none)
293 md_assemble ((char *) "dest-indirect");
295 md_assemble (new_str);
296 free (new_str);
297 return true;
300 void
301 md_assemble (char * str)
303 static int last_insn_had_delay_slot = 0;
304 m32c_insn insn;
305 char * errmsg;
306 finished_insnS results;
307 int rl_type;
308 int insn_size;
310 if (m32c_mach == bfd_mach_m32c && m32c_indirect_operand (str))
311 return;
313 /* Initialize GAS's cgen interface for a new instruction. */
314 gas_cgen_init_parse ();
316 insn.insn = m32c_cgen_assemble_insn
317 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
319 if (!insn.insn)
321 as_bad ("%s", errmsg);
322 return;
325 results.num_fixups = 0;
326 /* Doesn't really matter what we pass for RELAX_P here. */
327 gas_cgen_finish_insn (insn.insn, insn.buffer,
328 CGEN_FIELDS_BITSIZE (& insn.fields), 1, &results);
330 last_insn_had_delay_slot
331 = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
332 (void) last_insn_had_delay_slot;
333 insn_size = CGEN_INSN_BITSIZE(insn.insn);
335 rl_type = rl_for (insn);
337 /* We have to mark all the jumps, because we need to adjust them
338 when we delete bytes, but we only need to mark the displacements
339 if they're symbolic - if they're not, we've already picked the
340 shortest opcode by now. The linker, however, will still have to
341 check any operands to see if they're the displacement type, since
342 we don't know (nor record) *which* operands are relaxable. */
343 if (m32c_relax
344 && rl_type != RL_TYPE_NONE
345 && (rl_type == RL_TYPE_JUMP || results.num_fixups)
346 && !relaxable (insn))
348 int reloc = 0;
349 int addend = results.num_fixups + 16 * insn_size/8;
351 switch (rl_for (insn))
353 case RL_TYPE_JUMP: reloc = BFD_RELOC_M32C_RL_JUMP; break;
354 case RL_TYPE_1ADDR: reloc = BFD_RELOC_M32C_RL_1ADDR; break;
355 case RL_TYPE_2ADDR: reloc = BFD_RELOC_M32C_RL_2ADDR; break;
357 if (insn.insn->base->num == M32C_INSN_JMP16_S
358 || insn.insn->base->num == M32C_INSN_JMP32_S)
359 addend = 0x10;
361 fix_new (results.frag,
362 results.addr - results.frag->fr_literal,
363 0, abs_section_sym, addend, 0,
364 reloc);
368 /* The syntax in the manual says constants begin with '#'.
369 We just ignore it. */
371 void
372 md_operand (expressionS * exp)
374 /* In case of a syntax error, escape back to try next syntax combo. */
375 if (exp->X_op == O_absent)
376 gas_cgen_md_operand (exp);
379 valueT
380 md_section_align (segT segment, valueT size)
382 int align = bfd_section_alignment (segment);
383 return ((size + (1 << align) - 1) & -(1 << align));
386 symbolS *
387 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
389 return 0;
392 const relax_typeS md_relax_table[] =
394 /* The fields are:
395 1) most positive reach of this state,
396 2) most negative reach of this state,
397 3) how many bytes this mode will have in the variable part of the frag
398 4) which index into the table to try if we can't fit into this one. */
400 /* 0 */ { 0, 0, 0, 0 }, /* unused */
401 /* 1 */ { 0, 0, 0, 0 }, /* marker for "don't know yet" */
403 /* 2 */ { 127, -128, 2, 3 }, /* jcnd16_5.b */
404 /* 3 */ { 32767, -32768, 5, 4 }, /* jcnd16_5.w */
405 /* 4 */ { 0, 0, 6, 0 }, /* jcnd16_5.a */
407 /* 5 */ { 127, -128, 2, 6 }, /* jcnd16.b */
408 /* 6 */ { 32767, -32768, 5, 7 }, /* jcnd16.w */
409 /* 7 */ { 0, 0, 6, 0 }, /* jcnd16.a */
411 /* 8 */ { 8, 1, 1, 9 }, /* jmp16.s */
412 /* 9 */ { 127, -128, 2, 10 }, /* jmp16.b */
413 /* 10 */ { 32767, -32768, 3, 11 }, /* jmp16.w */
414 /* 11 */ { 0, 0, 4, 0 }, /* jmp16.a */
416 /* 12 */ { 127, -128, 2, 13 }, /* jcnd32.b */
417 /* 13 */ { 32767, -32768, 5, 14 }, /* jcnd32.w */
418 /* 14 */ { 0, 0, 6, 0 }, /* jcnd32.a */
420 /* 15 */ { 8, 1, 1, 16 }, /* jmp32.s */
421 /* 16 */ { 127, -128, 2, 17 }, /* jmp32.b */
422 /* 17 */ { 32767, -32768, 3, 18 }, /* jmp32.w */
423 /* 18 */ { 0, 0, 4, 0 }, /* jmp32.a */
425 /* 19 */ { 32767, -32768, 3, 20 }, /* jsr16.w */
426 /* 20 */ { 0, 0, 4, 0 }, /* jsr16.a */
427 /* 21 */ { 32767, -32768, 3, 11 }, /* jsr32.w */
428 /* 22 */ { 0, 0, 4, 0 }, /* jsr32.a */
430 /* 23 */ { 0, 0, 3, 0 }, /* adjnz pc8 */
431 /* 24 */ { 0, 0, 4, 0 }, /* adjnz disp8 pc8 */
432 /* 25 */ { 0, 0, 5, 0 }, /* adjnz disp16 pc8 */
433 /* 26 */ { 0, 0, 6, 0 } /* adjnz disp24 pc8 */
436 enum {
437 M32C_MACRO_JCND16_5_W,
438 M32C_MACRO_JCND16_5_A,
439 M32C_MACRO_JCND16_W,
440 M32C_MACRO_JCND16_A,
441 M32C_MACRO_JCND32_W,
442 M32C_MACRO_JCND32_A,
443 /* the digit is the array index of the pcrel byte */
444 M32C_MACRO_ADJNZ_2,
445 M32C_MACRO_ADJNZ_3,
446 M32C_MACRO_ADJNZ_4,
447 M32C_MACRO_ADJNZ_5,
450 static struct {
451 int insn;
452 int bytes;
453 int insn_for_extern;
454 int pcrel_aim_offset;
455 } subtype_mappings[] = {
456 /* 0 */ { 0, 0, 0, 0 },
457 /* 1 */ { 0, 0, 0, 0 },
459 /* 2 */ { M32C_INSN_JCND16_5, 2, -M32C_MACRO_JCND16_5_A, 1 },
460 /* 3 */ { -M32C_MACRO_JCND16_5_W, 5, -M32C_MACRO_JCND16_5_A, 4 },
461 /* 4 */ { -M32C_MACRO_JCND16_5_A, 6, -M32C_MACRO_JCND16_5_A, 0 },
463 /* 5 */ { M32C_INSN_JCND16, 3, -M32C_MACRO_JCND16_A, 1 },
464 /* 6 */ { -M32C_MACRO_JCND16_W, 6, -M32C_MACRO_JCND16_A, 4 },
465 /* 7 */ { -M32C_MACRO_JCND16_A, 7, -M32C_MACRO_JCND16_A, 0 },
467 /* 8 */ { M32C_INSN_JMP16_S, 1, M32C_INSN_JMP16_A, 0 },
468 /* 9 */ { M32C_INSN_JMP16_B, 2, M32C_INSN_JMP16_A, 1 },
469 /* 10 */ { M32C_INSN_JMP16_W, 3, M32C_INSN_JMP16_A, 2 },
470 /* 11 */ { M32C_INSN_JMP16_A, 4, M32C_INSN_JMP16_A, 0 },
472 /* 12 */ { M32C_INSN_JCND32, 2, -M32C_MACRO_JCND32_A, 1 },
473 /* 13 */ { -M32C_MACRO_JCND32_W, 5, -M32C_MACRO_JCND32_A, 4 },
474 /* 14 */ { -M32C_MACRO_JCND32_A, 6, -M32C_MACRO_JCND32_A, 0 },
476 /* 15 */ { M32C_INSN_JMP32_S, 1, M32C_INSN_JMP32_A, 0 },
477 /* 16 */ { M32C_INSN_JMP32_B, 2, M32C_INSN_JMP32_A, 1 },
478 /* 17 */ { M32C_INSN_JMP32_W, 3, M32C_INSN_JMP32_A, 2 },
479 /* 18 */ { M32C_INSN_JMP32_A, 4, M32C_INSN_JMP32_A, 0 },
481 /* 19 */ { M32C_INSN_JSR16_W, 3, M32C_INSN_JSR16_A, 2 },
482 /* 20 */ { M32C_INSN_JSR16_A, 4, M32C_INSN_JSR16_A, 0 },
483 /* 21 */ { M32C_INSN_JSR32_W, 3, M32C_INSN_JSR32_A, 2 },
484 /* 22 */ { M32C_INSN_JSR32_A, 4, M32C_INSN_JSR32_A, 0 },
486 /* 23 */ { -M32C_MACRO_ADJNZ_2, 3, -M32C_MACRO_ADJNZ_2, 0 },
487 /* 24 */ { -M32C_MACRO_ADJNZ_3, 4, -M32C_MACRO_ADJNZ_3, 0 },
488 /* 25 */ { -M32C_MACRO_ADJNZ_4, 5, -M32C_MACRO_ADJNZ_4, 0 },
489 /* 26 */ { -M32C_MACRO_ADJNZ_5, 6, -M32C_MACRO_ADJNZ_5, 0 }
491 #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
493 void
494 m32c_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
496 symbolS *symbolP = fragP->fr_symbol;
497 if (symbolP && !S_IS_DEFINED (symbolP))
498 *aim = 0;
499 /* Adjust for m32c pcrel not being relative to the next opcode. */
500 *aim += subtype_mappings[this_state].pcrel_aim_offset;
503 static int
504 insn_to_subtype (int inum, const CGEN_INSN *insn)
506 unsigned int i;
508 if (insn
509 && (startswith (insn->base->mnemonic, "adjnz")
510 || startswith (insn->base->mnemonic, "sbjnz")))
512 i = 23 + insn->base->bitsize/8 - 3;
513 /*printf("mapping %d used for %s\n", i, insn->base->mnemonic);*/
514 return i;
517 for (i=0; i<NUM_MAPPINGS; i++)
518 if (inum == subtype_mappings[i].insn)
520 /*printf("mapping %d used\n", i);*/
521 return i;
523 abort ();
526 /* Return an initial guess of the length by which a fragment must grow to
527 hold a branch to reach its destination.
528 Also updates fr_type/fr_subtype as necessary.
530 Called just before doing relaxation.
531 Any symbol that is now undefined will not become defined.
532 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
533 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
534 Although it may not be explicit in the frag, pretend fr_var starts with a
535 0 value. */
538 md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
540 int where = fragP->fr_opcode - fragP->fr_literal;
542 if (fragP->fr_subtype == 1)
543 fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num, fragP->fr_cgen.insn);
545 if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
547 int new_insn;
549 new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
550 fragP->fr_subtype = insn_to_subtype (new_insn, 0);
553 if (fragP->fr_cgen.insn->base
554 && fragP->fr_cgen.insn->base->num
555 != subtype_mappings[fragP->fr_subtype].insn
556 && subtype_mappings[fragP->fr_subtype].insn > 0)
558 int new_insn= subtype_mappings[fragP->fr_subtype].insn;
559 if (new_insn >= 0)
561 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
562 - fragP->fr_cgen.insn->base->num
563 + new_insn);
567 return subtype_mappings[fragP->fr_subtype].bytes - (fragP->fr_fix - where);
570 /* *fragP has been relaxed to its final size, and now needs to have
571 the bytes inside it modified to conform to the new size.
573 Called after relaxation is finished.
574 fragP->fr_type == rs_machine_dependent.
575 fragP->fr_subtype is the subtype of what the address relaxed to. */
577 static int
578 target_address_for (fragS *frag)
580 int rv = frag->fr_offset;
581 symbolS *sym = frag->fr_symbol;
583 if (sym)
584 rv += S_GET_VALUE (sym);
586 /*printf("target_address_for returns %d\n", rv);*/
587 return rv;
590 void
591 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
592 segT sec ATTRIBUTE_UNUSED,
593 fragS * fragP ATTRIBUTE_UNUSED)
595 int addend;
596 int operand;
597 int where = fragP->fr_opcode - fragP->fr_literal;
598 int rl_where = fragP->fr_opcode - fragP->fr_literal;
599 unsigned char *op = (unsigned char *)fragP->fr_opcode;
600 int rl_addend = 0;
602 addend = target_address_for (fragP) - (fragP->fr_address + where);
604 fragP->fr_fix = where + subtype_mappings[fragP->fr_subtype].bytes;
606 switch (subtype_mappings[fragP->fr_subtype].insn)
608 case M32C_INSN_JCND16_5:
609 op[1] = addend - 1;
610 operand = M32C_OPERAND_LAB_8_8;
611 rl_addend = 0x21;
612 break;
614 case -M32C_MACRO_JCND16_5_W:
615 op[0] ^= 0x04;
616 op[1] = 4;
617 op[2] = 0xf4;
618 op[3] = addend - 3;
619 op[4] = (addend - 3) >> 8;
620 operand = M32C_OPERAND_LAB_8_16;
621 where += 2;
622 rl_addend = 0x51;
623 break;
625 case -M32C_MACRO_JCND16_5_A:
626 op[0] ^= 0x04;
627 op[1] = 5;
628 op[2] = 0xfc;
629 operand = M32C_OPERAND_LAB_8_24;
630 where += 2;
631 rl_addend = 0x61;
632 break;
635 case M32C_INSN_JCND16:
636 op[2] = addend - 2;
637 operand = M32C_OPERAND_LAB_16_8;
638 rl_addend = 0x31;
639 break;
641 case -M32C_MACRO_JCND16_W:
642 op[1] ^= 0x04;
643 op[2] = 4;
644 op[3] = 0xf4;
645 op[4] = addend - 4;
646 op[5] = (addend - 4) >> 8;
647 operand = M32C_OPERAND_LAB_8_16;
648 where += 3;
649 rl_addend = 0x61;
650 break;
652 case -M32C_MACRO_JCND16_A:
653 op[1] ^= 0x04;
654 op[2] = 5;
655 op[3] = 0xfc;
656 operand = M32C_OPERAND_LAB_8_24;
657 where += 3;
658 rl_addend = 0x71;
659 break;
661 case M32C_INSN_JMP16_S:
662 op[0] = 0x60 | ((addend-2) & 0x07);
663 operand = M32C_OPERAND_LAB_5_3;
664 rl_addend = 0x10;
665 break;
667 case M32C_INSN_JMP16_B:
668 op[0] = 0xfe;
669 op[1] = addend - 1;
670 operand = M32C_OPERAND_LAB_8_8;
671 rl_addend = 0x21;
672 break;
674 case M32C_INSN_JMP16_W:
675 op[0] = 0xf4;
676 op[1] = addend - 1;
677 op[2] = (addend - 1) >> 8;
678 operand = M32C_OPERAND_LAB_8_16;
679 rl_addend = 0x31;
680 break;
682 case M32C_INSN_JMP16_A:
683 op[0] = 0xfc;
684 op[1] = 0;
685 op[2] = 0;
686 op[3] = 0;
687 operand = M32C_OPERAND_LAB_8_24;
688 rl_addend = 0x41;
689 break;
691 case M32C_INSN_JCND32:
692 op[1] = addend - 1;
693 operand = M32C_OPERAND_LAB_8_8;
694 rl_addend = 0x21;
695 break;
697 case -M32C_MACRO_JCND32_W:
698 op[0] ^= 0x40;
699 op[1] = 4;
700 op[2] = 0xce;
701 op[3] = addend - 3;
702 op[4] = (addend - 3) >> 8;
703 operand = M32C_OPERAND_LAB_8_16;
704 where += 2;
705 rl_addend = 0x51;
706 break;
708 case -M32C_MACRO_JCND32_A:
709 op[0] ^= 0x40;
710 op[1] = 5;
711 op[2] = 0xcc;
712 operand = M32C_OPERAND_LAB_8_24;
713 where += 2;
714 rl_addend = 0x61;
715 break;
717 case M32C_INSN_JMP32_S:
718 addend = ((addend-2) & 0x07);
719 op[0] = 0x4a | (addend & 0x01) | ((addend << 3) & 0x30);
720 operand = M32C_OPERAND_LAB32_JMP_S;
721 rl_addend = 0x10;
722 break;
724 case M32C_INSN_JMP32_B:
725 op[0] = 0xbb;
726 op[1] = addend - 1;
727 operand = M32C_OPERAND_LAB_8_8;
728 rl_addend = 0x21;
729 break;
731 case M32C_INSN_JMP32_W:
732 op[0] = 0xce;
733 op[1] = addend - 1;
734 op[2] = (addend - 1) >> 8;
735 operand = M32C_OPERAND_LAB_8_16;
736 rl_addend = 0x31;
737 break;
739 case M32C_INSN_JMP32_A:
740 op[0] = 0xcc;
741 op[1] = 0;
742 op[2] = 0;
743 op[3] = 0;
744 operand = M32C_OPERAND_LAB_8_24;
745 rl_addend = 0x41;
746 break;
749 case M32C_INSN_JSR16_W:
750 op[0] = 0xf5;
751 op[1] = addend - 1;
752 op[2] = (addend - 1) >> 8;
753 operand = M32C_OPERAND_LAB_8_16;
754 rl_addend = 0x31;
755 break;
757 case M32C_INSN_JSR16_A:
758 op[0] = 0xfd;
759 op[1] = 0;
760 op[2] = 0;
761 op[3] = 0;
762 operand = M32C_OPERAND_LAB_8_24;
763 rl_addend = 0x41;
764 break;
766 case M32C_INSN_JSR32_W:
767 op[0] = 0xcf;
768 op[1] = addend - 1;
769 op[2] = (addend - 1) >> 8;
770 operand = M32C_OPERAND_LAB_8_16;
771 rl_addend = 0x31;
772 break;
774 case M32C_INSN_JSR32_A:
775 op[0] = 0xcd;
776 op[1] = 0;
777 op[2] = 0;
778 op[3] = 0;
779 operand = M32C_OPERAND_LAB_8_24;
780 rl_addend = 0x41;
781 break;
783 case -M32C_MACRO_ADJNZ_2:
784 rl_addend = 0x31;
785 op[2] = addend - 2;
786 operand = M32C_OPERAND_LAB_16_8;
787 break;
788 case -M32C_MACRO_ADJNZ_3:
789 rl_addend = 0x41;
790 op[3] = addend - 2;
791 operand = M32C_OPERAND_LAB_24_8;
792 break;
793 case -M32C_MACRO_ADJNZ_4:
794 rl_addend = 0x51;
795 op[4] = addend - 2;
796 operand = M32C_OPERAND_LAB_32_8;
797 break;
798 case -M32C_MACRO_ADJNZ_5:
799 rl_addend = 0x61;
800 op[5] = addend - 2;
801 operand = M32C_OPERAND_LAB_40_8;
802 break;
804 default:
805 printf("\nHey! Need more opcode converters! missing: %d %s\n\n",
806 fragP->fr_subtype,
807 fragP->fr_cgen.insn->base->name);
808 abort();
811 if (m32c_relax)
813 if (operand != M32C_OPERAND_LAB_8_24)
814 fragP->fr_offset = (fragP->fr_address + where);
816 fix_new (fragP,
817 rl_where,
818 0, abs_section_sym, rl_addend, 0,
819 BFD_RELOC_M32C_RL_JUMP);
822 if (S_GET_SEGMENT (fragP->fr_symbol) != sec
823 || operand == M32C_OPERAND_LAB_8_24
824 || (m32c_relax && (operand != M32C_OPERAND_LAB_5_3
825 && operand != M32C_OPERAND_LAB32_JMP_S)))
827 gas_assert (fragP->fr_cgen.insn != 0);
828 gas_cgen_record_fixup (fragP,
829 where,
830 fragP->fr_cgen.insn,
831 (fragP->fr_fix - where) * 8,
832 cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
833 operand),
834 fragP->fr_cgen.opinfo,
835 fragP->fr_symbol,
836 fragP->fr_offset);
840 /* Functions concerning relocs. */
842 /* The location from which a PC relative jump should be calculated,
843 given a PC relative reloc. */
845 long
846 md_pcrel_from_section (fixS * fixP, segT sec)
848 if (fixP->fx_addsy != (symbolS *) NULL
849 && (! S_IS_DEFINED (fixP->fx_addsy)
850 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
851 /* The symbol is undefined (or is defined but not in this section).
852 Let the linker figure it out. */
853 return 0;
855 return (fixP->fx_frag->fr_address + fixP->fx_where);
858 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
859 Returns BFD_RELOC_NONE if no reloc type can be found.
860 *FIXP may be modified if desired. */
862 bfd_reloc_code_real_type
863 md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
864 const CGEN_OPERAND * operand,
865 fixS * fixP ATTRIBUTE_UNUSED)
867 static const struct op_reloc {
868 /* A CGEN operand type that can be a relocatable expression. */
869 CGEN_OPERAND_TYPE operand;
871 /* The appropriate BFD reloc type to use for that. */
872 bfd_reloc_code_real_type reloc;
874 /* The offset from the start of the instruction to the field to be
875 relocated, in bytes. */
876 int offset;
877 } op_reloc_table[] = {
879 /* PC-REL relocs for 8-bit fields. */
880 { M32C_OPERAND_LAB_8_8, BFD_RELOC_8_PCREL, 1 },
881 { M32C_OPERAND_LAB_16_8, BFD_RELOC_8_PCREL, 2 },
882 { M32C_OPERAND_LAB_24_8, BFD_RELOC_8_PCREL, 3 },
883 { M32C_OPERAND_LAB_32_8, BFD_RELOC_8_PCREL, 4 },
884 { M32C_OPERAND_LAB_40_8, BFD_RELOC_8_PCREL, 5 },
886 /* PC-REL relocs for 16-bit fields. */
887 { M32C_OPERAND_LAB_8_16, BFD_RELOC_16_PCREL, 1 },
889 /* Absolute relocs for 8-bit fields. */
890 { M32C_OPERAND_IMM_8_QI, BFD_RELOC_8, 1 },
891 { M32C_OPERAND_IMM_16_QI, BFD_RELOC_8, 2 },
892 { M32C_OPERAND_IMM_24_QI, BFD_RELOC_8, 3 },
893 { M32C_OPERAND_IMM_32_QI, BFD_RELOC_8, 4 },
894 { M32C_OPERAND_IMM_40_QI, BFD_RELOC_8, 5 },
895 { M32C_OPERAND_IMM_48_QI, BFD_RELOC_8, 6 },
896 { M32C_OPERAND_IMM_56_QI, BFD_RELOC_8, 7 },
897 { M32C_OPERAND_DSP_8_S8, BFD_RELOC_8, 1 },
898 { M32C_OPERAND_DSP_16_S8, BFD_RELOC_8, 2 },
899 { M32C_OPERAND_DSP_24_S8, BFD_RELOC_8, 3 },
900 { M32C_OPERAND_DSP_32_S8, BFD_RELOC_8, 4 },
901 { M32C_OPERAND_DSP_40_S8, BFD_RELOC_8, 5 },
902 { M32C_OPERAND_DSP_48_S8, BFD_RELOC_8, 6 },
903 { M32C_OPERAND_DSP_8_U8, BFD_RELOC_8, 1 },
904 { M32C_OPERAND_DSP_16_U8, BFD_RELOC_8, 2 },
905 { M32C_OPERAND_DSP_24_U8, BFD_RELOC_8, 3 },
906 { M32C_OPERAND_DSP_32_U8, BFD_RELOC_8, 4 },
907 { M32C_OPERAND_DSP_40_U8, BFD_RELOC_8, 5 },
908 { M32C_OPERAND_DSP_48_U8, BFD_RELOC_8, 6 },
909 { M32C_OPERAND_BITBASE32_16_S11_UNPREFIXED, BFD_RELOC_8, 2 },
910 { M32C_OPERAND_BITBASE32_16_U11_UNPREFIXED, BFD_RELOC_8, 2 },
911 { M32C_OPERAND_BITBASE32_24_S11_PREFIXED, BFD_RELOC_8, 3 },
912 { M32C_OPERAND_BITBASE32_24_U11_PREFIXED, BFD_RELOC_8, 3 },
914 /* Absolute relocs for 16-bit fields. */
915 { M32C_OPERAND_IMM_8_HI, BFD_RELOC_16, 1 },
916 { M32C_OPERAND_IMM_16_HI, BFD_RELOC_16, 2 },
917 { M32C_OPERAND_IMM_24_HI, BFD_RELOC_16, 3 },
918 { M32C_OPERAND_IMM_32_HI, BFD_RELOC_16, 4 },
919 { M32C_OPERAND_IMM_40_HI, BFD_RELOC_16, 5 },
920 { M32C_OPERAND_IMM_48_HI, BFD_RELOC_16, 6 },
921 { M32C_OPERAND_IMM_56_HI, BFD_RELOC_16, 7 },
922 { M32C_OPERAND_IMM_64_HI, BFD_RELOC_16, 8 },
923 { M32C_OPERAND_DSP_16_S16, BFD_RELOC_16, 2 },
924 { M32C_OPERAND_DSP_24_S16, BFD_RELOC_16, 3 },
925 { M32C_OPERAND_DSP_32_S16, BFD_RELOC_16, 4 },
926 { M32C_OPERAND_DSP_40_S16, BFD_RELOC_16, 5 },
927 { M32C_OPERAND_DSP_8_U16, BFD_RELOC_16, 1 },
928 { M32C_OPERAND_DSP_16_U16, BFD_RELOC_16, 2 },
929 { M32C_OPERAND_DSP_24_U16, BFD_RELOC_16, 3 },
930 { M32C_OPERAND_DSP_32_U16, BFD_RELOC_16, 4 },
931 { M32C_OPERAND_DSP_40_U16, BFD_RELOC_16, 5 },
932 { M32C_OPERAND_DSP_48_U16, BFD_RELOC_16, 6 },
933 { M32C_OPERAND_BITBASE32_16_S19_UNPREFIXED, BFD_RELOC_16, 2 },
934 { M32C_OPERAND_BITBASE32_16_U19_UNPREFIXED, BFD_RELOC_16, 2 },
935 { M32C_OPERAND_BITBASE32_24_S19_PREFIXED, BFD_RELOC_16, 3 },
936 { M32C_OPERAND_BITBASE32_24_U19_PREFIXED, BFD_RELOC_16, 3 },
938 /* Absolute relocs for 24-bit fields. */
939 { M32C_OPERAND_LAB_8_24, BFD_RELOC_24, 1 },
940 { M32C_OPERAND_DSP_8_S24, BFD_RELOC_24, 1 },
941 { M32C_OPERAND_DSP_8_U24, BFD_RELOC_24, 1 },
942 { M32C_OPERAND_DSP_16_U24, BFD_RELOC_24, 2 },
943 { M32C_OPERAND_DSP_24_U24, BFD_RELOC_24, 3 },
944 { M32C_OPERAND_DSP_32_U24, BFD_RELOC_24, 4 },
945 { M32C_OPERAND_DSP_40_U24, BFD_RELOC_24, 5 },
946 { M32C_OPERAND_DSP_48_U24, BFD_RELOC_24, 6 },
947 { M32C_OPERAND_DSP_16_U20, BFD_RELOC_24, 2 },
948 { M32C_OPERAND_DSP_24_U20, BFD_RELOC_24, 3 },
949 { M32C_OPERAND_DSP_32_U20, BFD_RELOC_24, 4 },
950 { M32C_OPERAND_BITBASE32_16_U27_UNPREFIXED, BFD_RELOC_24, 2 },
951 { M32C_OPERAND_BITBASE32_24_U27_PREFIXED, BFD_RELOC_24, 3 },
953 /* Absolute relocs for 32-bit fields. */
954 { M32C_OPERAND_IMM_16_SI, BFD_RELOC_32, 2 },
955 { M32C_OPERAND_IMM_24_SI, BFD_RELOC_32, 3 },
956 { M32C_OPERAND_IMM_32_SI, BFD_RELOC_32, 4 },
957 { M32C_OPERAND_IMM_40_SI, BFD_RELOC_32, 5 },
961 int i;
963 for (i = ARRAY_SIZE (op_reloc_table); --i >= 0; )
965 const struct op_reloc *or = &op_reloc_table[i];
967 if (or->operand == operand->type)
969 fixP->fx_where += or->offset;
970 fixP->fx_size -= or->offset;
972 if (fixP->fx_cgen.opinfo
973 && fixP->fx_cgen.opinfo != BFD_RELOC_NONE)
974 return fixP->fx_cgen.opinfo;
976 return or->reloc;
980 fprintf
981 (stderr,
982 "Error: tc-m32c.c:md_cgen_lookup_reloc Unimplemented relocation for operand %s\n",
983 operand->name);
985 return BFD_RELOC_NONE;
988 void
989 m32c_cons_fix_new (fragS * frag,
990 int where,
991 int size,
992 expressionS *exp,
993 bfd_reloc_code_real_type type)
995 switch (size)
997 case 1:
998 type = BFD_RELOC_8;
999 break;
1000 case 2:
1001 type = BFD_RELOC_16;
1002 break;
1003 case 3:
1004 type = BFD_RELOC_24;
1005 break;
1006 case 4:
1007 default:
1008 type = BFD_RELOC_32;
1009 break;
1010 case 8:
1011 type = BFD_RELOC_64;
1012 break;
1015 fix_new_exp (frag, where, (int) size, exp, 0, type);
1018 void
1019 m32c_apply_fix (struct fix *f, valueT *t, segT s)
1021 if (f->fx_r_type == BFD_RELOC_M32C_RL_JUMP
1022 || f->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
1023 || f->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
1024 return;
1025 gas_cgen_md_apply_fix (f, t, s);
1028 arelent *
1029 tc_gen_reloc (asection *sec, fixS *fx)
1031 if (fx->fx_r_type == BFD_RELOC_M32C_RL_JUMP
1032 || fx->fx_r_type == BFD_RELOC_M32C_RL_1ADDR
1033 || fx->fx_r_type == BFD_RELOC_M32C_RL_2ADDR)
1035 arelent * reloc;
1037 reloc = XNEW (arelent);
1039 reloc->sym_ptr_ptr = XNEW (asymbol *);
1040 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fx->fx_addsy);
1041 reloc->address = fx->fx_frag->fr_address + fx->fx_where;
1042 reloc->howto = bfd_reloc_type_lookup (stdoutput, fx->fx_r_type);
1043 reloc->addend = fx->fx_offset;
1044 return reloc;
1047 return gas_cgen_tc_gen_reloc (sec, fx);
1050 /* See whether we need to force a relocation into the output file.
1051 This is used to force out switch and PC relative relocations when
1052 relaxing. */
1055 m32c_force_relocation (fixS * fixp)
1057 int reloc = fixp->fx_r_type;
1059 if (reloc > (int)BFD_RELOC_UNUSED)
1061 reloc -= (int)BFD_RELOC_UNUSED;
1062 switch (reloc)
1064 case M32C_OPERAND_DSP_32_S16:
1065 case M32C_OPERAND_DSP_32_U16:
1066 case M32C_OPERAND_IMM_32_HI:
1067 case M32C_OPERAND_DSP_16_S16:
1068 case M32C_OPERAND_DSP_16_U16:
1069 case M32C_OPERAND_IMM_16_HI:
1070 case M32C_OPERAND_DSP_24_S16:
1071 case M32C_OPERAND_DSP_24_U16:
1072 case M32C_OPERAND_IMM_24_HI:
1073 return 1;
1075 /* If we're doing linker relaxing, we need to keep all the
1076 pc-relative jumps in case we need to fix them due to
1077 deleted bytes between the jump and its destination. */
1078 case M32C_OPERAND_LAB_8_8:
1079 case M32C_OPERAND_LAB_8_16:
1080 case M32C_OPERAND_LAB_8_24:
1081 case M32C_OPERAND_LAB_16_8:
1082 case M32C_OPERAND_LAB_24_8:
1083 case M32C_OPERAND_LAB_32_8:
1084 case M32C_OPERAND_LAB_40_8:
1085 if (m32c_relax)
1086 return 1;
1087 default:
1088 break;
1091 else
1093 switch (fixp->fx_r_type)
1095 case BFD_RELOC_16:
1096 return 1;
1098 case BFD_RELOC_M32C_RL_JUMP:
1099 case BFD_RELOC_M32C_RL_1ADDR:
1100 case BFD_RELOC_M32C_RL_2ADDR:
1101 case BFD_RELOC_8_PCREL:
1102 case BFD_RELOC_16_PCREL:
1103 if (m32c_relax)
1104 return 1;
1105 default:
1106 break;
1110 return generic_force_reloc (fixp);
1113 /* Write a value out to the object file, using the appropriate endianness. */
1115 void
1116 md_number_to_chars (char * buf, valueT val, int n)
1118 number_to_chars_littleendian (buf, val, n);
1121 /* Turn a string in input_line_pointer into a floating point constant of type
1122 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1123 emitted is stored in *sizeP . An error message is returned, or NULL on OK. */
1125 const char *
1126 md_atof (int type, char * litP, int * sizeP)
1128 return ieee_md_atof (type, litP, sizeP, true);
1131 bool
1132 m32c_fix_adjustable (fixS * fixP)
1134 int reloc;
1135 if (fixP->fx_addsy == NULL)
1136 return 1;
1138 /* We need the symbol name for the VTABLE entries. */
1139 reloc = fixP->fx_r_type;
1140 if (reloc > (int)BFD_RELOC_UNUSED)
1142 reloc -= (int)BFD_RELOC_UNUSED;
1143 switch (reloc)
1145 case M32C_OPERAND_DSP_32_S16:
1146 case M32C_OPERAND_DSP_32_U16:
1147 case M32C_OPERAND_IMM_32_HI:
1148 case M32C_OPERAND_DSP_16_S16:
1149 case M32C_OPERAND_DSP_16_U16:
1150 case M32C_OPERAND_IMM_16_HI:
1151 case M32C_OPERAND_DSP_24_S16:
1152 case M32C_OPERAND_DSP_24_U16:
1153 case M32C_OPERAND_IMM_24_HI:
1154 return 0;
1157 else
1159 if (fixP->fx_r_type == BFD_RELOC_16)
1160 return 0;
1163 /* Do not adjust relocations involving symbols in merged sections.
1165 A reloc patching in the value of some symbol S plus some addend A
1166 can be produced in different ways:
1168 1) It might simply be a reference to the data at S + A. Clearly,
1169 if linker merging shift that data around, the value patched in
1170 by the reloc needs to be adjusted accordingly.
1172 2) Or, it might be a reference to S, with A added in as a constant
1173 bias. For example, given code like this:
1175 static int S[100];
1177 ... S[i - 8] ...
1179 it would be reasonable for the compiler to rearrange the array
1180 reference to something like:
1182 ... (S-8)[i] ...
1184 and emit assembly code that refers to S - (8 * sizeof (int)),
1185 so the subtraction is done entirely at compile-time. In this
1186 case, the reloc's addend A would be -(8 * sizeof (int)), and
1187 shifting around code or data at S + A should not affect the
1188 reloc: the reloc isn't referring to that code or data at all.
1190 The linker has no way of knowing which case it has in hand. So,
1191 to disambiguate, we have the linker always treat reloc addends as
1192 in case 2): they're constants that should be simply added to the
1193 symbol value, just like the reloc says. And we express case 1)
1194 in different way: we have the compiler place a label at the real
1195 target, and reference that label with an addend of zero. (The
1196 compiler is unlikely to reference code using a label plus an
1197 offset anyway, since it doesn't know the sizes of the
1198 instructions.)
1200 The simplification being done by gas/write.c:adjust_reloc_syms,
1201 however, turns the explicit-label usage into the label-plus-
1202 offset usage, re-introducing the ambiguity the compiler avoided.
1203 So we need to disable that simplification for symbols referring
1204 to merged data.
1206 This only affects object size a little bit. */
1207 if (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
1208 return 0;
1210 if (m32c_relax)
1211 return 0;
1213 return 1;
1216 /* Worker function for m32c_is_colon_insn(). */
1217 static int
1218 restore_colon (char *next_i_l_p, char *nul_char)
1220 /* Restore the colon, and advance input_line_pointer to
1221 the end of the new symbol. */
1222 *input_line_pointer = *nul_char;
1223 input_line_pointer = next_i_l_p;
1224 *nul_char = *next_i_l_p;
1225 *next_i_l_p = 0;
1226 return 1;
1229 /* Determines if the symbol starting at START and ending in
1230 a colon that was at the location pointed to by INPUT_LINE_POINTER
1231 (but which has now been replaced bu a NUL) is in fact an
1232 :Z, :S, :Q, or :G suffix.
1233 If it is, then it restores the colon, advances INPUT_LINE_POINTER
1234 to the real end of the instruction/symbol, saves the char there to
1235 NUL_CHAR and pokes a NUL, and returns 1. Otherwise it returns 0. */
1237 m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED, char *nul_char)
1239 char * i_l_p = input_line_pointer;
1241 if (*nul_char == '"')
1242 ++i_l_p;
1244 /* Check to see if the text following the colon is 'G' */
1245 if (TOLOWER (i_l_p[1]) == 'g' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1246 return restore_colon (i_l_p + 2, nul_char);
1248 /* Check to see if the text following the colon is 'Q' */
1249 if (TOLOWER (i_l_p[1]) == 'q' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1250 return restore_colon (i_l_p + 2, nul_char);
1252 /* Check to see if the text following the colon is 'S' */
1253 if (TOLOWER (i_l_p[1]) == 's' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1254 return restore_colon (i_l_p + 2, nul_char);
1256 /* Check to see if the text following the colon is 'Z' */
1257 if (TOLOWER (i_l_p[1]) == 'z' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1258 return restore_colon (i_l_p + 2, nul_char);
1260 return 0;