xref: /openbsd-src/gnu/usr.bin/binutils-2.17/gas/config/tc-m32r.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* tc-m32r.c -- Assembler for the Renesas M32R.
2*3d8817e4Smiod    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod 
5*3d8817e4Smiod    This file is part of GAS, the GNU Assembler.
6*3d8817e4Smiod 
7*3d8817e4Smiod    GAS is free software; you can redistribute it and/or modify
8*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
9*3d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
10*3d8817e4Smiod    any later version.
11*3d8817e4Smiod 
12*3d8817e4Smiod    GAS is distributed in the hope that it will be useful,
13*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
14*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*3d8817e4Smiod    GNU General Public License for more details.
16*3d8817e4Smiod 
17*3d8817e4Smiod    You should have received a copy of the GNU General Public License
18*3d8817e4Smiod    along with GAS; see the file COPYING.  If not, write to
19*3d8817e4Smiod    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20*3d8817e4Smiod    Boston, MA 02110-1301, USA.  */
21*3d8817e4Smiod 
22*3d8817e4Smiod #include <stdio.h>
23*3d8817e4Smiod #include "as.h"
24*3d8817e4Smiod #include "safe-ctype.h"
25*3d8817e4Smiod #include "subsegs.h"
26*3d8817e4Smiod #include "symcat.h"
27*3d8817e4Smiod #include "opcodes/m32r-desc.h"
28*3d8817e4Smiod #include "opcodes/m32r-opc.h"
29*3d8817e4Smiod #include "cgen.h"
30*3d8817e4Smiod #include "elf/m32r.h"
31*3d8817e4Smiod 
32*3d8817e4Smiod /* Linked list of symbols that are debugging symbols to be defined as the
33*3d8817e4Smiod    beginning of the current instruction.  */
34*3d8817e4Smiod typedef struct sym_link
35*3d8817e4Smiod {
36*3d8817e4Smiod   struct sym_link *next;
37*3d8817e4Smiod   symbolS *symbol;
38*3d8817e4Smiod } sym_linkS;
39*3d8817e4Smiod 
40*3d8817e4Smiod static sym_linkS *debug_sym_link = (sym_linkS *) 0;
41*3d8817e4Smiod 
42*3d8817e4Smiod /* Structure to hold all of the different components describing
43*3d8817e4Smiod    an individual instruction.  */
44*3d8817e4Smiod typedef struct
45*3d8817e4Smiod {
46*3d8817e4Smiod   const CGEN_INSN *insn;
47*3d8817e4Smiod   const CGEN_INSN *orig_insn;
48*3d8817e4Smiod   CGEN_FIELDS fields;
49*3d8817e4Smiod #if CGEN_INT_INSN_P
50*3d8817e4Smiod   CGEN_INSN_INT buffer[1];
51*3d8817e4Smiod #define INSN_VALUE(buf) (*(buf))
52*3d8817e4Smiod #else
53*3d8817e4Smiod   unsigned char buffer[CGEN_MAX_INSN_SIZE];
54*3d8817e4Smiod #define INSN_VALUE(buf) (buf)
55*3d8817e4Smiod #endif
56*3d8817e4Smiod   char *addr;
57*3d8817e4Smiod   fragS *frag;
58*3d8817e4Smiod   int num_fixups;
59*3d8817e4Smiod   fixS *fixups[GAS_CGEN_MAX_FIXUPS];
60*3d8817e4Smiod   int indices[MAX_OPERAND_INSTANCES];
61*3d8817e4Smiod   sym_linkS *debug_sym_link;
62*3d8817e4Smiod }
63*3d8817e4Smiod m32r_insn;
64*3d8817e4Smiod 
65*3d8817e4Smiod /* prev_insn.insn is non-null if last insn was a 16 bit insn on a 32 bit
66*3d8817e4Smiod    boundary (i.e. was the first of two 16 bit insns).  */
67*3d8817e4Smiod static m32r_insn prev_insn;
68*3d8817e4Smiod 
69*3d8817e4Smiod /* Non-zero if we've seen a relaxable insn since the last 32 bit
70*3d8817e4Smiod    alignment request.  */
71*3d8817e4Smiod static int seen_relaxable_p = 0;
72*3d8817e4Smiod 
73*3d8817e4Smiod /* Non-zero if we are generating PIC code.  */
74*3d8817e4Smiod int pic_code;
75*3d8817e4Smiod 
76*3d8817e4Smiod /* Non-zero if -relax specified, in which case sufficient relocs are output
77*3d8817e4Smiod    for the linker to do relaxing.
78*3d8817e4Smiod    We do simple forms of relaxing internally, but they are always done.
79*3d8817e4Smiod    This flag does not apply to them.  */
80*3d8817e4Smiod static int m32r_relax;
81*3d8817e4Smiod 
82*3d8817e4Smiod /* Non-zero if warn when a high/shigh reloc has no matching low reloc.
83*3d8817e4Smiod    Each high/shigh reloc must be paired with it's low cousin in order to
84*3d8817e4Smiod    properly calculate the addend in a relocatable link (since there is a
85*3d8817e4Smiod    potential carry from the low to the high/shigh).
86*3d8817e4Smiod    This option is off by default though for user-written assembler code it
87*3d8817e4Smiod    might make sense to make the default be on (i.e. have gcc pass a flag
88*3d8817e4Smiod    to turn it off).  This warning must not be on for GCC created code as
89*3d8817e4Smiod    optimization may delete the low but not the high/shigh (at least we
90*3d8817e4Smiod    shouldn't assume or require it to).  */
91*3d8817e4Smiod static int warn_unmatched_high = 0;
92*3d8817e4Smiod 
93*3d8817e4Smiod /* 1 if -m32rx has been specified, in which case support for
94*3d8817e4Smiod      the extended M32RX instruction set should be enabled.
95*3d8817e4Smiod    2 if -m32r2 has been specified, in which case support for
96*3d8817e4Smiod      the extended M32R2 instruction set should be enabled.  */
97*3d8817e4Smiod static int enable_m32rx = 0; /* Default to M32R.  */
98*3d8817e4Smiod 
99*3d8817e4Smiod /* Non-zero if -m32rx -hidden has been specified, in which case support for
100*3d8817e4Smiod    the special M32RX instruction set should be enabled.  */
101*3d8817e4Smiod static int enable_special = 0;
102*3d8817e4Smiod 
103*3d8817e4Smiod /* Non-zero if -bitinst has been specified, in which case support
104*3d8817e4Smiod    for extended M32R bit-field instruction set should be enabled.  */
105*3d8817e4Smiod static int enable_special_m32r = 1;
106*3d8817e4Smiod 
107*3d8817e4Smiod /* Non-zero if -float has been specified, in which case support for
108*3d8817e4Smiod    extended M32R floating point instruction set should be enabled.  */
109*3d8817e4Smiod static int enable_special_float = 0;
110*3d8817e4Smiod 
111*3d8817e4Smiod /* Non-zero if the programmer should be warned when an explicit parallel
112*3d8817e4Smiod    instruction might have constraint violations.  */
113*3d8817e4Smiod static int warn_explicit_parallel_conflicts = 1;
114*3d8817e4Smiod 
115*3d8817e4Smiod /* Non-zero if the programmer should not receive any messages about
116*3d8817e4Smiod    parallel instruction with potential or real constraint violations.
117*3d8817e4Smiod    The ability to suppress these messages is intended only for hardware
118*3d8817e4Smiod    vendors testing the chip.  It superceedes
119*3d8817e4Smiod    warn_explicit_parallel_conflicts.  */
120*3d8817e4Smiod static int ignore_parallel_conflicts = 0;
121*3d8817e4Smiod 
122*3d8817e4Smiod /* Non-zero if insns can be made parallel.  */
123*3d8817e4Smiod static int use_parallel = 0;
124*3d8817e4Smiod 
125*3d8817e4Smiod /* Non-zero if optimizations should be performed.  */
126*3d8817e4Smiod static int optimize;
127*3d8817e4Smiod 
128*3d8817e4Smiod /* m32r er_flags.  */
129*3d8817e4Smiod static int m32r_flags = 0;
130*3d8817e4Smiod 
131*3d8817e4Smiod /* Stuff for .scomm symbols.  */
132*3d8817e4Smiod static segT     sbss_section;
133*3d8817e4Smiod static asection scom_section;
134*3d8817e4Smiod static asymbol  scom_symbol;
135*3d8817e4Smiod 
136*3d8817e4Smiod const char comment_chars[]        = ";";
137*3d8817e4Smiod const char line_comment_chars[]   = "#";
138*3d8817e4Smiod const char line_separator_chars[] = "!";
139*3d8817e4Smiod const char EXP_CHARS[]            = "eE";
140*3d8817e4Smiod const char FLT_CHARS[]            = "dD";
141*3d8817e4Smiod 
142*3d8817e4Smiod /* Relocations against symbols are done in two
143*3d8817e4Smiod    parts, with a HI relocation and a LO relocation.  Each relocation
144*3d8817e4Smiod    has only 16 bits of space to store an addend.  This means that in
145*3d8817e4Smiod    order for the linker to handle carries correctly, it must be able
146*3d8817e4Smiod    to locate both the HI and the LO relocation.  This means that the
147*3d8817e4Smiod    relocations must appear in order in the relocation table.
148*3d8817e4Smiod 
149*3d8817e4Smiod    In order to implement this, we keep track of each unmatched HI
150*3d8817e4Smiod    relocation.  We then sort them so that they immediately precede the
151*3d8817e4Smiod    corresponding LO relocation.  */
152*3d8817e4Smiod 
153*3d8817e4Smiod struct m32r_hi_fixup
154*3d8817e4Smiod {
155*3d8817e4Smiod   /* Next HI fixup.  */
156*3d8817e4Smiod   struct m32r_hi_fixup *next;
157*3d8817e4Smiod 
158*3d8817e4Smiod   /* This fixup.  */
159*3d8817e4Smiod   fixS *fixp;
160*3d8817e4Smiod 
161*3d8817e4Smiod   /* The section this fixup is in.  */
162*3d8817e4Smiod   segT seg;
163*3d8817e4Smiod };
164*3d8817e4Smiod 
165*3d8817e4Smiod /* The list of unmatched HI relocs.  */
166*3d8817e4Smiod 
167*3d8817e4Smiod static struct m32r_hi_fixup *m32r_hi_fixup_list;
168*3d8817e4Smiod 
169*3d8817e4Smiod struct
170*3d8817e4Smiod {
171*3d8817e4Smiod   enum bfd_architecture bfd_mach;
172*3d8817e4Smiod   int mach_flags;
173*3d8817e4Smiod } mach_table[] =
174*3d8817e4Smiod {
175*3d8817e4Smiod   { bfd_mach_m32r,  (1<<MACH_M32R) },
176*3d8817e4Smiod   { bfd_mach_m32rx, (1<<MACH_M32RX) },
177*3d8817e4Smiod   { bfd_mach_m32r2, (1<<MACH_M32R2) }
178*3d8817e4Smiod };
179*3d8817e4Smiod 
180*3d8817e4Smiod static void
allow_m32rx(int on)181*3d8817e4Smiod allow_m32rx (int on)
182*3d8817e4Smiod {
183*3d8817e4Smiod   enable_m32rx = on;
184*3d8817e4Smiod 
185*3d8817e4Smiod   if (stdoutput != NULL)
186*3d8817e4Smiod     bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_table[on].bfd_mach);
187*3d8817e4Smiod 
188*3d8817e4Smiod   if (gas_cgen_cpu_desc != NULL)
189*3d8817e4Smiod     gas_cgen_cpu_desc->machs = mach_table[on].mach_flags;
190*3d8817e4Smiod }
191*3d8817e4Smiod 
192*3d8817e4Smiod #define M32R_SHORTOPTS "O::K:"
193*3d8817e4Smiod 
194*3d8817e4Smiod const char *md_shortopts = M32R_SHORTOPTS;
195*3d8817e4Smiod 
196*3d8817e4Smiod enum md_option_enums
197*3d8817e4Smiod {
198*3d8817e4Smiod   OPTION_M32R = OPTION_MD_BASE,
199*3d8817e4Smiod   OPTION_M32RX,
200*3d8817e4Smiod   OPTION_M32R2,
201*3d8817e4Smiod   OPTION_BIG,
202*3d8817e4Smiod   OPTION_LITTLE,
203*3d8817e4Smiod   OPTION_PARALLEL,
204*3d8817e4Smiod   OPTION_NO_PARALLEL,
205*3d8817e4Smiod   OPTION_WARN_PARALLEL,
206*3d8817e4Smiod   OPTION_NO_WARN_PARALLEL,
207*3d8817e4Smiod   OPTION_IGNORE_PARALLEL,
208*3d8817e4Smiod   OPTION_NO_IGNORE_PARALLEL,
209*3d8817e4Smiod   OPTION_SPECIAL,
210*3d8817e4Smiod   OPTION_SPECIAL_M32R,
211*3d8817e4Smiod   OPTION_NO_SPECIAL_M32R,
212*3d8817e4Smiod   OPTION_SPECIAL_FLOAT,
213*3d8817e4Smiod   OPTION_WARN_UNMATCHED,
214*3d8817e4Smiod   OPTION_NO_WARN_UNMATCHED
215*3d8817e4Smiod };
216*3d8817e4Smiod 
217*3d8817e4Smiod struct option md_longopts[] =
218*3d8817e4Smiod {
219*3d8817e4Smiod   {"m32r",  no_argument, NULL, OPTION_M32R},
220*3d8817e4Smiod   {"m32rx", no_argument, NULL, OPTION_M32RX},
221*3d8817e4Smiod   {"m32r2", no_argument, NULL, OPTION_M32R2},
222*3d8817e4Smiod   {"big", no_argument, NULL, OPTION_BIG},
223*3d8817e4Smiod   {"little", no_argument, NULL, OPTION_LITTLE},
224*3d8817e4Smiod   {"EB", no_argument, NULL, OPTION_BIG},
225*3d8817e4Smiod   {"EL", no_argument, NULL, OPTION_LITTLE},
226*3d8817e4Smiod   {"parallel", no_argument, NULL, OPTION_PARALLEL},
227*3d8817e4Smiod   {"no-parallel", no_argument, NULL, OPTION_NO_PARALLEL},
228*3d8817e4Smiod   {"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN_PARALLEL},
229*3d8817e4Smiod   {"Wp", no_argument, NULL, OPTION_WARN_PARALLEL},
230*3d8817e4Smiod   {"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
231*3d8817e4Smiod   {"Wnp", no_argument, NULL, OPTION_NO_WARN_PARALLEL},
232*3d8817e4Smiod   {"ignore-parallel-conflicts", no_argument, NULL, OPTION_IGNORE_PARALLEL},
233*3d8817e4Smiod   {"Ip", no_argument, NULL, OPTION_IGNORE_PARALLEL},
234*3d8817e4Smiod   {"no-ignore-parallel-conflicts", no_argument, NULL, OPTION_NO_IGNORE_PARALLEL},
235*3d8817e4Smiod   {"nIp", no_argument, NULL, OPTION_NO_IGNORE_PARALLEL},
236*3d8817e4Smiod   {"hidden", no_argument, NULL, OPTION_SPECIAL},
237*3d8817e4Smiod   {"bitinst", no_argument, NULL, OPTION_SPECIAL_M32R},
238*3d8817e4Smiod   {"no-bitinst", no_argument, NULL, OPTION_NO_SPECIAL_M32R},
239*3d8817e4Smiod   {"float", no_argument, NULL, OPTION_SPECIAL_FLOAT},
240*3d8817e4Smiod   /* Sigh.  I guess all warnings must now have both variants.  */
241*3d8817e4Smiod   {"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED},
242*3d8817e4Smiod   {"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED},
243*3d8817e4Smiod   {"no-warn-unmatched-high", no_argument, NULL, OPTION_NO_WARN_UNMATCHED},
244*3d8817e4Smiod   {"Wnuh", no_argument, NULL, OPTION_NO_WARN_UNMATCHED},
245*3d8817e4Smiod   {NULL, no_argument, NULL, 0}
246*3d8817e4Smiod };
247*3d8817e4Smiod 
248*3d8817e4Smiod size_t md_longopts_size = sizeof (md_longopts);
249*3d8817e4Smiod 
250*3d8817e4Smiod static void
little(int on)251*3d8817e4Smiod little (int on)
252*3d8817e4Smiod {
253*3d8817e4Smiod   target_big_endian = ! on;
254*3d8817e4Smiod }
255*3d8817e4Smiod 
256*3d8817e4Smiod /* Use parallel execution.  */
257*3d8817e4Smiod 
258*3d8817e4Smiod static int
parallel(void)259*3d8817e4Smiod parallel (void)
260*3d8817e4Smiod {
261*3d8817e4Smiod   if (! enable_m32rx)
262*3d8817e4Smiod     return 0;
263*3d8817e4Smiod 
264*3d8817e4Smiod   if (use_parallel == 1)
265*3d8817e4Smiod     return 1;
266*3d8817e4Smiod 
267*3d8817e4Smiod   return 0;
268*3d8817e4Smiod }
269*3d8817e4Smiod 
270*3d8817e4Smiod int
md_parse_option(int c,char * arg ATTRIBUTE_UNUSED)271*3d8817e4Smiod md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
272*3d8817e4Smiod {
273*3d8817e4Smiod   switch (c)
274*3d8817e4Smiod     {
275*3d8817e4Smiod     case 'O':
276*3d8817e4Smiod       optimize = 1;
277*3d8817e4Smiod       use_parallel = 1;
278*3d8817e4Smiod       break;
279*3d8817e4Smiod 
280*3d8817e4Smiod     case OPTION_M32R:
281*3d8817e4Smiod       allow_m32rx (0);
282*3d8817e4Smiod       break;
283*3d8817e4Smiod 
284*3d8817e4Smiod     case OPTION_M32RX:
285*3d8817e4Smiod       allow_m32rx (1);
286*3d8817e4Smiod       break;
287*3d8817e4Smiod 
288*3d8817e4Smiod     case OPTION_M32R2:
289*3d8817e4Smiod       allow_m32rx (2);
290*3d8817e4Smiod       enable_special = 1;
291*3d8817e4Smiod       enable_special_m32r = 1;
292*3d8817e4Smiod       break;
293*3d8817e4Smiod 
294*3d8817e4Smiod     case OPTION_BIG:
295*3d8817e4Smiod       target_big_endian = 1;
296*3d8817e4Smiod       break;
297*3d8817e4Smiod 
298*3d8817e4Smiod     case OPTION_LITTLE:
299*3d8817e4Smiod       target_big_endian = 0;
300*3d8817e4Smiod       break;
301*3d8817e4Smiod 
302*3d8817e4Smiod     case OPTION_PARALLEL:
303*3d8817e4Smiod       use_parallel = 1;
304*3d8817e4Smiod       break;
305*3d8817e4Smiod 
306*3d8817e4Smiod     case OPTION_NO_PARALLEL:
307*3d8817e4Smiod       use_parallel = 0;
308*3d8817e4Smiod       break;
309*3d8817e4Smiod 
310*3d8817e4Smiod     case OPTION_WARN_PARALLEL:
311*3d8817e4Smiod       warn_explicit_parallel_conflicts = 1;
312*3d8817e4Smiod       break;
313*3d8817e4Smiod 
314*3d8817e4Smiod     case OPTION_NO_WARN_PARALLEL:
315*3d8817e4Smiod       warn_explicit_parallel_conflicts = 0;
316*3d8817e4Smiod       break;
317*3d8817e4Smiod 
318*3d8817e4Smiod     case OPTION_IGNORE_PARALLEL:
319*3d8817e4Smiod       ignore_parallel_conflicts = 1;
320*3d8817e4Smiod       break;
321*3d8817e4Smiod 
322*3d8817e4Smiod     case OPTION_NO_IGNORE_PARALLEL:
323*3d8817e4Smiod       ignore_parallel_conflicts = 0;
324*3d8817e4Smiod       break;
325*3d8817e4Smiod 
326*3d8817e4Smiod     case OPTION_SPECIAL:
327*3d8817e4Smiod       if (enable_m32rx)
328*3d8817e4Smiod 	enable_special = 1;
329*3d8817e4Smiod       else
330*3d8817e4Smiod 	{
331*3d8817e4Smiod 	  /* Pretend that we do not recognise this option.  */
332*3d8817e4Smiod 	  as_bad (_("Unrecognised option: -hidden"));
333*3d8817e4Smiod 	  return 0;
334*3d8817e4Smiod 	}
335*3d8817e4Smiod       break;
336*3d8817e4Smiod 
337*3d8817e4Smiod     case OPTION_SPECIAL_M32R:
338*3d8817e4Smiod       enable_special_m32r = 1;
339*3d8817e4Smiod       break;
340*3d8817e4Smiod 
341*3d8817e4Smiod     case OPTION_NO_SPECIAL_M32R:
342*3d8817e4Smiod       enable_special_m32r = 0;
343*3d8817e4Smiod       break;
344*3d8817e4Smiod 
345*3d8817e4Smiod     case OPTION_SPECIAL_FLOAT:
346*3d8817e4Smiod       enable_special_float = 1;
347*3d8817e4Smiod       break;
348*3d8817e4Smiod 
349*3d8817e4Smiod     case OPTION_WARN_UNMATCHED:
350*3d8817e4Smiod       warn_unmatched_high = 1;
351*3d8817e4Smiod       break;
352*3d8817e4Smiod 
353*3d8817e4Smiod     case OPTION_NO_WARN_UNMATCHED:
354*3d8817e4Smiod       warn_unmatched_high = 0;
355*3d8817e4Smiod       break;
356*3d8817e4Smiod 
357*3d8817e4Smiod     case 'K':
358*3d8817e4Smiod       if (strcmp (arg, "PIC") != 0)
359*3d8817e4Smiod         as_warn (_("Unrecognized option following -K"));
360*3d8817e4Smiod       else
361*3d8817e4Smiod         pic_code = 1;
362*3d8817e4Smiod       break;
363*3d8817e4Smiod 
364*3d8817e4Smiod     default:
365*3d8817e4Smiod       return 0;
366*3d8817e4Smiod     }
367*3d8817e4Smiod 
368*3d8817e4Smiod   return 1;
369*3d8817e4Smiod }
370*3d8817e4Smiod 
371*3d8817e4Smiod void
md_show_usage(FILE * stream)372*3d8817e4Smiod md_show_usage (FILE *stream)
373*3d8817e4Smiod {
374*3d8817e4Smiod   fprintf (stream, _(" M32R specific command line options:\n"));
375*3d8817e4Smiod 
376*3d8817e4Smiod   fprintf (stream, _("\
377*3d8817e4Smiod   -m32r                   disable support for the m32rx instruction set\n"));
378*3d8817e4Smiod   fprintf (stream, _("\
379*3d8817e4Smiod   -m32rx                  support the extended m32rx instruction set\n"));
380*3d8817e4Smiod   fprintf (stream, _("\
381*3d8817e4Smiod   -m32r2                  support the extended m32r2 instruction set\n"));
382*3d8817e4Smiod   fprintf (stream, _("\
383*3d8817e4Smiod   -EL,-little             produce little endian code and data\n"));
384*3d8817e4Smiod   fprintf (stream, _("\
385*3d8817e4Smiod   -EB,-big                produce big endian code and data\n"));
386*3d8817e4Smiod   fprintf (stream, _("\
387*3d8817e4Smiod   -parallel               try to combine instructions in parallel\n"));
388*3d8817e4Smiod   fprintf (stream, _("\
389*3d8817e4Smiod   -no-parallel            disable -parallel\n"));
390*3d8817e4Smiod   fprintf (stream, _("\
391*3d8817e4Smiod   -no-bitinst             disallow the M32R2's extended bit-field instructions\n"));
392*3d8817e4Smiod   fprintf (stream, _("\
393*3d8817e4Smiod   -O                      try to optimize code.  Implies -parallel\n"));
394*3d8817e4Smiod 
395*3d8817e4Smiod   fprintf (stream, _("\
396*3d8817e4Smiod   -warn-explicit-parallel-conflicts     warn when parallel instructions\n"));
397*3d8817e4Smiod   fprintf (stream, _("\
398*3d8817e4Smiod                                          might violate contraints\n"));
399*3d8817e4Smiod   fprintf (stream, _("\
400*3d8817e4Smiod   -no-warn-explicit-parallel-conflicts  do not warn when parallel\n"));
401*3d8817e4Smiod   fprintf (stream, _("\
402*3d8817e4Smiod                                          instructions might violate contraints\n"));
403*3d8817e4Smiod   fprintf (stream, _("\
404*3d8817e4Smiod   -Wp                     synonym for -warn-explicit-parallel-conflicts\n"));
405*3d8817e4Smiod   fprintf (stream, _("\
406*3d8817e4Smiod   -Wnp                    synonym for -no-warn-explicit-parallel-conflicts\n"));
407*3d8817e4Smiod   fprintf (stream, _("\
408*3d8817e4Smiod   -ignore-parallel-conflicts            do not check parallel instructions\n"));
409*3d8817e4Smiod   fprintf (stream, _("\
410*3d8817e4Smiod                                          fo contraint violations\n"));
411*3d8817e4Smiod   fprintf (stream, _("\
412*3d8817e4Smiod   -no-ignore-parallel-conflicts         check parallel instructions for\n"));
413*3d8817e4Smiod   fprintf (stream, _("\
414*3d8817e4Smiod                                          contraint violations\n"));
415*3d8817e4Smiod   fprintf (stream, _("\
416*3d8817e4Smiod   -Ip                     synonym for -ignore-parallel-conflicts\n"));
417*3d8817e4Smiod   fprintf (stream, _("\
418*3d8817e4Smiod   -nIp                    synonym for -no-ignore-parallel-conflicts\n"));
419*3d8817e4Smiod 
420*3d8817e4Smiod   fprintf (stream, _("\
421*3d8817e4Smiod   -warn-unmatched-high    warn when an (s)high reloc has no matching low reloc\n"));
422*3d8817e4Smiod   fprintf (stream, _("\
423*3d8817e4Smiod   -no-warn-unmatched-high do not warn about missing low relocs\n"));
424*3d8817e4Smiod   fprintf (stream, _("\
425*3d8817e4Smiod   -Wuh                    synonym for -warn-unmatched-high\n"));
426*3d8817e4Smiod   fprintf (stream, _("\
427*3d8817e4Smiod   -Wnuh                   synonym for -no-warn-unmatched-high\n"));
428*3d8817e4Smiod 
429*3d8817e4Smiod   fprintf (stream, _("\
430*3d8817e4Smiod   -KPIC                   generate PIC\n"));
431*3d8817e4Smiod }
432*3d8817e4Smiod 
433*3d8817e4Smiod /* Set by md_assemble for use by m32r_fill_insn.  */
434*3d8817e4Smiod static subsegT prev_subseg;
435*3d8817e4Smiod static segT prev_seg;
436*3d8817e4Smiod 
437*3d8817e4Smiod #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
438*3d8817e4Smiod symbolS * GOT_symbol;
439*3d8817e4Smiod 
440*3d8817e4Smiod static inline int
m32r_PIC_related_p(symbolS * sym)441*3d8817e4Smiod m32r_PIC_related_p (symbolS *sym)
442*3d8817e4Smiod {
443*3d8817e4Smiod   expressionS *exp;
444*3d8817e4Smiod 
445*3d8817e4Smiod   if (! sym)
446*3d8817e4Smiod     return 0;
447*3d8817e4Smiod 
448*3d8817e4Smiod   if (sym == GOT_symbol)
449*3d8817e4Smiod     return 1;
450*3d8817e4Smiod 
451*3d8817e4Smiod   exp = symbol_get_value_expression (sym);
452*3d8817e4Smiod 
453*3d8817e4Smiod   return (exp->X_op == O_PIC_reloc
454*3d8817e4Smiod           || exp->X_md == BFD_RELOC_M32R_26_PLTREL
455*3d8817e4Smiod           || m32r_PIC_related_p (exp->X_add_symbol)
456*3d8817e4Smiod           || m32r_PIC_related_p (exp->X_op_symbol));
457*3d8817e4Smiod }
458*3d8817e4Smiod 
459*3d8817e4Smiod static inline int
m32r_check_fixup(expressionS * main_exp,bfd_reloc_code_real_type * r_type_p)460*3d8817e4Smiod m32r_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p)
461*3d8817e4Smiod {
462*3d8817e4Smiod   expressionS *exp = main_exp;
463*3d8817e4Smiod 
464*3d8817e4Smiod   if (exp->X_op == O_add && m32r_PIC_related_p (exp->X_op_symbol))
465*3d8817e4Smiod     return 1;
466*3d8817e4Smiod 
467*3d8817e4Smiod   if (exp->X_op == O_symbol && exp->X_add_symbol)
468*3d8817e4Smiod     {
469*3d8817e4Smiod       if (exp->X_add_symbol == GOT_symbol)
470*3d8817e4Smiod         {
471*3d8817e4Smiod           *r_type_p = BFD_RELOC_M32R_GOTPC24;
472*3d8817e4Smiod           return 0;
473*3d8817e4Smiod         }
474*3d8817e4Smiod     }
475*3d8817e4Smiod   else if (exp->X_op == O_add)
476*3d8817e4Smiod     {
477*3d8817e4Smiod       exp = symbol_get_value_expression (exp->X_add_symbol);
478*3d8817e4Smiod       if (! exp)
479*3d8817e4Smiod         return 0;
480*3d8817e4Smiod     }
481*3d8817e4Smiod 
482*3d8817e4Smiod   if (exp->X_op == O_PIC_reloc)
483*3d8817e4Smiod     {
484*3d8817e4Smiod       *r_type_p = exp->X_md;
485*3d8817e4Smiod       if (exp == main_exp)
486*3d8817e4Smiod         exp->X_op = O_symbol;
487*3d8817e4Smiod       else
488*3d8817e4Smiod        {
489*3d8817e4Smiod           main_exp->X_add_symbol = exp->X_add_symbol;
490*3d8817e4Smiod           main_exp->X_add_number += exp->X_add_number;
491*3d8817e4Smiod        }
492*3d8817e4Smiod     }
493*3d8817e4Smiod   else
494*3d8817e4Smiod     return (m32r_PIC_related_p (exp->X_add_symbol)
495*3d8817e4Smiod             || m32r_PIC_related_p (exp->X_op_symbol));
496*3d8817e4Smiod 
497*3d8817e4Smiod   return 0;
498*3d8817e4Smiod }
499*3d8817e4Smiod 
500*3d8817e4Smiod /* FIXME: Should be machine generated.  */
501*3d8817e4Smiod #define NOP_INSN     0x7000
502*3d8817e4Smiod #define PAR_NOP_INSN 0xf000 /* Can only be used in 2nd slot.  */
503*3d8817e4Smiod 
504*3d8817e4Smiod /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
505*3d8817e4Smiod    of an rs_align_code fragment.  */
506*3d8817e4Smiod 
507*3d8817e4Smiod void
m32r_handle_align(fragS * fragp)508*3d8817e4Smiod m32r_handle_align (fragS *fragp)
509*3d8817e4Smiod {
510*3d8817e4Smiod   static const unsigned char nop_pattern[] = { 0xf0, 0x00 };
511*3d8817e4Smiod   static const unsigned char multi_nop_pattern[] = { 0x70, 0x00, 0xf0, 0x00 };
512*3d8817e4Smiod 
513*3d8817e4Smiod   int bytes, fix;
514*3d8817e4Smiod   char *p;
515*3d8817e4Smiod 
516*3d8817e4Smiod   if (fragp->fr_type != rs_align_code)
517*3d8817e4Smiod     return;
518*3d8817e4Smiod 
519*3d8817e4Smiod   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
520*3d8817e4Smiod   p = fragp->fr_literal + fragp->fr_fix;
521*3d8817e4Smiod   fix = 0;
522*3d8817e4Smiod 
523*3d8817e4Smiod   if (bytes & 1)
524*3d8817e4Smiod     {
525*3d8817e4Smiod       fix = 1;
526*3d8817e4Smiod       *p++ = 0;
527*3d8817e4Smiod       bytes--;
528*3d8817e4Smiod     }
529*3d8817e4Smiod 
530*3d8817e4Smiod   if (bytes & 2)
531*3d8817e4Smiod     {
532*3d8817e4Smiod       memcpy (p, nop_pattern, 2);
533*3d8817e4Smiod       p += 2;
534*3d8817e4Smiod       bytes -= 2;
535*3d8817e4Smiod       fix += 2;
536*3d8817e4Smiod     }
537*3d8817e4Smiod 
538*3d8817e4Smiod   memcpy (p, multi_nop_pattern, 4);
539*3d8817e4Smiod 
540*3d8817e4Smiod   fragp->fr_fix += fix;
541*3d8817e4Smiod   fragp->fr_var = 4;
542*3d8817e4Smiod }
543*3d8817e4Smiod 
544*3d8817e4Smiod /* If the last instruction was the first of 2 16 bit insns,
545*3d8817e4Smiod    output a nop to move the PC to a 32 bit boundary.
546*3d8817e4Smiod 
547*3d8817e4Smiod    This is done via an alignment specification since branch relaxing
548*3d8817e4Smiod    may make it unnecessary.
549*3d8817e4Smiod 
550*3d8817e4Smiod    Internally, we need to output one of these each time a 32 bit insn is
551*3d8817e4Smiod    seen after an insn that is relaxable.  */
552*3d8817e4Smiod 
553*3d8817e4Smiod static void
fill_insn(int ignore ATTRIBUTE_UNUSED)554*3d8817e4Smiod fill_insn (int ignore ATTRIBUTE_UNUSED)
555*3d8817e4Smiod {
556*3d8817e4Smiod   frag_align_code (2, 0);
557*3d8817e4Smiod   prev_insn.insn = NULL;
558*3d8817e4Smiod   seen_relaxable_p = 0;
559*3d8817e4Smiod }
560*3d8817e4Smiod 
561*3d8817e4Smiod /* Record the symbol so that when we output the insn, we can create
562*3d8817e4Smiod    a symbol that is at the start of the instruction.  This is used
563*3d8817e4Smiod    to emit the label for the start of a breakpoint without causing
564*3d8817e4Smiod    the assembler to emit a NOP if the previous instruction was a
565*3d8817e4Smiod    16 bit instruction.  */
566*3d8817e4Smiod 
567*3d8817e4Smiod static void
debug_sym(int ignore ATTRIBUTE_UNUSED)568*3d8817e4Smiod debug_sym (int ignore ATTRIBUTE_UNUSED)
569*3d8817e4Smiod {
570*3d8817e4Smiod   char *name;
571*3d8817e4Smiod   char delim;
572*3d8817e4Smiod   char *end_name;
573*3d8817e4Smiod   symbolS *symbolP;
574*3d8817e4Smiod   sym_linkS *link;
575*3d8817e4Smiod 
576*3d8817e4Smiod   name = input_line_pointer;
577*3d8817e4Smiod   delim = get_symbol_end ();
578*3d8817e4Smiod   end_name = input_line_pointer;
579*3d8817e4Smiod 
580*3d8817e4Smiod   if ((symbolP = symbol_find (name)) == NULL
581*3d8817e4Smiod       && (symbolP = md_undefined_symbol (name)) == NULL)
582*3d8817e4Smiod     symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
583*3d8817e4Smiod 
584*3d8817e4Smiod   symbol_table_insert (symbolP);
585*3d8817e4Smiod   if (S_IS_DEFINED (symbolP) && (S_GET_SEGMENT (symbolP) != reg_section
586*3d8817e4Smiod                                  || S_IS_EXTERNAL (symbolP)
587*3d8817e4Smiod                                  || S_IS_WEAK (symbolP)))
588*3d8817e4Smiod     /* xgettext:c-format */
589*3d8817e4Smiod     as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
590*3d8817e4Smiod 
591*3d8817e4Smiod   else
592*3d8817e4Smiod     {
593*3d8817e4Smiod       link = (sym_linkS *) xmalloc (sizeof (sym_linkS));
594*3d8817e4Smiod       link->symbol = symbolP;
595*3d8817e4Smiod       link->next = debug_sym_link;
596*3d8817e4Smiod       debug_sym_link = link;
597*3d8817e4Smiod       symbol_get_obj (symbolP)->local = 1;
598*3d8817e4Smiod     }
599*3d8817e4Smiod 
600*3d8817e4Smiod   *end_name = delim;
601*3d8817e4Smiod   demand_empty_rest_of_line ();
602*3d8817e4Smiod }
603*3d8817e4Smiod 
604*3d8817e4Smiod /* Second pass to expanding the debug symbols, go through linked
605*3d8817e4Smiod    list of symbols and reassign the address.  */
606*3d8817e4Smiod 
607*3d8817e4Smiod static void
expand_debug_syms(sym_linkS * syms,int align)608*3d8817e4Smiod expand_debug_syms (sym_linkS *syms, int align)
609*3d8817e4Smiod {
610*3d8817e4Smiod   char *save_input_line = input_line_pointer;
611*3d8817e4Smiod   sym_linkS *next_syms;
612*3d8817e4Smiod 
613*3d8817e4Smiod   if (!syms)
614*3d8817e4Smiod     return;
615*3d8817e4Smiod 
616*3d8817e4Smiod   (void) frag_align_code (align, 0);
617*3d8817e4Smiod   for (; syms != (sym_linkS *) 0; syms = next_syms)
618*3d8817e4Smiod     {
619*3d8817e4Smiod       symbolS *symbolP = syms->symbol;
620*3d8817e4Smiod       next_syms = syms->next;
621*3d8817e4Smiod       input_line_pointer = ".\n";
622*3d8817e4Smiod       pseudo_set (symbolP);
623*3d8817e4Smiod       free ((char *) syms);
624*3d8817e4Smiod     }
625*3d8817e4Smiod 
626*3d8817e4Smiod   input_line_pointer = save_input_line;
627*3d8817e4Smiod }
628*3d8817e4Smiod 
629*3d8817e4Smiod void
m32r_flush_pending_output(void)630*3d8817e4Smiod m32r_flush_pending_output (void)
631*3d8817e4Smiod {
632*3d8817e4Smiod   if (debug_sym_link)
633*3d8817e4Smiod     {
634*3d8817e4Smiod       expand_debug_syms (debug_sym_link, 1);
635*3d8817e4Smiod       debug_sym_link = (sym_linkS *) 0;
636*3d8817e4Smiod     }
637*3d8817e4Smiod }
638*3d8817e4Smiod 
639*3d8817e4Smiod /* Cover function to fill_insn called after a label and at end of assembly.
640*3d8817e4Smiod    The result is always 1: we're called in a conditional to see if the
641*3d8817e4Smiod    current line is a label.  */
642*3d8817e4Smiod 
643*3d8817e4Smiod int
m32r_fill_insn(int done)644*3d8817e4Smiod m32r_fill_insn (int done)
645*3d8817e4Smiod {
646*3d8817e4Smiod   if (prev_seg != NULL)
647*3d8817e4Smiod     {
648*3d8817e4Smiod       segT seg = now_seg;
649*3d8817e4Smiod       subsegT subseg = now_subseg;
650*3d8817e4Smiod 
651*3d8817e4Smiod       subseg_set (prev_seg, prev_subseg);
652*3d8817e4Smiod 
653*3d8817e4Smiod       fill_insn (0);
654*3d8817e4Smiod 
655*3d8817e4Smiod       subseg_set (seg, subseg);
656*3d8817e4Smiod     }
657*3d8817e4Smiod 
658*3d8817e4Smiod   if (done && debug_sym_link)
659*3d8817e4Smiod     {
660*3d8817e4Smiod       expand_debug_syms (debug_sym_link, 1);
661*3d8817e4Smiod       debug_sym_link = (sym_linkS *) 0;
662*3d8817e4Smiod     }
663*3d8817e4Smiod 
664*3d8817e4Smiod   return 1;
665*3d8817e4Smiod }
666*3d8817e4Smiod 
667*3d8817e4Smiod /* The default target format to use.  */
668*3d8817e4Smiod 
669*3d8817e4Smiod const char *
m32r_target_format(void)670*3d8817e4Smiod m32r_target_format (void)
671*3d8817e4Smiod {
672*3d8817e4Smiod #ifdef TE_LINUX
673*3d8817e4Smiod   if (target_big_endian)
674*3d8817e4Smiod     return "elf32-m32r-linux";
675*3d8817e4Smiod   else
676*3d8817e4Smiod     return "elf32-m32rle-linux";
677*3d8817e4Smiod #else
678*3d8817e4Smiod   if (target_big_endian)
679*3d8817e4Smiod     return "elf32-m32r";
680*3d8817e4Smiod   else
681*3d8817e4Smiod     return "elf32-m32rle";
682*3d8817e4Smiod #endif
683*3d8817e4Smiod }
684*3d8817e4Smiod 
685*3d8817e4Smiod void
md_begin(void)686*3d8817e4Smiod md_begin (void)
687*3d8817e4Smiod {
688*3d8817e4Smiod   flagword applicable;
689*3d8817e4Smiod   segT seg;
690*3d8817e4Smiod   subsegT subseg;
691*3d8817e4Smiod 
692*3d8817e4Smiod   /* Initialize the `cgen' interface.  */
693*3d8817e4Smiod 
694*3d8817e4Smiod   /* Set the machine number and endian.  */
695*3d8817e4Smiod   gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0,
696*3d8817e4Smiod 					  CGEN_CPU_OPEN_ENDIAN,
697*3d8817e4Smiod 					  (target_big_endian ?
698*3d8817e4Smiod 					   CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE),
699*3d8817e4Smiod 					  CGEN_CPU_OPEN_END);
700*3d8817e4Smiod   m32r_cgen_init_asm (gas_cgen_cpu_desc);
701*3d8817e4Smiod 
702*3d8817e4Smiod   /* The operand instance table is used during optimization to determine
703*3d8817e4Smiod      which insns can be executed in parallel.  It is also used to give
704*3d8817e4Smiod      warnings regarding operand interference in parallel insns.  */
705*3d8817e4Smiod   m32r_cgen_init_opinst_table (gas_cgen_cpu_desc);
706*3d8817e4Smiod 
707*3d8817e4Smiod   /* This is a callback from cgen to gas to parse operands.  */
708*3d8817e4Smiod   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
709*3d8817e4Smiod 
710*3d8817e4Smiod   /* Save the current subseg so we can restore it [it's the default one and
711*3d8817e4Smiod      we don't want the initial section to be .sbss].  */
712*3d8817e4Smiod   seg    = now_seg;
713*3d8817e4Smiod   subseg = now_subseg;
714*3d8817e4Smiod 
715*3d8817e4Smiod   /* The sbss section is for local .scomm symbols.  */
716*3d8817e4Smiod   sbss_section = subseg_new (".sbss", 0);
717*3d8817e4Smiod 
718*3d8817e4Smiod   /* This is copied from perform_an_assembly_pass.  */
719*3d8817e4Smiod   applicable = bfd_applicable_section_flags (stdoutput);
720*3d8817e4Smiod   bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
721*3d8817e4Smiod 
722*3d8817e4Smiod   subseg_set (seg, subseg);
723*3d8817e4Smiod 
724*3d8817e4Smiod   /* We must construct a fake section similar to bfd_com_section
725*3d8817e4Smiod      but with the name .scommon.  */
726*3d8817e4Smiod   scom_section                = bfd_com_section;
727*3d8817e4Smiod   scom_section.name           = ".scommon";
728*3d8817e4Smiod   scom_section.output_section = & scom_section;
729*3d8817e4Smiod   scom_section.symbol         = & scom_symbol;
730*3d8817e4Smiod   scom_section.symbol_ptr_ptr = & scom_section.symbol;
731*3d8817e4Smiod   scom_symbol                 = * bfd_com_section.symbol;
732*3d8817e4Smiod   scom_symbol.name            = ".scommon";
733*3d8817e4Smiod   scom_symbol.section         = & scom_section;
734*3d8817e4Smiod 
735*3d8817e4Smiod   allow_m32rx (enable_m32rx);
736*3d8817e4Smiod 
737*3d8817e4Smiod   gas_cgen_initialize_saved_fixups_array ();
738*3d8817e4Smiod }
739*3d8817e4Smiod 
740*3d8817e4Smiod #define OPERAND_IS_COND_BIT(operand, indices, index) \
741*3d8817e4Smiod   ((operand)->hw_type == HW_H_COND			\
742*3d8817e4Smiod    || ((operand)->hw_type == HW_H_PSW)			\
743*3d8817e4Smiod    || ((operand)->hw_type == HW_H_CR			\
744*3d8817e4Smiod        && (indices [index] == 0 || indices [index] == 1)))
745*3d8817e4Smiod 
746*3d8817e4Smiod /* Returns true if an output of instruction 'a' is referenced by an operand
747*3d8817e4Smiod    of instruction 'b'.  If 'check_outputs' is true then b's outputs are
748*3d8817e4Smiod    checked, otherwise its inputs are examined.  */
749*3d8817e4Smiod 
750*3d8817e4Smiod static int
first_writes_to_seconds_operands(m32r_insn * a,m32r_insn * b,const int check_outputs)751*3d8817e4Smiod first_writes_to_seconds_operands (m32r_insn *a,
752*3d8817e4Smiod 				  m32r_insn *b,
753*3d8817e4Smiod 				  const int check_outputs)
754*3d8817e4Smiod {
755*3d8817e4Smiod   const CGEN_OPINST *a_operands = CGEN_INSN_OPERANDS (a->insn);
756*3d8817e4Smiod   const CGEN_OPINST *b_ops = CGEN_INSN_OPERANDS (b->insn);
757*3d8817e4Smiod   int a_index;
758*3d8817e4Smiod 
759*3d8817e4Smiod   if (ignore_parallel_conflicts)
760*3d8817e4Smiod     return 0;
761*3d8817e4Smiod 
762*3d8817e4Smiod   /* If at least one of the instructions takes no operands, then there is
763*3d8817e4Smiod      nothing to check.  There really are instructions without operands,
764*3d8817e4Smiod      eg 'nop'.  */
765*3d8817e4Smiod   if (a_operands == NULL || b_ops == NULL)
766*3d8817e4Smiod     return 0;
767*3d8817e4Smiod 
768*3d8817e4Smiod   /* Scan the operand list of 'a' looking for an output operand.  */
769*3d8817e4Smiod   for (a_index = 0;
770*3d8817e4Smiod        a_operands->type != CGEN_OPINST_END;
771*3d8817e4Smiod        a_index ++, a_operands ++)
772*3d8817e4Smiod     {
773*3d8817e4Smiod       if (a_operands->type == CGEN_OPINST_OUTPUT)
774*3d8817e4Smiod 	{
775*3d8817e4Smiod 	  int b_index;
776*3d8817e4Smiod 	  const CGEN_OPINST *b_operands = b_ops;
777*3d8817e4Smiod 
778*3d8817e4Smiod 	  /* Special Case:
779*3d8817e4Smiod 	     The Condition bit 'C' is a shadow of the CBR register (control
780*3d8817e4Smiod 	     register 1) and also a shadow of bit 31 of the program status
781*3d8817e4Smiod 	     word (control register 0).  For now this is handled here, rather
782*3d8817e4Smiod 	     than by cgen....  */
783*3d8817e4Smiod 
784*3d8817e4Smiod 	  if (OPERAND_IS_COND_BIT (a_operands, a->indices, a_index))
785*3d8817e4Smiod 	    {
786*3d8817e4Smiod 	      /* Scan operand list of 'b' looking for another reference to the
787*3d8817e4Smiod 		 condition bit, which goes in the right direction.  */
788*3d8817e4Smiod 	      for (b_index = 0;
789*3d8817e4Smiod 		   b_operands->type != CGEN_OPINST_END;
790*3d8817e4Smiod 		   b_index++, b_operands++)
791*3d8817e4Smiod 		{
792*3d8817e4Smiod 		  if ((b_operands->type
793*3d8817e4Smiod 		       == (check_outputs
794*3d8817e4Smiod 			   ? CGEN_OPINST_OUTPUT
795*3d8817e4Smiod 			   : CGEN_OPINST_INPUT))
796*3d8817e4Smiod 		      && OPERAND_IS_COND_BIT (b_operands, b->indices, b_index))
797*3d8817e4Smiod 		    return 1;
798*3d8817e4Smiod 		}
799*3d8817e4Smiod 	    }
800*3d8817e4Smiod 	  else
801*3d8817e4Smiod 	    {
802*3d8817e4Smiod 	      /* Scan operand list of 'b' looking for an operand that
803*3d8817e4Smiod 		 references the same hardware element, and which goes in the
804*3d8817e4Smiod 		 right direction.  */
805*3d8817e4Smiod 	      for (b_index = 0;
806*3d8817e4Smiod 		   b_operands->type != CGEN_OPINST_END;
807*3d8817e4Smiod 		   b_index++, b_operands++)
808*3d8817e4Smiod 		{
809*3d8817e4Smiod 		  if ((b_operands->type
810*3d8817e4Smiod 		       == (check_outputs
811*3d8817e4Smiod 			   ? CGEN_OPINST_OUTPUT
812*3d8817e4Smiod 			   : CGEN_OPINST_INPUT))
813*3d8817e4Smiod 		      && (b_operands->hw_type == a_operands->hw_type)
814*3d8817e4Smiod 		      && (a->indices[a_index] == b->indices[b_index]))
815*3d8817e4Smiod 		    return 1;
816*3d8817e4Smiod 		}
817*3d8817e4Smiod 	    }
818*3d8817e4Smiod 	}
819*3d8817e4Smiod     }
820*3d8817e4Smiod 
821*3d8817e4Smiod   return 0;
822*3d8817e4Smiod }
823*3d8817e4Smiod 
824*3d8817e4Smiod /* Returns true if the insn can (potentially) alter the program counter.  */
825*3d8817e4Smiod 
826*3d8817e4Smiod static int
writes_to_pc(m32r_insn * a)827*3d8817e4Smiod writes_to_pc (m32r_insn *a)
828*3d8817e4Smiod {
829*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (a->insn, CGEN_INSN_UNCOND_CTI)
830*3d8817e4Smiod       || CGEN_INSN_ATTR_VALUE (a->insn, CGEN_INSN_COND_CTI))
831*3d8817e4Smiod     return 1;
832*3d8817e4Smiod   return 0;
833*3d8817e4Smiod }
834*3d8817e4Smiod 
835*3d8817e4Smiod /* Return NULL if the two 16 bit insns can be executed in parallel.
836*3d8817e4Smiod    Otherwise return a pointer to an error message explaining why not.  */
837*3d8817e4Smiod 
838*3d8817e4Smiod static const char *
can_make_parallel(m32r_insn * a,m32r_insn * b)839*3d8817e4Smiod can_make_parallel (m32r_insn *a, m32r_insn *b)
840*3d8817e4Smiod {
841*3d8817e4Smiod   PIPE_ATTR a_pipe;
842*3d8817e4Smiod   PIPE_ATTR b_pipe;
843*3d8817e4Smiod 
844*3d8817e4Smiod   /* Make sure the instructions are the right length.  */
845*3d8817e4Smiod   if (CGEN_FIELDS_BITSIZE (&a->fields) != 16
846*3d8817e4Smiod       || CGEN_FIELDS_BITSIZE (&b->fields) != 16)
847*3d8817e4Smiod     abort ();
848*3d8817e4Smiod 
849*3d8817e4Smiod   if (first_writes_to_seconds_operands (a, b, TRUE))
850*3d8817e4Smiod     return _("instructions write to the same destination register.");
851*3d8817e4Smiod 
852*3d8817e4Smiod   a_pipe = CGEN_INSN_ATTR_VALUE (a->insn, CGEN_INSN_PIPE);
853*3d8817e4Smiod   b_pipe = CGEN_INSN_ATTR_VALUE (b->insn, CGEN_INSN_PIPE);
854*3d8817e4Smiod 
855*3d8817e4Smiod   /* Make sure that the instructions use the correct execution pipelines.  */
856*3d8817e4Smiod   if (a_pipe == PIPE_NONE
857*3d8817e4Smiod       || b_pipe == PIPE_NONE)
858*3d8817e4Smiod     return _("Instructions do not use parallel execution pipelines.");
859*3d8817e4Smiod 
860*3d8817e4Smiod   /* Leave this test for last, since it is the only test that can
861*3d8817e4Smiod      go away if the instructions are swapped, and we want to make
862*3d8817e4Smiod      sure that any other errors are detected before this happens.  */
863*3d8817e4Smiod   if (a_pipe == PIPE_S
864*3d8817e4Smiod       || b_pipe == PIPE_O
865*3d8817e4Smiod       || (b_pipe == PIPE_O_OS && (enable_m32rx != 2)))
866*3d8817e4Smiod     return _("Instructions share the same execution pipeline");
867*3d8817e4Smiod 
868*3d8817e4Smiod   return NULL;
869*3d8817e4Smiod }
870*3d8817e4Smiod 
871*3d8817e4Smiod /* Force the top bit of the second 16-bit insn to be set.  */
872*3d8817e4Smiod 
873*3d8817e4Smiod static void
make_parallel(CGEN_INSN_BYTES_PTR buffer)874*3d8817e4Smiod make_parallel (CGEN_INSN_BYTES_PTR buffer)
875*3d8817e4Smiod {
876*3d8817e4Smiod #if CGEN_INT_INSN_P
877*3d8817e4Smiod   *buffer |= 0x8000;
878*3d8817e4Smiod #else
879*3d8817e4Smiod   buffer[CGEN_CPU_ENDIAN (gas_cgen_cpu_desc) == CGEN_ENDIAN_BIG ? 0 : 1]
880*3d8817e4Smiod     |= 0x80;
881*3d8817e4Smiod #endif
882*3d8817e4Smiod }
883*3d8817e4Smiod 
884*3d8817e4Smiod /* Same as make_parallel except buffer contains the bytes in target order.  */
885*3d8817e4Smiod 
886*3d8817e4Smiod static void
target_make_parallel(char * buffer)887*3d8817e4Smiod target_make_parallel (char *buffer)
888*3d8817e4Smiod {
889*3d8817e4Smiod   buffer[CGEN_CPU_ENDIAN (gas_cgen_cpu_desc) == CGEN_ENDIAN_BIG ? 0 : 1]
890*3d8817e4Smiod     |= 0x80;
891*3d8817e4Smiod }
892*3d8817e4Smiod 
893*3d8817e4Smiod /* Assemble two instructions with an explicit parallel operation (||) or
894*3d8817e4Smiod    sequential operation (->).  */
895*3d8817e4Smiod 
896*3d8817e4Smiod static void
assemble_two_insns(char * str1,char * str2,int parallel_p)897*3d8817e4Smiod assemble_two_insns (char *str1, char *str2, int parallel_p)
898*3d8817e4Smiod {
899*3d8817e4Smiod   char *str3;
900*3d8817e4Smiod   m32r_insn first;
901*3d8817e4Smiod   m32r_insn second;
902*3d8817e4Smiod   char *errmsg;
903*3d8817e4Smiod   char save_str2 = *str2;
904*3d8817e4Smiod 
905*3d8817e4Smiod   /* Separate the two instructions.  */
906*3d8817e4Smiod   *str2 = 0;
907*3d8817e4Smiod 
908*3d8817e4Smiod   /* Make sure the two insns begin on a 32 bit boundary.
909*3d8817e4Smiod      This is also done for the serial case (foo -> bar), relaxing doesn't
910*3d8817e4Smiod      affect insns written like this.
911*3d8817e4Smiod      Note that we must always do this as we can't assume anything about
912*3d8817e4Smiod      whether we're currently on a 32 bit boundary or not.  Relaxing may
913*3d8817e4Smiod      change this.  */
914*3d8817e4Smiod   fill_insn (0);
915*3d8817e4Smiod 
916*3d8817e4Smiod   first.debug_sym_link = debug_sym_link;
917*3d8817e4Smiod   debug_sym_link = (sym_linkS *) 0;
918*3d8817e4Smiod 
919*3d8817e4Smiod   /* Parse the first instruction.  */
920*3d8817e4Smiod   if (! (first.insn = m32r_cgen_assemble_insn
921*3d8817e4Smiod 	 (gas_cgen_cpu_desc, str1, & first.fields, first.buffer, & errmsg)))
922*3d8817e4Smiod     {
923*3d8817e4Smiod       as_bad (errmsg);
924*3d8817e4Smiod       return;
925*3d8817e4Smiod     }
926*3d8817e4Smiod 
927*3d8817e4Smiod   /* Check it.  */
928*3d8817e4Smiod   if (CGEN_FIELDS_BITSIZE (&first.fields) != 16)
929*3d8817e4Smiod     {
930*3d8817e4Smiod       /* xgettext:c-format  */
931*3d8817e4Smiod       as_bad (_("not a 16 bit instruction '%s'"), str1);
932*3d8817e4Smiod       return;
933*3d8817e4Smiod     }
934*3d8817e4Smiod #ifdef E_M32R2_ARCH
935*3d8817e4Smiod   else if ((enable_m32rx == 1)
936*3d8817e4Smiod            /* FIXME: Need standard macro to perform this test.  */
937*3d8817e4Smiod            && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
938*3d8817e4Smiod                 & (1 << MACH_M32R2))
939*3d8817e4Smiod                && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
940*3d8817e4Smiod                     & (1 << MACH_M32RX)))))
941*3d8817e4Smiod     {
942*3d8817e4Smiod       /* xgettext:c-format  */
943*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32R2 only"), str1);
944*3d8817e4Smiod       return;
945*3d8817e4Smiod     }
946*3d8817e4Smiod   else if ((! enable_special
947*3d8817e4Smiod             && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL))
948*3d8817e4Smiod            || (! enable_special_m32r
949*3d8817e4Smiod                && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R)))
950*3d8817e4Smiod #else
951*3d8817e4Smiod   else if (! enable_special
952*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL))
953*3d8817e4Smiod #endif
954*3d8817e4Smiod     {
955*3d8817e4Smiod       /* xgettext:c-format  */
956*3d8817e4Smiod       as_bad (_("unknown instruction '%s'"), str1);
957*3d8817e4Smiod       return;
958*3d8817e4Smiod     }
959*3d8817e4Smiod   else if (! enable_m32rx
960*3d8817e4Smiod 	   /* FIXME: Need standard macro to perform this test.  */
961*3d8817e4Smiod 	   && (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
962*3d8817e4Smiod 	       == (1 << MACH_M32RX)))
963*3d8817e4Smiod     {
964*3d8817e4Smiod       /* xgettext:c-format  */
965*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32RX only"), str1);
966*3d8817e4Smiod       return;
967*3d8817e4Smiod     }
968*3d8817e4Smiod 
969*3d8817e4Smiod   /* Check to see if this is an allowable parallel insn.  */
970*3d8817e4Smiod   if (parallel_p
971*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_PIPE) == PIPE_NONE)
972*3d8817e4Smiod     {
973*3d8817e4Smiod       /* xgettext:c-format  */
974*3d8817e4Smiod       as_bad (_("instruction '%s' cannot be executed in parallel."), str1);
975*3d8817e4Smiod       return;
976*3d8817e4Smiod     }
977*3d8817e4Smiod 
978*3d8817e4Smiod   /* Restore the original assembly text, just in case it is needed.  */
979*3d8817e4Smiod   *str2 = save_str2;
980*3d8817e4Smiod 
981*3d8817e4Smiod   /* Save the original string pointer.  */
982*3d8817e4Smiod   str3 = str1;
983*3d8817e4Smiod 
984*3d8817e4Smiod   /* Advanced past the parsed string.  */
985*3d8817e4Smiod   str1 = str2 + 2;
986*3d8817e4Smiod 
987*3d8817e4Smiod   /* Remember the entire string in case it is needed for error
988*3d8817e4Smiod      messages.  */
989*3d8817e4Smiod   str2 = str3;
990*3d8817e4Smiod 
991*3d8817e4Smiod   /* Convert the opcode to lower case.  */
992*3d8817e4Smiod   {
993*3d8817e4Smiod     char *s2 = str1;
994*3d8817e4Smiod 
995*3d8817e4Smiod     while (ISSPACE (*s2++))
996*3d8817e4Smiod       continue;
997*3d8817e4Smiod 
998*3d8817e4Smiod     --s2;
999*3d8817e4Smiod 
1000*3d8817e4Smiod     while (ISALNUM (*s2))
1001*3d8817e4Smiod       {
1002*3d8817e4Smiod 	*s2 = TOLOWER (*s2);
1003*3d8817e4Smiod 	s2++;
1004*3d8817e4Smiod       }
1005*3d8817e4Smiod   }
1006*3d8817e4Smiod 
1007*3d8817e4Smiod   /* Preserve any fixups that have been generated and reset the list
1008*3d8817e4Smiod      to empty.  */
1009*3d8817e4Smiod   gas_cgen_save_fixups (0);
1010*3d8817e4Smiod 
1011*3d8817e4Smiod   /* Get the indices of the operands of the instruction.  */
1012*3d8817e4Smiod   /* FIXME: CGEN_FIELDS is already recorded, but relying on that fact
1013*3d8817e4Smiod      doesn't seem right.  Perhaps allow passing fields like we do insn.  */
1014*3d8817e4Smiod   /* FIXME: ALIAS insns do not have operands, so we use this function
1015*3d8817e4Smiod      to find the equivalent insn and overwrite the value stored in our
1016*3d8817e4Smiod      structure.  We still need the original insn, however, since this
1017*3d8817e4Smiod      may have certain attributes that are not present in the unaliased
1018*3d8817e4Smiod      version (eg relaxability).  When aliases behave differently this
1019*3d8817e4Smiod      may have to change.  */
1020*3d8817e4Smiod   first.orig_insn = first.insn;
1021*3d8817e4Smiod   {
1022*3d8817e4Smiod     CGEN_FIELDS tmp_fields;
1023*3d8817e4Smiod     first.insn = cgen_lookup_get_insn_operands
1024*3d8817e4Smiod       (gas_cgen_cpu_desc, NULL, INSN_VALUE (first.buffer), NULL, 16,
1025*3d8817e4Smiod        first.indices, &tmp_fields);
1026*3d8817e4Smiod   }
1027*3d8817e4Smiod 
1028*3d8817e4Smiod   if (first.insn == NULL)
1029*3d8817e4Smiod     as_fatal (_("internal error: lookup/get operands failed"));
1030*3d8817e4Smiod 
1031*3d8817e4Smiod   second.debug_sym_link = NULL;
1032*3d8817e4Smiod 
1033*3d8817e4Smiod   /* Parse the second instruction.  */
1034*3d8817e4Smiod   if (! (second.insn = m32r_cgen_assemble_insn
1035*3d8817e4Smiod 	 (gas_cgen_cpu_desc, str1, & second.fields, second.buffer, & errmsg)))
1036*3d8817e4Smiod     {
1037*3d8817e4Smiod       as_bad (errmsg);
1038*3d8817e4Smiod       return;
1039*3d8817e4Smiod     }
1040*3d8817e4Smiod 
1041*3d8817e4Smiod   /* Check it.  */
1042*3d8817e4Smiod   if (CGEN_FIELDS_BITSIZE (&second.fields) != 16)
1043*3d8817e4Smiod     {
1044*3d8817e4Smiod       /* xgettext:c-format  */
1045*3d8817e4Smiod       as_bad (_("not a 16 bit instruction '%s'"), str1);
1046*3d8817e4Smiod       return;
1047*3d8817e4Smiod     }
1048*3d8817e4Smiod #ifdef E_M32R2_ARCH
1049*3d8817e4Smiod   else if ((enable_m32rx == 1)
1050*3d8817e4Smiod            /* FIXME: Need standard macro to perform this test.  */
1051*3d8817e4Smiod            && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
1052*3d8817e4Smiod                 & (1 << MACH_M32R2))
1053*3d8817e4Smiod                && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH)
1054*3d8817e4Smiod                     & (1 << MACH_M32RX)))))
1055*3d8817e4Smiod     {
1056*3d8817e4Smiod       /* xgettext:c-format  */
1057*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32R2 only"), str1);
1058*3d8817e4Smiod       return;
1059*3d8817e4Smiod     }
1060*3d8817e4Smiod   else if ((! enable_special
1061*3d8817e4Smiod             && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
1062*3d8817e4Smiod            || (! enable_special_m32r
1063*3d8817e4Smiod                && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R)))
1064*3d8817e4Smiod #else
1065*3d8817e4Smiod   else if (! enable_special
1066*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
1067*3d8817e4Smiod #endif
1068*3d8817e4Smiod     {
1069*3d8817e4Smiod       /* xgettext:c-format  */
1070*3d8817e4Smiod       as_bad (_("unknown instruction '%s'"), str1);
1071*3d8817e4Smiod       return;
1072*3d8817e4Smiod     }
1073*3d8817e4Smiod   else if (! enable_m32rx
1074*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
1075*3d8817e4Smiod     {
1076*3d8817e4Smiod       /* xgettext:c-format  */
1077*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32RX only"), str1);
1078*3d8817e4Smiod       return;
1079*3d8817e4Smiod     }
1080*3d8817e4Smiod 
1081*3d8817e4Smiod   /* Check to see if this is an allowable parallel insn.  */
1082*3d8817e4Smiod   if (parallel_p
1083*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_PIPE) == PIPE_NONE)
1084*3d8817e4Smiod     {
1085*3d8817e4Smiod       /* xgettext:c-format  */
1086*3d8817e4Smiod       as_bad (_("instruction '%s' cannot be executed in parallel."), str1);
1087*3d8817e4Smiod       return;
1088*3d8817e4Smiod     }
1089*3d8817e4Smiod 
1090*3d8817e4Smiod   if (parallel_p && ! enable_m32rx)
1091*3d8817e4Smiod     {
1092*3d8817e4Smiod       if (CGEN_INSN_NUM (first.insn) != M32R_INSN_NOP
1093*3d8817e4Smiod 	  && CGEN_INSN_NUM (second.insn) != M32R_INSN_NOP)
1094*3d8817e4Smiod 	{
1095*3d8817e4Smiod 	  /* xgettext:c-format  */
1096*3d8817e4Smiod 	  as_bad (_("'%s': only the NOP instruction can be issued in parallel on the m32r"), str2);
1097*3d8817e4Smiod 	  return;
1098*3d8817e4Smiod 	}
1099*3d8817e4Smiod     }
1100*3d8817e4Smiod 
1101*3d8817e4Smiod   /* Get the indices of the operands of the instruction.  */
1102*3d8817e4Smiod   second.orig_insn = second.insn;
1103*3d8817e4Smiod   {
1104*3d8817e4Smiod     CGEN_FIELDS tmp_fields;
1105*3d8817e4Smiod     second.insn = cgen_lookup_get_insn_operands
1106*3d8817e4Smiod       (gas_cgen_cpu_desc, NULL, INSN_VALUE (second.buffer), NULL, 16,
1107*3d8817e4Smiod        second.indices, &tmp_fields);
1108*3d8817e4Smiod   }
1109*3d8817e4Smiod 
1110*3d8817e4Smiod   if (second.insn == NULL)
1111*3d8817e4Smiod     as_fatal (_("internal error: lookup/get operands failed"));
1112*3d8817e4Smiod 
1113*3d8817e4Smiod   /* We assume that if the first instruction writes to a register that is
1114*3d8817e4Smiod      read by the second instruction it is because the programmer intended
1115*3d8817e4Smiod      this to happen, (after all they have explicitly requested that these
1116*3d8817e4Smiod      two instructions be executed in parallel).  Although if the global
1117*3d8817e4Smiod      variable warn_explicit_parallel_conflicts is true then we do generate
1118*3d8817e4Smiod      a warning message.  Similarly we assume that parallel branch and jump
1119*3d8817e4Smiod      instructions are deliberate and should not produce errors.  */
1120*3d8817e4Smiod 
1121*3d8817e4Smiod   if (parallel_p && warn_explicit_parallel_conflicts)
1122*3d8817e4Smiod     {
1123*3d8817e4Smiod       if (first_writes_to_seconds_operands (&first, &second, FALSE))
1124*3d8817e4Smiod 	/* xgettext:c-format  */
1125*3d8817e4Smiod 	as_warn (_("%s: output of 1st instruction is the same as an input to 2nd instruction - is this intentional ?"), str2);
1126*3d8817e4Smiod 
1127*3d8817e4Smiod       if (first_writes_to_seconds_operands (&second, &first, FALSE))
1128*3d8817e4Smiod 	/* xgettext:c-format  */
1129*3d8817e4Smiod 	as_warn (_("%s: output of 2nd instruction is the same as an input to 1st instruction - is this intentional ?"), str2);
1130*3d8817e4Smiod     }
1131*3d8817e4Smiod 
1132*3d8817e4Smiod   if (!parallel_p
1133*3d8817e4Smiod       || (errmsg = (char *) can_make_parallel (&first, &second)) == NULL)
1134*3d8817e4Smiod     {
1135*3d8817e4Smiod       /* Get the fixups for the first instruction.  */
1136*3d8817e4Smiod       gas_cgen_swap_fixups (0);
1137*3d8817e4Smiod 
1138*3d8817e4Smiod       /* Write it out.  */
1139*3d8817e4Smiod       expand_debug_syms (first.debug_sym_link, 1);
1140*3d8817e4Smiod       gas_cgen_finish_insn (first.orig_insn, first.buffer,
1141*3d8817e4Smiod 			    CGEN_FIELDS_BITSIZE (&first.fields), 0, NULL);
1142*3d8817e4Smiod 
1143*3d8817e4Smiod       /* Force the top bit of the second insn to be set.  */
1144*3d8817e4Smiod       if (parallel_p)
1145*3d8817e4Smiod 	make_parallel (second.buffer);
1146*3d8817e4Smiod 
1147*3d8817e4Smiod       /* Get its fixups.  */
1148*3d8817e4Smiod       gas_cgen_restore_fixups (0);
1149*3d8817e4Smiod 
1150*3d8817e4Smiod       /* Write it out.  */
1151*3d8817e4Smiod       expand_debug_syms (second.debug_sym_link, 1);
1152*3d8817e4Smiod       gas_cgen_finish_insn (second.orig_insn, second.buffer,
1153*3d8817e4Smiod 			    CGEN_FIELDS_BITSIZE (&second.fields), 0, NULL);
1154*3d8817e4Smiod     }
1155*3d8817e4Smiod   /* Try swapping the instructions to see if they work that way.  */
1156*3d8817e4Smiod   else if (can_make_parallel (&second, &first) == NULL)
1157*3d8817e4Smiod     {
1158*3d8817e4Smiod       /* Write out the second instruction first.  */
1159*3d8817e4Smiod       expand_debug_syms (second.debug_sym_link, 1);
1160*3d8817e4Smiod       gas_cgen_finish_insn (second.orig_insn, second.buffer,
1161*3d8817e4Smiod 			    CGEN_FIELDS_BITSIZE (&second.fields), 0, NULL);
1162*3d8817e4Smiod 
1163*3d8817e4Smiod       /* Force the top bit of the first instruction to be set.  */
1164*3d8817e4Smiod       make_parallel (first.buffer);
1165*3d8817e4Smiod 
1166*3d8817e4Smiod       /* Get the fixups for the first instruction.  */
1167*3d8817e4Smiod       gas_cgen_restore_fixups (0);
1168*3d8817e4Smiod 
1169*3d8817e4Smiod       /* Write out the first instruction.  */
1170*3d8817e4Smiod       expand_debug_syms (first.debug_sym_link, 1);
1171*3d8817e4Smiod       gas_cgen_finish_insn (first.orig_insn, first.buffer,
1172*3d8817e4Smiod 			    CGEN_FIELDS_BITSIZE (&first.fields), 0, NULL);
1173*3d8817e4Smiod     }
1174*3d8817e4Smiod   else
1175*3d8817e4Smiod     {
1176*3d8817e4Smiod       as_bad ("'%s': %s", str2, errmsg);
1177*3d8817e4Smiod       return;
1178*3d8817e4Smiod     }
1179*3d8817e4Smiod 
1180*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL)
1181*3d8817e4Smiod       || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL))
1182*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_HIDDEN_INST;
1183*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R)
1184*3d8817e4Smiod       || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R))
1185*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_BIT_INST;
1186*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_FLOAT)
1187*3d8817e4Smiod       || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_FLOAT))
1188*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_FLOAT_INST;
1189*3d8817e4Smiod 
1190*3d8817e4Smiod   /* Set these so m32r_fill_insn can use them.  */
1191*3d8817e4Smiod   prev_seg    = now_seg;
1192*3d8817e4Smiod   prev_subseg = now_subseg;
1193*3d8817e4Smiod }
1194*3d8817e4Smiod 
1195*3d8817e4Smiod void
md_assemble(char * str)1196*3d8817e4Smiod md_assemble (char *str)
1197*3d8817e4Smiod {
1198*3d8817e4Smiod   m32r_insn insn;
1199*3d8817e4Smiod   char *errmsg;
1200*3d8817e4Smiod   char *str2 = NULL;
1201*3d8817e4Smiod 
1202*3d8817e4Smiod   /* Initialize GAS's cgen interface for a new instruction.  */
1203*3d8817e4Smiod   gas_cgen_init_parse ();
1204*3d8817e4Smiod 
1205*3d8817e4Smiod   /* Look for a parallel instruction separator.  */
1206*3d8817e4Smiod   if ((str2 = strstr (str, "||")) != NULL)
1207*3d8817e4Smiod     {
1208*3d8817e4Smiod       assemble_two_insns (str, str2, 1);
1209*3d8817e4Smiod       m32r_flags |= E_M32R_HAS_PARALLEL;
1210*3d8817e4Smiod       return;
1211*3d8817e4Smiod     }
1212*3d8817e4Smiod 
1213*3d8817e4Smiod   /* Also look for a sequential instruction separator.  */
1214*3d8817e4Smiod   if ((str2 = strstr (str, "->")) != NULL)
1215*3d8817e4Smiod     {
1216*3d8817e4Smiod       assemble_two_insns (str, str2, 0);
1217*3d8817e4Smiod       return;
1218*3d8817e4Smiod     }
1219*3d8817e4Smiod 
1220*3d8817e4Smiod   insn.debug_sym_link = debug_sym_link;
1221*3d8817e4Smiod   debug_sym_link = (sym_linkS *) 0;
1222*3d8817e4Smiod 
1223*3d8817e4Smiod   insn.insn = m32r_cgen_assemble_insn
1224*3d8817e4Smiod     (gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, & errmsg);
1225*3d8817e4Smiod 
1226*3d8817e4Smiod   if (!insn.insn)
1227*3d8817e4Smiod     {
1228*3d8817e4Smiod       as_bad (errmsg);
1229*3d8817e4Smiod       return;
1230*3d8817e4Smiod     }
1231*3d8817e4Smiod 
1232*3d8817e4Smiod #ifdef E_M32R2_ARCH
1233*3d8817e4Smiod   if ((enable_m32rx == 1)
1234*3d8817e4Smiod        /* FIXME: Need standard macro to perform this test.  */
1235*3d8817e4Smiod       && ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH)
1236*3d8817e4Smiod            & (1 << MACH_M32R2))
1237*3d8817e4Smiod           && !((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH)
1238*3d8817e4Smiod                & (1 << MACH_M32RX)))))
1239*3d8817e4Smiod     {
1240*3d8817e4Smiod       /* xgettext:c-format  */
1241*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32R2 only"), str);
1242*3d8817e4Smiod       return;
1243*3d8817e4Smiod     }
1244*3d8817e4Smiod   else if ((! enable_special
1245*3d8817e4Smiod        && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
1246*3d8817e4Smiod       || (! enable_special_m32r
1247*3d8817e4Smiod           && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R)))
1248*3d8817e4Smiod #else
1249*3d8817e4Smiod   if (! enable_special
1250*3d8817e4Smiod       && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
1251*3d8817e4Smiod #endif
1252*3d8817e4Smiod     {
1253*3d8817e4Smiod       /* xgettext:c-format  */
1254*3d8817e4Smiod       as_bad (_("unknown instruction '%s'"), str);
1255*3d8817e4Smiod       return;
1256*3d8817e4Smiod     }
1257*3d8817e4Smiod   else if (! enable_m32rx
1258*3d8817e4Smiod 	   && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
1259*3d8817e4Smiod     {
1260*3d8817e4Smiod       /* xgettext:c-format  */
1261*3d8817e4Smiod       as_bad (_("instruction '%s' is for the M32RX only"), str);
1262*3d8817e4Smiod       return;
1263*3d8817e4Smiod     }
1264*3d8817e4Smiod 
1265*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL))
1266*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_HIDDEN_INST;
1267*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R))
1268*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_BIT_INST;
1269*3d8817e4Smiod   if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_FLOAT))
1270*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_FLOAT_INST;
1271*3d8817e4Smiod 
1272*3d8817e4Smiod   if (CGEN_INSN_BITSIZE (insn.insn) == 32)
1273*3d8817e4Smiod     {
1274*3d8817e4Smiod       /* 32 bit insns must live on 32 bit boundaries.  */
1275*3d8817e4Smiod       if (prev_insn.insn || seen_relaxable_p)
1276*3d8817e4Smiod 	{
1277*3d8817e4Smiod 	  /* ??? If calling fill_insn too many times turns us into a memory
1278*3d8817e4Smiod 	     pig, can we call a fn to assemble a nop instead of
1279*3d8817e4Smiod 	     !seen_relaxable_p?  */
1280*3d8817e4Smiod 	  fill_insn (0);
1281*3d8817e4Smiod 	}
1282*3d8817e4Smiod 
1283*3d8817e4Smiod       expand_debug_syms (insn.debug_sym_link, 2);
1284*3d8817e4Smiod 
1285*3d8817e4Smiod       /* Doesn't really matter what we pass for RELAX_P here.  */
1286*3d8817e4Smiod       gas_cgen_finish_insn (insn.insn, insn.buffer,
1287*3d8817e4Smiod 			    CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
1288*3d8817e4Smiod     }
1289*3d8817e4Smiod   else
1290*3d8817e4Smiod     {
1291*3d8817e4Smiod       int on_32bit_boundary_p;
1292*3d8817e4Smiod       int swap = FALSE;
1293*3d8817e4Smiod 
1294*3d8817e4Smiod       if (CGEN_INSN_BITSIZE (insn.insn) != 16)
1295*3d8817e4Smiod 	abort ();
1296*3d8817e4Smiod 
1297*3d8817e4Smiod       insn.orig_insn = insn.insn;
1298*3d8817e4Smiod 
1299*3d8817e4Smiod       /* If the previous insn was relaxable, then it may be expanded
1300*3d8817e4Smiod 	 to fill the current 16 bit slot.  Emit a NOP here to occupy
1301*3d8817e4Smiod 	 this slot, so that we can start at optimizing at a 32 bit
1302*3d8817e4Smiod 	 boundary.  */
1303*3d8817e4Smiod       if (prev_insn.insn && seen_relaxable_p && optimize)
1304*3d8817e4Smiod 	fill_insn (0);
1305*3d8817e4Smiod 
1306*3d8817e4Smiod       if (enable_m32rx)
1307*3d8817e4Smiod 	{
1308*3d8817e4Smiod 	  /* Get the indices of the operands of the instruction.
1309*3d8817e4Smiod 	     FIXME: See assemble_parallel for notes on orig_insn.  */
1310*3d8817e4Smiod 	  {
1311*3d8817e4Smiod 	    CGEN_FIELDS tmp_fields;
1312*3d8817e4Smiod 	    insn.insn = cgen_lookup_get_insn_operands
1313*3d8817e4Smiod 	      (gas_cgen_cpu_desc, NULL, INSN_VALUE (insn.buffer), NULL,
1314*3d8817e4Smiod 	       16, insn.indices, &tmp_fields);
1315*3d8817e4Smiod 	  }
1316*3d8817e4Smiod 
1317*3d8817e4Smiod 	  if (insn.insn == NULL)
1318*3d8817e4Smiod 	    as_fatal (_("internal error: lookup/get operands failed"));
1319*3d8817e4Smiod 	}
1320*3d8817e4Smiod 
1321*3d8817e4Smiod       /* Compute whether we're on a 32 bit boundary or not.
1322*3d8817e4Smiod 	 prev_insn.insn is NULL when we're on a 32 bit boundary.  */
1323*3d8817e4Smiod       on_32bit_boundary_p = prev_insn.insn == NULL;
1324*3d8817e4Smiod 
1325*3d8817e4Smiod       /* Change a frag to, if each insn to swap is in a different frag.
1326*3d8817e4Smiod          It must keep only one instruction in a frag.  */
1327*3d8817e4Smiod       if (parallel() && on_32bit_boundary_p)
1328*3d8817e4Smiod         {
1329*3d8817e4Smiod           frag_wane (frag_now);
1330*3d8817e4Smiod           frag_new (0);
1331*3d8817e4Smiod         }
1332*3d8817e4Smiod 
1333*3d8817e4Smiod       /* Look to see if this instruction can be combined with the
1334*3d8817e4Smiod 	 previous instruction to make one, parallel, 32 bit instruction.
1335*3d8817e4Smiod 	 If the previous instruction (potentially) changed the flow of
1336*3d8817e4Smiod 	 program control, then it cannot be combined with the current
1337*3d8817e4Smiod 	 instruction.  If the current instruction is relaxable, then it
1338*3d8817e4Smiod 	 might be replaced with a longer version, so we cannot combine it.
1339*3d8817e4Smiod 	 Also if the output of the previous instruction is used as an
1340*3d8817e4Smiod 	 input to the current instruction then it cannot be combined.
1341*3d8817e4Smiod 	 Otherwise call can_make_parallel() with both orderings of the
1342*3d8817e4Smiod 	 instructions to see if they can be combined.  */
1343*3d8817e4Smiod       if (! on_32bit_boundary_p
1344*3d8817e4Smiod 	  && parallel ()
1345*3d8817e4Smiod 	  && CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_RELAXABLE) == 0
1346*3d8817e4Smiod 	  && ! writes_to_pc (&prev_insn)
1347*3d8817e4Smiod 	  && ! first_writes_to_seconds_operands (&prev_insn, &insn, FALSE))
1348*3d8817e4Smiod 	{
1349*3d8817e4Smiod 	  if (can_make_parallel (&prev_insn, &insn) == NULL)
1350*3d8817e4Smiod 	    make_parallel (insn.buffer);
1351*3d8817e4Smiod 	  else if (can_make_parallel (&insn, &prev_insn) == NULL)
1352*3d8817e4Smiod 	    swap = TRUE;
1353*3d8817e4Smiod 	}
1354*3d8817e4Smiod 
1355*3d8817e4Smiod       expand_debug_syms (insn.debug_sym_link, 1);
1356*3d8817e4Smiod 
1357*3d8817e4Smiod       {
1358*3d8817e4Smiod 	int i;
1359*3d8817e4Smiod 	finished_insnS fi;
1360*3d8817e4Smiod 
1361*3d8817e4Smiod 	/* Ensure each pair of 16 bit insns is in the same frag.  */
1362*3d8817e4Smiod 	frag_grow (4);
1363*3d8817e4Smiod 
1364*3d8817e4Smiod 	gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
1365*3d8817e4Smiod 			      CGEN_FIELDS_BITSIZE (&insn.fields),
1366*3d8817e4Smiod 			      1 /* relax_p  */, &fi);
1367*3d8817e4Smiod 	insn.addr = fi.addr;
1368*3d8817e4Smiod 	insn.frag = fi.frag;
1369*3d8817e4Smiod 	insn.num_fixups = fi.num_fixups;
1370*3d8817e4Smiod 	for (i = 0; i < fi.num_fixups; ++i)
1371*3d8817e4Smiod 	  insn.fixups[i] = fi.fixups[i];
1372*3d8817e4Smiod       }
1373*3d8817e4Smiod 
1374*3d8817e4Smiod       if (swap)
1375*3d8817e4Smiod 	{
1376*3d8817e4Smiod 	  int i, tmp;
1377*3d8817e4Smiod 
1378*3d8817e4Smiod #define SWAP_BYTES(a,b) tmp = a; a = b; b = tmp
1379*3d8817e4Smiod 
1380*3d8817e4Smiod 	  /* Swap the two insns */
1381*3d8817e4Smiod 	  SWAP_BYTES (prev_insn.addr[0], insn.addr[0]);
1382*3d8817e4Smiod 	  SWAP_BYTES (prev_insn.addr[1], insn.addr[1]);
1383*3d8817e4Smiod 
1384*3d8817e4Smiod 	  target_make_parallel (insn.addr);
1385*3d8817e4Smiod 
1386*3d8817e4Smiod 	  /* Swap any relaxable frags recorded for the two insns.  */
1387*3d8817e4Smiod 	  /* FIXME: Clarify.  relaxation precludes parallel insns */
1388*3d8817e4Smiod 	  if (prev_insn.frag->fr_opcode == prev_insn.addr)
1389*3d8817e4Smiod 	    prev_insn.frag->fr_opcode = insn.addr;
1390*3d8817e4Smiod 	  else if (insn.frag->fr_opcode == insn.addr)
1391*3d8817e4Smiod 	    insn.frag->fr_opcode = prev_insn.addr;
1392*3d8817e4Smiod 
1393*3d8817e4Smiod           /* Change a frag to, if each insn is in a different frag.
1394*3d8817e4Smiod 	     It must keep only one instruction in a frag.  */
1395*3d8817e4Smiod           if (prev_insn.frag != insn.frag)
1396*3d8817e4Smiod             {
1397*3d8817e4Smiod               for (i = 0; i < prev_insn.num_fixups; ++i)
1398*3d8817e4Smiod                 prev_insn.fixups[i]->fx_frag = insn.frag;
1399*3d8817e4Smiod               for (i = 0; i < insn.num_fixups; ++i)
1400*3d8817e4Smiod                 insn.fixups[i]->fx_frag = prev_insn.frag;
1401*3d8817e4Smiod             }
1402*3d8817e4Smiod           else
1403*3d8817e4Smiod 	    {
1404*3d8817e4Smiod 	      /* Update the addresses in any fixups.
1405*3d8817e4Smiod 		 Note that we don't have to handle the case where each insn is in
1406*3d8817e4Smiod 		 a different frag as we ensure they're in the same frag above.  */
1407*3d8817e4Smiod 	      for (i = 0; i < prev_insn.num_fixups; ++i)
1408*3d8817e4Smiod 		prev_insn.fixups[i]->fx_where += 2;
1409*3d8817e4Smiod 	      for (i = 0; i < insn.num_fixups; ++i)
1410*3d8817e4Smiod 		insn.fixups[i]->fx_where -= 2;
1411*3d8817e4Smiod 	    }
1412*3d8817e4Smiod 	}
1413*3d8817e4Smiod 
1414*3d8817e4Smiod       /* Keep track of whether we've seen a pair of 16 bit insns.
1415*3d8817e4Smiod 	 prev_insn.insn is NULL when we're on a 32 bit boundary.  */
1416*3d8817e4Smiod       if (on_32bit_boundary_p)
1417*3d8817e4Smiod 	prev_insn = insn;
1418*3d8817e4Smiod       else
1419*3d8817e4Smiod 	prev_insn.insn = NULL;
1420*3d8817e4Smiod 
1421*3d8817e4Smiod       /* If the insn needs the following one to be on a 32 bit boundary
1422*3d8817e4Smiod 	 (e.g. subroutine calls), fill this insn's slot.  */
1423*3d8817e4Smiod       if (on_32bit_boundary_p
1424*3d8817e4Smiod 	  && CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0)
1425*3d8817e4Smiod 	fill_insn (0);
1426*3d8817e4Smiod 
1427*3d8817e4Smiod       /* If this is a relaxable insn (can be replaced with a larger version)
1428*3d8817e4Smiod 	 mark the fact so that we can emit an alignment directive for a
1429*3d8817e4Smiod 	 following 32 bit insn if we see one.   */
1430*3d8817e4Smiod       if (CGEN_INSN_ATTR_VALUE (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0)
1431*3d8817e4Smiod 	seen_relaxable_p = 1;
1432*3d8817e4Smiod     }
1433*3d8817e4Smiod 
1434*3d8817e4Smiod   /* Set these so m32r_fill_insn can use them.  */
1435*3d8817e4Smiod   prev_seg    = now_seg;
1436*3d8817e4Smiod   prev_subseg = now_subseg;
1437*3d8817e4Smiod }
1438*3d8817e4Smiod 
1439*3d8817e4Smiod /* The syntax in the manual says constants begin with '#'.
1440*3d8817e4Smiod    We just ignore it.  */
1441*3d8817e4Smiod 
1442*3d8817e4Smiod void
md_operand(expressionS * expressionP)1443*3d8817e4Smiod md_operand (expressionS *expressionP)
1444*3d8817e4Smiod {
1445*3d8817e4Smiod   if (*input_line_pointer == '#')
1446*3d8817e4Smiod     {
1447*3d8817e4Smiod       input_line_pointer++;
1448*3d8817e4Smiod       expression (expressionP);
1449*3d8817e4Smiod     }
1450*3d8817e4Smiod }
1451*3d8817e4Smiod 
1452*3d8817e4Smiod valueT
md_section_align(segT segment,valueT size)1453*3d8817e4Smiod md_section_align (segT segment, valueT size)
1454*3d8817e4Smiod {
1455*3d8817e4Smiod   int align = bfd_get_section_alignment (stdoutput, segment);
1456*3d8817e4Smiod 
1457*3d8817e4Smiod   return ((size + (1 << align) - 1) & (-1 << align));
1458*3d8817e4Smiod }
1459*3d8817e4Smiod 
1460*3d8817e4Smiod symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1461*3d8817e4Smiod md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1462*3d8817e4Smiod {
1463*3d8817e4Smiod   return 0;
1464*3d8817e4Smiod }
1465*3d8817e4Smiod 
1466*3d8817e4Smiod /* .scomm pseudo-op handler.
1467*3d8817e4Smiod 
1468*3d8817e4Smiod    This is a new pseudo-op to handle putting objects in .scommon.
1469*3d8817e4Smiod    By doing this the linker won't need to do any work,
1470*3d8817e4Smiod    and more importantly it removes the implicit -G arg necessary to
1471*3d8817e4Smiod    correctly link the object file.  */
1472*3d8817e4Smiod 
1473*3d8817e4Smiod static void
m32r_scomm(int ignore ATTRIBUTE_UNUSED)1474*3d8817e4Smiod m32r_scomm (int ignore ATTRIBUTE_UNUSED)
1475*3d8817e4Smiod {
1476*3d8817e4Smiod   char *name;
1477*3d8817e4Smiod   char c;
1478*3d8817e4Smiod   char *p;
1479*3d8817e4Smiod   offsetT size;
1480*3d8817e4Smiod   symbolS *symbolP;
1481*3d8817e4Smiod   offsetT align;
1482*3d8817e4Smiod   int align2;
1483*3d8817e4Smiod 
1484*3d8817e4Smiod   name = input_line_pointer;
1485*3d8817e4Smiod   c = get_symbol_end ();
1486*3d8817e4Smiod 
1487*3d8817e4Smiod   /* Just after name is now '\0'.  */
1488*3d8817e4Smiod   p = input_line_pointer;
1489*3d8817e4Smiod   *p = c;
1490*3d8817e4Smiod   SKIP_WHITESPACE ();
1491*3d8817e4Smiod   if (*input_line_pointer != ',')
1492*3d8817e4Smiod     {
1493*3d8817e4Smiod       as_bad (_("Expected comma after symbol-name: rest of line ignored."));
1494*3d8817e4Smiod       ignore_rest_of_line ();
1495*3d8817e4Smiod       return;
1496*3d8817e4Smiod     }
1497*3d8817e4Smiod 
1498*3d8817e4Smiod   /* Skip ','.  */
1499*3d8817e4Smiod   input_line_pointer++;
1500*3d8817e4Smiod   if ((size = get_absolute_expression ()) < 0)
1501*3d8817e4Smiod     {
1502*3d8817e4Smiod       /* xgettext:c-format  */
1503*3d8817e4Smiod       as_warn (_(".SCOMMon length (%ld.) <0! Ignored."), (long) size);
1504*3d8817e4Smiod       ignore_rest_of_line ();
1505*3d8817e4Smiod       return;
1506*3d8817e4Smiod     }
1507*3d8817e4Smiod 
1508*3d8817e4Smiod   /* The third argument to .scomm is the alignment.  */
1509*3d8817e4Smiod   if (*input_line_pointer != ',')
1510*3d8817e4Smiod     align = 8;
1511*3d8817e4Smiod   else
1512*3d8817e4Smiod     {
1513*3d8817e4Smiod       ++input_line_pointer;
1514*3d8817e4Smiod       align = get_absolute_expression ();
1515*3d8817e4Smiod       if (align <= 0)
1516*3d8817e4Smiod 	{
1517*3d8817e4Smiod 	  as_warn (_("ignoring bad alignment"));
1518*3d8817e4Smiod 	  align = 8;
1519*3d8817e4Smiod 	}
1520*3d8817e4Smiod     }
1521*3d8817e4Smiod 
1522*3d8817e4Smiod   /* Convert to a power of 2 alignment.  */
1523*3d8817e4Smiod   if (align)
1524*3d8817e4Smiod     {
1525*3d8817e4Smiod       for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2)
1526*3d8817e4Smiod 	continue;
1527*3d8817e4Smiod       if (align != 1)
1528*3d8817e4Smiod 	{
1529*3d8817e4Smiod 	  as_bad (_("Common alignment not a power of 2"));
1530*3d8817e4Smiod 	  ignore_rest_of_line ();
1531*3d8817e4Smiod 	  return;
1532*3d8817e4Smiod 	}
1533*3d8817e4Smiod     }
1534*3d8817e4Smiod   else
1535*3d8817e4Smiod     align2 = 0;
1536*3d8817e4Smiod 
1537*3d8817e4Smiod   *p = 0;
1538*3d8817e4Smiod   symbolP = symbol_find_or_make (name);
1539*3d8817e4Smiod   *p = c;
1540*3d8817e4Smiod 
1541*3d8817e4Smiod   if (S_IS_DEFINED (symbolP))
1542*3d8817e4Smiod     {
1543*3d8817e4Smiod       /* xgettext:c-format  */
1544*3d8817e4Smiod       as_bad (_("Ignoring attempt to re-define symbol `%s'."),
1545*3d8817e4Smiod 	      S_GET_NAME (symbolP));
1546*3d8817e4Smiod       ignore_rest_of_line ();
1547*3d8817e4Smiod       return;
1548*3d8817e4Smiod     }
1549*3d8817e4Smiod 
1550*3d8817e4Smiod   if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
1551*3d8817e4Smiod     {
1552*3d8817e4Smiod       /* xgettext:c-format  */
1553*3d8817e4Smiod       as_bad (_("Length of .scomm \"%s\" is already %ld. Not changed to %ld."),
1554*3d8817e4Smiod 	      S_GET_NAME (symbolP),
1555*3d8817e4Smiod 	      (long) S_GET_VALUE (symbolP),
1556*3d8817e4Smiod 	      (long) size);
1557*3d8817e4Smiod 
1558*3d8817e4Smiod       ignore_rest_of_line ();
1559*3d8817e4Smiod       return;
1560*3d8817e4Smiod     }
1561*3d8817e4Smiod 
1562*3d8817e4Smiod   if (symbol_get_obj (symbolP)->local)
1563*3d8817e4Smiod     {
1564*3d8817e4Smiod       segT old_sec = now_seg;
1565*3d8817e4Smiod       int old_subsec = now_subseg;
1566*3d8817e4Smiod       char *pfrag;
1567*3d8817e4Smiod 
1568*3d8817e4Smiod       record_alignment (sbss_section, align2);
1569*3d8817e4Smiod       subseg_set (sbss_section, 0);
1570*3d8817e4Smiod 
1571*3d8817e4Smiod       if (align2)
1572*3d8817e4Smiod 	frag_align (align2, 0, 0);
1573*3d8817e4Smiod 
1574*3d8817e4Smiod       if (S_GET_SEGMENT (symbolP) == sbss_section)
1575*3d8817e4Smiod 	symbol_get_frag (symbolP)->fr_symbol = 0;
1576*3d8817e4Smiod 
1577*3d8817e4Smiod       symbol_set_frag (symbolP, frag_now);
1578*3d8817e4Smiod 
1579*3d8817e4Smiod       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
1580*3d8817e4Smiod 			(char *) 0);
1581*3d8817e4Smiod       *pfrag = 0;
1582*3d8817e4Smiod       S_SET_SIZE (symbolP, size);
1583*3d8817e4Smiod       S_SET_SEGMENT (symbolP, sbss_section);
1584*3d8817e4Smiod       S_CLEAR_EXTERNAL (symbolP);
1585*3d8817e4Smiod       subseg_set (old_sec, old_subsec);
1586*3d8817e4Smiod     }
1587*3d8817e4Smiod   else
1588*3d8817e4Smiod     {
1589*3d8817e4Smiod       S_SET_VALUE (symbolP, (valueT) size);
1590*3d8817e4Smiod       S_SET_ALIGN (symbolP, align2);
1591*3d8817e4Smiod       S_SET_EXTERNAL (symbolP);
1592*3d8817e4Smiod       S_SET_SEGMENT (symbolP, &scom_section);
1593*3d8817e4Smiod     }
1594*3d8817e4Smiod 
1595*3d8817e4Smiod   demand_empty_rest_of_line ();
1596*3d8817e4Smiod }
1597*3d8817e4Smiod 
1598*3d8817e4Smiod /* The target specific pseudo-ops which we support.  */
1599*3d8817e4Smiod const pseudo_typeS md_pseudo_table[] =
1600*3d8817e4Smiod {
1601*3d8817e4Smiod   { "word",	cons,		4 },
1602*3d8817e4Smiod   { "fillinsn", fill_insn,	0 },
1603*3d8817e4Smiod   { "scomm",	m32r_scomm,	0 },
1604*3d8817e4Smiod   { "debugsym",	debug_sym,	0 },
1605*3d8817e4Smiod   { "m32r",	allow_m32rx,	0 },
1606*3d8817e4Smiod   { "m32rx",	allow_m32rx,	1 },
1607*3d8817e4Smiod   { "m32r2",	allow_m32rx,	2 },
1608*3d8817e4Smiod   { "little",   little,         1 },
1609*3d8817e4Smiod   { "big",      little,         0 },
1610*3d8817e4Smiod   { NULL, NULL, 0 }
1611*3d8817e4Smiod };
1612*3d8817e4Smiod 
1613*3d8817e4Smiod /* Interface to relax_segment.  */
1614*3d8817e4Smiod 
1615*3d8817e4Smiod /* FIXME: Build table by hand, get it working, then machine generate.  */
1616*3d8817e4Smiod 
1617*3d8817e4Smiod const relax_typeS md_relax_table[] =
1618*3d8817e4Smiod {
1619*3d8817e4Smiod /* The fields are:
1620*3d8817e4Smiod    1) most positive reach of this state,
1621*3d8817e4Smiod    2) most negative reach of this state,
1622*3d8817e4Smiod    3) how many bytes this mode will add to the size of the current frag
1623*3d8817e4Smiod    4) which index into the table to try if we can't fit into this one.  */
1624*3d8817e4Smiod 
1625*3d8817e4Smiod   /* The first entry must be unused because an `rlx_more' value of zero ends
1626*3d8817e4Smiod      each list.  */
1627*3d8817e4Smiod   {1, 1, 0, 0},
1628*3d8817e4Smiod 
1629*3d8817e4Smiod   /* The displacement used by GAS is from the end of the 2 byte insn,
1630*3d8817e4Smiod      so we subtract 2 from the following.  */
1631*3d8817e4Smiod   /* 16 bit insn, 8 bit disp -> 10 bit range.
1632*3d8817e4Smiod      This doesn't handle a branch in the right slot at the border:
1633*3d8817e4Smiod      the "& -4" isn't taken into account.  It's not important enough to
1634*3d8817e4Smiod      complicate things over it, so we subtract an extra 2 (or + 2 in -ve
1635*3d8817e4Smiod      case).  */
1636*3d8817e4Smiod   {511 - 2 - 2, -512 - 2 + 2, 0, 2 },
1637*3d8817e4Smiod   /* 32 bit insn, 24 bit disp -> 26 bit range.  */
1638*3d8817e4Smiod   {0x2000000 - 1 - 2, -0x2000000 - 2, 2, 0 },
1639*3d8817e4Smiod   /* Same thing, but with leading nop for alignment.  */
1640*3d8817e4Smiod   {0x2000000 - 1 - 2, -0x2000000 - 2, 4, 0 }
1641*3d8817e4Smiod };
1642*3d8817e4Smiod 
1643*3d8817e4Smiod long
m32r_relax_frag(segT segment,fragS * fragP,long stretch)1644*3d8817e4Smiod m32r_relax_frag (segT segment, fragS *fragP, long stretch)
1645*3d8817e4Smiod {
1646*3d8817e4Smiod   /* Address of branch insn.  */
1647*3d8817e4Smiod   long address = fragP->fr_address + fragP->fr_fix - 2;
1648*3d8817e4Smiod   long growth = 0;
1649*3d8817e4Smiod 
1650*3d8817e4Smiod   /* Keep 32 bit insns aligned on 32 bit boundaries.  */
1651*3d8817e4Smiod   if (fragP->fr_subtype == 2)
1652*3d8817e4Smiod     {
1653*3d8817e4Smiod       if ((address & 3) != 0)
1654*3d8817e4Smiod 	{
1655*3d8817e4Smiod 	  fragP->fr_subtype = 3;
1656*3d8817e4Smiod 	  growth = 2;
1657*3d8817e4Smiod 	}
1658*3d8817e4Smiod     }
1659*3d8817e4Smiod   else if (fragP->fr_subtype == 3)
1660*3d8817e4Smiod     {
1661*3d8817e4Smiod       if ((address & 3) == 0)
1662*3d8817e4Smiod 	{
1663*3d8817e4Smiod 	  fragP->fr_subtype = 2;
1664*3d8817e4Smiod 	  growth = -2;
1665*3d8817e4Smiod 	}
1666*3d8817e4Smiod     }
1667*3d8817e4Smiod   else
1668*3d8817e4Smiod     {
1669*3d8817e4Smiod       growth = relax_frag (segment, fragP, stretch);
1670*3d8817e4Smiod 
1671*3d8817e4Smiod       /* Long jump on odd halfword boundary?  */
1672*3d8817e4Smiod       if (fragP->fr_subtype == 2 && (address & 3) != 0)
1673*3d8817e4Smiod 	{
1674*3d8817e4Smiod 	  fragP->fr_subtype = 3;
1675*3d8817e4Smiod 	  growth += 2;
1676*3d8817e4Smiod 	}
1677*3d8817e4Smiod     }
1678*3d8817e4Smiod 
1679*3d8817e4Smiod   return growth;
1680*3d8817e4Smiod }
1681*3d8817e4Smiod 
1682*3d8817e4Smiod /* Return an initial guess of the length by which a fragment must grow to
1683*3d8817e4Smiod    hold a branch to reach its destination.
1684*3d8817e4Smiod    Also updates fr_type/fr_subtype as necessary.
1685*3d8817e4Smiod 
1686*3d8817e4Smiod    Called just before doing relaxation.
1687*3d8817e4Smiod    Any symbol that is now undefined will not become defined.
1688*3d8817e4Smiod    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
1689*3d8817e4Smiod    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
1690*3d8817e4Smiod    Although it may not be explicit in the frag, pretend fr_var starts
1691*3d8817e4Smiod    with a 0 value.  */
1692*3d8817e4Smiod 
1693*3d8817e4Smiod int
md_estimate_size_before_relax(fragS * fragP,segT segment)1694*3d8817e4Smiod md_estimate_size_before_relax (fragS *fragP, segT segment)
1695*3d8817e4Smiod {
1696*3d8817e4Smiod   /* The only thing we have to handle here are symbols outside of the
1697*3d8817e4Smiod      current segment.  They may be undefined or in a different segment in
1698*3d8817e4Smiod      which case linker scripts may place them anywhere.
1699*3d8817e4Smiod      However, we can't finish the fragment here and emit the reloc as insn
1700*3d8817e4Smiod      alignment requirements may move the insn about.  */
1701*3d8817e4Smiod   if (S_GET_SEGMENT (fragP->fr_symbol) != segment
1702*3d8817e4Smiod       || S_IS_EXTERNAL (fragP->fr_symbol)
1703*3d8817e4Smiod       || S_IS_WEAK (fragP->fr_symbol))
1704*3d8817e4Smiod     {
1705*3d8817e4Smiod       /* The symbol is undefined in this segment.
1706*3d8817e4Smiod 	 Change the relaxation subtype to the max allowable and leave
1707*3d8817e4Smiod 	 all further handling to md_convert_frag.  */
1708*3d8817e4Smiod       fragP->fr_subtype = 2;
1709*3d8817e4Smiod 
1710*3d8817e4Smiod       {
1711*3d8817e4Smiod 	const CGEN_INSN *insn;
1712*3d8817e4Smiod 	int i;
1713*3d8817e4Smiod 
1714*3d8817e4Smiod 	/* Update the recorded insn.
1715*3d8817e4Smiod 	   Fortunately we don't have to look very far.
1716*3d8817e4Smiod 	   FIXME: Change this to record in the instruction the next higher
1717*3d8817e4Smiod 	   relaxable insn to use.  */
1718*3d8817e4Smiod 	for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
1719*3d8817e4Smiod 	  {
1720*3d8817e4Smiod 	    if ((strcmp (CGEN_INSN_MNEMONIC (insn),
1721*3d8817e4Smiod 			 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
1722*3d8817e4Smiod 		 == 0)
1723*3d8817e4Smiod 		&& CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
1724*3d8817e4Smiod 	      break;
1725*3d8817e4Smiod 	  }
1726*3d8817e4Smiod 	if (i == 4)
1727*3d8817e4Smiod 	  abort ();
1728*3d8817e4Smiod 
1729*3d8817e4Smiod 	fragP->fr_cgen.insn = insn;
1730*3d8817e4Smiod 	return 2;
1731*3d8817e4Smiod       }
1732*3d8817e4Smiod     }
1733*3d8817e4Smiod 
1734*3d8817e4Smiod   return md_relax_table[fragP->fr_subtype].rlx_length;
1735*3d8817e4Smiod }
1736*3d8817e4Smiod 
1737*3d8817e4Smiod /* *FRAGP has been relaxed to its final size, and now needs to have
1738*3d8817e4Smiod    the bytes inside it modified to conform to the new size.
1739*3d8817e4Smiod 
1740*3d8817e4Smiod    Called after relaxation is finished.
1741*3d8817e4Smiod    fragP->fr_type == rs_machine_dependent.
1742*3d8817e4Smiod    fragP->fr_subtype is the subtype of what the address relaxed to.  */
1743*3d8817e4Smiod 
1744*3d8817e4Smiod void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec,fragS * fragP)1745*3d8817e4Smiod md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1746*3d8817e4Smiod 		 segT sec,
1747*3d8817e4Smiod 		 fragS *fragP)
1748*3d8817e4Smiod {
1749*3d8817e4Smiod   char *opcode;
1750*3d8817e4Smiod   char *displacement;
1751*3d8817e4Smiod   int target_address;
1752*3d8817e4Smiod   int opcode_address;
1753*3d8817e4Smiod   int extension;
1754*3d8817e4Smiod   int addend;
1755*3d8817e4Smiod 
1756*3d8817e4Smiod   opcode = fragP->fr_opcode;
1757*3d8817e4Smiod 
1758*3d8817e4Smiod   /* Address opcode resides at in file space.  */
1759*3d8817e4Smiod   opcode_address = fragP->fr_address + fragP->fr_fix - 2;
1760*3d8817e4Smiod 
1761*3d8817e4Smiod   switch (fragP->fr_subtype)
1762*3d8817e4Smiod     {
1763*3d8817e4Smiod     case 1:
1764*3d8817e4Smiod       extension = 0;
1765*3d8817e4Smiod       displacement = &opcode[1];
1766*3d8817e4Smiod       break;
1767*3d8817e4Smiod     case 2:
1768*3d8817e4Smiod       opcode[0] |= 0x80;
1769*3d8817e4Smiod       extension = 2;
1770*3d8817e4Smiod       displacement = &opcode[1];
1771*3d8817e4Smiod       break;
1772*3d8817e4Smiod     case 3:
1773*3d8817e4Smiod       opcode[2] = opcode[0] | 0x80;
1774*3d8817e4Smiod       md_number_to_chars (opcode, PAR_NOP_INSN, 2);
1775*3d8817e4Smiod       opcode_address += 2;
1776*3d8817e4Smiod       extension = 4;
1777*3d8817e4Smiod       displacement = &opcode[3];
1778*3d8817e4Smiod       break;
1779*3d8817e4Smiod     default:
1780*3d8817e4Smiod       abort ();
1781*3d8817e4Smiod     }
1782*3d8817e4Smiod 
1783*3d8817e4Smiod   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
1784*3d8817e4Smiod       || S_IS_EXTERNAL (fragP->fr_symbol)
1785*3d8817e4Smiod       || S_IS_WEAK (fragP->fr_symbol))
1786*3d8817e4Smiod     {
1787*3d8817e4Smiod       /* Symbol must be resolved by linker.  */
1788*3d8817e4Smiod       if (fragP->fr_offset & 3)
1789*3d8817e4Smiod 	as_warn (_("Addend to unresolved symbol not on word boundary."));
1790*3d8817e4Smiod #ifdef USE_M32R_OLD_RELOC
1791*3d8817e4Smiod       addend = fragP->fr_offset >> 2; /* Old M32R used USE_REL. */
1792*3d8817e4Smiod #else
1793*3d8817e4Smiod       addend = 0;
1794*3d8817e4Smiod #endif
1795*3d8817e4Smiod     }
1796*3d8817e4Smiod   else
1797*3d8817e4Smiod     {
1798*3d8817e4Smiod       /* Address we want to reach in file space.  */
1799*3d8817e4Smiod       target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
1800*3d8817e4Smiod       addend = (target_address - (opcode_address & -4)) >> 2;
1801*3d8817e4Smiod     }
1802*3d8817e4Smiod 
1803*3d8817e4Smiod   /* Create a relocation for symbols that must be resolved by the linker.
1804*3d8817e4Smiod      Otherwise output the completed insn.  */
1805*3d8817e4Smiod 
1806*3d8817e4Smiod   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
1807*3d8817e4Smiod       || S_IS_EXTERNAL (fragP->fr_symbol)
1808*3d8817e4Smiod       || S_IS_WEAK (fragP->fr_symbol))
1809*3d8817e4Smiod     {
1810*3d8817e4Smiod       fixS *fixP;
1811*3d8817e4Smiod 
1812*3d8817e4Smiod       assert (fragP->fr_subtype != 1);
1813*3d8817e4Smiod       assert (fragP->fr_cgen.insn != 0);
1814*3d8817e4Smiod 
1815*3d8817e4Smiod       fixP = gas_cgen_record_fixup (fragP,
1816*3d8817e4Smiod 				    /* Offset of branch insn in frag.  */
1817*3d8817e4Smiod 				    fragP->fr_fix + extension - 4,
1818*3d8817e4Smiod 				    fragP->fr_cgen.insn,
1819*3d8817e4Smiod 				    4 /* Length.  */,
1820*3d8817e4Smiod 				    /* FIXME: quick hack.  */
1821*3d8817e4Smiod 				    cgen_operand_lookup_by_num (gas_cgen_cpu_desc,
1822*3d8817e4Smiod 								M32R_OPERAND_DISP24),
1823*3d8817e4Smiod 				    fragP->fr_cgen.opinfo,
1824*3d8817e4Smiod 				    fragP->fr_symbol, fragP->fr_offset);
1825*3d8817e4Smiod       if (fragP->fr_cgen.opinfo)
1826*3d8817e4Smiod         fixP->fx_r_type = fragP->fr_cgen.opinfo;
1827*3d8817e4Smiod     }
1828*3d8817e4Smiod 
1829*3d8817e4Smiod #define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3)
1830*3d8817e4Smiod 
1831*3d8817e4Smiod   md_number_to_chars (displacement, (valueT) addend,
1832*3d8817e4Smiod 		      SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
1833*3d8817e4Smiod 
1834*3d8817e4Smiod   fragP->fr_fix += extension;
1835*3d8817e4Smiod }
1836*3d8817e4Smiod 
1837*3d8817e4Smiod /* Functions concerning relocs.  */
1838*3d8817e4Smiod 
1839*3d8817e4Smiod /* The location from which a PC relative jump should be calculated,
1840*3d8817e4Smiod    given a PC relative reloc.  */
1841*3d8817e4Smiod 
1842*3d8817e4Smiod long
md_pcrel_from_section(fixS * fixP,segT sec)1843*3d8817e4Smiod md_pcrel_from_section (fixS *fixP, segT sec)
1844*3d8817e4Smiod {
1845*3d8817e4Smiod   if (fixP->fx_addsy != (symbolS *) NULL
1846*3d8817e4Smiod       && (! S_IS_DEFINED (fixP->fx_addsy)
1847*3d8817e4Smiod 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec
1848*3d8817e4Smiod           || S_IS_EXTERNAL (fixP->fx_addsy)
1849*3d8817e4Smiod           || S_IS_WEAK (fixP->fx_addsy)))
1850*3d8817e4Smiod     {
1851*3d8817e4Smiod       if (S_GET_SEGMENT (fixP->fx_addsy) != sec
1852*3d8817e4Smiod           && S_IS_DEFINED (fixP->fx_addsy)
1853*3d8817e4Smiod           && ! S_IS_EXTERNAL (fixP->fx_addsy)
1854*3d8817e4Smiod           && ! S_IS_WEAK (fixP->fx_addsy))
1855*3d8817e4Smiod         return fixP->fx_offset;
1856*3d8817e4Smiod 
1857*3d8817e4Smiod       /* The symbol is undefined (or is defined but not in this section).
1858*3d8817e4Smiod 	 Let the linker figure it out.  */
1859*3d8817e4Smiod       return 0;
1860*3d8817e4Smiod     }
1861*3d8817e4Smiod 
1862*3d8817e4Smiod   return (fixP->fx_frag->fr_address + fixP->fx_where) & -4L;
1863*3d8817e4Smiod }
1864*3d8817e4Smiod 
1865*3d8817e4Smiod /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
1866*3d8817e4Smiod    Returns BFD_RELOC_NONE if no reloc type can be found.
1867*3d8817e4Smiod    *FIXP may be modified if desired.  */
1868*3d8817e4Smiod 
1869*3d8817e4Smiod bfd_reloc_code_real_type
md_cgen_lookup_reloc(const CGEN_INSN * insn ATTRIBUTE_UNUSED,const CGEN_OPERAND * operand,fixS * fixP)1870*3d8817e4Smiod md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
1871*3d8817e4Smiod 		      const CGEN_OPERAND *operand,
1872*3d8817e4Smiod 		      fixS *fixP)
1873*3d8817e4Smiod {
1874*3d8817e4Smiod   switch (operand->type)
1875*3d8817e4Smiod     {
1876*3d8817e4Smiod     case M32R_OPERAND_DISP8:  return BFD_RELOC_M32R_10_PCREL;
1877*3d8817e4Smiod     case M32R_OPERAND_DISP16: return BFD_RELOC_M32R_18_PCREL;
1878*3d8817e4Smiod     case M32R_OPERAND_DISP24: return BFD_RELOC_M32R_26_PCREL;
1879*3d8817e4Smiod     case M32R_OPERAND_UIMM24: return BFD_RELOC_M32R_24;
1880*3d8817e4Smiod     case M32R_OPERAND_HI16:
1881*3d8817e4Smiod     case M32R_OPERAND_SLO16:
1882*3d8817e4Smiod     case M32R_OPERAND_ULO16:
1883*3d8817e4Smiod       /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */
1884*3d8817e4Smiod       if (fixP->fx_cgen.opinfo != 0)
1885*3d8817e4Smiod 	return fixP->fx_cgen.opinfo;
1886*3d8817e4Smiod       break;
1887*3d8817e4Smiod     default:
1888*3d8817e4Smiod       /* Avoid -Wall warning.  */
1889*3d8817e4Smiod       break;
1890*3d8817e4Smiod     }
1891*3d8817e4Smiod   return BFD_RELOC_NONE;
1892*3d8817e4Smiod }
1893*3d8817e4Smiod 
1894*3d8817e4Smiod /* Record a HI16 reloc for later matching with its LO16 cousin.  */
1895*3d8817e4Smiod 
1896*3d8817e4Smiod static void
m32r_record_hi16(int reloc_type,fixS * fixP,segT seg ATTRIBUTE_UNUSED)1897*3d8817e4Smiod m32r_record_hi16 (int reloc_type,
1898*3d8817e4Smiod 		  fixS *fixP,
1899*3d8817e4Smiod 		  segT seg ATTRIBUTE_UNUSED)
1900*3d8817e4Smiod {
1901*3d8817e4Smiod   struct m32r_hi_fixup *hi_fixup;
1902*3d8817e4Smiod 
1903*3d8817e4Smiod   assert (reloc_type == BFD_RELOC_M32R_HI16_SLO
1904*3d8817e4Smiod 	  || reloc_type == BFD_RELOC_M32R_HI16_ULO);
1905*3d8817e4Smiod 
1906*3d8817e4Smiod   hi_fixup = xmalloc (sizeof (* hi_fixup));
1907*3d8817e4Smiod   hi_fixup->fixp = fixP;
1908*3d8817e4Smiod   hi_fixup->seg  = now_seg;
1909*3d8817e4Smiod   hi_fixup->next = m32r_hi_fixup_list;
1910*3d8817e4Smiod 
1911*3d8817e4Smiod   m32r_hi_fixup_list = hi_fixup;
1912*3d8817e4Smiod }
1913*3d8817e4Smiod 
1914*3d8817e4Smiod /* Called while parsing an instruction to create a fixup.
1915*3d8817e4Smiod    We need to check for HI16 relocs and queue them up for later sorting.  */
1916*3d8817e4Smiod 
1917*3d8817e4Smiod fixS *
m32r_cgen_record_fixup_exp(fragS * frag,int where,const CGEN_INSN * insn,int length,const CGEN_OPERAND * operand,int opinfo,expressionS * exp)1918*3d8817e4Smiod m32r_cgen_record_fixup_exp (fragS *frag,
1919*3d8817e4Smiod 			    int where,
1920*3d8817e4Smiod 			    const CGEN_INSN *insn,
1921*3d8817e4Smiod 			    int length,
1922*3d8817e4Smiod 			    const CGEN_OPERAND *operand,
1923*3d8817e4Smiod 			    int opinfo,
1924*3d8817e4Smiod 			    expressionS *exp)
1925*3d8817e4Smiod {
1926*3d8817e4Smiod   fixS *fixP;
1927*3d8817e4Smiod   bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
1928*3d8817e4Smiod 
1929*3d8817e4Smiod   if (m32r_check_fixup (exp, &r_type))
1930*3d8817e4Smiod     as_bad (_("Invalid PIC expression."));
1931*3d8817e4Smiod 
1932*3d8817e4Smiod   fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
1933*3d8817e4Smiod 				    operand, opinfo, exp);
1934*3d8817e4Smiod 
1935*3d8817e4Smiod   switch (operand->type)
1936*3d8817e4Smiod     {
1937*3d8817e4Smiod     case M32R_OPERAND_HI16:
1938*3d8817e4Smiod       /* If low/high/shigh/sda was used, it is recorded in `opinfo'.  */
1939*3d8817e4Smiod       if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO
1940*3d8817e4Smiod 	  || fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
1941*3d8817e4Smiod 	m32r_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
1942*3d8817e4Smiod       break;
1943*3d8817e4Smiod 
1944*3d8817e4Smiod     default:
1945*3d8817e4Smiod       /* Avoid -Wall warning.  */
1946*3d8817e4Smiod       break;
1947*3d8817e4Smiod     }
1948*3d8817e4Smiod 
1949*3d8817e4Smiod   switch (r_type)
1950*3d8817e4Smiod     {
1951*3d8817e4Smiod     case BFD_RELOC_UNUSED:
1952*3d8817e4Smiod     default:
1953*3d8817e4Smiod       return fixP;
1954*3d8817e4Smiod 
1955*3d8817e4Smiod     case BFD_RELOC_M32R_GOTPC24:
1956*3d8817e4Smiod       if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
1957*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTPC_HI_SLO;
1958*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
1959*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTPC_HI_ULO;
1960*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
1961*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTPC_LO;
1962*3d8817e4Smiod       break;
1963*3d8817e4Smiod 
1964*3d8817e4Smiod     case BFD_RELOC_M32R_GOT24:
1965*3d8817e4Smiod       if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
1966*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOT16_HI_SLO;
1967*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
1968*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOT16_HI_ULO;
1969*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
1970*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOT16_LO;
1971*3d8817e4Smiod       break;
1972*3d8817e4Smiod 
1973*3d8817e4Smiod     case BFD_RELOC_M32R_GOTOFF:
1974*3d8817e4Smiod       if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_SLO)
1975*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTOFF_HI_SLO;
1976*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_HI16_ULO)
1977*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTOFF_HI_ULO;
1978*3d8817e4Smiod       else if (fixP->fx_cgen.opinfo == BFD_RELOC_M32R_LO16)
1979*3d8817e4Smiod         r_type = BFD_RELOC_M32R_GOTOFF_LO;
1980*3d8817e4Smiod       break;
1981*3d8817e4Smiod 
1982*3d8817e4Smiod     case BFD_RELOC_M32R_26_PLTREL:
1983*3d8817e4Smiod       as_bad (_("Invalid PIC expression."));
1984*3d8817e4Smiod       break;
1985*3d8817e4Smiod     }
1986*3d8817e4Smiod 
1987*3d8817e4Smiod   fixP->fx_r_type = r_type;
1988*3d8817e4Smiod 
1989*3d8817e4Smiod   return fixP;
1990*3d8817e4Smiod }
1991*3d8817e4Smiod 
1992*3d8817e4Smiod /* Return BFD reloc type from opinfo field in a fixS.
1993*3d8817e4Smiod    It's tricky using fx_r_type in m32r_frob_file because the values
1994*3d8817e4Smiod    are BFD_RELOC_UNUSED + operand number.  */
1995*3d8817e4Smiod #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
1996*3d8817e4Smiod 
1997*3d8817e4Smiod /* Sort any unmatched HI16 relocs so that they immediately precede
1998*3d8817e4Smiod    the corresponding LO16 reloc.  This is called before md_apply_fix and
1999*3d8817e4Smiod    tc_gen_reloc.  */
2000*3d8817e4Smiod 
2001*3d8817e4Smiod void
m32r_frob_file(void)2002*3d8817e4Smiod m32r_frob_file (void)
2003*3d8817e4Smiod {
2004*3d8817e4Smiod   struct m32r_hi_fixup *l;
2005*3d8817e4Smiod 
2006*3d8817e4Smiod   for (l = m32r_hi_fixup_list; l != NULL; l = l->next)
2007*3d8817e4Smiod     {
2008*3d8817e4Smiod       segment_info_type *seginfo;
2009*3d8817e4Smiod       int pass;
2010*3d8817e4Smiod 
2011*3d8817e4Smiod       assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_SLO
2012*3d8817e4Smiod 	      || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_M32R_HI16_ULO);
2013*3d8817e4Smiod 
2014*3d8817e4Smiod       /* Check quickly whether the next fixup happens to be a matching low.  */
2015*3d8817e4Smiod       if (l->fixp->fx_next != NULL
2016*3d8817e4Smiod 	  && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_M32R_LO16
2017*3d8817e4Smiod 	  && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
2018*3d8817e4Smiod 	  && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
2019*3d8817e4Smiod 	continue;
2020*3d8817e4Smiod 
2021*3d8817e4Smiod       /* Look through the fixups for this segment for a matching `low'.
2022*3d8817e4Smiod          When we find one, move the high/shigh just in front of it.  We do
2023*3d8817e4Smiod          this in two passes.  In the first pass, we try to find a
2024*3d8817e4Smiod          unique `low'.  In the second pass, we permit multiple high's
2025*3d8817e4Smiod          relocs for a single `low'.  */
2026*3d8817e4Smiod       seginfo = seg_info (l->seg);
2027*3d8817e4Smiod       for (pass = 0; pass < 2; pass++)
2028*3d8817e4Smiod 	{
2029*3d8817e4Smiod 	  fixS *f;
2030*3d8817e4Smiod 	  fixS *prev;
2031*3d8817e4Smiod 
2032*3d8817e4Smiod 	  prev = NULL;
2033*3d8817e4Smiod 	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
2034*3d8817e4Smiod 	    {
2035*3d8817e4Smiod 	      /* Check whether this is a `low' fixup which matches l->fixp.  */
2036*3d8817e4Smiod 	      if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_M32R_LO16
2037*3d8817e4Smiod 		  && f->fx_addsy == l->fixp->fx_addsy
2038*3d8817e4Smiod 		  && f->fx_offset == l->fixp->fx_offset
2039*3d8817e4Smiod 		  && (pass == 1
2040*3d8817e4Smiod 		      || prev == NULL
2041*3d8817e4Smiod 		      || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_SLO
2042*3d8817e4Smiod 			  && FX_OPINFO_R_TYPE (prev) != BFD_RELOC_M32R_HI16_ULO)
2043*3d8817e4Smiod 		      || prev->fx_addsy != f->fx_addsy
2044*3d8817e4Smiod 		      || prev->fx_offset != f->fx_offset))
2045*3d8817e4Smiod 		{
2046*3d8817e4Smiod 		  fixS **pf;
2047*3d8817e4Smiod 
2048*3d8817e4Smiod 		  /* Move l->fixp before f.  */
2049*3d8817e4Smiod 		  for (pf = &seginfo->fix_root;
2050*3d8817e4Smiod 		       *pf != l->fixp;
2051*3d8817e4Smiod 		       pf = & (*pf)->fx_next)
2052*3d8817e4Smiod 		    assert (*pf != NULL);
2053*3d8817e4Smiod 
2054*3d8817e4Smiod 		  *pf = l->fixp->fx_next;
2055*3d8817e4Smiod 
2056*3d8817e4Smiod 		  l->fixp->fx_next = f;
2057*3d8817e4Smiod 		  if (prev == NULL)
2058*3d8817e4Smiod 		    seginfo->fix_root = l->fixp;
2059*3d8817e4Smiod 		  else
2060*3d8817e4Smiod 		    prev->fx_next = l->fixp;
2061*3d8817e4Smiod 
2062*3d8817e4Smiod 		  break;
2063*3d8817e4Smiod 		}
2064*3d8817e4Smiod 
2065*3d8817e4Smiod 	      prev = f;
2066*3d8817e4Smiod 	    }
2067*3d8817e4Smiod 
2068*3d8817e4Smiod 	  if (f != NULL)
2069*3d8817e4Smiod 	    break;
2070*3d8817e4Smiod 
2071*3d8817e4Smiod 	  if (pass == 1
2072*3d8817e4Smiod 	      && warn_unmatched_high)
2073*3d8817e4Smiod 	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
2074*3d8817e4Smiod 			   _("Unmatched high/shigh reloc"));
2075*3d8817e4Smiod 	}
2076*3d8817e4Smiod     }
2077*3d8817e4Smiod }
2078*3d8817e4Smiod 
2079*3d8817e4Smiod /* See whether we need to force a relocation into the output file.
2080*3d8817e4Smiod    This is used to force out switch and PC relative relocations when
2081*3d8817e4Smiod    relaxing.  */
2082*3d8817e4Smiod 
2083*3d8817e4Smiod int
m32r_force_relocation(fixS * fix)2084*3d8817e4Smiod m32r_force_relocation (fixS *fix)
2085*3d8817e4Smiod {
2086*3d8817e4Smiod   if (generic_force_reloc (fix))
2087*3d8817e4Smiod     return 1;
2088*3d8817e4Smiod 
2089*3d8817e4Smiod   if (! m32r_relax)
2090*3d8817e4Smiod     return 0;
2091*3d8817e4Smiod 
2092*3d8817e4Smiod   return fix->fx_pcrel;
2093*3d8817e4Smiod }
2094*3d8817e4Smiod 
2095*3d8817e4Smiod /* Write a value out to the object file, using the appropriate endianness.  */
2096*3d8817e4Smiod 
2097*3d8817e4Smiod void
md_number_to_chars(char * buf,valueT val,int n)2098*3d8817e4Smiod md_number_to_chars (char *buf, valueT val, int n)
2099*3d8817e4Smiod {
2100*3d8817e4Smiod   if (target_big_endian)
2101*3d8817e4Smiod     number_to_chars_bigendian (buf, val, n);
2102*3d8817e4Smiod   else
2103*3d8817e4Smiod     number_to_chars_littleendian (buf, val, n);
2104*3d8817e4Smiod }
2105*3d8817e4Smiod 
2106*3d8817e4Smiod /* Turn a string in input_line_pointer into a floating point constant
2107*3d8817e4Smiod    of type TYPE, and store the appropriate bytes in *LITP.  The number
2108*3d8817e4Smiod    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
2109*3d8817e4Smiod    returned, or NULL on OK.  */
2110*3d8817e4Smiod 
2111*3d8817e4Smiod /* Equal to MAX_PRECISION in atof-ieee.c.  */
2112*3d8817e4Smiod #define MAX_LITTLENUMS 6
2113*3d8817e4Smiod 
2114*3d8817e4Smiod char *
md_atof(int type,char * litP,int * sizeP)2115*3d8817e4Smiod md_atof (int type, char *litP, int *sizeP)
2116*3d8817e4Smiod {
2117*3d8817e4Smiod   int i;
2118*3d8817e4Smiod   int prec;
2119*3d8817e4Smiod   LITTLENUM_TYPE words[MAX_LITTLENUMS];
2120*3d8817e4Smiod   char *t;
2121*3d8817e4Smiod 
2122*3d8817e4Smiod   switch (type)
2123*3d8817e4Smiod     {
2124*3d8817e4Smiod     case 'f':
2125*3d8817e4Smiod     case 'F':
2126*3d8817e4Smiod     case 's':
2127*3d8817e4Smiod     case 'S':
2128*3d8817e4Smiod       prec = 2;
2129*3d8817e4Smiod       break;
2130*3d8817e4Smiod 
2131*3d8817e4Smiod     case 'd':
2132*3d8817e4Smiod     case 'D':
2133*3d8817e4Smiod     case 'r':
2134*3d8817e4Smiod     case 'R':
2135*3d8817e4Smiod       prec = 4;
2136*3d8817e4Smiod       break;
2137*3d8817e4Smiod 
2138*3d8817e4Smiod       /* FIXME: Some targets allow other format chars for bigger sizes
2139*3d8817e4Smiod          here.  */
2140*3d8817e4Smiod 
2141*3d8817e4Smiod     default:
2142*3d8817e4Smiod       *sizeP = 0;
2143*3d8817e4Smiod       return _("Bad call to md_atof()");
2144*3d8817e4Smiod     }
2145*3d8817e4Smiod 
2146*3d8817e4Smiod   t = atof_ieee (input_line_pointer, type, words);
2147*3d8817e4Smiod   if (t)
2148*3d8817e4Smiod     input_line_pointer = t;
2149*3d8817e4Smiod   *sizeP = prec * sizeof (LITTLENUM_TYPE);
2150*3d8817e4Smiod 
2151*3d8817e4Smiod   if (target_big_endian)
2152*3d8817e4Smiod     {
2153*3d8817e4Smiod       for (i = 0; i < prec; i++)
2154*3d8817e4Smiod 	{
2155*3d8817e4Smiod 	  md_number_to_chars (litP, (valueT) words[i],
2156*3d8817e4Smiod 			      sizeof (LITTLENUM_TYPE));
2157*3d8817e4Smiod 	  litP += sizeof (LITTLENUM_TYPE);
2158*3d8817e4Smiod 	}
2159*3d8817e4Smiod     }
2160*3d8817e4Smiod   else
2161*3d8817e4Smiod     {
2162*3d8817e4Smiod       for (i = prec - 1; i >= 0; i--)
2163*3d8817e4Smiod 	{
2164*3d8817e4Smiod 	  md_number_to_chars (litP, (valueT) words[i],
2165*3d8817e4Smiod 			      sizeof (LITTLENUM_TYPE));
2166*3d8817e4Smiod 	  litP += sizeof (LITTLENUM_TYPE);
2167*3d8817e4Smiod 	}
2168*3d8817e4Smiod     }
2169*3d8817e4Smiod 
2170*3d8817e4Smiod   return 0;
2171*3d8817e4Smiod }
2172*3d8817e4Smiod 
2173*3d8817e4Smiod void
m32r_elf_section_change_hook(void)2174*3d8817e4Smiod m32r_elf_section_change_hook (void)
2175*3d8817e4Smiod {
2176*3d8817e4Smiod   /* If we have reached the end of a section and we have just emitted a
2177*3d8817e4Smiod      16 bit insn, then emit a nop to make sure that the section ends on
2178*3d8817e4Smiod      a 32 bit boundary.  */
2179*3d8817e4Smiod 
2180*3d8817e4Smiod   if (prev_insn.insn || seen_relaxable_p)
2181*3d8817e4Smiod     (void) m32r_fill_insn (0);
2182*3d8817e4Smiod }
2183*3d8817e4Smiod 
2184*3d8817e4Smiod /* Return true if can adjust the reloc to be relative to its section
2185*3d8817e4Smiod    (such as .data) instead of relative to some symbol.  */
2186*3d8817e4Smiod 
2187*3d8817e4Smiod bfd_boolean
m32r_fix_adjustable(fixS * fixP)2188*3d8817e4Smiod m32r_fix_adjustable (fixS *fixP)
2189*3d8817e4Smiod {
2190*3d8817e4Smiod   bfd_reloc_code_real_type reloc_type;
2191*3d8817e4Smiod 
2192*3d8817e4Smiod   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
2193*3d8817e4Smiod     {
2194*3d8817e4Smiod       const CGEN_INSN *insn = NULL;
2195*3d8817e4Smiod       int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
2196*3d8817e4Smiod       const CGEN_OPERAND *operand =
2197*3d8817e4Smiod 	cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
2198*3d8817e4Smiod 
2199*3d8817e4Smiod       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
2200*3d8817e4Smiod     }
2201*3d8817e4Smiod   else
2202*3d8817e4Smiod     reloc_type = fixP->fx_r_type;
2203*3d8817e4Smiod 
2204*3d8817e4Smiod   if (fixP->fx_addsy == NULL)
2205*3d8817e4Smiod     return 1;
2206*3d8817e4Smiod 
2207*3d8817e4Smiod   /* Prevent all adjustments to global symbols.  */
2208*3d8817e4Smiod   if (S_IS_EXTERNAL (fixP->fx_addsy))
2209*3d8817e4Smiod     return 0;
2210*3d8817e4Smiod   if (S_IS_WEAK (fixP->fx_addsy))
2211*3d8817e4Smiod     return 0;
2212*3d8817e4Smiod 
2213*3d8817e4Smiod   if (pic_code
2214*3d8817e4Smiod       && (reloc_type == BFD_RELOC_M32R_24
2215*3d8817e4Smiod           || reloc_type == BFD_RELOC_M32R_26_PCREL
2216*3d8817e4Smiod           || reloc_type == BFD_RELOC_M32R_HI16_SLO
2217*3d8817e4Smiod           || reloc_type == BFD_RELOC_M32R_HI16_ULO
2218*3d8817e4Smiod           || reloc_type == BFD_RELOC_M32R_LO16))
2219*3d8817e4Smiod     return 0;
2220*3d8817e4Smiod 
2221*3d8817e4Smiod   if (reloc_type == BFD_RELOC_M32R_GOT24
2222*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_26_PLTREL
2223*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOTPC_HI_SLO
2224*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOTPC_HI_ULO
2225*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOTPC_LO
2226*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOT16_HI_SLO
2227*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOT16_HI_ULO
2228*3d8817e4Smiod       || reloc_type == BFD_RELOC_M32R_GOT16_LO)
2229*3d8817e4Smiod     return 0;
2230*3d8817e4Smiod 
2231*3d8817e4Smiod   /* We need the symbol name for the VTABLE entries.  */
2232*3d8817e4Smiod   if (reloc_type == BFD_RELOC_VTABLE_INHERIT
2233*3d8817e4Smiod       || reloc_type == BFD_RELOC_VTABLE_ENTRY)
2234*3d8817e4Smiod     return 0;
2235*3d8817e4Smiod 
2236*3d8817e4Smiod   return 1;
2237*3d8817e4Smiod }
2238*3d8817e4Smiod 
2239*3d8817e4Smiod void
m32r_elf_final_processing(void)2240*3d8817e4Smiod m32r_elf_final_processing (void)
2241*3d8817e4Smiod {
2242*3d8817e4Smiod   if (use_parallel)
2243*3d8817e4Smiod     m32r_flags |= E_M32R_HAS_PARALLEL;
2244*3d8817e4Smiod   elf_elfheader (stdoutput)->e_flags |= m32r_flags;
2245*3d8817e4Smiod }
2246*3d8817e4Smiod 
2247*3d8817e4Smiod /* Translate internal representation of relocation info to BFD target
2248*3d8817e4Smiod    format. */
2249*3d8817e4Smiod 
2250*3d8817e4Smiod arelent *
tc_gen_reloc(asection * section,fixS * fixP)2251*3d8817e4Smiod tc_gen_reloc (asection * section, fixS * fixP)
2252*3d8817e4Smiod {
2253*3d8817e4Smiod   arelent * reloc;
2254*3d8817e4Smiod   bfd_reloc_code_real_type code;
2255*3d8817e4Smiod 
2256*3d8817e4Smiod   reloc = xmalloc (sizeof (* reloc));
2257*3d8817e4Smiod 
2258*3d8817e4Smiod   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2259*3d8817e4Smiod   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
2260*3d8817e4Smiod   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
2261*3d8817e4Smiod 
2262*3d8817e4Smiod   if (fixP->fx_pcrel)
2263*3d8817e4Smiod     {
2264*3d8817e4Smiod       if (fixP->fx_r_type == BFD_RELOC_32)
2265*3d8817e4Smiod         fixP->fx_r_type = BFD_RELOC_32_PCREL;
2266*3d8817e4Smiod       else if (fixP->fx_r_type == BFD_RELOC_16)
2267*3d8817e4Smiod 	{
2268*3d8817e4Smiod           fixP->fx_r_type = BFD_RELOC_16_PCREL;
2269*3d8817e4Smiod           bfd_set_error (bfd_error_bad_value);
2270*3d8817e4Smiod 	}
2271*3d8817e4Smiod     }
2272*3d8817e4Smiod 
2273*3d8817e4Smiod   code = fixP->fx_r_type;
2274*3d8817e4Smiod   if (pic_code)
2275*3d8817e4Smiod     {
2276*3d8817e4Smiod #ifdef DEBUG_PIC
2277*3d8817e4Smiod printf("%s",bfd_get_reloc_code_name(code));
2278*3d8817e4Smiod #endif
2279*3d8817e4Smiod       switch (code)
2280*3d8817e4Smiod         {
2281*3d8817e4Smiod         case BFD_RELOC_M32R_26_PCREL:
2282*3d8817e4Smiod             code = BFD_RELOC_M32R_26_PLTREL;
2283*3d8817e4Smiod           break;
2284*3d8817e4Smiod 
2285*3d8817e4Smiod         case BFD_RELOC_M32R_24:
2286*3d8817e4Smiod           if (fixP->fx_addsy != NULL
2287*3d8817e4Smiod               && strcmp (S_GET_NAME (fixP->fx_addsy), GOT_NAME) == 0)
2288*3d8817e4Smiod             code = BFD_RELOC_M32R_GOTPC24;
2289*3d8817e4Smiod           else
2290*3d8817e4Smiod             code = BFD_RELOC_M32R_GOT24;
2291*3d8817e4Smiod           break;
2292*3d8817e4Smiod 
2293*3d8817e4Smiod         case BFD_RELOC_M32R_HI16_ULO:
2294*3d8817e4Smiod           if (fixP->fx_addsy != NULL
2295*3d8817e4Smiod               && strcmp (S_GET_NAME (fixP->fx_addsy), GOT_NAME) == 0)
2296*3d8817e4Smiod             code = BFD_RELOC_M32R_GOTPC_HI_ULO;
2297*3d8817e4Smiod           else
2298*3d8817e4Smiod             code = BFD_RELOC_M32R_GOT16_HI_ULO;
2299*3d8817e4Smiod           break;
2300*3d8817e4Smiod 
2301*3d8817e4Smiod         case BFD_RELOC_M32R_HI16_SLO:
2302*3d8817e4Smiod           if (fixP->fx_addsy != NULL
2303*3d8817e4Smiod               && strcmp (S_GET_NAME (fixP->fx_addsy), GOT_NAME) == 0)
2304*3d8817e4Smiod             code = BFD_RELOC_M32R_GOTPC_HI_SLO;
2305*3d8817e4Smiod           else
2306*3d8817e4Smiod             code = BFD_RELOC_M32R_GOT16_HI_SLO;
2307*3d8817e4Smiod           break;
2308*3d8817e4Smiod 
2309*3d8817e4Smiod         case BFD_RELOC_M32R_LO16:
2310*3d8817e4Smiod           if (fixP->fx_addsy != NULL
2311*3d8817e4Smiod               && strcmp (S_GET_NAME (fixP->fx_addsy), GOT_NAME) == 0)
2312*3d8817e4Smiod             code = BFD_RELOC_M32R_GOTPC_LO;
2313*3d8817e4Smiod           else
2314*3d8817e4Smiod             code = BFD_RELOC_M32R_GOT16_LO;
2315*3d8817e4Smiod           break;
2316*3d8817e4Smiod 
2317*3d8817e4Smiod         default:
2318*3d8817e4Smiod           break;
2319*3d8817e4Smiod         }
2320*3d8817e4Smiod #ifdef DEBUG_PIC
2321*3d8817e4Smiod printf(" => %s",bfd_get_reloc_code_name(code));
2322*3d8817e4Smiod #endif
2323*3d8817e4Smiod     }
2324*3d8817e4Smiod 
2325*3d8817e4Smiod   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2326*3d8817e4Smiod 
2327*3d8817e4Smiod #ifdef DEBUG_PIC
2328*3d8817e4Smiod printf(" => %s\n",reloc->howto->name);
2329*3d8817e4Smiod #endif
2330*3d8817e4Smiod 
2331*3d8817e4Smiod  if (reloc->howto == (reloc_howto_type *) NULL)
2332*3d8817e4Smiod     {
2333*3d8817e4Smiod       as_bad_where (fixP->fx_file, fixP->fx_line,
2334*3d8817e4Smiod             _("internal error: can't export reloc type %d (`%s')"),
2335*3d8817e4Smiod             fixP->fx_r_type, bfd_get_reloc_code_name (code));
2336*3d8817e4Smiod       return NULL;
2337*3d8817e4Smiod     }
2338*3d8817e4Smiod 
2339*3d8817e4Smiod   /* Use fx_offset for these cases.  */
2340*3d8817e4Smiod   if (   fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
2341*3d8817e4Smiod       || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2342*3d8817e4Smiod       || fixP->fx_r_type == BFD_RELOC_32_PCREL)
2343*3d8817e4Smiod     reloc->addend  = fixP->fx_offset;
2344*3d8817e4Smiod   else if ((!pic_code
2345*3d8817e4Smiod             && code != BFD_RELOC_M32R_26_PLTREL)
2346*3d8817e4Smiod            && fixP->fx_pcrel
2347*3d8817e4Smiod            && fixP->fx_addsy != NULL
2348*3d8817e4Smiod            && (S_GET_SEGMENT(fixP->fx_addsy) != section)
2349*3d8817e4Smiod            && S_IS_DEFINED (fixP->fx_addsy)
2350*3d8817e4Smiod            && ! S_IS_EXTERNAL(fixP->fx_addsy)
2351*3d8817e4Smiod            && ! S_IS_WEAK(fixP->fx_addsy))
2352*3d8817e4Smiod     /* Already used fx_offset in the opcode field itseld.  */
2353*3d8817e4Smiod     reloc->addend  = fixP->fx_offset;
2354*3d8817e4Smiod   else
2355*3d8817e4Smiod     reloc->addend  = fixP->fx_addnumber;
2356*3d8817e4Smiod 
2357*3d8817e4Smiod   return reloc;
2358*3d8817e4Smiod }
2359*3d8817e4Smiod 
2360*3d8817e4Smiod inline static char *
m32r_end_of_match(char * cont,char * what)2361*3d8817e4Smiod m32r_end_of_match (char *cont, char *what)
2362*3d8817e4Smiod {
2363*3d8817e4Smiod   int len = strlen (what);
2364*3d8817e4Smiod 
2365*3d8817e4Smiod   if (strncasecmp (cont, what, strlen (what)) == 0
2366*3d8817e4Smiod       && ! is_part_of_name (cont[len]))
2367*3d8817e4Smiod     return cont + len;
2368*3d8817e4Smiod 
2369*3d8817e4Smiod   return NULL;
2370*3d8817e4Smiod }
2371*3d8817e4Smiod 
2372*3d8817e4Smiod int
m32r_parse_name(char const * name,expressionS * exprP,enum expr_mode mode,char * nextcharP)2373*3d8817e4Smiod m32r_parse_name (char const *name,
2374*3d8817e4Smiod 		 expressionS *exprP,
2375*3d8817e4Smiod 		 enum expr_mode mode,
2376*3d8817e4Smiod 		 char *nextcharP)
2377*3d8817e4Smiod {
2378*3d8817e4Smiod   char *next = input_line_pointer;
2379*3d8817e4Smiod   char *next_end;
2380*3d8817e4Smiod   int reloc_type;
2381*3d8817e4Smiod   operatorT op_type;
2382*3d8817e4Smiod   segT segment;
2383*3d8817e4Smiod 
2384*3d8817e4Smiod   exprP->X_op_symbol = NULL;
2385*3d8817e4Smiod   exprP->X_md = BFD_RELOC_UNUSED;
2386*3d8817e4Smiod 
2387*3d8817e4Smiod   if (strcmp (name, GOT_NAME) == 0)
2388*3d8817e4Smiod     {
2389*3d8817e4Smiod       if (! GOT_symbol)
2390*3d8817e4Smiod 	GOT_symbol = symbol_find_or_make (name);
2391*3d8817e4Smiod 
2392*3d8817e4Smiod       exprP->X_add_symbol = GOT_symbol;
2393*3d8817e4Smiod     no_suffix:
2394*3d8817e4Smiod       /* If we have an absolute symbol or a
2395*3d8817e4Smiod 	 reg, then we know its value now.  */
2396*3d8817e4Smiod       segment = S_GET_SEGMENT (exprP->X_add_symbol);
2397*3d8817e4Smiod       if (mode != expr_defer && segment == absolute_section)
2398*3d8817e4Smiod 	{
2399*3d8817e4Smiod 	  exprP->X_op = O_constant;
2400*3d8817e4Smiod 	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
2401*3d8817e4Smiod 	  exprP->X_add_symbol = NULL;
2402*3d8817e4Smiod 	}
2403*3d8817e4Smiod       else if (mode != expr_defer && segment == reg_section)
2404*3d8817e4Smiod 	{
2405*3d8817e4Smiod 	  exprP->X_op = O_register;
2406*3d8817e4Smiod 	  exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol);
2407*3d8817e4Smiod 	  exprP->X_add_symbol = NULL;
2408*3d8817e4Smiod 	}
2409*3d8817e4Smiod       else
2410*3d8817e4Smiod 	{
2411*3d8817e4Smiod 	  exprP->X_op = O_symbol;
2412*3d8817e4Smiod 	  exprP->X_add_number = 0;
2413*3d8817e4Smiod 	}
2414*3d8817e4Smiod 
2415*3d8817e4Smiod       return 1;
2416*3d8817e4Smiod     }
2417*3d8817e4Smiod 
2418*3d8817e4Smiod   exprP->X_add_symbol = symbol_find_or_make (name);
2419*3d8817e4Smiod 
2420*3d8817e4Smiod   if (*nextcharP != '@')
2421*3d8817e4Smiod     goto no_suffix;
2422*3d8817e4Smiod   else if ((next_end = m32r_end_of_match (next + 1, "GOTOFF")))
2423*3d8817e4Smiod     {
2424*3d8817e4Smiod       reloc_type = BFD_RELOC_M32R_GOTOFF;
2425*3d8817e4Smiod       op_type = O_PIC_reloc;
2426*3d8817e4Smiod     }
2427*3d8817e4Smiod   else if ((next_end = m32r_end_of_match (next + 1, "GOT")))
2428*3d8817e4Smiod     {
2429*3d8817e4Smiod       reloc_type = BFD_RELOC_M32R_GOT24;
2430*3d8817e4Smiod       op_type = O_PIC_reloc;
2431*3d8817e4Smiod     }
2432*3d8817e4Smiod   else if ((next_end = m32r_end_of_match (next + 1, "PLT")))
2433*3d8817e4Smiod     {
2434*3d8817e4Smiod       reloc_type = BFD_RELOC_M32R_26_PLTREL;
2435*3d8817e4Smiod       op_type = O_PIC_reloc;
2436*3d8817e4Smiod     }
2437*3d8817e4Smiod   else
2438*3d8817e4Smiod     goto no_suffix;
2439*3d8817e4Smiod 
2440*3d8817e4Smiod   *input_line_pointer = *nextcharP;
2441*3d8817e4Smiod   input_line_pointer = next_end;
2442*3d8817e4Smiod   *nextcharP = *input_line_pointer;
2443*3d8817e4Smiod   *input_line_pointer = '\0';
2444*3d8817e4Smiod 
2445*3d8817e4Smiod   exprP->X_op = op_type;
2446*3d8817e4Smiod   exprP->X_add_number = 0;
2447*3d8817e4Smiod   exprP->X_md = reloc_type;
2448*3d8817e4Smiod 
2449*3d8817e4Smiod   return 1;
2450*3d8817e4Smiod }
2451*3d8817e4Smiod 
2452*3d8817e4Smiod int
m32r_cgen_parse_fix_exp(int opinfo,expressionS * exp)2453*3d8817e4Smiod m32r_cgen_parse_fix_exp(int opinfo, expressionS *exp)
2454*3d8817e4Smiod {
2455*3d8817e4Smiod   if (exp->X_op == O_PIC_reloc
2456*3d8817e4Smiod       && exp->X_md == BFD_RELOC_M32R_26_PLTREL)
2457*3d8817e4Smiod     {
2458*3d8817e4Smiod       exp->X_op = O_symbol;
2459*3d8817e4Smiod       opinfo = exp->X_md;
2460*3d8817e4Smiod     }
2461*3d8817e4Smiod 
2462*3d8817e4Smiod   return opinfo;
2463*3d8817e4Smiod }
2464