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