xref: /openbsd-src/gnu/usr.bin/binutils-2.17/gas/config/tc-s390.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
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