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