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