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