8f4f50225ed4ccccd0007eb1c0908ac990c34c7a
[deliverable/binutils-gdb.git] / gas / config / tc-m32c.c
1 /* tc-m32c.c -- Assembler for the Renesas M32C.
2 Copyright (C) 2005 Free Software Foundation.
3 Contributed by RedHat.
4
5 This file is part of GAS, the GNU Assembler.
6
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 2, or (at your option)
10 any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include <stdio.h>
23 #include "as.h"
24 #include "subsegs.h"
25 #include "symcat.h"
26 #include "opcodes/m32c-desc.h"
27 #include "opcodes/m32c-opc.h"
28 #include "cgen.h"
29 #include "elf/common.h"
30 #include "elf/m32c.h"
31 #include "libbfd.h"
32 #include "libiberty.h"
33 #include "safe-ctype.h"
34 #include "bfd.h"
35
36 /* Structure to hold all of the different components
37 describing an individual instruction. */
38 typedef struct
39 {
40 const CGEN_INSN * insn;
41 const CGEN_INSN * orig_insn;
42 CGEN_FIELDS fields;
43 #if CGEN_INT_INSN_P
44 CGEN_INSN_INT buffer [1];
45 #define INSN_VALUE(buf) (*(buf))
46 #else
47 unsigned char buffer [CGEN_MAX_INSN_SIZE];
48 #define INSN_VALUE(buf) (buf)
49 #endif
50 char * addr;
51 fragS * frag;
52 int num_fixups;
53 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
54 int indices [MAX_OPERAND_INSTANCES];
55 }
56 m32c_insn;
57
58 const char comment_chars[] = ";";
59 const char line_comment_chars[] = "#";
60 const char line_separator_chars[] = "|";
61 const char EXP_CHARS[] = "eE";
62 const char FLT_CHARS[] = "dD";
63 \f
64 #define M32C_SHORTOPTS ""
65 const char * md_shortopts = M32C_SHORTOPTS;
66
67 /* assembler options */
68 #define OPTION_CPU_M16C (OPTION_MD_BASE)
69 #define OPTION_CPU_M32C (OPTION_MD_BASE + 1)
70
71 struct option md_longopts[] =
72 {
73 { "m16c", no_argument, NULL, OPTION_CPU_M16C },
74 { "m32c", no_argument, NULL, OPTION_CPU_M32C },
75 {NULL, no_argument, NULL, 0}
76 };
77 size_t md_longopts_size = sizeof (md_longopts);
78
79 /* Default machine */
80
81 #define DEFAULT_MACHINE bfd_mach_m16c
82 #define DEFAULT_FLAGS EF_M32C_CPU_M16C
83
84 static unsigned long m32c_mach = bfd_mach_m16c;
85 static int cpu_mach = (1 << MACH_M16C);
86 static int insn_size;
87
88 /* Flags to set in the elf header */
89 static flagword m32c_flags = DEFAULT_FLAGS;
90
91 static char default_isa = 1 << (7 - ISA_M16C);
92 static CGEN_BITSET m32c_isa = {1, & default_isa};
93
94 static void
95 set_isa (enum isa_attr isa_num)
96 {
97 cgen_bitset_set (& m32c_isa, isa_num);
98 }
99
100 static void s_bss (int);
101
102 int
103 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
104 {
105 switch (c)
106 {
107 case OPTION_CPU_M16C:
108 m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M16C;
109 m32c_mach = bfd_mach_m16c;
110 cpu_mach = (1 << MACH_M16C);
111 set_isa (ISA_M16C);
112 break;
113
114 case OPTION_CPU_M32C:
115 m32c_flags = (m32c_flags & ~EF_M32C_CPU_MASK) | EF_M32C_CPU_M32C;
116 m32c_mach = bfd_mach_m32c;
117 cpu_mach = (1 << MACH_M32C);
118 set_isa (ISA_M32C);
119 break;
120
121 default:
122 return 0;
123 }
124 return 1;
125 }
126
127 void
128 md_show_usage (FILE * stream)
129 {
130 fprintf (stream, _(" M32C specific command line options:\n"));
131 }
132
133 static void
134 s_bss (int ignore ATTRIBUTE_UNUSED)
135 {
136 int temp;
137
138 temp = get_absolute_expression ();
139 subseg_set (bss_section, (subsegT) temp);
140 demand_empty_rest_of_line ();
141 }
142
143 /* The target specific pseudo-ops which we support. */
144 const pseudo_typeS md_pseudo_table[] =
145 {
146 { "bss", s_bss, 0},
147 { "word", cons, 4 },
148 { NULL, NULL, 0 }
149 };
150
151 \f
152 void
153 md_begin (void)
154 {
155 /* Initialize the `cgen' interface. */
156
157 /* Set the machine number and endian. */
158 gas_cgen_cpu_desc = m32c_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
159 CGEN_CPU_OPEN_ENDIAN,
160 CGEN_ENDIAN_BIG,
161 CGEN_CPU_OPEN_ISAS, & m32c_isa,
162 CGEN_CPU_OPEN_END);
163
164 m32c_cgen_init_asm (gas_cgen_cpu_desc);
165
166 /* This is a callback from cgen to gas to parse operands. */
167 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
168
169 /* Set the ELF flags if desired. */
170 if (m32c_flags)
171 bfd_set_private_flags (stdoutput, m32c_flags);
172
173 /* Set the machine type */
174 bfd_default_set_arch_mach (stdoutput, bfd_arch_m32c, m32c_mach);
175
176 insn_size = 0;
177 }
178
179 void
180 m32c_md_end (void)
181 {
182 int i, n_nops;
183
184 if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
185 {
186 /* Pad with nops for objdump. */
187 n_nops = (32 - ((insn_size) % 32)) / 8;
188 for (i = 1; i <= n_nops; i++)
189 md_assemble ("nop");
190 }
191 }
192
193 void
194 m32c_start_line_hook (void)
195 {
196 #if 0 /* not necessary....handled in the .cpu file */
197 char *s = input_line_pointer;
198 char *sg;
199
200 for (s = input_line_pointer ; s && s[0] != '\n'; s++)
201 {
202 if (s[0] == ':')
203 {
204 /* Remove :g suffix. Squeeze out blanks. */
205 if (s[1] == 'g')
206 {
207 for (sg = s - 1; sg && sg >= input_line_pointer; sg--)
208 {
209 sg[2] = sg[0];
210 }
211 sg[1] = ' ';
212 sg[2] = ' ';
213 input_line_pointer += 2;
214 }
215 }
216 }
217 #endif
218 }
219
220 /* Process [[indirect-operands]] in instruction str. */
221
222 static bfd_boolean
223 m32c_indirect_operand (char *str)
224 {
225 char *new_str;
226 char *s;
227 char *ns;
228 int ns_len;
229 char *ns_end;
230 enum indirect_type {none, relative, absolute} ;
231 enum indirect_type indirection [3] = { none, none, none };
232 int brace_n [3] = { 0, 0, 0 };
233 int operand;
234
235 s = str;
236 operand = 1;
237 for (s = str; *s; s++)
238 {
239 if (s[0] == ',')
240 operand = 2;
241 /* [abs] where abs is not a0 or a1 */
242 if (s[1] == '[' && ! (s[2] == 'a' && (s[3] == '0' || s[3] == '1'))
243 && (ISBLANK (s[0]) || s[0] == ','))
244 indirection[operand] = absolute;
245 if (s[0] == ']' && s[1] == ']')
246 indirection[operand] = relative;
247 if (s[0] == '[' && s[1] == '[')
248 indirection[operand] = relative;
249 }
250
251 if (indirection[1] == none && indirection[2] == none)
252 return FALSE;
253
254 operand = 1;
255 ns_len = strlen (str);
256 new_str = (char*) xmalloc (ns_len);
257 ns = new_str;
258 ns_end = ns + ns_len;
259
260 for (s = str; *s; s++)
261 {
262 if (s[0] == ',')
263 operand = 2;
264
265 if (s[0] == '[' && ! brace_n[operand])
266 {
267 brace_n[operand] += 1;
268 /* Squeeze [[ to [ if this is an indirect operand. */
269 if (indirection[operand] != none)
270 continue;
271 }
272
273 else if (s[0] == '[' && brace_n[operand])
274 {
275 brace_n[operand] += 1;
276 }
277 else if (s[0] == ']' && s[1] == ']' && indirection[operand] == relative)
278 {
279 s += 1; /* skip one ]. */
280 brace_n[operand] -= 2; /* allow for 2 [. */
281 }
282 else if (s[0] == ']' && indirection[operand] == absolute)
283 {
284 brace_n[operand] -= 1;
285 continue; /* skip closing ]. */
286 }
287 else if (s[0] == ']')
288 {
289 brace_n[operand] -= 1;
290 }
291 *ns = s[0];
292 ns += 1;
293 if (ns >= ns_end)
294 return FALSE;
295 if (s[0] == 0)
296 break;
297 }
298 *ns = '\0';
299 for (operand = 1; operand <= 2; operand++)
300 if (brace_n[operand])
301 {
302 fprintf (stderr, "Unmatched [[operand-%d]] %d\n", operand, brace_n[operand]);
303 }
304
305 if (indirection[1] != none && indirection[2] != none)
306 md_assemble ("src-dest-indirect");
307 else if (indirection[1] != none)
308 md_assemble ("src-indirect");
309 else if (indirection[2] != none)
310 md_assemble ("dest-indirect");
311
312 md_assemble (new_str);
313 free (new_str);
314 return TRUE;
315 }
316
317 void
318 md_assemble (char * str)
319 {
320 static int last_insn_had_delay_slot = 0;
321 m32c_insn insn;
322 char * errmsg;
323
324 if (m32c_mach == bfd_mach_m32c && m32c_indirect_operand (str))
325 return;
326
327 /* Initialize GAS's cgen interface for a new instruction. */
328 gas_cgen_init_parse ();
329
330 insn.insn = m32c_cgen_assemble_insn
331 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
332
333 if (!insn.insn)
334 {
335 as_bad ("%s", errmsg);
336 return;
337 }
338
339 /* Doesn't really matter what we pass for RELAX_P here. */
340 gas_cgen_finish_insn (insn.insn, insn.buffer,
341 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
342
343 last_insn_had_delay_slot
344 = CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
345 insn_size = CGEN_INSN_BITSIZE(insn.insn);
346 }
347
348 /* The syntax in the manual says constants begin with '#'.
349 We just ignore it. */
350
351 void
352 md_operand (expressionS * exp)
353 {
354 /* In case of a syntax error, escape back to try next syntax combo. */
355 if (exp->X_op == O_absent)
356 gas_cgen_md_operand (exp);
357 }
358
359 valueT
360 md_section_align (segT segment, valueT size)
361 {
362 int align = bfd_get_section_alignment (stdoutput, segment);
363 return ((size + (1 << align) - 1) & (-1 << align));
364 }
365
366 symbolS *
367 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
368 {
369 return 0;
370 }
371 \f
372 const relax_typeS md_relax_table[] =
373 {
374 /* The fields are:
375 1) most positive reach of this state,
376 2) most negative reach of this state,
377 3) how many bytes this mode will have in the variable part of the frag
378 4) which index into the table to try if we can't fit into this one. */
379
380 /* 0 */ { 0, 0, 0, 0 }, /* unused */
381 /* 1 */ { 0, 0, 0, 0 }, /* marker for "don't know yet" */
382
383 /* 2 */ { 127, -128, 2, 3 }, /* jcnd16_5.b */
384 /* 3 */ { 32767, -32768, 5, 4 }, /* jcnd16_5.w */
385 /* 4 */ { 0, 0, 6, 0 }, /* jcnd16_5.a */
386
387 /* 5 */ { 127, -128, 2, 6 }, /* jcnd16.b */
388 /* 6 */ { 32767, -32768, 5, 7 }, /* jcnd16.w */
389 /* 7 */ { 0, 0, 6, 0 }, /* jcnd16.a */
390
391 /* 8 */ { 8, 1, 1, 9 }, /* jmp16.s */
392 /* 9 */ { 127, -128, 2, 10 }, /* jmp16.b */
393 /* 10 */ { 32767, -32768, 3, 11 }, /* jmp16.w */
394 /* 11 */ { 0, 0, 4, 0 }, /* jmp16.a */
395
396 /* 12 */ { 127, -128, 2, 13 }, /* jcnd32.b */
397 /* 13 */ { 32767, -32768, 5, 14 }, /* jcnd32.w */
398 /* 14 */ { 0, 0, 6, 0 }, /* jcnd32.a */
399
400 /* 15 */ { 8, 1, 1, 16 }, /* jmp32.s */
401 /* 16 */ { 127, -128, 2, 17 }, /* jmp32.b */
402 /* 17 */ { 32767, -32768, 3, 18 }, /* jmp32.w */
403 /* 18 */ { 0, 0, 4, 0 }, /* jmp32.a */
404
405 /* 19 */ { 32767, -32768, 3, 20 }, /* jsr16.w */
406 /* 20 */ { 0, 0, 4, 0 }, /* jsr16.a */
407 /* 21 */ { 32767, -32768, 3, 11 }, /* jsr32.w */
408 /* 22 */ { 0, 0, 4, 0 } /* jsr32.a */
409 };
410
411 enum {
412 M32C_MACRO_JCND16_5_W,
413 M32C_MACRO_JCND16_5_A,
414 M32C_MACRO_JCND16_W,
415 M32C_MACRO_JCND16_A,
416 M32C_MACRO_JCND32_W,
417 M32C_MACRO_JCND32_A,
418 } M32C_Macros;
419
420 static struct {
421 int insn;
422 int bytes;
423 int insn_for_extern;
424 int pcrel_aim_offset;
425 } subtype_mappings[] = {
426 /* 0 */ { 0, 0, 0, 0 },
427 /* 1 */ { 0, 0, 0, 0 },
428
429 /* 2 */ { M32C_INSN_JCND16_5, 2, -M32C_MACRO_JCND16_5_A, 1 },
430 /* 3 */ { -M32C_MACRO_JCND16_5_W, 5, -M32C_MACRO_JCND16_5_A, 4 },
431 /* 4 */ { -M32C_MACRO_JCND16_5_A, 6, -M32C_MACRO_JCND16_5_A, 0 },
432
433 /* 5 */ { M32C_INSN_JCND16, 3, -M32C_MACRO_JCND16_A, 1 },
434 /* 6 */ { -M32C_MACRO_JCND16_W, 6, -M32C_MACRO_JCND16_A, 4 },
435 /* 7 */ { -M32C_MACRO_JCND16_A, 7, -M32C_MACRO_JCND16_A, 0 },
436
437 /* 8 */ { M32C_INSN_JMP16_S, 1, M32C_INSN_JMP16_A, 0 },
438 /* 9 */ { M32C_INSN_JMP16_B, 2, M32C_INSN_JMP16_A, 1 },
439 /* 10 */ { M32C_INSN_JMP16_W, 3, M32C_INSN_JMP16_A, 2 },
440 /* 11 */ { M32C_INSN_JMP16_A, 4, M32C_INSN_JMP16_A, 0 },
441
442 /* 12 */ { M32C_INSN_JCND32, 2, -M32C_MACRO_JCND32_A, 1 },
443 /* 13 */ { -M32C_MACRO_JCND32_W, 5, -M32C_MACRO_JCND32_A, 4 },
444 /* 14 */ { -M32C_MACRO_JCND32_A, 6, -M32C_MACRO_JCND32_A, 0 },
445
446 /* 15 */ { M32C_INSN_JMP32_S, 1, M32C_INSN_JMP32_A, 0 },
447 /* 16 */ { M32C_INSN_JMP32_B, 2, M32C_INSN_JMP32_A, 1 },
448 /* 17 */ { M32C_INSN_JMP32_W, 3, M32C_INSN_JMP32_A, 2 },
449 /* 18 */ { M32C_INSN_JMP32_A, 4, M32C_INSN_JMP32_A, 0 },
450
451 /* 19 */ { M32C_INSN_JSR16_W, 3, M32C_INSN_JSR16_A, 2 },
452 /* 20 */ { M32C_INSN_JSR16_A, 4, M32C_INSN_JSR16_A, 0 },
453 /* 21 */ { M32C_INSN_JSR32_W, 3, M32C_INSN_JSR32_A, 2 },
454 /* 22 */ { M32C_INSN_JSR32_A, 4, M32C_INSN_JSR32_A, 0 }
455 };
456 #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
457
458 void
459 m32c_prepare_relax_scan (fragS *fragP, offsetT *aim, relax_substateT this_state)
460 {
461 symbolS *symbolP = fragP->fr_symbol;
462 if (symbolP && !S_IS_DEFINED (symbolP))
463 *aim = 0;
464 /* Adjust for m32c pcrel not being relative to the next opcode. */
465 *aim += subtype_mappings[this_state].pcrel_aim_offset;
466 }
467
468 static int
469 insn_to_subtype (int insn)
470 {
471 unsigned int i;
472 for (i=0; i<NUM_MAPPINGS; i++)
473 if (insn == subtype_mappings[i].insn)
474 {
475 /*printf("mapping %d used\n", i);*/
476 return i;
477 }
478 abort ();
479 }
480
481 /* Return an initial guess of the length by which a fragment must grow to
482 hold a branch to reach its destination.
483 Also updates fr_type/fr_subtype as necessary.
484
485 Called just before doing relaxation.
486 Any symbol that is now undefined will not become defined.
487 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
488 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
489 Although it may not be explicit in the frag, pretend fr_var starts with a
490 0 value. */
491
492 int
493 md_estimate_size_before_relax (fragS * fragP, segT segment ATTRIBUTE_UNUSED)
494 {
495 int where = fragP->fr_opcode - fragP->fr_literal;
496
497 if (fragP->fr_subtype == 1)
498 fragP->fr_subtype = insn_to_subtype (fragP->fr_cgen.insn->base->num);
499
500 if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
501 {
502 int new_insn;
503
504 new_insn = subtype_mappings[fragP->fr_subtype].insn_for_extern;
505 fragP->fr_subtype = insn_to_subtype (new_insn);
506 }
507
508 if (fragP->fr_cgen.insn->base
509 && fragP->fr_cgen.insn->base->num
510 != subtype_mappings[fragP->fr_subtype].insn
511 && subtype_mappings[fragP->fr_subtype].insn > 0)
512 {
513 int new_insn= subtype_mappings[fragP->fr_subtype].insn;
514 if (new_insn >= 0)
515 {
516 fragP->fr_cgen.insn = (fragP->fr_cgen.insn
517 - fragP->fr_cgen.insn->base->num
518 + new_insn);
519 }
520 }
521
522 return subtype_mappings[fragP->fr_subtype].bytes - (fragP->fr_fix - where);
523 }
524
525 /* *fragP has been relaxed to its final size, and now needs to have
526 the bytes inside it modified to conform to the new size.
527
528 Called after relaxation is finished.
529 fragP->fr_type == rs_machine_dependent.
530 fragP->fr_subtype is the subtype of what the address relaxed to. */
531
532 static int
533 target_address_for (fragS *frag)
534 {
535 int rv = frag->fr_offset;
536 symbolS *sym = frag->fr_symbol;
537
538 if (sym)
539 rv += S_GET_VALUE (sym);
540
541 /*printf("target_address_for returns %d\n", rv);*/
542 return rv;
543 }
544
545 void
546 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
547 segT sec ATTRIBUTE_UNUSED,
548 fragS * fragP ATTRIBUTE_UNUSED)
549 {
550 int addend;
551 int operand;
552 int new_insn;
553 int where = fragP->fr_opcode - fragP->fr_literal;
554 unsigned char *op = (unsigned char *)fragP->fr_opcode;
555
556 addend = target_address_for (fragP) - (fragP->fr_address + where);
557 new_insn = subtype_mappings[fragP->fr_subtype].insn;
558
559 fragP->fr_fix = where + subtype_mappings[fragP->fr_subtype].bytes;
560
561 switch (subtype_mappings[fragP->fr_subtype].insn)
562 {
563 case M32C_INSN_JCND16_5:
564 op[1] = addend - 1;
565 operand = M32C_OPERAND_LAB_8_8;
566 break;
567
568 case -M32C_MACRO_JCND16_5_W:
569 op[0] ^= 0x04;
570 op[1] = 4;
571 op[2] = 0xf4;
572 op[3] = addend - 3;
573 op[4] = (addend - 3) >> 8;
574 operand = M32C_OPERAND_LAB_8_16;
575 where += 2;
576 new_insn = M32C_INSN_JMP16_W;
577 break;
578
579 case -M32C_MACRO_JCND16_5_A:
580 op[0] ^= 0x04;
581 op[1] = 5;
582 op[2] = 0xfc;
583 operand = M32C_OPERAND_LAB_8_24;
584 where += 2;
585 new_insn = M32C_INSN_JMP16_A;
586 break;
587
588
589 case M32C_INSN_JCND16:
590 op[2] = addend - 2;
591 operand = M32C_OPERAND_LAB_16_8;
592 break;
593
594 case -M32C_MACRO_JCND16_W:
595 op[1] ^= 0x04;
596 op[2] = 4;
597 op[3] = 0xf4;
598 op[4] = addend - 4;
599 op[5] = (addend - 4) >> 8;
600 operand = M32C_OPERAND_LAB_8_16;
601 where += 3;
602 new_insn = M32C_INSN_JMP16_W;
603 break;
604
605 case -M32C_MACRO_JCND16_A:
606 op[1] ^= 0x04;
607 op[2] = 5;
608 op[3] = 0xfc;
609 operand = M32C_OPERAND_LAB_8_24;
610 where += 3;
611 new_insn = M32C_INSN_JMP16_A;
612 break;
613
614 case M32C_INSN_JMP16_S:
615 op[0] = 0x60 | ((addend-2) & 0x07);
616 operand = M32C_OPERAND_LAB_5_3;
617 break;
618
619 case M32C_INSN_JMP16_B:
620 op[0] = 0xfe;
621 op[1] = addend - 1;
622 operand = M32C_OPERAND_LAB_8_8;
623 break;
624
625 case M32C_INSN_JMP16_W:
626 op[0] = 0xf4;
627 op[1] = addend - 1;
628 op[2] = (addend - 1) >> 8;
629 operand = M32C_OPERAND_LAB_8_16;
630 break;
631
632 case M32C_INSN_JMP16_A:
633 op[0] = 0xfc;
634 op[1] = 0;
635 op[2] = 0;
636 op[3] = 0;
637 operand = M32C_OPERAND_LAB_8_24;
638 break;
639
640 case M32C_INSN_JCND32:
641 op[1] = addend - 1;
642 operand = M32C_OPERAND_LAB_8_8;
643 break;
644
645 case -M32C_MACRO_JCND32_W:
646 op[0] ^= 0x40;
647 op[1] = 4;
648 op[2] = 0xce;
649 op[3] = addend - 3;
650 op[4] = (addend - 3) >> 8;
651 operand = M32C_OPERAND_LAB_8_16;
652 where += 2;
653 new_insn = M32C_INSN_JMP32_W;
654 break;
655
656 case -M32C_MACRO_JCND32_A:
657 op[0] ^= 0x40;
658 op[1] = 5;
659 op[2] = 0xcc;
660 operand = M32C_OPERAND_LAB_8_24;
661 where += 2;
662 new_insn = M32C_INSN_JMP32_A;
663 break;
664
665
666
667 case M32C_INSN_JMP32_S:
668 addend = ((addend-2) & 0x07);
669 op[0] = 0x4a | (addend & 0x01) | ((addend << 3) & 0x30);
670 operand = M32C_OPERAND_LAB32_JMP_S;
671 break;
672
673 case M32C_INSN_JMP32_B:
674 op[0] = 0xbb;
675 op[1] = addend - 1;
676 operand = M32C_OPERAND_LAB_8_8;
677 break;
678
679 case M32C_INSN_JMP32_W:
680 op[0] = 0xce;
681 op[1] = addend - 1;
682 op[2] = (addend - 1) >> 8;
683 operand = M32C_OPERAND_LAB_8_16;
684 break;
685
686 case M32C_INSN_JMP32_A:
687 op[0] = 0xcc;
688 op[1] = 0;
689 op[2] = 0;
690 op[3] = 0;
691 operand = M32C_OPERAND_LAB_8_24;
692 break;
693
694
695 case M32C_INSN_JSR16_W:
696 op[0] = 0xf5;
697 op[1] = addend - 1;
698 op[2] = (addend - 1) >> 8;
699 operand = M32C_OPERAND_LAB_8_16;
700 break;
701
702 case M32C_INSN_JSR16_A:
703 op[0] = 0xfd;
704 op[1] = 0;
705 op[2] = 0;
706 op[3] = 0;
707 operand = M32C_OPERAND_LAB_8_24;
708 break;
709
710 case M32C_INSN_JSR32_W:
711 op[0] = 0xcf;
712 op[1] = addend - 1;
713 op[2] = (addend - 1) >> 8;
714 operand = M32C_OPERAND_LAB_8_16;
715 break;
716
717 case M32C_INSN_JSR32_A:
718 op[0] = 0xcd;
719 op[1] = 0;
720 op[2] = 0;
721 op[3] = 0;
722 operand = M32C_OPERAND_LAB_8_24;
723 break;
724
725
726
727 default:
728 printf("\nHey! Need more opcode converters! missing: %d %s\n\n",
729 fragP->fr_subtype,
730 fragP->fr_cgen.insn->base->name);
731 abort();
732 }
733
734 if (S_GET_SEGMENT (fragP->fr_symbol) != sec
735 || operand == M32C_OPERAND_LAB_8_24)
736 {
737 assert (fragP->fr_cgen.insn != 0);
738 gas_cgen_record_fixup (fragP,
739 where,
740 fragP->fr_cgen.insn,
741 (fragP->fr_fix - where) * 8,
742 cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
743 operand),
744 fragP->fr_cgen.opinfo,
745 fragP->fr_symbol, fragP->fr_offset);
746 }
747 }
748 \f
749 /* Functions concerning relocs. */
750
751 /* The location from which a PC relative jump should be calculated,
752 given a PC relative reloc. */
753
754 long
755 md_pcrel_from_section (fixS * fixP, segT sec)
756 {
757 if (fixP->fx_addsy != (symbolS *) NULL
758 && (! S_IS_DEFINED (fixP->fx_addsy)
759 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
760 /* The symbol is undefined (or is defined but not in this section).
761 Let the linker figure it out. */
762 return 0;
763
764 return (fixP->fx_frag->fr_address + fixP->fx_where);
765 }
766
767 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
768 Returns BFD_RELOC_NONE if no reloc type can be found.
769 *FIXP may be modified if desired. */
770
771 bfd_reloc_code_real_type
772 md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
773 const CGEN_OPERAND * operand,
774 fixS * fixP ATTRIBUTE_UNUSED)
775 {
776 static const struct op_reloc {
777 /* A CGEN operand type that can be a relocatable expression. */
778 CGEN_OPERAND_TYPE operand;
779
780 /* The appropriate BFD reloc type to use for that. */
781 bfd_reloc_code_real_type reloc;
782
783 /* The offset from the start of the instruction to the field to be
784 relocated, in bytes. */
785 int offset;
786 } op_reloc_table[] = {
787
788 /* PC-REL relocs for 8-bit fields. */
789 { M32C_OPERAND_LAB_16_8, BFD_RELOC_8_PCREL, 2 },
790 { M32C_OPERAND_LAB_24_8, BFD_RELOC_8_PCREL, 3 },
791 { M32C_OPERAND_LAB_32_8, BFD_RELOC_8_PCREL, 4 },
792 { M32C_OPERAND_LAB_40_8, BFD_RELOC_8_PCREL, 5 },
793
794 /* Absolute relocs for 8-bit fields. */
795 { M32C_OPERAND_IMM_8_QI, BFD_RELOC_8, 1 },
796 { M32C_OPERAND_IMM_16_QI, BFD_RELOC_8, 2 },
797 { M32C_OPERAND_IMM_24_QI, BFD_RELOC_8, 3 },
798 { M32C_OPERAND_IMM_32_QI, BFD_RELOC_8, 4 },
799 { M32C_OPERAND_IMM_40_QI, BFD_RELOC_8, 5 },
800 { M32C_OPERAND_IMM_48_QI, BFD_RELOC_8, 6 },
801 { M32C_OPERAND_IMM_56_QI, BFD_RELOC_8, 7 },
802 { M32C_OPERAND_DSP_8_S8, BFD_RELOC_8, 1 },
803 { M32C_OPERAND_DSP_16_S8, BFD_RELOC_8, 2 },
804 { M32C_OPERAND_DSP_24_S8, BFD_RELOC_8, 3 },
805 { M32C_OPERAND_DSP_32_S8, BFD_RELOC_8, 4 },
806 { M32C_OPERAND_DSP_40_S8, BFD_RELOC_8, 5 },
807 { M32C_OPERAND_DSP_48_S8, BFD_RELOC_8, 6 },
808 { M32C_OPERAND_DSP_8_U8, BFD_RELOC_8, 1 },
809 { M32C_OPERAND_DSP_16_U8, BFD_RELOC_8, 2 },
810 { M32C_OPERAND_DSP_24_U8, BFD_RELOC_8, 3 },
811 { M32C_OPERAND_DSP_32_U8, BFD_RELOC_8, 4 },
812 { M32C_OPERAND_DSP_40_U8, BFD_RELOC_8, 5 },
813 { M32C_OPERAND_DSP_48_U8, BFD_RELOC_8, 6 },
814 { M32C_OPERAND_BITBASE32_16_S11_UNPREFIXED, BFD_RELOC_8, 2 },
815 { M32C_OPERAND_BITBASE32_16_U11_UNPREFIXED, BFD_RELOC_8, 2 },
816 { M32C_OPERAND_BITBASE32_24_S11_PREFIXED, BFD_RELOC_8, 3 },
817 { M32C_OPERAND_BITBASE32_24_U11_PREFIXED, BFD_RELOC_8, 3 },
818
819 /* Absolute relocs for 16-bit fields. */
820 { M32C_OPERAND_IMM_8_HI, BFD_RELOC_16, 1 },
821 { M32C_OPERAND_IMM_16_HI, BFD_RELOC_16, 2 },
822 { M32C_OPERAND_IMM_24_HI, BFD_RELOC_16, 3 },
823 { M32C_OPERAND_IMM_32_HI, BFD_RELOC_16, 4 },
824 { M32C_OPERAND_IMM_40_HI, BFD_RELOC_16, 5 },
825 { M32C_OPERAND_IMM_48_HI, BFD_RELOC_16, 6 },
826 { M32C_OPERAND_IMM_56_HI, BFD_RELOC_16, 7 },
827 { M32C_OPERAND_IMM_64_HI, BFD_RELOC_16, 8 },
828 { M32C_OPERAND_DSP_16_S16, BFD_RELOC_16, 2 },
829 { M32C_OPERAND_DSP_24_S16, BFD_RELOC_16, 3 },
830 { M32C_OPERAND_DSP_32_S16, BFD_RELOC_16, 4 },
831 { M32C_OPERAND_DSP_40_S16, BFD_RELOC_16, 5 },
832 { M32C_OPERAND_DSP_8_U16, BFD_RELOC_16, 1 },
833 { M32C_OPERAND_DSP_16_U16, BFD_RELOC_16, 2 },
834 { M32C_OPERAND_DSP_24_U16, BFD_RELOC_16, 3 },
835 { M32C_OPERAND_DSP_32_U16, BFD_RELOC_16, 4 },
836 { M32C_OPERAND_DSP_40_U16, BFD_RELOC_16, 5 },
837 { M32C_OPERAND_DSP_48_U16, BFD_RELOC_16, 6 },
838 { M32C_OPERAND_BITBASE32_16_S19_UNPREFIXED, BFD_RELOC_16, 2 },
839 { M32C_OPERAND_BITBASE32_16_U19_UNPREFIXED, BFD_RELOC_16, 2 },
840 { M32C_OPERAND_BITBASE32_24_S19_PREFIXED, BFD_RELOC_16, 3 },
841 { M32C_OPERAND_BITBASE32_24_U19_PREFIXED, BFD_RELOC_16, 3 },
842
843 /* Absolute relocs for 24-bit fields. */
844 { M32C_OPERAND_LAB_8_24, BFD_RELOC_24, 1 },
845 { M32C_OPERAND_DSP_8_S24, BFD_RELOC_24, 1 },
846 { M32C_OPERAND_DSP_8_U24, BFD_RELOC_24, 1 },
847 { M32C_OPERAND_DSP_16_U24, BFD_RELOC_24, 2 },
848 { M32C_OPERAND_DSP_24_U24, BFD_RELOC_24, 3 },
849 { M32C_OPERAND_DSP_32_U24, BFD_RELOC_24, 4 },
850 { M32C_OPERAND_DSP_40_U24, BFD_RELOC_24, 5 },
851 { M32C_OPERAND_DSP_48_U24, BFD_RELOC_24, 6 },
852 { M32C_OPERAND_DSP_16_U20, BFD_RELOC_24, 2 },
853 { M32C_OPERAND_DSP_24_U20, BFD_RELOC_24, 3 },
854 { M32C_OPERAND_DSP_32_U20, BFD_RELOC_24, 4 },
855 { M32C_OPERAND_BITBASE32_16_U27_UNPREFIXED, BFD_RELOC_24, 2 },
856 { M32C_OPERAND_BITBASE32_24_U27_PREFIXED, BFD_RELOC_24, 3 },
857
858 /* Absolute relocs for 32-bit fields. */
859 { M32C_OPERAND_IMM_16_SI, BFD_RELOC_32, 2 },
860 { M32C_OPERAND_IMM_24_SI, BFD_RELOC_32, 3 },
861 { M32C_OPERAND_IMM_32_SI, BFD_RELOC_32, 4 },
862 { M32C_OPERAND_IMM_40_SI, BFD_RELOC_32, 5 },
863
864 };
865
866 int i;
867
868 for (i = ARRAY_SIZE (op_reloc_table); --i >= 0; )
869 {
870 const struct op_reloc *or = &op_reloc_table[i];
871
872 if (or->operand == operand->type)
873 {
874 fixP->fx_where += or->offset;
875 fixP->fx_size -= or->offset;
876
877 if (fixP->fx_cgen.opinfo
878 && fixP->fx_cgen.opinfo != BFD_RELOC_NONE)
879 return fixP->fx_cgen.opinfo;
880
881 return or->reloc;
882 }
883 }
884
885 fprintf
886 (stderr,
887 "Error: tc-m32c.c:md_cgen_lookup_reloc Unimplemented relocation for operand %s\n",
888 operand->name);
889
890 return BFD_RELOC_NONE;
891 }
892
893 /* See whether we need to force a relocation into the output file.
894 This is used to force out switch and PC relative relocations when
895 relaxing. */
896
897 int
898 m32c_force_relocation (fixS * fixp)
899 {
900 int reloc = fixp->fx_r_type;
901
902 if (reloc > (int)BFD_RELOC_UNUSED)
903 {
904 reloc -= (int)BFD_RELOC_UNUSED;
905 switch (reloc)
906 {
907 case M32C_OPERAND_DSP_32_S16:
908 case M32C_OPERAND_DSP_32_U16:
909 case M32C_OPERAND_IMM_32_HI:
910 case M32C_OPERAND_DSP_16_S16:
911 case M32C_OPERAND_DSP_16_U16:
912 case M32C_OPERAND_IMM_16_HI:
913 case M32C_OPERAND_DSP_24_S16:
914 case M32C_OPERAND_DSP_24_U16:
915 case M32C_OPERAND_IMM_24_HI:
916 return 1;
917 }
918 }
919 else
920 {
921 if (fixp->fx_r_type == BFD_RELOC_16)
922 return 1;
923 }
924
925 return generic_force_reloc (fixp);
926 }
927 \f
928 /* Write a value out to the object file, using the appropriate endianness. */
929
930 void
931 md_number_to_chars (char * buf, valueT val, int n)
932 {
933 number_to_chars_littleendian (buf, val, n);
934 }
935
936 /* Turn a string in input_line_pointer into a floating point constant of type
937 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
938 emitted is stored in *sizeP . An error message is returned, or NULL on OK. */
939
940 /* Equal to MAX_PRECISION in atof-ieee.c. */
941 #define MAX_LITTLENUMS 6
942
943 char *
944 md_atof (int type, char * litP, int * sizeP)
945 {
946 int i;
947 int prec;
948 LITTLENUM_TYPE words [MAX_LITTLENUMS];
949 char * t;
950
951 switch (type)
952 {
953 case 'f':
954 case 'F':
955 case 's':
956 case 'S':
957 prec = 2;
958 break;
959
960 case 'd':
961 case 'D':
962 case 'r':
963 case 'R':
964 prec = 4;
965 break;
966
967 /* FIXME: Some targets allow other format chars for bigger sizes here. */
968
969 default:
970 * sizeP = 0;
971 return _("Bad call to md_atof()");
972 }
973
974 t = atof_ieee (input_line_pointer, type, words);
975 if (t)
976 input_line_pointer = t;
977 * sizeP = prec * sizeof (LITTLENUM_TYPE);
978
979 for (i = 0; i < prec; i++)
980 {
981 md_number_to_chars (litP, (valueT) words[i],
982 sizeof (LITTLENUM_TYPE));
983 litP += sizeof (LITTLENUM_TYPE);
984 }
985
986 return 0;
987 }
988
989 bfd_boolean
990 m32c_fix_adjustable (fixS * fixP)
991 {
992 int reloc;
993 if (fixP->fx_addsy == NULL)
994 return 1;
995
996 /* We need the symbol name for the VTABLE entries. */
997 reloc = fixP->fx_r_type;
998 if (reloc > (int)BFD_RELOC_UNUSED)
999 {
1000 reloc -= (int)BFD_RELOC_UNUSED;
1001 switch (reloc)
1002 {
1003 case M32C_OPERAND_DSP_32_S16:
1004 case M32C_OPERAND_DSP_32_U16:
1005 case M32C_OPERAND_IMM_32_HI:
1006 case M32C_OPERAND_DSP_16_S16:
1007 case M32C_OPERAND_DSP_16_U16:
1008 case M32C_OPERAND_IMM_16_HI:
1009 case M32C_OPERAND_DSP_24_S16:
1010 case M32C_OPERAND_DSP_24_U16:
1011 case M32C_OPERAND_IMM_24_HI:
1012 return 0;
1013 }
1014 }
1015 else
1016 {
1017 if (fixP->fx_r_type == BFD_RELOC_16)
1018 return 0;
1019 }
1020
1021 /* Do not adjust relocations involving symbols in merged sections.
1022
1023 A reloc patching in the value of some symbol S plus some addend A
1024 can be produced in different ways:
1025
1026 1) It might simply be a reference to the data at S + A. Clearly,
1027 if linker merging shift that data around, the value patched in
1028 by the reloc needs to be adjusted accordingly.
1029
1030 2) Or, it might be a reference to S, with A added in as a constant
1031 bias. For example, given code like this:
1032
1033 static int S[100];
1034
1035 ... S[i - 8] ...
1036
1037 it would be reasonable for the compiler to rearrange the array
1038 reference to something like:
1039
1040 ... (S-8)[i] ...
1041
1042 and emit assembly code that refers to S - (8 * sizeof (int)),
1043 so the subtraction is done entirely at compile-time. In this
1044 case, the reloc's addend A would be -(8 * sizeof (int)), and
1045 shifting around code or data at S + A should not affect the
1046 reloc: the reloc isn't referring to that code or data at all.
1047
1048 The linker has no way of knowing which case it has in hand. So,
1049 to disambiguate, we have the linker always treat reloc addends as
1050 in case 2): they're constants that should be simply added to the
1051 symbol value, just like the reloc says. And we express case 1)
1052 in different way: we have the compiler place a label at the real
1053 target, and reference that label with an addend of zero. (The
1054 compiler is unlikely to reference code using a label plus an
1055 offset anyway, since it doesn't know the sizes of the
1056 instructions.)
1057
1058 The simplification being done by gas/write.c:adjust_reloc_syms,
1059 however, turns the explicit-label usage into the label-plus-
1060 offset usage, re-introducing the ambiguity the compiler avoided.
1061 So we need to disable that simplification for symbols referring
1062 to merged data.
1063
1064 This only affects object size a little bit. */
1065 if (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
1066 return 0;
1067
1068 return 1;
1069 }
1070
1071 /* Worker function for m32c_is_colon_insn(). */
1072 static char restore_colon PARAMS ((int));
1073
1074 static char
1075 restore_colon (int advance_i_l_p_by)
1076 {
1077 char c;
1078
1079 /* Restore the colon, and advance input_line_pointer to
1080 the end of the new symbol. */
1081 * input_line_pointer = ':';
1082 input_line_pointer += advance_i_l_p_by;
1083 c = * input_line_pointer;
1084 * input_line_pointer = 0;
1085
1086 return c;
1087 }
1088
1089 /* Determines if the symbol starting at START and ending in
1090 a colon that was at the location pointed to by INPUT_LINE_POINTER
1091 (but which has now been replaced bu a NUL) is in fact an
1092 :Z, :S, :Q, or :G suffix.
1093 If it is, then it restores the colon, advances INPUT_LINE_POINTER
1094 to the real end of the instruction/symbol, and returns the character
1095 that really terminated the symbol. Otherwise it returns 0. */
1096 char
1097 m32c_is_colon_insn (char *start ATTRIBUTE_UNUSED)
1098 {
1099 char * i_l_p = input_line_pointer;
1100
1101 /* Check to see if the text following the colon is 'G' */
1102 if (TOLOWER (i_l_p[1]) == 'g' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1103 return restore_colon (2);
1104
1105 /* Check to see if the text following the colon is 'Q' */
1106 if (TOLOWER (i_l_p[1]) == 'q' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1107 return restore_colon (2);
1108
1109 /* Check to see if the text following the colon is 'S' */
1110 if (TOLOWER (i_l_p[1]) == 's' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1111 return restore_colon (2);
1112
1113 /* Check to see if the text following the colon is 'Z' */
1114 if (TOLOWER (i_l_p[1]) == 'z' && (i_l_p[2] == ' ' || i_l_p[2] == '\t'))
1115 return restore_colon (2);
1116
1117 return 0;
1118 }
This page took 0.053291 seconds and 4 git commands to generate.