1 /* tc-m32c.c -- Assembler for the Renesas M32C.
2 Copyright (C) 2005-2024 Free Software Foundation, Inc.
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)
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. */
25 #include "opcodes/m32c-desc.h"
26 #include "opcodes/m32c-opc.h"
28 #include "elf/common.h"
30 #include "safe-ctype.h"
32 /* Structure to hold all of the different components
33 describing an individual instruction. */
36 const CGEN_INSN
* insn
;
37 const CGEN_INSN
* orig_insn
;
40 CGEN_INSN_INT buffer
[1];
41 #define INSN_VALUE(buf) (*(buf))
43 unsigned char buffer
[CGEN_MAX_INSN_SIZE
];
44 #define INSN_VALUE(buf) (buf)
49 fixS
* fixups
[GAS_CGEN_MAX_FIXUPS
];
50 int indices
[MAX_OPERAND_INSTANCES
];
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
);
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
};
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
)
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
);
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
);
122 case OPTION_LINKRELAX
:
126 case OPTION_H_TICK_HEX
:
127 enable_h_tick_hex
= 1;
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 },
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
,
160 CGEN_CPU_OPEN_ISAS
, & m32c_isa
,
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. */
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
);
177 m32c_start_line_hook (void)
179 #if 0 /* not necessary....handled in the .cpu file */
180 char *s
= input_line_pointer
;
183 for (s
= input_line_pointer
; s
&& s
[0] != '\n'; s
++)
187 /* Remove :g suffix. Squeeze out blanks. */
190 for (sg
= s
- 1; sg
&& sg
>= input_line_pointer
; sg
--)
196 input_line_pointer
+= 2;
203 /* Process [[indirect-operands]] in instruction str. */
206 m32c_indirect_operand (char *str
)
213 enum indirect_type
{none
, relative
, absolute
} ;
214 enum indirect_type indirection
[3] = { none
, none
, none
};
215 int brace_n
[3] = { 0, 0, 0 };
220 for (s
= str
; *s
; s
++)
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
)
238 ns_len
= strlen (str
);
239 new_str
= XNEWVEC (char, ns_len
);
241 ns_end
= ns
+ ns_len
;
243 for (s
= str
; *s
; s
++)
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
)
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;
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
);
301 md_assemble (char * str
)
303 static int last_insn_had_delay_slot
= 0;
306 finished_insnS results
;
310 if (m32c_mach
== bfd_mach_m32c
&& m32c_indirect_operand (str
))
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
);
321 as_bad ("%s", errmsg
);
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. */
344 && rl_type
!= RL_TYPE_NONE
345 && (rl_type
== RL_TYPE_JUMP
|| results
.num_fixups
)
346 && !relaxable (insn
))
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
)
361 fix_new (results
.frag
,
362 results
.addr
- results
.frag
->fr_literal
,
363 0, abs_section_sym
, addend
, 0,
368 /* The syntax in the manual says constants begin with '#'.
369 We just ignore it. */
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
);
380 md_section_align (segT segment
, valueT size
)
382 int align
= bfd_section_alignment (segment
);
383 return ((size
+ (1 << align
) - 1) & -(1 << align
));
387 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
392 const relax_typeS md_relax_table
[] =
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 */
437 M32C_MACRO_JCND16_5_W
,
438 M32C_MACRO_JCND16_5_A
,
443 /* the digit is the array index of the pcrel byte */
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]))
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
))
499 /* Adjust for m32c pcrel not being relative to the next opcode. */
500 *aim
+= subtype_mappings
[this_state
].pcrel_aim_offset
;
504 insn_to_subtype (int inum
, const CGEN_INSN
*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);*/
517 for (i
=0; i
<NUM_MAPPINGS
; i
++)
518 if (inum
== subtype_mappings
[i
].insn
)
520 /*printf("mapping %d used\n", i);*/
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
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
)
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
;
561 fragP
->fr_cgen
.insn
= (fragP
->fr_cgen
.insn
562 - fragP
->fr_cgen
.insn
->base
->num
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. */
578 target_address_for (fragS
*frag
)
580 int rv
= frag
->fr_offset
;
581 symbolS
*sym
= frag
->fr_symbol
;
584 rv
+= S_GET_VALUE (sym
);
586 /*printf("target_address_for returns %d\n", rv);*/
591 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
592 segT sec ATTRIBUTE_UNUSED
,
593 fragS
* fragP ATTRIBUTE_UNUSED
)
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
;
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
:
610 operand
= M32C_OPERAND_LAB_8_8
;
614 case -M32C_MACRO_JCND16_5_W
:
619 op
[4] = (addend
- 3) >> 8;
620 operand
= M32C_OPERAND_LAB_8_16
;
625 case -M32C_MACRO_JCND16_5_A
:
629 operand
= M32C_OPERAND_LAB_8_24
;
635 case M32C_INSN_JCND16
:
637 operand
= M32C_OPERAND_LAB_16_8
;
641 case -M32C_MACRO_JCND16_W
:
646 op
[5] = (addend
- 4) >> 8;
647 operand
= M32C_OPERAND_LAB_8_16
;
652 case -M32C_MACRO_JCND16_A
:
656 operand
= M32C_OPERAND_LAB_8_24
;
661 case M32C_INSN_JMP16_S
:
662 op
[0] = 0x60 | ((addend
-2) & 0x07);
663 operand
= M32C_OPERAND_LAB_5_3
;
667 case M32C_INSN_JMP16_B
:
670 operand
= M32C_OPERAND_LAB_8_8
;
674 case M32C_INSN_JMP16_W
:
677 op
[2] = (addend
- 1) >> 8;
678 operand
= M32C_OPERAND_LAB_8_16
;
682 case M32C_INSN_JMP16_A
:
687 operand
= M32C_OPERAND_LAB_8_24
;
691 case M32C_INSN_JCND32
:
693 operand
= M32C_OPERAND_LAB_8_8
;
697 case -M32C_MACRO_JCND32_W
:
702 op
[4] = (addend
- 3) >> 8;
703 operand
= M32C_OPERAND_LAB_8_16
;
708 case -M32C_MACRO_JCND32_A
:
712 operand
= M32C_OPERAND_LAB_8_24
;
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
;
724 case M32C_INSN_JMP32_B
:
727 operand
= M32C_OPERAND_LAB_8_8
;
731 case M32C_INSN_JMP32_W
:
734 op
[2] = (addend
- 1) >> 8;
735 operand
= M32C_OPERAND_LAB_8_16
;
739 case M32C_INSN_JMP32_A
:
744 operand
= M32C_OPERAND_LAB_8_24
;
749 case M32C_INSN_JSR16_W
:
752 op
[2] = (addend
- 1) >> 8;
753 operand
= M32C_OPERAND_LAB_8_16
;
757 case M32C_INSN_JSR16_A
:
762 operand
= M32C_OPERAND_LAB_8_24
;
766 case M32C_INSN_JSR32_W
:
769 op
[2] = (addend
- 1) >> 8;
770 operand
= M32C_OPERAND_LAB_8_16
;
774 case M32C_INSN_JSR32_A
:
779 operand
= M32C_OPERAND_LAB_8_24
;
783 case -M32C_MACRO_ADJNZ_2
:
786 operand
= M32C_OPERAND_LAB_16_8
;
788 case -M32C_MACRO_ADJNZ_3
:
791 operand
= M32C_OPERAND_LAB_24_8
;
793 case -M32C_MACRO_ADJNZ_4
:
796 operand
= M32C_OPERAND_LAB_32_8
;
798 case -M32C_MACRO_ADJNZ_5
:
801 operand
= M32C_OPERAND_LAB_40_8
;
805 printf("\nHey! Need more opcode converters! missing: %d %s\n\n",
807 fragP
->fr_cgen
.insn
->base
->name
);
813 if (operand
!= M32C_OPERAND_LAB_8_24
)
814 fragP
->fr_offset
= (fragP
->fr_address
+ 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
,
831 (fragP
->fr_fix
- where
) * 8,
832 cgen_operand_lookup_by_num (gas_cgen_cpu_desc
,
834 fragP
->fr_cgen
.opinfo
,
840 /* Functions concerning relocs. */
842 /* The location from which a PC relative jump should be calculated,
843 given a PC relative reloc. */
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. */
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. */
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 },
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
;
982 "Error: tc-m32c.c:md_cgen_lookup_reloc Unimplemented relocation for operand %s\n",
985 return BFD_RELOC_NONE
;
989 m32c_cons_fix_new (fragS
* frag
,
993 bfd_reloc_code_real_type type
)
1001 type
= BFD_RELOC_16
;
1004 type
= BFD_RELOC_24
;
1008 type
= BFD_RELOC_32
;
1011 type
= BFD_RELOC_64
;
1015 fix_new_exp (frag
, where
, (int) size
, exp
, 0, type
);
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
)
1025 gas_cgen_md_apply_fix (f
, t
, s
);
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
)
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
;
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
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
;
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
:
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
:
1093 switch (fixp
->fx_r_type
)
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
:
1110 return generic_force_reloc (fixp
);
1113 /* Write a value out to the object file, using the appropriate endianness. */
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. */
1126 md_atof (int type
, char * litP
, int * sizeP
)
1128 return ieee_md_atof (type
, litP
, sizeP
, true);
1132 m32c_fix_adjustable (fixS
* fixP
)
1135 if (fixP
->fx_addsy
== NULL
)
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
;
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
:
1159 if (fixP
->fx_r_type
== BFD_RELOC_16
)
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:
1179 it would be reasonable for the compiler to rearrange the array
1180 reference to something like:
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
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
1206 This only affects object size a little bit. */
1207 if (S_GET_SEGMENT (fixP
->fx_addsy
)->flags
& SEC_MERGE
)
1216 /* Worker function for m32c_is_colon_insn(). */
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
;
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
== '"')
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
);