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