tc-alpha.c revision 1.1 1 1.1 christos /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 1.1 christos Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 1.1 christos 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4 1.1 christos Free Software Foundation, Inc.
5 1.1 christos Contributed by Carnegie Mellon University, 1993.
6 1.1 christos Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
7 1.1 christos Modified by Ken Raeburn for gas-2.x and ECOFF support.
8 1.1 christos Modified by Richard Henderson for ELF support.
9 1.1 christos Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 1.1 christos
11 1.1 christos This file is part of GAS, the GNU Assembler.
12 1.1 christos
13 1.1 christos GAS is free software; you can redistribute it and/or modify
14 1.1 christos it under the terms of the GNU General Public License as published by
15 1.1 christos the Free Software Foundation; either version 3, or (at your option)
16 1.1 christos any later version.
17 1.1 christos
18 1.1 christos GAS is distributed in the hope that it will be useful,
19 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
20 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 1.1 christos GNU General Public License for more details.
22 1.1 christos
23 1.1 christos You should have received a copy of the GNU General Public License
24 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
25 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
26 1.1 christos 02110-1301, USA. */
27 1.1 christos
28 1.1 christos /* Mach Operating System
29 1.1 christos Copyright (c) 1993 Carnegie Mellon University
30 1.1 christos All Rights Reserved.
31 1.1 christos
32 1.1 christos Permission to use, copy, modify and distribute this software and its
33 1.1 christos documentation is hereby granted, provided that both the copyright
34 1.1 christos notice and this permission notice appear in all copies of the
35 1.1 christos software, derivative works or modified versions, and any portions
36 1.1 christos thereof, and that both notices appear in supporting documentation.
37 1.1 christos
38 1.1 christos CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 1.1 christos CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 1.1 christos ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 1.1 christos
42 1.1 christos Carnegie Mellon requests users of this software to return to
43 1.1 christos
44 1.1 christos Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
45 1.1 christos School of Computer Science
46 1.1 christos Carnegie Mellon University
47 1.1 christos Pittsburgh PA 15213-3890
48 1.1 christos
49 1.1 christos any improvements or extensions that they make and grant Carnegie the
50 1.1 christos rights to redistribute these changes. */
51 1.1 christos
52 1.1 christos #include "as.h"
53 1.1 christos #include "subsegs.h"
54 1.1 christos #include "struc-symbol.h"
55 1.1 christos #include "ecoff.h"
56 1.1 christos
57 1.1 christos #include "opcode/alpha.h"
58 1.1 christos
59 1.1 christos #ifdef OBJ_ELF
60 1.1 christos #include "elf/alpha.h"
61 1.1 christos #endif
62 1.1 christos
63 1.1 christos #ifdef OBJ_EVAX
64 1.1 christos #include "vms.h"
65 1.1 christos #include "vms/egps.h"
66 1.1 christos #endif
67 1.1 christos
68 1.1 christos #include "dwarf2dbg.h"
69 1.1 christos #include "dw2gencfi.h"
70 1.1 christos #include "safe-ctype.h"
71 1.1 christos
72 1.1 christos /* Local types. */
74 1.1 christos
75 1.1 christos #define TOKENIZE_ERROR -1
76 1.1 christos #define TOKENIZE_ERROR_REPORT -2
77 1.1 christos #define MAX_INSN_FIXUPS 2
78 1.1 christos #define MAX_INSN_ARGS 5
79 1.1 christos
80 1.1 christos /* Used since new relocation types are introduced in this
81 1.1 christos file (DUMMY_RELOC_LITUSE_*) */
82 1.1 christos typedef int extended_bfd_reloc_code_real_type;
83 1.1 christos
84 1.1 christos struct alpha_fixup
85 1.1 christos {
86 1.1 christos expressionS exp;
87 1.1 christos /* bfd_reloc_code_real_type reloc; */
88 1.1 christos extended_bfd_reloc_code_real_type reloc;
89 1.1 christos #ifdef OBJ_EVAX
90 1.1 christos /* The symbol of the item in the linkage section. */
91 1.1 christos symbolS *xtrasym;
92 1.1 christos
93 1.1 christos /* The symbol of the procedure descriptor. */
94 1.1 christos symbolS *procsym;
95 1.1 christos #endif
96 1.1 christos };
97 1.1 christos
98 1.1 christos struct alpha_insn
99 1.1 christos {
100 1.1 christos unsigned insn;
101 1.1 christos int nfixups;
102 1.1 christos struct alpha_fixup fixups[MAX_INSN_FIXUPS];
103 1.1 christos long sequence;
104 1.1 christos };
105 1.1 christos
106 1.1 christos enum alpha_macro_arg
107 1.1 christos {
108 1.1 christos MACRO_EOA = 1,
109 1.1 christos MACRO_IR,
110 1.1 christos MACRO_PIR,
111 1.1 christos MACRO_OPIR,
112 1.1 christos MACRO_CPIR,
113 1.1 christos MACRO_FPR,
114 1.1 christos MACRO_EXP
115 1.1 christos };
116 1.1 christos
117 1.1 christos struct alpha_macro
118 1.1 christos {
119 1.1 christos const char *name;
120 1.1 christos void (*emit) (const expressionS *, int, const void *);
121 1.1 christos const void * arg;
122 1.1 christos enum alpha_macro_arg argsets[16];
123 1.1 christos };
124 1.1 christos
125 1.1 christos /* Extra expression types. */
126 1.1 christos
127 1.1 christos #define O_pregister O_md1 /* O_register, in parentheses. */
128 1.1 christos #define O_cpregister O_md2 /* + a leading comma. */
129 1.1 christos
130 1.1 christos /* The alpha_reloc_op table below depends on the ordering of these. */
131 1.1 christos #define O_literal O_md3 /* !literal relocation. */
132 1.1 christos #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
133 1.1 christos #define O_lituse_base O_md5 /* !lituse_base relocation. */
134 1.1 christos #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
135 1.1 christos #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
136 1.1 christos #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
137 1.1 christos #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
138 1.1 christos #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
139 1.1 christos #define O_gpdisp O_md11 /* !gpdisp relocation. */
140 1.1 christos #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
141 1.1 christos #define O_gprellow O_md13 /* !gprellow relocation. */
142 1.1 christos #define O_gprel O_md14 /* !gprel relocation. */
143 1.1 christos #define O_samegp O_md15 /* !samegp relocation. */
144 1.1 christos #define O_tlsgd O_md16 /* !tlsgd relocation. */
145 1.1 christos #define O_tlsldm O_md17 /* !tlsldm relocation. */
146 1.1 christos #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
147 1.1 christos #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
148 1.1 christos #define O_dtprello O_md20 /* !dtprello relocation. */
149 1.1 christos #define O_dtprel O_md21 /* !dtprel relocation. */
150 1.1 christos #define O_gottprel O_md22 /* !gottprel relocation. */
151 1.1 christos #define O_tprelhi O_md23 /* !tprelhi relocation. */
152 1.1 christos #define O_tprello O_md24 /* !tprello relocation. */
153 1.1 christos #define O_tprel O_md25 /* !tprel relocation. */
154 1.1 christos
155 1.1 christos #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
156 1.1 christos #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
157 1.1 christos #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
158 1.1 christos #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
159 1.1 christos #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
160 1.1 christos #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
161 1.1 christos #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
162 1.1 christos
163 1.1 christos #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
164 1.1 christos
165 1.1 christos /* Macros for extracting the type and number of encoded register tokens. */
166 1.1 christos
167 1.1 christos #define is_ir_num(x) (((x) & 32) == 0)
168 1.1 christos #define is_fpr_num(x) (((x) & 32) != 0)
169 1.1 christos #define regno(x) ((x) & 31)
170 1.1 christos
171 1.1 christos /* Something odd inherited from the old assembler. */
172 1.1 christos
173 1.1 christos #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
174 1.1 christos #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
175 1.1 christos
176 1.1 christos /* Predicates for 16- and 32-bit ranges */
177 1.1 christos /* XXX: The non-shift version appears to trigger a compiler bug when
178 1.1 christos cross-assembling from x86 w/ gcc 2.7.2. */
179 1.1 christos
180 1.1 christos #if 1
181 1.1 christos #define range_signed_16(x) \
182 1.1 christos (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
183 1.1 christos #define range_signed_32(x) \
184 1.1 christos (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
185 1.1 christos #else
186 1.1 christos #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
187 1.1 christos (offsetT) (x) <= (offsetT) 0x7FFF)
188 1.1 christos #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
189 1.1 christos (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
190 1.1 christos #endif
191 1.1 christos
192 1.1 christos /* Macros for sign extending from 16- and 32-bits. */
193 1.1 christos /* XXX: The cast macros will work on all the systems that I care about,
194 1.1 christos but really a predicate should be found to use the non-cast forms. */
195 1.1 christos
196 1.1 christos #if 1
197 1.1 christos #define sign_extend_16(x) ((short) (x))
198 1.1 christos #define sign_extend_32(x) ((int) (x))
199 1.1 christos #else
200 1.1 christos #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
201 1.1 christos #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
202 1.1 christos ^ 0x80000000) - 0x80000000)
203 1.1 christos #endif
204 1.1 christos
205 1.1 christos /* Macros to build tokens. */
206 1.1 christos
207 1.1 christos #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
208 1.1 christos (t).X_op = O_register, \
209 1.1 christos (t).X_add_number = (r))
210 1.1 christos #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
211 1.1 christos (t).X_op = O_pregister, \
212 1.1 christos (t).X_add_number = (r))
213 1.1 christos #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
214 1.1 christos (t).X_op = O_cpregister, \
215 1.1 christos (t).X_add_number = (r))
216 1.1 christos #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
217 1.1 christos (t).X_op = O_register, \
218 1.1 christos (t).X_add_number = (r) + 32)
219 1.1 christos #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
220 1.1 christos (t).X_op = O_symbol, \
221 1.1 christos (t).X_add_symbol = (s), \
222 1.1 christos (t).X_add_number = (a))
223 1.1 christos #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
224 1.1 christos (t).X_op = O_constant, \
225 1.1 christos (t).X_add_number = (n))
226 1.1 christos
227 1.1 christos /* Generic assembler global variables which must be defined by all
229 1.1 christos targets. */
230 1.1 christos
231 1.1 christos /* Characters which always start a comment. */
232 1.1 christos const char comment_chars[] = "#";
233 1.1 christos
234 1.1 christos /* Characters which start a comment at the beginning of a line. */
235 1.1 christos const char line_comment_chars[] = "#";
236 1.1 christos
237 1.1 christos /* Characters which may be used to separate multiple commands on a
238 1.1 christos single line. */
239 1.1 christos const char line_separator_chars[] = ";";
240 1.1 christos
241 1.1 christos /* Characters which are used to indicate an exponent in a floating
242 1.1 christos point number. */
243 1.1 christos const char EXP_CHARS[] = "eE";
244 1.1 christos
245 1.1 christos /* Characters which mean that a number is a floating point constant,
246 1.1 christos as in 0d1.0. */
247 1.1 christos /* XXX: Do all of these really get used on the alpha?? */
248 1.1 christos char FLT_CHARS[] = "rRsSfFdDxXpP";
249 1.1 christos
250 1.1 christos #ifdef OBJ_EVAX
251 1.1 christos const char *md_shortopts = "Fm:g+1h:HG:";
252 1.1 christos #else
253 1.1 christos const char *md_shortopts = "Fm:gG:";
254 1.1 christos #endif
255 1.1 christos
256 1.1 christos struct option md_longopts[] =
257 1.1 christos {
258 1.1 christos #define OPTION_32ADDR (OPTION_MD_BASE)
259 1.1 christos { "32addr", no_argument, NULL, OPTION_32ADDR },
260 1.1 christos #define OPTION_RELAX (OPTION_32ADDR + 1)
261 1.1 christos { "relax", no_argument, NULL, OPTION_RELAX },
262 1.1 christos #ifdef OBJ_ELF
263 1.1 christos #define OPTION_MDEBUG (OPTION_RELAX + 1)
264 1.1 christos #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
265 1.1 christos { "mdebug", no_argument, NULL, OPTION_MDEBUG },
266 1.1 christos { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
267 1.1 christos #endif
268 1.1 christos #ifdef OBJ_EVAX
269 1.1 christos #define OPTION_REPLACE (OPTION_RELAX + 1)
270 1.1 christos #define OPTION_NOREPLACE (OPTION_REPLACE+1)
271 1.1 christos { "replace", no_argument, NULL, OPTION_REPLACE },
272 1.1 christos { "noreplace", no_argument, NULL, OPTION_NOREPLACE },
273 1.1 christos #endif
274 1.1 christos { NULL, no_argument, NULL, 0 }
275 1.1 christos };
276 1.1 christos
277 1.1 christos size_t md_longopts_size = sizeof (md_longopts);
278 1.1 christos
279 1.1 christos #ifdef OBJ_EVAX
281 1.1 christos #define AXP_REG_R0 0
282 1.1 christos #define AXP_REG_R16 16
283 1.1 christos #define AXP_REG_R17 17
284 1.1 christos #undef AXP_REG_T9
285 1.1 christos #define AXP_REG_T9 22
286 1.1 christos #undef AXP_REG_T10
287 1.1 christos #define AXP_REG_T10 23
288 1.1 christos #undef AXP_REG_T11
289 1.1 christos #define AXP_REG_T11 24
290 1.1 christos #undef AXP_REG_T12
291 1.1 christos #define AXP_REG_T12 25
292 1.1 christos #define AXP_REG_AI 25
293 1.1 christos #undef AXP_REG_FP
294 1.1 christos #define AXP_REG_FP 29
295 1.1 christos
296 1.1 christos #undef AXP_REG_GP
297 1.1 christos #define AXP_REG_GP AXP_REG_PV
298 1.1 christos
299 1.1 christos #endif /* OBJ_EVAX */
300 1.1 christos
301 1.1 christos /* The cpu for which we are generating code. */
302 1.1 christos static unsigned alpha_target = AXP_OPCODE_BASE;
303 1.1 christos static const char *alpha_target_name = "<all>";
304 1.1 christos
305 1.1 christos /* The hash table of instruction opcodes. */
306 1.1 christos static struct hash_control *alpha_opcode_hash;
307 1.1 christos
308 1.1 christos /* The hash table of macro opcodes. */
309 1.1 christos static struct hash_control *alpha_macro_hash;
310 1.1 christos
311 1.1 christos #ifdef OBJ_ECOFF
312 1.1 christos /* The $gp relocation symbol. */
313 1.1 christos static symbolS *alpha_gp_symbol;
314 1.1 christos
315 1.1 christos /* XXX: what is this, and why is it exported? */
316 1.1 christos valueT alpha_gp_value;
317 1.1 christos #endif
318 1.1 christos
319 1.1 christos /* The current $gp register. */
320 1.1 christos static int alpha_gp_register = AXP_REG_GP;
321 1.1 christos
322 1.1 christos /* A table of the register symbols. */
323 1.1 christos static symbolS *alpha_register_table[64];
324 1.1 christos
325 1.1 christos /* Constant sections, or sections of constants. */
326 1.1 christos #ifdef OBJ_ECOFF
327 1.1 christos static segT alpha_lita_section;
328 1.1 christos #endif
329 1.1 christos #ifdef OBJ_EVAX
330 1.1 christos segT alpha_link_section;
331 1.1 christos #endif
332 1.1 christos #ifndef OBJ_EVAX
333 1.1 christos static segT alpha_lit8_section;
334 1.1 christos #endif
335 1.1 christos
336 1.1 christos /* Symbols referring to said sections. */
337 1.1 christos #ifdef OBJ_ECOFF
338 1.1 christos static symbolS *alpha_lita_symbol;
339 1.1 christos #endif
340 1.1 christos #ifdef OBJ_EVAX
341 1.1 christos static symbolS *alpha_link_symbol;
342 1.1 christos #endif
343 1.1 christos #ifndef OBJ_EVAX
344 1.1 christos static symbolS *alpha_lit8_symbol;
345 1.1 christos #endif
346 1.1 christos
347 1.1 christos /* Literal for .litX+0x8000 within .lita. */
348 1.1 christos #ifdef OBJ_ECOFF
349 1.1 christos static offsetT alpha_lit8_literal;
350 1.1 christos #endif
351 1.1 christos
352 1.1 christos /* Is the assembler not allowed to use $at? */
353 1.1 christos static int alpha_noat_on = 0;
354 1.1 christos
355 1.1 christos /* Are macros enabled? */
356 1.1 christos static int alpha_macros_on = 1;
357 1.1 christos
358 1.1 christos /* Are floats disabled? */
359 1.1 christos static int alpha_nofloats_on = 0;
360 1.1 christos
361 1.1 christos /* Are addresses 32 bit? */
362 1.1 christos static int alpha_addr32_on = 0;
363 1.1 christos
364 1.1 christos /* Symbol labelling the current insn. When the Alpha gas sees
365 1.1 christos foo:
366 1.1 christos .quad 0
367 1.1 christos and the section happens to not be on an eight byte boundary, it
368 1.1 christos will align both the symbol and the .quad to an eight byte boundary. */
369 1.1 christos static symbolS *alpha_insn_label;
370 1.1 christos #if defined(OBJ_ELF) || defined (OBJ_EVAX)
371 1.1 christos static symbolS *alpha_prologue_label;
372 1.1 christos #endif
373 1.1 christos
374 1.1 christos #ifdef OBJ_EVAX
375 1.1 christos /* Symbol associate with the current jsr instruction. */
376 1.1 christos static symbolS *alpha_linkage_symbol;
377 1.1 christos #endif
378 1.1 christos
379 1.1 christos /* Whether we should automatically align data generation pseudo-ops.
380 1.1 christos .align 0 will turn this off. */
381 1.1 christos static int alpha_auto_align_on = 1;
382 1.1 christos
383 1.1 christos /* The known current alignment of the current section. */
384 1.1 christos static int alpha_current_align;
385 1.1 christos
386 1.1 christos /* These are exported to ECOFF code. */
387 1.1 christos unsigned long alpha_gprmask, alpha_fprmask;
388 1.1 christos
389 1.1 christos /* Whether the debugging option was seen. */
390 1.1 christos static int alpha_debug;
391 1.1 christos
392 1.1 christos #ifdef OBJ_ELF
393 1.1 christos /* Whether we are emitting an mdebug section. */
394 1.1 christos int alpha_flag_mdebug = -1;
395 1.1 christos #endif
396 1.1 christos
397 1.1 christos #ifdef OBJ_EVAX
398 1.1 christos /* Whether to perform the VMS procedure call optimization. */
399 1.1 christos int alpha_flag_replace = 1;
400 1.1 christos #endif
401 1.1 christos
402 1.1 christos /* Don't fully resolve relocations, allowing code movement in the linker. */
403 1.1 christos static int alpha_flag_relax;
404 1.1 christos
405 1.1 christos /* What value to give to bfd_set_gp_size. */
406 1.1 christos static int g_switch_value = 8;
407 1.1 christos
408 1.1 christos #ifdef OBJ_EVAX
409 1.1 christos /* Collect information about current procedure here. */
410 1.1 christos struct alpha_evax_procs
411 1.1 christos {
412 1.1 christos symbolS *symbol; /* Proc pdesc symbol. */
413 1.1 christos int pdsckind;
414 1.1 christos int framereg; /* Register for frame pointer. */
415 1.1 christos int framesize; /* Size of frame. */
416 1.1 christos int rsa_offset;
417 1.1 christos int ra_save;
418 1.1 christos int fp_save;
419 1.1 christos long imask;
420 1.1 christos long fmask;
421 1.1 christos int type;
422 1.1 christos int prologue;
423 1.1 christos symbolS *handler;
424 1.1 christos int handler_data;
425 1.1 christos };
426 1.1 christos
427 1.1 christos /* Linked list of .linkage fixups. */
428 1.1 christos struct alpha_linkage_fixups *alpha_linkage_fixup_root;
429 1.1 christos static struct alpha_linkage_fixups *alpha_linkage_fixup_tail;
430 1.1 christos
431 1.1 christos /* Current procedure descriptor. */
432 1.1 christos static struct alpha_evax_procs *alpha_evax_proc;
433 1.1 christos static struct alpha_evax_procs alpha_evax_proc_data;
434 1.1 christos
435 1.1 christos static int alpha_flag_hash_long_names = 0; /* -+ */
436 1.1 christos static int alpha_flag_show_after_trunc = 0; /* -H */
437 1.1 christos
438 1.1 christos /* If the -+ switch is given, then a hash is appended to any name that is
439 1.1 christos longer than 64 characters, else longer symbol names are truncated. */
440 1.1 christos
441 1.1 christos #endif
442 1.1 christos
443 1.1 christos #ifdef RELOC_OP_P
445 1.1 christos /* A table to map the spelling of a relocation operand into an appropriate
446 1.1 christos bfd_reloc_code_real_type type. The table is assumed to be ordered such
447 1.1 christos that op-O_literal indexes into it. */
448 1.1 christos
449 1.1 christos #define ALPHA_RELOC_TABLE(op) \
450 1.1 christos (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
451 1.1 christos ? (abort (), 0) \
452 1.1 christos : (int) (op) - (int) O_literal) ])
453 1.1 christos
454 1.1 christos #define DEF(NAME, RELOC, REQ, ALLOW) \
455 1.1 christos { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
456 1.1 christos
457 1.1 christos static const struct alpha_reloc_op_tag
458 1.1 christos {
459 1.1 christos const char *name; /* String to lookup. */
460 1.1 christos size_t length; /* Size of the string. */
461 1.1 christos operatorT op; /* Which operator to use. */
462 1.1 christos extended_bfd_reloc_code_real_type reloc;
463 1.1 christos unsigned int require_seq : 1; /* Require a sequence number. */
464 1.1 christos unsigned int allow_seq : 1; /* Allow a sequence number. */
465 1.1 christos }
466 1.1 christos alpha_reloc_op[] =
467 1.1 christos {
468 1.1 christos DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
469 1.1 christos DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
470 1.1 christos DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
471 1.1 christos DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
472 1.1 christos DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
473 1.1 christos DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
474 1.1 christos DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
475 1.1 christos DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
476 1.1 christos DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
477 1.1 christos DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
478 1.1 christos DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
479 1.1 christos DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
480 1.1 christos DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
481 1.1 christos DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
482 1.1 christos DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
483 1.1 christos DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
484 1.1 christos DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
485 1.1 christos DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
486 1.1 christos DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
487 1.1 christos DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
488 1.1 christos DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
489 1.1 christos DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
490 1.1 christos DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
491 1.1 christos };
492 1.1 christos
493 1.1 christos #undef DEF
494 1.1 christos
495 1.1 christos static const int alpha_num_reloc_op
496 1.1 christos = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
497 1.1 christos #endif /* RELOC_OP_P */
498 1.1 christos
499 1.1 christos /* Maximum # digits needed to hold the largest sequence #. */
500 1.1 christos #define ALPHA_RELOC_DIGITS 25
501 1.1 christos
502 1.1 christos /* Structure to hold explicit sequence information. */
503 1.1 christos struct alpha_reloc_tag
504 1.1 christos {
505 1.1 christos fixS *master; /* The literal reloc. */
506 1.1 christos #ifdef OBJ_EVAX
507 1.1 christos struct symbol *sym; /* Linkage section item symbol. */
508 1.1 christos struct symbol *psym; /* Pdesc symbol. */
509 1.1 christos #endif
510 1.1 christos fixS *slaves; /* Head of linked list of lituses. */
511 1.1 christos segT segment; /* Segment relocs are in or undefined_section. */
512 1.1 christos long sequence; /* Sequence #. */
513 1.1 christos unsigned n_master; /* # of literals. */
514 1.1 christos unsigned n_slaves; /* # of lituses. */
515 1.1 christos unsigned saw_tlsgd : 1; /* True if ... */
516 1.1 christos unsigned saw_tlsldm : 1;
517 1.1 christos unsigned saw_lu_tlsgd : 1;
518 1.1 christos unsigned saw_lu_tlsldm : 1;
519 1.1 christos unsigned multi_section_p : 1; /* True if more than one section was used. */
520 1.1 christos char string[1]; /* Printable form of sequence to hash with. */
521 1.1 christos };
522 1.1 christos
523 1.1 christos /* Hash table to link up literals with the appropriate lituse. */
524 1.1 christos static struct hash_control *alpha_literal_hash;
525 1.1 christos
526 1.1 christos /* Sequence numbers for internal use by macros. */
527 1.1 christos static long next_sequence_num = -1;
528 1.1 christos
529 1.1 christos /* A table of CPU names and opcode sets. */
531 1.1 christos
532 1.1 christos static const struct cpu_type
533 1.1 christos {
534 1.1 christos const char *name;
535 1.1 christos unsigned flags;
536 1.1 christos }
537 1.1 christos cpu_types[] =
538 1.1 christos {
539 1.1 christos /* Ad hoc convention: cpu number gets palcode, process code doesn't.
540 1.1 christos This supports usage under DU 4.0b that does ".arch ev4", and
541 1.1 christos usage in MILO that does -m21064. Probably something more
542 1.1 christos specific like -m21064-pal should be used, but oh well. */
543 1.1 christos
544 1.1 christos { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
545 1.1 christos { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
546 1.1 christos { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
547 1.1 christos { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
548 1.1 christos { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
549 1.1 christos { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
550 1.1 christos { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
551 1.1 christos |AXP_OPCODE_MAX) },
552 1.1 christos { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
553 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
554 1.1 christos { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
555 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
556 1.1 christos { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
557 1.1 christos |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
558 1.1 christos
559 1.1 christos { "ev4", AXP_OPCODE_BASE },
560 1.1 christos { "ev45", AXP_OPCODE_BASE },
561 1.1 christos { "lca45", AXP_OPCODE_BASE },
562 1.1 christos { "ev5", AXP_OPCODE_BASE },
563 1.1 christos { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
564 1.1 christos { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
565 1.1 christos { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
566 1.1 christos { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
567 1.1 christos { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
568 1.1 christos
569 1.1 christos { "all", AXP_OPCODE_BASE },
570 1.1 christos { 0, 0 }
571 1.1 christos };
572 1.1 christos
573 1.1 christos /* Some instruction sets indexed by lg(size). */
574 1.1 christos static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
575 1.1 christos static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
576 1.1 christos static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
577 1.1 christos static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
578 1.1 christos static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
579 1.1 christos static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
580 1.1 christos static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
581 1.1 christos static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
582 1.1 christos static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
583 1.1 christos
584 1.1 christos static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type);
585 1.1 christos static void emit_insn (struct alpha_insn *);
586 1.1 christos static void assemble_tokens (const char *, const expressionS *, int, int);
587 1.1 christos #ifdef OBJ_EVAX
588 1.1 christos static char *s_alpha_section_name (void);
589 1.1 christos static symbolS *add_to_link_pool (symbolS *, offsetT);
590 1.1 christos #endif
591 1.1 christos
592 1.1 christos static struct alpha_reloc_tag *
594 1.1 christos get_alpha_reloc_tag (long sequence)
595 1.1 christos {
596 1.1 christos char buffer[ALPHA_RELOC_DIGITS];
597 1.1 christos struct alpha_reloc_tag *info;
598 1.1 christos
599 1.1 christos sprintf (buffer, "!%ld", sequence);
600 1.1 christos
601 1.1 christos info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
602 1.1 christos if (! info)
603 1.1 christos {
604 1.1 christos size_t len = strlen (buffer);
605 1.1 christos const char *errmsg;
606 1.1 christos
607 1.1 christos info = (struct alpha_reloc_tag *)
608 1.1 christos xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
609 1.1 christos
610 1.1 christos info->segment = now_seg;
611 1.1 christos info->sequence = sequence;
612 1.1 christos strcpy (info->string, buffer);
613 1.1 christos errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
614 1.1 christos if (errmsg)
615 1.1 christos as_fatal ("%s", errmsg);
616 1.1 christos #ifdef OBJ_EVAX
617 1.1 christos info->sym = 0;
618 1.1 christos info->psym = 0;
619 1.1 christos #endif
620 1.1 christos }
621 1.1 christos
622 1.1 christos return info;
623 1.1 christos }
624 1.1 christos
625 1.1 christos #ifndef OBJ_EVAX
626 1.1 christos
627 1.1 christos static void
628 1.1 christos alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
629 1.1 christos asection *sec,
630 1.1 christos void * ptr ATTRIBUTE_UNUSED)
631 1.1 christos {
632 1.1 christos segment_info_type *seginfo = seg_info (sec);
633 1.1 christos fixS **prevP;
634 1.1 christos fixS *fixp;
635 1.1 christos fixS *next;
636 1.1 christos fixS *slave;
637 1.1 christos
638 1.1 christos /* If seginfo is NULL, we did not create this section; don't do
639 1.1 christos anything with it. By using a pointer to a pointer, we can update
640 1.1 christos the links in place. */
641 1.1 christos if (seginfo == NULL)
642 1.1 christos return;
643 1.1 christos
644 1.1 christos /* If there are no relocations, skip the section. */
645 1.1 christos if (! seginfo->fix_root)
646 1.1 christos return;
647 1.1 christos
648 1.1 christos /* First rebuild the fixup chain without the explicit lituse and
649 1.1 christos gpdisp_lo16 relocs. */
650 1.1 christos prevP = &seginfo->fix_root;
651 1.1 christos for (fixp = seginfo->fix_root; fixp; fixp = next)
652 1.1 christos {
653 1.1 christos next = fixp->fx_next;
654 1.1 christos fixp->fx_next = (fixS *) 0;
655 1.1 christos
656 1.1 christos switch (fixp->fx_r_type)
657 1.1 christos {
658 1.1 christos case BFD_RELOC_ALPHA_LITUSE:
659 1.1 christos if (fixp->tc_fix_data.info->n_master == 0)
660 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
661 1.1 christos _("No !literal!%ld was found"),
662 1.1 christos fixp->tc_fix_data.info->sequence);
663 1.1 christos #ifdef RELOC_OP_P
664 1.1 christos if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
665 1.1 christos {
666 1.1 christos if (! fixp->tc_fix_data.info->saw_tlsgd)
667 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
668 1.1 christos _("No !tlsgd!%ld was found"),
669 1.1 christos fixp->tc_fix_data.info->sequence);
670 1.1 christos }
671 1.1 christos else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
672 1.1 christos {
673 1.1 christos if (! fixp->tc_fix_data.info->saw_tlsldm)
674 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
675 1.1 christos _("No !tlsldm!%ld was found"),
676 1.1 christos fixp->tc_fix_data.info->sequence);
677 1.1 christos }
678 1.1 christos #endif
679 1.1 christos break;
680 1.1 christos
681 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
682 1.1 christos if (fixp->tc_fix_data.info->n_master == 0)
683 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
684 1.1 christos _("No ldah !gpdisp!%ld was found"),
685 1.1 christos fixp->tc_fix_data.info->sequence);
686 1.1 christos break;
687 1.1 christos
688 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
689 1.1 christos if (fixp->tc_fix_data.info
690 1.1 christos && (fixp->tc_fix_data.info->saw_tlsgd
691 1.1 christos || fixp->tc_fix_data.info->saw_tlsldm))
692 1.1 christos break;
693 1.1 christos /* FALLTHRU */
694 1.1 christos
695 1.1 christos default:
696 1.1 christos *prevP = fixp;
697 1.1 christos prevP = &fixp->fx_next;
698 1.1 christos break;
699 1.1 christos }
700 1.1 christos }
701 1.1 christos
702 1.1 christos /* Go back and re-chain dependent relocations. They are currently
703 1.1 christos linked through the next_reloc field in reverse order, so as we
704 1.1 christos go through the next_reloc chain, we effectively reverse the chain
705 1.1 christos once again.
706 1.1 christos
707 1.1 christos Except if there is more than one !literal for a given sequence
708 1.1 christos number. In that case, the programmer and/or compiler is not sure
709 1.1 christos how control flows from literal to lituse, and we can't be sure to
710 1.1 christos get the relaxation correct.
711 1.1 christos
712 1.1 christos ??? Well, actually we could, if there are enough lituses such that
713 1.1 christos we can make each literal have at least one of each lituse type
714 1.1 christos present. Not implemented.
715 1.1 christos
716 1.1 christos Also suppress the optimization if the !literals/!lituses are spread
717 1.1 christos in different segments. This can happen with "intersting" uses of
718 1.1 christos inline assembly; examples are present in the Linux kernel semaphores. */
719 1.1 christos
720 1.1 christos for (fixp = seginfo->fix_root; fixp; fixp = next)
721 1.1 christos {
722 1.1 christos next = fixp->fx_next;
723 1.1 christos switch (fixp->fx_r_type)
724 1.1 christos {
725 1.1 christos case BFD_RELOC_ALPHA_TLSGD:
726 1.1 christos case BFD_RELOC_ALPHA_TLSLDM:
727 1.1 christos if (!fixp->tc_fix_data.info)
728 1.1 christos break;
729 1.1 christos if (fixp->tc_fix_data.info->n_master == 0)
730 1.1 christos break;
731 1.1 christos else if (fixp->tc_fix_data.info->n_master > 1)
732 1.1 christos {
733 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
734 1.1 christos _("too many !literal!%ld for %s"),
735 1.1 christos fixp->tc_fix_data.info->sequence,
736 1.1 christos (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
737 1.1 christos ? "!tlsgd" : "!tlsldm"));
738 1.1 christos break;
739 1.1 christos }
740 1.1 christos
741 1.1 christos fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
742 1.1 christos fixp->fx_next = fixp->tc_fix_data.info->master;
743 1.1 christos fixp = fixp->fx_next;
744 1.1 christos /* Fall through. */
745 1.1 christos
746 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
747 1.1 christos if (fixp->tc_fix_data.info
748 1.1 christos && fixp->tc_fix_data.info->n_master == 1
749 1.1 christos && ! fixp->tc_fix_data.info->multi_section_p)
750 1.1 christos {
751 1.1 christos for (slave = fixp->tc_fix_data.info->slaves;
752 1.1 christos slave != (fixS *) 0;
753 1.1 christos slave = slave->tc_fix_data.next_reloc)
754 1.1 christos {
755 1.1 christos slave->fx_next = fixp->fx_next;
756 1.1 christos fixp->fx_next = slave;
757 1.1 christos }
758 1.1 christos }
759 1.1 christos break;
760 1.1 christos
761 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
762 1.1 christos if (fixp->tc_fix_data.info->n_slaves == 0)
763 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
764 1.1 christos _("No lda !gpdisp!%ld was found"),
765 1.1 christos fixp->tc_fix_data.info->sequence);
766 1.1 christos else
767 1.1 christos {
768 1.1 christos slave = fixp->tc_fix_data.info->slaves;
769 1.1 christos slave->fx_next = next;
770 1.1 christos fixp->fx_next = slave;
771 1.1 christos }
772 1.1 christos break;
773 1.1 christos
774 1.1 christos default:
775 1.1 christos break;
776 1.1 christos }
777 1.1 christos }
778 1.1 christos }
779 1.1 christos
780 1.1 christos /* Before the relocations are written, reorder them, so that user
781 1.1 christos supplied !lituse relocations follow the appropriate !literal
782 1.1 christos relocations, and similarly for !gpdisp relocations. */
783 1.1 christos
784 1.1 christos void
785 1.1 christos alpha_before_fix (void)
786 1.1 christos {
787 1.1 christos if (alpha_literal_hash)
788 1.1 christos bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
789 1.1 christos }
790 1.1 christos
791 1.1 christos #endif
792 1.1 christos
793 1.1 christos #ifdef DEBUG_ALPHA
795 1.1 christos static void
796 1.1 christos debug_exp (expressionS tok[], int ntok)
797 1.1 christos {
798 1.1 christos int i;
799 1.1 christos
800 1.1 christos fprintf (stderr, "debug_exp: %d tokens", ntok);
801 1.1 christos for (i = 0; i < ntok; i++)
802 1.1 christos {
803 1.1 christos expressionS *t = &tok[i];
804 1.1 christos const char *name;
805 1.1 christos
806 1.1 christos switch (t->X_op)
807 1.1 christos {
808 1.1 christos default: name = "unknown"; break;
809 1.1 christos case O_illegal: name = "O_illegal"; break;
810 1.1 christos case O_absent: name = "O_absent"; break;
811 1.1 christos case O_constant: name = "O_constant"; break;
812 1.1 christos case O_symbol: name = "O_symbol"; break;
813 1.1 christos case O_symbol_rva: name = "O_symbol_rva"; break;
814 1.1 christos case O_register: name = "O_register"; break;
815 1.1 christos case O_big: name = "O_big"; break;
816 1.1 christos case O_uminus: name = "O_uminus"; break;
817 1.1 christos case O_bit_not: name = "O_bit_not"; break;
818 1.1 christos case O_logical_not: name = "O_logical_not"; break;
819 1.1 christos case O_multiply: name = "O_multiply"; break;
820 1.1 christos case O_divide: name = "O_divide"; break;
821 1.1 christos case O_modulus: name = "O_modulus"; break;
822 1.1 christos case O_left_shift: name = "O_left_shift"; break;
823 1.1 christos case O_right_shift: name = "O_right_shift"; break;
824 1.1 christos case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
825 1.1 christos case O_bit_or_not: name = "O_bit_or_not"; break;
826 1.1 christos case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
827 1.1 christos case O_bit_and: name = "O_bit_and"; break;
828 1.1 christos case O_add: name = "O_add"; break;
829 1.1 christos case O_subtract: name = "O_subtract"; break;
830 1.1 christos case O_eq: name = "O_eq"; break;
831 1.1 christos case O_ne: name = "O_ne"; break;
832 1.1 christos case O_lt: name = "O_lt"; break;
833 1.1 christos case O_le: name = "O_le"; break;
834 1.1 christos case O_ge: name = "O_ge"; break;
835 1.1 christos case O_gt: name = "O_gt"; break;
836 1.1 christos case O_logical_and: name = "O_logical_and"; break;
837 1.1 christos case O_logical_or: name = "O_logical_or"; break;
838 1.1 christos case O_index: name = "O_index"; break;
839 1.1 christos case O_pregister: name = "O_pregister"; break;
840 1.1 christos case O_cpregister: name = "O_cpregister"; break;
841 1.1 christos case O_literal: name = "O_literal"; break;
842 1.1 christos case O_lituse_addr: name = "O_lituse_addr"; break;
843 1.1 christos case O_lituse_base: name = "O_lituse_base"; break;
844 1.1 christos case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
845 1.1 christos case O_lituse_jsr: name = "O_lituse_jsr"; break;
846 1.1 christos case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
847 1.1 christos case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
848 1.1 christos case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break;
849 1.1 christos case O_gpdisp: name = "O_gpdisp"; break;
850 1.1 christos case O_gprelhigh: name = "O_gprelhigh"; break;
851 1.1 christos case O_gprellow: name = "O_gprellow"; break;
852 1.1 christos case O_gprel: name = "O_gprel"; break;
853 1.1 christos case O_samegp: name = "O_samegp"; break;
854 1.1 christos case O_tlsgd: name = "O_tlsgd"; break;
855 1.1 christos case O_tlsldm: name = "O_tlsldm"; break;
856 1.1 christos case O_gotdtprel: name = "O_gotdtprel"; break;
857 1.1 christos case O_dtprelhi: name = "O_dtprelhi"; break;
858 1.1 christos case O_dtprello: name = "O_dtprello"; break;
859 1.1 christos case O_dtprel: name = "O_dtprel"; break;
860 1.1 christos case O_gottprel: name = "O_gottprel"; break;
861 1.1 christos case O_tprelhi: name = "O_tprelhi"; break;
862 1.1 christos case O_tprello: name = "O_tprello"; break;
863 1.1 christos case O_tprel: name = "O_tprel"; break;
864 1.1 christos }
865 1.1 christos
866 1.1 christos fprintf (stderr, ", %s(%s, %s, %d)", name,
867 1.1 christos (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
868 1.1 christos (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
869 1.1 christos (int) t->X_add_number);
870 1.1 christos }
871 1.1 christos fprintf (stderr, "\n");
872 1.1 christos fflush (stderr);
873 1.1 christos }
874 1.1 christos #endif
875 1.1 christos
876 1.1 christos /* Parse the arguments to an opcode. */
877 1.1 christos
878 1.1 christos static int
879 1.1 christos tokenize_arguments (char *str,
880 1.1 christos expressionS tok[],
881 1.1 christos int ntok)
882 1.1 christos {
883 1.1 christos expressionS *end_tok = tok + ntok;
884 1.1 christos char *old_input_line_pointer;
885 1.1 christos int saw_comma = 0, saw_arg = 0;
886 1.1 christos #ifdef DEBUG_ALPHA
887 1.1 christos expressionS *orig_tok = tok;
888 1.1 christos #endif
889 1.1 christos #ifdef RELOC_OP_P
890 1.1 christos char *p;
891 1.1 christos const struct alpha_reloc_op_tag *r;
892 1.1 christos int c, i;
893 1.1 christos size_t len;
894 1.1 christos int reloc_found_p = 0;
895 1.1 christos #endif
896 1.1 christos
897 1.1 christos memset (tok, 0, sizeof (*tok) * ntok);
898 1.1 christos
899 1.1 christos /* Save and restore input_line_pointer around this function. */
900 1.1 christos old_input_line_pointer = input_line_pointer;
901 1.1 christos input_line_pointer = str;
902 1.1 christos
903 1.1 christos #ifdef RELOC_OP_P
904 1.1 christos /* ??? Wrest control of ! away from the regular expression parser. */
905 1.1 christos is_end_of_line[(unsigned char) '!'] = 1;
906 1.1 christos #endif
907 1.1 christos
908 1.1 christos while (tok < end_tok && *input_line_pointer)
909 1.1 christos {
910 1.1 christos SKIP_WHITESPACE ();
911 1.1 christos switch (*input_line_pointer)
912 1.1 christos {
913 1.1 christos case '\0':
914 1.1 christos goto fini;
915 1.1 christos
916 1.1 christos #ifdef RELOC_OP_P
917 1.1 christos case '!':
918 1.1 christos /* A relocation operand can be placed after the normal operand on an
919 1.1 christos assembly language statement, and has the following form:
920 1.1 christos !relocation_type!sequence_number. */
921 1.1 christos if (reloc_found_p)
922 1.1 christos {
923 1.1 christos /* Only support one relocation op per insn. */
924 1.1 christos as_bad (_("More than one relocation op per insn"));
925 1.1 christos goto err_report;
926 1.1 christos }
927 1.1 christos
928 1.1 christos if (!saw_arg)
929 1.1 christos goto err;
930 1.1 christos
931 1.1 christos ++input_line_pointer;
932 1.1 christos SKIP_WHITESPACE ();
933 1.1 christos p = input_line_pointer;
934 1.1 christos c = get_symbol_end ();
935 1.1 christos
936 1.1 christos /* Parse !relocation_type. */
937 1.1 christos len = input_line_pointer - p;
938 1.1 christos if (len == 0)
939 1.1 christos {
940 1.1 christos as_bad (_("No relocation operand"));
941 1.1 christos goto err_report;
942 1.1 christos }
943 1.1 christos
944 1.1 christos r = &alpha_reloc_op[0];
945 1.1 christos for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
946 1.1 christos if (len == r->length && memcmp (p, r->name, len) == 0)
947 1.1 christos break;
948 1.1 christos if (i < 0)
949 1.1 christos {
950 1.1 christos as_bad (_("Unknown relocation operand: !%s"), p);
951 1.1 christos goto err_report;
952 1.1 christos }
953 1.1 christos
954 1.1 christos *input_line_pointer = c;
955 1.1 christos SKIP_WHITESPACE ();
956 1.1 christos if (*input_line_pointer != '!')
957 1.1 christos {
958 1.1 christos if (r->require_seq)
959 1.1 christos {
960 1.1 christos as_bad (_("no sequence number after !%s"), p);
961 1.1 christos goto err_report;
962 1.1 christos }
963 1.1 christos
964 1.1 christos tok->X_add_number = 0;
965 1.1 christos }
966 1.1 christos else
967 1.1 christos {
968 1.1 christos if (! r->allow_seq)
969 1.1 christos {
970 1.1 christos as_bad (_("!%s does not use a sequence number"), p);
971 1.1 christos goto err_report;
972 1.1 christos }
973 1.1 christos
974 1.1 christos input_line_pointer++;
975 1.1 christos
976 1.1 christos /* Parse !sequence_number. */
977 1.1 christos expression (tok);
978 1.1 christos if (tok->X_op != O_constant || tok->X_add_number <= 0)
979 1.1 christos {
980 1.1 christos as_bad (_("Bad sequence number: !%s!%s"),
981 1.1 christos r->name, input_line_pointer);
982 1.1 christos goto err_report;
983 1.1 christos }
984 1.1 christos }
985 1.1 christos
986 1.1 christos tok->X_op = r->op;
987 1.1 christos reloc_found_p = 1;
988 1.1 christos ++tok;
989 1.1 christos break;
990 1.1 christos #endif /* RELOC_OP_P */
991 1.1 christos
992 1.1 christos case ',':
993 1.1 christos ++input_line_pointer;
994 1.1 christos if (saw_comma || !saw_arg)
995 1.1 christos goto err;
996 1.1 christos saw_comma = 1;
997 1.1 christos break;
998 1.1 christos
999 1.1 christos case '(':
1000 1.1 christos {
1001 1.1 christos char *hold = input_line_pointer++;
1002 1.1 christos
1003 1.1 christos /* First try for parenthesized register ... */
1004 1.1 christos expression (tok);
1005 1.1 christos if (*input_line_pointer == ')' && tok->X_op == O_register)
1006 1.1 christos {
1007 1.1 christos tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1008 1.1 christos saw_comma = 0;
1009 1.1 christos saw_arg = 1;
1010 1.1 christos ++input_line_pointer;
1011 1.1 christos ++tok;
1012 1.1 christos break;
1013 1.1 christos }
1014 1.1 christos
1015 1.1 christos /* ... then fall through to plain expression. */
1016 1.1 christos input_line_pointer = hold;
1017 1.1 christos }
1018 1.1 christos
1019 1.1 christos default:
1020 1.1 christos if (saw_arg && !saw_comma)
1021 1.1 christos goto err;
1022 1.1 christos
1023 1.1 christos expression (tok);
1024 1.1 christos if (tok->X_op == O_illegal || tok->X_op == O_absent)
1025 1.1 christos goto err;
1026 1.1 christos
1027 1.1 christos saw_comma = 0;
1028 1.1 christos saw_arg = 1;
1029 1.1 christos ++tok;
1030 1.1 christos break;
1031 1.1 christos }
1032 1.1 christos }
1033 1.1 christos
1034 1.1 christos fini:
1035 1.1 christos if (saw_comma)
1036 1.1 christos goto err;
1037 1.1 christos input_line_pointer = old_input_line_pointer;
1038 1.1 christos
1039 1.1 christos #ifdef DEBUG_ALPHA
1040 1.1 christos debug_exp (orig_tok, ntok - (end_tok - tok));
1041 1.1 christos #endif
1042 1.1 christos #ifdef RELOC_OP_P
1043 1.1 christos is_end_of_line[(unsigned char) '!'] = 0;
1044 1.1 christos #endif
1045 1.1 christos
1046 1.1 christos return ntok - (end_tok - tok);
1047 1.1 christos
1048 1.1 christos err:
1049 1.1 christos #ifdef RELOC_OP_P
1050 1.1 christos is_end_of_line[(unsigned char) '!'] = 0;
1051 1.1 christos #endif
1052 1.1 christos input_line_pointer = old_input_line_pointer;
1053 1.1 christos return TOKENIZE_ERROR;
1054 1.1 christos
1055 1.1 christos #ifdef RELOC_OP_P
1056 1.1 christos err_report:
1057 1.1 christos is_end_of_line[(unsigned char) '!'] = 0;
1058 1.1 christos #endif
1059 1.1 christos input_line_pointer = old_input_line_pointer;
1060 1.1 christos return TOKENIZE_ERROR_REPORT;
1061 1.1 christos }
1062 1.1 christos
1063 1.1 christos /* Search forward through all variants of an opcode looking for a
1064 1.1 christos syntax match. */
1065 1.1 christos
1066 1.1 christos static const struct alpha_opcode *
1067 1.1 christos find_opcode_match (const struct alpha_opcode *first_opcode,
1068 1.1 christos const expressionS *tok,
1069 1.1 christos int *pntok,
1070 1.1 christos int *pcpumatch)
1071 1.1 christos {
1072 1.1 christos const struct alpha_opcode *opcode = first_opcode;
1073 1.1 christos int ntok = *pntok;
1074 1.1 christos int got_cpu_match = 0;
1075 1.1 christos
1076 1.1 christos do
1077 1.1 christos {
1078 1.1 christos const unsigned char *opidx;
1079 1.1 christos int tokidx = 0;
1080 1.1 christos
1081 1.1 christos /* Don't match opcodes that don't exist on this architecture. */
1082 1.1 christos if (!(opcode->flags & alpha_target))
1083 1.1 christos goto match_failed;
1084 1.1 christos
1085 1.1 christos got_cpu_match = 1;
1086 1.1 christos
1087 1.1 christos for (opidx = opcode->operands; *opidx; ++opidx)
1088 1.1 christos {
1089 1.1 christos const struct alpha_operand *operand = &alpha_operands[*opidx];
1090 1.1 christos
1091 1.1 christos /* Only take input from real operands. */
1092 1.1 christos if (operand->flags & AXP_OPERAND_FAKE)
1093 1.1 christos continue;
1094 1.1 christos
1095 1.1 christos /* When we expect input, make sure we have it. */
1096 1.1 christos if (tokidx >= ntok)
1097 1.1 christos {
1098 1.1 christos if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1099 1.1 christos goto match_failed;
1100 1.1 christos continue;
1101 1.1 christos }
1102 1.1 christos
1103 1.1 christos /* Match operand type with expression type. */
1104 1.1 christos switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1105 1.1 christos {
1106 1.1 christos case AXP_OPERAND_IR:
1107 1.1 christos if (tok[tokidx].X_op != O_register
1108 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
1109 1.1 christos goto match_failed;
1110 1.1 christos break;
1111 1.1 christos case AXP_OPERAND_FPR:
1112 1.1 christos if (tok[tokidx].X_op != O_register
1113 1.1 christos || !is_fpr_num (tok[tokidx].X_add_number))
1114 1.1 christos goto match_failed;
1115 1.1 christos break;
1116 1.1 christos case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1117 1.1 christos if (tok[tokidx].X_op != O_pregister
1118 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
1119 1.1 christos goto match_failed;
1120 1.1 christos break;
1121 1.1 christos case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1122 1.1 christos if (tok[tokidx].X_op != O_cpregister
1123 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
1124 1.1 christos goto match_failed;
1125 1.1 christos break;
1126 1.1 christos
1127 1.1 christos case AXP_OPERAND_RELATIVE:
1128 1.1 christos case AXP_OPERAND_SIGNED:
1129 1.1 christos case AXP_OPERAND_UNSIGNED:
1130 1.1 christos switch (tok[tokidx].X_op)
1131 1.1 christos {
1132 1.1 christos case O_illegal:
1133 1.1 christos case O_absent:
1134 1.1 christos case O_register:
1135 1.1 christos case O_pregister:
1136 1.1 christos case O_cpregister:
1137 1.1 christos goto match_failed;
1138 1.1 christos
1139 1.1 christos default:
1140 1.1 christos break;
1141 1.1 christos }
1142 1.1 christos break;
1143 1.1 christos
1144 1.1 christos default:
1145 1.1 christos /* Everything else should have been fake. */
1146 1.1 christos abort ();
1147 1.1 christos }
1148 1.1 christos ++tokidx;
1149 1.1 christos }
1150 1.1 christos
1151 1.1 christos /* Possible match -- did we use all of our input? */
1152 1.1 christos if (tokidx == ntok)
1153 1.1 christos {
1154 1.1 christos *pntok = ntok;
1155 1.1 christos return opcode;
1156 1.1 christos }
1157 1.1 christos
1158 1.1 christos match_failed:;
1159 1.1 christos }
1160 1.1 christos while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1161 1.1 christos && !strcmp (opcode->name, first_opcode->name));
1162 1.1 christos
1163 1.1 christos if (*pcpumatch)
1164 1.1 christos *pcpumatch = got_cpu_match;
1165 1.1 christos
1166 1.1 christos return NULL;
1167 1.1 christos }
1168 1.1 christos
1169 1.1 christos /* Given an opcode name and a pre-tokenized set of arguments, assemble
1170 1.1 christos the insn, but do not emit it.
1171 1.1 christos
1172 1.1 christos Note that this implies no macros allowed, since we can't store more
1173 1.1 christos than one insn in an insn structure. */
1174 1.1 christos
1175 1.1 christos static void
1176 1.1 christos assemble_tokens_to_insn (const char *opname,
1177 1.1 christos const expressionS *tok,
1178 1.1 christos int ntok,
1179 1.1 christos struct alpha_insn *insn)
1180 1.1 christos {
1181 1.1 christos const struct alpha_opcode *opcode;
1182 1.1 christos
1183 1.1 christos /* Search opcodes. */
1184 1.1 christos opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1185 1.1 christos if (opcode)
1186 1.1 christos {
1187 1.1 christos int cpumatch;
1188 1.1 christos opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1189 1.1 christos if (opcode)
1190 1.1 christos {
1191 1.1 christos assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1192 1.1 christos return;
1193 1.1 christos }
1194 1.1 christos else if (cpumatch)
1195 1.1 christos as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1196 1.1 christos else
1197 1.1 christos as_bad (_("opcode `%s' not supported for target %s"), opname,
1198 1.1 christos alpha_target_name);
1199 1.1 christos }
1200 1.1 christos else
1201 1.1 christos as_bad (_("unknown opcode `%s'"), opname);
1202 1.1 christos }
1203 1.1 christos
1204 1.1 christos /* Build a BFD section with its flags set appropriately for the .lita,
1205 1.1 christos .lit8, or .lit4 sections. */
1206 1.1 christos
1207 1.1 christos static void
1208 1.1 christos create_literal_section (const char *name,
1209 1.1 christos segT *secp,
1210 1.1 christos symbolS **symp)
1211 1.1 christos {
1212 1.1 christos segT current_section = now_seg;
1213 1.1 christos int current_subsec = now_subseg;
1214 1.1 christos segT new_sec;
1215 1.1 christos
1216 1.1 christos *secp = new_sec = subseg_new (name, 0);
1217 1.1 christos subseg_set (current_section, current_subsec);
1218 1.1 christos bfd_set_section_alignment (stdoutput, new_sec, 4);
1219 1.1 christos bfd_set_section_flags (stdoutput, new_sec,
1220 1.1 christos SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1221 1.1 christos | SEC_DATA);
1222 1.1 christos
1223 1.1 christos S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1224 1.1 christos }
1225 1.1 christos
1226 1.1 christos /* Load a (partial) expression into a target register.
1227 1.1 christos
1228 1.1 christos If poffset is not null, after the call it will either contain
1229 1.1 christos O_constant 0, or a 16-bit offset appropriate for any MEM format
1230 1.1 christos instruction. In addition, pbasereg will be modified to point to
1231 1.1 christos the base register to use in that MEM format instruction.
1232 1.1 christos
1233 1.1 christos In any case, *pbasereg should contain a base register to add to the
1234 1.1 christos expression. This will normally be either AXP_REG_ZERO or
1235 1.1 christos alpha_gp_register. Symbol addresses will always be loaded via $gp,
1236 1.1 christos so "foo($0)" is interpreted as adding the address of foo to $0;
1237 1.1 christos i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1238 1.1 christos but this is what OSF/1 does.
1239 1.1 christos
1240 1.1 christos If explicit relocations of the form !literal!<number> are allowed,
1241 1.1 christos and used, then explicit_reloc with be an expression pointer.
1242 1.1 christos
1243 1.1 christos Finally, the return value is nonzero if the calling macro may emit
1244 1.1 christos a LITUSE reloc if otherwise appropriate; the return value is the
1245 1.1 christos sequence number to use. */
1246 1.1 christos
1247 1.1 christos static long
1248 1.1 christos load_expression (int targreg,
1249 1.1 christos const expressionS *exp,
1250 1.1 christos int *pbasereg,
1251 1.1 christos expressionS *poffset,
1252 1.1 christos const char *opname)
1253 1.1 christos {
1254 1.1 christos long emit_lituse = 0;
1255 1.1 christos offsetT addend = exp->X_add_number;
1256 1.1 christos int basereg = *pbasereg;
1257 1.1 christos struct alpha_insn insn;
1258 1.1 christos expressionS newtok[3];
1259 1.1 christos
1260 1.1 christos switch (exp->X_op)
1261 1.1 christos {
1262 1.1 christos case O_symbol:
1263 1.1 christos {
1264 1.1 christos #ifdef OBJ_ECOFF
1265 1.1 christos offsetT lit;
1266 1.1 christos
1267 1.1 christos /* Attempt to reduce .lit load by splitting the offset from
1268 1.1 christos its symbol when possible, but don't create a situation in
1269 1.1 christos which we'd fail. */
1270 1.1 christos if (!range_signed_32 (addend) &&
1271 1.1 christos (alpha_noat_on || targreg == AXP_REG_AT))
1272 1.1 christos {
1273 1.1 christos lit = add_to_literal_pool (exp->X_add_symbol, addend,
1274 1.1 christos alpha_lita_section, 8);
1275 1.1 christos addend = 0;
1276 1.1 christos }
1277 1.1 christos else
1278 1.1 christos lit = add_to_literal_pool (exp->X_add_symbol, 0,
1279 1.1 christos alpha_lita_section, 8);
1280 1.1 christos
1281 1.1 christos if (lit >= 0x8000)
1282 1.1 christos as_fatal (_("overflow in literal (.lita) table"));
1283 1.1 christos
1284 1.1 christos /* Emit "ldq r, lit(gp)". */
1285 1.1 christos
1286 1.1 christos if (basereg != alpha_gp_register && targreg == basereg)
1287 1.1 christos {
1288 1.1 christos if (alpha_noat_on)
1289 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
1290 1.1 christos if (targreg == AXP_REG_AT)
1291 1.1 christos as_bad (_("macro requires $at while $at in use"));
1292 1.1 christos
1293 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
1294 1.1 christos }
1295 1.1 christos else
1296 1.1 christos set_tok_reg (newtok[0], targreg);
1297 1.1 christos
1298 1.1 christos set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1299 1.1 christos set_tok_preg (newtok[2], alpha_gp_register);
1300 1.1 christos
1301 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1302 1.1 christos
1303 1.1 christos gas_assert (insn.nfixups == 1);
1304 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1305 1.1 christos insn.sequence = emit_lituse = next_sequence_num--;
1306 1.1 christos #endif /* OBJ_ECOFF */
1307 1.1 christos #ifdef OBJ_ELF
1308 1.1 christos /* Emit "ldq r, gotoff(gp)". */
1309 1.1 christos
1310 1.1 christos if (basereg != alpha_gp_register && targreg == basereg)
1311 1.1 christos {
1312 1.1 christos if (alpha_noat_on)
1313 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
1314 1.1 christos if (targreg == AXP_REG_AT)
1315 1.1 christos as_bad (_("macro requires $at while $at in use"));
1316 1.1 christos
1317 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
1318 1.1 christos }
1319 1.1 christos else
1320 1.1 christos set_tok_reg (newtok[0], targreg);
1321 1.1 christos
1322 1.1 christos /* XXX: Disable this .got minimizing optimization so that we can get
1323 1.1 christos better instruction offset knowledge in the compiler. This happens
1324 1.1 christos very infrequently anyway. */
1325 1.1 christos if (1
1326 1.1 christos || (!range_signed_32 (addend)
1327 1.1 christos && (alpha_noat_on || targreg == AXP_REG_AT)))
1328 1.1 christos {
1329 1.1 christos newtok[1] = *exp;
1330 1.1 christos addend = 0;
1331 1.1 christos }
1332 1.1 christos else
1333 1.1 christos set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1334 1.1 christos
1335 1.1 christos set_tok_preg (newtok[2], alpha_gp_register);
1336 1.1 christos
1337 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1338 1.1 christos
1339 1.1 christos gas_assert (insn.nfixups == 1);
1340 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1341 1.1 christos insn.sequence = emit_lituse = next_sequence_num--;
1342 1.1 christos #endif /* OBJ_ELF */
1343 1.1 christos #ifdef OBJ_EVAX
1344 1.1 christos /* Find symbol or symbol pointer in link section. */
1345 1.1 christos
1346 1.1 christos if (exp->X_add_symbol == alpha_evax_proc->symbol)
1347 1.1 christos {
1348 1.1 christos /* Linkage-relative expression. */
1349 1.1 christos set_tok_reg (newtok[0], targreg);
1350 1.1 christos
1351 1.1 christos if (range_signed_16 (addend))
1352 1.1 christos {
1353 1.1 christos set_tok_const (newtok[1], addend);
1354 1.1 christos addend = 0;
1355 1.1 christos }
1356 1.1 christos else
1357 1.1 christos {
1358 1.1 christos set_tok_const (newtok[1], 0);
1359 1.1 christos }
1360 1.1 christos set_tok_preg (newtok[2], basereg);
1361 1.1 christos assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1362 1.1 christos }
1363 1.1 christos else
1364 1.1 christos {
1365 1.1 christos const char *symname = S_GET_NAME (exp->X_add_symbol);
1366 1.1 christos const char *ptr1, *ptr2;
1367 1.1 christos int symlen = strlen (symname);
1368 1.1 christos
1369 1.1 christos if ((symlen > 4 &&
1370 1.1 christos strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
1371 1.1 christos {
1372 1.1 christos /* Access to an item whose address is stored in the linkage
1373 1.1 christos section. Just read the address. */
1374 1.1 christos set_tok_reg (newtok[0], targreg);
1375 1.1 christos
1376 1.1 christos newtok[1] = *exp;
1377 1.1 christos newtok[1].X_op = O_subtract;
1378 1.1 christos newtok[1].X_op_symbol = alpha_evax_proc->symbol;
1379 1.1 christos
1380 1.1 christos set_tok_preg (newtok[2], basereg);
1381 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1382 1.1 christos alpha_linkage_symbol = exp->X_add_symbol;
1383 1.1 christos
1384 1.1 christos if (poffset)
1385 1.1 christos set_tok_const (*poffset, 0);
1386 1.1 christos
1387 1.1 christos if (alpha_flag_replace && targreg == 26)
1388 1.1 christos {
1389 1.1 christos /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */
1390 1.1 christos char *ensymname;
1391 1.1 christos symbolS *ensym;
1392 1.1 christos
1393 1.1 christos /* Build the entry name as 'NAME..en'. */
1394 1.1 christos ptr1 = strstr (symname, "..") + 2;
1395 1.1 christos if (ptr1 > ptr2)
1396 1.1 christos ptr1 = symname;
1397 1.1 christos ensymname = (char *) alloca (ptr2 - ptr1 + 5);
1398 1.1 christos memcpy (ensymname, ptr1, ptr2 - ptr1);
1399 1.1 christos memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
1400 1.1 christos
1401 1.1 christos gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1402 1.1 christos insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
1403 1.1 christos ensym = symbol_find_or_make (ensymname);
1404 1.1 christos symbol_mark_used (ensym);
1405 1.1 christos /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH
1406 1.1 christos case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker
1407 1.1 christos Utility Manual. */
1408 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_symbol;
1409 1.1 christos insn.fixups[insn.nfixups].exp.X_add_symbol = ensym;
1410 1.1 christos insn.fixups[insn.nfixups].exp.X_add_number = 0;
1411 1.1 christos insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1412 1.1 christos insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1413 1.1 christos insn.nfixups++;
1414 1.1 christos
1415 1.1 christos /* ??? Force bsym to be instantiated now, as it will be
1416 1.1 christos too late to do so in tc_gen_reloc. */
1417 1.1 christos symbol_get_bfdsym (exp->X_add_symbol);
1418 1.1 christos }
1419 1.1 christos else if (alpha_flag_replace && targreg == 27)
1420 1.1 christos {
1421 1.1 christos /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'. */
1422 1.1 christos char *psymname;
1423 1.1 christos symbolS *psym;
1424 1.1 christos
1425 1.1 christos /* Extract NAME. */
1426 1.1 christos ptr1 = strstr (symname, "..") + 2;
1427 1.1 christos if (ptr1 > ptr2)
1428 1.1 christos ptr1 = symname;
1429 1.1 christos psymname = (char *) alloca (ptr2 - ptr1 + 1);
1430 1.1 christos memcpy (psymname, ptr1, ptr2 - ptr1);
1431 1.1 christos psymname [ptr2 - ptr1] = 0;
1432 1.1 christos
1433 1.1 christos gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1434 1.1 christos insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
1435 1.1 christos psym = symbol_find_or_make (psymname);
1436 1.1 christos symbol_mark_used (psym);
1437 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_subtract;
1438 1.1 christos insn.fixups[insn.nfixups].exp.X_add_symbol = psym;
1439 1.1 christos insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol;
1440 1.1 christos insn.fixups[insn.nfixups].exp.X_add_number = 0;
1441 1.1 christos insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1442 1.1 christos insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1443 1.1 christos insn.nfixups++;
1444 1.1 christos }
1445 1.1 christos
1446 1.1 christos emit_insn (&insn);
1447 1.1 christos return 0;
1448 1.1 christos }
1449 1.1 christos else
1450 1.1 christos {
1451 1.1 christos /* Not in the linkage section. Put the value into the linkage
1452 1.1 christos section. */
1453 1.1 christos symbolS *linkexp;
1454 1.1 christos
1455 1.1 christos if (!range_signed_32 (addend))
1456 1.1 christos addend = sign_extend_32 (addend);
1457 1.1 christos linkexp = add_to_link_pool (exp->X_add_symbol, 0);
1458 1.1 christos set_tok_reg (newtok[0], targreg);
1459 1.1 christos set_tok_sym (newtok[1], linkexp, 0);
1460 1.1 christos set_tok_preg (newtok[2], basereg);
1461 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1462 1.1 christos }
1463 1.1 christos }
1464 1.1 christos #endif /* OBJ_EVAX */
1465 1.1 christos
1466 1.1 christos emit_insn (&insn);
1467 1.1 christos
1468 1.1 christos #ifndef OBJ_EVAX
1469 1.1 christos if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1470 1.1 christos {
1471 1.1 christos /* Emit "addq r, base, r". */
1472 1.1 christos
1473 1.1 christos set_tok_reg (newtok[1], basereg);
1474 1.1 christos set_tok_reg (newtok[2], targreg);
1475 1.1 christos assemble_tokens ("addq", newtok, 3, 0);
1476 1.1 christos }
1477 1.1 christos #endif
1478 1.1 christos basereg = targreg;
1479 1.1 christos }
1480 1.1 christos break;
1481 1.1 christos
1482 1.1 christos case O_constant:
1483 1.1 christos break;
1484 1.1 christos
1485 1.1 christos case O_subtract:
1486 1.1 christos /* Assume that this difference expression will be resolved to an
1487 1.1 christos absolute value and that that value will fit in 16 bits. */
1488 1.1 christos
1489 1.1 christos set_tok_reg (newtok[0], targreg);
1490 1.1 christos newtok[1] = *exp;
1491 1.1 christos set_tok_preg (newtok[2], basereg);
1492 1.1 christos assemble_tokens (opname, newtok, 3, 0);
1493 1.1 christos
1494 1.1 christos if (poffset)
1495 1.1 christos set_tok_const (*poffset, 0);
1496 1.1 christos return 0;
1497 1.1 christos
1498 1.1 christos case O_big:
1499 1.1 christos if (exp->X_add_number > 0)
1500 1.1 christos as_bad (_("bignum invalid; zero assumed"));
1501 1.1 christos else
1502 1.1 christos as_bad (_("floating point number invalid; zero assumed"));
1503 1.1 christos addend = 0;
1504 1.1 christos break;
1505 1.1 christos
1506 1.1 christos default:
1507 1.1 christos as_bad (_("can't handle expression"));
1508 1.1 christos addend = 0;
1509 1.1 christos break;
1510 1.1 christos }
1511 1.1 christos
1512 1.1 christos if (!range_signed_32 (addend))
1513 1.1 christos {
1514 1.1 christos #ifdef OBJ_EVAX
1515 1.1 christos symbolS *litexp;
1516 1.1 christos #else
1517 1.1 christos offsetT lit;
1518 1.1 christos long seq_num = next_sequence_num--;
1519 1.1 christos #endif
1520 1.1 christos
1521 1.1 christos /* For 64-bit addends, just put it in the literal pool. */
1522 1.1 christos #ifdef OBJ_EVAX
1523 1.1 christos /* Emit "ldq targreg, lit(basereg)". */
1524 1.1 christos litexp = add_to_link_pool (section_symbol (absolute_section), addend);
1525 1.1 christos set_tok_reg (newtok[0], targreg);
1526 1.1 christos set_tok_sym (newtok[1], litexp, 0);
1527 1.1 christos set_tok_preg (newtok[2], alpha_gp_register);
1528 1.1 christos assemble_tokens ("ldq", newtok, 3, 0);
1529 1.1 christos #else
1530 1.1 christos
1531 1.1 christos if (alpha_lit8_section == NULL)
1532 1.1 christos {
1533 1.1 christos create_literal_section (".lit8",
1534 1.1 christos &alpha_lit8_section,
1535 1.1 christos &alpha_lit8_symbol);
1536 1.1 christos
1537 1.1 christos #ifdef OBJ_ECOFF
1538 1.1 christos alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1539 1.1 christos alpha_lita_section, 8);
1540 1.1 christos if (alpha_lit8_literal >= 0x8000)
1541 1.1 christos as_fatal (_("overflow in literal (.lita) table"));
1542 1.1 christos #endif
1543 1.1 christos }
1544 1.1 christos
1545 1.1 christos lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1546 1.1 christos if (lit >= 0x8000)
1547 1.1 christos as_fatal (_("overflow in literal (.lit8) table"));
1548 1.1 christos
1549 1.1 christos /* Emit "lda litreg, .lit8+0x8000". */
1550 1.1 christos
1551 1.1 christos if (targreg == basereg)
1552 1.1 christos {
1553 1.1 christos if (alpha_noat_on)
1554 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
1555 1.1 christos if (targreg == AXP_REG_AT)
1556 1.1 christos as_bad (_("macro requires $at while $at in use"));
1557 1.1 christos
1558 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
1559 1.1 christos }
1560 1.1 christos else
1561 1.1 christos set_tok_reg (newtok[0], targreg);
1562 1.1 christos #ifdef OBJ_ECOFF
1563 1.1 christos set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1564 1.1 christos #endif
1565 1.1 christos #ifdef OBJ_ELF
1566 1.1 christos set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1567 1.1 christos #endif
1568 1.1 christos set_tok_preg (newtok[2], alpha_gp_register);
1569 1.1 christos
1570 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1571 1.1 christos
1572 1.1 christos gas_assert (insn.nfixups == 1);
1573 1.1 christos #ifdef OBJ_ECOFF
1574 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1575 1.1 christos #endif
1576 1.1 christos #ifdef OBJ_ELF
1577 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1578 1.1 christos #endif
1579 1.1 christos insn.sequence = seq_num;
1580 1.1 christos
1581 1.1 christos emit_insn (&insn);
1582 1.1 christos
1583 1.1 christos /* Emit "ldq litreg, lit(litreg)". */
1584 1.1 christos
1585 1.1 christos set_tok_const (newtok[1], lit);
1586 1.1 christos set_tok_preg (newtok[2], newtok[0].X_add_number);
1587 1.1 christos
1588 1.1 christos assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1589 1.1 christos
1590 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
1591 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1592 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
1593 1.1 christos insn.nfixups++;
1594 1.1 christos insn.sequence = seq_num;
1595 1.1 christos emit_lituse = 0;
1596 1.1 christos
1597 1.1 christos emit_insn (&insn);
1598 1.1 christos
1599 1.1 christos /* Emit "addq litreg, base, target". */
1600 1.1 christos
1601 1.1 christos if (basereg != AXP_REG_ZERO)
1602 1.1 christos {
1603 1.1 christos set_tok_reg (newtok[1], basereg);
1604 1.1 christos set_tok_reg (newtok[2], targreg);
1605 1.1 christos assemble_tokens ("addq", newtok, 3, 0);
1606 1.1 christos }
1607 1.1 christos #endif /* !OBJ_EVAX */
1608 1.1 christos
1609 1.1 christos if (poffset)
1610 1.1 christos set_tok_const (*poffset, 0);
1611 1.1 christos *pbasereg = targreg;
1612 1.1 christos }
1613 1.1 christos else
1614 1.1 christos {
1615 1.1 christos offsetT low, high, extra, tmp;
1616 1.1 christos
1617 1.1 christos /* For 32-bit operands, break up the addend. */
1618 1.1 christos
1619 1.1 christos low = sign_extend_16 (addend);
1620 1.1 christos tmp = addend - low;
1621 1.1 christos high = sign_extend_16 (tmp >> 16);
1622 1.1 christos
1623 1.1 christos if (tmp - (high << 16))
1624 1.1 christos {
1625 1.1 christos extra = 0x4000;
1626 1.1 christos tmp -= 0x40000000;
1627 1.1 christos high = sign_extend_16 (tmp >> 16);
1628 1.1 christos }
1629 1.1 christos else
1630 1.1 christos extra = 0;
1631 1.1 christos
1632 1.1 christos set_tok_reg (newtok[0], targreg);
1633 1.1 christos set_tok_preg (newtok[2], basereg);
1634 1.1 christos
1635 1.1 christos if (extra)
1636 1.1 christos {
1637 1.1 christos /* Emit "ldah r, extra(r). */
1638 1.1 christos set_tok_const (newtok[1], extra);
1639 1.1 christos assemble_tokens ("ldah", newtok, 3, 0);
1640 1.1 christos set_tok_preg (newtok[2], basereg = targreg);
1641 1.1 christos }
1642 1.1 christos
1643 1.1 christos if (high)
1644 1.1 christos {
1645 1.1 christos /* Emit "ldah r, high(r). */
1646 1.1 christos set_tok_const (newtok[1], high);
1647 1.1 christos assemble_tokens ("ldah", newtok, 3, 0);
1648 1.1 christos basereg = targreg;
1649 1.1 christos set_tok_preg (newtok[2], basereg);
1650 1.1 christos }
1651 1.1 christos
1652 1.1 christos if ((low && !poffset) || (!poffset && basereg != targreg))
1653 1.1 christos {
1654 1.1 christos /* Emit "lda r, low(base)". */
1655 1.1 christos set_tok_const (newtok[1], low);
1656 1.1 christos assemble_tokens ("lda", newtok, 3, 0);
1657 1.1 christos basereg = targreg;
1658 1.1 christos low = 0;
1659 1.1 christos }
1660 1.1 christos
1661 1.1 christos if (poffset)
1662 1.1 christos set_tok_const (*poffset, low);
1663 1.1 christos *pbasereg = basereg;
1664 1.1 christos }
1665 1.1 christos
1666 1.1 christos return emit_lituse;
1667 1.1 christos }
1668 1.1 christos
1669 1.1 christos /* The lda macro differs from the lda instruction in that it handles
1670 1.1 christos most simple expressions, particularly symbol address loads and
1671 1.1 christos large constants. */
1672 1.1 christos
1673 1.1 christos static void
1674 1.1 christos emit_lda (const expressionS *tok,
1675 1.1 christos int ntok,
1676 1.1 christos const void * unused ATTRIBUTE_UNUSED)
1677 1.1 christos {
1678 1.1 christos int basereg;
1679 1.1 christos
1680 1.1 christos if (ntok == 2)
1681 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1682 1.1 christos else
1683 1.1 christos basereg = tok[2].X_add_number;
1684 1.1 christos
1685 1.1 christos (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda");
1686 1.1 christos }
1687 1.1 christos
1688 1.1 christos /* The ldah macro differs from the ldah instruction in that it has $31
1689 1.1 christos as an implied base register. */
1690 1.1 christos
1691 1.1 christos static void
1692 1.1 christos emit_ldah (const expressionS *tok,
1693 1.1 christos int ntok ATTRIBUTE_UNUSED,
1694 1.1 christos const void * unused ATTRIBUTE_UNUSED)
1695 1.1 christos {
1696 1.1 christos expressionS newtok[3];
1697 1.1 christos
1698 1.1 christos newtok[0] = tok[0];
1699 1.1 christos newtok[1] = tok[1];
1700 1.1 christos set_tok_preg (newtok[2], AXP_REG_ZERO);
1701 1.1 christos
1702 1.1 christos assemble_tokens ("ldah", newtok, 3, 0);
1703 1.1 christos }
1704 1.1 christos
1705 1.1 christos /* Called internally to handle all alignment needs. This takes care
1706 1.1 christos of eliding calls to frag_align if'n the cached current alignment
1707 1.1 christos says we've already got it, as well as taking care of the auto-align
1708 1.1 christos feature wrt labels. */
1709 1.1 christos
1710 1.1 christos static void
1711 1.1 christos alpha_align (int n,
1712 1.1 christos char *pfill,
1713 1.1 christos symbolS *label,
1714 1.1 christos int force ATTRIBUTE_UNUSED)
1715 1.1 christos {
1716 1.1 christos if (alpha_current_align >= n)
1717 1.1 christos return;
1718 1.1 christos
1719 1.1 christos if (pfill == NULL)
1720 1.1 christos {
1721 1.1 christos if (subseg_text_p (now_seg))
1722 1.1 christos frag_align_code (n, 0);
1723 1.1 christos else
1724 1.1 christos frag_align (n, 0, 0);
1725 1.1 christos }
1726 1.1 christos else
1727 1.1 christos frag_align (n, *pfill, 0);
1728 1.1 christos
1729 1.1 christos alpha_current_align = n;
1730 1.1 christos
1731 1.1 christos if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1732 1.1 christos {
1733 1.1 christos symbol_set_frag (label, frag_now);
1734 1.1 christos S_SET_VALUE (label, (valueT) frag_now_fix ());
1735 1.1 christos }
1736 1.1 christos
1737 1.1 christos record_alignment (now_seg, n);
1738 1.1 christos
1739 1.1 christos /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1740 1.1 christos in a reloc for the linker to see. */
1741 1.1 christos }
1742 1.1 christos
1743 1.1 christos /* Actually output an instruction with its fixup. */
1744 1.1 christos
1745 1.1 christos static void
1746 1.1 christos emit_insn (struct alpha_insn *insn)
1747 1.1 christos {
1748 1.1 christos char *f;
1749 1.1 christos int i;
1750 1.1 christos
1751 1.1 christos /* Take care of alignment duties. */
1752 1.1 christos if (alpha_auto_align_on && alpha_current_align < 2)
1753 1.1 christos alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1754 1.1 christos if (alpha_current_align > 2)
1755 1.1 christos alpha_current_align = 2;
1756 1.1 christos alpha_insn_label = NULL;
1757 1.1 christos
1758 1.1 christos /* Write out the instruction. */
1759 1.1 christos f = frag_more (4);
1760 1.1 christos md_number_to_chars (f, insn->insn, 4);
1761 1.1 christos
1762 1.1 christos #ifdef OBJ_ELF
1763 1.1 christos dwarf2_emit_insn (4);
1764 1.1 christos #endif
1765 1.1 christos
1766 1.1 christos /* Apply the fixups in order. */
1767 1.1 christos for (i = 0; i < insn->nfixups; ++i)
1768 1.1 christos {
1769 1.1 christos const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1770 1.1 christos struct alpha_fixup *fixup = &insn->fixups[i];
1771 1.1 christos struct alpha_reloc_tag *info = NULL;
1772 1.1 christos int size, pcrel;
1773 1.1 christos fixS *fixP;
1774 1.1 christos
1775 1.1 christos /* Some fixups are only used internally and so have no howto. */
1776 1.1 christos if ((int) fixup->reloc < 0)
1777 1.1 christos {
1778 1.1 christos operand = &alpha_operands[-(int) fixup->reloc];
1779 1.1 christos size = 4;
1780 1.1 christos pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1781 1.1 christos }
1782 1.1 christos else if (fixup->reloc > BFD_RELOC_UNUSED
1783 1.1 christos || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1784 1.1 christos || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1785 1.1 christos {
1786 1.1 christos size = 2;
1787 1.1 christos pcrel = 0;
1788 1.1 christos }
1789 1.1 christos else
1790 1.1 christos {
1791 1.1 christos reloc_howto_type *reloc_howto =
1792 1.1 christos bfd_reloc_type_lookup (stdoutput,
1793 1.1 christos (bfd_reloc_code_real_type) fixup->reloc);
1794 1.1 christos gas_assert (reloc_howto);
1795 1.1 christos
1796 1.1 christos size = bfd_get_reloc_size (reloc_howto);
1797 1.1 christos
1798 1.1 christos switch (fixup->reloc)
1799 1.1 christos {
1800 1.1 christos #ifdef OBJ_EVAX
1801 1.1 christos case BFD_RELOC_ALPHA_NOP:
1802 1.1 christos case BFD_RELOC_ALPHA_BSR:
1803 1.1 christos case BFD_RELOC_ALPHA_LDA:
1804 1.1 christos case BFD_RELOC_ALPHA_BOH:
1805 1.1 christos break;
1806 1.1 christos #endif
1807 1.1 christos default:
1808 1.1 christos gas_assert (size >= 1 && size <= 4);
1809 1.1 christos }
1810 1.1 christos
1811 1.1 christos pcrel = reloc_howto->pc_relative;
1812 1.1 christos }
1813 1.1 christos
1814 1.1 christos fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1815 1.1 christos &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc);
1816 1.1 christos
1817 1.1 christos /* Turn off complaints that the addend is too large for some fixups,
1818 1.1 christos and copy in the sequence number for the explicit relocations. */
1819 1.1 christos switch (fixup->reloc)
1820 1.1 christos {
1821 1.1 christos case BFD_RELOC_ALPHA_HINT:
1822 1.1 christos case BFD_RELOC_GPREL32:
1823 1.1 christos case BFD_RELOC_GPREL16:
1824 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16:
1825 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16:
1826 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16:
1827 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16:
1828 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16:
1829 1.1 christos case BFD_RELOC_ALPHA_DTPREL16:
1830 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16:
1831 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16:
1832 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16:
1833 1.1 christos case BFD_RELOC_ALPHA_TPREL16:
1834 1.1 christos fixP->fx_no_overflow = 1;
1835 1.1 christos break;
1836 1.1 christos
1837 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
1838 1.1 christos fixP->fx_no_overflow = 1;
1839 1.1 christos fixP->fx_addsy = section_symbol (now_seg);
1840 1.1 christos fixP->fx_offset = 0;
1841 1.1 christos
1842 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1843 1.1 christos if (++info->n_master > 1)
1844 1.1 christos as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1845 1.1 christos if (info->segment != now_seg)
1846 1.1 christos as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1847 1.1 christos insn->sequence);
1848 1.1 christos fixP->tc_fix_data.info = info;
1849 1.1 christos break;
1850 1.1 christos
1851 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
1852 1.1 christos fixP->fx_no_overflow = 1;
1853 1.1 christos
1854 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1855 1.1 christos if (++info->n_slaves > 1)
1856 1.1 christos as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1857 1.1 christos if (info->segment != now_seg)
1858 1.1 christos as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1859 1.1 christos insn->sequence);
1860 1.1 christos fixP->tc_fix_data.info = info;
1861 1.1 christos info->slaves = fixP;
1862 1.1 christos break;
1863 1.1 christos
1864 1.1 christos case BFD_RELOC_ALPHA_LITERAL:
1865 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
1866 1.1 christos fixP->fx_no_overflow = 1;
1867 1.1 christos
1868 1.1 christos if (insn->sequence == 0)
1869 1.1 christos break;
1870 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1871 1.1 christos info->master = fixP;
1872 1.1 christos info->n_master++;
1873 1.1 christos if (info->segment != now_seg)
1874 1.1 christos info->multi_section_p = 1;
1875 1.1 christos fixP->tc_fix_data.info = info;
1876 1.1 christos break;
1877 1.1 christos
1878 1.1 christos #ifdef RELOC_OP_P
1879 1.1 christos case DUMMY_RELOC_LITUSE_ADDR:
1880 1.1 christos fixP->fx_offset = LITUSE_ALPHA_ADDR;
1881 1.1 christos goto do_lituse;
1882 1.1 christos case DUMMY_RELOC_LITUSE_BASE:
1883 1.1 christos fixP->fx_offset = LITUSE_ALPHA_BASE;
1884 1.1 christos goto do_lituse;
1885 1.1 christos case DUMMY_RELOC_LITUSE_BYTOFF:
1886 1.1 christos fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1887 1.1 christos goto do_lituse;
1888 1.1 christos case DUMMY_RELOC_LITUSE_JSR:
1889 1.1 christos fixP->fx_offset = LITUSE_ALPHA_JSR;
1890 1.1 christos goto do_lituse;
1891 1.1 christos case DUMMY_RELOC_LITUSE_TLSGD:
1892 1.1 christos fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1893 1.1 christos goto do_lituse;
1894 1.1 christos case DUMMY_RELOC_LITUSE_TLSLDM:
1895 1.1 christos fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1896 1.1 christos goto do_lituse;
1897 1.1 christos case DUMMY_RELOC_LITUSE_JSRDIRECT:
1898 1.1 christos fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1899 1.1 christos goto do_lituse;
1900 1.1 christos do_lituse:
1901 1.1 christos fixP->fx_addsy = section_symbol (now_seg);
1902 1.1 christos fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1903 1.1 christos
1904 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1905 1.1 christos if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1906 1.1 christos info->saw_lu_tlsgd = 1;
1907 1.1 christos else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1908 1.1 christos info->saw_lu_tlsldm = 1;
1909 1.1 christos if (++info->n_slaves > 1)
1910 1.1 christos {
1911 1.1 christos if (info->saw_lu_tlsgd)
1912 1.1 christos as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1913 1.1 christos insn->sequence);
1914 1.1 christos else if (info->saw_lu_tlsldm)
1915 1.1 christos as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1916 1.1 christos insn->sequence);
1917 1.1 christos }
1918 1.1 christos fixP->tc_fix_data.info = info;
1919 1.1 christos fixP->tc_fix_data.next_reloc = info->slaves;
1920 1.1 christos info->slaves = fixP;
1921 1.1 christos if (info->segment != now_seg)
1922 1.1 christos info->multi_section_p = 1;
1923 1.1 christos break;
1924 1.1 christos
1925 1.1 christos case BFD_RELOC_ALPHA_TLSGD:
1926 1.1 christos fixP->fx_no_overflow = 1;
1927 1.1 christos
1928 1.1 christos if (insn->sequence == 0)
1929 1.1 christos break;
1930 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1931 1.1 christos if (info->saw_tlsgd)
1932 1.1 christos as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1933 1.1 christos else if (info->saw_tlsldm)
1934 1.1 christos as_bad (_("sequence number in use for !tlsldm!%ld"),
1935 1.1 christos insn->sequence);
1936 1.1 christos else
1937 1.1 christos info->saw_tlsgd = 1;
1938 1.1 christos fixP->tc_fix_data.info = info;
1939 1.1 christos break;
1940 1.1 christos
1941 1.1 christos case BFD_RELOC_ALPHA_TLSLDM:
1942 1.1 christos fixP->fx_no_overflow = 1;
1943 1.1 christos
1944 1.1 christos if (insn->sequence == 0)
1945 1.1 christos break;
1946 1.1 christos info = get_alpha_reloc_tag (insn->sequence);
1947 1.1 christos if (info->saw_tlsldm)
1948 1.1 christos as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1949 1.1 christos else if (info->saw_tlsgd)
1950 1.1 christos as_bad (_("sequence number in use for !tlsgd!%ld"),
1951 1.1 christos insn->sequence);
1952 1.1 christos else
1953 1.1 christos info->saw_tlsldm = 1;
1954 1.1 christos fixP->tc_fix_data.info = info;
1955 1.1 christos break;
1956 1.1 christos #endif
1957 1.1 christos #ifdef OBJ_EVAX
1958 1.1 christos case BFD_RELOC_ALPHA_NOP:
1959 1.1 christos case BFD_RELOC_ALPHA_LDA:
1960 1.1 christos case BFD_RELOC_ALPHA_BSR:
1961 1.1 christos case BFD_RELOC_ALPHA_BOH:
1962 1.1 christos info = get_alpha_reloc_tag (next_sequence_num--);
1963 1.1 christos fixP->tc_fix_data.info = info;
1964 1.1 christos fixP->tc_fix_data.info->sym = fixup->xtrasym;
1965 1.1 christos fixP->tc_fix_data.info->psym = fixup->procsym;
1966 1.1 christos break;
1967 1.1 christos #endif
1968 1.1 christos
1969 1.1 christos default:
1970 1.1 christos if ((int) fixup->reloc < 0)
1971 1.1 christos {
1972 1.1 christos if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1973 1.1 christos fixP->fx_no_overflow = 1;
1974 1.1 christos }
1975 1.1 christos break;
1976 1.1 christos }
1977 1.1 christos }
1978 1.1 christos }
1979 1.1 christos
1980 1.1 christos /* Insert an operand value into an instruction. */
1981 1.1 christos
1982 1.1 christos static unsigned
1983 1.1 christos insert_operand (unsigned insn,
1984 1.1 christos const struct alpha_operand *operand,
1985 1.1 christos offsetT val,
1986 1.1 christos char *file,
1987 1.1 christos unsigned line)
1988 1.1 christos {
1989 1.1 christos if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1990 1.1 christos {
1991 1.1 christos offsetT min, max;
1992 1.1 christos
1993 1.1 christos if (operand->flags & AXP_OPERAND_SIGNED)
1994 1.1 christos {
1995 1.1 christos max = (1 << (operand->bits - 1)) - 1;
1996 1.1 christos min = -(1 << (operand->bits - 1));
1997 1.1 christos }
1998 1.1 christos else
1999 1.1 christos {
2000 1.1 christos max = (1 << operand->bits) - 1;
2001 1.1 christos min = 0;
2002 1.1 christos }
2003 1.1 christos
2004 1.1 christos if (val < min || val > max)
2005 1.1 christos as_bad_value_out_of_range (_("operand"), val, min, max, file, line);
2006 1.1 christos }
2007 1.1 christos
2008 1.1 christos if (operand->insert)
2009 1.1 christos {
2010 1.1 christos const char *errmsg = NULL;
2011 1.1 christos
2012 1.1 christos insn = (*operand->insert) (insn, val, &errmsg);
2013 1.1 christos if (errmsg)
2014 1.1 christos as_warn ("%s", errmsg);
2015 1.1 christos }
2016 1.1 christos else
2017 1.1 christos insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2018 1.1 christos
2019 1.1 christos return insn;
2020 1.1 christos }
2021 1.1 christos
2022 1.1 christos /* Turn an opcode description and a set of arguments into
2023 1.1 christos an instruction and a fixup. */
2024 1.1 christos
2025 1.1 christos static void
2026 1.1 christos assemble_insn (const struct alpha_opcode *opcode,
2027 1.1 christos const expressionS *tok,
2028 1.1 christos int ntok,
2029 1.1 christos struct alpha_insn *insn,
2030 1.1 christos extended_bfd_reloc_code_real_type reloc)
2031 1.1 christos {
2032 1.1 christos const struct alpha_operand *reloc_operand = NULL;
2033 1.1 christos const expressionS *reloc_exp = NULL;
2034 1.1 christos const unsigned char *argidx;
2035 1.1 christos unsigned image;
2036 1.1 christos int tokidx = 0;
2037 1.1 christos
2038 1.1 christos memset (insn, 0, sizeof (*insn));
2039 1.1 christos image = opcode->opcode;
2040 1.1 christos
2041 1.1 christos for (argidx = opcode->operands; *argidx; ++argidx)
2042 1.1 christos {
2043 1.1 christos const struct alpha_operand *operand = &alpha_operands[*argidx];
2044 1.1 christos const expressionS *t = (const expressionS *) 0;
2045 1.1 christos
2046 1.1 christos if (operand->flags & AXP_OPERAND_FAKE)
2047 1.1 christos {
2048 1.1 christos /* Fake operands take no value and generate no fixup. */
2049 1.1 christos image = insert_operand (image, operand, 0, NULL, 0);
2050 1.1 christos continue;
2051 1.1 christos }
2052 1.1 christos
2053 1.1 christos if (tokidx >= ntok)
2054 1.1 christos {
2055 1.1 christos switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2056 1.1 christos {
2057 1.1 christos case AXP_OPERAND_DEFAULT_FIRST:
2058 1.1 christos t = &tok[0];
2059 1.1 christos break;
2060 1.1 christos case AXP_OPERAND_DEFAULT_SECOND:
2061 1.1 christos t = &tok[1];
2062 1.1 christos break;
2063 1.1 christos case AXP_OPERAND_DEFAULT_ZERO:
2064 1.1 christos {
2065 1.1 christos static expressionS zero_exp;
2066 1.1 christos t = &zero_exp;
2067 1.1 christos zero_exp.X_op = O_constant;
2068 1.1 christos zero_exp.X_unsigned = 1;
2069 1.1 christos }
2070 1.1 christos break;
2071 1.1 christos default:
2072 1.1 christos abort ();
2073 1.1 christos }
2074 1.1 christos }
2075 1.1 christos else
2076 1.1 christos t = &tok[tokidx++];
2077 1.1 christos
2078 1.1 christos switch (t->X_op)
2079 1.1 christos {
2080 1.1 christos case O_register:
2081 1.1 christos case O_pregister:
2082 1.1 christos case O_cpregister:
2083 1.1 christos image = insert_operand (image, operand, regno (t->X_add_number),
2084 1.1 christos NULL, 0);
2085 1.1 christos break;
2086 1.1 christos
2087 1.1 christos case O_constant:
2088 1.1 christos image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2089 1.1 christos gas_assert (reloc_operand == NULL);
2090 1.1 christos reloc_operand = operand;
2091 1.1 christos reloc_exp = t;
2092 1.1 christos break;
2093 1.1 christos
2094 1.1 christos default:
2095 1.1 christos /* This is only 0 for fields that should contain registers,
2096 1.1 christos which means this pattern shouldn't have matched. */
2097 1.1 christos if (operand->default_reloc == 0)
2098 1.1 christos abort ();
2099 1.1 christos
2100 1.1 christos /* There is one special case for which an insn receives two
2101 1.1 christos relocations, and thus the user-supplied reloc does not
2102 1.1 christos override the operand reloc. */
2103 1.1 christos if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2104 1.1 christos {
2105 1.1 christos struct alpha_fixup *fixup;
2106 1.1 christos
2107 1.1 christos if (insn->nfixups >= MAX_INSN_FIXUPS)
2108 1.1 christos as_fatal (_("too many fixups"));
2109 1.1 christos
2110 1.1 christos fixup = &insn->fixups[insn->nfixups++];
2111 1.1 christos fixup->exp = *t;
2112 1.1 christos fixup->reloc = BFD_RELOC_ALPHA_HINT;
2113 1.1 christos }
2114 1.1 christos else
2115 1.1 christos {
2116 1.1 christos if (reloc == BFD_RELOC_UNUSED)
2117 1.1 christos reloc = operand->default_reloc;
2118 1.1 christos
2119 1.1 christos gas_assert (reloc_operand == NULL);
2120 1.1 christos reloc_operand = operand;
2121 1.1 christos reloc_exp = t;
2122 1.1 christos }
2123 1.1 christos break;
2124 1.1 christos }
2125 1.1 christos }
2126 1.1 christos
2127 1.1 christos if (reloc != BFD_RELOC_UNUSED)
2128 1.1 christos {
2129 1.1 christos struct alpha_fixup *fixup;
2130 1.1 christos
2131 1.1 christos if (insn->nfixups >= MAX_INSN_FIXUPS)
2132 1.1 christos as_fatal (_("too many fixups"));
2133 1.1 christos
2134 1.1 christos /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2135 1.1 christos relocation tag for both ldah and lda with gpdisp. Choose the
2136 1.1 christos correct internal relocation based on the opcode. */
2137 1.1 christos if (reloc == BFD_RELOC_ALPHA_GPDISP)
2138 1.1 christos {
2139 1.1 christos if (strcmp (opcode->name, "ldah") == 0)
2140 1.1 christos reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2141 1.1 christos else if (strcmp (opcode->name, "lda") == 0)
2142 1.1 christos reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2143 1.1 christos else
2144 1.1 christos as_bad (_("invalid relocation for instruction"));
2145 1.1 christos }
2146 1.1 christos
2147 1.1 christos /* If this is a real relocation (as opposed to a lituse hint), then
2148 1.1 christos the relocation width should match the operand width.
2149 1.1 christos Take care of -MDISP in operand table. */
2150 1.1 christos else if (reloc < BFD_RELOC_UNUSED && reloc > 0)
2151 1.1 christos {
2152 1.1 christos reloc_howto_type *reloc_howto
2153 1.1 christos = bfd_reloc_type_lookup (stdoutput,
2154 1.1 christos (bfd_reloc_code_real_type) reloc);
2155 1.1 christos if (reloc_operand == NULL
2156 1.1 christos || reloc_howto->bitsize != reloc_operand->bits)
2157 1.1 christos {
2158 1.1 christos as_bad (_("invalid relocation for field"));
2159 1.1 christos return;
2160 1.1 christos }
2161 1.1 christos }
2162 1.1 christos
2163 1.1 christos fixup = &insn->fixups[insn->nfixups++];
2164 1.1 christos if (reloc_exp)
2165 1.1 christos fixup->exp = *reloc_exp;
2166 1.1 christos else
2167 1.1 christos fixup->exp.X_op = O_absent;
2168 1.1 christos fixup->reloc = reloc;
2169 1.1 christos }
2170 1.1 christos
2171 1.1 christos insn->insn = image;
2172 1.1 christos }
2173 1.1 christos
2174 1.1 christos /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2175 1.1 christos etc. They differ from the real instructions in that they do simple
2176 1.1 christos expressions like the lda macro. */
2177 1.1 christos
2178 1.1 christos static void
2179 1.1 christos emit_ir_load (const expressionS *tok,
2180 1.1 christos int ntok,
2181 1.1 christos const void * opname)
2182 1.1 christos {
2183 1.1 christos int basereg;
2184 1.1 christos long lituse;
2185 1.1 christos expressionS newtok[3];
2186 1.1 christos struct alpha_insn insn;
2187 1.1 christos const char *symname
2188 1.1 christos = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): "";
2189 1.1 christos int symlen = strlen (symname);
2190 1.1 christos
2191 1.1 christos if (ntok == 2)
2192 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2193 1.1 christos else
2194 1.1 christos basereg = tok[2].X_add_number;
2195 1.1 christos
2196 1.1 christos lituse = load_expression (tok[0].X_add_number, &tok[1],
2197 1.1 christos &basereg, &newtok[1], (const char *) opname);
2198 1.1 christos
2199 1.1 christos if (basereg == alpha_gp_register &&
2200 1.1 christos (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0))
2201 1.1 christos return;
2202 1.1 christos
2203 1.1 christos newtok[0] = tok[0];
2204 1.1 christos set_tok_preg (newtok[2], basereg);
2205 1.1 christos
2206 1.1 christos assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2207 1.1 christos
2208 1.1 christos if (lituse)
2209 1.1 christos {
2210 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2211 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2212 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2213 1.1 christos insn.nfixups++;
2214 1.1 christos insn.sequence = lituse;
2215 1.1 christos }
2216 1.1 christos
2217 1.1 christos emit_insn (&insn);
2218 1.1 christos }
2219 1.1 christos
2220 1.1 christos /* Handle fp register loads, and both integer and fp register stores.
2221 1.1 christos Again, we handle simple expressions. */
2222 1.1 christos
2223 1.1 christos static void
2224 1.1 christos emit_loadstore (const expressionS *tok,
2225 1.1 christos int ntok,
2226 1.1 christos const void * opname)
2227 1.1 christos {
2228 1.1 christos int basereg;
2229 1.1 christos long lituse;
2230 1.1 christos expressionS newtok[3];
2231 1.1 christos struct alpha_insn insn;
2232 1.1 christos
2233 1.1 christos if (ntok == 2)
2234 1.1 christos basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2235 1.1 christos else
2236 1.1 christos basereg = tok[2].X_add_number;
2237 1.1 christos
2238 1.1 christos if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2239 1.1 christos {
2240 1.1 christos if (alpha_noat_on)
2241 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2242 1.1 christos
2243 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1],
2244 1.1 christos &basereg, &newtok[1], (const char *) opname);
2245 1.1 christos }
2246 1.1 christos else
2247 1.1 christos {
2248 1.1 christos newtok[1] = tok[1];
2249 1.1 christos lituse = 0;
2250 1.1 christos }
2251 1.1 christos
2252 1.1 christos newtok[0] = tok[0];
2253 1.1 christos set_tok_preg (newtok[2], basereg);
2254 1.1 christos
2255 1.1 christos assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2256 1.1 christos
2257 1.1 christos if (lituse)
2258 1.1 christos {
2259 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2260 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2261 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2262 1.1 christos insn.nfixups++;
2263 1.1 christos insn.sequence = lituse;
2264 1.1 christos }
2265 1.1 christos
2266 1.1 christos emit_insn (&insn);
2267 1.1 christos }
2268 1.1 christos
2269 1.1 christos /* Load a half-word or byte as an unsigned value. */
2270 1.1 christos
2271 1.1 christos static void
2272 1.1 christos emit_ldXu (const expressionS *tok,
2273 1.1 christos int ntok,
2274 1.1 christos const void * vlgsize)
2275 1.1 christos {
2276 1.1 christos if (alpha_target & AXP_OPCODE_BWX)
2277 1.1 christos emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2278 1.1 christos else
2279 1.1 christos {
2280 1.1 christos expressionS newtok[3];
2281 1.1 christos struct alpha_insn insn;
2282 1.1 christos int basereg;
2283 1.1 christos long lituse;
2284 1.1 christos
2285 1.1 christos if (alpha_noat_on)
2286 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2287 1.1 christos
2288 1.1 christos if (ntok == 2)
2289 1.1 christos basereg = (tok[1].X_op == O_constant
2290 1.1 christos ? AXP_REG_ZERO : alpha_gp_register);
2291 1.1 christos else
2292 1.1 christos basereg = tok[2].X_add_number;
2293 1.1 christos
2294 1.1 christos /* Emit "lda $at, exp". */
2295 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2296 1.1 christos
2297 1.1 christos /* Emit "ldq_u targ, 0($at)". */
2298 1.1 christos newtok[0] = tok[0];
2299 1.1 christos set_tok_const (newtok[1], 0);
2300 1.1 christos set_tok_preg (newtok[2], basereg);
2301 1.1 christos assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2302 1.1 christos
2303 1.1 christos if (lituse)
2304 1.1 christos {
2305 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2306 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2307 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2308 1.1 christos insn.nfixups++;
2309 1.1 christos insn.sequence = lituse;
2310 1.1 christos }
2311 1.1 christos
2312 1.1 christos emit_insn (&insn);
2313 1.1 christos
2314 1.1 christos /* Emit "extXl targ, $at, targ". */
2315 1.1 christos set_tok_reg (newtok[1], basereg);
2316 1.1 christos newtok[2] = newtok[0];
2317 1.1 christos assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2318 1.1 christos
2319 1.1 christos if (lituse)
2320 1.1 christos {
2321 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2322 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2323 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2324 1.1 christos insn.nfixups++;
2325 1.1 christos insn.sequence = lituse;
2326 1.1 christos }
2327 1.1 christos
2328 1.1 christos emit_insn (&insn);
2329 1.1 christos }
2330 1.1 christos }
2331 1.1 christos
2332 1.1 christos /* Load a half-word or byte as a signed value. */
2333 1.1 christos
2334 1.1 christos static void
2335 1.1 christos emit_ldX (const expressionS *tok,
2336 1.1 christos int ntok,
2337 1.1 christos const void * vlgsize)
2338 1.1 christos {
2339 1.1 christos emit_ldXu (tok, ntok, vlgsize);
2340 1.1 christos assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2341 1.1 christos }
2342 1.1 christos
2343 1.1 christos /* Load an integral value from an unaligned address as an unsigned
2344 1.1 christos value. */
2345 1.1 christos
2346 1.1 christos static void
2347 1.1 christos emit_uldXu (const expressionS *tok,
2348 1.1 christos int ntok,
2349 1.1 christos const void * vlgsize)
2350 1.1 christos {
2351 1.1 christos long lgsize = (long) vlgsize;
2352 1.1 christos expressionS newtok[3];
2353 1.1 christos
2354 1.1 christos if (alpha_noat_on)
2355 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2356 1.1 christos
2357 1.1 christos /* Emit "lda $at, exp". */
2358 1.1 christos memcpy (newtok, tok, sizeof (expressionS) * ntok);
2359 1.1 christos newtok[0].X_add_number = AXP_REG_AT;
2360 1.1 christos assemble_tokens ("lda", newtok, ntok, 1);
2361 1.1 christos
2362 1.1 christos /* Emit "ldq_u $t9, 0($at)". */
2363 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2364 1.1 christos set_tok_const (newtok[1], 0);
2365 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT);
2366 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1);
2367 1.1 christos
2368 1.1 christos /* Emit "ldq_u $t10, size-1($at)". */
2369 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2370 1.1 christos set_tok_const (newtok[1], (1 << lgsize) - 1);
2371 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1);
2372 1.1 christos
2373 1.1 christos /* Emit "extXl $t9, $at, $t9". */
2374 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2375 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT);
2376 1.1 christos set_tok_reg (newtok[2], AXP_REG_T9);
2377 1.1 christos assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2378 1.1 christos
2379 1.1 christos /* Emit "extXh $t10, $at, $t10". */
2380 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2381 1.1 christos set_tok_reg (newtok[2], AXP_REG_T10);
2382 1.1 christos assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2383 1.1 christos
2384 1.1 christos /* Emit "or $t9, $t10, targ". */
2385 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2386 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10);
2387 1.1 christos newtok[2] = tok[0];
2388 1.1 christos assemble_tokens ("or", newtok, 3, 1);
2389 1.1 christos }
2390 1.1 christos
2391 1.1 christos /* Load an integral value from an unaligned address as a signed value.
2392 1.1 christos Note that quads should get funneled to the unsigned load since we
2393 1.1 christos don't have to do the sign extension. */
2394 1.1 christos
2395 1.1 christos static void
2396 1.1 christos emit_uldX (const expressionS *tok,
2397 1.1 christos int ntok,
2398 1.1 christos const void * vlgsize)
2399 1.1 christos {
2400 1.1 christos emit_uldXu (tok, ntok, vlgsize);
2401 1.1 christos assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2402 1.1 christos }
2403 1.1 christos
2404 1.1 christos /* Implement the ldil macro. */
2405 1.1 christos
2406 1.1 christos static void
2407 1.1 christos emit_ldil (const expressionS *tok,
2408 1.1 christos int ntok,
2409 1.1 christos const void * unused ATTRIBUTE_UNUSED)
2410 1.1 christos {
2411 1.1 christos expressionS newtok[2];
2412 1.1 christos
2413 1.1 christos memcpy (newtok, tok, sizeof (newtok));
2414 1.1 christos newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2415 1.1 christos
2416 1.1 christos assemble_tokens ("lda", newtok, ntok, 1);
2417 1.1 christos }
2418 1.1 christos
2419 1.1 christos /* Store a half-word or byte. */
2420 1.1 christos
2421 1.1 christos static void
2422 1.1 christos emit_stX (const expressionS *tok,
2423 1.1 christos int ntok,
2424 1.1 christos const void * vlgsize)
2425 1.1 christos {
2426 1.1 christos int lgsize = (int) (long) vlgsize;
2427 1.1 christos
2428 1.1 christos if (alpha_target & AXP_OPCODE_BWX)
2429 1.1 christos emit_loadstore (tok, ntok, stX_op[lgsize]);
2430 1.1 christos else
2431 1.1 christos {
2432 1.1 christos expressionS newtok[3];
2433 1.1 christos struct alpha_insn insn;
2434 1.1 christos int basereg;
2435 1.1 christos long lituse;
2436 1.1 christos
2437 1.1 christos if (alpha_noat_on)
2438 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2439 1.1 christos
2440 1.1 christos if (ntok == 2)
2441 1.1 christos basereg = (tok[1].X_op == O_constant
2442 1.1 christos ? AXP_REG_ZERO : alpha_gp_register);
2443 1.1 christos else
2444 1.1 christos basereg = tok[2].X_add_number;
2445 1.1 christos
2446 1.1 christos /* Emit "lda $at, exp". */
2447 1.1 christos lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2448 1.1 christos
2449 1.1 christos /* Emit "ldq_u $t9, 0($at)". */
2450 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2451 1.1 christos set_tok_const (newtok[1], 0);
2452 1.1 christos set_tok_preg (newtok[2], basereg);
2453 1.1 christos assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2454 1.1 christos
2455 1.1 christos if (lituse)
2456 1.1 christos {
2457 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2458 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2459 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2460 1.1 christos insn.nfixups++;
2461 1.1 christos insn.sequence = lituse;
2462 1.1 christos }
2463 1.1 christos
2464 1.1 christos emit_insn (&insn);
2465 1.1 christos
2466 1.1 christos /* Emit "insXl src, $at, $t10". */
2467 1.1 christos newtok[0] = tok[0];
2468 1.1 christos set_tok_reg (newtok[1], basereg);
2469 1.1 christos set_tok_reg (newtok[2], AXP_REG_T10);
2470 1.1 christos assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2471 1.1 christos
2472 1.1 christos if (lituse)
2473 1.1 christos {
2474 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2475 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2476 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2477 1.1 christos insn.nfixups++;
2478 1.1 christos insn.sequence = lituse;
2479 1.1 christos }
2480 1.1 christos
2481 1.1 christos emit_insn (&insn);
2482 1.1 christos
2483 1.1 christos /* Emit "mskXl $t9, $at, $t9". */
2484 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2485 1.1 christos newtok[2] = newtok[0];
2486 1.1 christos assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2487 1.1 christos
2488 1.1 christos if (lituse)
2489 1.1 christos {
2490 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2491 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2492 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2493 1.1 christos insn.nfixups++;
2494 1.1 christos insn.sequence = lituse;
2495 1.1 christos }
2496 1.1 christos
2497 1.1 christos emit_insn (&insn);
2498 1.1 christos
2499 1.1 christos /* Emit "or $t9, $t10, $t9". */
2500 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10);
2501 1.1 christos assemble_tokens ("or", newtok, 3, 1);
2502 1.1 christos
2503 1.1 christos /* Emit "stq_u $t9, 0($at). */
2504 1.1 christos set_tok_const(newtok[1], 0);
2505 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT);
2506 1.1 christos assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2507 1.1 christos
2508 1.1 christos if (lituse)
2509 1.1 christos {
2510 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2511 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2512 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2513 1.1 christos insn.nfixups++;
2514 1.1 christos insn.sequence = lituse;
2515 1.1 christos }
2516 1.1 christos
2517 1.1 christos emit_insn (&insn);
2518 1.1 christos }
2519 1.1 christos }
2520 1.1 christos
2521 1.1 christos /* Store an integer to an unaligned address. */
2522 1.1 christos
2523 1.1 christos static void
2524 1.1 christos emit_ustX (const expressionS *tok,
2525 1.1 christos int ntok,
2526 1.1 christos const void * vlgsize)
2527 1.1 christos {
2528 1.1 christos int lgsize = (int) (long) vlgsize;
2529 1.1 christos expressionS newtok[3];
2530 1.1 christos
2531 1.1 christos /* Emit "lda $at, exp". */
2532 1.1 christos memcpy (newtok, tok, sizeof (expressionS) * ntok);
2533 1.1 christos newtok[0].X_add_number = AXP_REG_AT;
2534 1.1 christos assemble_tokens ("lda", newtok, ntok, 1);
2535 1.1 christos
2536 1.1 christos /* Emit "ldq_u $9, 0($at)". */
2537 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2538 1.1 christos set_tok_const (newtok[1], 0);
2539 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT);
2540 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1);
2541 1.1 christos
2542 1.1 christos /* Emit "ldq_u $10, size-1($at)". */
2543 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2544 1.1 christos set_tok_const (newtok[1], (1 << lgsize) - 1);
2545 1.1 christos assemble_tokens ("ldq_u", newtok, 3, 1);
2546 1.1 christos
2547 1.1 christos /* Emit "insXl src, $at, $t11". */
2548 1.1 christos newtok[0] = tok[0];
2549 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT);
2550 1.1 christos set_tok_reg (newtok[2], AXP_REG_T11);
2551 1.1 christos assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2552 1.1 christos
2553 1.1 christos /* Emit "insXh src, $at, $t12". */
2554 1.1 christos set_tok_reg (newtok[2], AXP_REG_T12);
2555 1.1 christos assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2556 1.1 christos
2557 1.1 christos /* Emit "mskXl $t9, $at, $t9". */
2558 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2559 1.1 christos newtok[2] = newtok[0];
2560 1.1 christos assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2561 1.1 christos
2562 1.1 christos /* Emit "mskXh $t10, $at, $t10". */
2563 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2564 1.1 christos newtok[2] = newtok[0];
2565 1.1 christos assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2566 1.1 christos
2567 1.1 christos /* Emit "or $t9, $t11, $t9". */
2568 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2569 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11);
2570 1.1 christos newtok[2] = newtok[0];
2571 1.1 christos assemble_tokens ("or", newtok, 3, 1);
2572 1.1 christos
2573 1.1 christos /* Emit "or $t10, $t12, $t10". */
2574 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2575 1.1 christos set_tok_reg (newtok[1], AXP_REG_T12);
2576 1.1 christos newtok[2] = newtok[0];
2577 1.1 christos assemble_tokens ("or", newtok, 3, 1);
2578 1.1 christos
2579 1.1 christos /* Emit "stq_u $t10, size-1($at)". */
2580 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2581 1.1 christos set_tok_const (newtok[1], (1 << lgsize) - 1);
2582 1.1 christos set_tok_preg (newtok[2], AXP_REG_AT);
2583 1.1 christos assemble_tokens ("stq_u", newtok, 3, 1);
2584 1.1 christos
2585 1.1 christos /* Emit "stq_u $t9, 0($at)". */
2586 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2587 1.1 christos set_tok_const (newtok[1], 0);
2588 1.1 christos assemble_tokens ("stq_u", newtok, 3, 1);
2589 1.1 christos }
2590 1.1 christos
2591 1.1 christos /* Sign extend a half-word or byte. The 32-bit sign extend is
2592 1.1 christos implemented as "addl $31, $r, $t" in the opcode table. */
2593 1.1 christos
2594 1.1 christos static void
2595 1.1 christos emit_sextX (const expressionS *tok,
2596 1.1 christos int ntok,
2597 1.1 christos const void * vlgsize)
2598 1.1 christos {
2599 1.1 christos long lgsize = (long) vlgsize;
2600 1.1 christos
2601 1.1 christos if (alpha_target & AXP_OPCODE_BWX)
2602 1.1 christos assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2603 1.1 christos else
2604 1.1 christos {
2605 1.1 christos int bitshift = 64 - 8 * (1 << lgsize);
2606 1.1 christos expressionS newtok[3];
2607 1.1 christos
2608 1.1 christos /* Emit "sll src,bits,dst". */
2609 1.1 christos newtok[0] = tok[0];
2610 1.1 christos set_tok_const (newtok[1], bitshift);
2611 1.1 christos newtok[2] = tok[ntok - 1];
2612 1.1 christos assemble_tokens ("sll", newtok, 3, 1);
2613 1.1 christos
2614 1.1 christos /* Emit "sra dst,bits,dst". */
2615 1.1 christos newtok[0] = newtok[2];
2616 1.1 christos assemble_tokens ("sra", newtok, 3, 1);
2617 1.1 christos }
2618 1.1 christos }
2619 1.1 christos
2620 1.1 christos /* Implement the division and modulus macros. */
2621 1.1 christos
2622 1.1 christos #ifdef OBJ_EVAX
2623 1.1 christos
2624 1.1 christos /* Make register usage like in normal procedure call.
2625 1.1 christos Don't clobber PV and RA. */
2626 1.1 christos
2627 1.1 christos static void
2628 1.1 christos emit_division (const expressionS *tok,
2629 1.1 christos int ntok,
2630 1.1 christos const void * symname)
2631 1.1 christos {
2632 1.1 christos /* DIVISION and MODULUS. Yech.
2633 1.1 christos
2634 1.1 christos Convert
2635 1.1 christos OP x,y,result
2636 1.1 christos to
2637 1.1 christos mov x,R16 # if x != R16
2638 1.1 christos mov y,R17 # if y != R17
2639 1.1 christos lda AT,__OP
2640 1.1 christos jsr AT,(AT),0
2641 1.1 christos mov R0,result
2642 1.1 christos
2643 1.1 christos with appropriate optimizations if R0,R16,R17 are the registers
2644 1.1 christos specified by the compiler. */
2645 1.1 christos
2646 1.1 christos int xr, yr, rr;
2647 1.1 christos symbolS *sym;
2648 1.1 christos expressionS newtok[3];
2649 1.1 christos
2650 1.1 christos xr = regno (tok[0].X_add_number);
2651 1.1 christos yr = regno (tok[1].X_add_number);
2652 1.1 christos
2653 1.1 christos if (ntok < 3)
2654 1.1 christos rr = xr;
2655 1.1 christos else
2656 1.1 christos rr = regno (tok[2].X_add_number);
2657 1.1 christos
2658 1.1 christos /* Move the operands into the right place. */
2659 1.1 christos if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2660 1.1 christos {
2661 1.1 christos /* They are in exactly the wrong order -- swap through AT. */
2662 1.1 christos if (alpha_noat_on)
2663 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2664 1.1 christos
2665 1.1 christos set_tok_reg (newtok[0], AXP_REG_R16);
2666 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT);
2667 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2668 1.1 christos
2669 1.1 christos set_tok_reg (newtok[0], AXP_REG_R17);
2670 1.1 christos set_tok_reg (newtok[1], AXP_REG_R16);
2671 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2672 1.1 christos
2673 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
2674 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17);
2675 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2676 1.1 christos }
2677 1.1 christos else
2678 1.1 christos {
2679 1.1 christos if (yr == AXP_REG_R16)
2680 1.1 christos {
2681 1.1 christos set_tok_reg (newtok[0], AXP_REG_R16);
2682 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17);
2683 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2684 1.1 christos }
2685 1.1 christos
2686 1.1 christos if (xr != AXP_REG_R16)
2687 1.1 christos {
2688 1.1 christos set_tok_reg (newtok[0], xr);
2689 1.1 christos set_tok_reg (newtok[1], AXP_REG_R16);
2690 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2691 1.1 christos }
2692 1.1 christos
2693 1.1 christos if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2694 1.1 christos {
2695 1.1 christos set_tok_reg (newtok[0], yr);
2696 1.1 christos set_tok_reg (newtok[1], AXP_REG_R17);
2697 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2698 1.1 christos }
2699 1.1 christos }
2700 1.1 christos
2701 1.1 christos sym = symbol_find_or_make ((const char *) symname);
2702 1.1 christos
2703 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
2704 1.1 christos set_tok_sym (newtok[1], sym, 0);
2705 1.1 christos assemble_tokens ("lda", newtok, 2, 1);
2706 1.1 christos
2707 1.1 christos /* Call the division routine. */
2708 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
2709 1.1 christos set_tok_cpreg (newtok[1], AXP_REG_AT);
2710 1.1 christos set_tok_const (newtok[2], 0);
2711 1.1 christos assemble_tokens ("jsr", newtok, 3, 1);
2712 1.1 christos
2713 1.1 christos /* Move the result to the right place. */
2714 1.1 christos if (rr != AXP_REG_R0)
2715 1.1 christos {
2716 1.1 christos set_tok_reg (newtok[0], AXP_REG_R0);
2717 1.1 christos set_tok_reg (newtok[1], rr);
2718 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2719 1.1 christos }
2720 1.1 christos }
2721 1.1 christos
2722 1.1 christos #else /* !OBJ_EVAX */
2723 1.1 christos
2724 1.1 christos static void
2725 1.1 christos emit_division (const expressionS *tok,
2726 1.1 christos int ntok,
2727 1.1 christos const void * symname)
2728 1.1 christos {
2729 1.1 christos /* DIVISION and MODULUS. Yech.
2730 1.1 christos Convert
2731 1.1 christos OP x,y,result
2732 1.1 christos to
2733 1.1 christos lda pv,__OP
2734 1.1 christos mov x,t10
2735 1.1 christos mov y,t11
2736 1.1 christos jsr t9,(pv),__OP
2737 1.1 christos mov t12,result
2738 1.1 christos
2739 1.1 christos with appropriate optimizations if t10,t11,t12 are the registers
2740 1.1 christos specified by the compiler. */
2741 1.1 christos
2742 1.1 christos int xr, yr, rr;
2743 1.1 christos symbolS *sym;
2744 1.1 christos expressionS newtok[3];
2745 1.1 christos
2746 1.1 christos xr = regno (tok[0].X_add_number);
2747 1.1 christos yr = regno (tok[1].X_add_number);
2748 1.1 christos
2749 1.1 christos if (ntok < 3)
2750 1.1 christos rr = xr;
2751 1.1 christos else
2752 1.1 christos rr = regno (tok[2].X_add_number);
2753 1.1 christos
2754 1.1 christos sym = symbol_find_or_make ((const char *) symname);
2755 1.1 christos
2756 1.1 christos /* Move the operands into the right place. */
2757 1.1 christos if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2758 1.1 christos {
2759 1.1 christos /* They are in exactly the wrong order -- swap through AT. */
2760 1.1 christos if (alpha_noat_on)
2761 1.1 christos as_bad (_("macro requires $at register while noat in effect"));
2762 1.1 christos
2763 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2764 1.1 christos set_tok_reg (newtok[1], AXP_REG_AT);
2765 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2766 1.1 christos
2767 1.1 christos set_tok_reg (newtok[0], AXP_REG_T11);
2768 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10);
2769 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2770 1.1 christos
2771 1.1 christos set_tok_reg (newtok[0], AXP_REG_AT);
2772 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11);
2773 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2774 1.1 christos }
2775 1.1 christos else
2776 1.1 christos {
2777 1.1 christos if (yr == AXP_REG_T10)
2778 1.1 christos {
2779 1.1 christos set_tok_reg (newtok[0], AXP_REG_T10);
2780 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11);
2781 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2782 1.1 christos }
2783 1.1 christos
2784 1.1 christos if (xr != AXP_REG_T10)
2785 1.1 christos {
2786 1.1 christos set_tok_reg (newtok[0], xr);
2787 1.1 christos set_tok_reg (newtok[1], AXP_REG_T10);
2788 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2789 1.1 christos }
2790 1.1 christos
2791 1.1 christos if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2792 1.1 christos {
2793 1.1 christos set_tok_reg (newtok[0], yr);
2794 1.1 christos set_tok_reg (newtok[1], AXP_REG_T11);
2795 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2796 1.1 christos }
2797 1.1 christos }
2798 1.1 christos
2799 1.1 christos /* Call the division routine. */
2800 1.1 christos set_tok_reg (newtok[0], AXP_REG_T9);
2801 1.1 christos set_tok_sym (newtok[1], sym, 0);
2802 1.1 christos assemble_tokens ("jsr", newtok, 2, 1);
2803 1.1 christos
2804 1.1 christos /* Reload the GP register. */
2805 1.1 christos #ifdef OBJ_AOUT
2806 1.1 christos FIXME
2807 1.1 christos #endif
2808 1.1 christos #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2809 1.1 christos set_tok_reg (newtok[0], alpha_gp_register);
2810 1.1 christos set_tok_const (newtok[1], 0);
2811 1.1 christos set_tok_preg (newtok[2], AXP_REG_T9);
2812 1.1 christos assemble_tokens ("ldgp", newtok, 3, 1);
2813 1.1 christos #endif
2814 1.1 christos
2815 1.1 christos /* Move the result to the right place. */
2816 1.1 christos if (rr != AXP_REG_T12)
2817 1.1 christos {
2818 1.1 christos set_tok_reg (newtok[0], AXP_REG_T12);
2819 1.1 christos set_tok_reg (newtok[1], rr);
2820 1.1 christos assemble_tokens ("mov", newtok, 2, 1);
2821 1.1 christos }
2822 1.1 christos }
2823 1.1 christos
2824 1.1 christos #endif /* !OBJ_EVAX */
2825 1.1 christos
2826 1.1 christos /* The jsr and jmp macros differ from their instruction counterparts
2827 1.1 christos in that they can load the target address and default most
2828 1.1 christos everything. */
2829 1.1 christos
2830 1.1 christos static void
2831 1.1 christos emit_jsrjmp (const expressionS *tok,
2832 1.1 christos int ntok,
2833 1.1 christos const void * vopname)
2834 1.1 christos {
2835 1.1 christos const char *opname = (const char *) vopname;
2836 1.1 christos struct alpha_insn insn;
2837 1.1 christos expressionS newtok[3];
2838 1.1 christos int r, tokidx = 0;
2839 1.1 christos long lituse = 0;
2840 1.1 christos
2841 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_register)
2842 1.1 christos r = regno (tok[tokidx++].X_add_number);
2843 1.1 christos else
2844 1.1 christos r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2845 1.1 christos
2846 1.1 christos set_tok_reg (newtok[0], r);
2847 1.1 christos
2848 1.1 christos if (tokidx < ntok &&
2849 1.1 christos (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2850 1.1 christos r = regno (tok[tokidx++].X_add_number);
2851 1.1 christos #ifdef OBJ_EVAX
2852 1.1 christos /* Keep register if jsr $n.<sym>. */
2853 1.1 christos #else
2854 1.1 christos else
2855 1.1 christos {
2856 1.1 christos int basereg = alpha_gp_register;
2857 1.1 christos lituse = load_expression (r = AXP_REG_PV, &tok[tokidx],
2858 1.1 christos &basereg, NULL, opname);
2859 1.1 christos }
2860 1.1 christos #endif
2861 1.1 christos
2862 1.1 christos set_tok_cpreg (newtok[1], r);
2863 1.1 christos
2864 1.1 christos #ifndef OBJ_EVAX
2865 1.1 christos if (tokidx < ntok)
2866 1.1 christos newtok[2] = tok[tokidx];
2867 1.1 christos else
2868 1.1 christos #endif
2869 1.1 christos set_tok_const (newtok[2], 0);
2870 1.1 christos
2871 1.1 christos assemble_tokens_to_insn (opname, newtok, 3, &insn);
2872 1.1 christos
2873 1.1 christos if (lituse)
2874 1.1 christos {
2875 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2876 1.1 christos insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2877 1.1 christos insn.fixups[insn.nfixups].exp.X_op = O_absent;
2878 1.1 christos insn.nfixups++;
2879 1.1 christos insn.sequence = lituse;
2880 1.1 christos }
2881 1.1 christos
2882 1.1 christos #ifdef OBJ_EVAX
2883 1.1 christos if (alpha_flag_replace
2884 1.1 christos && r == AXP_REG_RA
2885 1.1 christos && tok[tokidx].X_add_symbol
2886 1.1 christos && alpha_linkage_symbol)
2887 1.1 christos {
2888 1.1 christos /* Create a BOH reloc for 'jsr $27,NAME'. */
2889 1.1 christos const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
2890 1.1 christos int symlen = strlen (symname);
2891 1.1 christos char *ensymname;
2892 1.1 christos
2893 1.1 christos /* Build the entry name as 'NAME..en'. */
2894 1.1 christos ensymname = (char *) alloca (symlen + 5);
2895 1.1 christos memcpy (ensymname, symname, symlen);
2896 1.1 christos memcpy (ensymname + symlen, "..en", 5);
2897 1.1 christos
2898 1.1 christos gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2899 1.1 christos if (insn.nfixups > 0)
2900 1.1 christos {
2901 1.1 christos memmove (&insn.fixups[1], &insn.fixups[0],
2902 1.1 christos sizeof(struct alpha_fixup) * insn.nfixups);
2903 1.1 christos }
2904 1.1 christos
2905 1.1 christos /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2906 1.1 christos case in load_expression. See B.4.5.2 of the OpenVMS
2907 1.1 christos Linker Utility Manual. */
2908 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH;
2909 1.1 christos insn.fixups[0].exp.X_op = O_symbol;
2910 1.1 christos insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname);
2911 1.1 christos insn.fixups[0].exp.X_add_number = 0;
2912 1.1 christos insn.fixups[0].xtrasym = alpha_linkage_symbol;
2913 1.1 christos insn.fixups[0].procsym = alpha_evax_proc->symbol;
2914 1.1 christos insn.nfixups++;
2915 1.1 christos alpha_linkage_symbol = 0;
2916 1.1 christos }
2917 1.1 christos #endif
2918 1.1 christos
2919 1.1 christos emit_insn (&insn);
2920 1.1 christos }
2921 1.1 christos
2922 1.1 christos /* The ret and jcr instructions differ from their instruction
2923 1.1 christos counterparts in that everything can be defaulted. */
2924 1.1 christos
2925 1.1 christos static void
2926 1.1 christos emit_retjcr (const expressionS *tok,
2927 1.1 christos int ntok,
2928 1.1 christos const void * vopname)
2929 1.1 christos {
2930 1.1 christos const char *opname = (const char *) vopname;
2931 1.1 christos expressionS newtok[3];
2932 1.1 christos int r, tokidx = 0;
2933 1.1 christos
2934 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_register)
2935 1.1 christos r = regno (tok[tokidx++].X_add_number);
2936 1.1 christos else
2937 1.1 christos r = AXP_REG_ZERO;
2938 1.1 christos
2939 1.1 christos set_tok_reg (newtok[0], r);
2940 1.1 christos
2941 1.1 christos if (tokidx < ntok &&
2942 1.1 christos (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2943 1.1 christos r = regno (tok[tokidx++].X_add_number);
2944 1.1 christos else
2945 1.1 christos r = AXP_REG_RA;
2946 1.1 christos
2947 1.1 christos set_tok_cpreg (newtok[1], r);
2948 1.1 christos
2949 1.1 christos if (tokidx < ntok)
2950 1.1 christos newtok[2] = tok[tokidx];
2951 1.1 christos else
2952 1.1 christos set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2953 1.1 christos
2954 1.1 christos assemble_tokens (opname, newtok, 3, 0);
2955 1.1 christos }
2956 1.1 christos
2957 1.1 christos /* Implement the ldgp macro. */
2958 1.1 christos
2959 1.1 christos static void
2960 1.1 christos emit_ldgp (const expressionS *tok ATTRIBUTE_UNUSED,
2961 1.1 christos int ntok ATTRIBUTE_UNUSED,
2962 1.1 christos const void * unused ATTRIBUTE_UNUSED)
2963 1.1 christos {
2964 1.1 christos #ifdef OBJ_AOUT
2965 1.1 christos FIXME
2966 1.1 christos #endif
2967 1.1 christos #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2968 1.1 christos /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2969 1.1 christos with appropriate constants and relocations. */
2970 1.1 christos struct alpha_insn insn;
2971 1.1 christos expressionS newtok[3];
2972 1.1 christos expressionS addend;
2973 1.1 christos
2974 1.1 christos #ifdef OBJ_ECOFF
2975 1.1 christos if (regno (tok[2].X_add_number) == AXP_REG_PV)
2976 1.1 christos ecoff_set_gp_prolog_size (0);
2977 1.1 christos #endif
2978 1.1 christos
2979 1.1 christos newtok[0] = tok[0];
2980 1.1 christos set_tok_const (newtok[1], 0);
2981 1.1 christos newtok[2] = tok[2];
2982 1.1 christos
2983 1.1 christos assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2984 1.1 christos
2985 1.1 christos addend = tok[1];
2986 1.1 christos
2987 1.1 christos #ifdef OBJ_ECOFF
2988 1.1 christos if (addend.X_op != O_constant)
2989 1.1 christos as_bad (_("can not resolve expression"));
2990 1.1 christos addend.X_op = O_symbol;
2991 1.1 christos addend.X_add_symbol = alpha_gp_symbol;
2992 1.1 christos #endif
2993 1.1 christos
2994 1.1 christos insn.nfixups = 1;
2995 1.1 christos insn.fixups[0].exp = addend;
2996 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2997 1.1 christos insn.sequence = next_sequence_num;
2998 1.1 christos
2999 1.1 christos emit_insn (&insn);
3000 1.1 christos
3001 1.1 christos set_tok_preg (newtok[2], tok[0].X_add_number);
3002 1.1 christos
3003 1.1 christos assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3004 1.1 christos
3005 1.1 christos #ifdef OBJ_ECOFF
3006 1.1 christos addend.X_add_number += 4;
3007 1.1 christos #endif
3008 1.1 christos
3009 1.1 christos insn.nfixups = 1;
3010 1.1 christos insn.fixups[0].exp = addend;
3011 1.1 christos insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
3012 1.1 christos insn.sequence = next_sequence_num--;
3013 1.1 christos
3014 1.1 christos emit_insn (&insn);
3015 1.1 christos #endif /* OBJ_ECOFF || OBJ_ELF */
3016 1.1 christos }
3017 1.1 christos
3018 1.1 christos /* The macro table. */
3019 1.1 christos
3020 1.1 christos static const struct alpha_macro alpha_macros[] =
3021 1.1 christos {
3022 1.1 christos /* Load/Store macros. */
3023 1.1 christos { "lda", emit_lda, NULL,
3024 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3025 1.1 christos { "ldah", emit_ldah, NULL,
3026 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3027 1.1 christos
3028 1.1 christos { "ldl", emit_ir_load, "ldl",
3029 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3030 1.1 christos { "ldl_l", emit_ir_load, "ldl_l",
3031 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3032 1.1 christos { "ldq", emit_ir_load, "ldq",
3033 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3034 1.1 christos { "ldq_l", emit_ir_load, "ldq_l",
3035 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3036 1.1 christos { "ldq_u", emit_ir_load, "ldq_u",
3037 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3038 1.1 christos { "ldf", emit_loadstore, "ldf",
3039 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3040 1.1 christos { "ldg", emit_loadstore, "ldg",
3041 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3042 1.1 christos { "lds", emit_loadstore, "lds",
3043 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3044 1.1 christos { "ldt", emit_loadstore, "ldt",
3045 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3046 1.1 christos
3047 1.1 christos { "ldb", emit_ldX, (void *) 0,
3048 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3049 1.1 christos { "ldbu", emit_ldXu, (void *) 0,
3050 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3051 1.1 christos { "ldw", emit_ldX, (void *) 1,
3052 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3053 1.1 christos { "ldwu", emit_ldXu, (void *) 1,
3054 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3055 1.1 christos
3056 1.1 christos { "uldw", emit_uldX, (void *) 1,
3057 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3058 1.1 christos { "uldwu", emit_uldXu, (void *) 1,
3059 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3060 1.1 christos { "uldl", emit_uldX, (void *) 2,
3061 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3062 1.1 christos { "uldlu", emit_uldXu, (void *) 2,
3063 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3064 1.1 christos { "uldq", emit_uldXu, (void *) 3,
3065 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3066 1.1 christos
3067 1.1 christos { "ldgp", emit_ldgp, NULL,
3068 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
3069 1.1 christos
3070 1.1 christos { "ldi", emit_lda, NULL,
3071 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3072 1.1 christos { "ldil", emit_ldil, NULL,
3073 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3074 1.1 christos { "ldiq", emit_lda, NULL,
3075 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3076 1.1 christos
3077 1.1 christos { "stl", emit_loadstore, "stl",
3078 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3079 1.1 christos { "stl_c", emit_loadstore, "stl_c",
3080 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3081 1.1 christos { "stq", emit_loadstore, "stq",
3082 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3083 1.1 christos { "stq_c", emit_loadstore, "stq_c",
3084 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3085 1.1 christos { "stq_u", emit_loadstore, "stq_u",
3086 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3087 1.1 christos { "stf", emit_loadstore, "stf",
3088 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3089 1.1 christos { "stg", emit_loadstore, "stg",
3090 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3091 1.1 christos { "sts", emit_loadstore, "sts",
3092 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3093 1.1 christos { "stt", emit_loadstore, "stt",
3094 1.1 christos { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3095 1.1 christos
3096 1.1 christos { "stb", emit_stX, (void *) 0,
3097 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3098 1.1 christos { "stw", emit_stX, (void *) 1,
3099 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3100 1.1 christos { "ustw", emit_ustX, (void *) 1,
3101 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3102 1.1 christos { "ustl", emit_ustX, (void *) 2,
3103 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3104 1.1 christos { "ustq", emit_ustX, (void *) 3,
3105 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3106 1.1 christos
3107 1.1 christos /* Arithmetic macros. */
3108 1.1 christos
3109 1.1 christos { "sextb", emit_sextX, (void *) 0,
3110 1.1 christos { MACRO_IR, MACRO_IR, MACRO_EOA,
3111 1.1 christos MACRO_IR, MACRO_EOA,
3112 1.1 christos /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3113 1.1 christos { "sextw", emit_sextX, (void *) 1,
3114 1.1 christos { MACRO_IR, MACRO_IR, MACRO_EOA,
3115 1.1 christos MACRO_IR, MACRO_EOA,
3116 1.1 christos /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3117 1.1 christos
3118 1.1 christos { "divl", emit_division, "__divl",
3119 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3120 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3121 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3122 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3123 1.1 christos { "divlu", emit_division, "__divlu",
3124 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3125 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3126 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3127 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3128 1.1 christos { "divq", emit_division, "__divq",
3129 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3130 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3131 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3132 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3133 1.1 christos { "divqu", emit_division, "__divqu",
3134 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3135 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3136 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3137 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3138 1.1 christos { "reml", emit_division, "__reml",
3139 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3140 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3141 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3142 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3143 1.1 christos { "remlu", emit_division, "__remlu",
3144 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3145 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3146 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3147 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3148 1.1 christos { "remq", emit_division, "__remq",
3149 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3150 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3151 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3152 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3153 1.1 christos { "remqu", emit_division, "__remqu",
3154 1.1 christos { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3155 1.1 christos MACRO_IR, MACRO_IR, MACRO_EOA,
3156 1.1 christos /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3157 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3158 1.1 christos
3159 1.1 christos { "jsr", emit_jsrjmp, "jsr",
3160 1.1 christos { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3161 1.1 christos MACRO_PIR, MACRO_EOA,
3162 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA,
3163 1.1 christos MACRO_EXP, MACRO_EOA } },
3164 1.1 christos { "jmp", emit_jsrjmp, "jmp",
3165 1.1 christos { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3166 1.1 christos MACRO_PIR, MACRO_EOA,
3167 1.1 christos MACRO_IR, MACRO_EXP, MACRO_EOA,
3168 1.1 christos MACRO_EXP, MACRO_EOA } },
3169 1.1 christos { "ret", emit_retjcr, "ret",
3170 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA,
3171 1.1 christos MACRO_IR, MACRO_EOA,
3172 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA,
3173 1.1 christos MACRO_PIR, MACRO_EOA,
3174 1.1 christos MACRO_EXP, MACRO_EOA,
3175 1.1 christos MACRO_EOA } },
3176 1.1 christos { "jcr", emit_retjcr, "jcr",
3177 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA,
3178 1.1 christos MACRO_IR, MACRO_EOA,
3179 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA,
3180 1.1 christos MACRO_PIR, MACRO_EOA,
3181 1.1 christos MACRO_EXP, MACRO_EOA,
3182 1.1 christos MACRO_EOA } },
3183 1.1 christos { "jsr_coroutine", emit_retjcr, "jcr",
3184 1.1 christos { MACRO_IR, MACRO_EXP, MACRO_EOA,
3185 1.1 christos MACRO_IR, MACRO_EOA,
3186 1.1 christos MACRO_PIR, MACRO_EXP, MACRO_EOA,
3187 1.1 christos MACRO_PIR, MACRO_EOA,
3188 1.1 christos MACRO_EXP, MACRO_EOA,
3189 1.1 christos MACRO_EOA } },
3190 1.1 christos };
3191 1.1 christos
3192 1.1 christos static const unsigned int alpha_num_macros
3193 1.1 christos = sizeof (alpha_macros) / sizeof (*alpha_macros);
3194 1.1 christos
3195 1.1 christos /* Search forward through all variants of a macro looking for a syntax
3196 1.1 christos match. */
3197 1.1 christos
3198 1.1 christos static const struct alpha_macro *
3199 1.1 christos find_macro_match (const struct alpha_macro *first_macro,
3200 1.1 christos const expressionS *tok,
3201 1.1 christos int *pntok)
3202 1.1 christos
3203 1.1 christos {
3204 1.1 christos const struct alpha_macro *macro = first_macro;
3205 1.1 christos int ntok = *pntok;
3206 1.1 christos
3207 1.1 christos do
3208 1.1 christos {
3209 1.1 christos const enum alpha_macro_arg *arg = macro->argsets;
3210 1.1 christos int tokidx = 0;
3211 1.1 christos
3212 1.1 christos while (*arg)
3213 1.1 christos {
3214 1.1 christos switch (*arg)
3215 1.1 christos {
3216 1.1 christos case MACRO_EOA:
3217 1.1 christos if (tokidx == ntok)
3218 1.1 christos return macro;
3219 1.1 christos else
3220 1.1 christos tokidx = 0;
3221 1.1 christos break;
3222 1.1 christos
3223 1.1 christos /* Index register. */
3224 1.1 christos case MACRO_IR:
3225 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_register
3226 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
3227 1.1 christos goto match_failed;
3228 1.1 christos ++tokidx;
3229 1.1 christos break;
3230 1.1 christos
3231 1.1 christos /* Parenthesized index register. */
3232 1.1 christos case MACRO_PIR:
3233 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
3234 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
3235 1.1 christos goto match_failed;
3236 1.1 christos ++tokidx;
3237 1.1 christos break;
3238 1.1 christos
3239 1.1 christos /* Optional parenthesized index register. */
3240 1.1 christos case MACRO_OPIR:
3241 1.1 christos if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3242 1.1 christos && is_ir_num (tok[tokidx].X_add_number))
3243 1.1 christos ++tokidx;
3244 1.1 christos break;
3245 1.1 christos
3246 1.1 christos /* Leading comma with a parenthesized index register. */
3247 1.1 christos case MACRO_CPIR:
3248 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3249 1.1 christos || !is_ir_num (tok[tokidx].X_add_number))
3250 1.1 christos goto match_failed;
3251 1.1 christos ++tokidx;
3252 1.1 christos break;
3253 1.1 christos
3254 1.1 christos /* Floating point register. */
3255 1.1 christos case MACRO_FPR:
3256 1.1 christos if (tokidx >= ntok || tok[tokidx].X_op != O_register
3257 1.1 christos || !is_fpr_num (tok[tokidx].X_add_number))
3258 1.1 christos goto match_failed;
3259 1.1 christos ++tokidx;
3260 1.1 christos break;
3261 1.1 christos
3262 1.1 christos /* Normal expression. */
3263 1.1 christos case MACRO_EXP:
3264 1.1 christos if (tokidx >= ntok)
3265 1.1 christos goto match_failed;
3266 1.1 christos switch (tok[tokidx].X_op)
3267 1.1 christos {
3268 1.1 christos case O_illegal:
3269 1.1 christos case O_absent:
3270 1.1 christos case O_register:
3271 1.1 christos case O_pregister:
3272 1.1 christos case O_cpregister:
3273 1.1 christos case O_literal:
3274 1.1 christos case O_lituse_base:
3275 1.1 christos case O_lituse_bytoff:
3276 1.1 christos case O_lituse_jsr:
3277 1.1 christos case O_gpdisp:
3278 1.1 christos case O_gprelhigh:
3279 1.1 christos case O_gprellow:
3280 1.1 christos case O_gprel:
3281 1.1 christos case O_samegp:
3282 1.1 christos goto match_failed;
3283 1.1 christos
3284 1.1 christos default:
3285 1.1 christos break;
3286 1.1 christos }
3287 1.1 christos ++tokidx;
3288 1.1 christos break;
3289 1.1 christos
3290 1.1 christos match_failed:
3291 1.1 christos while (*arg != MACRO_EOA)
3292 1.1 christos ++arg;
3293 1.1 christos tokidx = 0;
3294 1.1 christos break;
3295 1.1 christos }
3296 1.1 christos ++arg;
3297 1.1 christos }
3298 1.1 christos }
3299 1.1 christos while (++macro - alpha_macros < (int) alpha_num_macros
3300 1.1 christos && !strcmp (macro->name, first_macro->name));
3301 1.1 christos
3302 1.1 christos return NULL;
3303 1.1 christos }
3304 1.1 christos
3305 1.1 christos /* Given an opcode name and a pre-tokenized set of arguments, take the
3306 1.1 christos opcode all the way through emission. */
3307 1.1 christos
3308 1.1 christos static void
3309 1.1 christos assemble_tokens (const char *opname,
3310 1.1 christos const expressionS *tok,
3311 1.1 christos int ntok,
3312 1.1 christos int local_macros_on)
3313 1.1 christos {
3314 1.1 christos int found_something = 0;
3315 1.1 christos const struct alpha_opcode *opcode;
3316 1.1 christos const struct alpha_macro *macro;
3317 1.1 christos int cpumatch = 1;
3318 1.1 christos extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3319 1.1 christos
3320 1.1 christos #ifdef RELOC_OP_P
3321 1.1 christos /* If a user-specified relocation is present, this is not a macro. */
3322 1.1 christos if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3323 1.1 christos {
3324 1.1 christos reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3325 1.1 christos ntok--;
3326 1.1 christos }
3327 1.1 christos else
3328 1.1 christos #endif
3329 1.1 christos if (local_macros_on)
3330 1.1 christos {
3331 1.1 christos macro = ((const struct alpha_macro *)
3332 1.1 christos hash_find (alpha_macro_hash, opname));
3333 1.1 christos if (macro)
3334 1.1 christos {
3335 1.1 christos found_something = 1;
3336 1.1 christos macro = find_macro_match (macro, tok, &ntok);
3337 1.1 christos if (macro)
3338 1.1 christos {
3339 1.1 christos (*macro->emit) (tok, ntok, macro->arg);
3340 1.1 christos return;
3341 1.1 christos }
3342 1.1 christos }
3343 1.1 christos }
3344 1.1 christos
3345 1.1 christos /* Search opcodes. */
3346 1.1 christos opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3347 1.1 christos if (opcode)
3348 1.1 christos {
3349 1.1 christos found_something = 1;
3350 1.1 christos opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3351 1.1 christos if (opcode)
3352 1.1 christos {
3353 1.1 christos struct alpha_insn insn;
3354 1.1 christos assemble_insn (opcode, tok, ntok, &insn, reloc);
3355 1.1 christos
3356 1.1 christos /* Copy the sequence number for the reloc from the reloc token. */
3357 1.1 christos if (reloc != BFD_RELOC_UNUSED)
3358 1.1 christos insn.sequence = tok[ntok].X_add_number;
3359 1.1 christos
3360 1.1 christos emit_insn (&insn);
3361 1.1 christos return;
3362 1.1 christos }
3363 1.1 christos }
3364 1.1 christos
3365 1.1 christos if (found_something)
3366 1.1 christos {
3367 1.1 christos if (cpumatch)
3368 1.1 christos as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3369 1.1 christos else
3370 1.1 christos as_bad (_("opcode `%s' not supported for target %s"), opname,
3371 1.1 christos alpha_target_name);
3372 1.1 christos }
3373 1.1 christos else
3374 1.1 christos as_bad (_("unknown opcode `%s'"), opname);
3375 1.1 christos }
3376 1.1 christos
3377 1.1 christos #ifdef OBJ_EVAX
3379 1.1 christos
3380 1.1 christos /* Add sym+addend to link pool.
3381 1.1 christos Return offset from curent procedure value (pv) to entry in link pool.
3382 1.1 christos
3383 1.1 christos Add new fixup only if offset isn't 16bit. */
3384 1.1 christos
3385 1.1 christos static symbolS *
3386 1.1 christos add_to_link_pool (symbolS *sym, offsetT addend)
3387 1.1 christos {
3388 1.1 christos symbolS *basesym;
3389 1.1 christos segT current_section = now_seg;
3390 1.1 christos int current_subsec = now_subseg;
3391 1.1 christos char *p;
3392 1.1 christos segment_info_type *seginfo = seg_info (alpha_link_section);
3393 1.1 christos fixS *fixp;
3394 1.1 christos symbolS *linksym, *expsym;
3395 1.1 christos expressionS e;
3396 1.1 christos
3397 1.1 christos basesym = alpha_evax_proc->symbol;
3398 1.1 christos
3399 1.1 christos /* @@ This assumes all entries in a given section will be of the same
3400 1.1 christos size... Probably correct, but unwise to rely on. */
3401 1.1 christos /* This must always be called with the same subsegment. */
3402 1.1 christos
3403 1.1 christos if (seginfo->frchainP)
3404 1.1 christos for (fixp = seginfo->frchainP->fix_root;
3405 1.1 christos fixp != (fixS *) NULL;
3406 1.1 christos fixp = fixp->fx_next)
3407 1.1 christos {
3408 1.1 christos if (fixp->fx_addsy == sym
3409 1.1 christos && fixp->fx_offset == (valueT)addend
3410 1.1 christos && fixp->tc_fix_data.info
3411 1.1 christos && fixp->tc_fix_data.info->sym
3412 1.1 christos && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
3413 1.1 christos return fixp->tc_fix_data.info->sym;
3414 1.1 christos }
3415 1.1 christos
3416 1.1 christos /* Not found, add a new entry. */
3417 1.1 christos subseg_set (alpha_link_section, 0);
3418 1.1 christos linksym = symbol_new
3419 1.1 christos (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3420 1.1 christos p = frag_more (8);
3421 1.1 christos memset (p, 0, 8);
3422 1.1 christos
3423 1.1 christos /* Create a symbol for 'basesym - linksym' (offset of the added entry). */
3424 1.1 christos e.X_op = O_subtract;
3425 1.1 christos e.X_add_symbol = linksym;
3426 1.1 christos e.X_op_symbol = basesym;
3427 1.1 christos e.X_add_number = 0;
3428 1.1 christos expsym = make_expr_symbol (&e);
3429 1.1 christos
3430 1.1 christos /* Create a fixup for the entry. */
3431 1.1 christos fixp = fix_new
3432 1.1 christos (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
3433 1.1 christos fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--);
3434 1.1 christos fixp->tc_fix_data.info->sym = expsym;
3435 1.1 christos
3436 1.1 christos subseg_set (current_section, current_subsec);
3437 1.1 christos
3438 1.1 christos /* Return the symbol. */
3439 1.1 christos return expsym;
3440 1.1 christos }
3441 1.1 christos #endif /* OBJ_EVAX */
3442 1.1 christos
3443 1.1 christos /* Assembler directives. */
3445 1.1 christos
3446 1.1 christos /* Handle the .text pseudo-op. This is like the usual one, but it
3447 1.1 christos clears alpha_insn_label and restores auto alignment. */
3448 1.1 christos
3449 1.1 christos static void
3450 1.1 christos s_alpha_text (int i)
3451 1.1 christos {
3452 1.1 christos #ifdef OBJ_ELF
3453 1.1 christos obj_elf_text (i);
3454 1.1 christos #else
3455 1.1 christos s_text (i);
3456 1.1 christos #endif
3457 1.1 christos #ifdef OBJ_EVAX
3458 1.1 christos {
3459 1.1 christos symbolS * symbolP;
3460 1.1 christos
3461 1.1 christos symbolP = symbol_find (".text");
3462 1.1 christos if (symbolP == NULL)
3463 1.1 christos {
3464 1.1 christos symbolP = symbol_make (".text");
3465 1.1 christos S_SET_SEGMENT (symbolP, text_section);
3466 1.1 christos symbol_table_insert (symbolP);
3467 1.1 christos }
3468 1.1 christos }
3469 1.1 christos #endif
3470 1.1 christos alpha_insn_label = NULL;
3471 1.1 christos alpha_auto_align_on = 1;
3472 1.1 christos alpha_current_align = 0;
3473 1.1 christos }
3474 1.1 christos
3475 1.1 christos /* Handle the .data pseudo-op. This is like the usual one, but it
3476 1.1 christos clears alpha_insn_label and restores auto alignment. */
3477 1.1 christos
3478 1.1 christos static void
3479 1.1 christos s_alpha_data (int i)
3480 1.1 christos {
3481 1.1 christos #ifdef OBJ_ELF
3482 1.1 christos obj_elf_data (i);
3483 1.1 christos #else
3484 1.1 christos s_data (i);
3485 1.1 christos #endif
3486 1.1 christos alpha_insn_label = NULL;
3487 1.1 christos alpha_auto_align_on = 1;
3488 1.1 christos alpha_current_align = 0;
3489 1.1 christos }
3490 1.1 christos
3491 1.1 christos #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3492 1.1 christos
3493 1.1 christos /* Handle the OSF/1 and openVMS .comm pseudo quirks. */
3494 1.1 christos
3495 1.1 christos static void
3496 1.1 christos s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3497 1.1 christos {
3498 1.1 christos char *name;
3499 1.1 christos char c;
3500 1.1 christos char *p;
3501 1.1 christos offsetT size;
3502 1.1 christos symbolS *symbolP;
3503 1.1 christos #ifdef OBJ_EVAX
3504 1.1 christos offsetT temp;
3505 1.1 christos int log_align = 0;
3506 1.1 christos #endif
3507 1.1 christos
3508 1.1 christos name = input_line_pointer;
3509 1.1 christos c = get_symbol_end ();
3510 1.1 christos
3511 1.1 christos /* Just after name is now '\0'. */
3512 1.1 christos p = input_line_pointer;
3513 1.1 christos *p = c;
3514 1.1 christos
3515 1.1 christos SKIP_WHITESPACE ();
3516 1.1 christos
3517 1.1 christos /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3518 1.1 christos if (*input_line_pointer == ',')
3519 1.1 christos {
3520 1.1 christos input_line_pointer++;
3521 1.1 christos SKIP_WHITESPACE ();
3522 1.1 christos }
3523 1.1 christos if ((size = get_absolute_expression ()) < 0)
3524 1.1 christos {
3525 1.1 christos as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
3526 1.1 christos ignore_rest_of_line ();
3527 1.1 christos return;
3528 1.1 christos }
3529 1.1 christos
3530 1.1 christos *p = 0;
3531 1.1 christos symbolP = symbol_find_or_make (name);
3532 1.1 christos *p = c;
3533 1.1 christos
3534 1.1 christos if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3535 1.1 christos {
3536 1.1 christos as_bad (_("Ignoring attempt to re-define symbol"));
3537 1.1 christos ignore_rest_of_line ();
3538 1.1 christos return;
3539 1.1 christos }
3540 1.1 christos
3541 1.1 christos #ifdef OBJ_EVAX
3542 1.1 christos if (*input_line_pointer != ',')
3543 1.1 christos temp = 8; /* Default alignment. */
3544 1.1 christos else
3545 1.1 christos {
3546 1.1 christos input_line_pointer++;
3547 1.1 christos SKIP_WHITESPACE ();
3548 1.1 christos temp = get_absolute_expression ();
3549 1.1 christos }
3550 1.1 christos
3551 1.1 christos /* ??? Unlike on OSF/1, the alignment factor is not in log units. */
3552 1.1 christos while ((temp >>= 1) != 0)
3553 1.1 christos ++log_align;
3554 1.1 christos
3555 1.1 christos if (*input_line_pointer == ',')
3556 1.1 christos {
3557 1.1 christos /* Extended form of the directive
3558 1.1 christos
3559 1.1 christos .comm symbol, size, alignment, section
3560 1.1 christos
3561 1.1 christos where the "common" semantics is transferred to the section.
3562 1.1 christos The symbol is effectively an alias for the section name. */
3563 1.1 christos
3564 1.1 christos segT sec;
3565 1.1 christos char *sec_name;
3566 1.1 christos symbolS *sec_symbol;
3567 1.1 christos segT current_seg = now_seg;
3568 1.1 christos subsegT current_subseg = now_subseg;
3569 1.1 christos int cur_size;
3570 1.1 christos
3571 1.1 christos input_line_pointer++;
3572 1.1 christos SKIP_WHITESPACE ();
3573 1.1 christos sec_name = s_alpha_section_name ();
3574 1.1 christos sec_symbol = symbol_find_or_make (sec_name);
3575 1.1 christos sec = subseg_new (sec_name, 0);
3576 1.1 christos S_SET_SEGMENT (sec_symbol, sec);
3577 1.1 christos symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM;
3578 1.1 christos bfd_vms_set_section_flags (stdoutput, sec, 0,
3579 1.1 christos EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD);
3580 1.1 christos record_alignment (sec, log_align);
3581 1.1 christos
3582 1.1 christos /* Reuse stab_string_size to store the size of the section. */
3583 1.1 christos cur_size = seg_info (sec)->stabu.stab_string_size;
3584 1.1 christos if ((int) size > cur_size)
3585 1.1 christos {
3586 1.1 christos char *pfrag
3587 1.1 christos = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
3588 1.1 christos (valueT)size - (valueT)cur_size, NULL);
3589 1.1 christos *pfrag = 0;
3590 1.1 christos seg_info (sec)->stabu.stab_string_size = (int)size;
3591 1.1 christos }
3592 1.1 christos
3593 1.1 christos S_SET_SEGMENT (symbolP, sec);
3594 1.1 christos
3595 1.1 christos subseg_set (current_seg, current_subseg);
3596 1.1 christos }
3597 1.1 christos else
3598 1.1 christos {
3599 1.1 christos /* Regular form of the directive
3600 1.1 christos
3601 1.1 christos .comm symbol, size, alignment
3602 1.1 christos
3603 1.1 christos where the "common" semantics in on the symbol.
3604 1.1 christos These symbols are assembled in the .bss section. */
3605 1.1 christos
3606 1.1 christos char *pfrag;
3607 1.1 christos segT current_seg = now_seg;
3608 1.1 christos subsegT current_subseg = now_subseg;
3609 1.1 christos
3610 1.1 christos subseg_set (bss_section, 1);
3611 1.1 christos frag_align (log_align, 0, 0);
3612 1.1 christos record_alignment (bss_section, log_align);
3613 1.1 christos
3614 1.1 christos symbol_set_frag (symbolP, frag_now);
3615 1.1 christos pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
3616 1.1 christos size, NULL);
3617 1.1 christos *pfrag = 0;
3618 1.1 christos
3619 1.1 christos S_SET_SEGMENT (symbolP, bss_section);
3620 1.1 christos
3621 1.1 christos subseg_set (current_seg, current_subseg);
3622 1.1 christos }
3623 1.1 christos #endif
3624 1.1 christos
3625 1.1 christos if (S_GET_VALUE (symbolP))
3626 1.1 christos {
3627 1.1 christos if (S_GET_VALUE (symbolP) != (valueT) size)
3628 1.1 christos as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3629 1.1 christos S_GET_NAME (symbolP),
3630 1.1 christos (long) S_GET_VALUE (symbolP),
3631 1.1 christos (long) size);
3632 1.1 christos }
3633 1.1 christos else
3634 1.1 christos {
3635 1.1 christos #ifndef OBJ_EVAX
3636 1.1 christos S_SET_VALUE (symbolP, (valueT) size);
3637 1.1 christos #endif
3638 1.1 christos S_SET_EXTERNAL (symbolP);
3639 1.1 christos }
3640 1.1 christos
3641 1.1 christos #ifndef OBJ_EVAX
3642 1.1 christos know (symbolP->sy_frag == &zero_address_frag);
3643 1.1 christos #endif
3644 1.1 christos demand_empty_rest_of_line ();
3645 1.1 christos }
3646 1.1 christos
3647 1.1 christos #endif /* ! OBJ_ELF */
3648 1.1 christos
3649 1.1 christos #ifdef OBJ_ECOFF
3650 1.1 christos
3651 1.1 christos /* Handle the .rdata pseudo-op. This is like the usual one, but it
3652 1.1 christos clears alpha_insn_label and restores auto alignment. */
3653 1.1 christos
3654 1.1 christos static void
3655 1.1 christos s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3656 1.1 christos {
3657 1.1 christos get_absolute_expression ();
3658 1.1 christos subseg_new (".rdata", 0);
3659 1.1 christos demand_empty_rest_of_line ();
3660 1.1 christos alpha_insn_label = NULL;
3661 1.1 christos alpha_auto_align_on = 1;
3662 1.1 christos alpha_current_align = 0;
3663 1.1 christos }
3664 1.1 christos
3665 1.1 christos #endif
3666 1.1 christos
3667 1.1 christos #ifdef OBJ_ECOFF
3668 1.1 christos
3669 1.1 christos /* Handle the .sdata pseudo-op. This is like the usual one, but it
3670 1.1 christos clears alpha_insn_label and restores auto alignment. */
3671 1.1 christos
3672 1.1 christos static void
3673 1.1 christos s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3674 1.1 christos {
3675 1.1 christos get_absolute_expression ();
3676 1.1 christos subseg_new (".sdata", 0);
3677 1.1 christos demand_empty_rest_of_line ();
3678 1.1 christos alpha_insn_label = NULL;
3679 1.1 christos alpha_auto_align_on = 1;
3680 1.1 christos alpha_current_align = 0;
3681 1.1 christos }
3682 1.1 christos #endif
3683 1.1 christos
3684 1.1 christos #ifdef OBJ_ELF
3685 1.1 christos struct alpha_elf_frame_data
3686 1.1 christos {
3687 1.1 christos symbolS *func_sym;
3688 1.1 christos symbolS *func_end_sym;
3689 1.1 christos symbolS *prologue_sym;
3690 1.1 christos unsigned int mask;
3691 1.1 christos unsigned int fmask;
3692 1.1 christos int fp_regno;
3693 1.1 christos int ra_regno;
3694 1.1 christos offsetT frame_size;
3695 1.1 christos offsetT mask_offset;
3696 1.1 christos offsetT fmask_offset;
3697 1.1 christos
3698 1.1 christos struct alpha_elf_frame_data *next;
3699 1.1 christos };
3700 1.1 christos
3701 1.1 christos static struct alpha_elf_frame_data *all_frame_data;
3702 1.1 christos static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3703 1.1 christos static struct alpha_elf_frame_data *cur_frame_data;
3704 1.1 christos
3705 1.1 christos /* Handle the .section pseudo-op. This is like the usual one, but it
3706 1.1 christos clears alpha_insn_label and restores auto alignment. */
3707 1.1 christos
3708 1.1 christos static void
3709 1.1 christos s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3710 1.1 christos {
3711 1.1 christos obj_elf_section (ignore);
3712 1.1 christos
3713 1.1 christos alpha_insn_label = NULL;
3714 1.1 christos alpha_auto_align_on = 1;
3715 1.1 christos alpha_current_align = 0;
3716 1.1 christos }
3717 1.1 christos
3718 1.1 christos static void
3719 1.1 christos s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3720 1.1 christos {
3721 1.1 christos if (ECOFF_DEBUGGING)
3722 1.1 christos ecoff_directive_ent (0);
3723 1.1 christos else
3724 1.1 christos {
3725 1.1 christos char *name, name_end;
3726 1.1 christos name = input_line_pointer;
3727 1.1 christos name_end = get_symbol_end ();
3728 1.1 christos
3729 1.1 christos if (! is_name_beginner (*name))
3730 1.1 christos {
3731 1.1 christos as_warn (_(".ent directive has no name"));
3732 1.1 christos *input_line_pointer = name_end;
3733 1.1 christos }
3734 1.1 christos else
3735 1.1 christos {
3736 1.1 christos symbolS *sym;
3737 1.1 christos
3738 1.1 christos if (cur_frame_data)
3739 1.1 christos as_warn (_("nested .ent directives"));
3740 1.1 christos
3741 1.1 christos sym = symbol_find_or_make (name);
3742 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3743 1.1 christos
3744 1.1 christos cur_frame_data = (struct alpha_elf_frame_data *)
3745 1.1 christos calloc (1, sizeof (*cur_frame_data));
3746 1.1 christos cur_frame_data->func_sym = sym;
3747 1.1 christos
3748 1.1 christos /* Provide sensible defaults. */
3749 1.1 christos cur_frame_data->fp_regno = 30; /* sp */
3750 1.1 christos cur_frame_data->ra_regno = 26; /* ra */
3751 1.1 christos
3752 1.1 christos *plast_frame_data = cur_frame_data;
3753 1.1 christos plast_frame_data = &cur_frame_data->next;
3754 1.1 christos
3755 1.1 christos /* The .ent directive is sometimes followed by a number. Not sure
3756 1.1 christos what it really means, but ignore it. */
3757 1.1 christos *input_line_pointer = name_end;
3758 1.1 christos SKIP_WHITESPACE ();
3759 1.1 christos if (*input_line_pointer == ',')
3760 1.1 christos {
3761 1.1 christos input_line_pointer++;
3762 1.1 christos SKIP_WHITESPACE ();
3763 1.1 christos }
3764 1.1 christos if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3765 1.1 christos (void) get_absolute_expression ();
3766 1.1 christos }
3767 1.1 christos demand_empty_rest_of_line ();
3768 1.1 christos }
3769 1.1 christos }
3770 1.1 christos
3771 1.1 christos static void
3772 1.1 christos s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3773 1.1 christos {
3774 1.1 christos if (ECOFF_DEBUGGING)
3775 1.1 christos ecoff_directive_end (0);
3776 1.1 christos else
3777 1.1 christos {
3778 1.1 christos char *name, name_end;
3779 1.1 christos name = input_line_pointer;
3780 1.1 christos name_end = get_symbol_end ();
3781 1.1 christos
3782 1.1 christos if (! is_name_beginner (*name))
3783 1.1 christos {
3784 1.1 christos as_warn (_(".end directive has no name"));
3785 1.1 christos *input_line_pointer = name_end;
3786 1.1 christos }
3787 1.1 christos else
3788 1.1 christos {
3789 1.1 christos symbolS *sym;
3790 1.1 christos
3791 1.1 christos sym = symbol_find (name);
3792 1.1 christos if (!cur_frame_data)
3793 1.1 christos as_warn (_(".end directive without matching .ent"));
3794 1.1 christos else if (sym != cur_frame_data->func_sym)
3795 1.1 christos as_warn (_(".end directive names different symbol than .ent"));
3796 1.1 christos
3797 1.1 christos /* Create an expression to calculate the size of the function. */
3798 1.1 christos if (sym && cur_frame_data)
3799 1.1 christos {
3800 1.1 christos OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3801 1.1 christos expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS));
3802 1.1 christos
3803 1.1 christos obj->size = exp;
3804 1.1 christos exp->X_op = O_subtract;
3805 1.1 christos exp->X_add_symbol = symbol_temp_new_now ();
3806 1.1 christos exp->X_op_symbol = sym;
3807 1.1 christos exp->X_add_number = 0;
3808 1.1 christos
3809 1.1 christos cur_frame_data->func_end_sym = exp->X_add_symbol;
3810 1.1 christos }
3811 1.1 christos
3812 1.1 christos cur_frame_data = NULL;
3813 1.1 christos
3814 1.1 christos *input_line_pointer = name_end;
3815 1.1 christos }
3816 1.1 christos demand_empty_rest_of_line ();
3817 1.1 christos }
3818 1.1 christos }
3819 1.1 christos
3820 1.1 christos static void
3821 1.1 christos s_alpha_mask (int fp)
3822 1.1 christos {
3823 1.1 christos if (ECOFF_DEBUGGING)
3824 1.1 christos {
3825 1.1 christos if (fp)
3826 1.1 christos ecoff_directive_fmask (0);
3827 1.1 christos else
3828 1.1 christos ecoff_directive_mask (0);
3829 1.1 christos }
3830 1.1 christos else
3831 1.1 christos {
3832 1.1 christos long val;
3833 1.1 christos offsetT offset;
3834 1.1 christos
3835 1.1 christos if (!cur_frame_data)
3836 1.1 christos {
3837 1.1 christos if (fp)
3838 1.1 christos as_warn (_(".fmask outside of .ent"));
3839 1.1 christos else
3840 1.1 christos as_warn (_(".mask outside of .ent"));
3841 1.1 christos discard_rest_of_line ();
3842 1.1 christos return;
3843 1.1 christos }
3844 1.1 christos
3845 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',')
3846 1.1 christos {
3847 1.1 christos if (fp)
3848 1.1 christos as_warn (_("bad .fmask directive"));
3849 1.1 christos else
3850 1.1 christos as_warn (_("bad .mask directive"));
3851 1.1 christos --input_line_pointer;
3852 1.1 christos discard_rest_of_line ();
3853 1.1 christos return;
3854 1.1 christos }
3855 1.1 christos
3856 1.1 christos offset = get_absolute_expression ();
3857 1.1 christos demand_empty_rest_of_line ();
3858 1.1 christos
3859 1.1 christos if (fp)
3860 1.1 christos {
3861 1.1 christos cur_frame_data->fmask = val;
3862 1.1 christos cur_frame_data->fmask_offset = offset;
3863 1.1 christos }
3864 1.1 christos else
3865 1.1 christos {
3866 1.1 christos cur_frame_data->mask = val;
3867 1.1 christos cur_frame_data->mask_offset = offset;
3868 1.1 christos }
3869 1.1 christos }
3870 1.1 christos }
3871 1.1 christos
3872 1.1 christos static void
3873 1.1 christos s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3874 1.1 christos {
3875 1.1 christos if (ECOFF_DEBUGGING)
3876 1.1 christos ecoff_directive_frame (0);
3877 1.1 christos else
3878 1.1 christos {
3879 1.1 christos long val;
3880 1.1 christos
3881 1.1 christos if (!cur_frame_data)
3882 1.1 christos {
3883 1.1 christos as_warn (_(".frame outside of .ent"));
3884 1.1 christos discard_rest_of_line ();
3885 1.1 christos return;
3886 1.1 christos }
3887 1.1 christos
3888 1.1 christos cur_frame_data->fp_regno = tc_get_register (1);
3889 1.1 christos
3890 1.1 christos SKIP_WHITESPACE ();
3891 1.1 christos if (*input_line_pointer++ != ','
3892 1.1 christos || get_absolute_expression_and_terminator (&val) != ',')
3893 1.1 christos {
3894 1.1 christos as_warn (_("bad .frame directive"));
3895 1.1 christos --input_line_pointer;
3896 1.1 christos discard_rest_of_line ();
3897 1.1 christos return;
3898 1.1 christos }
3899 1.1 christos cur_frame_data->frame_size = val;
3900 1.1 christos
3901 1.1 christos cur_frame_data->ra_regno = tc_get_register (0);
3902 1.1 christos
3903 1.1 christos /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3904 1.1 christos this is current_function_pretend_args_size. There's no place
3905 1.1 christos to put this value, so ignore it. */
3906 1.1 christos s_ignore (42);
3907 1.1 christos }
3908 1.1 christos }
3909 1.1 christos
3910 1.1 christos static void
3911 1.1 christos s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3912 1.1 christos {
3913 1.1 christos symbolS *sym;
3914 1.1 christos int arg;
3915 1.1 christos
3916 1.1 christos arg = get_absolute_expression ();
3917 1.1 christos demand_empty_rest_of_line ();
3918 1.1 christos alpha_prologue_label = symbol_new
3919 1.1 christos (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3920 1.1 christos
3921 1.1 christos if (ECOFF_DEBUGGING)
3922 1.1 christos sym = ecoff_get_cur_proc_sym ();
3923 1.1 christos else
3924 1.1 christos sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3925 1.1 christos
3926 1.1 christos if (sym == NULL)
3927 1.1 christos {
3928 1.1 christos as_bad (_(".prologue directive without a preceding .ent directive"));
3929 1.1 christos return;
3930 1.1 christos }
3931 1.1 christos
3932 1.1 christos switch (arg)
3933 1.1 christos {
3934 1.1 christos case 0: /* No PV required. */
3935 1.1 christos S_SET_OTHER (sym, STO_ALPHA_NOPV
3936 1.1 christos | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3937 1.1 christos break;
3938 1.1 christos case 1: /* Std GP load. */
3939 1.1 christos S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3940 1.1 christos | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3941 1.1 christos break;
3942 1.1 christos case 2: /* Non-std use of PV. */
3943 1.1 christos break;
3944 1.1 christos
3945 1.1 christos default:
3946 1.1 christos as_bad (_("Invalid argument %d to .prologue."), arg);
3947 1.1 christos break;
3948 1.1 christos }
3949 1.1 christos
3950 1.1 christos if (cur_frame_data)
3951 1.1 christos cur_frame_data->prologue_sym = symbol_temp_new_now ();
3952 1.1 christos }
3953 1.1 christos
3954 1.1 christos static char *first_file_directive;
3955 1.1 christos
3956 1.1 christos static void
3957 1.1 christos s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3958 1.1 christos {
3959 1.1 christos /* Save the first .file directive we see, so that we can change our
3960 1.1 christos minds about whether ecoff debugging should or shouldn't be enabled. */
3961 1.1 christos if (alpha_flag_mdebug < 0 && ! first_file_directive)
3962 1.1 christos {
3963 1.1 christos char *start = input_line_pointer;
3964 1.1 christos size_t len;
3965 1.1 christos
3966 1.1 christos discard_rest_of_line ();
3967 1.1 christos
3968 1.1 christos len = input_line_pointer - start;
3969 1.1 christos first_file_directive = (char *) xmalloc (len + 1);
3970 1.1 christos memcpy (first_file_directive, start, len);
3971 1.1 christos first_file_directive[len] = '\0';
3972 1.1 christos
3973 1.1 christos input_line_pointer = start;
3974 1.1 christos }
3975 1.1 christos
3976 1.1 christos if (ECOFF_DEBUGGING)
3977 1.1 christos ecoff_directive_file (0);
3978 1.1 christos else
3979 1.1 christos dwarf2_directive_file (0);
3980 1.1 christos }
3981 1.1 christos
3982 1.1 christos static void
3983 1.1 christos s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3984 1.1 christos {
3985 1.1 christos if (ECOFF_DEBUGGING)
3986 1.1 christos ecoff_directive_loc (0);
3987 1.1 christos else
3988 1.1 christos dwarf2_directive_loc (0);
3989 1.1 christos }
3990 1.1 christos
3991 1.1 christos static void
3992 1.1 christos s_alpha_stab (int n)
3993 1.1 christos {
3994 1.1 christos /* If we've been undecided about mdebug, make up our minds in favour. */
3995 1.1 christos if (alpha_flag_mdebug < 0)
3996 1.1 christos {
3997 1.1 christos segT sec = subseg_new (".mdebug", 0);
3998 1.1 christos bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3999 1.1 christos bfd_set_section_alignment (stdoutput, sec, 3);
4000 1.1 christos
4001 1.1 christos ecoff_read_begin_hook ();
4002 1.1 christos
4003 1.1 christos if (first_file_directive)
4004 1.1 christos {
4005 1.1 christos char *save_ilp = input_line_pointer;
4006 1.1 christos input_line_pointer = first_file_directive;
4007 1.1 christos ecoff_directive_file (0);
4008 1.1 christos input_line_pointer = save_ilp;
4009 1.1 christos free (first_file_directive);
4010 1.1 christos }
4011 1.1 christos
4012 1.1 christos alpha_flag_mdebug = 1;
4013 1.1 christos }
4014 1.1 christos s_stab (n);
4015 1.1 christos }
4016 1.1 christos
4017 1.1 christos static void
4018 1.1 christos s_alpha_coff_wrapper (int which)
4019 1.1 christos {
4020 1.1 christos static void (* const fns[]) (int) = {
4021 1.1 christos ecoff_directive_begin,
4022 1.1 christos ecoff_directive_bend,
4023 1.1 christos ecoff_directive_def,
4024 1.1 christos ecoff_directive_dim,
4025 1.1 christos ecoff_directive_endef,
4026 1.1 christos ecoff_directive_scl,
4027 1.1 christos ecoff_directive_tag,
4028 1.1 christos ecoff_directive_val,
4029 1.1 christos };
4030 1.1 christos
4031 1.1 christos gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4032 1.1 christos
4033 1.1 christos if (ECOFF_DEBUGGING)
4034 1.1 christos (*fns[which]) (0);
4035 1.1 christos else
4036 1.1 christos {
4037 1.1 christos as_bad (_("ECOFF debugging is disabled."));
4038 1.1 christos ignore_rest_of_line ();
4039 1.1 christos }
4040 1.1 christos }
4041 1.1 christos
4042 1.1 christos /* Called at the end of assembly. Here we emit unwind info for frames
4043 1.1 christos unless the compiler has done it for us. */
4044 1.1 christos
4045 1.1 christos void
4046 1.1 christos alpha_elf_md_end (void)
4047 1.1 christos {
4048 1.1 christos struct alpha_elf_frame_data *p;
4049 1.1 christos
4050 1.1 christos if (cur_frame_data)
4051 1.1 christos as_warn (_(".ent directive without matching .end"));
4052 1.1 christos
4053 1.1 christos /* If someone has generated the unwind info themselves, great. */
4054 1.1 christos if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
4055 1.1 christos return;
4056 1.1 christos
4057 1.1 christos /* ??? In theory we could look for functions for which we have
4058 1.1 christos generated unwind info via CFI directives, and those we have not.
4059 1.1 christos Those we have not could still get their unwind info from here.
4060 1.1 christos For now, do nothing if we've seen any CFI directives. Note that
4061 1.1 christos the above test will not trigger, as we've not emitted data yet. */
4062 1.1 christos if (all_fde_data != NULL)
4063 1.1 christos return;
4064 1.1 christos
4065 1.1 christos /* Generate .eh_frame data for the unwind directives specified. */
4066 1.1 christos for (p = all_frame_data; p ; p = p->next)
4067 1.1 christos if (p->prologue_sym)
4068 1.1 christos {
4069 1.1 christos /* Create a temporary symbol at the same location as our
4070 1.1 christos function symbol. This prevents problems with globals. */
4071 1.1 christos cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
4072 1.1 christos S_GET_VALUE (p->func_sym),
4073 1.1 christos symbol_get_frag (p->func_sym)));
4074 1.1 christos
4075 1.1 christos cfi_set_return_column (p->ra_regno);
4076 1.1 christos cfi_add_CFA_def_cfa_register (30);
4077 1.1 christos if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
4078 1.1 christos {
4079 1.1 christos unsigned int mask;
4080 1.1 christos offsetT offset;
4081 1.1 christos
4082 1.1 christos cfi_add_advance_loc (p->prologue_sym);
4083 1.1 christos
4084 1.1 christos if (p->fp_regno != 30)
4085 1.1 christos if (p->frame_size != 0)
4086 1.1 christos cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
4087 1.1 christos else
4088 1.1 christos cfi_add_CFA_def_cfa_register (p->fp_regno);
4089 1.1 christos else if (p->frame_size != 0)
4090 1.1 christos cfi_add_CFA_def_cfa_offset (p->frame_size);
4091 1.1 christos
4092 1.1 christos mask = p->mask;
4093 1.1 christos offset = p->mask_offset;
4094 1.1 christos
4095 1.1 christos /* Recall that $26 is special-cased and stored first. */
4096 1.1 christos if ((mask >> 26) & 1)
4097 1.1 christos {
4098 1.1 christos cfi_add_CFA_offset (26, offset);
4099 1.1 christos offset += 8;
4100 1.1 christos mask &= ~(1 << 26);
4101 1.1 christos }
4102 1.1 christos while (mask)
4103 1.1 christos {
4104 1.1 christos unsigned int i;
4105 1.1 christos i = mask & -mask;
4106 1.1 christos mask ^= i;
4107 1.1 christos i = ffs (i) - 1;
4108 1.1 christos
4109 1.1 christos cfi_add_CFA_offset (i, offset);
4110 1.1 christos offset += 8;
4111 1.1 christos }
4112 1.1 christos
4113 1.1 christos mask = p->fmask;
4114 1.1 christos offset = p->fmask_offset;
4115 1.1 christos while (mask)
4116 1.1 christos {
4117 1.1 christos unsigned int i;
4118 1.1 christos i = mask & -mask;
4119 1.1 christos mask ^= i;
4120 1.1 christos i = ffs (i) - 1;
4121 1.1 christos
4122 1.1 christos cfi_add_CFA_offset (i + 32, offset);
4123 1.1 christos offset += 8;
4124 1.1 christos }
4125 1.1 christos }
4126 1.1 christos
4127 1.1 christos cfi_end_fde (p->func_end_sym);
4128 1.1 christos }
4129 1.1 christos }
4130 1.1 christos
4131 1.1 christos static void
4132 1.1 christos s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
4133 1.1 christos {
4134 1.1 christos char *name, name_end;
4135 1.1 christos char *which, which_end;
4136 1.1 christos symbolS *sym;
4137 1.1 christos int other;
4138 1.1 christos
4139 1.1 christos name = input_line_pointer;
4140 1.1 christos name_end = get_symbol_end ();
4141 1.1 christos
4142 1.1 christos if (! is_name_beginner (*name))
4143 1.1 christos {
4144 1.1 christos as_bad (_(".usepv directive has no name"));
4145 1.1 christos *input_line_pointer = name_end;
4146 1.1 christos ignore_rest_of_line ();
4147 1.1 christos return;
4148 1.1 christos }
4149 1.1 christos
4150 1.1 christos sym = symbol_find_or_make (name);
4151 1.1 christos *input_line_pointer++ = name_end;
4152 1.1 christos
4153 1.1 christos if (name_end != ',')
4154 1.1 christos {
4155 1.1 christos as_bad (_(".usepv directive has no type"));
4156 1.1 christos ignore_rest_of_line ();
4157 1.1 christos return;
4158 1.1 christos }
4159 1.1 christos
4160 1.1 christos SKIP_WHITESPACE ();
4161 1.1 christos which = input_line_pointer;
4162 1.1 christos which_end = get_symbol_end ();
4163 1.1 christos
4164 1.1 christos if (strcmp (which, "no") == 0)
4165 1.1 christos other = STO_ALPHA_NOPV;
4166 1.1 christos else if (strcmp (which, "std") == 0)
4167 1.1 christos other = STO_ALPHA_STD_GPLOAD;
4168 1.1 christos else
4169 1.1 christos {
4170 1.1 christos as_bad (_("unknown argument for .usepv"));
4171 1.1 christos other = 0;
4172 1.1 christos }
4173 1.1 christos
4174 1.1 christos *input_line_pointer = which_end;
4175 1.1 christos demand_empty_rest_of_line ();
4176 1.1 christos
4177 1.1 christos S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4178 1.1 christos }
4179 1.1 christos #endif /* OBJ_ELF */
4180 1.1 christos
4181 1.1 christos /* Standard calling conventions leaves the CFA at $30 on entry. */
4182 1.1 christos
4183 1.1 christos void
4184 1.1 christos alpha_cfi_frame_initial_instructions (void)
4185 1.1 christos {
4186 1.1 christos cfi_add_CFA_def_cfa_register (30);
4187 1.1 christos }
4188 1.1 christos
4189 1.1 christos #ifdef OBJ_EVAX
4190 1.1 christos
4191 1.1 christos /* Get name of section. */
4192 1.1 christos static char *
4193 1.1 christos s_alpha_section_name (void)
4194 1.1 christos {
4195 1.1 christos char *name;
4196 1.1 christos
4197 1.1 christos SKIP_WHITESPACE ();
4198 1.1 christos if (*input_line_pointer == '"')
4199 1.1 christos {
4200 1.1 christos int dummy;
4201 1.1 christos
4202 1.1 christos name = demand_copy_C_string (&dummy);
4203 1.1 christos if (name == NULL)
4204 1.1 christos {
4205 1.1 christos ignore_rest_of_line ();
4206 1.1 christos return NULL;
4207 1.1 christos }
4208 1.1 christos }
4209 1.1 christos else
4210 1.1 christos {
4211 1.1 christos char *end = input_line_pointer;
4212 1.1 christos
4213 1.1 christos while (0 == strchr ("\n\t,; ", *end))
4214 1.1 christos end++;
4215 1.1 christos if (end == input_line_pointer)
4216 1.1 christos {
4217 1.1 christos as_warn (_("missing name"));
4218 1.1 christos ignore_rest_of_line ();
4219 1.1 christos return NULL;
4220 1.1 christos }
4221 1.1 christos
4222 1.1 christos name = xmalloc (end - input_line_pointer + 1);
4223 1.1 christos memcpy (name, input_line_pointer, end - input_line_pointer);
4224 1.1 christos name[end - input_line_pointer] = '\0';
4225 1.1 christos input_line_pointer = end;
4226 1.1 christos }
4227 1.1 christos SKIP_WHITESPACE ();
4228 1.1 christos return name;
4229 1.1 christos }
4230 1.1 christos
4231 1.1 christos /* Put clear/set flags in one flagword. The LSBs are flags to be set,
4232 1.1 christos the MSBs are the flags to be cleared. */
4233 1.1 christos
4234 1.1 christos #define EGPS__V_NO_SHIFT 16
4235 1.1 christos #define EGPS__V_MASK 0xffff
4236 1.1 christos
4237 1.1 christos /* Parse one VMS section flag. */
4238 1.1 christos
4239 1.1 christos static flagword
4240 1.1 christos s_alpha_section_word (char *str, size_t len)
4241 1.1 christos {
4242 1.1 christos int no = 0;
4243 1.1 christos flagword flag = 0;
4244 1.1 christos
4245 1.1 christos if (len == 5 && strncmp (str, "NO", 2) == 0)
4246 1.1 christos {
4247 1.1 christos no = 1;
4248 1.1 christos str += 2;
4249 1.1 christos len -= 2;
4250 1.1 christos }
4251 1.1 christos
4252 1.1 christos if (len == 3)
4253 1.1 christos {
4254 1.1 christos if (strncmp (str, "PIC", 3) == 0)
4255 1.1 christos flag = EGPS__V_PIC;
4256 1.1 christos else if (strncmp (str, "LIB", 3) == 0)
4257 1.1 christos flag = EGPS__V_LIB;
4258 1.1 christos else if (strncmp (str, "OVR", 3) == 0)
4259 1.1 christos flag = EGPS__V_OVR;
4260 1.1 christos else if (strncmp (str, "REL", 3) == 0)
4261 1.1 christos flag = EGPS__V_REL;
4262 1.1 christos else if (strncmp (str, "GBL", 3) == 0)
4263 1.1 christos flag = EGPS__V_GBL;
4264 1.1 christos else if (strncmp (str, "SHR", 3) == 0)
4265 1.1 christos flag = EGPS__V_SHR;
4266 1.1 christos else if (strncmp (str, "EXE", 3) == 0)
4267 1.1 christos flag = EGPS__V_EXE;
4268 1.1 christos else if (strncmp (str, "WRT", 3) == 0)
4269 1.1 christos flag = EGPS__V_WRT;
4270 1.1 christos else if (strncmp (str, "VEC", 3) == 0)
4271 1.1 christos flag = EGPS__V_VEC;
4272 1.1 christos else if (strncmp (str, "MOD", 3) == 0)
4273 1.1 christos {
4274 1.1 christos flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT;
4275 1.1 christos no = 0;
4276 1.1 christos }
4277 1.1 christos else if (strncmp (str, "COM", 3) == 0)
4278 1.1 christos flag = EGPS__V_COM;
4279 1.1 christos }
4280 1.1 christos
4281 1.1 christos if (flag == 0)
4282 1.1 christos {
4283 1.1 christos char c = str[len];
4284 1.1 christos str[len] = 0;
4285 1.1 christos as_warn (_("unknown section attribute %s"), str);
4286 1.1 christos str[len] = c;
4287 1.1 christos return 0;
4288 1.1 christos }
4289 1.1 christos
4290 1.1 christos if (no)
4291 1.1 christos return flag << EGPS__V_NO_SHIFT;
4292 1.1 christos else
4293 1.1 christos return flag;
4294 1.1 christos }
4295 1.1 christos
4296 1.1 christos /* Handle the section specific pseudo-op. */
4297 1.1 christos
4298 1.1 christos #define EVAX_SECTION_COUNT 5
4299 1.1 christos
4300 1.1 christos static char *section_name[EVAX_SECTION_COUNT + 1] =
4301 1.1 christos { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4302 1.1 christos
4303 1.1 christos static void
4304 1.1 christos s_alpha_section (int secid)
4305 1.1 christos {
4306 1.1 christos char *name, *beg;
4307 1.1 christos segT sec;
4308 1.1 christos flagword vms_flags = 0;
4309 1.1 christos symbolS *symbol;
4310 1.1 christos
4311 1.1 christos if (secid == 0)
4312 1.1 christos {
4313 1.1 christos name = s_alpha_section_name ();
4314 1.1 christos if (name == NULL)
4315 1.1 christos return;
4316 1.1 christos sec = subseg_new (name, 0);
4317 1.1 christos if (*input_line_pointer == ',')
4318 1.1 christos {
4319 1.1 christos /* Skip the comma. */
4320 1.1 christos ++input_line_pointer;
4321 1.1 christos SKIP_WHITESPACE ();
4322 1.1 christos
4323 1.1 christos do
4324 1.1 christos {
4325 1.1 christos char c;
4326 1.1 christos
4327 1.1 christos SKIP_WHITESPACE ();
4328 1.1 christos beg = input_line_pointer;
4329 1.1 christos c = get_symbol_end ();
4330 1.1 christos *input_line_pointer = c;
4331 1.1 christos
4332 1.1 christos vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg);
4333 1.1 christos
4334 1.1 christos SKIP_WHITESPACE ();
4335 1.1 christos }
4336 1.1 christos while (*input_line_pointer++ == ',');
4337 1.1 christos --input_line_pointer;
4338 1.1 christos }
4339 1.1 christos
4340 1.1 christos symbol = symbol_find_or_make (name);
4341 1.1 christos S_SET_SEGMENT (symbol, sec);
4342 1.1 christos symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM;
4343 1.1 christos bfd_vms_set_section_flags
4344 1.1 christos (stdoutput, sec,
4345 1.1 christos (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK,
4346 1.1 christos vms_flags & EGPS__V_MASK);
4347 1.1 christos }
4348 1.1 christos else
4349 1.1 christos {
4350 1.1 christos get_absolute_expression ();
4351 1.1 christos subseg_new (section_name[secid], 0);
4352 1.1 christos }
4353 1.1 christos
4354 1.1 christos demand_empty_rest_of_line ();
4355 1.1 christos alpha_insn_label = NULL;
4356 1.1 christos alpha_auto_align_on = 1;
4357 1.1 christos alpha_current_align = 0;
4358 1.1 christos }
4359 1.1 christos
4360 1.1 christos static void
4361 1.1 christos s_alpha_literals (int ignore ATTRIBUTE_UNUSED)
4362 1.1 christos {
4363 1.1 christos subseg_new (".literals", 0);
4364 1.1 christos demand_empty_rest_of_line ();
4365 1.1 christos alpha_insn_label = NULL;
4366 1.1 christos alpha_auto_align_on = 1;
4367 1.1 christos alpha_current_align = 0;
4368 1.1 christos }
4369 1.1 christos
4370 1.1 christos /* Parse .ent directives. */
4371 1.1 christos
4372 1.1 christos static void
4373 1.1 christos s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
4374 1.1 christos {
4375 1.1 christos symbolS *symbol;
4376 1.1 christos expressionS symexpr;
4377 1.1 christos
4378 1.1 christos if (alpha_evax_proc != NULL)
4379 1.1 christos as_bad (_("previous .ent not closed by a .end"));
4380 1.1 christos
4381 1.1 christos alpha_evax_proc = &alpha_evax_proc_data;
4382 1.1 christos
4383 1.1 christos alpha_evax_proc->pdsckind = 0;
4384 1.1 christos alpha_evax_proc->framereg = -1;
4385 1.1 christos alpha_evax_proc->framesize = 0;
4386 1.1 christos alpha_evax_proc->rsa_offset = 0;
4387 1.1 christos alpha_evax_proc->ra_save = AXP_REG_RA;
4388 1.1 christos alpha_evax_proc->fp_save = -1;
4389 1.1 christos alpha_evax_proc->imask = 0;
4390 1.1 christos alpha_evax_proc->fmask = 0;
4391 1.1 christos alpha_evax_proc->prologue = 0;
4392 1.1 christos alpha_evax_proc->type = 0;
4393 1.1 christos alpha_evax_proc->handler = 0;
4394 1.1 christos alpha_evax_proc->handler_data = 0;
4395 1.1 christos
4396 1.1 christos expression (&symexpr);
4397 1.1 christos
4398 1.1 christos if (symexpr.X_op != O_symbol)
4399 1.1 christos {
4400 1.1 christos as_fatal (_(".ent directive has no symbol"));
4401 1.1 christos demand_empty_rest_of_line ();
4402 1.1 christos return;
4403 1.1 christos }
4404 1.1 christos
4405 1.1 christos symbol = make_expr_symbol (&symexpr);
4406 1.1 christos symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4407 1.1 christos alpha_evax_proc->symbol = symbol;
4408 1.1 christos
4409 1.1 christos demand_empty_rest_of_line ();
4410 1.1 christos }
4411 1.1 christos
4412 1.1 christos static void
4413 1.1 christos s_alpha_handler (int is_data)
4414 1.1 christos {
4415 1.1 christos if (is_data)
4416 1.1 christos alpha_evax_proc->handler_data = get_absolute_expression ();
4417 1.1 christos else
4418 1.1 christos {
4419 1.1 christos char *name, name_end;
4420 1.1 christos name = input_line_pointer;
4421 1.1 christos name_end = get_symbol_end ();
4422 1.1 christos
4423 1.1 christos if (! is_name_beginner (*name))
4424 1.1 christos {
4425 1.1 christos as_warn (_(".handler directive has no name"));
4426 1.1 christos *input_line_pointer = name_end;
4427 1.1 christos }
4428 1.1 christos else
4429 1.1 christos {
4430 1.1 christos symbolS *sym;
4431 1.1 christos
4432 1.1 christos sym = symbol_find_or_make (name);
4433 1.1 christos symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4434 1.1 christos alpha_evax_proc->handler = sym;
4435 1.1 christos *input_line_pointer = name_end;
4436 1.1 christos }
4437 1.1 christos }
4438 1.1 christos demand_empty_rest_of_line ();
4439 1.1 christos }
4440 1.1 christos
4441 1.1 christos /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4442 1.1 christos
4443 1.1 christos static void
4444 1.1 christos s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
4445 1.1 christos {
4446 1.1 christos long val;
4447 1.1 christos int ra;
4448 1.1 christos
4449 1.1 christos alpha_evax_proc->framereg = tc_get_register (1);
4450 1.1 christos
4451 1.1 christos SKIP_WHITESPACE ();
4452 1.1 christos if (*input_line_pointer++ != ','
4453 1.1 christos || get_absolute_expression_and_terminator (&val) != ',')
4454 1.1 christos {
4455 1.1 christos as_warn (_("Bad .frame directive 1./2. param"));
4456 1.1 christos --input_line_pointer;
4457 1.1 christos demand_empty_rest_of_line ();
4458 1.1 christos return;
4459 1.1 christos }
4460 1.1 christos
4461 1.1 christos alpha_evax_proc->framesize = val;
4462 1.1 christos
4463 1.1 christos ra = tc_get_register (1);
4464 1.1 christos if (ra != AXP_REG_RA)
4465 1.1 christos as_warn (_("Bad RA (%d) register for .frame"), ra);
4466 1.1 christos
4467 1.1 christos SKIP_WHITESPACE ();
4468 1.1 christos if (*input_line_pointer++ != ',')
4469 1.1 christos {
4470 1.1 christos as_warn (_("Bad .frame directive 3./4. param"));
4471 1.1 christos --input_line_pointer;
4472 1.1 christos demand_empty_rest_of_line ();
4473 1.1 christos return;
4474 1.1 christos }
4475 1.1 christos alpha_evax_proc->rsa_offset = get_absolute_expression ();
4476 1.1 christos }
4477 1.1 christos
4478 1.1 christos /* Parse .prologue. */
4479 1.1 christos
4480 1.1 christos static void
4481 1.1 christos s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
4482 1.1 christos {
4483 1.1 christos demand_empty_rest_of_line ();
4484 1.1 christos alpha_prologue_label = symbol_new
4485 1.1 christos (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4486 1.1 christos }
4487 1.1 christos
4488 1.1 christos /* Parse .pdesc <entry_name>,{null|stack|reg}
4489 1.1 christos Insert a procedure descriptor. */
4490 1.1 christos
4491 1.1 christos static void
4492 1.1 christos s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
4493 1.1 christos {
4494 1.1 christos char *name;
4495 1.1 christos char name_end;
4496 1.1 christos register char *p;
4497 1.1 christos expressionS exp;
4498 1.1 christos symbolS *entry_sym;
4499 1.1 christos const char *entry_sym_name;
4500 1.1 christos const char *pdesc_sym_name;
4501 1.1 christos fixS *fixp;
4502 1.1 christos size_t len;
4503 1.1 christos
4504 1.1 christos if (now_seg != alpha_link_section)
4505 1.1 christos {
4506 1.1 christos as_bad (_(".pdesc directive not in link (.link) section"));
4507 1.1 christos return;
4508 1.1 christos }
4509 1.1 christos
4510 1.1 christos expression (&exp);
4511 1.1 christos if (exp.X_op != O_symbol)
4512 1.1 christos {
4513 1.1 christos as_bad (_(".pdesc directive has no entry symbol"));
4514 1.1 christos return;
4515 1.1 christos }
4516 1.1 christos
4517 1.1 christos entry_sym = make_expr_symbol (&exp);
4518 1.1 christos entry_sym_name = S_GET_NAME (entry_sym);
4519 1.1 christos
4520 1.1 christos /* Strip "..en". */
4521 1.1 christos len = strlen (entry_sym_name);
4522 1.1 christos if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0)
4523 1.1 christos {
4524 1.1 christos as_bad (_(".pdesc has a bad entry symbol"));
4525 1.1 christos return;
4526 1.1 christos }
4527 1.1 christos len -= 4;
4528 1.1 christos pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol);
4529 1.1 christos
4530 1.1 christos if (!alpha_evax_proc
4531 1.1 christos || !S_IS_DEFINED (alpha_evax_proc->symbol)
4532 1.1 christos || strlen (pdesc_sym_name) != len
4533 1.1 christos || memcmp (entry_sym_name, pdesc_sym_name, len) != 0)
4534 1.1 christos {
4535 1.1 christos as_fatal (_(".pdesc doesn't match with last .ent"));
4536 1.1 christos return;
4537 1.1 christos }
4538 1.1 christos
4539 1.1 christos /* Define pdesc symbol. */
4540 1.1 christos symbol_set_value_now (alpha_evax_proc->symbol);
4541 1.1 christos
4542 1.1 christos /* Save bfd symbol of proc entry in function symbol. */
4543 1.1 christos ((struct evax_private_udata_struct *)
4544 1.1 christos symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym
4545 1.1 christos = symbol_get_bfdsym (entry_sym);
4546 1.1 christos
4547 1.1 christos SKIP_WHITESPACE ();
4548 1.1 christos if (*input_line_pointer++ != ',')
4549 1.1 christos {
4550 1.1 christos as_warn (_("No comma after .pdesc <entryname>"));
4551 1.1 christos demand_empty_rest_of_line ();
4552 1.1 christos return;
4553 1.1 christos }
4554 1.1 christos
4555 1.1 christos SKIP_WHITESPACE ();
4556 1.1 christos name = input_line_pointer;
4557 1.1 christos name_end = get_symbol_end ();
4558 1.1 christos
4559 1.1 christos if (strncmp (name, "stack", 5) == 0)
4560 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_STACK;
4561 1.1 christos
4562 1.1 christos else if (strncmp (name, "reg", 3) == 0)
4563 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4564 1.1 christos
4565 1.1 christos else if (strncmp (name, "null", 4) == 0)
4566 1.1 christos alpha_evax_proc->pdsckind = PDSC_S_K_KIND_NULL;
4567 1.1 christos
4568 1.1 christos else
4569 1.1 christos {
4570 1.1 christos as_fatal (_("unknown procedure kind"));
4571 1.1 christos demand_empty_rest_of_line ();
4572 1.1 christos return;
4573 1.1 christos }
4574 1.1 christos
4575 1.1 christos *input_line_pointer = name_end;
4576 1.1 christos demand_empty_rest_of_line ();
4577 1.1 christos
4578 1.1 christos #ifdef md_flush_pending_output
4579 1.1 christos md_flush_pending_output ();
4580 1.1 christos #endif
4581 1.1 christos
4582 1.1 christos frag_align (3, 0, 0);
4583 1.1 christos p = frag_more (16);
4584 1.1 christos fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4585 1.1 christos fixp->fx_done = 1;
4586 1.1 christos
4587 1.1 christos *p = alpha_evax_proc->pdsckind
4588 1.1 christos | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
4589 1.1 christos | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0)
4590 1.1 christos | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0);
4591 1.1 christos *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4592 1.1 christos
4593 1.1 christos switch (alpha_evax_proc->pdsckind)
4594 1.1 christos {
4595 1.1 christos case PDSC_S_K_KIND_NULL:
4596 1.1 christos *(p + 2) = 0;
4597 1.1 christos *(p + 3) = 0;
4598 1.1 christos break;
4599 1.1 christos case PDSC_S_K_KIND_FP_REGISTER:
4600 1.1 christos *(p + 2) = alpha_evax_proc->fp_save;
4601 1.1 christos *(p + 3) = alpha_evax_proc->ra_save;
4602 1.1 christos break;
4603 1.1 christos case PDSC_S_K_KIND_FP_STACK:
4604 1.1 christos md_number_to_chars (p + 2, (valueT) alpha_evax_proc->rsa_offset, 2);
4605 1.1 christos break;
4606 1.1 christos default: /* impossible */
4607 1.1 christos break;
4608 1.1 christos }
4609 1.1 christos
4610 1.1 christos *(p + 4) = 0;
4611 1.1 christos *(p + 5) = alpha_evax_proc->type & 0x0f;
4612 1.1 christos
4613 1.1 christos /* Signature offset. */
4614 1.1 christos md_number_to_chars (p + 6, (valueT) 0, 2);
4615 1.1 christos
4616 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal + 8,
4617 1.1 christos 8, &exp, 0, BFD_RELOC_64);
4618 1.1 christos
4619 1.1 christos if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
4620 1.1 christos return;
4621 1.1 christos
4622 1.1 christos /* pdesc+16: Size. */
4623 1.1 christos p = frag_more (6);
4624 1.1 christos md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
4625 1.1 christos md_number_to_chars (p + 4, (valueT) 0, 2);
4626 1.1 christos
4627 1.1 christos /* Entry length. */
4628 1.1 christos exp.X_op = O_subtract;
4629 1.1 christos exp.X_add_symbol = alpha_prologue_label;
4630 1.1 christos exp.X_op_symbol = entry_sym;
4631 1.1 christos emit_expr (&exp, 2);
4632 1.1 christos
4633 1.1 christos if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4634 1.1 christos return;
4635 1.1 christos
4636 1.1 christos /* pdesc+24: register masks. */
4637 1.1 christos p = frag_more (8);
4638 1.1 christos md_number_to_chars (p, alpha_evax_proc->imask, 4);
4639 1.1 christos md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
4640 1.1 christos
4641 1.1 christos if (alpha_evax_proc->handler)
4642 1.1 christos {
4643 1.1 christos p = frag_more (8);
4644 1.1 christos fixp = fix_new (frag_now, p - frag_now->fr_literal, 8,
4645 1.1 christos alpha_evax_proc->handler, 0, 0, BFD_RELOC_64);
4646 1.1 christos }
4647 1.1 christos
4648 1.1 christos if (alpha_evax_proc->handler_data)
4649 1.1 christos {
4650 1.1 christos p = frag_more (8);
4651 1.1 christos md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
4652 1.1 christos }
4653 1.1 christos }
4654 1.1 christos
4655 1.1 christos /* Support for crash debug on vms. */
4656 1.1 christos
4657 1.1 christos static void
4658 1.1 christos s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4659 1.1 christos {
4660 1.1 christos char *p;
4661 1.1 christos expressionS exp;
4662 1.1 christos
4663 1.1 christos if (now_seg != alpha_link_section)
4664 1.1 christos {
4665 1.1 christos as_bad (_(".name directive not in link (.link) section"));
4666 1.1 christos demand_empty_rest_of_line ();
4667 1.1 christos return;
4668 1.1 christos }
4669 1.1 christos
4670 1.1 christos expression (&exp);
4671 1.1 christos if (exp.X_op != O_symbol)
4672 1.1 christos {
4673 1.1 christos as_warn (_(".name directive has no symbol"));
4674 1.1 christos demand_empty_rest_of_line ();
4675 1.1 christos return;
4676 1.1 christos }
4677 1.1 christos
4678 1.1 christos demand_empty_rest_of_line ();
4679 1.1 christos
4680 1.1 christos #ifdef md_flush_pending_output
4681 1.1 christos md_flush_pending_output ();
4682 1.1 christos #endif
4683 1.1 christos
4684 1.1 christos frag_align (3, 0, 0);
4685 1.1 christos p = frag_more (8);
4686 1.1 christos
4687 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4688 1.1 christos }
4689 1.1 christos
4690 1.1 christos /* Parse .linkage <symbol>.
4691 1.1 christos Create a linkage pair relocation. */
4692 1.1 christos
4693 1.1 christos static void
4694 1.1 christos s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4695 1.1 christos {
4696 1.1 christos expressionS exp;
4697 1.1 christos char *p;
4698 1.1 christos fixS *fixp;
4699 1.1 christos
4700 1.1 christos #ifdef md_flush_pending_output
4701 1.1 christos md_flush_pending_output ();
4702 1.1 christos #endif
4703 1.1 christos
4704 1.1 christos expression (&exp);
4705 1.1 christos if (exp.X_op != O_symbol)
4706 1.1 christos {
4707 1.1 christos as_fatal (_("No symbol after .linkage"));
4708 1.1 christos }
4709 1.1 christos else
4710 1.1 christos {
4711 1.1 christos struct alpha_linkage_fixups *linkage_fixup;
4712 1.1 christos
4713 1.1 christos p = frag_more (LKP_S_K_SIZE);
4714 1.1 christos memset (p, 0, LKP_S_K_SIZE);
4715 1.1 christos fixp = fix_new_exp
4716 1.1 christos (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,
4717 1.1 christos BFD_RELOC_ALPHA_LINKAGE);
4718 1.1 christos
4719 1.1 christos if (alpha_insn_label == NULL)
4720 1.1 christos alpha_insn_label = symbol_new
4721 1.1 christos (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4722 1.1 christos
4723 1.1 christos /* Create a linkage element. */
4724 1.1 christos linkage_fixup = (struct alpha_linkage_fixups *)
4725 1.1 christos xmalloc (sizeof (struct alpha_linkage_fixups));
4726 1.1 christos linkage_fixup->fixp = fixp;
4727 1.1 christos linkage_fixup->next = NULL;
4728 1.1 christos linkage_fixup->label = alpha_insn_label;
4729 1.1 christos
4730 1.1 christos /* Append it to the list. */
4731 1.1 christos if (alpha_linkage_fixup_root == NULL)
4732 1.1 christos alpha_linkage_fixup_root = linkage_fixup;
4733 1.1 christos else
4734 1.1 christos alpha_linkage_fixup_tail->next = linkage_fixup;
4735 1.1 christos alpha_linkage_fixup_tail = linkage_fixup;
4736 1.1 christos }
4737 1.1 christos demand_empty_rest_of_line ();
4738 1.1 christos }
4739 1.1 christos
4740 1.1 christos /* Parse .code_address <symbol>.
4741 1.1 christos Create a code address relocation. */
4742 1.1 christos
4743 1.1 christos static void
4744 1.1 christos s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4745 1.1 christos {
4746 1.1 christos expressionS exp;
4747 1.1 christos char *p;
4748 1.1 christos
4749 1.1 christos #ifdef md_flush_pending_output
4750 1.1 christos md_flush_pending_output ();
4751 1.1 christos #endif
4752 1.1 christos
4753 1.1 christos expression (&exp);
4754 1.1 christos if (exp.X_op != O_symbol)
4755 1.1 christos as_fatal (_("No symbol after .code_address"));
4756 1.1 christos else
4757 1.1 christos {
4758 1.1 christos p = frag_more (8);
4759 1.1 christos memset (p, 0, 8);
4760 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4761 1.1 christos BFD_RELOC_ALPHA_CODEADDR);
4762 1.1 christos }
4763 1.1 christos demand_empty_rest_of_line ();
4764 1.1 christos }
4765 1.1 christos
4766 1.1 christos static void
4767 1.1 christos s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4768 1.1 christos {
4769 1.1 christos alpha_evax_proc->fp_save = tc_get_register (1);
4770 1.1 christos
4771 1.1 christos demand_empty_rest_of_line ();
4772 1.1 christos }
4773 1.1 christos
4774 1.1 christos static void
4775 1.1 christos s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4776 1.1 christos {
4777 1.1 christos long val;
4778 1.1 christos
4779 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',')
4780 1.1 christos {
4781 1.1 christos as_warn (_("Bad .mask directive"));
4782 1.1 christos --input_line_pointer;
4783 1.1 christos }
4784 1.1 christos else
4785 1.1 christos {
4786 1.1 christos alpha_evax_proc->imask = val;
4787 1.1 christos (void) get_absolute_expression ();
4788 1.1 christos }
4789 1.1 christos demand_empty_rest_of_line ();
4790 1.1 christos }
4791 1.1 christos
4792 1.1 christos static void
4793 1.1 christos s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4794 1.1 christos {
4795 1.1 christos long val;
4796 1.1 christos
4797 1.1 christos if (get_absolute_expression_and_terminator (&val) != ',')
4798 1.1 christos {
4799 1.1 christos as_warn (_("Bad .fmask directive"));
4800 1.1 christos --input_line_pointer;
4801 1.1 christos }
4802 1.1 christos else
4803 1.1 christos {
4804 1.1 christos alpha_evax_proc->fmask = val;
4805 1.1 christos (void) get_absolute_expression ();
4806 1.1 christos }
4807 1.1 christos demand_empty_rest_of_line ();
4808 1.1 christos }
4809 1.1 christos
4810 1.1 christos static void
4811 1.1 christos s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4812 1.1 christos {
4813 1.1 christos char c;
4814 1.1 christos
4815 1.1 christos c = get_symbol_end ();
4816 1.1 christos *input_line_pointer = c;
4817 1.1 christos demand_empty_rest_of_line ();
4818 1.1 christos alpha_evax_proc = NULL;
4819 1.1 christos }
4820 1.1 christos
4821 1.1 christos static void
4822 1.1 christos s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4823 1.1 christos {
4824 1.1 christos symbolS *s;
4825 1.1 christos int length;
4826 1.1 christos static char case_hack[32];
4827 1.1 christos
4828 1.1 christos sprintf (case_hack, "<CASE:%01d%01d>",
4829 1.1 christos alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4830 1.1 christos
4831 1.1 christos s = symbol_find_or_make (case_hack);
4832 1.1 christos symbol_get_bfdsym (s)->flags |= BSF_FILE;
4833 1.1 christos
4834 1.1 christos get_absolute_expression ();
4835 1.1 christos s = symbol_find_or_make (demand_copy_string (&length));
4836 1.1 christos symbol_get_bfdsym (s)->flags |= BSF_FILE;
4837 1.1 christos demand_empty_rest_of_line ();
4838 1.1 christos }
4839 1.1 christos #endif /* OBJ_EVAX */
4840 1.1 christos
4841 1.1 christos /* Handle the .gprel32 pseudo op. */
4842 1.1 christos
4843 1.1 christos static void
4844 1.1 christos s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4845 1.1 christos {
4846 1.1 christos expressionS e;
4847 1.1 christos char *p;
4848 1.1 christos
4849 1.1 christos SKIP_WHITESPACE ();
4850 1.1 christos expression (&e);
4851 1.1 christos
4852 1.1 christos #ifdef OBJ_ELF
4853 1.1 christos switch (e.X_op)
4854 1.1 christos {
4855 1.1 christos case O_constant:
4856 1.1 christos e.X_add_symbol = section_symbol (absolute_section);
4857 1.1 christos e.X_op = O_symbol;
4858 1.1 christos /* FALLTHRU */
4859 1.1 christos case O_symbol:
4860 1.1 christos break;
4861 1.1 christos default:
4862 1.1 christos abort ();
4863 1.1 christos }
4864 1.1 christos #else
4865 1.1 christos #ifdef OBJ_ECOFF
4866 1.1 christos switch (e.X_op)
4867 1.1 christos {
4868 1.1 christos case O_constant:
4869 1.1 christos e.X_add_symbol = section_symbol (absolute_section);
4870 1.1 christos /* fall through */
4871 1.1 christos case O_symbol:
4872 1.1 christos e.X_op = O_subtract;
4873 1.1 christos e.X_op_symbol = alpha_gp_symbol;
4874 1.1 christos break;
4875 1.1 christos default:
4876 1.1 christos abort ();
4877 1.1 christos }
4878 1.1 christos #endif
4879 1.1 christos #endif
4880 1.1 christos
4881 1.1 christos if (alpha_auto_align_on && alpha_current_align < 2)
4882 1.1 christos alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4883 1.1 christos if (alpha_current_align > 2)
4884 1.1 christos alpha_current_align = 2;
4885 1.1 christos alpha_insn_label = NULL;
4886 1.1 christos
4887 1.1 christos p = frag_more (4);
4888 1.1 christos memset (p, 0, 4);
4889 1.1 christos fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4890 1.1 christos &e, 0, BFD_RELOC_GPREL32);
4891 1.1 christos }
4892 1.1 christos
4893 1.1 christos /* Handle floating point allocation pseudo-ops. This is like the
4894 1.1 christos generic vresion, but it makes sure the current label, if any, is
4895 1.1 christos correctly aligned. */
4896 1.1 christos
4897 1.1 christos static void
4898 1.1 christos s_alpha_float_cons (int type)
4899 1.1 christos {
4900 1.1 christos int log_size;
4901 1.1 christos
4902 1.1 christos switch (type)
4903 1.1 christos {
4904 1.1 christos default:
4905 1.1 christos case 'f':
4906 1.1 christos case 'F':
4907 1.1 christos log_size = 2;
4908 1.1 christos break;
4909 1.1 christos
4910 1.1 christos case 'd':
4911 1.1 christos case 'D':
4912 1.1 christos case 'G':
4913 1.1 christos log_size = 3;
4914 1.1 christos break;
4915 1.1 christos
4916 1.1 christos case 'x':
4917 1.1 christos case 'X':
4918 1.1 christos case 'p':
4919 1.1 christos case 'P':
4920 1.1 christos log_size = 4;
4921 1.1 christos break;
4922 1.1 christos }
4923 1.1 christos
4924 1.1 christos if (alpha_auto_align_on && alpha_current_align < log_size)
4925 1.1 christos alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4926 1.1 christos if (alpha_current_align > log_size)
4927 1.1 christos alpha_current_align = log_size;
4928 1.1 christos alpha_insn_label = NULL;
4929 1.1 christos
4930 1.1 christos float_cons (type);
4931 1.1 christos }
4932 1.1 christos
4933 1.1 christos /* Handle the .proc pseudo op. We don't really do much with it except
4934 1.1 christos parse it. */
4935 1.1 christos
4936 1.1 christos static void
4937 1.1 christos s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4938 1.1 christos {
4939 1.1 christos char *name;
4940 1.1 christos char c;
4941 1.1 christos char *p;
4942 1.1 christos symbolS *symbolP;
4943 1.1 christos int temp;
4944 1.1 christos
4945 1.1 christos /* Takes ".proc name,nargs". */
4946 1.1 christos SKIP_WHITESPACE ();
4947 1.1 christos name = input_line_pointer;
4948 1.1 christos c = get_symbol_end ();
4949 1.1 christos p = input_line_pointer;
4950 1.1 christos symbolP = symbol_find_or_make (name);
4951 1.1 christos *p = c;
4952 1.1 christos SKIP_WHITESPACE ();
4953 1.1 christos if (*input_line_pointer != ',')
4954 1.1 christos {
4955 1.1 christos *p = 0;
4956 1.1 christos as_warn (_("Expected comma after name \"%s\""), name);
4957 1.1 christos *p = c;
4958 1.1 christos temp = 0;
4959 1.1 christos ignore_rest_of_line ();
4960 1.1 christos }
4961 1.1 christos else
4962 1.1 christos {
4963 1.1 christos input_line_pointer++;
4964 1.1 christos temp = get_absolute_expression ();
4965 1.1 christos }
4966 1.1 christos /* *symbol_get_obj (symbolP) = (signed char) temp; */
4967 1.1 christos (void) symbolP;
4968 1.1 christos as_warn (_("unhandled: .proc %s,%d"), name, temp);
4969 1.1 christos demand_empty_rest_of_line ();
4970 1.1 christos }
4971 1.1 christos
4972 1.1 christos /* Handle the .set pseudo op. This is used to turn on and off most of
4973 1.1 christos the assembler features. */
4974 1.1 christos
4975 1.1 christos static void
4976 1.1 christos s_alpha_set (int x ATTRIBUTE_UNUSED)
4977 1.1 christos {
4978 1.1 christos char *name, ch, *s;
4979 1.1 christos int yesno = 1;
4980 1.1 christos
4981 1.1 christos SKIP_WHITESPACE ();
4982 1.1 christos name = input_line_pointer;
4983 1.1 christos ch = get_symbol_end ();
4984 1.1 christos
4985 1.1 christos s = name;
4986 1.1 christos if (s[0] == 'n' && s[1] == 'o')
4987 1.1 christos {
4988 1.1 christos yesno = 0;
4989 1.1 christos s += 2;
4990 1.1 christos }
4991 1.1 christos if (!strcmp ("reorder", s))
4992 1.1 christos /* ignore */ ;
4993 1.1 christos else if (!strcmp ("at", s))
4994 1.1 christos alpha_noat_on = !yesno;
4995 1.1 christos else if (!strcmp ("macro", s))
4996 1.1 christos alpha_macros_on = yesno;
4997 1.1 christos else if (!strcmp ("move", s))
4998 1.1 christos /* ignore */ ;
4999 1.1 christos else if (!strcmp ("volatile", s))
5000 1.1 christos /* ignore */ ;
5001 1.1 christos else
5002 1.1 christos as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5003 1.1 christos
5004 1.1 christos *input_line_pointer = ch;
5005 1.1 christos demand_empty_rest_of_line ();
5006 1.1 christos }
5007 1.1 christos
5008 1.1 christos /* Handle the .base pseudo op. This changes the assembler's notion of
5009 1.1 christos the $gp register. */
5010 1.1 christos
5011 1.1 christos static void
5012 1.1 christos s_alpha_base (int ignore ATTRIBUTE_UNUSED)
5013 1.1 christos {
5014 1.1 christos SKIP_WHITESPACE ();
5015 1.1 christos
5016 1.1 christos if (*input_line_pointer == '$')
5017 1.1 christos {
5018 1.1 christos /* $rNN form. */
5019 1.1 christos input_line_pointer++;
5020 1.1 christos if (*input_line_pointer == 'r')
5021 1.1 christos input_line_pointer++;
5022 1.1 christos }
5023 1.1 christos
5024 1.1 christos alpha_gp_register = get_absolute_expression ();
5025 1.1 christos if (alpha_gp_register < 0 || alpha_gp_register > 31)
5026 1.1 christos {
5027 1.1 christos alpha_gp_register = AXP_REG_GP;
5028 1.1 christos as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5029 1.1 christos }
5030 1.1 christos
5031 1.1 christos demand_empty_rest_of_line ();
5032 1.1 christos }
5033 1.1 christos
5034 1.1 christos /* Handle the .align pseudo-op. This aligns to a power of two. It
5035 1.1 christos also adjusts any current instruction label. We treat this the same
5036 1.1 christos way the MIPS port does: .align 0 turns off auto alignment. */
5037 1.1 christos
5038 1.1 christos static void
5039 1.1 christos s_alpha_align (int ignore ATTRIBUTE_UNUSED)
5040 1.1 christos {
5041 1.1 christos int align;
5042 1.1 christos char fill, *pfill;
5043 1.1 christos long max_alignment = 16;
5044 1.1 christos
5045 1.1 christos align = get_absolute_expression ();
5046 1.1 christos if (align > max_alignment)
5047 1.1 christos {
5048 1.1 christos align = max_alignment;
5049 1.1 christos as_bad (_("Alignment too large: %d. assumed"), align);
5050 1.1 christos }
5051 1.1 christos else if (align < 0)
5052 1.1 christos {
5053 1.1 christos as_warn (_("Alignment negative: 0 assumed"));
5054 1.1 christos align = 0;
5055 1.1 christos }
5056 1.1 christos
5057 1.1 christos if (*input_line_pointer == ',')
5058 1.1 christos {
5059 1.1 christos input_line_pointer++;
5060 1.1 christos fill = get_absolute_expression ();
5061 1.1 christos pfill = &fill;
5062 1.1 christos }
5063 1.1 christos else
5064 1.1 christos pfill = NULL;
5065 1.1 christos
5066 1.1 christos if (align != 0)
5067 1.1 christos {
5068 1.1 christos alpha_auto_align_on = 1;
5069 1.1 christos alpha_align (align, pfill, NULL, 1);
5070 1.1 christos }
5071 1.1 christos else
5072 1.1 christos {
5073 1.1 christos alpha_auto_align_on = 0;
5074 1.1 christos }
5075 1.1 christos alpha_insn_label = NULL;
5076 1.1 christos
5077 1.1 christos demand_empty_rest_of_line ();
5078 1.1 christos }
5079 1.1 christos
5080 1.1 christos /* Hook the normal string processor to reset known alignment. */
5081 1.1 christos
5082 1.1 christos static void
5083 1.1 christos s_alpha_stringer (int terminate)
5084 1.1 christos {
5085 1.1 christos alpha_current_align = 0;
5086 1.1 christos alpha_insn_label = NULL;
5087 1.1 christos stringer (8 + terminate);
5088 1.1 christos }
5089 1.1 christos
5090 1.1 christos /* Hook the normal space processing to reset known alignment. */
5091 1.1 christos
5092 1.1 christos static void
5093 1.1 christos s_alpha_space (int ignore)
5094 1.1 christos {
5095 1.1 christos alpha_current_align = 0;
5096 1.1 christos alpha_insn_label = NULL;
5097 1.1 christos s_space (ignore);
5098 1.1 christos }
5099 1.1 christos
5100 1.1 christos /* Hook into cons for auto-alignment. */
5101 1.1 christos
5102 1.1 christos void
5103 1.1 christos alpha_cons_align (int size)
5104 1.1 christos {
5105 1.1 christos int log_size;
5106 1.1 christos
5107 1.1 christos log_size = 0;
5108 1.1 christos while ((size >>= 1) != 0)
5109 1.1 christos ++log_size;
5110 1.1 christos
5111 1.1 christos if (alpha_auto_align_on && alpha_current_align < log_size)
5112 1.1 christos alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5113 1.1 christos if (alpha_current_align > log_size)
5114 1.1 christos alpha_current_align = log_size;
5115 1.1 christos alpha_insn_label = NULL;
5116 1.1 christos }
5117 1.1 christos
5118 1.1 christos /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5119 1.1 christos pseudos. We just turn off auto-alignment and call down to cons. */
5120 1.1 christos
5121 1.1 christos static void
5122 1.1 christos s_alpha_ucons (int bytes)
5123 1.1 christos {
5124 1.1 christos int hold = alpha_auto_align_on;
5125 1.1 christos alpha_auto_align_on = 0;
5126 1.1 christos cons (bytes);
5127 1.1 christos alpha_auto_align_on = hold;
5128 1.1 christos }
5129 1.1 christos
5130 1.1 christos /* Switch the working cpu type. */
5131 1.1 christos
5132 1.1 christos static void
5133 1.1 christos s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
5134 1.1 christos {
5135 1.1 christos char *name, ch;
5136 1.1 christos const struct cpu_type *p;
5137 1.1 christos
5138 1.1 christos SKIP_WHITESPACE ();
5139 1.1 christos name = input_line_pointer;
5140 1.1 christos ch = get_symbol_end ();
5141 1.1 christos
5142 1.1 christos for (p = cpu_types; p->name; ++p)
5143 1.1 christos if (strcmp (name, p->name) == 0)
5144 1.1 christos {
5145 1.1 christos alpha_target_name = p->name, alpha_target = p->flags;
5146 1.1 christos goto found;
5147 1.1 christos }
5148 1.1 christos as_warn (_("Unknown CPU identifier `%s'"), name);
5149 1.1 christos
5150 1.1 christos found:
5151 1.1 christos *input_line_pointer = ch;
5152 1.1 christos demand_empty_rest_of_line ();
5153 1.1 christos }
5154 1.1 christos
5155 1.1 christos #ifdef DEBUG1
5157 1.1 christos /* print token expression with alpha specific extension. */
5158 1.1 christos
5159 1.1 christos static void
5160 1.1 christos alpha_print_token (FILE *f, const expressionS *exp)
5161 1.1 christos {
5162 1.1 christos switch (exp->X_op)
5163 1.1 christos {
5164 1.1 christos case O_cpregister:
5165 1.1 christos putc (',', f);
5166 1.1 christos /* FALLTHRU */
5167 1.1 christos case O_pregister:
5168 1.1 christos putc ('(', f);
5169 1.1 christos {
5170 1.1 christos expressionS nexp = *exp;
5171 1.1 christos nexp.X_op = O_register;
5172 1.1 christos print_expr_1 (f, &nexp);
5173 1.1 christos }
5174 1.1 christos putc (')', f);
5175 1.1 christos break;
5176 1.1 christos default:
5177 1.1 christos print_expr_1 (f, exp);
5178 1.1 christos break;
5179 1.1 christos }
5180 1.1 christos }
5181 1.1 christos #endif
5182 1.1 christos
5183 1.1 christos /* The target specific pseudo-ops which we support. */
5185 1.1 christos
5186 1.1 christos const pseudo_typeS md_pseudo_table[] =
5187 1.1 christos {
5188 1.1 christos #ifdef OBJ_ECOFF
5189 1.1 christos {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */
5190 1.1 christos {"rdata", s_alpha_rdata, 0},
5191 1.1 christos #endif
5192 1.1 christos {"text", s_alpha_text, 0},
5193 1.1 christos {"data", s_alpha_data, 0},
5194 1.1 christos #ifdef OBJ_ECOFF
5195 1.1 christos {"sdata", s_alpha_sdata, 0},
5196 1.1 christos #endif
5197 1.1 christos #ifdef OBJ_ELF
5198 1.1 christos {"section", s_alpha_section, 0},
5199 1.1 christos {"section.s", s_alpha_section, 0},
5200 1.1 christos {"sect", s_alpha_section, 0},
5201 1.1 christos {"sect.s", s_alpha_section, 0},
5202 1.1 christos #endif
5203 1.1 christos #ifdef OBJ_EVAX
5204 1.1 christos {"section", s_alpha_section, 0},
5205 1.1 christos {"literals", s_alpha_literals, 0},
5206 1.1 christos {"pdesc", s_alpha_pdesc, 0},
5207 1.1 christos {"name", s_alpha_name, 0},
5208 1.1 christos {"linkage", s_alpha_linkage, 0},
5209 1.1 christos {"code_address", s_alpha_code_address, 0},
5210 1.1 christos {"ent", s_alpha_ent, 0},
5211 1.1 christos {"frame", s_alpha_frame, 0},
5212 1.1 christos {"fp_save", s_alpha_fp_save, 0},
5213 1.1 christos {"mask", s_alpha_mask, 0},
5214 1.1 christos {"fmask", s_alpha_fmask, 0},
5215 1.1 christos {"end", s_alpha_end, 0},
5216 1.1 christos {"file", s_alpha_file, 0},
5217 1.1 christos {"rdata", s_alpha_section, 1},
5218 1.1 christos {"comm", s_alpha_comm, 0},
5219 1.1 christos {"link", s_alpha_section, 3},
5220 1.1 christos {"ctors", s_alpha_section, 4},
5221 1.1 christos {"dtors", s_alpha_section, 5},
5222 1.1 christos {"handler", s_alpha_handler, 0},
5223 1.1 christos {"handler_data", s_alpha_handler, 1},
5224 1.1 christos #endif
5225 1.1 christos #ifdef OBJ_ELF
5226 1.1 christos /* Frame related pseudos. */
5227 1.1 christos {"ent", s_alpha_ent, 0},
5228 1.1 christos {"end", s_alpha_end, 0},
5229 1.1 christos {"mask", s_alpha_mask, 0},
5230 1.1 christos {"fmask", s_alpha_mask, 1},
5231 1.1 christos {"frame", s_alpha_frame, 0},
5232 1.1 christos {"prologue", s_alpha_prologue, 0},
5233 1.1 christos {"file", s_alpha_file, 5},
5234 1.1 christos {"loc", s_alpha_loc, 9},
5235 1.1 christos {"stabs", s_alpha_stab, 's'},
5236 1.1 christos {"stabn", s_alpha_stab, 'n'},
5237 1.1 christos {"usepv", s_alpha_usepv, 0},
5238 1.1 christos /* COFF debugging related pseudos. */
5239 1.1 christos {"begin", s_alpha_coff_wrapper, 0},
5240 1.1 christos {"bend", s_alpha_coff_wrapper, 1},
5241 1.1 christos {"def", s_alpha_coff_wrapper, 2},
5242 1.1 christos {"dim", s_alpha_coff_wrapper, 3},
5243 1.1 christos {"endef", s_alpha_coff_wrapper, 4},
5244 1.1 christos {"scl", s_alpha_coff_wrapper, 5},
5245 1.1 christos {"tag", s_alpha_coff_wrapper, 6},
5246 1.1 christos {"val", s_alpha_coff_wrapper, 7},
5247 1.1 christos #else
5248 1.1 christos #ifdef OBJ_EVAX
5249 1.1 christos {"prologue", s_alpha_prologue, 0},
5250 1.1 christos #else
5251 1.1 christos {"prologue", s_ignore, 0},
5252 1.1 christos #endif
5253 1.1 christos #endif
5254 1.1 christos {"gprel32", s_alpha_gprel32, 0},
5255 1.1 christos {"t_floating", s_alpha_float_cons, 'd'},
5256 1.1 christos {"s_floating", s_alpha_float_cons, 'f'},
5257 1.1 christos {"f_floating", s_alpha_float_cons, 'F'},
5258 1.1 christos {"g_floating", s_alpha_float_cons, 'G'},
5259 1.1 christos {"d_floating", s_alpha_float_cons, 'D'},
5260 1.1 christos
5261 1.1 christos {"proc", s_alpha_proc, 0},
5262 1.1 christos {"aproc", s_alpha_proc, 1},
5263 1.1 christos {"set", s_alpha_set, 0},
5264 1.1 christos {"reguse", s_ignore, 0},
5265 1.1 christos {"livereg", s_ignore, 0},
5266 1.1 christos {"base", s_alpha_base, 0}, /*??*/
5267 1.1 christos {"option", s_ignore, 0},
5268 1.1 christos {"aent", s_ignore, 0},
5269 1.1 christos {"ugen", s_ignore, 0},
5270 1.1 christos {"eflag", s_ignore, 0},
5271 1.1 christos
5272 1.1 christos {"align", s_alpha_align, 0},
5273 1.1 christos {"double", s_alpha_float_cons, 'd'},
5274 1.1 christos {"float", s_alpha_float_cons, 'f'},
5275 1.1 christos {"single", s_alpha_float_cons, 'f'},
5276 1.1 christos {"ascii", s_alpha_stringer, 0},
5277 1.1 christos {"asciz", s_alpha_stringer, 1},
5278 1.1 christos {"string", s_alpha_stringer, 1},
5279 1.1 christos {"space", s_alpha_space, 0},
5280 1.1 christos {"skip", s_alpha_space, 0},
5281 1.1 christos {"zero", s_alpha_space, 0},
5282 1.1 christos
5283 1.1 christos /* Unaligned data pseudos. */
5284 1.1 christos {"uword", s_alpha_ucons, 2},
5285 1.1 christos {"ulong", s_alpha_ucons, 4},
5286 1.1 christos {"uquad", s_alpha_ucons, 8},
5287 1.1 christos
5288 1.1 christos #ifdef OBJ_ELF
5289 1.1 christos /* Dwarf wants these versions of unaligned. */
5290 1.1 christos {"2byte", s_alpha_ucons, 2},
5291 1.1 christos {"4byte", s_alpha_ucons, 4},
5292 1.1 christos {"8byte", s_alpha_ucons, 8},
5293 1.1 christos #endif
5294 1.1 christos
5295 1.1 christos /* We don't do any optimizing, so we can safely ignore these. */
5296 1.1 christos {"noalias", s_ignore, 0},
5297 1.1 christos {"alias", s_ignore, 0},
5298 1.1 christos
5299 1.1 christos {"arch", s_alpha_arch, 0},
5300 1.1 christos
5301 1.1 christos {NULL, 0, 0},
5302 1.1 christos };
5303 1.1 christos
5304 1.1 christos #ifdef OBJ_ECOFF
5306 1.1 christos
5307 1.1 christos /* @@@ GP selection voodoo. All of this seems overly complicated and
5308 1.1 christos unnecessary; which is the primary reason it's for ECOFF only. */
5309 1.1 christos
5310 1.1 christos static inline void
5311 1.1 christos maybe_set_gp (asection *sec)
5312 1.1 christos {
5313 1.1 christos bfd_vma vma;
5314 1.1 christos
5315 1.1 christos if (!sec)
5316 1.1 christos return;
5317 1.1 christos vma = bfd_get_section_vma (sec->owner, sec);
5318 1.1 christos if (vma && vma < alpha_gp_value)
5319 1.1 christos alpha_gp_value = vma;
5320 1.1 christos }
5321 1.1 christos
5322 1.1 christos static void
5323 1.1 christos select_gp_value (void)
5324 1.1 christos {
5325 1.1 christos gas_assert (alpha_gp_value == 0);
5326 1.1 christos
5327 1.1 christos /* Get minus-one in whatever width... */
5328 1.1 christos alpha_gp_value = 0;
5329 1.1 christos alpha_gp_value--;
5330 1.1 christos
5331 1.1 christos /* Select the smallest VMA of these existing sections. */
5332 1.1 christos maybe_set_gp (alpha_lita_section);
5333 1.1 christos
5334 1.1 christos /* @@ Will a simple 0x8000 work here? If not, why not? */
5335 1.1 christos #define GP_ADJUSTMENT (0x8000 - 0x10)
5336 1.1 christos
5337 1.1 christos alpha_gp_value += GP_ADJUSTMENT;
5338 1.1 christos
5339 1.1 christos S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5340 1.1 christos
5341 1.1 christos #ifdef DEBUG1
5342 1.1 christos printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5343 1.1 christos #endif
5344 1.1 christos }
5345 1.1 christos #endif /* OBJ_ECOFF */
5346 1.1 christos
5347 1.1 christos #ifdef OBJ_ELF
5348 1.1 christos /* Map 's' to SHF_ALPHA_GPREL. */
5349 1.1 christos
5350 1.1 christos bfd_vma
5351 1.1 christos alpha_elf_section_letter (int letter, char **ptr_msg)
5352 1.1 christos {
5353 1.1 christos if (letter == 's')
5354 1.1 christos return SHF_ALPHA_GPREL;
5355 1.1 christos
5356 1.1 christos *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string");
5357 1.1 christos return -1;
5358 1.1 christos }
5359 1.1 christos
5360 1.1 christos /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5361 1.1 christos
5362 1.1 christos flagword
5363 1.1 christos alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
5364 1.1 christos {
5365 1.1 christos if (attr & SHF_ALPHA_GPREL)
5366 1.1 christos flags |= SEC_SMALL_DATA;
5367 1.1 christos return flags;
5368 1.1 christos }
5369 1.1 christos #endif /* OBJ_ELF */
5370 1.1 christos
5371 1.1 christos /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5372 1.1 christos of an rs_align_code fragment. */
5373 1.1 christos
5374 1.1 christos void
5375 1.1 christos alpha_handle_align (fragS *fragp)
5376 1.1 christos {
5377 1.1 christos static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5378 1.1 christos static char const nopunop[8] =
5379 1.1 christos {
5380 1.1 christos 0x1f, 0x04, 0xff, 0x47,
5381 1.1 christos 0x00, 0x00, 0xfe, 0x2f
5382 1.1 christos };
5383 1.1 christos
5384 1.1 christos int bytes, fix;
5385 1.1 christos char *p;
5386 1.1 christos
5387 1.1 christos if (fragp->fr_type != rs_align_code)
5388 1.1 christos return;
5389 1.1 christos
5390 1.1 christos bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5391 1.1 christos p = fragp->fr_literal + fragp->fr_fix;
5392 1.1 christos fix = 0;
5393 1.1 christos
5394 1.1 christos if (bytes & 3)
5395 1.1 christos {
5396 1.1 christos fix = bytes & 3;
5397 1.1 christos memset (p, 0, fix);
5398 1.1 christos p += fix;
5399 1.1 christos bytes -= fix;
5400 1.1 christos }
5401 1.1 christos
5402 1.1 christos if (bytes & 4)
5403 1.1 christos {
5404 1.1 christos memcpy (p, unop, 4);
5405 1.1 christos p += 4;
5406 1.1 christos bytes -= 4;
5407 1.1 christos fix += 4;
5408 1.1 christos }
5409 1.1 christos
5410 1.1 christos memcpy (p, nopunop, 8);
5411 1.1 christos
5412 1.1 christos fragp->fr_fix += fix;
5413 1.1 christos fragp->fr_var = 8;
5414 1.1 christos }
5415 1.1 christos
5416 1.1 christos /* Public interface functions. */
5418 1.1 christos
5419 1.1 christos /* This function is called once, at assembler startup time. It sets
5420 1.1 christos up all the tables, etc. that the MD part of the assembler will
5421 1.1 christos need, that can be determined before arguments are parsed. */
5422 1.1 christos
5423 1.1 christos void
5424 1.1 christos md_begin (void)
5425 1.1 christos {
5426 1.1 christos unsigned int i;
5427 1.1 christos
5428 1.1 christos /* Verify that X_op field is wide enough. */
5429 1.1 christos {
5430 1.1 christos expressionS e;
5431 1.1 christos
5432 1.1 christos e.X_op = O_max;
5433 1.1 christos gas_assert (e.X_op == O_max);
5434 1.1 christos }
5435 1.1 christos
5436 1.1 christos /* Create the opcode hash table. */
5437 1.1 christos alpha_opcode_hash = hash_new ();
5438 1.1 christos
5439 1.1 christos for (i = 0; i < alpha_num_opcodes;)
5440 1.1 christos {
5441 1.1 christos const char *name, *retval, *slash;
5442 1.1 christos
5443 1.1 christos name = alpha_opcodes[i].name;
5444 1.1 christos retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
5445 1.1 christos if (retval)
5446 1.1 christos as_fatal (_("internal error: can't hash opcode `%s': %s"),
5447 1.1 christos name, retval);
5448 1.1 christos
5449 1.1 christos /* Some opcodes include modifiers of various sorts with a "/mod"
5450 1.1 christos syntax, like the architecture manual suggests. However, for
5451 1.1 christos use with gcc at least, we also need access to those same opcodes
5452 1.1 christos without the "/". */
5453 1.1 christos
5454 1.1 christos if ((slash = strchr (name, '/')) != NULL)
5455 1.1 christos {
5456 1.1 christos char *p = (char *) xmalloc (strlen (name));
5457 1.1 christos
5458 1.1 christos memcpy (p, name, slash - name);
5459 1.1 christos strcpy (p + (slash - name), slash + 1);
5460 1.1 christos
5461 1.1 christos (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
5462 1.1 christos /* Ignore failures -- the opcode table does duplicate some
5463 1.1 christos variants in different forms, like "hw_stq" and "hw_st/q". */
5464 1.1 christos }
5465 1.1 christos
5466 1.1 christos while (++i < alpha_num_opcodes
5467 1.1 christos && (alpha_opcodes[i].name == name
5468 1.1 christos || !strcmp (alpha_opcodes[i].name, name)))
5469 1.1 christos continue;
5470 1.1 christos }
5471 1.1 christos
5472 1.1 christos /* Create the macro hash table. */
5473 1.1 christos alpha_macro_hash = hash_new ();
5474 1.1 christos
5475 1.1 christos for (i = 0; i < alpha_num_macros;)
5476 1.1 christos {
5477 1.1 christos const char *name, *retval;
5478 1.1 christos
5479 1.1 christos name = alpha_macros[i].name;
5480 1.1 christos retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
5481 1.1 christos if (retval)
5482 1.1 christos as_fatal (_("internal error: can't hash macro `%s': %s"),
5483 1.1 christos name, retval);
5484 1.1 christos
5485 1.1 christos while (++i < alpha_num_macros
5486 1.1 christos && (alpha_macros[i].name == name
5487 1.1 christos || !strcmp (alpha_macros[i].name, name)))
5488 1.1 christos continue;
5489 1.1 christos }
5490 1.1 christos
5491 1.1 christos /* Construct symbols for each of the registers. */
5492 1.1 christos for (i = 0; i < 32; ++i)
5493 1.1 christos {
5494 1.1 christos char name[4];
5495 1.1 christos
5496 1.1 christos sprintf (name, "$%d", i);
5497 1.1 christos alpha_register_table[i] = symbol_create (name, reg_section, i,
5498 1.1 christos &zero_address_frag);
5499 1.1 christos }
5500 1.1 christos
5501 1.1 christos for (; i < 64; ++i)
5502 1.1 christos {
5503 1.1 christos char name[5];
5504 1.1 christos
5505 1.1 christos sprintf (name, "$f%d", i - 32);
5506 1.1 christos alpha_register_table[i] = symbol_create (name, reg_section, i,
5507 1.1 christos &zero_address_frag);
5508 1.1 christos }
5509 1.1 christos
5510 1.1 christos /* Create the special symbols and sections we'll be using. */
5511 1.1 christos
5512 1.1 christos /* So .sbss will get used for tiny objects. */
5513 1.1 christos bfd_set_gp_size (stdoutput, g_switch_value);
5514 1.1 christos
5515 1.1 christos #ifdef OBJ_ECOFF
5516 1.1 christos create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
5517 1.1 christos
5518 1.1 christos /* For handling the GP, create a symbol that won't be output in the
5519 1.1 christos symbol table. We'll edit it out of relocs later. */
5520 1.1 christos alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
5521 1.1 christos &zero_address_frag);
5522 1.1 christos #endif
5523 1.1 christos
5524 1.1 christos #ifdef OBJ_EVAX
5525 1.1 christos create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
5526 1.1 christos #endif
5527 1.1 christos
5528 1.1 christos #ifdef OBJ_ELF
5529 1.1 christos if (ECOFF_DEBUGGING)
5530 1.1 christos {
5531 1.1 christos segT sec = subseg_new (".mdebug", (subsegT) 0);
5532 1.1 christos bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
5533 1.1 christos bfd_set_section_alignment (stdoutput, sec, 3);
5534 1.1 christos }
5535 1.1 christos #endif
5536 1.1 christos
5537 1.1 christos /* Create literal lookup hash table. */
5538 1.1 christos alpha_literal_hash = hash_new ();
5539 1.1 christos
5540 1.1 christos subseg_set (text_section, 0);
5541 1.1 christos }
5542 1.1 christos
5543 1.1 christos /* The public interface to the instruction assembler. */
5544 1.1 christos
5545 1.1 christos void
5546 1.1 christos md_assemble (char *str)
5547 1.1 christos {
5548 1.1 christos /* Current maximum is 13. */
5549 1.1 christos char opname[32];
5550 1.1 christos expressionS tok[MAX_INSN_ARGS];
5551 1.1 christos int ntok, trunclen;
5552 1.1 christos size_t opnamelen;
5553 1.1 christos
5554 1.1 christos /* Split off the opcode. */
5555 1.1 christos opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
5556 1.1 christos trunclen = (opnamelen < sizeof (opname) - 1
5557 1.1 christos ? opnamelen
5558 1.1 christos : sizeof (opname) - 1);
5559 1.1 christos memcpy (opname, str, trunclen);
5560 1.1 christos opname[trunclen] = '\0';
5561 1.1 christos
5562 1.1 christos /* Tokenize the rest of the line. */
5563 1.1 christos if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
5564 1.1 christos {
5565 1.1 christos if (ntok != TOKENIZE_ERROR_REPORT)
5566 1.1 christos as_bad (_("syntax error"));
5567 1.1 christos
5568 1.1 christos return;
5569 1.1 christos }
5570 1.1 christos
5571 1.1 christos /* Finish it off. */
5572 1.1 christos assemble_tokens (opname, tok, ntok, alpha_macros_on);
5573 1.1 christos }
5574 1.1 christos
5575 1.1 christos /* Round up a section's size to the appropriate boundary. */
5576 1.1 christos
5577 1.1 christos valueT
5578 1.1 christos md_section_align (segT seg, valueT size)
5579 1.1 christos {
5580 1.1 christos int align = bfd_get_section_alignment (stdoutput, seg);
5581 1.1 christos valueT mask = ((valueT) 1 << align) - 1;
5582 1.1 christos
5583 1.1 christos return (size + mask) & ~mask;
5584 1.1 christos }
5585 1.1 christos
5586 1.1 christos /* Turn a string in input_line_pointer into a floating point constant
5587 1.1 christos of type TYPE, and store the appropriate bytes in *LITP. The number
5588 1.1 christos of LITTLENUMS emitted is stored in *SIZEP. An error message is
5589 1.1 christos returned, or NULL on OK. */
5590 1.1 christos
5591 1.1 christos char *
5592 1.1 christos md_atof (int type, char *litP, int *sizeP)
5593 1.1 christos {
5594 1.1 christos extern char *vax_md_atof (int, char *, int *);
5595 1.1 christos
5596 1.1 christos switch (type)
5597 1.1 christos {
5598 1.1 christos /* VAX floats. */
5599 1.1 christos case 'G':
5600 1.1 christos /* vax_md_atof() doesn't like "G" for some reason. */
5601 1.1 christos type = 'g';
5602 1.1 christos case 'F':
5603 1.1 christos case 'D':
5604 1.1 christos return vax_md_atof (type, litP, sizeP);
5605 1.1 christos
5606 1.1 christos default:
5607 1.1 christos return ieee_md_atof (type, litP, sizeP, FALSE);
5608 1.1 christos }
5609 1.1 christos }
5610 1.1 christos
5611 1.1 christos /* Take care of the target-specific command-line options. */
5612 1.1 christos
5613 1.1 christos int
5614 1.1 christos md_parse_option (int c, char *arg)
5615 1.1 christos {
5616 1.1 christos switch (c)
5617 1.1 christos {
5618 1.1 christos case 'F':
5619 1.1 christos alpha_nofloats_on = 1;
5620 1.1 christos break;
5621 1.1 christos
5622 1.1 christos case OPTION_32ADDR:
5623 1.1 christos alpha_addr32_on = 1;
5624 1.1 christos break;
5625 1.1 christos
5626 1.1 christos case 'g':
5627 1.1 christos alpha_debug = 1;
5628 1.1 christos break;
5629 1.1 christos
5630 1.1 christos case 'G':
5631 1.1 christos g_switch_value = atoi (arg);
5632 1.1 christos break;
5633 1.1 christos
5634 1.1 christos case 'm':
5635 1.1 christos {
5636 1.1 christos const struct cpu_type *p;
5637 1.1 christos
5638 1.1 christos for (p = cpu_types; p->name; ++p)
5639 1.1 christos if (strcmp (arg, p->name) == 0)
5640 1.1 christos {
5641 1.1 christos alpha_target_name = p->name, alpha_target = p->flags;
5642 1.1 christos goto found;
5643 1.1 christos }
5644 1.1 christos as_warn (_("Unknown CPU identifier `%s'"), arg);
5645 1.1 christos found:;
5646 1.1 christos }
5647 1.1 christos break;
5648 1.1 christos
5649 1.1 christos #ifdef OBJ_EVAX
5650 1.1 christos case '+': /* For g++. Hash any name > 63 chars long. */
5651 1.1 christos alpha_flag_hash_long_names = 1;
5652 1.1 christos break;
5653 1.1 christos
5654 1.1 christos case 'H': /* Show new symbol after hash truncation. */
5655 1.1 christos alpha_flag_show_after_trunc = 1;
5656 1.1 christos break;
5657 1.1 christos
5658 1.1 christos case 'h': /* For gnu-c/vax compatibility. */
5659 1.1 christos break;
5660 1.1 christos
5661 1.1 christos case OPTION_REPLACE:
5662 1.1 christos alpha_flag_replace = 1;
5663 1.1 christos break;
5664 1.1 christos
5665 1.1 christos case OPTION_NOREPLACE:
5666 1.1 christos alpha_flag_replace = 0;
5667 1.1 christos break;
5668 1.1 christos #endif
5669 1.1 christos
5670 1.1 christos case OPTION_RELAX:
5671 1.1 christos alpha_flag_relax = 1;
5672 1.1 christos break;
5673 1.1 christos
5674 1.1 christos #ifdef OBJ_ELF
5675 1.1 christos case OPTION_MDEBUG:
5676 1.1 christos alpha_flag_mdebug = 1;
5677 1.1 christos break;
5678 1.1 christos case OPTION_NO_MDEBUG:
5679 1.1 christos alpha_flag_mdebug = 0;
5680 1.1 christos break;
5681 1.1 christos #endif
5682 1.1 christos
5683 1.1 christos default:
5684 1.1 christos return 0;
5685 1.1 christos }
5686 1.1 christos
5687 1.1 christos return 1;
5688 1.1 christos }
5689 1.1 christos
5690 1.1 christos /* Print a description of the command-line options that we accept. */
5691 1.1 christos
5692 1.1 christos void
5693 1.1 christos md_show_usage (FILE *stream)
5694 1.1 christos {
5695 1.1 christos fputs (_("\
5696 1.1 christos Alpha options:\n\
5697 1.1 christos -32addr treat addresses as 32-bit values\n\
5698 1.1 christos -F lack floating point instructions support\n\
5699 1.1 christos -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5700 1.1 christos specify variant of Alpha architecture\n\
5701 1.1 christos -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5702 1.1 christos these variants include PALcode opcodes\n"),
5703 1.1 christos stream);
5704 1.1 christos #ifdef OBJ_EVAX
5705 1.1 christos fputs (_("\
5706 1.1 christos VMS options:\n\
5707 1.1 christos -+ encode (don't truncate) names longer than 64 characters\n\
5708 1.1 christos -H show new symbol after hash truncation\n\
5709 1.1 christos -replace/-noreplace enable or disable the optimization of procedure calls\n"),
5710 1.1 christos stream);
5711 1.1 christos #endif
5712 1.1 christos }
5713 1.1 christos
5714 1.1 christos /* Decide from what point a pc-relative relocation is relative to,
5715 1.1 christos relative to the pc-relative fixup. Er, relatively speaking. */
5716 1.1 christos
5717 1.1 christos long
5718 1.1 christos md_pcrel_from (fixS *fixP)
5719 1.1 christos {
5720 1.1 christos valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5721 1.1 christos
5722 1.1 christos switch (fixP->fx_r_type)
5723 1.1 christos {
5724 1.1 christos case BFD_RELOC_23_PCREL_S2:
5725 1.1 christos case BFD_RELOC_ALPHA_HINT:
5726 1.1 christos case BFD_RELOC_ALPHA_BRSGP:
5727 1.1 christos return addr + 4;
5728 1.1 christos default:
5729 1.1 christos return addr;
5730 1.1 christos }
5731 1.1 christos }
5732 1.1 christos
5733 1.1 christos /* Attempt to simplify or even eliminate a fixup. The return value is
5734 1.1 christos ignored; perhaps it was once meaningful, but now it is historical.
5735 1.1 christos To indicate that a fixup has been eliminated, set fixP->fx_done.
5736 1.1 christos
5737 1.1 christos For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5738 1.1 christos internally into the GPDISP reloc used externally. We had to do
5739 1.1 christos this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5740 1.1 christos the distance to the "lda" instruction for setting the addend to
5741 1.1 christos GPDISP. */
5742 1.1 christos
5743 1.1 christos void
5744 1.1 christos md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5745 1.1 christos {
5746 1.1 christos char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5747 1.1 christos valueT value = * valP;
5748 1.1 christos unsigned image, size;
5749 1.1 christos
5750 1.1 christos switch (fixP->fx_r_type)
5751 1.1 christos {
5752 1.1 christos /* The GPDISP relocations are processed internally with a symbol
5753 1.1 christos referring to the current function's section; we need to drop
5754 1.1 christos in a value which, when added to the address of the start of
5755 1.1 christos the function, gives the desired GP. */
5756 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
5757 1.1 christos {
5758 1.1 christos fixS *next = fixP->fx_next;
5759 1.1 christos
5760 1.1 christos /* With user-specified !gpdisp relocations, we can be missing
5761 1.1 christos the matching LO16 reloc. We will have already issued an
5762 1.1 christos error message. */
5763 1.1 christos if (next)
5764 1.1 christos fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5765 1.1 christos - fixP->fx_frag->fr_address - fixP->fx_where);
5766 1.1 christos
5767 1.1 christos value = (value - sign_extend_16 (value)) >> 16;
5768 1.1 christos }
5769 1.1 christos #ifdef OBJ_ELF
5770 1.1 christos fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5771 1.1 christos #endif
5772 1.1 christos goto do_reloc_gp;
5773 1.1 christos
5774 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
5775 1.1 christos value = sign_extend_16 (value);
5776 1.1 christos fixP->fx_offset = 0;
5777 1.1 christos #ifdef OBJ_ELF
5778 1.1 christos fixP->fx_done = 1;
5779 1.1 christos #endif
5780 1.1 christos
5781 1.1 christos do_reloc_gp:
5782 1.1 christos fixP->fx_addsy = section_symbol (seg);
5783 1.1 christos md_number_to_chars (fixpos, value, 2);
5784 1.1 christos break;
5785 1.1 christos
5786 1.1 christos case BFD_RELOC_16:
5787 1.1 christos if (fixP->fx_pcrel)
5788 1.1 christos fixP->fx_r_type = BFD_RELOC_16_PCREL;
5789 1.1 christos size = 2;
5790 1.1 christos goto do_reloc_xx;
5791 1.1 christos
5792 1.1 christos case BFD_RELOC_32:
5793 1.1 christos if (fixP->fx_pcrel)
5794 1.1 christos fixP->fx_r_type = BFD_RELOC_32_PCREL;
5795 1.1 christos size = 4;
5796 1.1 christos goto do_reloc_xx;
5797 1.1 christos
5798 1.1 christos case BFD_RELOC_64:
5799 1.1 christos if (fixP->fx_pcrel)
5800 1.1 christos fixP->fx_r_type = BFD_RELOC_64_PCREL;
5801 1.1 christos size = 8;
5802 1.1 christos
5803 1.1 christos do_reloc_xx:
5804 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5805 1.1 christos {
5806 1.1 christos md_number_to_chars (fixpos, value, size);
5807 1.1 christos goto done;
5808 1.1 christos }
5809 1.1 christos return;
5810 1.1 christos
5811 1.1 christos #ifdef OBJ_ECOFF
5812 1.1 christos case BFD_RELOC_GPREL32:
5813 1.1 christos gas_assert (fixP->fx_subsy == alpha_gp_symbol);
5814 1.1 christos fixP->fx_subsy = 0;
5815 1.1 christos /* FIXME: inherited this obliviousness of `value' -- why? */
5816 1.1 christos md_number_to_chars (fixpos, -alpha_gp_value, 4);
5817 1.1 christos break;
5818 1.1 christos #else
5819 1.1 christos case BFD_RELOC_GPREL32:
5820 1.1 christos #endif
5821 1.1 christos case BFD_RELOC_GPREL16:
5822 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16:
5823 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16:
5824 1.1 christos return;
5825 1.1 christos
5826 1.1 christos case BFD_RELOC_23_PCREL_S2:
5827 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5828 1.1 christos {
5829 1.1 christos image = bfd_getl32 (fixpos);
5830 1.1 christos image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5831 1.1 christos goto write_done;
5832 1.1 christos }
5833 1.1 christos return;
5834 1.1 christos
5835 1.1 christos case BFD_RELOC_ALPHA_HINT:
5836 1.1 christos if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5837 1.1 christos {
5838 1.1 christos image = bfd_getl32 (fixpos);
5839 1.1 christos image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5840 1.1 christos goto write_done;
5841 1.1 christos }
5842 1.1 christos return;
5843 1.1 christos
5844 1.1 christos #ifdef OBJ_ELF
5845 1.1 christos case BFD_RELOC_ALPHA_BRSGP:
5846 1.1 christos return;
5847 1.1 christos
5848 1.1 christos case BFD_RELOC_ALPHA_TLSGD:
5849 1.1 christos case BFD_RELOC_ALPHA_TLSLDM:
5850 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16:
5851 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16:
5852 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16:
5853 1.1 christos case BFD_RELOC_ALPHA_DTPREL16:
5854 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16:
5855 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16:
5856 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16:
5857 1.1 christos case BFD_RELOC_ALPHA_TPREL16:
5858 1.1 christos if (fixP->fx_addsy)
5859 1.1 christos S_SET_THREAD_LOCAL (fixP->fx_addsy);
5860 1.1 christos return;
5861 1.1 christos #endif
5862 1.1 christos
5863 1.1 christos #ifdef OBJ_ECOFF
5864 1.1 christos case BFD_RELOC_ALPHA_LITERAL:
5865 1.1 christos md_number_to_chars (fixpos, value, 2);
5866 1.1 christos return;
5867 1.1 christos #endif
5868 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
5869 1.1 christos case BFD_RELOC_ALPHA_LITUSE:
5870 1.1 christos case BFD_RELOC_ALPHA_LINKAGE:
5871 1.1 christos case BFD_RELOC_ALPHA_CODEADDR:
5872 1.1 christos return;
5873 1.1 christos
5874 1.1 christos #ifdef OBJ_EVAX
5875 1.1 christos case BFD_RELOC_ALPHA_NOP:
5876 1.1 christos value -= (8 + 4); /* PC-relative, base is jsr+4. */
5877 1.1 christos
5878 1.1 christos /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5879 1.1 christos "Finally, the ETIR$C_STC_BSR command passes the same address
5880 1.1 christos as ETIR$C_STC_NOP (so that they will fail or succeed together),
5881 1.1 christos and the same test is done again." */
5882 1.1 christos if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5883 1.1 christos {
5884 1.1 christos fixP->fx_addnumber = -value;
5885 1.1 christos return;
5886 1.1 christos }
5887 1.1 christos
5888 1.1 christos if ((abs (value) >> 2) & ~0xfffff)
5889 1.1 christos goto done;
5890 1.1 christos else
5891 1.1 christos {
5892 1.1 christos /* Change to a nop. */
5893 1.1 christos image = 0x47FF041F;
5894 1.1 christos goto write_done;
5895 1.1 christos }
5896 1.1 christos
5897 1.1 christos case BFD_RELOC_ALPHA_LDA:
5898 1.1 christos /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5899 1.1 christos the value for an O_subtract. */
5900 1.1 christos if (fixP->fx_addsy
5901 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5902 1.1 christos {
5903 1.1 christos fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value;
5904 1.1 christos return;
5905 1.1 christos }
5906 1.1 christos
5907 1.1 christos if ((abs (value)) & ~0x7fff)
5908 1.1 christos goto done;
5909 1.1 christos else
5910 1.1 christos {
5911 1.1 christos /* Change to an lda. */
5912 1.1 christos image = 0x237B0000 | (value & 0xFFFF);
5913 1.1 christos goto write_done;
5914 1.1 christos }
5915 1.1 christos
5916 1.1 christos case BFD_RELOC_ALPHA_BSR:
5917 1.1 christos case BFD_RELOC_ALPHA_BOH:
5918 1.1 christos value -= 4; /* PC-relative, base is jsr+4. */
5919 1.1 christos
5920 1.1 christos /* See comment in the BFD_RELOC_ALPHA_NOP case above. */
5921 1.1 christos if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5922 1.1 christos {
5923 1.1 christos fixP->fx_addnumber = -value;
5924 1.1 christos return;
5925 1.1 christos }
5926 1.1 christos
5927 1.1 christos if ((abs (value) >> 2) & ~0xfffff)
5928 1.1 christos {
5929 1.1 christos /* Out of range. */
5930 1.1 christos if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH)
5931 1.1 christos {
5932 1.1 christos /* Add a hint. */
5933 1.1 christos image = bfd_getl32(fixpos);
5934 1.1 christos image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5935 1.1 christos goto write_done;
5936 1.1 christos }
5937 1.1 christos goto done;
5938 1.1 christos }
5939 1.1 christos else
5940 1.1 christos {
5941 1.1 christos /* Change to a branch. */
5942 1.1 christos image = 0xD3400000 | ((value >> 2) & 0x1FFFFF);
5943 1.1 christos goto write_done;
5944 1.1 christos }
5945 1.1 christos #endif
5946 1.1 christos
5947 1.1 christos case BFD_RELOC_VTABLE_INHERIT:
5948 1.1 christos case BFD_RELOC_VTABLE_ENTRY:
5949 1.1 christos return;
5950 1.1 christos
5951 1.1 christos default:
5952 1.1 christos {
5953 1.1 christos const struct alpha_operand *operand;
5954 1.1 christos
5955 1.1 christos if ((int) fixP->fx_r_type >= 0)
5956 1.1 christos as_fatal (_("unhandled relocation type %s"),
5957 1.1 christos bfd_get_reloc_code_name (fixP->fx_r_type));
5958 1.1 christos
5959 1.1 christos gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5960 1.1 christos operand = &alpha_operands[-(int) fixP->fx_r_type];
5961 1.1 christos
5962 1.1 christos /* The rest of these fixups only exist internally during symbol
5963 1.1 christos resolution and have no representation in the object file.
5964 1.1 christos Therefore they must be completely resolved as constants. */
5965 1.1 christos
5966 1.1 christos if (fixP->fx_addsy != 0
5967 1.1 christos && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5968 1.1 christos as_bad_where (fixP->fx_file, fixP->fx_line,
5969 1.1 christos _("non-absolute expression in constant field"));
5970 1.1 christos
5971 1.1 christos image = bfd_getl32 (fixpos);
5972 1.1 christos image = insert_operand (image, operand, (offsetT) value,
5973 1.1 christos fixP->fx_file, fixP->fx_line);
5974 1.1 christos }
5975 1.1 christos goto write_done;
5976 1.1 christos }
5977 1.1 christos
5978 1.1 christos if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5979 1.1 christos return;
5980 1.1 christos else
5981 1.1 christos {
5982 1.1 christos as_warn_where (fixP->fx_file, fixP->fx_line,
5983 1.1 christos _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5984 1.1 christos goto done;
5985 1.1 christos }
5986 1.1 christos
5987 1.1 christos write_done:
5988 1.1 christos md_number_to_chars (fixpos, image, 4);
5989 1.1 christos
5990 1.1 christos done:
5991 1.1 christos fixP->fx_done = 1;
5992 1.1 christos }
5993 1.1 christos
5994 1.1 christos /* Look for a register name in the given symbol. */
5995 1.1 christos
5996 1.1 christos symbolS *
5997 1.1 christos md_undefined_symbol (char *name)
5998 1.1 christos {
5999 1.1 christos if (*name == '$')
6000 1.1 christos {
6001 1.1 christos int is_float = 0, num;
6002 1.1 christos
6003 1.1 christos switch (*++name)
6004 1.1 christos {
6005 1.1 christos case 'f':
6006 1.1 christos if (name[1] == 'p' && name[2] == '\0')
6007 1.1 christos return alpha_register_table[AXP_REG_FP];
6008 1.1 christos is_float = 32;
6009 1.1 christos /* Fall through. */
6010 1.1 christos
6011 1.1 christos case 'r':
6012 1.1 christos if (!ISDIGIT (*++name))
6013 1.1 christos break;
6014 1.1 christos /* Fall through. */
6015 1.1 christos
6016 1.1 christos case '0': case '1': case '2': case '3': case '4':
6017 1.1 christos case '5': case '6': case '7': case '8': case '9':
6018 1.1 christos if (name[1] == '\0')
6019 1.1 christos num = name[0] - '0';
6020 1.1 christos else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
6021 1.1 christos {
6022 1.1 christos num = (name[0] - '0') * 10 + name[1] - '0';
6023 1.1 christos if (num >= 32)
6024 1.1 christos break;
6025 1.1 christos }
6026 1.1 christos else
6027 1.1 christos break;
6028 1.1 christos
6029 1.1 christos if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
6030 1.1 christos as_warn (_("Used $at without \".set noat\""));
6031 1.1 christos return alpha_register_table[num + is_float];
6032 1.1 christos
6033 1.1 christos case 'a':
6034 1.1 christos if (name[1] == 't' && name[2] == '\0')
6035 1.1 christos {
6036 1.1 christos if (!alpha_noat_on)
6037 1.1 christos as_warn (_("Used $at without \".set noat\""));
6038 1.1 christos return alpha_register_table[AXP_REG_AT];
6039 1.1 christos }
6040 1.1 christos break;
6041 1.1 christos
6042 1.1 christos case 'g':
6043 1.1 christos if (name[1] == 'p' && name[2] == '\0')
6044 1.1 christos return alpha_register_table[alpha_gp_register];
6045 1.1 christos break;
6046 1.1 christos
6047 1.1 christos case 's':
6048 1.1 christos if (name[1] == 'p' && name[2] == '\0')
6049 1.1 christos return alpha_register_table[AXP_REG_SP];
6050 1.1 christos break;
6051 1.1 christos }
6052 1.1 christos }
6053 1.1 christos return NULL;
6054 1.1 christos }
6055 1.1 christos
6056 1.1 christos #ifdef OBJ_ECOFF
6057 1.1 christos /* @@@ Magic ECOFF bits. */
6058 1.1 christos
6059 1.1 christos void
6060 1.1 christos alpha_frob_ecoff_data (void)
6061 1.1 christos {
6062 1.1 christos select_gp_value ();
6063 1.1 christos /* $zero and $f31 are read-only. */
6064 1.1 christos alpha_gprmask &= ~1;
6065 1.1 christos alpha_fprmask &= ~1;
6066 1.1 christos }
6067 1.1 christos #endif
6068 1.1 christos
6069 1.1 christos /* Hook to remember a recently defined label so that the auto-align
6070 1.1 christos code can adjust the symbol after we know what alignment will be
6071 1.1 christos required. */
6072 1.1 christos
6073 1.1 christos void
6074 1.1 christos alpha_define_label (symbolS *sym)
6075 1.1 christos {
6076 1.1 christos alpha_insn_label = sym;
6077 1.1 christos #ifdef OBJ_ELF
6078 1.1 christos dwarf2_emit_label (sym);
6079 1.1 christos #endif
6080 1.1 christos }
6081 1.1 christos
6082 1.1 christos /* Return true if we must always emit a reloc for a type and false if
6083 1.1 christos there is some hope of resolving it at assembly time. */
6084 1.1 christos
6085 1.1 christos int
6086 1.1 christos alpha_force_relocation (fixS *f)
6087 1.1 christos {
6088 1.1 christos if (alpha_flag_relax)
6089 1.1 christos return 1;
6090 1.1 christos
6091 1.1 christos switch (f->fx_r_type)
6092 1.1 christos {
6093 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
6094 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
6095 1.1 christos case BFD_RELOC_ALPHA_GPDISP:
6096 1.1 christos case BFD_RELOC_ALPHA_LITERAL:
6097 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
6098 1.1 christos case BFD_RELOC_ALPHA_LITUSE:
6099 1.1 christos case BFD_RELOC_GPREL16:
6100 1.1 christos case BFD_RELOC_GPREL32:
6101 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16:
6102 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16:
6103 1.1 christos case BFD_RELOC_ALPHA_LINKAGE:
6104 1.1 christos case BFD_RELOC_ALPHA_CODEADDR:
6105 1.1 christos case BFD_RELOC_ALPHA_BRSGP:
6106 1.1 christos case BFD_RELOC_ALPHA_TLSGD:
6107 1.1 christos case BFD_RELOC_ALPHA_TLSLDM:
6108 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16:
6109 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16:
6110 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16:
6111 1.1 christos case BFD_RELOC_ALPHA_DTPREL16:
6112 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16:
6113 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16:
6114 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16:
6115 1.1 christos case BFD_RELOC_ALPHA_TPREL16:
6116 1.1 christos #ifdef OBJ_EVAX
6117 1.1 christos case BFD_RELOC_ALPHA_NOP:
6118 1.1 christos case BFD_RELOC_ALPHA_BSR:
6119 1.1 christos case BFD_RELOC_ALPHA_LDA:
6120 1.1 christos case BFD_RELOC_ALPHA_BOH:
6121 1.1 christos #endif
6122 1.1 christos return 1;
6123 1.1 christos
6124 1.1 christos default:
6125 1.1 christos break;
6126 1.1 christos }
6127 1.1 christos
6128 1.1 christos return generic_force_reloc (f);
6129 1.1 christos }
6130 1.1 christos
6131 1.1 christos /* Return true if we can partially resolve a relocation now. */
6132 1.1 christos
6133 1.1 christos int
6134 1.1 christos alpha_fix_adjustable (fixS *f)
6135 1.1 christos {
6136 1.1 christos /* Are there any relocation types for which we must generate a
6137 1.1 christos reloc but we can adjust the values contained within it? */
6138 1.1 christos switch (f->fx_r_type)
6139 1.1 christos {
6140 1.1 christos case BFD_RELOC_ALPHA_GPDISP_HI16:
6141 1.1 christos case BFD_RELOC_ALPHA_GPDISP_LO16:
6142 1.1 christos case BFD_RELOC_ALPHA_GPDISP:
6143 1.1 christos return 0;
6144 1.1 christos
6145 1.1 christos case BFD_RELOC_ALPHA_LITERAL:
6146 1.1 christos case BFD_RELOC_ALPHA_ELF_LITERAL:
6147 1.1 christos case BFD_RELOC_ALPHA_LITUSE:
6148 1.1 christos case BFD_RELOC_ALPHA_LINKAGE:
6149 1.1 christos case BFD_RELOC_ALPHA_CODEADDR:
6150 1.1 christos return 1;
6151 1.1 christos
6152 1.1 christos case BFD_RELOC_VTABLE_ENTRY:
6153 1.1 christos case BFD_RELOC_VTABLE_INHERIT:
6154 1.1 christos return 0;
6155 1.1 christos
6156 1.1 christos case BFD_RELOC_GPREL16:
6157 1.1 christos case BFD_RELOC_GPREL32:
6158 1.1 christos case BFD_RELOC_ALPHA_GPREL_HI16:
6159 1.1 christos case BFD_RELOC_ALPHA_GPREL_LO16:
6160 1.1 christos case BFD_RELOC_23_PCREL_S2:
6161 1.1 christos case BFD_RELOC_16:
6162 1.1 christos case BFD_RELOC_32:
6163 1.1 christos case BFD_RELOC_64:
6164 1.1 christos case BFD_RELOC_ALPHA_HINT:
6165 1.1 christos return 1;
6166 1.1 christos
6167 1.1 christos case BFD_RELOC_ALPHA_TLSGD:
6168 1.1 christos case BFD_RELOC_ALPHA_TLSLDM:
6169 1.1 christos case BFD_RELOC_ALPHA_GOTDTPREL16:
6170 1.1 christos case BFD_RELOC_ALPHA_DTPREL_HI16:
6171 1.1 christos case BFD_RELOC_ALPHA_DTPREL_LO16:
6172 1.1 christos case BFD_RELOC_ALPHA_DTPREL16:
6173 1.1 christos case BFD_RELOC_ALPHA_GOTTPREL16:
6174 1.1 christos case BFD_RELOC_ALPHA_TPREL_HI16:
6175 1.1 christos case BFD_RELOC_ALPHA_TPREL_LO16:
6176 1.1 christos case BFD_RELOC_ALPHA_TPREL16:
6177 1.1 christos /* ??? No idea why we can't return a reference to .tbss+10, but
6178 1.1 christos we're preventing this in the other assemblers. Follow for now. */
6179 1.1 christos return 0;
6180 1.1 christos
6181 1.1 christos #ifdef OBJ_ELF
6182 1.1 christos case BFD_RELOC_ALPHA_BRSGP:
6183 1.1 christos /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6184 1.1 christos let it get resolved at assembly time. */
6185 1.1 christos {
6186 1.1 christos symbolS *sym = f->fx_addsy;
6187 1.1 christos const char *name;
6188 1.1 christos int offset = 0;
6189 1.1 christos
6190 1.1 christos if (generic_force_reloc (f))
6191 1.1 christos return 0;
6192 1.1 christos
6193 1.1 christos switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
6194 1.1 christos {
6195 1.1 christos case STO_ALPHA_NOPV:
6196 1.1 christos break;
6197 1.1 christos case STO_ALPHA_STD_GPLOAD:
6198 1.1 christos offset = 8;
6199 1.1 christos break;
6200 1.1 christos default:
6201 1.1 christos if (S_IS_LOCAL (sym))
6202 1.1 christos name = "<local>";
6203 1.1 christos else
6204 1.1 christos name = S_GET_NAME (sym);
6205 1.1 christos as_bad_where (f->fx_file, f->fx_line,
6206 1.1 christos _("!samegp reloc against symbol without .prologue: %s"),
6207 1.1 christos name);
6208 1.1 christos break;
6209 1.1 christos }
6210 1.1 christos f->fx_r_type = BFD_RELOC_23_PCREL_S2;
6211 1.1 christos f->fx_offset += offset;
6212 1.1 christos return 1;
6213 1.1 christos }
6214 1.1 christos #endif
6215 1.1 christos #ifdef OBJ_EVAX
6216 1.1 christos case BFD_RELOC_ALPHA_NOP:
6217 1.1 christos case BFD_RELOC_ALPHA_BSR:
6218 1.1 christos case BFD_RELOC_ALPHA_LDA:
6219 1.1 christos case BFD_RELOC_ALPHA_BOH:
6220 1.1 christos return 1;
6221 1.1 christos #endif
6222 1.1 christos
6223 1.1 christos default:
6224 1.1 christos return 1;
6225 1.1 christos }
6226 1.1 christos }
6227 1.1 christos
6228 1.1 christos /* Generate the BFD reloc to be stuck in the object file from the
6229 1.1 christos fixup used internally in the assembler. */
6230 1.1 christos
6231 1.1 christos arelent *
6232 1.1 christos tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
6233 1.1 christos fixS *fixp)
6234 1.1 christos {
6235 1.1 christos arelent *reloc;
6236 1.1 christos
6237 1.1 christos reloc = (arelent *) xmalloc (sizeof (* reloc));
6238 1.1 christos reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6239 1.1 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6240 1.1 christos reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6241 1.1 christos
6242 1.1 christos /* Make sure none of our internal relocations make it this far.
6243 1.1 christos They'd better have been fully resolved by this point. */
6244 1.1 christos gas_assert ((int) fixp->fx_r_type > 0);
6245 1.1 christos
6246 1.1 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6247 1.1 christos if (reloc->howto == NULL)
6248 1.1 christos {
6249 1.1 christos as_bad_where (fixp->fx_file, fixp->fx_line,
6250 1.1 christos _("cannot represent `%s' relocation in object file"),
6251 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type));
6252 1.1 christos return NULL;
6253 1.1 christos }
6254 1.1 christos
6255 1.1 christos if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
6256 1.1 christos as_fatal (_("internal error? cannot generate `%s' relocation"),
6257 1.1 christos bfd_get_reloc_code_name (fixp->fx_r_type));
6258 1.1 christos
6259 1.1 christos gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
6260 1.1 christos
6261 1.1 christos reloc->addend = fixp->fx_offset;
6262 1.1 christos
6263 1.1 christos #ifdef OBJ_ECOFF
6264 1.1 christos /* Fake out bfd_perform_relocation. sigh. */
6265 1.1 christos /* ??? Better would be to use the special_function hook. */
6266 1.1 christos if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
6267 1.1 christos reloc->addend = -alpha_gp_value;
6268 1.1 christos #endif
6269 1.1 christos
6270 1.1 christos #ifdef OBJ_EVAX
6271 1.1 christos switch (fixp->fx_r_type)
6272 1.1 christos {
6273 1.1 christos struct evax_private_udata_struct *udata;
6274 1.1 christos const char *pname;
6275 1.1 christos int pname_len;
6276 1.1 christos
6277 1.1 christos case BFD_RELOC_ALPHA_LINKAGE:
6278 1.1 christos /* Copy the linkage index. */
6279 1.1 christos reloc->addend = fixp->fx_addnumber;
6280 1.1 christos break;
6281 1.1 christos
6282 1.1 christos case BFD_RELOC_ALPHA_NOP:
6283 1.1 christos case BFD_RELOC_ALPHA_BSR:
6284 1.1 christos case BFD_RELOC_ALPHA_LDA:
6285 1.1 christos case BFD_RELOC_ALPHA_BOH:
6286 1.1 christos pname = symbol_get_bfdsym (fixp->fx_addsy)->name;
6287 1.1 christos
6288 1.1 christos /* We need the non-suffixed name of the procedure. Beware that
6289 1.1 christos the main symbol might be equated so look it up and take its name. */
6290 1.1 christos pname_len = strlen (pname);
6291 1.1 christos if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
6292 1.1 christos {
6293 1.1 christos symbolS *sym;
6294 1.1 christos char *my_pname = (char *) alloca (pname_len - 4 + 1);
6295 1.1 christos
6296 1.1 christos memcpy (my_pname, pname, pname_len - 4);
6297 1.1 christos my_pname [pname_len - 4] = 0;
6298 1.1 christos sym = symbol_find (my_pname);
6299 1.1 christos if (sym == NULL)
6300 1.1 christos abort ();
6301 1.1 christos
6302 1.1 christos while (symbol_equated_reloc_p (sym))
6303 1.1 christos {
6304 1.1 christos symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;
6305 1.1 christos
6306 1.1 christos /* We must avoid looping, as that can occur with a badly
6307 1.1 christos written program. */
6308 1.1 christos if (n == sym)
6309 1.1 christos break;
6310 1.1 christos sym = n;
6311 1.1 christos }
6312 1.1 christos pname = symbol_get_bfdsym (sym)->name;
6313 1.1 christos }
6314 1.1 christos
6315 1.1 christos udata = (struct evax_private_udata_struct *)
6316 1.1 christos xmalloc (sizeof (struct evax_private_udata_struct));
6317 1.1 christos udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy);
6318 1.1 christos udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym);
6319 1.1 christos udata->origname = (char *)pname;
6320 1.1 christos udata->lkindex = ((struct evax_private_udata_struct *)
6321 1.1 christos symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex;
6322 1.1 christos reloc->sym_ptr_ptr = (void *)udata;
6323 1.1 christos reloc->addend = fixp->fx_addnumber;
6324 1.1 christos
6325 1.1 christos default:
6326 1.1 christos break;
6327 1.1 christos }
6328 1.1 christos #endif
6329 1.1 christos
6330 1.1 christos return reloc;
6331 1.1 christos }
6332 1.1 christos
6333 1.1 christos /* Parse a register name off of the input_line and return a register
6334 1.1 christos number. Gets md_undefined_symbol above to do the register name
6335 1.1 christos matching for us.
6336 1.1 christos
6337 1.1 christos Only called as a part of processing the ECOFF .frame directive. */
6338 1.1 christos
6339 1.1 christos int
6340 1.1 christos tc_get_register (int frame ATTRIBUTE_UNUSED)
6341 1.1 christos {
6342 1.1 christos int framereg = AXP_REG_SP;
6343 1.1 christos
6344 1.1 christos SKIP_WHITESPACE ();
6345 1.1 christos if (*input_line_pointer == '$')
6346 1.1 christos {
6347 1.1 christos char *s = input_line_pointer;
6348 1.1 christos char c = get_symbol_end ();
6349 1.1 christos symbolS *sym = md_undefined_symbol (s);
6350 1.1 christos
6351 1.1 christos *strchr (s, '\0') = c;
6352 1.1 christos if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
6353 1.1 christos goto found;
6354 1.1 christos }
6355 1.1 christos as_warn (_("frame reg expected, using $%d."), framereg);
6356 1.1 christos
6357 1.1 christos found:
6358 1.1 christos note_gpreg (framereg);
6359 1.1 christos return framereg;
6360 1.1 christos }
6361 1.1 christos
6362 1.1 christos /* This is called before the symbol table is processed. In order to
6363 1.1 christos work with gcc when using mips-tfile, we must keep all local labels.
6364 1.1 christos However, in other cases, we want to discard them. If we were
6365 1.1 christos called with -g, but we didn't see any debugging information, it may
6366 1.1 christos mean that gcc is smuggling debugging information through to
6367 1.1 christos mips-tfile, in which case we must generate all local labels. */
6368 1.1 christos
6369 1.1 christos #ifdef OBJ_ECOFF
6370 1.1 christos
6371 1.1 christos void
6372 alpha_frob_file_before_adjust (void)
6373 {
6374 if (alpha_debug != 0
6375 && ! ecoff_debugging_seen)
6376 flag_keep_locals = 1;
6377 }
6378
6379 #endif /* OBJ_ECOFF */
6380
6381 /* The Alpha has support for some VAX floating point types, as well as for
6382 IEEE floating point. We consider IEEE to be the primary floating point
6383 format, and sneak in the VAX floating point support here. */
6384 #include "config/atof-vax.c"
6385