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