1*3d8817e4Smiod /* tc-s390.c -- Assemble for the S390
2*3d8817e4Smiod Copyright 2000, 2001, 2002, 2003, 2004, 2005
3*3d8817e4Smiod Free Software Foundation, Inc.
4*3d8817e4Smiod Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
5*3d8817e4Smiod
6*3d8817e4Smiod This file is part of GAS, the GNU Assembler.
7*3d8817e4Smiod
8*3d8817e4Smiod GAS is free software; you can redistribute it and/or modify
9*3d8817e4Smiod it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod the Free Software Foundation; either version 2, or (at your option)
11*3d8817e4Smiod any later version.
12*3d8817e4Smiod
13*3d8817e4Smiod GAS is distributed in the hope that it will be useful,
14*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*3d8817e4Smiod GNU General Public License for more details.
17*3d8817e4Smiod
18*3d8817e4Smiod You should have received a copy of the GNU General Public License
19*3d8817e4Smiod along with GAS; see the file COPYING. If not, write to the Free
20*3d8817e4Smiod Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21*3d8817e4Smiod 02110-1301, USA. */
22*3d8817e4Smiod
23*3d8817e4Smiod #include <stdio.h>
24*3d8817e4Smiod #include "as.h"
25*3d8817e4Smiod #include "safe-ctype.h"
26*3d8817e4Smiod #include "subsegs.h"
27*3d8817e4Smiod #include "struc-symbol.h"
28*3d8817e4Smiod #include "dwarf2dbg.h"
29*3d8817e4Smiod #include "dw2gencfi.h"
30*3d8817e4Smiod
31*3d8817e4Smiod #include "opcode/s390.h"
32*3d8817e4Smiod #include "elf/s390.h"
33*3d8817e4Smiod
34*3d8817e4Smiod /* The default architecture. */
35*3d8817e4Smiod #ifndef DEFAULT_ARCH
36*3d8817e4Smiod #define DEFAULT_ARCH "s390"
37*3d8817e4Smiod #endif
38*3d8817e4Smiod static char *default_arch = DEFAULT_ARCH;
39*3d8817e4Smiod /* Either 32 or 64, selects file format. */
40*3d8817e4Smiod static int s390_arch_size = 0;
41*3d8817e4Smiod
42*3d8817e4Smiod static unsigned int current_mode_mask = 0;
43*3d8817e4Smiod static unsigned int current_cpu = -1U;
44*3d8817e4Smiod
45*3d8817e4Smiod /* Whether to use user friendly register names. Default is TRUE. */
46*3d8817e4Smiod #ifndef TARGET_REG_NAMES_P
47*3d8817e4Smiod #define TARGET_REG_NAMES_P TRUE
48*3d8817e4Smiod #endif
49*3d8817e4Smiod
50*3d8817e4Smiod static bfd_boolean reg_names_p = TARGET_REG_NAMES_P;
51*3d8817e4Smiod
52*3d8817e4Smiod /* Set to TRUE if we want to warn about zero base/index registers. */
53*3d8817e4Smiod static bfd_boolean warn_areg_zero = FALSE;
54*3d8817e4Smiod
55*3d8817e4Smiod /* Generic assembler global variables which must be defined by all
56*3d8817e4Smiod targets. */
57*3d8817e4Smiod
58*3d8817e4Smiod const char comment_chars[] = "#";
59*3d8817e4Smiod
60*3d8817e4Smiod /* Characters which start a comment at the beginning of a line. */
61*3d8817e4Smiod const char line_comment_chars[] = "#";
62*3d8817e4Smiod
63*3d8817e4Smiod /* Characters which may be used to separate multiple commands on a
64*3d8817e4Smiod single line. */
65*3d8817e4Smiod const char line_separator_chars[] = ";";
66*3d8817e4Smiod
67*3d8817e4Smiod /* Characters which are used to indicate an exponent in a floating
68*3d8817e4Smiod point number. */
69*3d8817e4Smiod const char EXP_CHARS[] = "eE";
70*3d8817e4Smiod
71*3d8817e4Smiod /* Characters which mean that a number is a floating point constant,
72*3d8817e4Smiod as in 0d1.0. */
73*3d8817e4Smiod const char FLT_CHARS[] = "dD";
74*3d8817e4Smiod
75*3d8817e4Smiod /* The dwarf2 data alignment, adjusted for 32 or 64 bit. */
76*3d8817e4Smiod int s390_cie_data_alignment;
77*3d8817e4Smiod
78*3d8817e4Smiod /* The target specific pseudo-ops which we support. */
79*3d8817e4Smiod
80*3d8817e4Smiod /* Define the prototypes for the pseudo-ops */
81*3d8817e4Smiod static void s390_byte PARAMS ((int));
82*3d8817e4Smiod static void s390_elf_cons PARAMS ((int));
83*3d8817e4Smiod static void s390_bss PARAMS ((int));
84*3d8817e4Smiod static void s390_insn PARAMS ((int));
85*3d8817e4Smiod static void s390_literals PARAMS ((int));
86*3d8817e4Smiod
87*3d8817e4Smiod const pseudo_typeS md_pseudo_table[] =
88*3d8817e4Smiod {
89*3d8817e4Smiod { "align", s_align_bytes, 0 },
90*3d8817e4Smiod /* Pseudo-ops which must be defined. */
91*3d8817e4Smiod { "bss", s390_bss, 0 },
92*3d8817e4Smiod { "insn", s390_insn, 0 },
93*3d8817e4Smiod /* Pseudo-ops which must be overridden. */
94*3d8817e4Smiod { "byte", s390_byte, 0 },
95*3d8817e4Smiod { "short", s390_elf_cons, 2 },
96*3d8817e4Smiod { "long", s390_elf_cons, 4 },
97*3d8817e4Smiod { "quad", s390_elf_cons, 8 },
98*3d8817e4Smiod { "ltorg", s390_literals, 0 },
99*3d8817e4Smiod { "string", stringer, 2 },
100*3d8817e4Smiod { NULL, NULL, 0 }
101*3d8817e4Smiod };
102*3d8817e4Smiod
103*3d8817e4Smiod
104*3d8817e4Smiod /* Structure to hold information about predefined registers. */
105*3d8817e4Smiod struct pd_reg
106*3d8817e4Smiod {
107*3d8817e4Smiod char *name;
108*3d8817e4Smiod int value;
109*3d8817e4Smiod };
110*3d8817e4Smiod
111*3d8817e4Smiod /* List of registers that are pre-defined:
112*3d8817e4Smiod
113*3d8817e4Smiod Each access register has a predefined name of the form:
114*3d8817e4Smiod a<reg_num> which has the value <reg_num>.
115*3d8817e4Smiod
116*3d8817e4Smiod Each control register has a predefined name of the form:
117*3d8817e4Smiod c<reg_num> which has the value <reg_num>.
118*3d8817e4Smiod
119*3d8817e4Smiod Each general register has a predefined name of the form:
120*3d8817e4Smiod r<reg_num> which has the value <reg_num>.
121*3d8817e4Smiod
122*3d8817e4Smiod Each floating point register a has predefined name of the form:
123*3d8817e4Smiod f<reg_num> which has the value <reg_num>.
124*3d8817e4Smiod
125*3d8817e4Smiod There are individual registers as well:
126*3d8817e4Smiod sp has the value 15
127*3d8817e4Smiod lit has the value 12
128*3d8817e4Smiod
129*3d8817e4Smiod The table is sorted. Suitable for searching by a binary search. */
130*3d8817e4Smiod
131*3d8817e4Smiod static const struct pd_reg pre_defined_registers[] =
132*3d8817e4Smiod {
133*3d8817e4Smiod { "a0", 0 }, /* Access registers */
134*3d8817e4Smiod { "a1", 1 },
135*3d8817e4Smiod { "a10", 10 },
136*3d8817e4Smiod { "a11", 11 },
137*3d8817e4Smiod { "a12", 12 },
138*3d8817e4Smiod { "a13", 13 },
139*3d8817e4Smiod { "a14", 14 },
140*3d8817e4Smiod { "a15", 15 },
141*3d8817e4Smiod { "a2", 2 },
142*3d8817e4Smiod { "a3", 3 },
143*3d8817e4Smiod { "a4", 4 },
144*3d8817e4Smiod { "a5", 5 },
145*3d8817e4Smiod { "a6", 6 },
146*3d8817e4Smiod { "a7", 7 },
147*3d8817e4Smiod { "a8", 8 },
148*3d8817e4Smiod { "a9", 9 },
149*3d8817e4Smiod
150*3d8817e4Smiod { "c0", 0 }, /* Control registers */
151*3d8817e4Smiod { "c1", 1 },
152*3d8817e4Smiod { "c10", 10 },
153*3d8817e4Smiod { "c11", 11 },
154*3d8817e4Smiod { "c12", 12 },
155*3d8817e4Smiod { "c13", 13 },
156*3d8817e4Smiod { "c14", 14 },
157*3d8817e4Smiod { "c15", 15 },
158*3d8817e4Smiod { "c2", 2 },
159*3d8817e4Smiod { "c3", 3 },
160*3d8817e4Smiod { "c4", 4 },
161*3d8817e4Smiod { "c5", 5 },
162*3d8817e4Smiod { "c6", 6 },
163*3d8817e4Smiod { "c7", 7 },
164*3d8817e4Smiod { "c8", 8 },
165*3d8817e4Smiod { "c9", 9 },
166*3d8817e4Smiod
167*3d8817e4Smiod { "f0", 0 }, /* Floating point registers */
168*3d8817e4Smiod { "f1", 1 },
169*3d8817e4Smiod { "f10", 10 },
170*3d8817e4Smiod { "f11", 11 },
171*3d8817e4Smiod { "f12", 12 },
172*3d8817e4Smiod { "f13", 13 },
173*3d8817e4Smiod { "f14", 14 },
174*3d8817e4Smiod { "f15", 15 },
175*3d8817e4Smiod { "f2", 2 },
176*3d8817e4Smiod { "f3", 3 },
177*3d8817e4Smiod { "f4", 4 },
178*3d8817e4Smiod { "f5", 5 },
179*3d8817e4Smiod { "f6", 6 },
180*3d8817e4Smiod { "f7", 7 },
181*3d8817e4Smiod { "f8", 8 },
182*3d8817e4Smiod { "f9", 9 },
183*3d8817e4Smiod
184*3d8817e4Smiod { "lit", 13 }, /* Pointer to literal pool */
185*3d8817e4Smiod
186*3d8817e4Smiod { "r0", 0 }, /* General purpose registers */
187*3d8817e4Smiod { "r1", 1 },
188*3d8817e4Smiod { "r10", 10 },
189*3d8817e4Smiod { "r11", 11 },
190*3d8817e4Smiod { "r12", 12 },
191*3d8817e4Smiod { "r13", 13 },
192*3d8817e4Smiod { "r14", 14 },
193*3d8817e4Smiod { "r15", 15 },
194*3d8817e4Smiod { "r2", 2 },
195*3d8817e4Smiod { "r3", 3 },
196*3d8817e4Smiod { "r4", 4 },
197*3d8817e4Smiod { "r5", 5 },
198*3d8817e4Smiod { "r6", 6 },
199*3d8817e4Smiod { "r7", 7 },
200*3d8817e4Smiod { "r8", 8 },
201*3d8817e4Smiod { "r9", 9 },
202*3d8817e4Smiod
203*3d8817e4Smiod { "sp", 15 }, /* Stack pointer */
204*3d8817e4Smiod
205*3d8817e4Smiod };
206*3d8817e4Smiod
207*3d8817e4Smiod #define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
208*3d8817e4Smiod
209*3d8817e4Smiod static int reg_name_search
210*3d8817e4Smiod PARAMS ((const struct pd_reg *, int, const char *));
211*3d8817e4Smiod static bfd_boolean register_name PARAMS ((expressionS *));
212*3d8817e4Smiod static void init_default_arch PARAMS ((void));
213*3d8817e4Smiod static void s390_insert_operand
214*3d8817e4Smiod PARAMS ((unsigned char *, const struct s390_operand *, offsetT, char *,
215*3d8817e4Smiod unsigned int));
216*3d8817e4Smiod static char *md_gather_operands
217*3d8817e4Smiod PARAMS ((char *, unsigned char *, const struct s390_opcode *));
218*3d8817e4Smiod
219*3d8817e4Smiod /* Given NAME, find the register number associated with that name, return
220*3d8817e4Smiod the integer value associated with the given name or -1 on failure. */
221*3d8817e4Smiod
222*3d8817e4Smiod static int
reg_name_search(regs,regcount,name)223*3d8817e4Smiod reg_name_search (regs, regcount, name)
224*3d8817e4Smiod const struct pd_reg *regs;
225*3d8817e4Smiod int regcount;
226*3d8817e4Smiod const char *name;
227*3d8817e4Smiod {
228*3d8817e4Smiod int middle, low, high;
229*3d8817e4Smiod int cmp;
230*3d8817e4Smiod
231*3d8817e4Smiod low = 0;
232*3d8817e4Smiod high = regcount - 1;
233*3d8817e4Smiod
234*3d8817e4Smiod do
235*3d8817e4Smiod {
236*3d8817e4Smiod middle = (low + high) / 2;
237*3d8817e4Smiod cmp = strcasecmp (name, regs[middle].name);
238*3d8817e4Smiod if (cmp < 0)
239*3d8817e4Smiod high = middle - 1;
240*3d8817e4Smiod else if (cmp > 0)
241*3d8817e4Smiod low = middle + 1;
242*3d8817e4Smiod else
243*3d8817e4Smiod return regs[middle].value;
244*3d8817e4Smiod }
245*3d8817e4Smiod while (low <= high);
246*3d8817e4Smiod
247*3d8817e4Smiod return -1;
248*3d8817e4Smiod }
249*3d8817e4Smiod
250*3d8817e4Smiod
251*3d8817e4Smiod /*
252*3d8817e4Smiod * Summary of register_name().
253*3d8817e4Smiod *
254*3d8817e4Smiod * in: Input_line_pointer points to 1st char of operand.
255*3d8817e4Smiod *
256*3d8817e4Smiod * out: A expressionS.
257*3d8817e4Smiod * The operand may have been a register: in this case, X_op == O_register,
258*3d8817e4Smiod * X_add_number is set to the register number, and truth is returned.
259*3d8817e4Smiod * Input_line_pointer->(next non-blank) char after operand, or is in its
260*3d8817e4Smiod * original state.
261*3d8817e4Smiod */
262*3d8817e4Smiod
263*3d8817e4Smiod static bfd_boolean
register_name(expressionP)264*3d8817e4Smiod register_name (expressionP)
265*3d8817e4Smiod expressionS *expressionP;
266*3d8817e4Smiod {
267*3d8817e4Smiod int reg_number;
268*3d8817e4Smiod char *name;
269*3d8817e4Smiod char *start;
270*3d8817e4Smiod char c;
271*3d8817e4Smiod
272*3d8817e4Smiod /* Find the spelling of the operand. */
273*3d8817e4Smiod start = name = input_line_pointer;
274*3d8817e4Smiod if (name[0] == '%' && ISALPHA (name[1]))
275*3d8817e4Smiod name = ++input_line_pointer;
276*3d8817e4Smiod else
277*3d8817e4Smiod return FALSE;
278*3d8817e4Smiod
279*3d8817e4Smiod c = get_symbol_end ();
280*3d8817e4Smiod reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
281*3d8817e4Smiod
282*3d8817e4Smiod /* Put back the delimiting char. */
283*3d8817e4Smiod *input_line_pointer = c;
284*3d8817e4Smiod
285*3d8817e4Smiod /* Look to see if it's in the register table. */
286*3d8817e4Smiod if (reg_number >= 0)
287*3d8817e4Smiod {
288*3d8817e4Smiod expressionP->X_op = O_register;
289*3d8817e4Smiod expressionP->X_add_number = reg_number;
290*3d8817e4Smiod
291*3d8817e4Smiod /* Make the rest nice. */
292*3d8817e4Smiod expressionP->X_add_symbol = NULL;
293*3d8817e4Smiod expressionP->X_op_symbol = NULL;
294*3d8817e4Smiod return TRUE;
295*3d8817e4Smiod }
296*3d8817e4Smiod
297*3d8817e4Smiod /* Reset the line as if we had not done anything. */
298*3d8817e4Smiod input_line_pointer = start;
299*3d8817e4Smiod return FALSE;
300*3d8817e4Smiod }
301*3d8817e4Smiod
302*3d8817e4Smiod /* Local variables. */
303*3d8817e4Smiod
304*3d8817e4Smiod /* Opformat hash table. */
305*3d8817e4Smiod static struct hash_control *s390_opformat_hash;
306*3d8817e4Smiod
307*3d8817e4Smiod /* Opcode hash table. */
308*3d8817e4Smiod static struct hash_control *s390_opcode_hash;
309*3d8817e4Smiod
310*3d8817e4Smiod /* Flags to set in the elf header */
311*3d8817e4Smiod static flagword s390_flags = 0;
312*3d8817e4Smiod
313*3d8817e4Smiod symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
314*3d8817e4Smiod
315*3d8817e4Smiod #ifndef WORKING_DOT_WORD
316*3d8817e4Smiod int md_short_jump_size = 4;
317*3d8817e4Smiod int md_long_jump_size = 4;
318*3d8817e4Smiod #endif
319*3d8817e4Smiod
320*3d8817e4Smiod const char *md_shortopts = "A:m:kVQ:";
321*3d8817e4Smiod struct option md_longopts[] = {
322*3d8817e4Smiod {NULL, no_argument, NULL, 0}
323*3d8817e4Smiod };
324*3d8817e4Smiod size_t md_longopts_size = sizeof (md_longopts);
325*3d8817e4Smiod
326*3d8817e4Smiod /* Initialize the default opcode arch and word size from the default
327*3d8817e4Smiod architecture name if not specified by an option. */
328*3d8817e4Smiod static void
init_default_arch()329*3d8817e4Smiod init_default_arch ()
330*3d8817e4Smiod {
331*3d8817e4Smiod if (strcmp (default_arch, "s390") == 0)
332*3d8817e4Smiod {
333*3d8817e4Smiod if (s390_arch_size == 0)
334*3d8817e4Smiod s390_arch_size = 32;
335*3d8817e4Smiod }
336*3d8817e4Smiod else if (strcmp (default_arch, "s390x") == 0)
337*3d8817e4Smiod {
338*3d8817e4Smiod if (s390_arch_size == 0)
339*3d8817e4Smiod s390_arch_size = 64;
340*3d8817e4Smiod }
341*3d8817e4Smiod else
342*3d8817e4Smiod as_fatal ("Invalid default architecture, broken assembler.");
343*3d8817e4Smiod
344*3d8817e4Smiod if (current_mode_mask == 0)
345*3d8817e4Smiod {
346*3d8817e4Smiod if (s390_arch_size == 32)
347*3d8817e4Smiod current_mode_mask = 1 << S390_OPCODE_ESA;
348*3d8817e4Smiod else
349*3d8817e4Smiod current_mode_mask = 1 << S390_OPCODE_ZARCH;
350*3d8817e4Smiod }
351*3d8817e4Smiod if (current_cpu == -1U)
352*3d8817e4Smiod {
353*3d8817e4Smiod if (current_mode_mask == (1 << S390_OPCODE_ESA))
354*3d8817e4Smiod current_cpu = S390_OPCODE_G5;
355*3d8817e4Smiod else
356*3d8817e4Smiod current_cpu = S390_OPCODE_Z900;
357*3d8817e4Smiod }
358*3d8817e4Smiod }
359*3d8817e4Smiod
360*3d8817e4Smiod /* Called by TARGET_FORMAT. */
361*3d8817e4Smiod const char *
s390_target_format()362*3d8817e4Smiod s390_target_format ()
363*3d8817e4Smiod {
364*3d8817e4Smiod /* We don't get a chance to initialize anything before we're called,
365*3d8817e4Smiod so handle that now. */
366*3d8817e4Smiod init_default_arch ();
367*3d8817e4Smiod
368*3d8817e4Smiod return s390_arch_size == 64 ? "elf64-s390" : "elf32-s390";
369*3d8817e4Smiod }
370*3d8817e4Smiod
371*3d8817e4Smiod int
md_parse_option(c,arg)372*3d8817e4Smiod md_parse_option (c, arg)
373*3d8817e4Smiod int c;
374*3d8817e4Smiod char *arg;
375*3d8817e4Smiod {
376*3d8817e4Smiod switch (c)
377*3d8817e4Smiod {
378*3d8817e4Smiod /* -k: Ignore for FreeBSD compatibility. */
379*3d8817e4Smiod case 'k':
380*3d8817e4Smiod break;
381*3d8817e4Smiod case 'm':
382*3d8817e4Smiod if (arg != NULL && strcmp (arg, "regnames") == 0)
383*3d8817e4Smiod reg_names_p = TRUE;
384*3d8817e4Smiod
385*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "no-regnames") == 0)
386*3d8817e4Smiod reg_names_p = FALSE;
387*3d8817e4Smiod
388*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "warn-areg-zero") == 0)
389*3d8817e4Smiod warn_areg_zero = TRUE;
390*3d8817e4Smiod
391*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "31") == 0)
392*3d8817e4Smiod s390_arch_size = 32;
393*3d8817e4Smiod
394*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "64") == 0)
395*3d8817e4Smiod s390_arch_size = 64;
396*3d8817e4Smiod
397*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "esa") == 0)
398*3d8817e4Smiod current_mode_mask = 1 << S390_OPCODE_ESA;
399*3d8817e4Smiod
400*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "zarch") == 0)
401*3d8817e4Smiod current_mode_mask = 1 << S390_OPCODE_ZARCH;
402*3d8817e4Smiod
403*3d8817e4Smiod else if (arg != NULL && strncmp (arg, "arch=", 5) == 0)
404*3d8817e4Smiod {
405*3d8817e4Smiod if (strcmp (arg + 5, "g5") == 0)
406*3d8817e4Smiod current_cpu = S390_OPCODE_G5;
407*3d8817e4Smiod else if (strcmp (arg + 5, "g6") == 0)
408*3d8817e4Smiod current_cpu = S390_OPCODE_G6;
409*3d8817e4Smiod else if (strcmp (arg + 5, "z900") == 0)
410*3d8817e4Smiod current_cpu = S390_OPCODE_Z900;
411*3d8817e4Smiod else if (strcmp (arg + 5, "z990") == 0)
412*3d8817e4Smiod current_cpu = S390_OPCODE_Z990;
413*3d8817e4Smiod else if (strcmp (arg + 5, "z9-109") == 0)
414*3d8817e4Smiod current_cpu = S390_OPCODE_Z9_109;
415*3d8817e4Smiod else
416*3d8817e4Smiod {
417*3d8817e4Smiod as_bad (_("invalid switch -m%s"), arg);
418*3d8817e4Smiod return 0;
419*3d8817e4Smiod }
420*3d8817e4Smiod }
421*3d8817e4Smiod
422*3d8817e4Smiod else
423*3d8817e4Smiod {
424*3d8817e4Smiod as_bad (_("invalid switch -m%s"), arg);
425*3d8817e4Smiod return 0;
426*3d8817e4Smiod }
427*3d8817e4Smiod break;
428*3d8817e4Smiod
429*3d8817e4Smiod case 'A':
430*3d8817e4Smiod /* Option -A is deprecated. Still available for compatibility. */
431*3d8817e4Smiod if (arg != NULL && strcmp (arg, "esa") == 0)
432*3d8817e4Smiod current_cpu = S390_OPCODE_G5;
433*3d8817e4Smiod else if (arg != NULL && strcmp (arg, "esame") == 0)
434*3d8817e4Smiod current_cpu = S390_OPCODE_Z900;
435*3d8817e4Smiod else
436*3d8817e4Smiod as_bad ("invalid architecture -A%s", arg);
437*3d8817e4Smiod break;
438*3d8817e4Smiod
439*3d8817e4Smiod /* -V: SVR4 argument to print version ID. */
440*3d8817e4Smiod case 'V':
441*3d8817e4Smiod print_version_id ();
442*3d8817e4Smiod break;
443*3d8817e4Smiod
444*3d8817e4Smiod /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
445*3d8817e4Smiod should be emitted or not. FIXME: Not implemented. */
446*3d8817e4Smiod case 'Q':
447*3d8817e4Smiod break;
448*3d8817e4Smiod
449*3d8817e4Smiod default:
450*3d8817e4Smiod return 0;
451*3d8817e4Smiod }
452*3d8817e4Smiod
453*3d8817e4Smiod return 1;
454*3d8817e4Smiod }
455*3d8817e4Smiod
456*3d8817e4Smiod void
md_show_usage(stream)457*3d8817e4Smiod md_show_usage (stream)
458*3d8817e4Smiod FILE *stream;
459*3d8817e4Smiod {
460*3d8817e4Smiod fprintf (stream, _("\
461*3d8817e4Smiod S390 options:\n\
462*3d8817e4Smiod -mregnames Allow symbolic names for registers\n\
463*3d8817e4Smiod -mwarn-areg-zero Warn about zero base/index registers\n\
464*3d8817e4Smiod -mno-regnames Do not allow symbolic names for registers\n\
465*3d8817e4Smiod -m31 Set file format to 31 bit format\n\
466*3d8817e4Smiod -m64 Set file format to 64 bit format\n"));
467*3d8817e4Smiod fprintf (stream, _("\
468*3d8817e4Smiod -V print assembler version number\n\
469*3d8817e4Smiod -Qy, -Qn ignored\n"));
470*3d8817e4Smiod }
471*3d8817e4Smiod
472*3d8817e4Smiod /* This function is called when the assembler starts up. It is called
473*3d8817e4Smiod after the options have been parsed and the output file has been
474*3d8817e4Smiod opened. */
475*3d8817e4Smiod
476*3d8817e4Smiod void
md_begin()477*3d8817e4Smiod md_begin ()
478*3d8817e4Smiod {
479*3d8817e4Smiod register const struct s390_opcode *op;
480*3d8817e4Smiod const struct s390_opcode *op_end;
481*3d8817e4Smiod bfd_boolean dup_insn = FALSE;
482*3d8817e4Smiod const char *retval;
483*3d8817e4Smiod
484*3d8817e4Smiod /* Give a warning if the combination -m64-bit and -Aesa is used. */
485*3d8817e4Smiod if (s390_arch_size == 64 && current_cpu < S390_OPCODE_Z900)
486*3d8817e4Smiod as_warn ("The 64 bit file format is used without esame instructions.");
487*3d8817e4Smiod
488*3d8817e4Smiod s390_cie_data_alignment = -s390_arch_size / 8;
489*3d8817e4Smiod
490*3d8817e4Smiod /* Set the ELF flags if desired. */
491*3d8817e4Smiod if (s390_flags)
492*3d8817e4Smiod bfd_set_private_flags (stdoutput, s390_flags);
493*3d8817e4Smiod
494*3d8817e4Smiod /* Insert the opcode formats into a hash table. */
495*3d8817e4Smiod s390_opformat_hash = hash_new ();
496*3d8817e4Smiod
497*3d8817e4Smiod op_end = s390_opformats + s390_num_opformats;
498*3d8817e4Smiod for (op = s390_opformats; op < op_end; op++)
499*3d8817e4Smiod {
500*3d8817e4Smiod retval = hash_insert (s390_opformat_hash, op->name, (PTR) op);
501*3d8817e4Smiod if (retval != (const char *) NULL)
502*3d8817e4Smiod {
503*3d8817e4Smiod as_bad (_("Internal assembler error for instruction format %s"),
504*3d8817e4Smiod op->name);
505*3d8817e4Smiod dup_insn = TRUE;
506*3d8817e4Smiod }
507*3d8817e4Smiod }
508*3d8817e4Smiod
509*3d8817e4Smiod /* Insert the opcodes into a hash table. */
510*3d8817e4Smiod s390_opcode_hash = hash_new ();
511*3d8817e4Smiod
512*3d8817e4Smiod op_end = s390_opcodes + s390_num_opcodes;
513*3d8817e4Smiod for (op = s390_opcodes; op < op_end; op++)
514*3d8817e4Smiod if (op->min_cpu <= current_cpu)
515*3d8817e4Smiod {
516*3d8817e4Smiod retval = hash_insert (s390_opcode_hash, op->name, (PTR) op);
517*3d8817e4Smiod if (retval != (const char *) NULL)
518*3d8817e4Smiod {
519*3d8817e4Smiod as_bad (_("Internal assembler error for instruction %s"),
520*3d8817e4Smiod op->name);
521*3d8817e4Smiod dup_insn = TRUE;
522*3d8817e4Smiod }
523*3d8817e4Smiod while (op < op_end - 1 && strcmp (op->name, op[1].name) == 0)
524*3d8817e4Smiod op++;
525*3d8817e4Smiod }
526*3d8817e4Smiod
527*3d8817e4Smiod if (dup_insn)
528*3d8817e4Smiod abort ();
529*3d8817e4Smiod
530*3d8817e4Smiod record_alignment (text_section, 2);
531*3d8817e4Smiod record_alignment (data_section, 2);
532*3d8817e4Smiod record_alignment (bss_section, 2);
533*3d8817e4Smiod
534*3d8817e4Smiod }
535*3d8817e4Smiod
536*3d8817e4Smiod /* Called after all assembly has been done. */
537*3d8817e4Smiod void
s390_md_end()538*3d8817e4Smiod s390_md_end ()
539*3d8817e4Smiod {
540*3d8817e4Smiod if (s390_arch_size == 64)
541*3d8817e4Smiod bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_64);
542*3d8817e4Smiod else
543*3d8817e4Smiod bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_31);
544*3d8817e4Smiod }
545*3d8817e4Smiod
546*3d8817e4Smiod /* Insert an operand value into an instruction. */
547*3d8817e4Smiod
548*3d8817e4Smiod static void
s390_insert_operand(insn,operand,val,file,line)549*3d8817e4Smiod s390_insert_operand (insn, operand, val, file, line)
550*3d8817e4Smiod unsigned char *insn;
551*3d8817e4Smiod const struct s390_operand *operand;
552*3d8817e4Smiod offsetT val;
553*3d8817e4Smiod char *file;
554*3d8817e4Smiod unsigned int line;
555*3d8817e4Smiod {
556*3d8817e4Smiod addressT uval;
557*3d8817e4Smiod int offset;
558*3d8817e4Smiod
559*3d8817e4Smiod if (operand->flags & (S390_OPERAND_SIGNED|S390_OPERAND_PCREL))
560*3d8817e4Smiod {
561*3d8817e4Smiod offsetT min, max;
562*3d8817e4Smiod
563*3d8817e4Smiod max = ((offsetT) 1 << (operand->bits - 1)) - 1;
564*3d8817e4Smiod min = - ((offsetT) 1 << (operand->bits - 1));
565*3d8817e4Smiod /* Halve PCREL operands. */
566*3d8817e4Smiod if (operand->flags & S390_OPERAND_PCREL)
567*3d8817e4Smiod val >>= 1;
568*3d8817e4Smiod /* Check for underflow / overflow. */
569*3d8817e4Smiod if (val < min || val > max)
570*3d8817e4Smiod {
571*3d8817e4Smiod const char *err =
572*3d8817e4Smiod "operand out of range (%s not between %ld and %ld)";
573*3d8817e4Smiod char buf[100];
574*3d8817e4Smiod
575*3d8817e4Smiod if (operand->flags & S390_OPERAND_PCREL)
576*3d8817e4Smiod {
577*3d8817e4Smiod val <<= 1;
578*3d8817e4Smiod min <<= 1;
579*3d8817e4Smiod max <<= 1;
580*3d8817e4Smiod }
581*3d8817e4Smiod sprint_value (buf, val);
582*3d8817e4Smiod if (file == (char *) NULL)
583*3d8817e4Smiod as_bad (err, buf, (int) min, (int) max);
584*3d8817e4Smiod else
585*3d8817e4Smiod as_bad_where (file, line, err, buf, (int) min, (int) max);
586*3d8817e4Smiod return;
587*3d8817e4Smiod }
588*3d8817e4Smiod /* val is ok, now restrict it to operand->bits bits. */
589*3d8817e4Smiod uval = (addressT) val & ((((addressT) 1 << (operand->bits-1)) << 1) - 1);
590*3d8817e4Smiod /* val is restrict, now check for special case. */
591*3d8817e4Smiod if (operand->bits == 20 && operand->shift == 20)
592*3d8817e4Smiod uval = (uval >> 12) | ((uval & 0xfff) << 8);
593*3d8817e4Smiod }
594*3d8817e4Smiod else
595*3d8817e4Smiod {
596*3d8817e4Smiod addressT min, max;
597*3d8817e4Smiod
598*3d8817e4Smiod max = (((addressT) 1 << (operand->bits - 1)) << 1) - 1;
599*3d8817e4Smiod min = (offsetT) 0;
600*3d8817e4Smiod uval = (addressT) val;
601*3d8817e4Smiod /* Length x in an instructions has real length x+1. */
602*3d8817e4Smiod if (operand->flags & S390_OPERAND_LENGTH)
603*3d8817e4Smiod uval--;
604*3d8817e4Smiod /* Check for underflow / overflow. */
605*3d8817e4Smiod if (uval < min || uval > max)
606*3d8817e4Smiod {
607*3d8817e4Smiod if (operand->flags & S390_OPERAND_LENGTH)
608*3d8817e4Smiod {
609*3d8817e4Smiod uval++;
610*3d8817e4Smiod min++;
611*3d8817e4Smiod max++;
612*3d8817e4Smiod }
613*3d8817e4Smiod
614*3d8817e4Smiod as_bad_value_out_of_range (_("operand"), uval, (offsetT) min, (offsetT) max, file, line);
615*3d8817e4Smiod
616*3d8817e4Smiod return;
617*3d8817e4Smiod }
618*3d8817e4Smiod }
619*3d8817e4Smiod
620*3d8817e4Smiod /* Insert fragments of the operand byte for byte. */
621*3d8817e4Smiod offset = operand->shift + operand->bits;
622*3d8817e4Smiod uval <<= (-offset) & 7;
623*3d8817e4Smiod insn += (offset - 1) / 8;
624*3d8817e4Smiod while (uval != 0)
625*3d8817e4Smiod {
626*3d8817e4Smiod *insn-- |= uval;
627*3d8817e4Smiod uval >>= 8;
628*3d8817e4Smiod }
629*3d8817e4Smiod }
630*3d8817e4Smiod
631*3d8817e4Smiod struct map_tls
632*3d8817e4Smiod {
633*3d8817e4Smiod char *string;
634*3d8817e4Smiod int length;
635*3d8817e4Smiod bfd_reloc_code_real_type reloc;
636*3d8817e4Smiod };
637*3d8817e4Smiod
638*3d8817e4Smiod static bfd_reloc_code_real_type s390_tls_suffix
639*3d8817e4Smiod PARAMS ((char **, expressionS *));
640*3d8817e4Smiod
641*3d8817e4Smiod /* Parse tls marker and return the desired relocation. */
642*3d8817e4Smiod static bfd_reloc_code_real_type
s390_tls_suffix(str_p,exp_p)643*3d8817e4Smiod s390_tls_suffix (str_p, exp_p)
644*3d8817e4Smiod char **str_p;
645*3d8817e4Smiod expressionS *exp_p;
646*3d8817e4Smiod {
647*3d8817e4Smiod static struct map_tls mapping[] =
648*3d8817e4Smiod {
649*3d8817e4Smiod { "tls_load", 8, BFD_RELOC_390_TLS_LOAD },
650*3d8817e4Smiod { "tls_gdcall", 10, BFD_RELOC_390_TLS_GDCALL },
651*3d8817e4Smiod { "tls_ldcall", 10, BFD_RELOC_390_TLS_LDCALL },
652*3d8817e4Smiod { NULL, 0, BFD_RELOC_UNUSED }
653*3d8817e4Smiod };
654*3d8817e4Smiod struct map_tls *ptr;
655*3d8817e4Smiod char *orig_line;
656*3d8817e4Smiod char *str;
657*3d8817e4Smiod char *ident;
658*3d8817e4Smiod int len;
659*3d8817e4Smiod
660*3d8817e4Smiod str = *str_p;
661*3d8817e4Smiod if (*str++ != ':')
662*3d8817e4Smiod return BFD_RELOC_UNUSED;
663*3d8817e4Smiod
664*3d8817e4Smiod ident = str;
665*3d8817e4Smiod while (ISIDNUM (*str))
666*3d8817e4Smiod str++;
667*3d8817e4Smiod len = str - ident;
668*3d8817e4Smiod if (*str++ != ':')
669*3d8817e4Smiod return BFD_RELOC_UNUSED;
670*3d8817e4Smiod
671*3d8817e4Smiod orig_line = input_line_pointer;
672*3d8817e4Smiod input_line_pointer = str;
673*3d8817e4Smiod expression (exp_p);
674*3d8817e4Smiod str = input_line_pointer;
675*3d8817e4Smiod if (&input_line_pointer != str_p)
676*3d8817e4Smiod input_line_pointer = orig_line;
677*3d8817e4Smiod
678*3d8817e4Smiod if (exp_p->X_op != O_symbol)
679*3d8817e4Smiod return BFD_RELOC_UNUSED;
680*3d8817e4Smiod
681*3d8817e4Smiod for (ptr = &mapping[0]; ptr->length > 0; ptr++)
682*3d8817e4Smiod if (len == ptr->length
683*3d8817e4Smiod && strncasecmp (ident, ptr->string, ptr->length) == 0)
684*3d8817e4Smiod {
685*3d8817e4Smiod /* Found a matching tls suffix. */
686*3d8817e4Smiod *str_p = str;
687*3d8817e4Smiod return ptr->reloc;
688*3d8817e4Smiod }
689*3d8817e4Smiod return BFD_RELOC_UNUSED;
690*3d8817e4Smiod }
691*3d8817e4Smiod
692*3d8817e4Smiod /* Structure used to hold suffixes. */
693*3d8817e4Smiod typedef enum
694*3d8817e4Smiod {
695*3d8817e4Smiod ELF_SUFFIX_NONE = 0,
696*3d8817e4Smiod ELF_SUFFIX_GOT,
697*3d8817e4Smiod ELF_SUFFIX_PLT,
698*3d8817e4Smiod ELF_SUFFIX_GOTENT,
699*3d8817e4Smiod ELF_SUFFIX_GOTOFF,
700*3d8817e4Smiod ELF_SUFFIX_GOTPLT,
701*3d8817e4Smiod ELF_SUFFIX_PLTOFF,
702*3d8817e4Smiod ELF_SUFFIX_TLS_GD,
703*3d8817e4Smiod ELF_SUFFIX_TLS_GOTIE,
704*3d8817e4Smiod ELF_SUFFIX_TLS_IE,
705*3d8817e4Smiod ELF_SUFFIX_TLS_LDM,
706*3d8817e4Smiod ELF_SUFFIX_TLS_LDO,
707*3d8817e4Smiod ELF_SUFFIX_TLS_LE
708*3d8817e4Smiod }
709*3d8817e4Smiod elf_suffix_type;
710*3d8817e4Smiod
711*3d8817e4Smiod struct map_bfd
712*3d8817e4Smiod {
713*3d8817e4Smiod char *string;
714*3d8817e4Smiod int length;
715*3d8817e4Smiod elf_suffix_type suffix;
716*3d8817e4Smiod };
717*3d8817e4Smiod
718*3d8817e4Smiod static elf_suffix_type s390_elf_suffix PARAMS ((char **, expressionS *));
719*3d8817e4Smiod static int s390_exp_compare PARAMS ((expressionS *exp1, expressionS *exp2));
720*3d8817e4Smiod static elf_suffix_type s390_lit_suffix
721*3d8817e4Smiod PARAMS ((char **, expressionS *, elf_suffix_type));
722*3d8817e4Smiod
723*3d8817e4Smiod
724*3d8817e4Smiod /* Parse @got/@plt/@gotoff. and return the desired relocation. */
725*3d8817e4Smiod static elf_suffix_type
s390_elf_suffix(str_p,exp_p)726*3d8817e4Smiod s390_elf_suffix (str_p, exp_p)
727*3d8817e4Smiod char **str_p;
728*3d8817e4Smiod expressionS *exp_p;
729*3d8817e4Smiod {
730*3d8817e4Smiod static struct map_bfd mapping[] =
731*3d8817e4Smiod {
732*3d8817e4Smiod { "got", 3, ELF_SUFFIX_GOT },
733*3d8817e4Smiod { "got12", 5, ELF_SUFFIX_GOT },
734*3d8817e4Smiod { "plt", 3, ELF_SUFFIX_PLT },
735*3d8817e4Smiod { "gotent", 6, ELF_SUFFIX_GOTENT },
736*3d8817e4Smiod { "gotoff", 6, ELF_SUFFIX_GOTOFF },
737*3d8817e4Smiod { "gotplt", 6, ELF_SUFFIX_GOTPLT },
738*3d8817e4Smiod { "pltoff", 6, ELF_SUFFIX_PLTOFF },
739*3d8817e4Smiod { "tlsgd", 5, ELF_SUFFIX_TLS_GD },
740*3d8817e4Smiod { "gotntpoff", 9, ELF_SUFFIX_TLS_GOTIE },
741*3d8817e4Smiod { "indntpoff", 9, ELF_SUFFIX_TLS_IE },
742*3d8817e4Smiod { "tlsldm", 6, ELF_SUFFIX_TLS_LDM },
743*3d8817e4Smiod { "dtpoff", 6, ELF_SUFFIX_TLS_LDO },
744*3d8817e4Smiod { "ntpoff", 6, ELF_SUFFIX_TLS_LE },
745*3d8817e4Smiod { NULL, 0, ELF_SUFFIX_NONE }
746*3d8817e4Smiod };
747*3d8817e4Smiod
748*3d8817e4Smiod struct map_bfd *ptr;
749*3d8817e4Smiod char *str = *str_p;
750*3d8817e4Smiod char *ident;
751*3d8817e4Smiod int len;
752*3d8817e4Smiod
753*3d8817e4Smiod if (*str++ != '@')
754*3d8817e4Smiod return ELF_SUFFIX_NONE;
755*3d8817e4Smiod
756*3d8817e4Smiod ident = str;
757*3d8817e4Smiod while (ISALNUM (*str))
758*3d8817e4Smiod str++;
759*3d8817e4Smiod len = str - ident;
760*3d8817e4Smiod
761*3d8817e4Smiod for (ptr = &mapping[0]; ptr->length > 0; ptr++)
762*3d8817e4Smiod if (len == ptr->length
763*3d8817e4Smiod && strncasecmp (ident, ptr->string, ptr->length) == 0)
764*3d8817e4Smiod {
765*3d8817e4Smiod if (exp_p->X_add_number != 0)
766*3d8817e4Smiod as_warn (_("identifier+constant@%s means identifier@%s+constant"),
767*3d8817e4Smiod ptr->string, ptr->string);
768*3d8817e4Smiod /* Now check for identifier@suffix+constant. */
769*3d8817e4Smiod if (*str == '-' || *str == '+')
770*3d8817e4Smiod {
771*3d8817e4Smiod char *orig_line = input_line_pointer;
772*3d8817e4Smiod expressionS new_exp;
773*3d8817e4Smiod
774*3d8817e4Smiod input_line_pointer = str;
775*3d8817e4Smiod expression (&new_exp);
776*3d8817e4Smiod
777*3d8817e4Smiod switch (new_exp.X_op)
778*3d8817e4Smiod {
779*3d8817e4Smiod case O_constant: /* X_add_number (a constant expression). */
780*3d8817e4Smiod exp_p->X_add_number += new_exp.X_add_number;
781*3d8817e4Smiod str = input_line_pointer;
782*3d8817e4Smiod break;
783*3d8817e4Smiod case O_symbol: /* X_add_symbol + X_add_number. */
784*3d8817e4Smiod /* this case is used for e.g. xyz@PLT+.Label. */
785*3d8817e4Smiod exp_p->X_add_number += new_exp.X_add_number;
786*3d8817e4Smiod exp_p->X_op_symbol = new_exp.X_add_symbol;
787*3d8817e4Smiod exp_p->X_op = O_add;
788*3d8817e4Smiod str = input_line_pointer;
789*3d8817e4Smiod break;
790*3d8817e4Smiod case O_uminus: /* (- X_add_symbol) + X_add_number. */
791*3d8817e4Smiod /* this case is used for e.g. xyz@PLT-.Label. */
792*3d8817e4Smiod exp_p->X_add_number += new_exp.X_add_number;
793*3d8817e4Smiod exp_p->X_op_symbol = new_exp.X_add_symbol;
794*3d8817e4Smiod exp_p->X_op = O_subtract;
795*3d8817e4Smiod str = input_line_pointer;
796*3d8817e4Smiod break;
797*3d8817e4Smiod default:
798*3d8817e4Smiod break;
799*3d8817e4Smiod }
800*3d8817e4Smiod
801*3d8817e4Smiod /* If s390_elf_suffix has not been called with
802*3d8817e4Smiod &input_line_pointer as first parameter, we have
803*3d8817e4Smiod clobbered the input_line_pointer. We have to
804*3d8817e4Smiod undo that. */
805*3d8817e4Smiod if (&input_line_pointer != str_p)
806*3d8817e4Smiod input_line_pointer = orig_line;
807*3d8817e4Smiod }
808*3d8817e4Smiod *str_p = str;
809*3d8817e4Smiod return ptr->suffix;
810*3d8817e4Smiod }
811*3d8817e4Smiod
812*3d8817e4Smiod return BFD_RELOC_UNUSED;
813*3d8817e4Smiod }
814*3d8817e4Smiod
815*3d8817e4Smiod /* Structure used to hold a literal pool entry. */
816*3d8817e4Smiod struct s390_lpe
817*3d8817e4Smiod {
818*3d8817e4Smiod struct s390_lpe *next;
819*3d8817e4Smiod expressionS ex;
820*3d8817e4Smiod FLONUM_TYPE floatnum; /* used if X_op == O_big && X_add_number <= 0 */
821*3d8817e4Smiod LITTLENUM_TYPE bignum[4]; /* used if X_op == O_big && X_add_number > 0 */
822*3d8817e4Smiod int nbytes;
823*3d8817e4Smiod bfd_reloc_code_real_type reloc;
824*3d8817e4Smiod symbolS *sym;
825*3d8817e4Smiod };
826*3d8817e4Smiod
827*3d8817e4Smiod static struct s390_lpe *lpe_free_list = NULL;
828*3d8817e4Smiod static struct s390_lpe *lpe_list = NULL;
829*3d8817e4Smiod static struct s390_lpe *lpe_list_tail = NULL;
830*3d8817e4Smiod static symbolS *lp_sym = NULL;
831*3d8817e4Smiod static int lp_count = 0;
832*3d8817e4Smiod static int lpe_count = 0;
833*3d8817e4Smiod
834*3d8817e4Smiod static int
s390_exp_compare(exp1,exp2)835*3d8817e4Smiod s390_exp_compare (exp1, exp2)
836*3d8817e4Smiod expressionS *exp1;
837*3d8817e4Smiod expressionS *exp2;
838*3d8817e4Smiod {
839*3d8817e4Smiod if (exp1->X_op != exp2->X_op)
840*3d8817e4Smiod return 0;
841*3d8817e4Smiod
842*3d8817e4Smiod switch (exp1->X_op)
843*3d8817e4Smiod {
844*3d8817e4Smiod case O_constant: /* X_add_number must be equal. */
845*3d8817e4Smiod case O_register:
846*3d8817e4Smiod return exp1->X_add_number == exp2->X_add_number;
847*3d8817e4Smiod
848*3d8817e4Smiod case O_big:
849*3d8817e4Smiod as_bad (_("Can't handle O_big in s390_exp_compare"));
850*3d8817e4Smiod
851*3d8817e4Smiod case O_symbol: /* X_add_symbol & X_add_number must be equal. */
852*3d8817e4Smiod case O_symbol_rva:
853*3d8817e4Smiod case O_uminus:
854*3d8817e4Smiod case O_bit_not:
855*3d8817e4Smiod case O_logical_not:
856*3d8817e4Smiod return (exp1->X_add_symbol == exp2->X_add_symbol)
857*3d8817e4Smiod && (exp1->X_add_number == exp2->X_add_number);
858*3d8817e4Smiod
859*3d8817e4Smiod case O_multiply: /* X_add_symbol,X_op_symbol&X_add_number must be equal. */
860*3d8817e4Smiod case O_divide:
861*3d8817e4Smiod case O_modulus:
862*3d8817e4Smiod case O_left_shift:
863*3d8817e4Smiod case O_right_shift:
864*3d8817e4Smiod case O_bit_inclusive_or:
865*3d8817e4Smiod case O_bit_or_not:
866*3d8817e4Smiod case O_bit_exclusive_or:
867*3d8817e4Smiod case O_bit_and:
868*3d8817e4Smiod case O_add:
869*3d8817e4Smiod case O_subtract:
870*3d8817e4Smiod case O_eq:
871*3d8817e4Smiod case O_ne:
872*3d8817e4Smiod case O_lt:
873*3d8817e4Smiod case O_le:
874*3d8817e4Smiod case O_ge:
875*3d8817e4Smiod case O_gt:
876*3d8817e4Smiod case O_logical_and:
877*3d8817e4Smiod case O_logical_or:
878*3d8817e4Smiod return (exp1->X_add_symbol == exp2->X_add_symbol)
879*3d8817e4Smiod && (exp1->X_op_symbol == exp2->X_op_symbol)
880*3d8817e4Smiod && (exp1->X_add_number == exp2->X_add_number);
881*3d8817e4Smiod default:
882*3d8817e4Smiod return 0;
883*3d8817e4Smiod }
884*3d8817e4Smiod }
885*3d8817e4Smiod
886*3d8817e4Smiod /* Test for @lit and if its present make an entry in the literal pool and
887*3d8817e4Smiod modify the current expression to be an offset into the literal pool. */
888*3d8817e4Smiod static elf_suffix_type
s390_lit_suffix(str_p,exp_p,suffix)889*3d8817e4Smiod s390_lit_suffix (str_p, exp_p, suffix)
890*3d8817e4Smiod char **str_p;
891*3d8817e4Smiod expressionS *exp_p;
892*3d8817e4Smiod elf_suffix_type suffix;
893*3d8817e4Smiod {
894*3d8817e4Smiod bfd_reloc_code_real_type reloc;
895*3d8817e4Smiod char tmp_name[64];
896*3d8817e4Smiod char *str = *str_p;
897*3d8817e4Smiod char *ident;
898*3d8817e4Smiod struct s390_lpe *lpe;
899*3d8817e4Smiod int nbytes, len;
900*3d8817e4Smiod
901*3d8817e4Smiod if (*str++ != ':')
902*3d8817e4Smiod return suffix; /* No modification. */
903*3d8817e4Smiod
904*3d8817e4Smiod /* We look for a suffix of the form "@lit1", "@lit2", "@lit4" or "@lit8". */
905*3d8817e4Smiod ident = str;
906*3d8817e4Smiod while (ISALNUM (*str))
907*3d8817e4Smiod str++;
908*3d8817e4Smiod len = str - ident;
909*3d8817e4Smiod if (len != 4 || strncasecmp (ident, "lit", 3) != 0
910*3d8817e4Smiod || (ident[3]!='1' && ident[3]!='2' && ident[3]!='4' && ident[3]!='8'))
911*3d8817e4Smiod return suffix; /* no modification */
912*3d8817e4Smiod nbytes = ident[3] - '0';
913*3d8817e4Smiod
914*3d8817e4Smiod reloc = BFD_RELOC_UNUSED;
915*3d8817e4Smiod if (suffix == ELF_SUFFIX_GOT)
916*3d8817e4Smiod {
917*3d8817e4Smiod if (nbytes == 2)
918*3d8817e4Smiod reloc = BFD_RELOC_390_GOT16;
919*3d8817e4Smiod else if (nbytes == 4)
920*3d8817e4Smiod reloc = BFD_RELOC_32_GOT_PCREL;
921*3d8817e4Smiod else if (nbytes == 8)
922*3d8817e4Smiod reloc = BFD_RELOC_390_GOT64;
923*3d8817e4Smiod }
924*3d8817e4Smiod else if (suffix == ELF_SUFFIX_PLT)
925*3d8817e4Smiod {
926*3d8817e4Smiod if (nbytes == 4)
927*3d8817e4Smiod reloc = BFD_RELOC_390_PLT32;
928*3d8817e4Smiod else if (nbytes == 8)
929*3d8817e4Smiod reloc = BFD_RELOC_390_PLT64;
930*3d8817e4Smiod }
931*3d8817e4Smiod
932*3d8817e4Smiod if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
933*3d8817e4Smiod as_bad (_("Invalid suffix for literal pool entry"));
934*3d8817e4Smiod
935*3d8817e4Smiod /* Search the pool if the new entry is a duplicate. */
936*3d8817e4Smiod if (exp_p->X_op == O_big)
937*3d8817e4Smiod {
938*3d8817e4Smiod /* Special processing for big numbers. */
939*3d8817e4Smiod for (lpe = lpe_list; lpe != NULL; lpe = lpe->next)
940*3d8817e4Smiod {
941*3d8817e4Smiod if (lpe->ex.X_op == O_big)
942*3d8817e4Smiod {
943*3d8817e4Smiod if (exp_p->X_add_number <= 0 && lpe->ex.X_add_number <= 0)
944*3d8817e4Smiod {
945*3d8817e4Smiod if (memcmp (&generic_floating_point_number, &lpe->floatnum,
946*3d8817e4Smiod sizeof (FLONUM_TYPE)) == 0)
947*3d8817e4Smiod break;
948*3d8817e4Smiod }
949*3d8817e4Smiod else if (exp_p->X_add_number == lpe->ex.X_add_number)
950*3d8817e4Smiod {
951*3d8817e4Smiod if (memcmp (generic_bignum, lpe->bignum,
952*3d8817e4Smiod sizeof (LITTLENUM_TYPE)*exp_p->X_add_number) == 0)
953*3d8817e4Smiod break;
954*3d8817e4Smiod }
955*3d8817e4Smiod }
956*3d8817e4Smiod }
957*3d8817e4Smiod }
958*3d8817e4Smiod else
959*3d8817e4Smiod {
960*3d8817e4Smiod /* Processing for 'normal' data types. */
961*3d8817e4Smiod for (lpe = lpe_list; lpe != NULL; lpe = lpe->next)
962*3d8817e4Smiod if (lpe->nbytes == nbytes && lpe->reloc == reloc
963*3d8817e4Smiod && s390_exp_compare (exp_p, &lpe->ex) != 0)
964*3d8817e4Smiod break;
965*3d8817e4Smiod }
966*3d8817e4Smiod
967*3d8817e4Smiod if (lpe == NULL)
968*3d8817e4Smiod {
969*3d8817e4Smiod /* A new literal. */
970*3d8817e4Smiod if (lpe_free_list != NULL)
971*3d8817e4Smiod {
972*3d8817e4Smiod lpe = lpe_free_list;
973*3d8817e4Smiod lpe_free_list = lpe_free_list->next;
974*3d8817e4Smiod }
975*3d8817e4Smiod else
976*3d8817e4Smiod {
977*3d8817e4Smiod lpe = (struct s390_lpe *) xmalloc (sizeof (struct s390_lpe));
978*3d8817e4Smiod }
979*3d8817e4Smiod
980*3d8817e4Smiod lpe->ex = *exp_p;
981*3d8817e4Smiod
982*3d8817e4Smiod if (exp_p->X_op == O_big)
983*3d8817e4Smiod {
984*3d8817e4Smiod if (exp_p->X_add_number <= 0)
985*3d8817e4Smiod lpe->floatnum = generic_floating_point_number;
986*3d8817e4Smiod else if (exp_p->X_add_number <= 4)
987*3d8817e4Smiod memcpy (lpe->bignum, generic_bignum,
988*3d8817e4Smiod exp_p->X_add_number * sizeof (LITTLENUM_TYPE));
989*3d8817e4Smiod else
990*3d8817e4Smiod as_bad (_("Big number is too big"));
991*3d8817e4Smiod }
992*3d8817e4Smiod
993*3d8817e4Smiod lpe->nbytes = nbytes;
994*3d8817e4Smiod lpe->reloc = reloc;
995*3d8817e4Smiod /* Literal pool name defined ? */
996*3d8817e4Smiod if (lp_sym == NULL)
997*3d8817e4Smiod {
998*3d8817e4Smiod sprintf (tmp_name, ".L\001%i", lp_count);
999*3d8817e4Smiod lp_sym = symbol_make (tmp_name);
1000*3d8817e4Smiod }
1001*3d8817e4Smiod
1002*3d8817e4Smiod /* Make name for literal pool entry. */
1003*3d8817e4Smiod sprintf (tmp_name, ".L\001%i\002%i", lp_count, lpe_count);
1004*3d8817e4Smiod lpe_count++;
1005*3d8817e4Smiod lpe->sym = symbol_make (tmp_name);
1006*3d8817e4Smiod
1007*3d8817e4Smiod /* Add to literal pool list. */
1008*3d8817e4Smiod lpe->next = NULL;
1009*3d8817e4Smiod if (lpe_list_tail != NULL)
1010*3d8817e4Smiod {
1011*3d8817e4Smiod lpe_list_tail->next = lpe;
1012*3d8817e4Smiod lpe_list_tail = lpe;
1013*3d8817e4Smiod }
1014*3d8817e4Smiod else
1015*3d8817e4Smiod lpe_list = lpe_list_tail = lpe;
1016*3d8817e4Smiod }
1017*3d8817e4Smiod
1018*3d8817e4Smiod /* Now change exp_p to the offset into the literal pool.
1019*3d8817e4Smiod Thats the expression: .L^Ax^By-.L^Ax */
1020*3d8817e4Smiod exp_p->X_add_symbol = lpe->sym;
1021*3d8817e4Smiod exp_p->X_op_symbol = lp_sym;
1022*3d8817e4Smiod exp_p->X_op = O_subtract;
1023*3d8817e4Smiod exp_p->X_add_number = 0;
1024*3d8817e4Smiod
1025*3d8817e4Smiod *str_p = str;
1026*3d8817e4Smiod
1027*3d8817e4Smiod /* We change the suffix type to ELF_SUFFIX_NONE, because
1028*3d8817e4Smiod the difference of two local labels is just a number. */
1029*3d8817e4Smiod return ELF_SUFFIX_NONE;
1030*3d8817e4Smiod }
1031*3d8817e4Smiod
1032*3d8817e4Smiod /* Like normal .long/.short/.word, except support @got, etc.
1033*3d8817e4Smiod clobbers input_line_pointer, checks end-of-line. */
1034*3d8817e4Smiod static void
s390_elf_cons(nbytes)1035*3d8817e4Smiod s390_elf_cons (nbytes)
1036*3d8817e4Smiod register int nbytes; /* 1=.byte, 2=.word, 4=.long */
1037*3d8817e4Smiod {
1038*3d8817e4Smiod expressionS exp;
1039*3d8817e4Smiod elf_suffix_type suffix;
1040*3d8817e4Smiod
1041*3d8817e4Smiod if (is_it_end_of_statement ())
1042*3d8817e4Smiod {
1043*3d8817e4Smiod demand_empty_rest_of_line ();
1044*3d8817e4Smiod return;
1045*3d8817e4Smiod }
1046*3d8817e4Smiod
1047*3d8817e4Smiod do
1048*3d8817e4Smiod {
1049*3d8817e4Smiod expression (&exp);
1050*3d8817e4Smiod
1051*3d8817e4Smiod if (exp.X_op == O_symbol
1052*3d8817e4Smiod && *input_line_pointer == '@'
1053*3d8817e4Smiod && (suffix = s390_elf_suffix (&input_line_pointer, &exp)) != ELF_SUFFIX_NONE)
1054*3d8817e4Smiod {
1055*3d8817e4Smiod bfd_reloc_code_real_type reloc;
1056*3d8817e4Smiod reloc_howto_type *reloc_howto;
1057*3d8817e4Smiod int size;
1058*3d8817e4Smiod char *where;
1059*3d8817e4Smiod
1060*3d8817e4Smiod if (nbytes == 2)
1061*3d8817e4Smiod {
1062*3d8817e4Smiod static bfd_reloc_code_real_type tab2[] =
1063*3d8817e4Smiod {
1064*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
1065*3d8817e4Smiod BFD_RELOC_390_GOT16, /* ELF_SUFFIX_GOT */
1066*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_PLT */
1067*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
1068*3d8817e4Smiod BFD_RELOC_16_GOTOFF, /* ELF_SUFFIX_GOTOFF */
1069*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTPLT */
1070*3d8817e4Smiod BFD_RELOC_390_PLTOFF16, /* ELF_SUFFIX_PLTOFF */
1071*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_GD */
1072*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_GOTIE */
1073*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_IE */
1074*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_LDM */
1075*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_TLS_LDO */
1076*3d8817e4Smiod BFD_RELOC_UNUSED /* ELF_SUFFIX_TLS_LE */
1077*3d8817e4Smiod };
1078*3d8817e4Smiod reloc = tab2[suffix];
1079*3d8817e4Smiod }
1080*3d8817e4Smiod else if (nbytes == 4)
1081*3d8817e4Smiod {
1082*3d8817e4Smiod static bfd_reloc_code_real_type tab4[] =
1083*3d8817e4Smiod {
1084*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
1085*3d8817e4Smiod BFD_RELOC_32_GOT_PCREL, /* ELF_SUFFIX_GOT */
1086*3d8817e4Smiod BFD_RELOC_390_PLT32, /* ELF_SUFFIX_PLT */
1087*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
1088*3d8817e4Smiod BFD_RELOC_32_GOTOFF, /* ELF_SUFFIX_GOTOFF */
1089*3d8817e4Smiod BFD_RELOC_390_GOTPLT32, /* ELF_SUFFIX_GOTPLT */
1090*3d8817e4Smiod BFD_RELOC_390_PLTOFF32, /* ELF_SUFFIX_PLTOFF */
1091*3d8817e4Smiod BFD_RELOC_390_TLS_GD32, /* ELF_SUFFIX_TLS_GD */
1092*3d8817e4Smiod BFD_RELOC_390_TLS_GOTIE32, /* ELF_SUFFIX_TLS_GOTIE */
1093*3d8817e4Smiod BFD_RELOC_390_TLS_IE32, /* ELF_SUFFIX_TLS_IE */
1094*3d8817e4Smiod BFD_RELOC_390_TLS_LDM32, /* ELF_SUFFIX_TLS_LDM */
1095*3d8817e4Smiod BFD_RELOC_390_TLS_LDO32, /* ELF_SUFFIX_TLS_LDO */
1096*3d8817e4Smiod BFD_RELOC_390_TLS_LE32 /* ELF_SUFFIX_TLS_LE */
1097*3d8817e4Smiod };
1098*3d8817e4Smiod reloc = tab4[suffix];
1099*3d8817e4Smiod }
1100*3d8817e4Smiod else if (nbytes == 8)
1101*3d8817e4Smiod {
1102*3d8817e4Smiod static bfd_reloc_code_real_type tab8[] =
1103*3d8817e4Smiod {
1104*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_NONE */
1105*3d8817e4Smiod BFD_RELOC_390_GOT64, /* ELF_SUFFIX_GOT */
1106*3d8817e4Smiod BFD_RELOC_390_PLT64, /* ELF_SUFFIX_PLT */
1107*3d8817e4Smiod BFD_RELOC_UNUSED, /* ELF_SUFFIX_GOTENT */
1108*3d8817e4Smiod BFD_RELOC_390_GOTOFF64, /* ELF_SUFFIX_GOTOFF */
1109*3d8817e4Smiod BFD_RELOC_390_GOTPLT64, /* ELF_SUFFIX_GOTPLT */
1110*3d8817e4Smiod BFD_RELOC_390_PLTOFF64, /* ELF_SUFFIX_PLTOFF */
1111*3d8817e4Smiod BFD_RELOC_390_TLS_GD64, /* ELF_SUFFIX_TLS_GD */
1112*3d8817e4Smiod BFD_RELOC_390_TLS_GOTIE64, /* ELF_SUFFIX_TLS_GOTIE */
1113*3d8817e4Smiod BFD_RELOC_390_TLS_IE64, /* ELF_SUFFIX_TLS_IE */
1114*3d8817e4Smiod BFD_RELOC_390_TLS_LDM64, /* ELF_SUFFIX_TLS_LDM */
1115*3d8817e4Smiod BFD_RELOC_390_TLS_LDO64, /* ELF_SUFFIX_TLS_LDO */
1116*3d8817e4Smiod BFD_RELOC_390_TLS_LE64 /* ELF_SUFFIX_TLS_LE */
1117*3d8817e4Smiod };
1118*3d8817e4Smiod reloc = tab8[suffix];
1119*3d8817e4Smiod }
1120*3d8817e4Smiod else
1121*3d8817e4Smiod reloc = BFD_RELOC_UNUSED;
1122*3d8817e4Smiod
1123*3d8817e4Smiod if (reloc != BFD_RELOC_UNUSED
1124*3d8817e4Smiod && (reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc)))
1125*3d8817e4Smiod {
1126*3d8817e4Smiod size = bfd_get_reloc_size (reloc_howto);
1127*3d8817e4Smiod if (size > nbytes)
1128*3d8817e4Smiod as_bad (_("%s relocations do not fit in %d bytes"),
1129*3d8817e4Smiod reloc_howto->name, nbytes);
1130*3d8817e4Smiod where = frag_more (nbytes);
1131*3d8817e4Smiod md_number_to_chars (where, 0, size);
1132*3d8817e4Smiod /* To make fixup_segment do the pc relative conversion the
1133*3d8817e4Smiod pcrel parameter on the fix_new_exp call needs to be FALSE. */
1134*3d8817e4Smiod fix_new_exp (frag_now, where - frag_now->fr_literal,
1135*3d8817e4Smiod size, &exp, FALSE, reloc);
1136*3d8817e4Smiod }
1137*3d8817e4Smiod else
1138*3d8817e4Smiod as_bad (_("relocation not applicable"));
1139*3d8817e4Smiod }
1140*3d8817e4Smiod else
1141*3d8817e4Smiod emit_expr (&exp, (unsigned int) nbytes);
1142*3d8817e4Smiod }
1143*3d8817e4Smiod while (*input_line_pointer++ == ',');
1144*3d8817e4Smiod
1145*3d8817e4Smiod input_line_pointer--; /* Put terminator back into stream. */
1146*3d8817e4Smiod demand_empty_rest_of_line ();
1147*3d8817e4Smiod }
1148*3d8817e4Smiod
1149*3d8817e4Smiod /* We need to keep a list of fixups. We can't simply generate them as
1150*3d8817e4Smiod we go, because that would require us to first create the frag, and
1151*3d8817e4Smiod that would screw up references to ``.''. */
1152*3d8817e4Smiod
1153*3d8817e4Smiod struct s390_fixup
1154*3d8817e4Smiod {
1155*3d8817e4Smiod expressionS exp;
1156*3d8817e4Smiod int opindex;
1157*3d8817e4Smiod bfd_reloc_code_real_type reloc;
1158*3d8817e4Smiod };
1159*3d8817e4Smiod
1160*3d8817e4Smiod #define MAX_INSN_FIXUPS (4)
1161*3d8817e4Smiod
1162*3d8817e4Smiod /* This routine is called for each instruction to be assembled. */
1163*3d8817e4Smiod
1164*3d8817e4Smiod static char *
md_gather_operands(str,insn,opcode)1165*3d8817e4Smiod md_gather_operands (str, insn, opcode)
1166*3d8817e4Smiod char *str;
1167*3d8817e4Smiod unsigned char *insn;
1168*3d8817e4Smiod const struct s390_opcode *opcode;
1169*3d8817e4Smiod {
1170*3d8817e4Smiod struct s390_fixup fixups[MAX_INSN_FIXUPS];
1171*3d8817e4Smiod const struct s390_operand *operand;
1172*3d8817e4Smiod const unsigned char *opindex_ptr;
1173*3d8817e4Smiod expressionS ex;
1174*3d8817e4Smiod elf_suffix_type suffix;
1175*3d8817e4Smiod bfd_reloc_code_real_type reloc;
1176*3d8817e4Smiod int skip_optional;
1177*3d8817e4Smiod int parentheses;
1178*3d8817e4Smiod char *f;
1179*3d8817e4Smiod int fc, i;
1180*3d8817e4Smiod
1181*3d8817e4Smiod while (ISSPACE (*str))
1182*3d8817e4Smiod str++;
1183*3d8817e4Smiod
1184*3d8817e4Smiod parentheses = 0;
1185*3d8817e4Smiod skip_optional = 0;
1186*3d8817e4Smiod
1187*3d8817e4Smiod /* Gather the operands. */
1188*3d8817e4Smiod fc = 0;
1189*3d8817e4Smiod for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
1190*3d8817e4Smiod {
1191*3d8817e4Smiod char *hold;
1192*3d8817e4Smiod
1193*3d8817e4Smiod operand = s390_operands + *opindex_ptr;
1194*3d8817e4Smiod
1195*3d8817e4Smiod if (skip_optional && (operand->flags & S390_OPERAND_INDEX))
1196*3d8817e4Smiod {
1197*3d8817e4Smiod /* We do an early skip. For D(X,B) constructions the index
1198*3d8817e4Smiod register is skipped (X is optional). For D(L,B) the base
1199*3d8817e4Smiod register will be the skipped operand, because L is NOT
1200*3d8817e4Smiod optional. */
1201*3d8817e4Smiod skip_optional = 0;
1202*3d8817e4Smiod continue;
1203*3d8817e4Smiod }
1204*3d8817e4Smiod
1205*3d8817e4Smiod /* Gather the operand. */
1206*3d8817e4Smiod hold = input_line_pointer;
1207*3d8817e4Smiod input_line_pointer = str;
1208*3d8817e4Smiod
1209*3d8817e4Smiod /* Parse the operand. */
1210*3d8817e4Smiod if (! register_name (&ex))
1211*3d8817e4Smiod expression (&ex);
1212*3d8817e4Smiod
1213*3d8817e4Smiod str = input_line_pointer;
1214*3d8817e4Smiod input_line_pointer = hold;
1215*3d8817e4Smiod
1216*3d8817e4Smiod /* Write the operand to the insn. */
1217*3d8817e4Smiod if (ex.X_op == O_illegal)
1218*3d8817e4Smiod as_bad (_("illegal operand"));
1219*3d8817e4Smiod else if (ex.X_op == O_absent)
1220*3d8817e4Smiod as_bad (_("missing operand"));
1221*3d8817e4Smiod else if (ex.X_op == O_register || ex.X_op == O_constant)
1222*3d8817e4Smiod {
1223*3d8817e4Smiod s390_lit_suffix (&str, &ex, ELF_SUFFIX_NONE);
1224*3d8817e4Smiod
1225*3d8817e4Smiod if (ex.X_op != O_register && ex.X_op != O_constant)
1226*3d8817e4Smiod {
1227*3d8817e4Smiod /* We need to generate a fixup for the
1228*3d8817e4Smiod expression returned by s390_lit_suffix. */
1229*3d8817e4Smiod if (fc >= MAX_INSN_FIXUPS)
1230*3d8817e4Smiod as_fatal (_("too many fixups"));
1231*3d8817e4Smiod fixups[fc].exp = ex;
1232*3d8817e4Smiod fixups[fc].opindex = *opindex_ptr;
1233*3d8817e4Smiod fixups[fc].reloc = BFD_RELOC_UNUSED;
1234*3d8817e4Smiod ++fc;
1235*3d8817e4Smiod }
1236*3d8817e4Smiod else
1237*3d8817e4Smiod {
1238*3d8817e4Smiod if ((operand->flags & S390_OPERAND_INDEX)
1239*3d8817e4Smiod && ex.X_add_number == 0
1240*3d8817e4Smiod && warn_areg_zero)
1241*3d8817e4Smiod as_warn ("index register specified but zero");
1242*3d8817e4Smiod if ((operand->flags & S390_OPERAND_BASE)
1243*3d8817e4Smiod && ex.X_add_number == 0
1244*3d8817e4Smiod && warn_areg_zero)
1245*3d8817e4Smiod as_warn ("base register specified but zero");
1246*3d8817e4Smiod s390_insert_operand (insn, operand, ex.X_add_number, NULL, 0);
1247*3d8817e4Smiod }
1248*3d8817e4Smiod }
1249*3d8817e4Smiod else
1250*3d8817e4Smiod {
1251*3d8817e4Smiod suffix = s390_elf_suffix (&str, &ex);
1252*3d8817e4Smiod suffix = s390_lit_suffix (&str, &ex, suffix);
1253*3d8817e4Smiod reloc = BFD_RELOC_UNUSED;
1254*3d8817e4Smiod
1255*3d8817e4Smiod if (suffix == ELF_SUFFIX_GOT)
1256*3d8817e4Smiod {
1257*3d8817e4Smiod if ((operand->flags & S390_OPERAND_DISP) &&
1258*3d8817e4Smiod (operand->bits == 12))
1259*3d8817e4Smiod reloc = BFD_RELOC_390_GOT12;
1260*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_DISP) &&
1261*3d8817e4Smiod (operand->bits == 20))
1262*3d8817e4Smiod reloc = BFD_RELOC_390_GOT20;
1263*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_SIGNED)
1264*3d8817e4Smiod && (operand->bits == 16))
1265*3d8817e4Smiod reloc = BFD_RELOC_390_GOT16;
1266*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_PCREL)
1267*3d8817e4Smiod && (operand->bits == 32))
1268*3d8817e4Smiod reloc = BFD_RELOC_390_GOTENT;
1269*3d8817e4Smiod }
1270*3d8817e4Smiod else if (suffix == ELF_SUFFIX_PLT)
1271*3d8817e4Smiod {
1272*3d8817e4Smiod if ((operand->flags & S390_OPERAND_PCREL)
1273*3d8817e4Smiod && (operand->bits == 16))
1274*3d8817e4Smiod reloc = BFD_RELOC_390_PLT16DBL;
1275*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_PCREL)
1276*3d8817e4Smiod && (operand->bits == 32))
1277*3d8817e4Smiod reloc = BFD_RELOC_390_PLT32DBL;
1278*3d8817e4Smiod }
1279*3d8817e4Smiod else if (suffix == ELF_SUFFIX_GOTENT)
1280*3d8817e4Smiod {
1281*3d8817e4Smiod if ((operand->flags & S390_OPERAND_PCREL)
1282*3d8817e4Smiod && (operand->bits == 32))
1283*3d8817e4Smiod reloc = BFD_RELOC_390_GOTENT;
1284*3d8817e4Smiod }
1285*3d8817e4Smiod else if (suffix == ELF_SUFFIX_GOTOFF)
1286*3d8817e4Smiod {
1287*3d8817e4Smiod if ((operand->flags & S390_OPERAND_SIGNED)
1288*3d8817e4Smiod && (operand->bits == 16))
1289*3d8817e4Smiod reloc = BFD_RELOC_16_GOTOFF;
1290*3d8817e4Smiod }
1291*3d8817e4Smiod else if (suffix == ELF_SUFFIX_PLTOFF)
1292*3d8817e4Smiod {
1293*3d8817e4Smiod if ((operand->flags & S390_OPERAND_SIGNED)
1294*3d8817e4Smiod && (operand->bits == 16))
1295*3d8817e4Smiod reloc = BFD_RELOC_390_PLTOFF16;
1296*3d8817e4Smiod }
1297*3d8817e4Smiod else if (suffix == ELF_SUFFIX_GOTPLT)
1298*3d8817e4Smiod {
1299*3d8817e4Smiod if ((operand->flags & S390_OPERAND_DISP)
1300*3d8817e4Smiod && (operand->bits == 12))
1301*3d8817e4Smiod reloc = BFD_RELOC_390_GOTPLT12;
1302*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_SIGNED)
1303*3d8817e4Smiod && (operand->bits == 16))
1304*3d8817e4Smiod reloc = BFD_RELOC_390_GOTPLT16;
1305*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_PCREL)
1306*3d8817e4Smiod && (operand->bits == 32))
1307*3d8817e4Smiod reloc = BFD_RELOC_390_GOTPLTENT;
1308*3d8817e4Smiod }
1309*3d8817e4Smiod else if (suffix == ELF_SUFFIX_TLS_GOTIE)
1310*3d8817e4Smiod {
1311*3d8817e4Smiod if ((operand->flags & S390_OPERAND_DISP)
1312*3d8817e4Smiod && (operand->bits == 12))
1313*3d8817e4Smiod reloc = BFD_RELOC_390_TLS_GOTIE12;
1314*3d8817e4Smiod else if ((operand->flags & S390_OPERAND_DISP)
1315*3d8817e4Smiod && (operand->bits == 20))
1316*3d8817e4Smiod reloc = BFD_RELOC_390_TLS_GOTIE20;
1317*3d8817e4Smiod }
1318*3d8817e4Smiod else if (suffix == ELF_SUFFIX_TLS_IE)
1319*3d8817e4Smiod {
1320*3d8817e4Smiod if ((operand->flags & S390_OPERAND_PCREL)
1321*3d8817e4Smiod && (operand->bits == 32))
1322*3d8817e4Smiod reloc = BFD_RELOC_390_TLS_IEENT;
1323*3d8817e4Smiod }
1324*3d8817e4Smiod
1325*3d8817e4Smiod if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED)
1326*3d8817e4Smiod as_bad (_("invalid operand suffix"));
1327*3d8817e4Smiod /* We need to generate a fixup of type 'reloc' for this
1328*3d8817e4Smiod expression. */
1329*3d8817e4Smiod if (fc >= MAX_INSN_FIXUPS)
1330*3d8817e4Smiod as_fatal (_("too many fixups"));
1331*3d8817e4Smiod fixups[fc].exp = ex;
1332*3d8817e4Smiod fixups[fc].opindex = *opindex_ptr;
1333*3d8817e4Smiod fixups[fc].reloc = reloc;
1334*3d8817e4Smiod ++fc;
1335*3d8817e4Smiod }
1336*3d8817e4Smiod
1337*3d8817e4Smiod /* Check the next character. The call to expression has advanced
1338*3d8817e4Smiod str past any whitespace. */
1339*3d8817e4Smiod if (operand->flags & S390_OPERAND_DISP)
1340*3d8817e4Smiod {
1341*3d8817e4Smiod /* After a displacement a block in parentheses can start. */
1342*3d8817e4Smiod if (*str != '(')
1343*3d8817e4Smiod {
1344*3d8817e4Smiod /* Check if parenthesized block can be skipped. If the next
1345*3d8817e4Smiod operand is neiter an optional operand nor a base register
1346*3d8817e4Smiod then we have a syntax error. */
1347*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1348*3d8817e4Smiod if (!(operand->flags & (S390_OPERAND_INDEX|S390_OPERAND_BASE)))
1349*3d8817e4Smiod as_bad (_("syntax error; missing '(' after displacement"));
1350*3d8817e4Smiod
1351*3d8817e4Smiod /* Ok, skip all operands until S390_OPERAND_BASE. */
1352*3d8817e4Smiod while (!(operand->flags & S390_OPERAND_BASE))
1353*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1354*3d8817e4Smiod
1355*3d8817e4Smiod /* If there is a next operand it must be separated by a comma. */
1356*3d8817e4Smiod if (opindex_ptr[1] != '\0')
1357*3d8817e4Smiod {
1358*3d8817e4Smiod if (*str != ',')
1359*3d8817e4Smiod {
1360*3d8817e4Smiod while (opindex_ptr[1] != '\0')
1361*3d8817e4Smiod {
1362*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1363*3d8817e4Smiod if (operand->flags & S390_OPERAND_OPTIONAL)
1364*3d8817e4Smiod continue;
1365*3d8817e4Smiod as_bad (_("syntax error; expected ,"));
1366*3d8817e4Smiod break;
1367*3d8817e4Smiod }
1368*3d8817e4Smiod }
1369*3d8817e4Smiod else
1370*3d8817e4Smiod str++;
1371*3d8817e4Smiod }
1372*3d8817e4Smiod }
1373*3d8817e4Smiod else
1374*3d8817e4Smiod {
1375*3d8817e4Smiod /* We found an opening parentheses. */
1376*3d8817e4Smiod str++;
1377*3d8817e4Smiod for (f = str; *f != '\0'; f++)
1378*3d8817e4Smiod if (*f == ',' || *f == ')')
1379*3d8817e4Smiod break;
1380*3d8817e4Smiod /* If there is no comma until the closing parentheses OR
1381*3d8817e4Smiod there is a comma right after the opening parentheses,
1382*3d8817e4Smiod we have to skip optional operands. */
1383*3d8817e4Smiod if (*f == ',' && f == str)
1384*3d8817e4Smiod {
1385*3d8817e4Smiod /* comma directly after '(' ? */
1386*3d8817e4Smiod skip_optional = 1;
1387*3d8817e4Smiod str++;
1388*3d8817e4Smiod }
1389*3d8817e4Smiod else
1390*3d8817e4Smiod skip_optional = (*f != ',');
1391*3d8817e4Smiod }
1392*3d8817e4Smiod }
1393*3d8817e4Smiod else if (operand->flags & S390_OPERAND_BASE)
1394*3d8817e4Smiod {
1395*3d8817e4Smiod /* After the base register the parenthesed block ends. */
1396*3d8817e4Smiod if (*str++ != ')')
1397*3d8817e4Smiod as_bad (_("syntax error; missing ')' after base register"));
1398*3d8817e4Smiod skip_optional = 0;
1399*3d8817e4Smiod /* If there is a next operand it must be separated by a comma. */
1400*3d8817e4Smiod if (opindex_ptr[1] != '\0')
1401*3d8817e4Smiod {
1402*3d8817e4Smiod if (*str != ',')
1403*3d8817e4Smiod {
1404*3d8817e4Smiod while (opindex_ptr[1] != '\0')
1405*3d8817e4Smiod {
1406*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1407*3d8817e4Smiod if (operand->flags & S390_OPERAND_OPTIONAL)
1408*3d8817e4Smiod continue;
1409*3d8817e4Smiod as_bad (_("syntax error; expected ,"));
1410*3d8817e4Smiod break;
1411*3d8817e4Smiod }
1412*3d8817e4Smiod }
1413*3d8817e4Smiod else
1414*3d8817e4Smiod str++;
1415*3d8817e4Smiod }
1416*3d8817e4Smiod }
1417*3d8817e4Smiod else
1418*3d8817e4Smiod {
1419*3d8817e4Smiod /* We can find an 'early' closing parentheses in e.g. D(L) instead
1420*3d8817e4Smiod of D(L,B). In this case the base register has to be skipped. */
1421*3d8817e4Smiod if (*str == ')')
1422*3d8817e4Smiod {
1423*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1424*3d8817e4Smiod
1425*3d8817e4Smiod if (!(operand->flags & S390_OPERAND_BASE))
1426*3d8817e4Smiod as_bad (_("syntax error; ')' not allowed here"));
1427*3d8817e4Smiod str++;
1428*3d8817e4Smiod }
1429*3d8817e4Smiod /* If there is a next operand it must be separated by a comma. */
1430*3d8817e4Smiod if (opindex_ptr[1] != '\0')
1431*3d8817e4Smiod {
1432*3d8817e4Smiod if (*str != ',')
1433*3d8817e4Smiod {
1434*3d8817e4Smiod while (opindex_ptr[1] != '\0')
1435*3d8817e4Smiod {
1436*3d8817e4Smiod operand = s390_operands + *(++opindex_ptr);
1437*3d8817e4Smiod if (operand->flags & S390_OPERAND_OPTIONAL)
1438*3d8817e4Smiod continue;
1439*3d8817e4Smiod as_bad (_("syntax error; expected ,"));
1440*3d8817e4Smiod break;
1441*3d8817e4Smiod }
1442*3d8817e4Smiod }
1443*3d8817e4Smiod else
1444*3d8817e4Smiod str++;
1445*3d8817e4Smiod }
1446*3d8817e4Smiod }
1447*3d8817e4Smiod }
1448*3d8817e4Smiod
1449*3d8817e4Smiod while (ISSPACE (*str))
1450*3d8817e4Smiod ++str;
1451*3d8817e4Smiod
1452*3d8817e4Smiod /* Check for tls instruction marker. */
1453*3d8817e4Smiod reloc = s390_tls_suffix (&str, &ex);
1454*3d8817e4Smiod if (reloc != BFD_RELOC_UNUSED)
1455*3d8817e4Smiod {
1456*3d8817e4Smiod /* We need to generate a fixup of type 'reloc' for this
1457*3d8817e4Smiod instruction. */
1458*3d8817e4Smiod if (fc >= MAX_INSN_FIXUPS)
1459*3d8817e4Smiod as_fatal (_("too many fixups"));
1460*3d8817e4Smiod fixups[fc].exp = ex;
1461*3d8817e4Smiod fixups[fc].opindex = -1;
1462*3d8817e4Smiod fixups[fc].reloc = reloc;
1463*3d8817e4Smiod ++fc;
1464*3d8817e4Smiod }
1465*3d8817e4Smiod
1466*3d8817e4Smiod if (*str != '\0')
1467*3d8817e4Smiod {
1468*3d8817e4Smiod char *linefeed;
1469*3d8817e4Smiod
1470*3d8817e4Smiod if ((linefeed = strchr (str, '\n')) != NULL)
1471*3d8817e4Smiod *linefeed = '\0';
1472*3d8817e4Smiod as_bad (_("junk at end of line: `%s'"), str);
1473*3d8817e4Smiod if (linefeed != NULL)
1474*3d8817e4Smiod *linefeed = '\n';
1475*3d8817e4Smiod }
1476*3d8817e4Smiod
1477*3d8817e4Smiod /* Write out the instruction. */
1478*3d8817e4Smiod f = frag_more (opcode->oplen);
1479*3d8817e4Smiod memcpy (f, insn, opcode->oplen);
1480*3d8817e4Smiod dwarf2_emit_insn (opcode->oplen);
1481*3d8817e4Smiod
1482*3d8817e4Smiod /* Create any fixups. At this point we do not use a
1483*3d8817e4Smiod bfd_reloc_code_real_type, but instead just use the
1484*3d8817e4Smiod BFD_RELOC_UNUSED plus the operand index. This lets us easily
1485*3d8817e4Smiod handle fixups for any operand type, although that is admittedly
1486*3d8817e4Smiod not a very exciting feature. We pick a BFD reloc type in
1487*3d8817e4Smiod md_apply_fix. */
1488*3d8817e4Smiod for (i = 0; i < fc; i++)
1489*3d8817e4Smiod {
1490*3d8817e4Smiod
1491*3d8817e4Smiod if (fixups[i].opindex < 0)
1492*3d8817e4Smiod {
1493*3d8817e4Smiod /* Create tls instruction marker relocation. */
1494*3d8817e4Smiod fix_new_exp (frag_now, f - frag_now->fr_literal, opcode->oplen,
1495*3d8817e4Smiod &fixups[i].exp, 0, fixups[i].reloc);
1496*3d8817e4Smiod continue;
1497*3d8817e4Smiod }
1498*3d8817e4Smiod
1499*3d8817e4Smiod operand = s390_operands + fixups[i].opindex;
1500*3d8817e4Smiod
1501*3d8817e4Smiod if (fixups[i].reloc != BFD_RELOC_UNUSED)
1502*3d8817e4Smiod {
1503*3d8817e4Smiod reloc_howto_type *reloc_howto;
1504*3d8817e4Smiod fixS *fixP;
1505*3d8817e4Smiod int size;
1506*3d8817e4Smiod
1507*3d8817e4Smiod reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
1508*3d8817e4Smiod if (!reloc_howto)
1509*3d8817e4Smiod abort ();
1510*3d8817e4Smiod
1511*3d8817e4Smiod size = bfd_get_reloc_size (reloc_howto);
1512*3d8817e4Smiod
1513*3d8817e4Smiod if (size < 1 || size > 4)
1514*3d8817e4Smiod abort ();
1515*3d8817e4Smiod
1516*3d8817e4Smiod fixP = fix_new_exp (frag_now,
1517*3d8817e4Smiod f - frag_now->fr_literal + (operand->shift/8),
1518*3d8817e4Smiod size, &fixups[i].exp, reloc_howto->pc_relative,
1519*3d8817e4Smiod fixups[i].reloc);
1520*3d8817e4Smiod /* Turn off overflow checking in fixup_segment. This is necessary
1521*3d8817e4Smiod because fixup_segment will signal an overflow for large 4 byte
1522*3d8817e4Smiod quantities for GOT12 relocations. */
1523*3d8817e4Smiod if ( fixups[i].reloc == BFD_RELOC_390_GOT12
1524*3d8817e4Smiod || fixups[i].reloc == BFD_RELOC_390_GOT20
1525*3d8817e4Smiod || fixups[i].reloc == BFD_RELOC_390_GOT16)
1526*3d8817e4Smiod fixP->fx_no_overflow = 1;
1527*3d8817e4Smiod }
1528*3d8817e4Smiod else
1529*3d8817e4Smiod fix_new_exp (frag_now, f - frag_now->fr_literal, 4, &fixups[i].exp,
1530*3d8817e4Smiod (operand->flags & S390_OPERAND_PCREL) != 0,
1531*3d8817e4Smiod ((bfd_reloc_code_real_type)
1532*3d8817e4Smiod (fixups[i].opindex + (int) BFD_RELOC_UNUSED)));
1533*3d8817e4Smiod }
1534*3d8817e4Smiod return str;
1535*3d8817e4Smiod }
1536*3d8817e4Smiod
1537*3d8817e4Smiod /* This routine is called for each instruction to be assembled. */
1538*3d8817e4Smiod
1539*3d8817e4Smiod void
md_assemble(str)1540*3d8817e4Smiod md_assemble (str)
1541*3d8817e4Smiod char *str;
1542*3d8817e4Smiod {
1543*3d8817e4Smiod const struct s390_opcode *opcode;
1544*3d8817e4Smiod unsigned char insn[6];
1545*3d8817e4Smiod char *s;
1546*3d8817e4Smiod
1547*3d8817e4Smiod /* Get the opcode. */
1548*3d8817e4Smiod for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
1549*3d8817e4Smiod ;
1550*3d8817e4Smiod if (*s != '\0')
1551*3d8817e4Smiod *s++ = '\0';
1552*3d8817e4Smiod
1553*3d8817e4Smiod /* Look up the opcode in the hash table. */
1554*3d8817e4Smiod opcode = (struct s390_opcode *) hash_find (s390_opcode_hash, str);
1555*3d8817e4Smiod if (opcode == (const struct s390_opcode *) NULL)
1556*3d8817e4Smiod {
1557*3d8817e4Smiod as_bad (_("Unrecognized opcode: `%s'"), str);
1558*3d8817e4Smiod return;
1559*3d8817e4Smiod }
1560*3d8817e4Smiod else if (!(opcode->modes & current_mode_mask))
1561*3d8817e4Smiod {
1562*3d8817e4Smiod as_bad ("Opcode %s not available in this mode", str);
1563*3d8817e4Smiod return;
1564*3d8817e4Smiod }
1565*3d8817e4Smiod memcpy (insn, opcode->opcode, sizeof (insn));
1566*3d8817e4Smiod md_gather_operands (s, insn, opcode);
1567*3d8817e4Smiod }
1568*3d8817e4Smiod
1569*3d8817e4Smiod #ifndef WORKING_DOT_WORD
1570*3d8817e4Smiod /* Handle long and short jumps. We don't support these */
1571*3d8817e4Smiod void
md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)1572*3d8817e4Smiod md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
1573*3d8817e4Smiod char *ptr;
1574*3d8817e4Smiod addressT from_addr, to_addr;
1575*3d8817e4Smiod fragS *frag;
1576*3d8817e4Smiod symbolS *to_symbol;
1577*3d8817e4Smiod {
1578*3d8817e4Smiod abort ();
1579*3d8817e4Smiod }
1580*3d8817e4Smiod
1581*3d8817e4Smiod void
md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)1582*3d8817e4Smiod md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
1583*3d8817e4Smiod char *ptr;
1584*3d8817e4Smiod addressT from_addr, to_addr;
1585*3d8817e4Smiod fragS *frag;
1586*3d8817e4Smiod symbolS *to_symbol;
1587*3d8817e4Smiod {
1588*3d8817e4Smiod abort ();
1589*3d8817e4Smiod }
1590*3d8817e4Smiod #endif
1591*3d8817e4Smiod
1592*3d8817e4Smiod void
s390_bss(ignore)1593*3d8817e4Smiod s390_bss (ignore)
1594*3d8817e4Smiod int ignore ATTRIBUTE_UNUSED;
1595*3d8817e4Smiod {
1596*3d8817e4Smiod /* We don't support putting frags in the BSS segment, we fake it
1597*3d8817e4Smiod by marking in_bss, then looking at s_skip for clues. */
1598*3d8817e4Smiod
1599*3d8817e4Smiod subseg_set (bss_section, 0);
1600*3d8817e4Smiod demand_empty_rest_of_line ();
1601*3d8817e4Smiod }
1602*3d8817e4Smiod
1603*3d8817e4Smiod /* Pseudo-op handling. */
1604*3d8817e4Smiod
1605*3d8817e4Smiod void
s390_insn(ignore)1606*3d8817e4Smiod s390_insn (ignore)
1607*3d8817e4Smiod int ignore ATTRIBUTE_UNUSED;
1608*3d8817e4Smiod {
1609*3d8817e4Smiod expressionS exp;
1610*3d8817e4Smiod const struct s390_opcode *opformat;
1611*3d8817e4Smiod unsigned char insn[6];
1612*3d8817e4Smiod char *s;
1613*3d8817e4Smiod
1614*3d8817e4Smiod /* Get the opcode format. */
1615*3d8817e4Smiod s = input_line_pointer;
1616*3d8817e4Smiod while (*s != '\0' && *s != ',' && ! ISSPACE (*s))
1617*3d8817e4Smiod s++;
1618*3d8817e4Smiod if (*s != ',')
1619*3d8817e4Smiod as_bad (_("Invalid .insn format\n"));
1620*3d8817e4Smiod *s++ = '\0';
1621*3d8817e4Smiod
1622*3d8817e4Smiod /* Look up the opcode in the hash table. */
1623*3d8817e4Smiod opformat = (struct s390_opcode *)
1624*3d8817e4Smiod hash_find (s390_opformat_hash, input_line_pointer);
1625*3d8817e4Smiod if (opformat == (const struct s390_opcode *) NULL)
1626*3d8817e4Smiod {
1627*3d8817e4Smiod as_bad (_("Unrecognized opcode format: `%s'"), input_line_pointer);
1628*3d8817e4Smiod return;
1629*3d8817e4Smiod }
1630*3d8817e4Smiod input_line_pointer = s;
1631*3d8817e4Smiod expression (&exp);
1632*3d8817e4Smiod if (exp.X_op == O_constant)
1633*3d8817e4Smiod {
1634*3d8817e4Smiod if ( ( opformat->oplen == 6
1635*3d8817e4Smiod && (addressT) exp.X_add_number < (1ULL << 48))
1636*3d8817e4Smiod || ( opformat->oplen == 4
1637*3d8817e4Smiod && (addressT) exp.X_add_number < (1ULL << 32))
1638*3d8817e4Smiod || ( opformat->oplen == 2
1639*3d8817e4Smiod && (addressT) exp.X_add_number < (1ULL << 16)))
1640*3d8817e4Smiod md_number_to_chars ((char *) insn, exp.X_add_number, opformat->oplen);
1641*3d8817e4Smiod else
1642*3d8817e4Smiod as_bad (_("Invalid .insn format\n"));
1643*3d8817e4Smiod }
1644*3d8817e4Smiod else if (exp.X_op == O_big)
1645*3d8817e4Smiod {
1646*3d8817e4Smiod if (exp.X_add_number > 0
1647*3d8817e4Smiod && opformat->oplen == 6
1648*3d8817e4Smiod && generic_bignum[3] == 0)
1649*3d8817e4Smiod {
1650*3d8817e4Smiod md_number_to_chars ((char *) insn, generic_bignum[2], 2);
1651*3d8817e4Smiod md_number_to_chars ((char *) &insn[2], generic_bignum[1], 2);
1652*3d8817e4Smiod md_number_to_chars ((char *) &insn[4], generic_bignum[0], 2);
1653*3d8817e4Smiod }
1654*3d8817e4Smiod else
1655*3d8817e4Smiod as_bad (_("Invalid .insn format\n"));
1656*3d8817e4Smiod }
1657*3d8817e4Smiod else
1658*3d8817e4Smiod as_bad (_("second operand of .insn not a constant\n"));
1659*3d8817e4Smiod
1660*3d8817e4Smiod if (strcmp (opformat->name, "e") != 0 && *input_line_pointer++ != ',')
1661*3d8817e4Smiod as_bad (_("missing comma after insn constant\n"));
1662*3d8817e4Smiod
1663*3d8817e4Smiod if ((s = strchr (input_line_pointer, '\n')) != NULL)
1664*3d8817e4Smiod *s = '\0';
1665*3d8817e4Smiod input_line_pointer = md_gather_operands (input_line_pointer, insn,
1666*3d8817e4Smiod opformat);
1667*3d8817e4Smiod if (s != NULL)
1668*3d8817e4Smiod *s = '\n';
1669*3d8817e4Smiod demand_empty_rest_of_line ();
1670*3d8817e4Smiod }
1671*3d8817e4Smiod
1672*3d8817e4Smiod /* The .byte pseudo-op. This is similar to the normal .byte
1673*3d8817e4Smiod pseudo-op, but it can also take a single ASCII string. */
1674*3d8817e4Smiod
1675*3d8817e4Smiod static void
s390_byte(ignore)1676*3d8817e4Smiod s390_byte (ignore)
1677*3d8817e4Smiod int ignore ATTRIBUTE_UNUSED;
1678*3d8817e4Smiod {
1679*3d8817e4Smiod if (*input_line_pointer != '\"')
1680*3d8817e4Smiod {
1681*3d8817e4Smiod cons (1);
1682*3d8817e4Smiod return;
1683*3d8817e4Smiod }
1684*3d8817e4Smiod
1685*3d8817e4Smiod /* Gather characters. A real double quote is doubled. Unusual
1686*3d8817e4Smiod characters are not permitted. */
1687*3d8817e4Smiod ++input_line_pointer;
1688*3d8817e4Smiod while (1)
1689*3d8817e4Smiod {
1690*3d8817e4Smiod char c;
1691*3d8817e4Smiod
1692*3d8817e4Smiod c = *input_line_pointer++;
1693*3d8817e4Smiod
1694*3d8817e4Smiod if (c == '\"')
1695*3d8817e4Smiod {
1696*3d8817e4Smiod if (*input_line_pointer != '\"')
1697*3d8817e4Smiod break;
1698*3d8817e4Smiod ++input_line_pointer;
1699*3d8817e4Smiod }
1700*3d8817e4Smiod
1701*3d8817e4Smiod FRAG_APPEND_1_CHAR (c);
1702*3d8817e4Smiod }
1703*3d8817e4Smiod
1704*3d8817e4Smiod demand_empty_rest_of_line ();
1705*3d8817e4Smiod }
1706*3d8817e4Smiod
1707*3d8817e4Smiod /* The .ltorg pseudo-op.This emits all literals defined since the last
1708*3d8817e4Smiod .ltorg or the invocation of gas. Literals are defined with the
1709*3d8817e4Smiod @lit suffix. */
1710*3d8817e4Smiod
1711*3d8817e4Smiod static void
s390_literals(ignore)1712*3d8817e4Smiod s390_literals (ignore)
1713*3d8817e4Smiod int ignore ATTRIBUTE_UNUSED;
1714*3d8817e4Smiod {
1715*3d8817e4Smiod struct s390_lpe *lpe;
1716*3d8817e4Smiod
1717*3d8817e4Smiod if (lp_sym == NULL || lpe_count == 0)
1718*3d8817e4Smiod return; /* Nothing to be done. */
1719*3d8817e4Smiod
1720*3d8817e4Smiod /* Emit symbol for start of literal pool. */
1721*3d8817e4Smiod S_SET_SEGMENT (lp_sym, now_seg);
1722*3d8817e4Smiod S_SET_VALUE (lp_sym, (valueT) frag_now_fix ());
1723*3d8817e4Smiod lp_sym->sy_frag = frag_now;
1724*3d8817e4Smiod
1725*3d8817e4Smiod while (lpe_list)
1726*3d8817e4Smiod {
1727*3d8817e4Smiod lpe = lpe_list;
1728*3d8817e4Smiod lpe_list = lpe_list->next;
1729*3d8817e4Smiod S_SET_SEGMENT (lpe->sym, now_seg);
1730*3d8817e4Smiod S_SET_VALUE (lpe->sym, (valueT) frag_now_fix ());
1731*3d8817e4Smiod lpe->sym->sy_frag = frag_now;
1732*3d8817e4Smiod
1733*3d8817e4Smiod /* Emit literal pool entry. */
1734*3d8817e4Smiod if (lpe->reloc != BFD_RELOC_UNUSED)
1735*3d8817e4Smiod {
1736*3d8817e4Smiod reloc_howto_type *reloc_howto =
1737*3d8817e4Smiod bfd_reloc_type_lookup (stdoutput, lpe->reloc);
1738*3d8817e4Smiod int size = bfd_get_reloc_size (reloc_howto);
1739*3d8817e4Smiod char *where;
1740*3d8817e4Smiod
1741*3d8817e4Smiod if (size > lpe->nbytes)
1742*3d8817e4Smiod as_bad (_("%s relocations do not fit in %d bytes"),
1743*3d8817e4Smiod reloc_howto->name, lpe->nbytes);
1744*3d8817e4Smiod where = frag_more (lpe->nbytes);
1745*3d8817e4Smiod md_number_to_chars (where, 0, size);
1746*3d8817e4Smiod fix_new_exp (frag_now, where - frag_now->fr_literal,
1747*3d8817e4Smiod size, &lpe->ex, reloc_howto->pc_relative, lpe->reloc);
1748*3d8817e4Smiod }
1749*3d8817e4Smiod else
1750*3d8817e4Smiod {
1751*3d8817e4Smiod if (lpe->ex.X_op == O_big)
1752*3d8817e4Smiod {
1753*3d8817e4Smiod if (lpe->ex.X_add_number <= 0)
1754*3d8817e4Smiod generic_floating_point_number = lpe->floatnum;
1755*3d8817e4Smiod else
1756*3d8817e4Smiod memcpy (generic_bignum, lpe->bignum,
1757*3d8817e4Smiod lpe->ex.X_add_number * sizeof (LITTLENUM_TYPE));
1758*3d8817e4Smiod }
1759*3d8817e4Smiod emit_expr (&lpe->ex, lpe->nbytes);
1760*3d8817e4Smiod }
1761*3d8817e4Smiod
1762*3d8817e4Smiod lpe->next = lpe_free_list;
1763*3d8817e4Smiod lpe_free_list = lpe;
1764*3d8817e4Smiod }
1765*3d8817e4Smiod lpe_list_tail = NULL;
1766*3d8817e4Smiod lp_sym = NULL;
1767*3d8817e4Smiod lp_count++;
1768*3d8817e4Smiod lpe_count = 0;
1769*3d8817e4Smiod }
1770*3d8817e4Smiod
1771*3d8817e4Smiod /* Turn a string in input_line_pointer into a floating point constant
1772*3d8817e4Smiod of type type, and store the appropriate bytes in *litp. The number
1773*3d8817e4Smiod of LITTLENUMS emitted is stored in *sizep . An error message is
1774*3d8817e4Smiod returned, or NULL on OK. */
1775*3d8817e4Smiod
1776*3d8817e4Smiod char *
md_atof(type,litp,sizep)1777*3d8817e4Smiod md_atof (type, litp, sizep)
1778*3d8817e4Smiod int type;
1779*3d8817e4Smiod char *litp;
1780*3d8817e4Smiod int *sizep;
1781*3d8817e4Smiod {
1782*3d8817e4Smiod int prec;
1783*3d8817e4Smiod LITTLENUM_TYPE words[4];
1784*3d8817e4Smiod char *t;
1785*3d8817e4Smiod int i;
1786*3d8817e4Smiod
1787*3d8817e4Smiod switch (type)
1788*3d8817e4Smiod {
1789*3d8817e4Smiod case 'f':
1790*3d8817e4Smiod prec = 2;
1791*3d8817e4Smiod break;
1792*3d8817e4Smiod
1793*3d8817e4Smiod case 'd':
1794*3d8817e4Smiod prec = 4;
1795*3d8817e4Smiod break;
1796*3d8817e4Smiod
1797*3d8817e4Smiod default:
1798*3d8817e4Smiod *sizep = 0;
1799*3d8817e4Smiod return "bad call to md_atof";
1800*3d8817e4Smiod }
1801*3d8817e4Smiod
1802*3d8817e4Smiod t = atof_ieee (input_line_pointer, type, words);
1803*3d8817e4Smiod if (t)
1804*3d8817e4Smiod input_line_pointer = t;
1805*3d8817e4Smiod
1806*3d8817e4Smiod *sizep = prec * 2;
1807*3d8817e4Smiod
1808*3d8817e4Smiod for (i = 0; i < prec; i++)
1809*3d8817e4Smiod {
1810*3d8817e4Smiod md_number_to_chars (litp, (valueT) words[i], 2);
1811*3d8817e4Smiod litp += 2;
1812*3d8817e4Smiod }
1813*3d8817e4Smiod
1814*3d8817e4Smiod return NULL;
1815*3d8817e4Smiod }
1816*3d8817e4Smiod
1817*3d8817e4Smiod /* Align a section (I don't know why this is machine dependent). */
1818*3d8817e4Smiod
1819*3d8817e4Smiod valueT
md_section_align(seg,addr)1820*3d8817e4Smiod md_section_align (seg, addr)
1821*3d8817e4Smiod asection *seg;
1822*3d8817e4Smiod valueT addr;
1823*3d8817e4Smiod {
1824*3d8817e4Smiod int align = bfd_get_section_alignment (stdoutput, seg);
1825*3d8817e4Smiod
1826*3d8817e4Smiod return ((addr + (1 << align) - 1) & (-1 << align));
1827*3d8817e4Smiod }
1828*3d8817e4Smiod
1829*3d8817e4Smiod /* We don't have any form of relaxing. */
1830*3d8817e4Smiod
1831*3d8817e4Smiod int
md_estimate_size_before_relax(fragp,seg)1832*3d8817e4Smiod md_estimate_size_before_relax (fragp, seg)
1833*3d8817e4Smiod fragS *fragp ATTRIBUTE_UNUSED;
1834*3d8817e4Smiod asection *seg ATTRIBUTE_UNUSED;
1835*3d8817e4Smiod {
1836*3d8817e4Smiod abort ();
1837*3d8817e4Smiod return 0;
1838*3d8817e4Smiod }
1839*3d8817e4Smiod
1840*3d8817e4Smiod /* Convert a machine dependent frag. We never generate these. */
1841*3d8817e4Smiod
1842*3d8817e4Smiod void
md_convert_frag(abfd,sec,fragp)1843*3d8817e4Smiod md_convert_frag (abfd, sec, fragp)
1844*3d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
1845*3d8817e4Smiod asection *sec ATTRIBUTE_UNUSED;
1846*3d8817e4Smiod fragS *fragp ATTRIBUTE_UNUSED;
1847*3d8817e4Smiod {
1848*3d8817e4Smiod abort ();
1849*3d8817e4Smiod }
1850*3d8817e4Smiod
1851*3d8817e4Smiod symbolS *
md_undefined_symbol(name)1852*3d8817e4Smiod md_undefined_symbol (name)
1853*3d8817e4Smiod char *name;
1854*3d8817e4Smiod {
1855*3d8817e4Smiod if (*name == '_' && *(name + 1) == 'G'
1856*3d8817e4Smiod && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
1857*3d8817e4Smiod {
1858*3d8817e4Smiod if (!GOT_symbol)
1859*3d8817e4Smiod {
1860*3d8817e4Smiod if (symbol_find (name))
1861*3d8817e4Smiod as_bad (_("GOT already in symbol table"));
1862*3d8817e4Smiod GOT_symbol = symbol_new (name, undefined_section,
1863*3d8817e4Smiod (valueT) 0, &zero_address_frag);
1864*3d8817e4Smiod }
1865*3d8817e4Smiod return GOT_symbol;
1866*3d8817e4Smiod }
1867*3d8817e4Smiod return 0;
1868*3d8817e4Smiod }
1869*3d8817e4Smiod
1870*3d8817e4Smiod /* Functions concerning relocs. */
1871*3d8817e4Smiod
1872*3d8817e4Smiod /* The location from which a PC relative jump should be calculated,
1873*3d8817e4Smiod given a PC relative reloc. */
1874*3d8817e4Smiod
1875*3d8817e4Smiod long
md_pcrel_from_section(fixp,sec)1876*3d8817e4Smiod md_pcrel_from_section (fixp, sec)
1877*3d8817e4Smiod fixS *fixp;
1878*3d8817e4Smiod segT sec ATTRIBUTE_UNUSED;
1879*3d8817e4Smiod {
1880*3d8817e4Smiod return fixp->fx_frag->fr_address + fixp->fx_where;
1881*3d8817e4Smiod }
1882*3d8817e4Smiod
1883*3d8817e4Smiod /* Here we decide which fixups can be adjusted to make them relative to
1884*3d8817e4Smiod the beginning of the section instead of the symbol. Basically we need
1885*3d8817e4Smiod to make sure that the dynamic relocations are done correctly, so in
1886*3d8817e4Smiod some cases we force the original symbol to be used. */
1887*3d8817e4Smiod int
tc_s390_fix_adjustable(fixP)1888*3d8817e4Smiod tc_s390_fix_adjustable (fixP)
1889*3d8817e4Smiod fixS *fixP;
1890*3d8817e4Smiod {
1891*3d8817e4Smiod /* Don't adjust references to merge sections. */
1892*3d8817e4Smiod if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
1893*3d8817e4Smiod return 0;
1894*3d8817e4Smiod /* adjust_reloc_syms doesn't know about the GOT. */
1895*3d8817e4Smiod if ( fixP->fx_r_type == BFD_RELOC_16_GOTOFF
1896*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_32_GOTOFF
1897*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTOFF64
1898*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLTOFF16
1899*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLTOFF32
1900*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLTOFF64
1901*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLT16DBL
1902*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLT32
1903*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLT32DBL
1904*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_PLT64
1905*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOT12
1906*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOT20
1907*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOT16
1908*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL
1909*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOT64
1910*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTENT
1911*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLT12
1912*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLT16
1913*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLT20
1914*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLT32
1915*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLT64
1916*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_GOTPLTENT
1917*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LOAD
1918*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GDCALL
1919*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LDCALL
1920*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GD32
1921*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GD64
1922*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE12
1923*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE20
1924*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE32
1925*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_GOTIE64
1926*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM32
1927*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LDM64
1928*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_IE32
1929*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_IE64
1930*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_IEENT
1931*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LE32
1932*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LE64
1933*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO32
1934*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_LDO64
1935*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPMOD
1936*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_DTPOFF
1937*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_390_TLS_TPOFF
1938*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1939*3d8817e4Smiod || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1940*3d8817e4Smiod return 0;
1941*3d8817e4Smiod return 1;
1942*3d8817e4Smiod }
1943*3d8817e4Smiod
1944*3d8817e4Smiod /* Return true if we must always emit a reloc for a type and false if
1945*3d8817e4Smiod there is some hope of resolving it at assembly time. */
1946*3d8817e4Smiod int
tc_s390_force_relocation(fixp)1947*3d8817e4Smiod tc_s390_force_relocation (fixp)
1948*3d8817e4Smiod struct fix *fixp;
1949*3d8817e4Smiod {
1950*3d8817e4Smiod /* Ensure we emit a relocation for every reference to the global
1951*3d8817e4Smiod offset table or to the procedure link table. */
1952*3d8817e4Smiod switch (fixp->fx_r_type)
1953*3d8817e4Smiod {
1954*3d8817e4Smiod case BFD_RELOC_390_GOT12:
1955*3d8817e4Smiod case BFD_RELOC_390_GOT20:
1956*3d8817e4Smiod case BFD_RELOC_32_GOT_PCREL:
1957*3d8817e4Smiod case BFD_RELOC_32_GOTOFF:
1958*3d8817e4Smiod case BFD_RELOC_390_GOTOFF64:
1959*3d8817e4Smiod case BFD_RELOC_390_PLTOFF16:
1960*3d8817e4Smiod case BFD_RELOC_390_PLTOFF32:
1961*3d8817e4Smiod case BFD_RELOC_390_PLTOFF64:
1962*3d8817e4Smiod case BFD_RELOC_390_GOTPC:
1963*3d8817e4Smiod case BFD_RELOC_390_GOT16:
1964*3d8817e4Smiod case BFD_RELOC_390_GOTPCDBL:
1965*3d8817e4Smiod case BFD_RELOC_390_GOT64:
1966*3d8817e4Smiod case BFD_RELOC_390_GOTENT:
1967*3d8817e4Smiod case BFD_RELOC_390_PLT32:
1968*3d8817e4Smiod case BFD_RELOC_390_PLT16DBL:
1969*3d8817e4Smiod case BFD_RELOC_390_PLT32DBL:
1970*3d8817e4Smiod case BFD_RELOC_390_PLT64:
1971*3d8817e4Smiod case BFD_RELOC_390_GOTPLT12:
1972*3d8817e4Smiod case BFD_RELOC_390_GOTPLT16:
1973*3d8817e4Smiod case BFD_RELOC_390_GOTPLT20:
1974*3d8817e4Smiod case BFD_RELOC_390_GOTPLT32:
1975*3d8817e4Smiod case BFD_RELOC_390_GOTPLT64:
1976*3d8817e4Smiod case BFD_RELOC_390_GOTPLTENT:
1977*3d8817e4Smiod return 1;
1978*3d8817e4Smiod default:
1979*3d8817e4Smiod break;;
1980*3d8817e4Smiod }
1981*3d8817e4Smiod
1982*3d8817e4Smiod return generic_force_reloc (fixp);
1983*3d8817e4Smiod }
1984*3d8817e4Smiod
1985*3d8817e4Smiod /* Apply a fixup to the object code. This is called for all the
1986*3d8817e4Smiod fixups we generated by the call to fix_new_exp, above. In the call
1987*3d8817e4Smiod above we used a reloc code which was the largest legal reloc code
1988*3d8817e4Smiod plus the operand index. Here we undo that to recover the operand
1989*3d8817e4Smiod index. At this point all symbol values should be fully resolved,
1990*3d8817e4Smiod and we attempt to completely resolve the reloc. If we can not do
1991*3d8817e4Smiod that, we determine the correct reloc code and put it back in the
1992*3d8817e4Smiod fixup. */
1993*3d8817e4Smiod
1994*3d8817e4Smiod void
md_apply_fix(fixP,valP,seg)1995*3d8817e4Smiod md_apply_fix (fixP, valP, seg)
1996*3d8817e4Smiod fixS *fixP;
1997*3d8817e4Smiod valueT *valP;
1998*3d8817e4Smiod segT seg ATTRIBUTE_UNUSED;
1999*3d8817e4Smiod {
2000*3d8817e4Smiod char *where;
2001*3d8817e4Smiod valueT value = *valP;
2002*3d8817e4Smiod
2003*3d8817e4Smiod where = fixP->fx_frag->fr_literal + fixP->fx_where;
2004*3d8817e4Smiod
2005*3d8817e4Smiod if (fixP->fx_subsy != NULL)
2006*3d8817e4Smiod as_bad_where (fixP->fx_file, fixP->fx_line,
2007*3d8817e4Smiod "cannot emit relocation %s against subsy symbol %s",
2008*3d8817e4Smiod bfd_get_reloc_code_name (fixP->fx_r_type),
2009*3d8817e4Smiod S_GET_NAME (fixP->fx_subsy));
2010*3d8817e4Smiod
2011*3d8817e4Smiod if (fixP->fx_addsy != NULL)
2012*3d8817e4Smiod {
2013*3d8817e4Smiod if (fixP->fx_pcrel)
2014*3d8817e4Smiod value += fixP->fx_frag->fr_address + fixP->fx_where;
2015*3d8817e4Smiod }
2016*3d8817e4Smiod else
2017*3d8817e4Smiod fixP->fx_done = 1;
2018*3d8817e4Smiod
2019*3d8817e4Smiod if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
2020*3d8817e4Smiod {
2021*3d8817e4Smiod const struct s390_operand *operand;
2022*3d8817e4Smiod int opindex;
2023*3d8817e4Smiod
2024*3d8817e4Smiod opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
2025*3d8817e4Smiod operand = &s390_operands[opindex];
2026*3d8817e4Smiod
2027*3d8817e4Smiod if (fixP->fx_done)
2028*3d8817e4Smiod {
2029*3d8817e4Smiod /* Insert the fully resolved operand value. */
2030*3d8817e4Smiod s390_insert_operand ((unsigned char *) where, operand,
2031*3d8817e4Smiod (offsetT) value, fixP->fx_file, fixP->fx_line);
2032*3d8817e4Smiod return;
2033*3d8817e4Smiod }
2034*3d8817e4Smiod
2035*3d8817e4Smiod /* Determine a BFD reloc value based on the operand information.
2036*3d8817e4Smiod We are only prepared to turn a few of the operands into
2037*3d8817e4Smiod relocs. */
2038*3d8817e4Smiod fixP->fx_offset = value;
2039*3d8817e4Smiod if (operand->bits == 12 && operand->shift == 20)
2040*3d8817e4Smiod {
2041*3d8817e4Smiod fixP->fx_size = 2;
2042*3d8817e4Smiod fixP->fx_where += 2;
2043*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_390_12;
2044*3d8817e4Smiod }
2045*3d8817e4Smiod else if (operand->bits == 12 && operand->shift == 36)
2046*3d8817e4Smiod {
2047*3d8817e4Smiod fixP->fx_size = 2;
2048*3d8817e4Smiod fixP->fx_where += 4;
2049*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_390_12;
2050*3d8817e4Smiod }
2051*3d8817e4Smiod else if (operand->bits == 20 && operand->shift == 20)
2052*3d8817e4Smiod {
2053*3d8817e4Smiod fixP->fx_size = 2;
2054*3d8817e4Smiod fixP->fx_where += 2;
2055*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_390_20;
2056*3d8817e4Smiod }
2057*3d8817e4Smiod else if (operand->bits == 8 && operand->shift == 8)
2058*3d8817e4Smiod {
2059*3d8817e4Smiod fixP->fx_size = 1;
2060*3d8817e4Smiod fixP->fx_where += 1;
2061*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_8;
2062*3d8817e4Smiod }
2063*3d8817e4Smiod else if (operand->bits == 16 && operand->shift == 16)
2064*3d8817e4Smiod {
2065*3d8817e4Smiod fixP->fx_size = 2;
2066*3d8817e4Smiod fixP->fx_where += 2;
2067*3d8817e4Smiod if (operand->flags & S390_OPERAND_PCREL)
2068*3d8817e4Smiod {
2069*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_390_PC16DBL;
2070*3d8817e4Smiod fixP->fx_offset += 2;
2071*3d8817e4Smiod }
2072*3d8817e4Smiod else
2073*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_16;
2074*3d8817e4Smiod }
2075*3d8817e4Smiod else if (operand->bits == 32 && operand->shift == 16
2076*3d8817e4Smiod && (operand->flags & S390_OPERAND_PCREL))
2077*3d8817e4Smiod {
2078*3d8817e4Smiod fixP->fx_size = 4;
2079*3d8817e4Smiod fixP->fx_where += 2;
2080*3d8817e4Smiod fixP->fx_offset += 2;
2081*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_390_PC32DBL;
2082*3d8817e4Smiod }
2083*3d8817e4Smiod else
2084*3d8817e4Smiod {
2085*3d8817e4Smiod char *sfile;
2086*3d8817e4Smiod unsigned int sline;
2087*3d8817e4Smiod
2088*3d8817e4Smiod /* Use expr_symbol_where to see if this is an expression
2089*3d8817e4Smiod symbol. */
2090*3d8817e4Smiod if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
2091*3d8817e4Smiod as_bad_where (fixP->fx_file, fixP->fx_line,
2092*3d8817e4Smiod _("unresolved expression that must be resolved"));
2093*3d8817e4Smiod else
2094*3d8817e4Smiod as_bad_where (fixP->fx_file, fixP->fx_line,
2095*3d8817e4Smiod _("unsupported relocation type"));
2096*3d8817e4Smiod fixP->fx_done = 1;
2097*3d8817e4Smiod return;
2098*3d8817e4Smiod }
2099*3d8817e4Smiod }
2100*3d8817e4Smiod else
2101*3d8817e4Smiod {
2102*3d8817e4Smiod switch (fixP->fx_r_type)
2103*3d8817e4Smiod {
2104*3d8817e4Smiod case BFD_RELOC_8:
2105*3d8817e4Smiod if (fixP->fx_pcrel)
2106*3d8817e4Smiod abort ();
2107*3d8817e4Smiod if (fixP->fx_done)
2108*3d8817e4Smiod md_number_to_chars (where, value, 1);
2109*3d8817e4Smiod break;
2110*3d8817e4Smiod case BFD_RELOC_390_12:
2111*3d8817e4Smiod case BFD_RELOC_390_GOT12:
2112*3d8817e4Smiod case BFD_RELOC_390_GOTPLT12:
2113*3d8817e4Smiod if (fixP->fx_done)
2114*3d8817e4Smiod {
2115*3d8817e4Smiod unsigned short mop;
2116*3d8817e4Smiod
2117*3d8817e4Smiod mop = bfd_getb16 ((unsigned char *) where);
2118*3d8817e4Smiod mop |= (unsigned short) (value & 0xfff);
2119*3d8817e4Smiod bfd_putb16 ((bfd_vma) mop, (unsigned char *) where);
2120*3d8817e4Smiod }
2121*3d8817e4Smiod break;
2122*3d8817e4Smiod
2123*3d8817e4Smiod case BFD_RELOC_390_20:
2124*3d8817e4Smiod case BFD_RELOC_390_GOT20:
2125*3d8817e4Smiod case BFD_RELOC_390_GOTPLT20:
2126*3d8817e4Smiod if (fixP->fx_done)
2127*3d8817e4Smiod {
2128*3d8817e4Smiod unsigned int mop;
2129*3d8817e4Smiod mop = bfd_getb32 ((unsigned char *) where);
2130*3d8817e4Smiod mop |= (unsigned int) ((value & 0xfff) << 8 |
2131*3d8817e4Smiod (value & 0xff000) >> 12);
2132*3d8817e4Smiod bfd_putb32 ((bfd_vma) mop, (unsigned char *) where);
2133*3d8817e4Smiod }
2134*3d8817e4Smiod break;
2135*3d8817e4Smiod
2136*3d8817e4Smiod case BFD_RELOC_16:
2137*3d8817e4Smiod case BFD_RELOC_GPREL16:
2138*3d8817e4Smiod case BFD_RELOC_16_GOT_PCREL:
2139*3d8817e4Smiod case BFD_RELOC_16_GOTOFF:
2140*3d8817e4Smiod if (fixP->fx_pcrel)
2141*3d8817e4Smiod as_bad_where (fixP->fx_file, fixP->fx_line,
2142*3d8817e4Smiod "cannot emit PC relative %s relocation%s%s",
2143*3d8817e4Smiod bfd_get_reloc_code_name (fixP->fx_r_type),
2144*3d8817e4Smiod fixP->fx_addsy != NULL ? " against " : "",
2145*3d8817e4Smiod (fixP->fx_addsy != NULL
2146*3d8817e4Smiod ? S_GET_NAME (fixP->fx_addsy)
2147*3d8817e4Smiod : ""));
2148*3d8817e4Smiod if (fixP->fx_done)
2149*3d8817e4Smiod md_number_to_chars (where, value, 2);
2150*3d8817e4Smiod break;
2151*3d8817e4Smiod case BFD_RELOC_390_GOT16:
2152*3d8817e4Smiod case BFD_RELOC_390_PLTOFF16:
2153*3d8817e4Smiod case BFD_RELOC_390_GOTPLT16:
2154*3d8817e4Smiod if (fixP->fx_done)
2155*3d8817e4Smiod md_number_to_chars (where, value, 2);
2156*3d8817e4Smiod break;
2157*3d8817e4Smiod case BFD_RELOC_390_PC16DBL:
2158*3d8817e4Smiod case BFD_RELOC_390_PLT16DBL:
2159*3d8817e4Smiod value += 2;
2160*3d8817e4Smiod if (fixP->fx_done)
2161*3d8817e4Smiod md_number_to_chars (where, (offsetT) value >> 1, 2);
2162*3d8817e4Smiod break;
2163*3d8817e4Smiod
2164*3d8817e4Smiod case BFD_RELOC_32:
2165*3d8817e4Smiod if (fixP->fx_pcrel)
2166*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_32_PCREL;
2167*3d8817e4Smiod else
2168*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_32;
2169*3d8817e4Smiod if (fixP->fx_done)
2170*3d8817e4Smiod md_number_to_chars (where, value, 4);
2171*3d8817e4Smiod break;
2172*3d8817e4Smiod case BFD_RELOC_32_PCREL:
2173*3d8817e4Smiod case BFD_RELOC_32_BASEREL:
2174*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_32_PCREL;
2175*3d8817e4Smiod if (fixP->fx_done)
2176*3d8817e4Smiod md_number_to_chars (where, value, 4);
2177*3d8817e4Smiod break;
2178*3d8817e4Smiod case BFD_RELOC_32_GOT_PCREL:
2179*3d8817e4Smiod case BFD_RELOC_390_PLTOFF32:
2180*3d8817e4Smiod case BFD_RELOC_390_PLT32:
2181*3d8817e4Smiod case BFD_RELOC_390_GOTPLT32:
2182*3d8817e4Smiod if (fixP->fx_done)
2183*3d8817e4Smiod md_number_to_chars (where, value, 4);
2184*3d8817e4Smiod break;
2185*3d8817e4Smiod case BFD_RELOC_390_PC32DBL:
2186*3d8817e4Smiod case BFD_RELOC_390_PLT32DBL:
2187*3d8817e4Smiod case BFD_RELOC_390_GOTPCDBL:
2188*3d8817e4Smiod case BFD_RELOC_390_GOTENT:
2189*3d8817e4Smiod case BFD_RELOC_390_GOTPLTENT:
2190*3d8817e4Smiod value += 2;
2191*3d8817e4Smiod if (fixP->fx_done)
2192*3d8817e4Smiod md_number_to_chars (where, (offsetT) value >> 1, 4);
2193*3d8817e4Smiod break;
2194*3d8817e4Smiod
2195*3d8817e4Smiod case BFD_RELOC_32_GOTOFF:
2196*3d8817e4Smiod if (fixP->fx_done)
2197*3d8817e4Smiod md_number_to_chars (where, value, sizeof (int));
2198*3d8817e4Smiod break;
2199*3d8817e4Smiod
2200*3d8817e4Smiod case BFD_RELOC_390_GOTOFF64:
2201*3d8817e4Smiod if (fixP->fx_done)
2202*3d8817e4Smiod md_number_to_chars (where, value, 8);
2203*3d8817e4Smiod break;
2204*3d8817e4Smiod
2205*3d8817e4Smiod case BFD_RELOC_390_GOT64:
2206*3d8817e4Smiod case BFD_RELOC_390_PLTOFF64:
2207*3d8817e4Smiod case BFD_RELOC_390_PLT64:
2208*3d8817e4Smiod case BFD_RELOC_390_GOTPLT64:
2209*3d8817e4Smiod if (fixP->fx_done)
2210*3d8817e4Smiod md_number_to_chars (where, value, 8);
2211*3d8817e4Smiod break;
2212*3d8817e4Smiod
2213*3d8817e4Smiod case BFD_RELOC_64:
2214*3d8817e4Smiod if (fixP->fx_pcrel)
2215*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_64_PCREL;
2216*3d8817e4Smiod else
2217*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_64;
2218*3d8817e4Smiod if (fixP->fx_done)
2219*3d8817e4Smiod md_number_to_chars (where, value, 8);
2220*3d8817e4Smiod break;
2221*3d8817e4Smiod
2222*3d8817e4Smiod case BFD_RELOC_64_PCREL:
2223*3d8817e4Smiod fixP->fx_r_type = BFD_RELOC_64_PCREL;
2224*3d8817e4Smiod if (fixP->fx_done)
2225*3d8817e4Smiod md_number_to_chars (where, value, 8);
2226*3d8817e4Smiod break;
2227*3d8817e4Smiod
2228*3d8817e4Smiod case BFD_RELOC_VTABLE_INHERIT:
2229*3d8817e4Smiod case BFD_RELOC_VTABLE_ENTRY:
2230*3d8817e4Smiod fixP->fx_done = 0;
2231*3d8817e4Smiod return;
2232*3d8817e4Smiod
2233*3d8817e4Smiod case BFD_RELOC_390_TLS_LOAD:
2234*3d8817e4Smiod case BFD_RELOC_390_TLS_GDCALL:
2235*3d8817e4Smiod case BFD_RELOC_390_TLS_LDCALL:
2236*3d8817e4Smiod case BFD_RELOC_390_TLS_GD32:
2237*3d8817e4Smiod case BFD_RELOC_390_TLS_GD64:
2238*3d8817e4Smiod case BFD_RELOC_390_TLS_GOTIE12:
2239*3d8817e4Smiod case BFD_RELOC_390_TLS_GOTIE20:
2240*3d8817e4Smiod case BFD_RELOC_390_TLS_GOTIE32:
2241*3d8817e4Smiod case BFD_RELOC_390_TLS_GOTIE64:
2242*3d8817e4Smiod case BFD_RELOC_390_TLS_LDM32:
2243*3d8817e4Smiod case BFD_RELOC_390_TLS_LDM64:
2244*3d8817e4Smiod case BFD_RELOC_390_TLS_IE32:
2245*3d8817e4Smiod case BFD_RELOC_390_TLS_IE64:
2246*3d8817e4Smiod case BFD_RELOC_390_TLS_LE32:
2247*3d8817e4Smiod case BFD_RELOC_390_TLS_LE64:
2248*3d8817e4Smiod case BFD_RELOC_390_TLS_LDO32:
2249*3d8817e4Smiod case BFD_RELOC_390_TLS_LDO64:
2250*3d8817e4Smiod case BFD_RELOC_390_TLS_DTPMOD:
2251*3d8817e4Smiod case BFD_RELOC_390_TLS_DTPOFF:
2252*3d8817e4Smiod case BFD_RELOC_390_TLS_TPOFF:
2253*3d8817e4Smiod S_SET_THREAD_LOCAL (fixP->fx_addsy);
2254*3d8817e4Smiod /* Fully resolved at link time. */
2255*3d8817e4Smiod break;
2256*3d8817e4Smiod case BFD_RELOC_390_TLS_IEENT:
2257*3d8817e4Smiod /* Fully resolved at link time. */
2258*3d8817e4Smiod S_SET_THREAD_LOCAL (fixP->fx_addsy);
2259*3d8817e4Smiod value += 2;
2260*3d8817e4Smiod break;
2261*3d8817e4Smiod
2262*3d8817e4Smiod default:
2263*3d8817e4Smiod {
2264*3d8817e4Smiod const char *reloc_name = bfd_get_reloc_code_name (fixP->fx_r_type);
2265*3d8817e4Smiod
2266*3d8817e4Smiod if (reloc_name != NULL)
2267*3d8817e4Smiod fprintf (stderr, "Gas failure, reloc type %s\n", reloc_name);
2268*3d8817e4Smiod else
2269*3d8817e4Smiod fprintf (stderr, "Gas failure, reloc type #%i\n", fixP->fx_r_type);
2270*3d8817e4Smiod fflush (stderr);
2271*3d8817e4Smiod abort ();
2272*3d8817e4Smiod }
2273*3d8817e4Smiod }
2274*3d8817e4Smiod
2275*3d8817e4Smiod fixP->fx_offset = value;
2276*3d8817e4Smiod }
2277*3d8817e4Smiod }
2278*3d8817e4Smiod
2279*3d8817e4Smiod /* Generate a reloc for a fixup. */
2280*3d8817e4Smiod
2281*3d8817e4Smiod arelent *
tc_gen_reloc(seg,fixp)2282*3d8817e4Smiod tc_gen_reloc (seg, fixp)
2283*3d8817e4Smiod asection *seg ATTRIBUTE_UNUSED;
2284*3d8817e4Smiod fixS *fixp;
2285*3d8817e4Smiod {
2286*3d8817e4Smiod bfd_reloc_code_real_type code;
2287*3d8817e4Smiod arelent *reloc;
2288*3d8817e4Smiod
2289*3d8817e4Smiod code = fixp->fx_r_type;
2290*3d8817e4Smiod if (GOT_symbol && fixp->fx_addsy == GOT_symbol)
2291*3d8817e4Smiod {
2292*3d8817e4Smiod if ( (s390_arch_size == 32 && code == BFD_RELOC_32_PCREL)
2293*3d8817e4Smiod || (s390_arch_size == 64 && code == BFD_RELOC_64_PCREL))
2294*3d8817e4Smiod code = BFD_RELOC_390_GOTPC;
2295*3d8817e4Smiod if (code == BFD_RELOC_390_PC32DBL)
2296*3d8817e4Smiod code = BFD_RELOC_390_GOTPCDBL;
2297*3d8817e4Smiod }
2298*3d8817e4Smiod
2299*3d8817e4Smiod reloc = (arelent *) xmalloc (sizeof (arelent));
2300*3d8817e4Smiod reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2301*3d8817e4Smiod *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2302*3d8817e4Smiod reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2303*3d8817e4Smiod reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2304*3d8817e4Smiod if (reloc->howto == NULL)
2305*3d8817e4Smiod {
2306*3d8817e4Smiod as_bad_where (fixp->fx_file, fixp->fx_line,
2307*3d8817e4Smiod _("cannot represent relocation type %s"),
2308*3d8817e4Smiod bfd_get_reloc_code_name (code));
2309*3d8817e4Smiod /* Set howto to a garbage value so that we can keep going. */
2310*3d8817e4Smiod reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2311*3d8817e4Smiod assert (reloc->howto != NULL);
2312*3d8817e4Smiod }
2313*3d8817e4Smiod reloc->addend = fixp->fx_offset;
2314*3d8817e4Smiod
2315*3d8817e4Smiod return reloc;
2316*3d8817e4Smiod }
2317*3d8817e4Smiod
2318*3d8817e4Smiod void
s390_cfi_frame_initial_instructions()2319*3d8817e4Smiod s390_cfi_frame_initial_instructions ()
2320*3d8817e4Smiod {
2321*3d8817e4Smiod cfi_add_CFA_def_cfa (15, s390_arch_size == 64 ? 160 : 96);
2322*3d8817e4Smiod }
2323*3d8817e4Smiod
2324*3d8817e4Smiod int
tc_s390_regname_to_dw2regnum(const char * regname)2325*3d8817e4Smiod tc_s390_regname_to_dw2regnum (const char *regname)
2326*3d8817e4Smiod {
2327*3d8817e4Smiod int regnum = -1;
2328*3d8817e4Smiod
2329*3d8817e4Smiod if (regname[0] != 'c' && regname[0] != 'a')
2330*3d8817e4Smiod {
2331*3d8817e4Smiod regnum = reg_name_search (pre_defined_registers, REG_NAME_CNT, regname);
2332*3d8817e4Smiod if (regname[0] == 'f' && regnum != -1)
2333*3d8817e4Smiod regnum += 16;
2334*3d8817e4Smiod }
2335*3d8817e4Smiod else if (strcmp (regname, "ap") == 0)
2336*3d8817e4Smiod regnum = 32;
2337*3d8817e4Smiod else if (strcmp (regname, "cc") == 0)
2338*3d8817e4Smiod regnum = 33;
2339*3d8817e4Smiod return regnum;
2340*3d8817e4Smiod }
2341