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