]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-alpha.c
* config/tc-alpha.c: Add some static function prototypes.
[thirdparty/binutils-gdb.git] / gas / config / tc-alpha.c
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus Kaempf for EVAX (openVMS/Alpha) support.
8
9 This file is part of GAS, the GNU Assembler.
10
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
25
26 /*
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
30 *
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
36 *
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 *
41 * Carnegie Mellon requests users of this software to return to
42 *
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
47 *
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
50 */
51
52 #include "as.h"
53 #include "subsegs.h"
54
55 #include "opcode/alpha.h"
56
57 #ifdef OBJ_ELF
58 #include "elf/alpha.h"
59 #endif
60
61 #include <ctype.h>
62
63 \f
64 /* Local types */
65
66 #define MAX_INSN_FIXUPS 2
67 #define MAX_INSN_ARGS 5
68
69 struct alpha_fixup
70 {
71 expressionS exp;
72 bfd_reloc_code_real_type reloc;
73 };
74
75 struct alpha_insn
76 {
77 unsigned insn;
78 int nfixups;
79 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
80 };
81
82 enum alpha_macro_arg
83 {
84 MACRO_EOA = 1, MACRO_IR, MACRO_PIR, MACRO_CPIR, MACRO_FPR, MACRO_EXP
85 };
86
87 struct alpha_macro
88 {
89 const char *name;
90 void (*emit) PARAMS((const expressionS *, int, void *));
91 void *arg;
92 enum alpha_macro_arg argsets[16];
93 };
94
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
97
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + a leading comma */
100
101 /* Macros for extracting the type and number of encoded register tokens */
102
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
106
107 /* Something odd inherited from the old assembler */
108
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
111
112 /* Predicates for 16- and 32-bit ranges */
113
114 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
115 (offsetT)(x) <= (offsetT)0x7FFF)
116 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
117 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
118
119 /* Macros for sign extending from 16- and 32-bits. */
120 /* XXX: The cast macros will work on all the systems that I care about,
121 but really a predicate should be found to use the non-cast forms. */
122
123 #if 1
124 #define sign_extend_16(x) ((short)(x))
125 #define sign_extend_32(x) ((int)(x))
126 #else
127 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
128 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
129 ^ 0x80000000) - 0x80000000)
130 #endif
131
132 /* Macros to build tokens */
133
134 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
135 (t).X_op = O_register, \
136 (t).X_add_number = (r))
137 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
138 (t).X_op = O_pregister, \
139 (t).X_add_number = (r))
140 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
141 (t).X_op = O_cpregister, \
142 (t).X_add_number = (r))
143 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r)+32)
146 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_symbol, \
148 (t).X_add_symbol = (s), \
149 (t).X_add_number = (a))
150 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
151 (t).X_op = O_constant, \
152 (t).X_add_number = (n))
153
154 \f
155 /* Prototypes for all local functions */
156
157 static int tokenize_arguments PARAMS((char *, expressionS*, int));
158 static const struct alpha_opcode *find_opcode_match
159 PARAMS((const struct alpha_opcode*, const expressionS*, int*, int*));
160 static const struct alpha_macro *find_macro_match
161 PARAMS((const struct alpha_macro*, const expressionS*, int*));
162 static unsigned insert_operand PARAMS((unsigned, const struct alpha_operand*,
163 offsetT, char *, unsigned));
164 static void assemble_insn PARAMS((const struct alpha_opcode*,
165 const expressionS*, int,
166 struct alpha_insn*));
167 static void emit_insn PARAMS((struct alpha_insn *));
168 static void assemble_tokens_to_insn PARAMS((const char *, const expressionS*,
169 int, struct alpha_insn *));
170 static void assemble_tokens PARAMS((const char *, const expressionS*,
171 int, int));
172
173 static int load_expression PARAMS((int, const expressionS*, int *,
174 expressionS*));
175
176 static void emit_ldgp PARAMS((const expressionS*, int, void*));
177 static void emit_division PARAMS((const expressionS*, int, void*));
178 static void emit_lda PARAMS((const expressionS*, int, void*));
179 static void emit_ldah PARAMS((const expressionS*, int, void*));
180 static void emit_ir_load PARAMS((const expressionS*, int, void*));
181 static void emit_loadstore PARAMS((const expressionS*, int, void*));
182 static void emit_jsrjmp PARAMS((const expressionS*, int, void*));
183 static void emit_ldX PARAMS((const expressionS*, int, void*));
184 static void emit_ldXu PARAMS((const expressionS*, int, void*));
185 static void emit_uldX PARAMS((const expressionS*, int, void*));
186 static void emit_uldXu PARAMS((const expressionS*, int, void*));
187 static void emit_ldil PARAMS((const expressionS*, int, void*));
188 static void emit_stX PARAMS((const expressionS*, int, void*));
189 static void emit_ustX PARAMS((const expressionS*, int, void*));
190 static void emit_sextX PARAMS((const expressionS*, int, void*));
191 static void emit_retjcr PARAMS((const expressionS*, int, void*));
192
193 static void s_alpha_text PARAMS((int));
194 static void s_alpha_data PARAMS((int));
195 #ifndef OBJ_ELF
196 static void s_alpha_comm PARAMS((int));
197 #endif
198 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
199 static void s_alpha_rdata PARAMS((int));
200 #endif
201 #ifdef OBJ_ECOFF
202 static void s_alpha_sdata PARAMS((int));
203 #endif
204 #ifdef OBJ_ELF
205 static void s_alpha_section PARAMS((int));
206 #endif
207 static void s_alpha_gprel32 PARAMS((int));
208 static void s_alpha_float_cons PARAMS((int));
209 static void s_alpha_proc PARAMS((int));
210 static void s_alpha_set PARAMS((int));
211 static void s_alpha_base PARAMS((int));
212 static void s_alpha_align PARAMS((int));
213 static void s_alpha_stringer PARAMS((int));
214 static void s_alpha_space PARAMS((int));
215
216 static void create_literal_section PARAMS((const char *, segT*, symbolS**));
217 #ifndef OBJ_ELF
218 static void select_gp_value PARAMS((void));
219 #endif
220 static void alpha_align PARAMS((int, char *, symbolS *));
221
222 \f
223 /* Generic assembler global variables which must be defined by all
224 targets. */
225
226 /* These are exported to relaxing code, even though we don't do any
227 relaxing on this processor currently. */
228 int md_short_jump_size = 4;
229 int md_long_jump_size = 4;
230
231 /* Characters which always start a comment. */
232 const char comment_chars[] = "#";
233
234 /* Characters which start a comment at the beginning of a line. */
235 const char line_comment_chars[] = "#";
236
237 /* Characters which may be used to separate multiple commands on a
238 single line. */
239 const char line_separator_chars[] = ";";
240
241 /* Characters which are used to indicate an exponent in a floating
242 point number. */
243 const char EXP_CHARS[] = "eE";
244
245 /* Characters which mean that a number is a floating point constant,
246 as in 0d1.0. */
247 #if 0
248 const char FLT_CHARS[] = "dD";
249 #else
250 /* XXX: Do all of these really get used on the alpha?? */
251 char FLT_CHARS[] = "rRsSfFdDxXpP";
252 #endif
253
254 const char *md_shortopts = "Fm:g";
255
256 struct option md_longopts[] = {
257 #define OPTION_32ADDR (OPTION_MD_BASE)
258 { "32addr", no_argument, NULL, OPTION_32ADDR },
259 { NULL, no_argument, NULL, 0 }
260 };
261
262 size_t md_longopts_size = sizeof(md_longopts);
263
264 \f
265 /* The cpu for which we are generating code */
266 static unsigned alpha_target = AXP_OPCODE_ALL;
267 static const char *alpha_target_name = "<all>";
268
269 /* The hash table of instruction opcodes */
270 static struct hash_control *alpha_opcode_hash;
271
272 /* The hash table of macro opcodes */
273 static struct hash_control *alpha_macro_hash;
274
275 #ifdef OBJ_ECOFF
276 /* The $gp relocation symbol */
277 static symbolS *alpha_gp_symbol;
278
279 /* XXX: what is this, and why is it exported? */
280 valueT alpha_gp_value;
281 #endif
282
283 /* The current $gp register */
284 static int alpha_gp_register = AXP_REG_GP;
285
286 /* A table of the register symbols */
287 static symbolS *alpha_register_table[64];
288
289 /* Constant sections, or sections of constants */
290 #ifdef OBJ_ECOFF
291 static segT alpha_lita_section;
292 static segT alpha_lit4_section;
293 #endif
294 #ifdef OBJ_EVAX
295 static segT alpha_link_section;
296 #endif
297 static segT alpha_lit8_section;
298
299 /* Symbols referring to said sections. */
300 #ifdef OBJ_ECOFF
301 static symbolS *alpha_lita_symbol;
302 static symbolS *alpha_lit4_symbol;
303 #endif
304 #ifdef OBJ_EVAX
305 static symbolS *alpha_link_symbol;
306 #endif
307 static symbolS *alpha_lit8_symbol;
308
309 /* Is the assembler not allowed to use $at? */
310 static int alpha_noat_on = 0;
311
312 /* Are macros enabled? */
313 static int alpha_macros_on = 1;
314
315 /* Are floats disabled? */
316 static int alpha_nofloats_on = 0;
317
318 /* Are addresses 32 bit? */
319 static int alpha_addr32_on = 0;
320
321 /* Symbol labelling the current insn. When the Alpha gas sees
322 foo:
323 .quad 0
324 and the section happens to not be on an eight byte boundary, it
325 will align both the symbol and the .quad to an eight byte boundary. */
326 static symbolS *alpha_insn_label;
327
328 /* Whether we should automatically align data generation pseudo-ops.
329 .align 0 will turn this off. */
330 static int alpha_auto_align_on = 1;
331
332 /* The known current alignment of the current section. */
333 static int alpha_current_align;
334
335 /* These are exported to ECOFF code. */
336 unsigned long alpha_gprmask, alpha_fprmask;
337
338 #ifdef OBJ_EVAX
339 /* Collect information about current procedure here. */
340 static evaxProcT alpha_evax_proc;
341 #endif
342 \f
343 /* The macro table */
344
345 static const struct alpha_macro alpha_macros[] = {
346 /* Load/Store macros */
347 { "lda", emit_lda, NULL,
348 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
349 MACRO_IR, MACRO_EXP, MACRO_EOA } },
350 { "ldah", emit_ldah, NULL,
351 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
352
353 { "ldl", emit_ir_load, "ldl",
354 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
355 MACRO_IR, MACRO_EXP, MACRO_EOA } },
356 { "ldl_l", emit_ir_load, "ldl_l",
357 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
358 MACRO_IR, MACRO_EXP, MACRO_EOA } },
359 { "ldq", emit_ir_load, "ldq",
360 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
361 MACRO_IR, MACRO_EXP, MACRO_EOA } },
362 { "ldq_l", emit_ir_load, "ldq_l",
363 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
364 MACRO_IR, MACRO_EXP, MACRO_EOA } },
365 { "ldq_u", emit_ir_load, "ldq_u",
366 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
367 MACRO_IR, MACRO_EXP, MACRO_EOA } },
368 { "ldf", emit_loadstore, "ldf",
369 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
370 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
371 { "ldg", emit_loadstore, "ldg",
372 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
373 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
374 { "lds", emit_loadstore, "lds",
375 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
376 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
377 { "ldt", emit_loadstore, "ldt",
378 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
379 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
380
381 { "ldb", emit_ldX, (void *)0,
382 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
383 MACRO_IR, MACRO_EXP, MACRO_EOA } },
384 { "ldbu", emit_ldXu, (void *)0,
385 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
386 MACRO_IR, MACRO_EXP, MACRO_EOA } },
387 { "ldw", emit_ldX, (void *)1,
388 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
389 MACRO_IR, MACRO_EXP, MACRO_EOA } },
390 { "ldwu", emit_ldXu, (void *)1,
391 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
392 MACRO_IR, MACRO_EXP, MACRO_EOA } },
393
394 { "uldw", emit_uldX, (void*)1,
395 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
396 MACRO_IR, MACRO_EXP, MACRO_EOA } },
397 { "uldwu", emit_uldXu, (void*)1,
398 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
399 MACRO_IR, MACRO_EXP, MACRO_EOA } },
400 { "uldl", emit_uldX, (void*)2,
401 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
402 MACRO_IR, MACRO_EXP, MACRO_EOA } },
403 { "uldlu", emit_uldXu, (void*)2,
404 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
405 MACRO_IR, MACRO_EXP, MACRO_EOA } },
406 { "uldq", emit_uldXu, (void*)3,
407 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
408 MACRO_IR, MACRO_EXP, MACRO_EOA } },
409
410 { "ldgp", emit_ldgp, NULL,
411 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
412
413 { "ldi", emit_lda, NULL,
414 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
415 { "ldil", emit_ldil, NULL,
416 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
417 { "ldiq", emit_lda, NULL,
418 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
419 #if 0
420 { "ldif" emit_ldiq, NULL,
421 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
422 { "ldid" emit_ldiq, NULL,
423 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
424 { "ldig" emit_ldiq, NULL,
425 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
426 { "ldis" emit_ldiq, NULL,
427 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
428 { "ldit" emit_ldiq, NULL,
429 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
430 #endif
431
432 { "stl", emit_loadstore, "stl",
433 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
434 MACRO_IR, MACRO_EXP, MACRO_EOA } },
435 { "stl_c", emit_loadstore, "stl_c",
436 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
437 MACRO_IR, MACRO_EXP, MACRO_EOA } },
438 { "stq", emit_loadstore, "stq",
439 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
440 MACRO_IR, MACRO_EXP, MACRO_EOA } },
441 { "stq_c", emit_loadstore, "stq_c",
442 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
443 MACRO_IR, MACRO_EXP, MACRO_EOA } },
444 { "stq_u", emit_loadstore, "stq_u",
445 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
446 MACRO_IR, MACRO_EXP, MACRO_EOA } },
447 { "stf", emit_loadstore, "stf",
448 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
449 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
450 { "stg", emit_loadstore, "stg",
451 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
452 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
453 { "sts", emit_loadstore, "sts",
454 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
455 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
456 { "stt", emit_loadstore, "stt",
457 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
458 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
459
460 { "stb", emit_stX, (void*)0,
461 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
462 MACRO_IR, MACRO_EXP, MACRO_EOA } },
463 { "stw", emit_stX, (void*)1,
464 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
465 MACRO_IR, MACRO_EXP, MACRO_EOA } },
466 { "ustw", emit_ustX, (void*)1,
467 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
468 MACRO_IR, MACRO_EXP, MACRO_EOA } },
469 { "ustl", emit_ustX, (void*)2,
470 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
471 MACRO_IR, MACRO_EXP, MACRO_EOA } },
472 { "ustq", emit_ustX, (void*)3,
473 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
474 MACRO_IR, MACRO_EXP, MACRO_EOA } },
475
476 /* Arithmetic macros */
477 #if 0
478 { "absl" emit_absl, 1, { IR } },
479 { "absl" emit_absl, 2, { IR, IR } },
480 { "absl" emit_absl, 2, { EXP, IR } },
481 { "absq" emit_absq, 1, { IR } },
482 { "absq" emit_absq, 2, { IR, IR } },
483 { "absq" emit_absq, 2, { EXP, IR } },
484 #endif
485
486 { "sextb", emit_sextX, (void *)0,
487 { MACRO_IR, MACRO_IR, MACRO_EOA,
488 MACRO_IR, MACRO_EOA,
489 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
490 { "sextw", emit_sextX, (void *)1,
491 { MACRO_IR, MACRO_IR, MACRO_EOA,
492 MACRO_IR, MACRO_EOA,
493 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
494
495 { "divl", emit_division, "__divl",
496 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
497 MACRO_IR, MACRO_IR, MACRO_EOA,
498 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
499 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
500 { "divlu", emit_division, "__divlu",
501 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
502 MACRO_IR, MACRO_IR, MACRO_EOA,
503 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
504 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
505 { "divq", emit_division, "__divq",
506 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
507 MACRO_IR, MACRO_IR, MACRO_EOA,
508 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
509 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
510 { "divqu", emit_division, "__divqu",
511 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
512 MACRO_IR, MACRO_IR, MACRO_EOA,
513 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
514 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
515 { "reml", emit_division, "__reml",
516 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
517 MACRO_IR, MACRO_IR, MACRO_EOA,
518 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
519 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
520 { "remlu", emit_division, "__remlu",
521 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
522 MACRO_IR, MACRO_IR, MACRO_EOA,
523 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
524 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
525 { "remq", emit_division, "__remq",
526 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
527 MACRO_IR, MACRO_IR, MACRO_EOA,
528 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
529 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
530 { "remqu", emit_division, "__remqu",
531 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
532 MACRO_IR, MACRO_IR, MACRO_EOA,
533 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
534 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
535
536 { "jsr", emit_jsrjmp, "jsr",
537 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
538 MACRO_PIR, MACRO_EOA,
539 MACRO_IR, MACRO_EXP, MACRO_EOA,
540 MACRO_EXP, MACRO_EOA } },
541 { "jmp", emit_jsrjmp, "jmp",
542 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
543 MACRO_PIR, MACRO_EOA,
544 MACRO_IR, MACRO_EXP, MACRO_EOA,
545 MACRO_EXP, MACRO_EOA } },
546 { "ret", emit_retjcr, "ret",
547 { MACRO_IR, MACRO_EXP, MACRO_EOA,
548 MACRO_IR, MACRO_EOA,
549 MACRO_PIR, MACRO_EXP, MACRO_EOA,
550 MACRO_PIR, MACRO_EOA,
551 MACRO_EXP, MACRO_EOA,
552 MACRO_EOA } },
553 { "jcr", emit_retjcr, "jcr",
554 { MACRO_IR, MACRO_EXP, MACRO_EOA,
555 MACRO_IR, MACRO_EOA,
556 MACRO_PIR, MACRO_EXP, MACRO_EOA,
557 MACRO_PIR, MACRO_EOA,
558 MACRO_EXP, MACRO_EOA,
559 MACRO_EOA } },
560 { "jsr_coroutine", emit_retjcr, "jcr",
561 { MACRO_IR, MACRO_EXP, MACRO_EOA,
562 MACRO_IR, MACRO_EOA,
563 MACRO_PIR, MACRO_EXP, MACRO_EOA,
564 MACRO_PIR, MACRO_EOA,
565 MACRO_EXP, MACRO_EOA,
566 MACRO_EOA } },
567 };
568
569 static const int alpha_num_macros
570 = sizeof(alpha_macros) / sizeof(*alpha_macros);
571 \f
572 /* Public interface functions */
573
574 /* This function is called once, at assembler startup time. It sets
575 up all the tables, etc. that the MD part of the assembler will
576 need, that can be determined before arguments are parsed. */
577
578 void
579 md_begin ()
580 {
581 unsigned int i = 0;
582
583 /* Create the opcode hash table */
584
585 alpha_opcode_hash = hash_new ();
586 for (i = 0; i < alpha_num_opcodes; )
587 {
588 const char *name, *retval;
589
590 name = alpha_opcodes[i].name;
591 retval = hash_insert (alpha_opcode_hash, name, (PTR)&alpha_opcodes[i]);
592 if (retval)
593 as_fatal ("internal error: can't hash opcode `%s': %s", name, retval);
594
595 while (++i < alpha_num_opcodes
596 && (alpha_opcodes[i].name == name
597 || !strcmp (alpha_opcodes[i].name, name)))
598 continue;
599 }
600
601 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
602 like the architecture manual suggests. However, for use with gcc at
603 least, we also need access to those same opcodes without the "/". */
604 for (i = 0; i < alpha_num_opcodes; )
605 {
606 const char *name, *slash;
607 name = alpha_opcodes[i].name;
608 if ((slash = strchr(name, '/')) != NULL)
609 {
610 char *p = xmalloc (strlen (name));
611 memcpy(p, name, slash-name);
612 strcpy(p+(slash-name), slash+1);
613
614 (void)hash_insert(alpha_opcode_hash, p, (PTR)&alpha_opcodes[i]);
615 /* Ignore failures -- the opcode table does duplicate some
616 variants in different forms, like "hw_stq" and "hw_st/q". */
617 }
618
619 while (++i < alpha_num_opcodes
620 && (alpha_opcodes[i].name == name
621 || !strcmp (alpha_opcodes[i].name, name)))
622 continue;
623 }
624
625 /* Create the macro hash table */
626
627 alpha_macro_hash = hash_new ();
628 for (i = 0; i < alpha_num_macros; )
629 {
630 const char *name, *retval;
631
632 name = alpha_macros[i].name;
633 retval = hash_insert (alpha_macro_hash, name, (PTR)&alpha_macros[i]);
634 if (retval)
635 as_fatal ("internal error: can't hash macro `%s': %s", name, retval);
636
637 while (++i < alpha_num_macros
638 && (alpha_macros[i].name == name
639 || !strcmp (alpha_macros[i].name, name)))
640 continue;
641 }
642
643 /* Construct symbols for each of the registers */
644
645 for (i = 0; i < 32; ++i)
646 {
647 char name[4];
648 sprintf(name, "$%d", i);
649 alpha_register_table[i] = symbol_create(name, reg_section, i,
650 &zero_address_frag);
651 }
652 for (; i < 64; ++i)
653 {
654 char name[5];
655 sprintf(name, "$f%d", i-32);
656 alpha_register_table[i] = symbol_create(name, reg_section, i,
657 &zero_address_frag);
658 }
659
660 /* Create the special symbols and sections we'll be using */
661
662 /* So .sbss will get used for tiny objects. */
663 bfd_set_gp_size (stdoutput, 8);
664
665 #ifdef OBJ_ECOFF
666 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
667
668 /* For handling the GP, create a symbol that won't be output in the
669 symbol table. We'll edit it out of relocs later. */
670 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
671 &zero_address_frag);
672 #endif
673
674 #ifdef OBJ_EVAX
675 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
676 #endif
677
678 #ifdef OBJ_ELF
679 if (ECOFF_DEBUGGING)
680 {
681 segT sec;
682
683 sec = subseg_new(".mdebug", (subsegT)0);
684 bfd_set_section_flags(stdoutput, sec, SEC_HAS_CONTENTS|SEC_READONLY);
685 bfd_set_section_alignment(stdoutput, sec, 3);
686
687 #ifdef ERIC_neverdef
688 sec = subseg_new(".reginfo", (subsegT)0);
689 /* The ABI says this section should be loaded so that the running
690 program can access it. */
691 bfd_set_section_flags(stdoutput, sec,
692 SEC_ALLOC|SEC_LOAD|SEC_READONLY|SEC_DATA);
693 bfd_set_section_alignement(stdoutput, sec, 3);
694 #endif
695 }
696 #endif /* OBJ_ELF */
697
698 subseg_set(text_section, 0);
699 }
700
701 /* The public interface to the instruction assembler. */
702
703 void
704 md_assemble (str)
705 char *str;
706 {
707 char opname[32]; /* current maximum is 13 */
708 expressionS tok[MAX_INSN_ARGS];
709 int ntok, opnamelen, trunclen;
710
711 /* split off the opcode */
712 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/48");
713 trunclen = (opnamelen < sizeof (opname) - 1
714 ? opnamelen
715 : sizeof (opname) - 1);
716 memcpy (opname, str, trunclen);
717 opname[trunclen] = '\0';
718
719 /* tokenize the rest of the line */
720 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
721 {
722 as_bad ("syntax error");
723 return;
724 }
725
726 /* finish it off */
727 assemble_tokens (opname, tok, ntok, alpha_macros_on);
728 }
729
730 /* Round up a section's size to the appropriate boundary. */
731
732 valueT
733 md_section_align (seg, size)
734 segT seg;
735 valueT size;
736 {
737 int align = bfd_get_section_alignment(stdoutput, seg);
738 valueT mask = ((valueT)1 << align) - 1;
739
740 return (size + mask) & ~mask;
741 }
742
743 /* Turn a string in input_line_pointer into a floating point constant
744 of type type, and store the appropriate bytes in *litP. The number
745 of LITTLENUMS emitted is stored in *sizeP. An error message is
746 returned, or NULL on OK. */
747
748 /* Equal to MAX_PRECISION in atof-ieee.c */
749 #define MAX_LITTLENUMS 6
750
751 char *
752 md_atof (type, litP, sizeP)
753 char type;
754 char *litP;
755 int *sizeP;
756 {
757 int prec;
758 LITTLENUM_TYPE words[MAX_LITTLENUMS];
759 LITTLENUM_TYPE *wordP;
760 char *t;
761 char *atof_ieee (), *vax_md_atof ();
762
763 switch (type)
764 {
765 /* VAX floats */
766 case 'G':
767 /* VAX md_atof doesn't like "G" for some reason. */
768 type = 'g';
769 case 'F':
770 case 'D':
771 return vax_md_atof (type, litP, sizeP);
772
773 /* IEEE floats */
774 case 'f':
775 prec = 2;
776 break;
777
778 case 'd':
779 prec = 4;
780 break;
781
782 case 'x':
783 case 'X':
784 prec = 6;
785 break;
786
787 case 'p':
788 case 'P':
789 prec = 6;
790 break;
791
792 default:
793 *sizeP = 0;
794 return "Bad call to MD_ATOF()";
795 }
796 t = atof_ieee (input_line_pointer, type, words);
797 if (t)
798 input_line_pointer = t;
799 *sizeP = prec * sizeof (LITTLENUM_TYPE);
800
801 for (wordP = words + prec - 1; prec--;)
802 {
803 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
804 litP += sizeof (LITTLENUM_TYPE);
805 }
806
807 return 0;
808 }
809
810 /* Take care of the target-specific command-line options. */
811
812 int
813 md_parse_option (c, arg)
814 int c;
815 char *arg;
816 {
817 switch (c)
818 {
819 case 'F':
820 alpha_nofloats_on = 1;
821 break;
822
823 case OPTION_32ADDR:
824 alpha_addr32_on = 1;
825 break;
826
827 case 'g':
828 /* Ignore `-g' so gcc can provide this option to the Digital
829 UNIX assembler, which otherwise would throw away info that
830 mips-tfile needs. */
831 break;
832
833 case 'm':
834 {
835 static const struct machine
836 {
837 const char *name;
838 unsigned flags;
839 } *p, m[] =
840 {
841 { "21064", AXP_OPCODE_EV4|AXP_OPCODE_ALL },
842 { "21066", AXP_OPCODE_EV4|AXP_OPCODE_ALL },
843 { "21164", AXP_OPCODE_EV5|AXP_OPCODE_ALL },
844 { "21164a", AXP_OPCODE_EV56|AXP_OPCODE_ALL },
845 { "ev4", AXP_OPCODE_EV4|AXP_OPCODE_ALL },
846 { "ev45", AXP_OPCODE_EV4|AXP_OPCODE_ALL },
847 { "ev5", AXP_OPCODE_EV5|AXP_OPCODE_ALL },
848 { "ev56", AXP_OPCODE_EV56|AXP_OPCODE_ALL },
849 { "all", AXP_OPCODE_ALL },
850 { 0 }
851 };
852
853 for (p = m; p->name; ++p)
854 if (strcmp(arg, p->name) == 0)
855 {
856 alpha_target_name = p->name, alpha_target = p->flags;
857 goto found;
858 }
859 as_warn("Unknown CPU identifier `%s'", arg);
860 found:;
861 }
862 break;
863
864 default:
865 return 0;
866 }
867
868 return 1;
869 }
870
871 /* Print a description of the command-line options that we accept. */
872
873 void
874 md_show_usage (stream)
875 FILE *stream;
876 {
877 fputs("\
878 Alpha options:\n\
879 -32addr treat addresses as 32-bit values\n\
880 -F lack floating point instructions support\n\
881 -m21064 | -m21066 | -m21164 | -m21164a\n\
882 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
883 specify variant of Alpha architecture\n",
884 stream);
885 }
886
887 /* Decide from what point a pc-relative relocation is relative to,
888 relative to the pc-relative fixup. Er, relatively speaking. */
889
890 long
891 md_pcrel_from (fixP)
892 fixS *fixP;
893 {
894 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
895 switch (fixP->fx_r_type)
896 {
897 case BFD_RELOC_ALPHA_GPDISP:
898 case BFD_RELOC_ALPHA_GPDISP_HI16:
899 case BFD_RELOC_ALPHA_GPDISP_LO16:
900 return addr;
901 default:
902 return fixP->fx_size + addr;
903 }
904 }
905
906 /* Attempt to simplify or even eliminate a fixup. The return value is
907 ignored; perhaps it was once meaningful, but now it is historical.
908 To indicate that a fixup has been eliminated, set fixP->fx_done.
909
910 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
911 internally into the GPDISP reloc used externally. We had to do
912 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
913 the distance to the "lda" instruction for setting the addend to
914 GPDISP. */
915
916 int
917 md_apply_fix (fixP, valueP)
918 fixS *fixP;
919 valueT *valueP;
920 {
921 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
922 valueT value = *valueP;
923 unsigned image, size;
924
925 switch (fixP->fx_r_type)
926 {
927 /* The GPDISP relocations are processed internally with a symbol
928 referring to the current function; we need to drop in a value
929 which, when added to the address of the start of the function,
930 gives the desired GP. */
931 case BFD_RELOC_ALPHA_GPDISP_HI16:
932 {
933 fixS *next = fixP->fx_next;
934 assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
935
936 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
937 - fixP->fx_frag->fr_address - fixP->fx_where);
938
939 value = (value - sign_extend_16 (value)) >> 16;
940 }
941 #ifdef OBJ_ELF
942 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
943 #endif
944 goto do_reloc_gp;
945
946 case BFD_RELOC_ALPHA_GPDISP_LO16:
947 value = sign_extend_16 (value);
948 fixP->fx_offset = 0;
949 #ifdef OBJ_ELF
950 fixP->fx_done = 1;
951 #endif
952
953 do_reloc_gp:
954 fixP->fx_addsy = section_symbol (absolute_section);
955 md_number_to_chars (fixpos, value, 2);
956 break;
957
958 case BFD_RELOC_16:
959 size = 2;
960 goto do_reloc_xx;
961 case BFD_RELOC_32:
962 size = 4;
963 goto do_reloc_xx;
964 case BFD_RELOC_64:
965 size = 8;
966 do_reloc_xx:
967 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
968 {
969 md_number_to_chars (fixpos, value, size);
970 goto done;
971 }
972 return 1;
973
974 #ifdef OBJ_ECOFF
975 case BFD_RELOC_GPREL32:
976 assert (fixP->fx_subsy == alpha_gp_symbol);
977 fixP->fx_subsy = 0;
978 /* FIXME: inherited this obliviousness of `value' -- why? */
979 md_number_to_chars (fixpos, -alpha_gp_value, 4);
980 break;
981 #endif
982 #ifdef OBJ_ELF
983 case BFD_RELOC_GPREL32:
984 return 1;
985 #endif
986
987 case BFD_RELOC_23_PCREL_S2:
988 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
989 {
990 image = bfd_getl32(fixpos);
991 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
992 goto write_done;
993 }
994 return 1;
995
996 case BFD_RELOC_ALPHA_HINT:
997 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
998 {
999 image = bfd_getl32(fixpos);
1000 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1001 goto write_done;
1002 }
1003 return 1;
1004
1005 #ifdef OBJ_ECOFF
1006 case BFD_RELOC_ALPHA_LITERAL:
1007 md_number_to_chars (fixpos, value, 2);
1008 return 1;
1009
1010 case BFD_RELOC_ALPHA_LITUSE:
1011 return 1;
1012 #endif
1013 #ifdef OBJ_ELF
1014 case BFD_RELOC_ALPHA_LITERAL:
1015 case BFD_RELOC_ALPHA_LITUSE:
1016 return 1;
1017 #endif
1018 #ifdef OBJ_EVAX
1019 case BFD_RELOC_ALPHA_LINKAGE:
1020 return 1;
1021 #endif
1022
1023 default:
1024 {
1025 const struct alpha_operand *operand;
1026
1027 if (fixP->fx_r_type <= BFD_RELOC_UNUSED)
1028 as_fatal ("unhandled relocation type %s",
1029 bfd_get_reloc_code_name (fixP->fx_r_type));
1030
1031 assert (fixP->fx_r_type < BFD_RELOC_UNUSED + alpha_num_operands);
1032 operand = &alpha_operands[fixP->fx_r_type - BFD_RELOC_UNUSED];
1033
1034 /* The rest of these fixups only exist internally during symbol
1035 resolution and have no representation in the object file.
1036 Therefore they must be completely resolved as constants. */
1037
1038 if (fixP->fx_addsy != 0
1039 && fixP->fx_addsy->bsym->section != absolute_section)
1040 as_bad_where (fixP->fx_file, fixP->fx_line,
1041 "non-absolute expression in constant field");
1042
1043 image = bfd_getl32(fixpos);
1044 image = insert_operand(image, operand, (offsetT)value,
1045 fixP->fx_file, fixP->fx_line);
1046 }
1047 goto write_done;
1048 }
1049
1050 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1051 return 1;
1052 else
1053 {
1054 as_warn_where(fixP->fx_file, fixP->fx_line,
1055 "type %d reloc done?\n", fixP->fx_r_type);
1056 goto done;
1057 }
1058
1059 write_done:
1060 md_number_to_chars(fixpos, image, 4);
1061
1062 done:
1063 fixP->fx_done = 1;
1064 return 0;
1065 }
1066
1067 /*
1068 * Look for a register name in the given symbol.
1069 */
1070
1071 symbolS *
1072 md_undefined_symbol(name)
1073 char *name;
1074 {
1075 if (*name == '$')
1076 {
1077 int is_float = 0, num;
1078
1079 switch (*++name)
1080 {
1081 case 'f':
1082 if (name[1] == 'p' && name[2] == '\0')
1083 return alpha_register_table[AXP_REG_FP];
1084 is_float = 32;
1085 /* FALLTHRU */
1086
1087 case 'r':
1088 if (!isdigit(*++name))
1089 break;
1090 /* FALLTHRU */
1091
1092 case '0': case '1': case '2': case '3': case '4':
1093 case '5': case '6': case '7': case '8': case '9':
1094 if (name[1] == '\0')
1095 num = name[0] - '0';
1096 else if (name[0] != '0' && isdigit(name[1]) && name[2] == '\0')
1097 {
1098 num = (name[0] - '0')*10 + name[1] - '0';
1099 if (num >= 32)
1100 break;
1101 }
1102 else
1103 break;
1104
1105 if (!alpha_noat_on && num == AXP_REG_AT)
1106 as_warn("Used $at without \".set noat\"");
1107 return alpha_register_table[num + is_float];
1108
1109 case 'a':
1110 if (name[1] == 't' && name[2] == '\0')
1111 {
1112 if (!alpha_noat_on)
1113 as_warn("Used $at without \".set noat\"");
1114 return alpha_register_table[AXP_REG_AT];
1115 }
1116 break;
1117
1118 case 'g':
1119 if (name[1] == 'p' && name[2] == '\0')
1120 return alpha_register_table[alpha_gp_register];
1121 break;
1122
1123 case 's':
1124 if (name[1] == 'p' && name[2] == '\0')
1125 return alpha_register_table[AXP_REG_SP];
1126 break;
1127 }
1128 }
1129 return NULL;
1130 }
1131
1132 #ifdef OBJ_ECOFF
1133 /* @@@ Magic ECOFF bits. */
1134
1135 void
1136 alpha_frob_ecoff_data ()
1137 {
1138 select_gp_value ();
1139 /* $zero and $f31 are read-only */
1140 alpha_gprmask &= ~1;
1141 alpha_fprmask &= ~1;
1142 }
1143 #endif
1144
1145 /* Hook to remember a recently defined label so that the auto-align
1146 code can adjust the symbol after we know what alignment will be
1147 required. */
1148
1149 void
1150 alpha_define_label (sym)
1151 symbolS *sym;
1152 {
1153 alpha_insn_label = sym;
1154 }
1155
1156 /* Return true if we must always emit a reloc for a type and false if
1157 there is some hope of resolving it a assembly time. */
1158
1159 int
1160 alpha_force_relocation (f)
1161 fixS *f;
1162 {
1163 switch (f->fx_r_type)
1164 {
1165 case BFD_RELOC_ALPHA_GPDISP_HI16:
1166 case BFD_RELOC_ALPHA_GPDISP_LO16:
1167 case BFD_RELOC_ALPHA_GPDISP:
1168 case BFD_RELOC_ALPHA_LITERAL:
1169 case BFD_RELOC_ALPHA_LITUSE:
1170 case BFD_RELOC_GPREL32:
1171 #ifdef OBJ_EVAX
1172 case BFD_RELOC_ALPHA_LINKAGE:
1173 #endif
1174 return 1;
1175
1176 case BFD_RELOC_23_PCREL_S2:
1177 case BFD_RELOC_32:
1178 case BFD_RELOC_64:
1179 case BFD_RELOC_ALPHA_HINT:
1180 return 0;
1181
1182 default:
1183 assert(f->fx_r_type > BFD_RELOC_UNUSED &&
1184 f->fx_r_type < BFD_RELOC_UNUSED + alpha_num_operands);
1185 return 0;
1186 }
1187 }
1188
1189 /* Return true if we can partially resolve a relocation now. */
1190
1191 int
1192 alpha_fix_adjustable (f)
1193 fixS *f;
1194 {
1195 #ifdef OBJ_ELF
1196 /* Prevent all adjustments to global symbols */
1197 if (S_IS_EXTERN (f->fx_addsy))
1198 return 0;
1199 #endif
1200
1201 /* Are there any relocation types for which we must generate a reloc
1202 but we can adjust the values contained within it? */
1203 switch (f->fx_r_type)
1204 {
1205 case BFD_RELOC_GPREL32:
1206 return 1;
1207 default:
1208 return !alpha_force_relocation (f);
1209 }
1210 /*NOTREACHED*/
1211 }
1212
1213 /* Generate the BFD reloc to be stuck in the object file from the
1214 fixup used internally in the assembler. */
1215
1216 arelent *
1217 tc_gen_reloc (sec, fixp)
1218 asection *sec;
1219 fixS *fixp;
1220 {
1221 arelent *reloc;
1222
1223 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
1224 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1225 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1226
1227 /* Make sure none of our internal relocations make it this far.
1228 They'd better have been fully resolved by this point. */
1229 assert (fixp->fx_r_type < BFD_RELOC_UNUSED);
1230
1231 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1232 if (reloc->howto == NULL)
1233 {
1234 as_bad_where (fixp->fx_file, fixp->fx_line,
1235 "cannot represent `%s' relocation in object file",
1236 bfd_get_reloc_code_name (fixp->fx_r_type));
1237 return NULL;
1238 }
1239
1240 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1241 {
1242 as_fatal ("internal error? cannot generate `%s' relocation",
1243 bfd_get_reloc_code_name (fixp->fx_r_type));
1244 }
1245 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1246
1247 #ifdef OBJ_ECOFF
1248 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1249 {
1250 /* fake out bfd_perform_relocation. sigh */
1251 reloc->addend = -alpha_gp_value;
1252 }
1253 else
1254 #endif
1255 {
1256 reloc->addend = fixp->fx_offset;
1257 #ifdef OBJ_ELF
1258 /*
1259 * Ohhh, this is ugly. The problem is that if this is a local global
1260 * symbol, the relocation will entirely be performed at link time, not
1261 * at assembly time. bfd_perform_reloc doesn't know about this sort
1262 * of thing, and as a result we need to fake it out here.
1263 */
1264 if (S_IS_EXTERN (fixp->fx_addsy) && !S_IS_COMMON(fixp->fx_addsy))
1265 reloc->addend -= fixp->fx_addsy->bsym->value;
1266 #endif
1267 }
1268
1269 return reloc;
1270 }
1271
1272 /* Parse a register name off of the input_line and return a register
1273 number. Gets md_undefined_symbol above to do the register name
1274 matching for us.
1275
1276 Only called as a part of processing the ECOFF .frame directive. */
1277
1278 int
1279 tc_get_register (frame)
1280 int frame;
1281 {
1282 int framereg = AXP_REG_SP;
1283
1284 SKIP_WHITESPACE ();
1285 if (*input_line_pointer == '$')
1286 {
1287 char *s = input_line_pointer;
1288 char c = get_symbol_end ();
1289 symbolS *sym = md_undefined_symbol (s);
1290
1291 *strchr(s, '\0') = c;
1292 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1293 goto found;
1294 }
1295 as_warn ("frame reg expected, using $%d.", framereg);
1296
1297 found:
1298 note_gpreg (framereg);
1299 return framereg;
1300 }
1301
1302 \f
1303 /* Parse the arguments to an opcode. */
1304
1305 static int
1306 tokenize_arguments (str, tok, ntok)
1307 char *str;
1308 expressionS tok[];
1309 int ntok;
1310 {
1311 expressionS *end_tok = tok + ntok;
1312 char *old_input_line_pointer;
1313 int saw_comma = 0, saw_arg = 0;
1314
1315 memset (tok, 0, sizeof(*tok)*ntok);
1316
1317 /* Save and restore input_line_pointer around this function */
1318 old_input_line_pointer = input_line_pointer;
1319 input_line_pointer = str;
1320
1321 while (tok < end_tok && *input_line_pointer)
1322 {
1323 SKIP_WHITESPACE ();
1324 switch (*input_line_pointer)
1325 {
1326 case '\0':
1327 goto fini;
1328
1329 case ',':
1330 ++input_line_pointer;
1331 if (saw_comma || !saw_arg)
1332 goto err;
1333 saw_comma = 1;
1334 break;
1335
1336 case '(':
1337 {
1338 char *hold = input_line_pointer++;
1339
1340 /* First try for parenthesized register ... */
1341 expression (tok);
1342 if (*input_line_pointer == ')' && tok->X_op == O_register)
1343 {
1344 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1345 saw_comma = 0;
1346 saw_arg = 1;
1347 ++input_line_pointer;
1348 ++tok;
1349 break;
1350 }
1351
1352 /* ... then fall through to plain expression */
1353 input_line_pointer = hold;
1354 }
1355
1356 default:
1357 if (saw_arg && !saw_comma)
1358 goto err;
1359 expression (tok);
1360 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1361 goto err;
1362
1363 saw_comma = 0;
1364 saw_arg = 1;
1365 ++tok;
1366 break;
1367 }
1368 }
1369
1370 fini:
1371 if (saw_comma)
1372 goto err;
1373 input_line_pointer = old_input_line_pointer;
1374 return ntok - (end_tok - tok);
1375
1376 err:
1377 input_line_pointer = old_input_line_pointer;
1378 return -1;
1379 }
1380
1381 /* Search forward through all variants of an opcode looking for a
1382 syntax match. */
1383
1384 static const struct alpha_opcode *
1385 find_opcode_match(first_opcode, tok, pntok, pcpumatch)
1386 const struct alpha_opcode *first_opcode;
1387 const expressionS *tok;
1388 int *pntok;
1389 int *pcpumatch;
1390 {
1391 const struct alpha_opcode *opcode = first_opcode;
1392 int ntok = *pntok;
1393 int got_cpu_match = 0;
1394
1395 do
1396 {
1397 const unsigned char *opidx;
1398 int tokidx = 0;
1399
1400 /* Don't match opcodes that don't exist on this architecture */
1401 if (!(opcode->flags & alpha_target))
1402 goto match_failed;
1403
1404 got_cpu_match = 1;
1405
1406 for (opidx = opcode->operands; *opidx; ++opidx)
1407 {
1408 const struct alpha_operand *operand = &alpha_operands[*opidx];
1409
1410 /* only take input from real operands */
1411 if (operand->flags & AXP_OPERAND_FAKE)
1412 continue;
1413
1414 /* when we expect input, make sure we have it */
1415 if (tokidx >= ntok)
1416 {
1417 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1418 goto match_failed;
1419 continue;
1420 }
1421
1422 /* match operand type with expression type */
1423 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1424 {
1425 case AXP_OPERAND_IR:
1426 if (tok[tokidx].X_op != O_register
1427 || !is_ir_num(tok[tokidx].X_add_number))
1428 goto match_failed;
1429 break;
1430 case AXP_OPERAND_FPR:
1431 if (tok[tokidx].X_op != O_register
1432 || !is_fpr_num(tok[tokidx].X_add_number))
1433 goto match_failed;
1434 break;
1435 case AXP_OPERAND_IR|AXP_OPERAND_PARENS:
1436 if (tok[tokidx].X_op != O_pregister
1437 || !is_ir_num(tok[tokidx].X_add_number))
1438 goto match_failed;
1439 break;
1440 case AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA:
1441 if (tok[tokidx].X_op != O_cpregister
1442 || !is_ir_num(tok[tokidx].X_add_number))
1443 goto match_failed;
1444 break;
1445
1446 case AXP_OPERAND_RELATIVE:
1447 case AXP_OPERAND_SIGNED:
1448 case AXP_OPERAND_UNSIGNED:
1449 switch (tok[tokidx].X_op)
1450 {
1451 case O_illegal:
1452 case O_absent:
1453 case O_register:
1454 case O_pregister:
1455 case O_cpregister:
1456 goto match_failed;
1457 }
1458 break;
1459
1460 default:
1461 /* everything else should have been fake */
1462 abort();
1463 }
1464 ++tokidx;
1465 }
1466
1467 /* possible match -- did we use all of our input? */
1468 if (tokidx == ntok)
1469 {
1470 *pntok = ntok;
1471 return opcode;
1472 }
1473
1474 match_failed:;
1475 }
1476 while (++opcode-alpha_opcodes < alpha_num_opcodes
1477 && !strcmp(opcode->name, first_opcode->name));
1478
1479 if (*pcpumatch)
1480 *pcpumatch = got_cpu_match;
1481
1482 return NULL;
1483 }
1484
1485 /* Search forward through all variants of a macro looking for a syntax
1486 match. */
1487
1488 static const struct alpha_macro *
1489 find_macro_match(first_macro, tok, pntok)
1490 const struct alpha_macro *first_macro;
1491 const expressionS *tok;
1492 int *pntok;
1493 {
1494 const struct alpha_macro *macro = first_macro;
1495 int ntok = *pntok;
1496
1497 do
1498 {
1499 const enum alpha_macro_arg *arg = macro->argsets;
1500 int tokidx = 0;
1501
1502 while (*arg)
1503 {
1504 switch (*arg)
1505 {
1506 case MACRO_EOA:
1507 if (tokidx == ntok)
1508 return macro;
1509 else
1510 tokidx = 0;
1511 break;
1512
1513 case MACRO_IR:
1514 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1515 || !is_ir_num(tok[tokidx].X_add_number))
1516 goto match_failed;
1517 ++tokidx;
1518 break;
1519 case MACRO_PIR:
1520 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
1521 || !is_ir_num(tok[tokidx].X_add_number))
1522 goto match_failed;
1523 ++tokidx;
1524 break;
1525 case MACRO_CPIR:
1526 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
1527 || !is_ir_num(tok[tokidx].X_add_number))
1528 goto match_failed;
1529 ++tokidx;
1530 break;
1531 case MACRO_FPR:
1532 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1533 || !is_fpr_num(tok[tokidx].X_add_number))
1534 goto match_failed;
1535 ++tokidx;
1536 break;
1537
1538 case MACRO_EXP:
1539 if (tokidx >= ntok)
1540 goto match_failed;
1541 switch (tok[tokidx].X_op)
1542 {
1543 case O_illegal:
1544 case O_absent:
1545 case O_register:
1546 case O_pregister:
1547 case O_cpregister:
1548 goto match_failed;
1549 }
1550 ++tokidx;
1551 break;
1552
1553 match_failed:
1554 while (*arg != MACRO_EOA)
1555 ++arg;
1556 tokidx = 0;
1557 break;
1558 }
1559 ++arg;
1560 }
1561 }
1562 while (++macro-alpha_macros < alpha_num_macros
1563 && !strcmp(macro->name, first_macro->name));
1564
1565 return NULL;
1566 }
1567
1568 /* Insert an operand value into an instruction. */
1569
1570 static unsigned
1571 insert_operand(insn, operand, val, file, line)
1572 unsigned insn;
1573 const struct alpha_operand *operand;
1574 offsetT val;
1575 char *file;
1576 unsigned line;
1577 {
1578 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1579 {
1580 offsetT min, max;
1581
1582 if (operand->flags & AXP_OPERAND_SIGNED)
1583 {
1584 max = (1 << (operand->bits - 1)) - 1;
1585 min = -(1 << (operand->bits - 1));
1586 }
1587 else
1588 {
1589 max = (1 << operand->bits) - 1;
1590 min = 0;
1591 }
1592
1593 if (val < min || val > max)
1594 {
1595 const char *err =
1596 "operand out of range (%s not between %d and %d)";
1597 char buf[sizeof(val)*3+2];
1598
1599 sprint_value(buf, val);
1600 if (file)
1601 as_warn_where(file, line, err, buf, min, max);
1602 else
1603 as_warn(err, buf, min, max);
1604 }
1605 }
1606
1607 if (operand->insert)
1608 {
1609 const char *errmsg = NULL;
1610
1611 insn = (*operand->insert)(insn, val, &errmsg);
1612 if (errmsg)
1613 as_warn(errmsg);
1614 }
1615 else
1616 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1617
1618 return insn;
1619 }
1620
1621 /*
1622 * Turn an opcode description and a set of arguments into
1623 * an instruction and a fixup.
1624 */
1625
1626 static void
1627 assemble_insn(opcode, tok, ntok, insn)
1628 const struct alpha_opcode *opcode;
1629 const expressionS *tok;
1630 int ntok;
1631 struct alpha_insn *insn;
1632 {
1633 const unsigned char *argidx;
1634 unsigned image;
1635 int tokidx = 0;
1636
1637 memset(insn, 0, sizeof(*insn));
1638 image = opcode->opcode;
1639
1640 for (argidx = opcode->operands; *argidx; ++argidx)
1641 {
1642 const struct alpha_operand *operand = &alpha_operands[*argidx];
1643 const expressionS *t;
1644
1645 if (operand->flags & AXP_OPERAND_FAKE)
1646 {
1647 /* fake operands take no value and generate no fixup */
1648 image = insert_operand(image, operand, 0, NULL, 0);
1649 continue;
1650 }
1651
1652 if (tokidx >= ntok)
1653 {
1654 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1655 {
1656 case AXP_OPERAND_DEFAULT_FIRST:
1657 t = &tok[0];
1658 break;
1659 case AXP_OPERAND_DEFAULT_SECOND:
1660 t = &tok[1];
1661 break;
1662 case AXP_OPERAND_DEFAULT_ZERO:
1663 {
1664 static const expressionS zero_exp = { 0, 0, 0, O_constant, 1 };
1665 t = &zero_exp;
1666 }
1667 break;
1668 default:
1669 abort();
1670 }
1671 }
1672 else
1673 t = &tok[tokidx++];
1674
1675 switch (t->X_op)
1676 {
1677 case O_register:
1678 case O_pregister:
1679 case O_cpregister:
1680 image = insert_operand(image, operand, regno(t->X_add_number),
1681 NULL, 0);
1682 break;
1683
1684 case O_constant:
1685 image = insert_operand(image, operand, t->X_add_number, NULL, 0);
1686 break;
1687
1688 default:
1689 {
1690 struct alpha_fixup *fixup;
1691
1692 if (insn->nfixups >= MAX_INSN_FIXUPS)
1693 as_fatal("too many fixups");
1694
1695 fixup = &insn->fixups[insn->nfixups++];
1696
1697 fixup->exp = *t;
1698 fixup->reloc = operand->default_reloc;
1699 }
1700 break;
1701 }
1702 }
1703
1704 insn->insn = image;
1705 }
1706
1707 /*
1708 * Actually output an instruction with its fixup.
1709 */
1710
1711 static void
1712 emit_insn (insn)
1713 struct alpha_insn *insn;
1714 {
1715 char *f;
1716 int i;
1717
1718 /* Take care of alignment duties */
1719 if (alpha_auto_align_on && alpha_current_align < 2)
1720 alpha_align (2, (char *) NULL, alpha_insn_label);
1721 if (alpha_current_align > 2)
1722 alpha_current_align = 2;
1723 alpha_insn_label = NULL;
1724
1725 /* Write out the instruction. */
1726 f = frag_more (4);
1727 md_number_to_chars (f, insn->insn, 4);
1728
1729 /* Apply the fixups in order */
1730 for (i = 0; i < insn->nfixups; ++i)
1731 {
1732 struct alpha_fixup *fixup = &insn->fixups[i];
1733 int size, pcrel;
1734 fixS *fixP;
1735
1736 /* Some fixups are only used internally and so have no howto */
1737 if (fixup->reloc > BFD_RELOC_UNUSED)
1738 size = 4, pcrel = 0;
1739 #ifdef OBJ_ELF
1740 /* These relocation types are only used internally. */
1741 else if (fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1742 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1743 {
1744 size = 2, pcrel = 0;
1745 }
1746 #endif
1747 else
1748 {
1749 reloc_howto_type *reloc_howto
1750 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1751 assert (reloc_howto);
1752
1753 size = bfd_get_reloc_size (reloc_howto);
1754 pcrel = reloc_howto->pc_relative;
1755 }
1756 assert (size >= 1 && size <= 4);
1757
1758 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1759 &fixup->exp, pcrel, fixup->reloc);
1760
1761 /* Turn off complaints that the addend is too large for some fixups */
1762 switch (fixup->reloc)
1763 {
1764 case BFD_RELOC_ALPHA_GPDISP_LO16:
1765 case BFD_RELOC_ALPHA_LITERAL:
1766 case BFD_RELOC_GPREL32:
1767 fixP->fx_no_overflow = 1;
1768 break;
1769 default:
1770 break;
1771 }
1772 }
1773 }
1774
1775 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1776 the insn, but do not emit it.
1777
1778 Note that this implies no macros allowed, since we can't store more
1779 than one insn in an insn structure. */
1780
1781 static void
1782 assemble_tokens_to_insn(opname, tok, ntok, insn)
1783 const char *opname;
1784 const expressionS *tok;
1785 int ntok;
1786 struct alpha_insn *insn;
1787 {
1788 const struct alpha_opcode *opcode;
1789
1790 /* search opcodes */
1791 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1792 if (opcode)
1793 {
1794 int cpumatch;
1795 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1796 if (opcode)
1797 {
1798 assemble_insn (opcode, tok, ntok, insn);
1799 return;
1800 }
1801 else if (cpumatch)
1802 as_bad ("inappropriate arguments for opcode `%s'", opname);
1803 else
1804 as_bad ("opcode `%s' not supported for target %s", opname,
1805 alpha_target_name);
1806 }
1807 else
1808 as_bad ("unknown opcode `%s'", opname);
1809 }
1810
1811 /* Given an opcode name and a pre-tokenized set of arguments, take the
1812 opcode all the way through emission. */
1813
1814 static void
1815 assemble_tokens (opname, tok, ntok, local_macros_on)
1816 const char *opname;
1817 const expressionS *tok;
1818 int ntok;
1819 int local_macros_on;
1820 {
1821 int found_something = 0;
1822 const struct alpha_opcode *opcode;
1823 const struct alpha_macro *macro;
1824 int cpumatch = 1;
1825
1826 /* search macros */
1827 if (local_macros_on)
1828 {
1829 macro = ((const struct alpha_macro *)
1830 hash_find (alpha_macro_hash, opname));
1831 if (macro)
1832 {
1833 found_something = 1;
1834 macro = find_macro_match (macro, tok, &ntok);
1835 if (macro)
1836 {
1837 (*macro->emit) (tok, ntok, macro->arg);
1838 return;
1839 }
1840 }
1841 }
1842
1843 /* search opcodes */
1844 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1845 if (opcode)
1846 {
1847 found_something = 1;
1848 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1849 if (opcode)
1850 {
1851 struct alpha_insn insn;
1852 assemble_insn (opcode, tok, ntok, &insn);
1853 emit_insn (&insn);
1854 return;
1855 }
1856 }
1857
1858 if (found_something)
1859 if (cpumatch)
1860 as_bad ("inappropriate arguments for opcode `%s'", opname);
1861 else
1862 as_bad ("opcode `%s' not supported for target %s", opname,
1863 alpha_target_name);
1864 else
1865 as_bad ("unknown opcode `%s'", opname);
1866 }
1867
1868 \f
1869 /* Some instruction sets indexed by lg(size) */
1870 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
1871 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
1872 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
1873 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
1874 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
1875 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
1876 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
1877
1878 /* Implement the ldgp macro. */
1879
1880 static void
1881 emit_ldgp (tok, ntok, unused)
1882 const expressionS *tok;
1883 int ntok;
1884 void *unused;
1885 {
1886 #ifdef OBJ_AOUT
1887 FIXME
1888 #endif
1889 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
1890 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
1891 with appropriate constants and relocations. */
1892 struct alpha_insn insn;
1893 expressionS newtok[3];
1894 expressionS addend;
1895
1896 /* We're going to need this symbol in md_apply_fix(). */
1897 (void) section_symbol (absolute_section);
1898
1899 #ifdef OBJ_ECOFF
1900 if (regno (tok[2].X_add_number) == AXP_REG_PV)
1901 ecoff_set_gp_prolog_size (0);
1902 #endif
1903
1904 newtok[0] = tok[0];
1905 set_tok_const (newtok[1], 0);
1906 newtok[2] = tok[2];
1907
1908 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
1909
1910 addend = tok[1];
1911
1912 #ifdef OBJ_ECOFF
1913 assert (addend.X_op == O_constant);
1914 addend.X_op = O_symbol;
1915 addend.X_add_symbol = alpha_gp_symbol;
1916 #endif
1917
1918 insn.nfixups = 1;
1919 insn.fixups[0].exp = addend;
1920 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
1921
1922 emit_insn (&insn);
1923
1924 set_tok_preg (newtok[2], tok[0].X_add_number);
1925
1926 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1927
1928 #ifdef OBJ_ECOFF
1929 addend.X_add_number += 4;
1930 #endif
1931
1932 insn.nfixups = 1;
1933 insn.fixups[0].exp = addend;
1934 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
1935
1936 emit_insn (&insn);
1937 #endif /* OBJ_ECOFF || OBJ_ELF */
1938 }
1939
1940 #ifdef OBJ_EVAX
1941
1942 /* Add symbol+addend to link pool.
1943 Return offset from basesym to entry in link pool.
1944
1945 Add new fixup only if offset isn't 16bit. */
1946
1947 valueT
1948 add_to_link_pool (basesym, sym, addend)
1949 symbolS *basesym;
1950 symbolS *sym;
1951 offsetT addend;
1952 {
1953 segT current_section = now_seg;
1954 int current_subsec = now_subseg;
1955 valueT offset;
1956 bfd_reloc_code_real_type reloc_type;
1957 char *p;
1958 segment_info_type *seginfo = seg_info (alpha_link_section);
1959 fixS *fixp;
1960
1961 offset = -basesym->sy_obj;
1962
1963 /* @@ This assumes all entries in a given section will be of the same
1964 size... Probably correct, but unwise to rely on. */
1965 /* This must always be called with the same subsegment. */
1966
1967 if (seginfo->frchainP)
1968 for (fixp = seginfo->frchainP->fix_root;
1969 fixp != (fixS *) NULL;
1970 fixp = fixp->fx_next, offset += 8)
1971 {
1972 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
1973 {
1974 if (range_signed_16 (offset))
1975 {
1976 return offset;
1977 }
1978 }
1979 }
1980
1981 /* Not found in 16bit signed range. */
1982
1983 subseg_set (alpha_link_section, 0);
1984 p = frag_more (8);
1985 memset (p, 0, 8);
1986
1987 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
1988 BFD_RELOC_64);
1989
1990 subseg_set (current_section, current_subsec);
1991 seginfo->literal_pool_size += 8;
1992 return offset;
1993 }
1994
1995 #endif /* OBJ_EVAX */
1996
1997 /* Load a (partial) expression into a target register.
1998
1999 If poffset is not null, after the call it will either contain
2000 O_constant 0, or a 16-bit offset appropriate for any MEM format
2001 instruction. In addition, pbasereg will be modified to point to
2002 the base register to use in that MEM format instruction.
2003
2004 In any case, *pbasereg should contain a base register to add to the
2005 expression. This will normally be either AXP_REG_ZERO or
2006 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2007 so "foo($0)" is interpreted as adding the address of foo to $0;
2008 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2009 but this is what OSF/1 does.
2010
2011 Finally, the return value is true if the calling macro may emit a
2012 LITUSE reloc if otherwise appropriate. */
2013
2014 static int
2015 load_expression (targreg, exp, pbasereg, poffset)
2016 int targreg;
2017 const expressionS *exp;
2018 int *pbasereg;
2019 expressionS *poffset;
2020 {
2021 int emit_lituse = 0;
2022 offsetT addend = exp->X_add_number;
2023 int basereg = *pbasereg;
2024 struct alpha_insn insn;
2025 expressionS newtok[3];
2026
2027 switch (exp->X_op)
2028 {
2029 case O_symbol:
2030 {
2031 #ifdef OBJ_ECOFF
2032 offsetT lit;
2033
2034 /* attempt to reduce .lit load by splitting the offset from
2035 its symbol when possible, but don't create a situation in
2036 which we'd fail. */
2037 if (!range_signed_32 (addend) &&
2038 (alpha_noat_on || targreg == AXP_REG_AT))
2039 {
2040 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2041 alpha_lita_section, 8);
2042 addend = 0;
2043 }
2044 else
2045 {
2046 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2047 alpha_lita_section, 8);
2048 }
2049
2050 if (lit >= 0x8000)
2051 as_fatal ("overflow in literal (.lita) table");
2052
2053 /* emit "ldq r, lit(gp)" */
2054
2055 if (basereg != alpha_gp_register && targreg == basereg)
2056 {
2057 if (alpha_noat_on)
2058 as_bad ("macro requires $at register while noat in effect");
2059 if (targreg == AXP_REG_AT)
2060 as_bad ("macro requires $at while $at in use");
2061
2062 set_tok_reg (newtok[0], AXP_REG_AT);
2063 }
2064 else
2065 set_tok_reg (newtok[0], targreg);
2066 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2067 set_tok_preg (newtok[2], alpha_gp_register);
2068
2069 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2070
2071 assert (insn.nfixups == 1);
2072 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2073 #endif /* OBJ_ECOFF */
2074 #ifdef OBJ_ELF
2075 /* emit "ldq r, gotoff(gp)" */
2076
2077 if (basereg != alpha_gp_register && targreg == basereg)
2078 {
2079 if (alpha_noat_on)
2080 as_bad ("macro requires $at register while noat in effect");
2081 if (targreg == AXP_REG_AT)
2082 as_bad ("macro requires $at while $at in use");
2083
2084 set_tok_reg (newtok[0], AXP_REG_AT);
2085 }
2086 else
2087 set_tok_reg (newtok[0], targreg);
2088
2089 if (!range_signed_32 (addend)
2090 && (alpha_noat_on || targreg == AXP_REG_AT))
2091 {
2092 newtok[1] = *exp;
2093 addend = 0;
2094 }
2095 else
2096 {
2097 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2098 }
2099
2100 set_tok_preg (newtok[2], alpha_gp_register);
2101
2102 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2103
2104 assert (insn.nfixups == 1);
2105 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2106 #endif /* OBJ_ELF */
2107 #ifdef OBJ_EVAX
2108 offsetT link;
2109
2110 /* Find symbol or symbol pointer in link section. */
2111
2112 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2113 {
2114 if (range_signed_16 (addend))
2115 {
2116 set_tok_reg (newtok[0], targreg);
2117 set_tok_const (newtok[1], addend);
2118 set_tok_preg (newtok[2], basereg);
2119 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2120 addend = 0;
2121 }
2122 else
2123 {
2124 set_tok_reg (newtok[0], targreg);
2125 set_tok_const (newtok[1], 0);
2126 set_tok_preg (newtok[2], basereg);
2127 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2128 }
2129 }
2130 else
2131 {
2132 if (!range_signed_32 (addend))
2133 {
2134 link = add_to_link_pool (alpha_evax_proc.symbol,
2135 exp->X_add_symbol, addend);
2136 addend = 0;
2137 }
2138 else
2139 {
2140 link = add_to_link_pool (alpha_evax_proc.symbol,
2141 exp->X_add_symbol, 0);
2142 }
2143 set_tok_reg (newtok[0], targreg);
2144 set_tok_const (newtok[1], link);
2145 set_tok_preg (newtok[2], basereg);
2146 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2147 }
2148 #endif /* OBJ_EVAX */
2149
2150 emit_insn(&insn);
2151 #ifndef OBJ_EVAX
2152 emit_lituse = 1;
2153
2154 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2155 {
2156 /* emit "addq r, base, r" */
2157
2158 set_tok_reg (newtok[1], basereg);
2159 set_tok_reg (newtok[2], targreg);
2160 assemble_tokens ("addq", newtok, 3, 0);
2161 }
2162 #endif
2163 basereg = targreg;
2164 }
2165 break;
2166
2167 case O_constant:
2168 break;
2169
2170 case O_subtract:
2171 /* Assume that this difference expression will be resolved to an
2172 absolute value and that that value will fit in 16 bits. */
2173
2174 set_tok_reg (newtok[0], targreg);
2175 newtok[1] = *exp;
2176 set_tok_preg (newtok[2], basereg);
2177 assemble_tokens ("lda", newtok, 3, 0);
2178
2179 if (poffset)
2180 set_tok_const (*poffset, 0);
2181 return 0;
2182
2183 default:
2184 abort();
2185 }
2186
2187 if (!range_signed_32 (addend))
2188 {
2189 offsetT lit;
2190
2191 /* for 64-bit addends, just put it in the literal pool */
2192
2193 #ifdef OBJ_EVAX
2194
2195 /* emit "ldq targreg, lit(basereg)" */
2196 lit = add_to_link_pool (alpha_evax_proc.symbol,
2197 section_symbol (absolute_section), addend);
2198 set_tok_reg (newtok[0], targreg);
2199 set_tok_const (newtok[1], lit);
2200 set_tok_preg (newtok[2], alpha_gp_register);
2201 assemble_tokens ("ldq", newtok, 3, 0);
2202
2203 #else
2204
2205 if (alpha_lit8_section == NULL)
2206 {
2207 create_literal_section (".lit8",
2208 &alpha_lit8_section,
2209 &alpha_lit8_symbol);
2210 S_SET_VALUE (alpha_lit8_symbol, 0x8000);
2211 }
2212
2213 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
2214 if (lit >= 0x8000)
2215 as_fatal ("overflow in literal (.lit8) table");
2216
2217 /* emit "ldq litreg, .lit8+lit" */
2218
2219 if (targreg == basereg)
2220 {
2221 if (alpha_noat_on)
2222 as_bad ("macro requires $at register while noat in effect");
2223 if (targreg == AXP_REG_AT)
2224 as_bad ("macro requires $at while $at in use");
2225
2226 set_tok_reg (newtok[0], AXP_REG_AT);
2227 }
2228 else
2229 set_tok_reg (newtok[0], targreg);
2230 set_tok_sym (newtok[1], alpha_lit8_symbol, lit);
2231
2232 assemble_tokens ("ldq", newtok, 2, 1); /* note this does recurse */
2233
2234 /* emit "addq litreg, base, target" */
2235
2236 if (basereg != AXP_REG_ZERO)
2237 {
2238 set_tok_reg (newtok[1], basereg);
2239 set_tok_reg (newtok[2], targreg);
2240 assemble_tokens ("addq", newtok, 3, 0);
2241 }
2242 #endif /* !OBJ_EVAX */
2243
2244 if (poffset)
2245 set_tok_const (*poffset, 0);
2246 *pbasereg = targreg;
2247 }
2248 else
2249 {
2250 offsetT low, high, extra, tmp;
2251
2252 /* for 32-bit operands, break up the addend */
2253
2254 low = sign_extend_16 (addend);
2255 tmp = addend - low;
2256 high = sign_extend_16 (tmp >> 16);
2257
2258 if (tmp - (high << 16))
2259 {
2260 extra = 0x4000;
2261 tmp -= 0x40000000;
2262 high = sign_extend_16 (tmp >> 16);
2263 }
2264 else
2265 extra = 0;
2266
2267 set_tok_reg (newtok[0], targreg);
2268 set_tok_preg (newtok[2], basereg);
2269
2270 if (extra)
2271 {
2272 /* emit "ldah r, extra(r) */
2273 set_tok_const (newtok[1], extra);
2274 assemble_tokens ("ldah", newtok, 3, 0);
2275 set_tok_preg (newtok[2], basereg = targreg);
2276 }
2277
2278 if (high)
2279 {
2280 /* emit "ldah r, high(r) */
2281 set_tok_const (newtok[1], high);
2282 assemble_tokens ("ldah", newtok, 3, 0);
2283 basereg = targreg;
2284 set_tok_preg (newtok[2], basereg);
2285 }
2286
2287 if ((low && !poffset) || (!poffset && basereg != targreg))
2288 {
2289 /* emit "lda r, low(base)" */
2290 set_tok_const (newtok[1], low);
2291 assemble_tokens ("lda", newtok, 3, 0);
2292 basereg = targreg;
2293 low = 0;
2294 }
2295
2296 if (poffset)
2297 set_tok_const (*poffset, low);
2298 *pbasereg = basereg;
2299 }
2300
2301 return emit_lituse;
2302 }
2303
2304 /* The lda macro differs from the lda instruction in that it handles
2305 most simple expressions, particualrly symbol address loads and
2306 large constants. */
2307
2308 static void
2309 emit_lda (tok, ntok, unused)
2310 const expressionS *tok;
2311 int ntok;
2312 void *unused;
2313 {
2314 int basereg;
2315
2316 if (ntok == 2)
2317 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2318 else
2319 basereg = tok[2].X_add_number;
2320
2321 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
2322 }
2323
2324 /* The ldah macro differs from the ldah instruction in that it has $31
2325 as an implied base register. */
2326
2327 static void
2328 emit_ldah (tok, ntok, unused)
2329 const expressionS *tok;
2330 int ntok;
2331 void *unused;
2332 {
2333 expressionS newtok[3];
2334
2335 newtok[0] = tok[0];
2336 newtok[1] = tok[1];
2337 set_tok_preg (newtok[2], AXP_REG_ZERO);
2338
2339 assemble_tokens ("ldah", newtok, 3, 0);
2340 }
2341
2342 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2343 etc. They differ from the real instructions in that they do simple
2344 expressions like the lda macro. */
2345
2346 static void
2347 emit_ir_load (tok, ntok, opname)
2348 const expressionS *tok;
2349 int ntok;
2350 void *opname;
2351 {
2352 int basereg, lituse;
2353 expressionS newtok[3];
2354 struct alpha_insn insn;
2355
2356 if (ntok == 2)
2357 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2358 else
2359 basereg = tok[2].X_add_number;
2360
2361 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2362 &newtok[1]);
2363
2364 newtok[0] = tok[0];
2365 set_tok_preg (newtok[2], basereg);
2366
2367 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2368
2369 if (lituse)
2370 {
2371 assert (insn.nfixups < MAX_INSN_FIXUPS);
2372 if (insn.nfixups > 0)
2373 {
2374 memmove (&insn.fixups[1], &insn.fixups[0],
2375 sizeof(struct alpha_fixup) * insn.nfixups);
2376 }
2377 insn.nfixups++;
2378 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2379 insn.fixups[0].exp.X_op = O_constant;
2380 insn.fixups[0].exp.X_add_number = 1;
2381 }
2382
2383 emit_insn (&insn);
2384 }
2385
2386 /* Handle fp register loads, and both integer and fp register stores.
2387 Again, we handle simple expressions. */
2388
2389 static void
2390 emit_loadstore (tok, ntok, opname)
2391 const expressionS *tok;
2392 int ntok;
2393 void *opname;
2394 {
2395 int basereg, lituse;
2396 expressionS newtok[3];
2397 struct alpha_insn insn;
2398
2399 if (ntok == 2)
2400 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2401 else
2402 basereg = tok[2].X_add_number;
2403
2404 if (tok[1].X_op != O_constant || !range_signed_16(tok[1].X_add_number))
2405 {
2406 if (alpha_noat_on)
2407 as_bad ("macro requires $at register while noat in effect");
2408
2409 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2410 }
2411 else
2412 {
2413 newtok[1] = tok[1];
2414 lituse = 0;
2415 }
2416
2417 newtok[0] = tok[0];
2418 set_tok_preg (newtok[2], basereg);
2419
2420 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2421
2422 if (lituse)
2423 {
2424 assert (insn.nfixups < MAX_INSN_FIXUPS);
2425 if (insn.nfixups > 0)
2426 {
2427 memmove (&insn.fixups[1], &insn.fixups[0],
2428 sizeof(struct alpha_fixup) * insn.nfixups);
2429 }
2430 insn.nfixups++;
2431 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2432 insn.fixups[0].exp.X_op = O_constant;
2433 insn.fixups[0].exp.X_add_number = 1;
2434 }
2435
2436 emit_insn (&insn);
2437 }
2438
2439 /* Load a half-word or byte as an unsigned value. */
2440
2441 static void
2442 emit_ldXu (tok, ntok, vlgsize)
2443 const expressionS *tok;
2444 int ntok;
2445 void *vlgsize;
2446 {
2447 expressionS newtok[3];
2448
2449 if (alpha_noat_on)
2450 as_bad ("macro requires $at register while noat in effect");
2451
2452 /* emit "lda $at, exp" */
2453
2454 memcpy (newtok, tok, sizeof(expressionS)*ntok);
2455 newtok[0].X_add_number = AXP_REG_AT;
2456 assemble_tokens ("lda", newtok, ntok, 1);
2457
2458 /* emit "ldq_u targ, 0($at)" */
2459
2460 newtok[0] = tok[0];
2461 set_tok_const (newtok[1], 0);
2462 set_tok_preg (newtok[2], AXP_REG_AT);
2463 assemble_tokens ("ldq_u", newtok, 3, 1);
2464
2465 /* emit "extXl targ, $at, targ" */
2466
2467 set_tok_reg (newtok[1], AXP_REG_AT);
2468 newtok[2] = newtok[0];
2469 assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1);
2470 }
2471
2472 /* Load a half-word or byte as a signed value. */
2473
2474 static void
2475 emit_ldX (tok, ntok, vlgsize)
2476 const expressionS *tok;
2477 int ntok;
2478 void *vlgsize;
2479 {
2480 emit_ldXu (tok, ntok, vlgsize);
2481 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2482 }
2483
2484 /* Load an integral value from an unaligned address as an unsigned
2485 value. */
2486
2487 static void
2488 emit_uldXu (tok, ntok, vlgsize)
2489 const expressionS *tok;
2490 int ntok;
2491 void *vlgsize;
2492 {
2493 long lgsize = (long)vlgsize;
2494 expressionS newtok[3];
2495
2496 if (alpha_noat_on)
2497 as_bad ("macro requires $at register while noat in effect");
2498
2499 /* emit "lda $at, exp" */
2500
2501 memcpy (newtok, tok, sizeof(expressionS)*ntok);
2502 newtok[0].X_add_number = AXP_REG_AT;
2503 assemble_tokens ("lda", newtok, ntok, 1);
2504
2505 /* emit "ldq_u $t9, 0($at)" */
2506
2507 set_tok_reg (newtok[0], AXP_REG_T9);
2508 set_tok_const (newtok[1], 0);
2509 set_tok_preg (newtok[2], AXP_REG_AT);
2510 assemble_tokens ("ldq_u", newtok, 3, 1);
2511
2512 /* emit "ldq_u $t10, size-1($at)" */
2513
2514 set_tok_reg (newtok[0], AXP_REG_T10);
2515 set_tok_const (newtok[1], (1<<lgsize)-1);
2516 assemble_tokens ("ldq_u", newtok, 3, 1);
2517
2518 /* emit "extXl $t9, $at, $t9" */
2519
2520 set_tok_reg (newtok[0], AXP_REG_T9);
2521 set_tok_reg (newtok[1], AXP_REG_AT);
2522 set_tok_reg (newtok[2], AXP_REG_T9);
2523 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2524
2525 /* emit "extXh $t10, $at, $t10" */
2526
2527 set_tok_reg (newtok[0], AXP_REG_T10);
2528 set_tok_reg (newtok[2], AXP_REG_T10);
2529 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2530
2531 /* emit "or $t9, $t10, targ" */
2532
2533 set_tok_reg (newtok[0], AXP_REG_T9);
2534 set_tok_reg (newtok[1], AXP_REG_T10);
2535 newtok[2] = tok[0];
2536 assemble_tokens ("or", newtok, 3, 1);
2537 }
2538
2539 /* Load an integral value from an unaligned address as a signed value.
2540 Note that quads should get funneled to the unsigned load since we
2541 don't have to do the sign extension. */
2542
2543 static void
2544 emit_uldX (tok, ntok, vlgsize)
2545 const expressionS *tok;
2546 int ntok;
2547 void *vlgsize;
2548 {
2549 emit_uldXu (tok, ntok, vlgsize);
2550 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2551 }
2552
2553 /* Implement the ldil macro. */
2554
2555 static void
2556 emit_ldil (tok, ntok, unused)
2557 const expressionS *tok;
2558 int ntok;
2559 void *unused;
2560 {
2561 expressionS newtok[2];
2562
2563 memcpy (newtok, tok, sizeof(newtok));
2564 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2565
2566 assemble_tokens ("lda", newtok, ntok, 1);
2567 }
2568
2569 /* Store a half-word or byte. */
2570
2571 static void
2572 emit_stX (tok, ntok, vlgsize)
2573 const expressionS *tok;
2574 void *vlgsize;
2575 {
2576 int lgsize = (int)(long)vlgsize;
2577 expressionS newtok[3];
2578
2579 if (alpha_noat_on)
2580 as_bad("macro requires $at register while noat in effect");
2581
2582 /* emit "lda $at, exp" */
2583
2584 memcpy (newtok, tok, sizeof(expressionS)*ntok);
2585 newtok[0].X_add_number = AXP_REG_AT;
2586 assemble_tokens ("lda", newtok, ntok, 1);
2587
2588 /* emit "ldq_u $t9, 0($at)" */
2589
2590 set_tok_reg (newtok[0], AXP_REG_T9);
2591 set_tok_const (newtok[1], 0);
2592 set_tok_preg (newtok[2], AXP_REG_AT);
2593 assemble_tokens ("ldq_u", newtok, 3, 1);
2594
2595 /* emit "insXl src, $at, $t10" */
2596
2597 newtok[0] = tok[0];
2598 set_tok_reg (newtok[1], AXP_REG_AT);
2599 set_tok_reg (newtok[2], AXP_REG_T10);
2600 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2601
2602 /* emit "mskXl $t9, $at, $t9" */
2603
2604 set_tok_reg (newtok[0], AXP_REG_T9);
2605 newtok[2] = newtok[0];
2606 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2607
2608 /* emit "or $t9, $t10, $t9" */
2609
2610 set_tok_reg (newtok[1], AXP_REG_T10);
2611 assemble_tokens ("or", newtok, 3, 1);
2612
2613 /* emit "stq_u $t9, 0($at) */
2614
2615 set_tok_const (newtok[1], 0);
2616 set_tok_preg (newtok[2], AXP_REG_AT);
2617 assemble_tokens ("stq_u", newtok, 3, 1);
2618 }
2619
2620 /* Store an integer to an unaligned address. */
2621
2622 static void
2623 emit_ustX (tok, ntok, vlgsize)
2624 const expressionS *tok;
2625 int ntok;
2626 void *vlgsize;
2627 {
2628 int lgsize = (int)(long)vlgsize;
2629 expressionS newtok[3];
2630
2631 /* emit "lda $at, exp" */
2632
2633 memcpy (newtok, tok, sizeof(expressionS)*ntok);
2634 newtok[0].X_add_number = AXP_REG_AT;
2635 assemble_tokens ("lda", newtok, ntok, 1);
2636
2637 /* emit "ldq_u $9, 0($at)" */
2638
2639 set_tok_reg (newtok[0], AXP_REG_T9);
2640 set_tok_const (newtok[1], 0);
2641 set_tok_preg (newtok[2], AXP_REG_AT);
2642 assemble_tokens ("ldq_u", newtok, 3, 1);
2643
2644 /* emit "ldq_u $10, size-1($at)" */
2645
2646 set_tok_reg (newtok[0], AXP_REG_T10);
2647 set_tok_const (newtok[1], (1 << lgsize)-1);
2648 assemble_tokens ("ldq_u", newtok, 3, 1);
2649
2650 /* emit "insXl src, $at, $t11" */
2651
2652 newtok[0] = tok[0];
2653 set_tok_reg (newtok[1], AXP_REG_AT);
2654 set_tok_reg (newtok[2], AXP_REG_T11);
2655 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2656
2657 /* emit "insXh src, $at, $t12" */
2658
2659 set_tok_reg (newtok[2], AXP_REG_T12);
2660 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2661
2662 /* emit "mskXl $t9, $at, $t9" */
2663
2664 set_tok_reg (newtok[0], AXP_REG_T9);
2665 newtok[2] = newtok[0];
2666 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2667
2668 /* emit "mskXh $t10, $at, $t10" */
2669
2670 set_tok_reg (newtok[0], AXP_REG_T10);
2671 newtok[2] = newtok[0];
2672 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2673
2674 /* emit "or $t9, $t11, $t9" */
2675
2676 set_tok_reg (newtok[0], AXP_REG_T9);
2677 set_tok_reg (newtok[1], AXP_REG_T11);
2678 newtok[2] = newtok[0];
2679 assemble_tokens ("or", newtok, 3, 1);
2680
2681 /* emit "or $t10, $t12, $t10" */
2682
2683 set_tok_reg (newtok[0], AXP_REG_T10);
2684 set_tok_reg (newtok[1], AXP_REG_T12);
2685 newtok[2] = newtok[0];
2686 assemble_tokens ("or", newtok, 3, 1);
2687
2688 /* emit "stq_u $t9, 0($at)" */
2689
2690 set_tok_reg (newtok[0], AXP_REG_T9);
2691 set_tok_const (newtok[1], 0);
2692 set_tok_preg (newtok[2], AXP_REG_AT);
2693 assemble_tokens ("stq_u", newtok, 3, 1);
2694
2695 /* emit "stq_u $t10, size-1($at)" */
2696
2697 set_tok_reg (newtok[0], AXP_REG_T10);
2698 set_tok_const (newtok[1], (1 << lgsize)-1);
2699 assemble_tokens ("stq_u", newtok, 3, 1);
2700 }
2701
2702 /* Sign extend a half-word or byte. The 32-bit sign extend is
2703 implemented as "addl $31, $r, $t" in the opcode table. */
2704
2705 static void
2706 emit_sextX (tok, ntok, vlgsize)
2707 const expressionS *tok;
2708 int ntok;
2709 void *vlgsize;
2710 {
2711 int bitshift = 64 - 8*(1 << (long)vlgsize);
2712 expressionS newtok[3];
2713
2714 /* emit "sll src,bits,dst" */
2715
2716 newtok[0] = tok[0];
2717 set_tok_const (newtok[1], bitshift);
2718 newtok[2] = tok[ntok - 1];
2719 assemble_tokens ("sll", newtok, 3, 1);
2720
2721 /* emit "sra dst,bits,dst" */
2722
2723 newtok[0] = newtok[2];
2724 assemble_tokens ("sra", newtok, 3, 1);
2725 }
2726
2727 /* Implement the division and modulus macros. */
2728
2729 #ifdef OBJ_EVAX
2730
2731 /* Make register usage like in normal procedure call.
2732 Don't clobber PV and RA. */
2733
2734 static void
2735 emit_division (tok, ntok, symname)
2736 const expressionS *tok;
2737 int ntok;
2738 void *symname;
2739 {
2740 /* DIVISION and MODULUS. Yech.
2741 *
2742 * Convert
2743 * OP x,y,result
2744 * to
2745 * mov x,R16 # if x != R16
2746 * mov y,R17 # if y != R17
2747 * lda AT,__OP
2748 * jsr AT,(AT),0
2749 * mov R0,result
2750 *
2751 * with appropriate optimizations if R0,R16,R17 are the registers
2752 * specified by the compiler.
2753 */
2754
2755 int xr, yr, rr;
2756 symbolS *sym;
2757 expressionS newtok[3];
2758
2759 xr = regno (tok[0].X_add_number);
2760 yr = regno (tok[1].X_add_number);
2761
2762 if (ntok < 3)
2763 rr = xr;
2764 else
2765 rr = regno (tok[2].X_add_number);
2766
2767 /* Move the operands into the right place */
2768 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2769 {
2770 /* They are in exactly the wrong order -- swap through AT */
2771
2772 if (alpha_noat_on)
2773 as_bad ("macro requires $at register while noat in effect");
2774
2775 set_tok_reg (newtok[0], AXP_REG_R16);
2776 set_tok_reg (newtok[1], AXP_REG_AT);
2777 assemble_tokens ("mov", newtok, 2, 1);
2778
2779 set_tok_reg (newtok[0], AXP_REG_R17);
2780 set_tok_reg (newtok[1], AXP_REG_R16);
2781 assemble_tokens ("mov", newtok, 2, 1);
2782
2783 set_tok_reg (newtok[0], AXP_REG_AT);
2784 set_tok_reg (newtok[1], AXP_REG_R17);
2785 assemble_tokens ("mov", newtok, 2, 1);
2786 }
2787 else
2788 {
2789 if (yr == AXP_REG_R16)
2790 {
2791 set_tok_reg (newtok[0], AXP_REG_R16);
2792 set_tok_reg (newtok[1], AXP_REG_R17);
2793 assemble_tokens ("mov", newtok, 2, 1);
2794 }
2795
2796 if (xr != AXP_REG_R16)
2797 {
2798 set_tok_reg (newtok[0], xr);
2799 set_tok_reg (newtok[1], AXP_REG_R16);
2800 assemble_tokens ("mov", newtok, 2, 1);
2801 }
2802
2803 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2804 {
2805 set_tok_reg (newtok[0], yr);
2806 set_tok_reg (newtok[1], AXP_REG_R17);
2807 assemble_tokens ("mov", newtok, 2, 1);
2808 }
2809 }
2810
2811 sym = symbol_find_or_make ((const char *)symname);
2812
2813 set_tok_reg (newtok[0], AXP_REG_AT);
2814 set_tok_sym (newtok[1], sym, 0);
2815 assemble_tokens ("lda", newtok, 2, 1);
2816
2817 /* Call the division routine */
2818 set_tok_reg (newtok[0], AXP_REG_AT);
2819 set_tok_cpreg (newtok[1], AXP_REG_AT);
2820 set_tok_const (newtok[2], 0);
2821 assemble_tokens ("jsr", newtok, 3, 1);
2822
2823 /* Move the result to the right place */
2824 if (rr != AXP_REG_R0)
2825 {
2826 set_tok_reg (newtok[0], AXP_REG_R0);
2827 set_tok_reg (newtok[1], rr);
2828 assemble_tokens ("mov", newtok, 2, 1);
2829 }
2830 }
2831
2832 #else /* !OBJ_EVAX */
2833
2834 static void
2835 emit_division (tok, ntok, symname)
2836 const expressionS *tok;
2837 int ntok;
2838 void *symname;
2839 {
2840 /* DIVISION and MODULUS. Yech.
2841 * Convert
2842 * OP x,y,result
2843 * to
2844 * lda pv,__OP
2845 * mov x,t10
2846 * mov y,t11
2847 * jsr t9,(pv),__OP
2848 * mov t12,result
2849 *
2850 * with appropriate optimizations if t10,t11,t12 are the registers
2851 * specified by the compiler.
2852 */
2853
2854 int xr, yr, rr;
2855 symbolS *sym;
2856 expressionS newtok[3];
2857
2858 xr = regno (tok[0].X_add_number);
2859 yr = regno (tok[1].X_add_number);
2860
2861 if (ntok < 3)
2862 rr = xr;
2863 else
2864 rr = regno (tok[2].X_add_number);
2865
2866 sym = symbol_find_or_make ((const char *)symname);
2867
2868 /* Move the operands into the right place */
2869 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2870 {
2871 /* They are in exactly the wrong order -- swap through AT */
2872
2873 if (alpha_noat_on)
2874 as_bad ("macro requires $at register while noat in effect");
2875
2876 set_tok_reg (newtok[0], AXP_REG_T10);
2877 set_tok_reg (newtok[1], AXP_REG_AT);
2878 assemble_tokens ("mov", newtok, 2, 1);
2879
2880 set_tok_reg (newtok[0], AXP_REG_T11);
2881 set_tok_reg (newtok[1], AXP_REG_T10);
2882 assemble_tokens ("mov", newtok, 2, 1);
2883
2884 set_tok_reg (newtok[0], AXP_REG_AT);
2885 set_tok_reg (newtok[1], AXP_REG_T11);
2886 assemble_tokens ("mov", newtok, 2, 1);
2887 }
2888 else
2889 {
2890 if (yr == AXP_REG_T10)
2891 {
2892 set_tok_reg (newtok[0], AXP_REG_T10);
2893 set_tok_reg (newtok[1], AXP_REG_T11);
2894 assemble_tokens ("mov", newtok, 2, 1);
2895 }
2896
2897 if (xr != AXP_REG_T10)
2898 {
2899 set_tok_reg (newtok[0], xr);
2900 set_tok_reg (newtok[1], AXP_REG_T10);
2901 assemble_tokens ("mov", newtok, 2, 1);
2902 }
2903
2904 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2905 {
2906 set_tok_reg (newtok[0], yr);
2907 set_tok_reg (newtok[1], AXP_REG_T11);
2908 assemble_tokens ("mov", newtok, 2, 1);
2909 }
2910 }
2911
2912 /* Call the division routine */
2913 set_tok_reg (newtok[0], AXP_REG_T9);
2914 set_tok_sym (newtok[1], sym, 0);
2915 assemble_tokens ("jsr", newtok, 2, 1);
2916
2917 /* Reload the GP register */
2918 #ifdef OBJ_AOUT
2919 FIXME
2920 #endif
2921 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2922 set_tok_reg (newtok[0], alpha_gp_register);
2923 set_tok_const (newtok[1], 0);
2924 set_tok_preg (newtok[2], AXP_REG_T9);
2925 assemble_tokens ("ldgp", newtok, 3, 1);
2926 #endif
2927
2928 /* Move the result to the right place */
2929 if (rr != AXP_REG_T12)
2930 {
2931 set_tok_reg (newtok[0], AXP_REG_T12);
2932 set_tok_reg (newtok[1], rr);
2933 assemble_tokens ("mov", newtok, 2, 1);
2934 }
2935 }
2936
2937 #endif /* !OBJ_EVAX */
2938
2939 /* The jsr and jmp macros differ from their instruction counterparts
2940 in that they can load the target address and default most
2941 everything. */
2942
2943 static void
2944 emit_jsrjmp (tok, ntok, vopname)
2945 const expressionS *tok;
2946 int ntok;
2947 void *vopname;
2948 {
2949 const char *opname = (const char *) vopname;
2950 struct alpha_insn insn;
2951 expressionS newtok[3];
2952 int r, tokidx = 0, lituse = 0;
2953
2954 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2955 r = regno (tok[tokidx++].X_add_number);
2956 else
2957 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2958
2959 set_tok_reg (newtok[0], r);
2960
2961 if (tokidx < ntok &&
2962 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2963 r = regno (tok[tokidx++].X_add_number);
2964 #ifdef OBJ_EVAX
2965 /* keep register if jsr $n.<sym> */
2966 #else
2967 else
2968 {
2969 int basereg = alpha_gp_register;
2970 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
2971 }
2972 #endif
2973
2974 set_tok_cpreg (newtok[1], r);
2975
2976 #ifdef OBJ_EVAX
2977 /* FIXME: Add hint relocs to BFD for evax. */
2978 #else
2979 if (tokidx < ntok)
2980 newtok[2] = tok[tokidx];
2981 else
2982 #endif
2983 set_tok_const (newtok[2], 0);
2984
2985 assemble_tokens_to_insn (opname, newtok, 3, &insn);
2986
2987 /* add the LITUSE fixup */
2988 if (lituse)
2989 {
2990 assert (insn.nfixups < MAX_INSN_FIXUPS);
2991 if (insn.nfixups > 0)
2992 {
2993 memmove (&insn.fixups[1], &insn.fixups[0],
2994 sizeof(struct alpha_fixup) * insn.nfixups);
2995 }
2996 insn.nfixups++;
2997 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2998 insn.fixups[0].exp.X_op = O_constant;
2999 insn.fixups[0].exp.X_add_number = 3;
3000 }
3001
3002 emit_insn (&insn);
3003
3004 #if OBJ_EVAX
3005 /* reload PV from 0(FP) if it is our current base register. */
3006 if (alpha_gp_register == AXP_REG_PV)
3007 {
3008 set_tok_reg (newtok[0], AXP_REG_PV);
3009 set_tok_const (newtok[1], 0);
3010 set_tok_preg (newtok[2], AXP_REG_FP);
3011 assemble_tokens ("ldq", newtok, 3, 0);
3012 }
3013 #endif
3014 }
3015
3016 /* The ret and jcr instructions differ from their instruction
3017 counterparts in that everything can be defaulted. */
3018
3019 static void
3020 emit_retjcr (tok, ntok, vopname)
3021 const expressionS *tok;
3022 int ntok;
3023 void *vopname;
3024 {
3025 const char *opname = (const char *)vopname;
3026 expressionS newtok[3];
3027 int r, tokidx = 0;
3028
3029 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3030 r = regno (tok[tokidx++].X_add_number);
3031 else
3032 r = AXP_REG_ZERO;
3033
3034 set_tok_reg (newtok[0], r);
3035
3036 if (tokidx < ntok &&
3037 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3038 r = regno (tok[tokidx++].X_add_number);
3039 else
3040 r = AXP_REG_RA;
3041
3042 set_tok_cpreg (newtok[1], r);
3043
3044 if (tokidx < ntok)
3045 newtok[2] = tok[tokidx];
3046 else
3047 set_tok_const (newtok[2], strcmp(opname, "ret") == 0);
3048
3049 assemble_tokens (opname, newtok, 3, 0);
3050 }
3051 \f
3052 /* Assembler directives */
3053
3054 /* Handle the .text pseudo-op. This is like the usual one, but it
3055 clears alpha_insn_label and restores auto alignment. */
3056
3057 static void
3058 s_alpha_text (i)
3059 int i;
3060
3061 {
3062 s_text (i);
3063 alpha_insn_label = NULL;
3064 alpha_auto_align_on = 1;
3065 alpha_current_align = 0;
3066 }
3067
3068 /* Handle the .data pseudo-op. This is like the usual one, but it
3069 clears alpha_insn_label and restores auto alignment. */
3070
3071 static void
3072 s_alpha_data (i)
3073 int i;
3074 {
3075 s_data (i);
3076 alpha_insn_label = NULL;
3077 alpha_auto_align_on = 1;
3078 alpha_current_align = 0;
3079 }
3080
3081 #ifndef OBJ_ELF
3082
3083 /* Handle the OSF/1 .comm pseudo quirks. */
3084
3085 static void
3086 s_alpha_comm (ignore)
3087 int ignore;
3088 {
3089 register char *name;
3090 register char c;
3091 register char *p;
3092 offsetT temp;
3093 register symbolS *symbolP;
3094
3095 name = input_line_pointer;
3096 c = get_symbol_end ();
3097
3098 /* just after name is now '\0' */
3099 p = input_line_pointer;
3100 *p = c;
3101
3102 SKIP_WHITESPACE ();
3103
3104 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3105 if (*input_line_pointer == ',')
3106 {
3107 input_line_pointer++;
3108 SKIP_WHITESPACE ();
3109 }
3110 if ((temp = get_absolute_expression ()) < 0)
3111 {
3112 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
3113 ignore_rest_of_line ();
3114 return;
3115 }
3116
3117 *p = 0;
3118 symbolP = symbol_find_or_make (name);
3119 *p = c;
3120
3121 if (S_IS_DEFINED (symbolP))
3122 {
3123 as_bad ("Ignoring attempt to re-define symbol");
3124 ignore_rest_of_line ();
3125 return;
3126 }
3127
3128 #if OBJ_EVAX
3129 {
3130 /* Fill common area with zeros. */
3131 char *pfrag;
3132 segT current_seg = now_seg;
3133 subsegT current_subseg = now_subseg;
3134
3135 subseg_set (bss_section, 1);
3136 frag_align (3, 0);
3137
3138 symbolP->sy_frag = frag_now;
3139 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
3140 temp, (char *)0);
3141
3142 *pfrag = 0;
3143 S_SET_SEGMENT (symbolP, bss_section);
3144
3145 subseg_set (current_seg, current_subseg);
3146 }
3147 #endif
3148
3149 if (S_GET_VALUE (symbolP))
3150 {
3151 if (S_GET_VALUE (symbolP) != (valueT) temp)
3152 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3153 S_GET_NAME (symbolP),
3154 (long) S_GET_VALUE (symbolP),
3155 (long) temp);
3156 }
3157 else
3158 {
3159 S_SET_VALUE (symbolP, (valueT) temp);
3160 S_SET_EXTERNAL (symbolP);
3161 }
3162
3163 #ifndef OBJ_EVAX
3164 know (symbolP->sy_frag == &zero_address_frag);
3165 #endif
3166
3167 demand_empty_rest_of_line ();
3168 }
3169
3170 #endif /* ! OBJ_ELF */
3171
3172 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3173
3174 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3175 clears alpha_insn_label and restores auto alignment. */
3176
3177 static void
3178 s_alpha_rdata (ignore)
3179 int ignore;
3180 {
3181 int temp;
3182
3183 temp = get_absolute_expression ();
3184 subseg_new (".rdata", 0);
3185 demand_empty_rest_of_line ();
3186 alpha_insn_label = NULL;
3187 alpha_auto_align_on = 1;
3188 alpha_current_align = 0;
3189 }
3190
3191 #endif
3192
3193 #ifdef OBJ_ECOFF
3194
3195 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3196 clears alpha_insn_label and restores auto alignment. */
3197
3198 static void
3199 s_alpha_sdata (ignore)
3200 int ignore;
3201 {
3202 int temp;
3203
3204 temp = get_absolute_expression ();
3205 subseg_new (".sdata", 0);
3206 demand_empty_rest_of_line ();
3207 alpha_insn_label = NULL;
3208 alpha_auto_align_on = 1;
3209 alpha_current_align = 0;
3210 }
3211 #endif
3212
3213 #ifdef OBJ_ELF
3214
3215 /* Handle the .section pseudo-op. This is like the usual one, but it
3216 clears alpha_insn_label and restores auto alignment. */
3217
3218 static void
3219 s_alpha_section (ignore)
3220 int ignore;
3221 {
3222 obj_elf_section (ignore);
3223
3224 alpha_insn_label = NULL;
3225 alpha_auto_align_on = 1;
3226 alpha_current_align = 0;
3227 }
3228
3229 #endif
3230
3231 #ifdef OBJ_EVAX
3232 static void
3233 s_alpha_link (ignore)
3234 int ignore;
3235 {
3236 int temp;
3237
3238 temp = get_absolute_expression ();
3239 subseg_new (".link", 0);
3240 demand_empty_rest_of_line ();
3241 alpha_insn_label = NULL;
3242 alpha_auto_align_on = 1;
3243 alpha_current_align = 0;
3244 }
3245
3246
3247 /* .prologue */
3248
3249 static void
3250 s_alpha_prologue (ignore)
3251 int ignore;
3252 {
3253 demand_empty_rest_of_line ();
3254
3255 return;
3256 }
3257
3258
3259 /* Parse .ent directives. */
3260
3261 static void
3262 s_alpha_ent (ignore)
3263 int ignore;
3264 {
3265 symbolS *symbol;
3266 expressionS symexpr;
3267
3268 alpha_evax_proc.pdsckind = 0;
3269 alpha_evax_proc.framereg = -1;
3270 alpha_evax_proc.framesize = 0;
3271 alpha_evax_proc.rsa_offset = 0;
3272 alpha_evax_proc.ra_save = AXP_REG_RA;
3273 alpha_evax_proc.fp_save = -1;
3274 alpha_evax_proc.imask = 0;
3275 alpha_evax_proc.fmask = 0;
3276 alpha_evax_proc.prologue = 0;
3277 alpha_evax_proc.type = 0;
3278
3279 expression (&symexpr);
3280
3281 if (symexpr.X_op != O_symbol)
3282 {
3283 as_fatal (".ent directive has no symbol");
3284 demand_empty_rest_of_line ();
3285 return;
3286 }
3287
3288 symbol = make_expr_symbol (&symexpr);
3289 symbol->bsym->flags |= BSF_FUNCTION;
3290 alpha_evax_proc.symbol = symbol;
3291
3292 demand_empty_rest_of_line ();
3293 return;
3294 }
3295
3296
3297 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3298
3299 static void
3300 s_alpha_frame (ignore)
3301 int ignore;
3302 {
3303 long val;
3304
3305 alpha_evax_proc.framereg = tc_get_register (1);
3306
3307 SKIP_WHITESPACE ();
3308 if (*input_line_pointer++ != ','
3309 || get_absolute_expression_and_terminator (&val) != ',')
3310 {
3311 as_warn ("Bad .frame directive 1./2. param");
3312 --input_line_pointer;
3313 demand_empty_rest_of_line ();
3314 return;
3315 }
3316
3317 alpha_evax_proc.framesize = val;
3318
3319 (void) tc_get_register (1);
3320 SKIP_WHITESPACE ();
3321 if (*input_line_pointer++ != ',')
3322 {
3323 as_warn ("Bad .frame directive 3./4. param");
3324 --input_line_pointer;
3325 demand_empty_rest_of_line ();
3326 return;
3327 }
3328 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3329
3330 return;
3331 }
3332
3333 static void
3334 s_alpha_pdesc (ignore)
3335 int ignore;
3336 {
3337 char *name;
3338 char name_end;
3339 long val;
3340 register char *p;
3341 expressionS exp;
3342 symbolS *entry_sym;
3343 fixS *fixp;
3344 segment_info_type *seginfo = seg_info (alpha_link_section);
3345
3346 if (now_seg != alpha_link_section)
3347 {
3348 as_bad (".pdesc directive not in link (.link) section");
3349 demand_empty_rest_of_line ();
3350 return;
3351 }
3352
3353 if ((alpha_evax_proc.symbol == 0)
3354 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3355 {
3356 as_fatal (".pdesc has no matching .ent");
3357 demand_empty_rest_of_line ();
3358 return;
3359 }
3360
3361 alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size;
3362
3363 expression (&exp);
3364 if (exp.X_op != O_symbol)
3365 {
3366 as_warn (".pdesc directive has no entry symbol");
3367 demand_empty_rest_of_line ();
3368 return;
3369 }
3370
3371 entry_sym = make_expr_symbol (&exp);
3372 /* Save bfd symbol of proc desc in function symbol. */
3373 alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym;
3374
3375 SKIP_WHITESPACE ();
3376 if (*input_line_pointer++ != ',')
3377 {
3378 as_warn ("No comma after .pdesc <entryname>");
3379 demand_empty_rest_of_line ();
3380 return;
3381 }
3382
3383 SKIP_WHITESPACE ();
3384 name = input_line_pointer;
3385 name_end = get_symbol_end ();
3386
3387 if (strncmp(name, "stack", 5) == 0)
3388 {
3389 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
3390 }
3391 else if (strncmp(name, "reg", 3) == 0)
3392 {
3393 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
3394 }
3395 else if (strncmp(name, "null", 4) == 0)
3396 {
3397 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
3398 }
3399 else
3400 {
3401 as_fatal ("unknown procedure kind");
3402 demand_empty_rest_of_line ();
3403 return;
3404 }
3405
3406 *input_line_pointer = name_end;
3407 demand_empty_rest_of_line ();
3408
3409 #ifdef md_flush_pending_output
3410 md_flush_pending_output ();
3411 #endif
3412
3413 frag_align (3, 0);
3414 p = frag_more (16);
3415 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3416 fixp->fx_done = 1;
3417 seginfo->literal_pool_size += 16;
3418
3419 *p = alpha_evax_proc.pdsckind
3420 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
3421 *(p+1) = PDSC_S_M_NATIVE
3422 | PDSC_S_M_NO_JACKET;
3423
3424 switch (alpha_evax_proc.pdsckind)
3425 {
3426 case PDSC_S_K_KIND_NULL:
3427 *(p+2) = 0;
3428 *(p+3) = 0;
3429 break;
3430 case PDSC_S_K_KIND_FP_REGISTER:
3431 *(p+2) = alpha_evax_proc.fp_save;
3432 *(p+3) = alpha_evax_proc.ra_save;
3433 break;
3434 case PDSC_S_K_KIND_FP_STACK:
3435 md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
3436 break;
3437 default: /* impossible */
3438 break;
3439 }
3440
3441 *(p+4) = 0;
3442 *(p+5) = alpha_evax_proc.type & 0x0f;
3443
3444 /* Signature offset. */
3445 md_number_to_chars (p+6, (valueT)0, 2);
3446
3447 fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
3448
3449 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
3450 return;
3451
3452 /* Add dummy fix to make add_to_link_pool work. */
3453 p = frag_more (8);
3454 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3455 fixp->fx_done = 1;
3456 seginfo->literal_pool_size += 8;
3457
3458 /* pdesc+16: Size. */
3459 md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
3460
3461 md_number_to_chars (p+4, (valueT)0, 2);
3462
3463 /* Entry length. */
3464 md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
3465
3466 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
3467 return;
3468
3469 /* Add dummy fix to make add_to_link_pool work. */
3470 p = frag_more (8);
3471 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3472 fixp->fx_done = 1;
3473 seginfo->literal_pool_size += 8;
3474
3475 /* pdesc+24: register masks. */
3476
3477 md_number_to_chars (p, alpha_evax_proc.imask, 4);
3478 md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
3479
3480 return;
3481 }
3482
3483
3484 static void
3485 s_alpha_linkage (ignore)
3486 int ignore;
3487 {
3488 expressionS exp;
3489 char *p;
3490
3491 #ifdef md_flush_pending_output
3492 md_flush_pending_output ();
3493 #endif
3494
3495 expression (&exp);
3496 if (exp.X_op != O_symbol)
3497 {
3498 as_fatal ("No symbol after .linkage");
3499 }
3500 else
3501 {
3502 p = frag_more (LKP_S_K_SIZE);
3503 memset (p, 0, LKP_S_K_SIZE);
3504 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
3505 BFD_RELOC_ALPHA_LINKAGE);
3506 }
3507 demand_empty_rest_of_line ();
3508
3509 return;
3510 }
3511
3512
3513 static void
3514 s_alpha_fp_save (ignore)
3515 int ignore;
3516 {
3517
3518 alpha_evax_proc.fp_save = tc_get_register (1);
3519
3520 demand_empty_rest_of_line ();
3521 return;
3522 }
3523
3524
3525 static void
3526 s_alpha_mask (ignore)
3527 int ignore;
3528 {
3529 long val;
3530
3531 if (get_absolute_expression_and_terminator (&val) != ',')
3532 {
3533 as_warn ("Bad .mask directive");
3534 --input_line_pointer;
3535 }
3536 else
3537 {
3538 alpha_evax_proc.imask = val;
3539 (void)get_absolute_expression ();
3540 }
3541 demand_empty_rest_of_line ();
3542
3543 return;
3544 }
3545
3546
3547 static void
3548 s_alpha_fmask (ignore)
3549 int ignore;
3550 {
3551 long val;
3552
3553 if (get_absolute_expression_and_terminator (&val) != ',')
3554 {
3555 as_warn ("Bad .fmask directive");
3556 --input_line_pointer;
3557 }
3558 else
3559 {
3560 alpha_evax_proc.fmask = val;
3561 (void) get_absolute_expression ();
3562 }
3563 demand_empty_rest_of_line ();
3564
3565 return;
3566 }
3567
3568 static void
3569 s_alpha_end (ignore)
3570 int ignore;
3571 {
3572 char c;
3573
3574 c = get_symbol_end ();
3575 *input_line_pointer = c;
3576 demand_empty_rest_of_line ();
3577 alpha_evax_proc.symbol = 0;
3578
3579 return;
3580 }
3581
3582
3583 static void
3584 s_alpha_file (ignore)
3585 int ignore;
3586 {
3587 char* s;
3588 int length;
3589 extern char *demand_copy_string PARAMS ((int *lenP));
3590
3591 get_absolute_expression ();
3592 s = demand_copy_string (&length);
3593 demand_empty_rest_of_line ();
3594
3595 return;
3596 }
3597 #endif /* OBJ_EVAX */
3598
3599 /* Handle the .gprel32 pseudo op. */
3600
3601 static void
3602 s_alpha_gprel32 (ignore)
3603 int ignore;
3604 {
3605 expressionS e;
3606 char *p;
3607
3608 SKIP_WHITESPACE ();
3609 expression (&e);
3610
3611 #ifdef OBJ_ELF
3612 switch (e.X_op)
3613 {
3614 case O_constant:
3615 e.X_add_symbol = section_symbol(absolute_section);
3616 e.X_op = O_symbol;
3617 /* FALLTHRU */
3618 case O_symbol:
3619 break;
3620 default:
3621 abort();
3622 }
3623 #else
3624 #ifdef OBJ_ECOFF
3625 switch (e.X_op)
3626 {
3627 case O_constant:
3628 e.X_add_symbol = section_symbol (absolute_section);
3629 /* fall through */
3630 case O_symbol:
3631 e.X_op = O_subtract;
3632 e.X_op_symbol = alpha_gp_symbol;
3633 break;
3634 default:
3635 abort ();
3636 }
3637 #endif
3638 #endif
3639
3640 if (alpha_auto_align_on && alpha_current_align < 2)
3641 alpha_align (2, (char *) NULL, alpha_insn_label);
3642 if (alpha_current_align > 2)
3643 alpha_current_align = 2;
3644 alpha_insn_label = NULL;
3645
3646 p = frag_more (4);
3647 memset (p, 0, 4);
3648 fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
3649 &e, 0, BFD_RELOC_GPREL32);
3650 }
3651
3652 /* Handle floating point allocation pseudo-ops. This is like the
3653 generic vresion, but it makes sure the current label, if any, is
3654 correctly aligned. */
3655
3656 static void
3657 s_alpha_float_cons (type)
3658 int type;
3659 {
3660 int log_size;
3661
3662 switch (type)
3663 {
3664 default:
3665 case 'f':
3666 case 'F':
3667 log_size = 2;
3668 break;
3669
3670 case 'd':
3671 case 'D':
3672 case 'G':
3673 log_size = 3;
3674 break;
3675
3676 case 'x':
3677 case 'X':
3678 case 'p':
3679 case 'P':
3680 log_size = 4;
3681 break;
3682 }
3683
3684 if (alpha_auto_align_on && alpha_current_align < log_size)
3685 alpha_align (log_size, (char *) NULL, alpha_insn_label);
3686 if (alpha_current_align > log_size)
3687 alpha_current_align = log_size;
3688 alpha_insn_label = NULL;
3689
3690 float_cons (type);
3691 }
3692
3693 /* Handle the .proc pseudo op. We don't really do much with it except
3694 parse it. */
3695
3696 static void
3697 s_alpha_proc (is_static)
3698 int is_static;
3699 {
3700 char *name;
3701 char c;
3702 char *p;
3703 symbolS *symbolP;
3704 int temp;
3705
3706 /* Takes ".proc name,nargs" */
3707 name = input_line_pointer;
3708 c = get_symbol_end ();
3709 p = input_line_pointer;
3710 symbolP = symbol_find_or_make (name);
3711 *p = c;
3712 SKIP_WHITESPACE ();
3713 if (*input_line_pointer != ',')
3714 {
3715 *p = 0;
3716 as_warn ("Expected comma after name \"%s\"", name);
3717 *p = c;
3718 temp = 0;
3719 ignore_rest_of_line ();
3720 }
3721 else
3722 {
3723 input_line_pointer++;
3724 temp = get_absolute_expression ();
3725 }
3726 /* symbolP->sy_other = (signed char) temp; */
3727 as_warn ("unhandled: .proc %s,%d", name, temp);
3728 demand_empty_rest_of_line ();
3729 }
3730
3731 /* Handle the .set pseudo op. This is used to turn on and off most of
3732 the assembler features. */
3733
3734 static void
3735 s_alpha_set (x)
3736 int x;
3737 {
3738 char *name = input_line_pointer, ch, *s;
3739 int yesno = 1;
3740
3741 while (!is_end_of_line[(unsigned char) *input_line_pointer])
3742 input_line_pointer++;
3743 ch = *input_line_pointer;
3744 *input_line_pointer = '\0';
3745
3746 s = name;
3747 if (s[0] == 'n' && s[1] == 'o')
3748 {
3749 yesno = 0;
3750 s += 2;
3751 }
3752 if (!strcmp ("reorder", s))
3753 /* ignore */ ;
3754 else if (!strcmp ("at", s))
3755 alpha_noat_on = !yesno;
3756 else if (!strcmp ("macro", s))
3757 alpha_macros_on = yesno;
3758 else if (!strcmp ("move", s))
3759 /* ignore */ ;
3760 else if (!strcmp ("volatile", s))
3761 /* ignore */ ;
3762 else
3763 as_warn ("Tried to .set unrecognized mode `%s'", name);
3764
3765 *input_line_pointer = ch;
3766 demand_empty_rest_of_line ();
3767 }
3768
3769 /* Handle the .base pseudo op. This changes the assembler's notion of
3770 the $gp register. */
3771
3772 static void
3773 s_alpha_base (ignore)
3774 int ignore;
3775 {
3776 #if 0
3777 if (first_32bit_quadrant)
3778 {
3779 /* not fatal, but it might not work in the end */
3780 as_warn ("File overrides no-base-register option.");
3781 first_32bit_quadrant = 0;
3782 }
3783 #endif
3784
3785 SKIP_WHITESPACE ();
3786 if (*input_line_pointer == '$')
3787 { /* $rNN form */
3788 input_line_pointer++;
3789 if (*input_line_pointer == 'r')
3790 input_line_pointer++;
3791 }
3792
3793 alpha_gp_register = get_absolute_expression ();
3794 if (alpha_gp_register < 0 || alpha_gp_register > 31)
3795 {
3796 alpha_gp_register = AXP_REG_GP;
3797 as_warn ("Bad base register, using $%d.", alpha_gp_register);
3798 }
3799
3800 demand_empty_rest_of_line ();
3801 }
3802
3803 /* Handle the .align pseudo-op. This aligns to a power of two. It
3804 also adjusts any current instruction label. We treat this the same
3805 way the MIPS port does: .align 0 turns off auto alignment. */
3806
3807 static void
3808 s_alpha_align (ignore)
3809 int ignore;
3810 {
3811 int align;
3812 char fill, *pfill;
3813 long max_alignment = 15;
3814
3815 align = get_absolute_expression ();
3816 if (align > max_alignment)
3817 {
3818 align = max_alignment;
3819 as_bad ("Alignment too large: %d. assumed", align);
3820 }
3821 else if (align < 0)
3822 {
3823 as_warn ("Alignment negative: 0 assumed");
3824 align = 0;
3825 }
3826
3827 if (*input_line_pointer == ',')
3828 {
3829 input_line_pointer++;
3830 fill = get_absolute_expression ();
3831 pfill = &fill;
3832 }
3833 else
3834 pfill = NULL;
3835
3836 if (align != 0)
3837 {
3838 alpha_auto_align_on = 1;
3839 alpha_align (align, pfill, alpha_insn_label);
3840 }
3841 else
3842 {
3843 alpha_auto_align_on = 0;
3844 }
3845
3846 demand_empty_rest_of_line ();
3847 }
3848
3849 /* Hook the normal string processor to reset known alignment. */
3850
3851 static void
3852 s_alpha_stringer (terminate)
3853 int terminate;
3854 {
3855 alpha_current_align = 0;
3856 alpha_insn_label = NULL;
3857 stringer (terminate);
3858 }
3859
3860 /* Hook the normal space processing to reset known alignment. */
3861
3862 static void
3863 s_alpha_space (ignore)
3864 int ignore;
3865 {
3866 alpha_current_align = 0;
3867 alpha_insn_label = NULL;
3868 s_space (ignore);
3869 }
3870
3871 /* Hook into cons for auto-alignment. */
3872
3873 void
3874 alpha_cons_align (size)
3875 int size;
3876 {
3877 int log_size;
3878
3879 log_size = 0;
3880 while ((size >>= 1) != 0)
3881 ++log_size;
3882
3883 if (alpha_auto_align_on && alpha_current_align < log_size)
3884 alpha_align (log_size, (char *) NULL, alpha_insn_label);
3885 if (alpha_current_align > log_size)
3886 alpha_current_align = log_size;
3887 alpha_insn_label = NULL;
3888 }
3889 \f
3890 /* The target specific pseudo-ops which we support. */
3891
3892 const pseudo_typeS md_pseudo_table[] =
3893 {
3894 {"common", s_comm, 0}, /* is this used? */
3895 #ifndef OBJ_ELF
3896 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
3897 #endif
3898 {"text", s_alpha_text, 0},
3899 {"data", s_alpha_data, 0},
3900 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3901 {"rdata", s_alpha_rdata, 0},
3902 #endif
3903 #ifdef OBJ_ECOFF
3904 {"sdata", s_alpha_sdata, 0},
3905 #endif
3906 #ifdef OBJ_ELF
3907 {"section", s_alpha_section, 0},
3908 {"section.s", s_alpha_section, 0},
3909 {"sect", s_alpha_section, 0},
3910 {"sect.s", s_alpha_section, 0},
3911 #endif
3912 #ifdef OBJ_EVAX
3913 { "pdesc", s_alpha_pdesc, 0},
3914 { "linkage", s_alpha_linkage, 0},
3915 { "ent", s_alpha_ent, 0},
3916 { "frame", s_alpha_frame, 0},
3917 { "fp_save", s_alpha_fp_save, 0},
3918 { "mask", s_alpha_mask, 0},
3919 { "fmask", s_alpha_fmask, 0},
3920 { "link", s_alpha_link, 0},
3921 { "end", s_alpha_end, 0},
3922 { "file", s_alpha_file, 0},
3923 #endif
3924 {"gprel32", s_alpha_gprel32, 0},
3925 {"t_floating", s_alpha_float_cons, 'd'},
3926 {"s_floating", s_alpha_float_cons, 'f'},
3927 {"f_floating", s_alpha_float_cons, 'F'},
3928 {"g_floating", s_alpha_float_cons, 'G'},
3929 {"d_floating", s_alpha_float_cons, 'D'},
3930
3931 {"proc", s_alpha_proc, 0},
3932 {"aproc", s_alpha_proc, 1},
3933 {"set", s_alpha_set, 0},
3934 {"reguse", s_ignore, 0},
3935 {"livereg", s_ignore, 0},
3936 {"base", s_alpha_base, 0}, /*??*/
3937 {"option", s_ignore, 0},
3938 {"prologue", s_ignore, 0},
3939 {"aent", s_ignore, 0},
3940 {"ugen", s_ignore, 0},
3941 {"eflag", s_ignore, 0},
3942
3943 {"align", s_alpha_align, 0},
3944 {"double", s_alpha_float_cons, 'd'},
3945 {"float", s_alpha_float_cons, 'f'},
3946 {"single", s_alpha_float_cons, 'f'},
3947 {"ascii", s_alpha_stringer, 0},
3948 {"asciz", s_alpha_stringer, 1},
3949 {"string", s_alpha_stringer, 1},
3950 {"space", s_alpha_space, 0},
3951 {"skip", s_alpha_space, 0},
3952 {"zero", s_alpha_space, 0},
3953
3954 /* We don't do any optimizing, so we can safely ignore these. */
3955 {"noalias", s_ignore, 0},
3956 {"alias", s_ignore, 0},
3957
3958 {NULL, 0, 0},
3959 };
3960
3961 \f
3962 /* Build a BFD section with its flags set appropriately for the .lita,
3963 .lit8, or .lit4 sections. */
3964
3965 static void
3966 create_literal_section (name, secp, symp)
3967 const char *name;
3968 segT *secp;
3969 symbolS **symp;
3970 {
3971 segT current_section = now_seg;
3972 int current_subsec = now_subseg;
3973 segT new_sec;
3974
3975 *secp = new_sec = subseg_new (name, 0);
3976 subseg_set (current_section, current_subsec);
3977 bfd_set_section_alignment (stdoutput, new_sec, 4);
3978 bfd_set_section_flags (stdoutput, new_sec,
3979 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
3980 | SEC_DATA);
3981
3982 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
3983 }
3984
3985 #ifdef OBJ_ECOFF
3986
3987 /* @@@ GP selection voodoo. All of this seems overly complicated and
3988 unnecessary; which is the primary reason it's for ECOFF only. */
3989
3990 static inline void
3991 maybe_set_gp (sec)
3992 asection *sec;
3993 {
3994 bfd_vma vma;
3995 if (!sec)
3996 return;
3997 vma = bfd_get_section_vma (foo, sec);
3998 if (vma && vma < alpha_gp_value)
3999 alpha_gp_value = vma;
4000 }
4001
4002 static void
4003 select_gp_value ()
4004 {
4005 assert (alpha_gp_value == 0);
4006
4007 /* Get minus-one in whatever width... */
4008 alpha_gp_value = 0; alpha_gp_value--;
4009
4010 /* Select the smallest VMA of these existing sections. */
4011 maybe_set_gp (alpha_lita_section);
4012 #if 0
4013 /* These were disabled before -- should we use them? */
4014 maybe_set_gp (sdata);
4015 maybe_set_gp (lit8_sec);
4016 maybe_set_gp (lit4_sec);
4017 #endif
4018
4019 /* @@ Will a simple 0x8000 work here? If not, why not? */
4020 #define GP_ADJUSTMENT (0x8000 - 0x10)
4021
4022 alpha_gp_value += GP_ADJUSTMENT;
4023
4024 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4025
4026 #ifdef DEBUG1
4027 printf ("Chose GP value of %lx\n", alpha_gp_value);
4028 #endif
4029 }
4030 #endif /* OBJ_ECOFF */
4031
4032 /* Called internally to handle all alignment needs. This takes care
4033 of eliding calls to frag_align if'n the cached current alignment
4034 says we've already got it, as well as taking care of the auto-align
4035 feature wrt labels. */
4036
4037 static void
4038 alpha_align (n, pfill, label)
4039 int n;
4040 char *pfill;
4041 symbolS *label;
4042 {
4043 if (alpha_current_align >= n)
4044 return;
4045
4046 if (pfill == NULL)
4047 {
4048 if (n > 2
4049 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
4050 {
4051 static char const nop[4] = { 0x1f, 0x04, 0xff, 0x47 };
4052
4053 /* First, make sure we're on a four-byte boundary, in case
4054 someone has been putting .byte values into the text
4055 section. The DEC assembler silently fills with unaligned
4056 no-op instructions. This will zero-fill, then nop-fill
4057 with proper alignment. */
4058 if (alpha_current_align < 2)
4059 frag_align (2, 0);
4060 frag_align_pattern (n, nop, sizeof nop);
4061 }
4062 else
4063 frag_align (n, 0);
4064 }
4065 else
4066 frag_align (n, *pfill);
4067
4068 alpha_current_align = n;
4069
4070 if (label != NULL)
4071 {
4072 assert (S_GET_SEGMENT (label) == now_seg);
4073 label->sy_frag = frag_now;
4074 S_SET_VALUE (label, (valueT) frag_now_fix ());
4075 }
4076
4077 record_alignment(now_seg, n);
4078 }
4079
4080 /* The Alpha has support for some VAX floating point types, as well as for
4081 IEEE floating point. We consider IEEE to be the primary floating point
4082 format, and sneak in the VAX floating point support here. */
4083 #define md_atof vax_md_atof
4084 #include "config/atof-vax.c"