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