]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-alpha.c
* config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until after any
[thirdparty/binutils-gdb.git] / gas / config / tc-alpha.c
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha CPU.
2 Copyright (C) 1989, 1993, 1994 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
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 /*
24 * Mach Operating System
25 * Copyright (c) 1993 Carnegie Mellon University
26 * All Rights Reserved.
27 *
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
33 *
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
37 *
38 * Carnegie Mellon requests users of this software to return to
39 *
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
44 *
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
47 */
48 /*
49 * HISTORY
50 * 5-Oct-93 Alessandro Forin (af) at Carnegie-Mellon University
51 * First Checkin
52 *
53 * Author: Alessandro Forin, Carnegie Mellon University
54 * Date: Jan 1993
55 */
56
57 #include <ctype.h>
58
59 #include "as.h"
60 #include "alpha-opcode.h"
61 #include "subsegs.h"
62
63 /* @@ Will a simple 0x8000 work here? If not, why not? */
64 #define GP_ADJUSTMENT (0x8000 - 0x10)
65
66 /* Which machine type is this? Currently stores an integer for the
67 model, one of: 21064, 21066, 21164. */
68 static unsigned long machine;
69
70 /* These are exported to relaxing code, even though we don't do any
71 relaxing on this processor currently. */
72 const relax_typeS md_relax_table[1];
73 int md_short_jump_size = 4;
74 int md_long_jump_size = 4;
75
76 /* handle of the OPCODE hash table */
77 static struct hash_control *op_hash;
78
79 /* Sections and symbols we'll want to keep track of. */
80 static segT lita_sec, rdata, sdata, lit8_sec, lit4_sec;
81 static symbolS *lit8_sym, *lit4_sym;
82
83 /* Setting for ".set [no]{at,macro}". */
84 static int at_ok = 1, macro_ok = 1;
85
86 /* Keep track of global pointer. */
87 valueT alpha_gp_value;
88 static symbolS *gp;
89
90 /* We'll probably be using this relocation frequently, and we
91 will want to compare for it. */
92 static const reloc_howto_type *gpdisp_hi16_howto;
93
94 /* These are exported to ECOFF code. */
95 unsigned long alpha_gprmask, alpha_fprmask;
96
97 /* Used for LITUSE relocations. */
98 static expressionS lituse_basereg, lituse_byteoff, lituse_jsr;
99
100 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
101 cause all addresses to be treated as 32-bit values in memory. (The
102 in-register versions are all sign-extended to 64 bits, of course.)
103 Some other systems may want this option too. */
104 static int addr32;
105
106 /* Imported functions -- they should be defined in header files somewhere. */
107 extern segT subseg_get ();
108 extern PTR bfd_alloc_by_size_t ();
109 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
110 s_data (), float_cons ();
111
112 /* Static functions, needing forward declarations. */
113 static void s_base (), s_proc (), s_alpha_set ();
114 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
115 static int alpha_ip ();
116
117 static void emit_unaligned_io PARAMS ((char *, int, valueT, int));
118 static void emit_load_unal PARAMS ((int, valueT, int));
119 static void emit_store_unal PARAMS ((int, valueT, int));
120 static void emit_byte_manip_r PARAMS ((char *, int, int, int, int, int));
121 static void emit_extract_r PARAMS ((int, int, int, int, int));
122 static void emit_insert_r PARAMS ((int, int, int, int, int));
123 static void emit_mask_r PARAMS ((int, int, int, int, int));
124 static void emit_sign_extend PARAMS ((int, int));
125 static void emit_bis_r PARAMS ((int, int, int));
126 static int build_mem PARAMS ((int, int, int, bfd_signed_vma));
127 static int build_operate_n PARAMS ((int, int, int, int, int));
128 static void emit_sll_n PARAMS ((int, int, int));
129 static void emit_ldah_num PARAMS ((int, bfd_vma, int));
130 static void emit_addq_r PARAMS ((int, int, int));
131 static void emit_lda_n PARAMS ((int, bfd_vma, int));
132 static void emit_add64 PARAMS ((int, int, bfd_vma));
133 static int in_range_signed PARAMS ((bfd_vma, int));
134
135 const pseudo_typeS md_pseudo_table[] =
136 {
137 {"common", s_comm, 0}, /* is this used? */
138 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
139 {"rdata", s_rdata, 0},
140 {"sdata", s_sdata, 0},
141 {"gprel32", s_gprel32, 0},
142 {"t_floating", float_cons, 'd'},
143 {"s_floating", float_cons, 'f'},
144 {"f_floating", float_cons, 'F'},
145 {"g_floating", float_cons, 'G'},
146 {"d_floating", float_cons, 'D'},
147
148 {"proc", s_proc, 0},
149 {"aproc", s_proc, 1},
150 {"set", s_alpha_set, 0},
151 {"reguse", s_ignore, 0},
152 {"livereg", s_ignore, 0},
153 {"extern", s_ignore, 0}, /*??*/
154 {"base", s_base, 0}, /*??*/
155 {"option", s_ignore, 0},
156 {"prologue", s_ignore, 0},
157 {"aent", s_ignore, 0},
158 {"ugen", s_ignore, 0},
159
160 /* We don't do any optimizing, so we can safely ignore these. */
161 {"noalias", s_ignore, 0},
162 {"alias", s_ignore, 0},
163
164 {NULL, 0, 0},
165 };
166
167 #define SA 21 /* shift for register Ra */
168 #define SB 16 /* shift for register Rb */
169 #define SC 0 /* shift for register Rc */
170 #define SN 13 /* shift for 8 bit immediate # */
171
172 #define T9 23
173 #define T10 24
174 #define T11 25
175 #define T12 26
176 #define RA 26 /* note: same as T12 */
177 #define PV 27
178 #define AT 28
179 #define GP 29
180 #define SP 30
181 #define ZERO 31
182
183 #define OPCODE(X) (((X) >> 26) & 0x3f)
184 #define OP_FCN(X) (((X) >> 5) & 0x7f)
185
186 #ifndef FIRST_32BIT_QUADRANT
187 #define FIRST_32BIT_QUADRANT 0
188 #endif
189
190 int first_32bit_quadrant = FIRST_32BIT_QUADRANT;
191 int base_register = FIRST_32BIT_QUADRANT ? ZERO : GP;
192
193 int no_mixed_code = 0;
194 int nofloats = 0;
195
196 /* This array holds the chars that always start a comment. If the
197 pre-processor is disabled, these aren't very useful */
198 const char comment_chars[] = "#";
199
200 /* This array holds the chars that only start a comment at the beginning of
201 a line. If the line seems to have the form '# 123 filename'
202 .line and .file directives will appear in the pre-processed output */
203 /* Note that input_file.c hand checks for '#' at the beginning of the
204 first line of the input file. This is because the compiler outputs
205 #NO_APP at the beginning of its output. */
206 /* Also note that C style comments are always recognized. */
207 const char line_comment_chars[] = "#!";
208
209 /* Chars that can be used to separate mant from exp in floating point nums */
210 const char EXP_CHARS[] = "eE";
211
212 const char line_separator_chars[1];
213
214 /* Chars that mean this number is a floating point constant, as in
215 "0f12.456" or "0d1.2345e12". */
216 /* @@ Do all of these really get used on the alpha?? */
217 char FLT_CHARS[] = "rRsSfFdDxXpP";
218
219 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
220 changed in read.c. Ideally it shouldn't have to know about it at all,
221 but nothing is ideal around here. */
222
223 struct reloc_data {
224 expressionS exp;
225 int pcrel;
226 bfd_reloc_code_real_type code;
227 };
228
229 /* Occasionally, two relocations will be desired for one address.
230 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
231 and a HINT reloc. */
232 #define MAX_RELOCS 2
233
234 struct alpha_it {
235 unsigned long opcode; /* need at least 32 bits */
236 struct reloc_data reloc[MAX_RELOCS];
237 };
238
239 static void getExpression (char *str, struct alpha_it *insn);
240 static char *expr_end;
241
242 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
243 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
244
245 int
246 tc_get_register (frame)
247 int frame;
248 {
249 int framereg = SP;
250
251 SKIP_WHITESPACE ();
252 if (*input_line_pointer == '$')
253 {
254 input_line_pointer++;
255 if (input_line_pointer[0] == 's'
256 && input_line_pointer[1] == 'p')
257 {
258 input_line_pointer += 2;
259 framereg = SP;
260 }
261 else
262 framereg = get_absolute_expression ();
263 framereg &= 31; /* ? */
264 }
265 else
266 as_warn ("frame reg expected, using $%d.", framereg);
267
268 note_gpreg (framereg);
269 return framereg;
270 }
271
272 static void
273 s_rdata (ignore)
274 int ignore;
275 {
276 int temp;
277
278 temp = get_absolute_expression ();
279 #if 0
280 if (!rdata)
281 rdata = subseg_get (".rdata", 0);
282 subseg_set (rdata, (subsegT) temp);
283 #else
284 rdata = subseg_new (".rdata", 0);
285 #endif
286 demand_empty_rest_of_line ();
287 }
288
289 static void
290 s_sdata (ignore)
291 int ignore;
292 {
293 int temp;
294
295 temp = get_absolute_expression ();
296 #if 0
297 if (!sdata)
298 sdata = subseg_get (".sdata", 0);
299 subseg_set (sdata, (subsegT) temp);
300 #else
301 sdata = subseg_new (".sdata", 0);
302 #endif
303 demand_empty_rest_of_line ();
304 }
305
306 static void
307 s_alpha_comm (ignore)
308 int ignore;
309 {
310 register char *name;
311 register char c;
312 register char *p;
313 offsetT temp;
314 register symbolS *symbolP;
315
316 name = input_line_pointer;
317 c = get_symbol_end ();
318 /* just after name is now '\0' */
319 p = input_line_pointer;
320 *p = c;
321 SKIP_WHITESPACE ();
322 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
323 if (*input_line_pointer == ',')
324 {
325 input_line_pointer++;
326 SKIP_WHITESPACE ();
327 }
328 if ((temp = get_absolute_expression ()) < 0)
329 {
330 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
331 ignore_rest_of_line ();
332 return;
333 }
334 *p = 0;
335 symbolP = symbol_find_or_make (name);
336 *p = c;
337 if (S_IS_DEFINED (symbolP))
338 {
339 as_bad ("Ignoring attempt to re-define symbol");
340 ignore_rest_of_line ();
341 return;
342 }
343 if (S_GET_VALUE (symbolP))
344 {
345 if (S_GET_VALUE (symbolP) != (valueT) temp)
346 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
347 S_GET_NAME (symbolP),
348 (long) S_GET_VALUE (symbolP),
349 (long) temp);
350 }
351 else
352 {
353 S_SET_VALUE (symbolP, (valueT) temp);
354 S_SET_EXTERNAL (symbolP);
355 }
356
357 know (symbolP->sy_frag == &zero_address_frag);
358 demand_empty_rest_of_line ();
359 }
360
361 arelent *
362 tc_gen_reloc (sec, fixp)
363 asection *sec;
364 fixS *fixp;
365 {
366 arelent *reloc;
367
368 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
369 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
370 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
371
372 if (fixp->fx_r_type > BFD_RELOC_UNUSED)
373 abort ();
374
375 if (fixp->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
376 {
377 if (!gpdisp_hi16_howto)
378 gpdisp_hi16_howto = bfd_reloc_type_lookup (stdoutput,
379 fixp->fx_r_type);
380 reloc->howto = gpdisp_hi16_howto;
381 }
382 else
383 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
384 assert (reloc->howto != 0);
385 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
386 {
387 as_fatal ("internal error? cannot generate `%s' relocation",
388 bfd_get_reloc_code_name (fixp->fx_r_type));
389 }
390 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
391
392 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
393 {
394 /* fake out bfd_perform_relocation. sigh */
395 reloc->addend = -alpha_gp_value;
396 }
397 else if (reloc->howto->pc_relative && reloc->howto->pcrel_offset)
398 {
399 reloc->addend = fixp->fx_offset - reloc->address;
400 }
401 else
402 reloc->addend = fixp->fx_offset;
403 return reloc;
404 }
405
406 static void
407 s_base ()
408 {
409 if (first_32bit_quadrant)
410 {
411 /* not fatal, but it might not work in the end */
412 as_warn ("File overrides no-base-register option.");
413 first_32bit_quadrant = 0;
414 }
415
416 SKIP_WHITESPACE ();
417 if (*input_line_pointer == '$')
418 { /* $rNN form */
419 input_line_pointer++;
420 if (*input_line_pointer == 'r')
421 input_line_pointer++;
422 }
423
424 base_register = get_absolute_expression ();
425 if (base_register < 0 || base_register > 31)
426 {
427 base_register = GP;
428 as_warn ("Bad base register, using $%d.", base_register);
429 }
430 demand_empty_rest_of_line ();
431 }
432
433 static int in_range_signed (val, nbits)
434 bfd_vma val;
435 int nbits;
436 {
437 /* Look at top bit of value that would be stored, figure out how it
438 would be extended by the hardware, and see if that matches the
439 original supplied value. */
440 bfd_vma mask;
441 bfd_vma one = 1;
442 bfd_vma top_bit, stored_value, missing_bits;
443
444 mask = (one << nbits) - 1;
445 stored_value = val & mask;
446 top_bit = stored_value & (one << nbits - 1);
447 missing_bits = val & ~mask;
448 /* will sign-extend */
449 if (top_bit)
450 {
451 /* all remaining bits beyond mask should be one */
452 missing_bits |= mask;
453 return missing_bits + 1 == 0;
454 }
455 else
456 {
457 /* all other bits should be zero */
458 return missing_bits == 0;
459 }
460 }
461
462 #if 0
463 static int in_range_unsigned (val, nbits)
464 bfd_vma val;
465 int nbits;
466 {
467 /* Look at top bit of value that would be stored, figure out how it
468 would be extended by the hardware, and see if that matches the
469 original supplied value. */
470 bfd_vma mask;
471 bfd_vma one = 1;
472 bfd_vma top_bit, stored_value, missing_bits;
473
474 mask = (one << nbits) - 1;
475 stored_value = val & mask;
476 top_bit = stored_value & (one << nbits - 1);
477 missing_bits = val & ~mask;
478 return missing_bits == 0;
479 }
480 #endif
481
482 static void
483 s_gprel32 ()
484 {
485 expressionS e;
486 char *p;
487
488 SKIP_WHITESPACE ();
489 expression (&e);
490 switch (e.X_op)
491 {
492 case O_constant:
493 e.X_add_symbol = section_symbol (absolute_section);
494 /* fall through */
495 case O_symbol:
496 e.X_op = O_subtract;
497 e.X_op_symbol = gp;
498 break;
499 default:
500 abort ();
501 }
502 p = frag_more (4);
503 memset (p, 0, 4);
504 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &e, 0,
505 BFD_RELOC_GPREL32);
506 }
507
508 static void
509 create_literal_section (secp, name)
510 segT *secp;
511 const char *name;
512 {
513 segT current_section = now_seg;
514 int current_subsec = now_subseg;
515 segT new_sec;
516
517 *secp = new_sec = subseg_new (name, 0);
518 subseg_set (current_section, current_subsec);
519 bfd_set_section_alignment (stdoutput, new_sec, 3);
520 bfd_set_section_flags (stdoutput, new_sec,
521 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
522 | SEC_DATA);
523 }
524
525 static valueT
526 get_lit8_offset (val)
527 bfd_vma val;
528 {
529 valueT retval;
530 if (lit8_sec == 0)
531 {
532 create_literal_section (&lit8_sec, ".lit8");
533 lit8_sym = section_symbol (lit8_sec);
534 }
535 retval = add_to_literal_pool ((symbolS *) 0, val, lit8_sec, 8);
536 if (retval >= 0xfff0)
537 as_fatal ("overflow in fp literal (.lit8) table");
538 return retval;
539 }
540
541 static valueT
542 get_lit4_offset (val)
543 bfd_vma val;
544 {
545 valueT retval;
546 if (lit4_sec == 0)
547 {
548 create_literal_section (&lit4_sec, ".lit4");
549 lit4_sym = section_symbol (lit4_sec);
550 }
551 retval = add_to_literal_pool ((symbolS *) 0, val, lit4_sec, 4);
552 if (retval >= 0xfff0)
553 as_fatal ("overflow in fp literal (.lit4) table");
554 return retval;
555 }
556
557 #define load_insn(NAME, OP) (hash_insert (op_hash, (NAME), (PTR) (OP)))
558
559 static void
560 load_insn_table (ops, size)
561 struct alpha_opcode *ops;
562 int size;
563 {
564 struct alpha_opcode *end = ops + size;
565 struct alpha_opcode *op;
566 const char *name;
567
568 for (op = ops; op < end; )
569 {
570 const char *retval;
571
572 name = op->name;
573
574 retval = load_insn (op->name, op);
575 if (retval)
576 as_fatal ("internal error: can't hash opcode `%s': %s",
577 op->name, retval);
578
579 do
580 op++;
581 while (op < end
582 && (op->name == name
583 || !strcmp (op->name, name)));
584 }
585 /* Some opcodes include modifiers of various sorts with a "/mod"
586 syntax, like the architecture documentation suggests. However,
587 for use with gcc at least, we also need to access those same
588 opcodes without the "/". */
589 for (op = ops; op < end; )
590 {
591 name = op->name;
592
593 if (strchr (name, '/'))
594 {
595 char *name2, *p;
596 const char *q;
597
598 name2 = xmalloc (strlen (name));
599 p = name2;
600 q = name;
601
602 while (*q)
603 if (*q == '/')
604 q++;
605 else
606 *p++ = *q++;
607 *p = 0;
608 /* Ignore failures -- the opcode table does duplicate some
609 variants in different forms, like "hw_stq" and "hw_st/q".
610 Maybe the variants can be eliminated, and this error checking
611 restored. */
612 load_insn (name2, op);
613 }
614
615 do
616 op++;
617 while (op < end
618 && (op->name == name
619 || !strcmp (op->name, name)));
620 }
621 }
622
623 static struct alpha_it clear_insn;
624
625 /* This function is called once, at assembler startup time. It should
626 set up all the tables, etc. that the MD part of the assembler will
627 need, that can be determined before arguments are parsed. */
628 void
629 md_begin ()
630 {
631 int i;
632
633 op_hash = hash_new ();
634 load_insn_table (alpha_opcodes, NUMOPCODES);
635
636 /* Default to 21064 PAL instructions. */
637 if (machine == 0)
638 machine = 21064;
639
640 switch (machine)
641 {
642 case 21064:
643 case 21066:
644 load_insn_table (alpha_pal21064_opcodes, NUM21064OPCODES);
645 break;
646 case 21164:
647 load_insn_table (alpha_pal21164_opcodes, NUM21164OPCODES);
648 break;
649 default:
650 as_fatal ("palcode set unknown (internal error)");
651 }
652
653 lituse_basereg.X_op = O_constant;
654 lituse_basereg.X_add_number = 1;
655 lituse_byteoff.X_op = O_constant;
656 lituse_byteoff.X_add_number = 2;
657 lituse_jsr.X_op = O_constant;
658 lituse_jsr.X_add_number = 3;
659
660 /* So .sbss will get used for tiny objects. */
661 bfd_set_gp_size (stdoutput, 8);
662 create_literal_section (&lita_sec, ".lita");
663 /* For handling the GP, create a symbol that won't be output in the
664 symbol table. We'll edit it out of relocs later. */
665 gp = symbol_create ("<GP value>", lita_sec, 0x8000, &zero_address_frag);
666
667 memset (&clear_insn, 0, sizeof (clear_insn));
668 for (i = 0; i < MAX_RELOCS; i++)
669 clear_insn.reloc[i].code = BFD_RELOC_NONE;
670 }
671
672 int optnum = 1;
673
674 static void
675 emit_insn (insn)
676 struct alpha_it *insn;
677 {
678 char *toP;
679 int j;
680
681 toP = frag_more (4);
682
683 /* put out the opcode */
684 md_number_to_chars (toP, insn->opcode, 4);
685
686 /* put out the symbol-dependent stuff */
687 for (j = 0; j < MAX_RELOCS; j++)
688 {
689 struct reloc_data *r = &insn->reloc[j];
690 fixS *f;
691
692 if (r->code != BFD_RELOC_NONE)
693 {
694 if (r->exp.X_op == O_constant)
695 {
696 r->exp.X_add_symbol = section_symbol (absolute_section);
697 r->exp.X_op = O_symbol;
698 }
699 f = fix_new_exp (frag_now, (toP - frag_now->fr_literal), 4,
700 &r->exp, r->pcrel, r->code);
701 }
702 if (r->code == BFD_RELOC_ALPHA_GPDISP_LO16)
703 {
704 static bit_fixS cookie;
705 /* @@ This'll make the range checking in write.c shut up. */
706 f->fx_bit_fixP = &cookie;
707 }
708 }
709 }
710
711 void
712 md_assemble (str)
713 char *str;
714 {
715 int i, count;
716 #define MAX_INSNS 5
717 struct alpha_it insns[MAX_INSNS];
718
719 count = alpha_ip (str, insns);
720 if (count <= 0)
721 return;
722
723 for (i = 0; i < count; i++)
724 emit_insn (&insns[i]);
725 }
726
727 static inline void
728 maybe_set_gp (sec)
729 asection *sec;
730 {
731 bfd_vma vma;
732 if (!sec)
733 return;
734 vma = bfd_get_section_vma (foo, sec);
735 if (vma && vma < alpha_gp_value)
736 alpha_gp_value = vma;
737 }
738
739 static void
740 select_gp_value ()
741 {
742 if (alpha_gp_value != 0)
743 abort ();
744
745 /* Get minus-one in whatever width... */
746 alpha_gp_value = 0; alpha_gp_value--;
747
748 /* Select the smallest VMA of these existing sections. */
749 maybe_set_gp (lita_sec);
750 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
751 #if 0
752 maybe_set_gp (lit8_sec);
753 maybe_set_gp (lit4_sec);
754 #endif
755
756 alpha_gp_value += GP_ADJUSTMENT;
757
758 S_SET_VALUE (gp, alpha_gp_value);
759
760 #ifdef DEBUG1
761 printf ("Chose GP value of %lx\n", alpha_gp_value);
762 #endif
763 }
764
765 int
766 alpha_force_relocation (f)
767 fixS *f;
768 {
769 switch (f->fx_r_type)
770 {
771 case BFD_RELOC_ALPHA_GPDISP_HI16:
772 case BFD_RELOC_ALPHA_GPDISP_LO16:
773 case BFD_RELOC_ALPHA_LITERAL:
774 case BFD_RELOC_ALPHA_LITUSE:
775 case BFD_RELOC_GPREL32:
776 return 1;
777 case BFD_RELOC_ALPHA_HINT:
778 case BFD_RELOC_64:
779 case BFD_RELOC_32:
780 case BFD_RELOC_16:
781 case BFD_RELOC_8:
782 case BFD_RELOC_23_PCREL_S2:
783 case BFD_RELOC_14:
784 case BFD_RELOC_26:
785 return 0;
786 default:
787 abort ();
788 return 0;
789 }
790 }
791
792 int
793 alpha_fix_adjustable (f)
794 fixS *f;
795 {
796 /* Are there any relocation types for which we must generate a reloc
797 but we can adjust the values contained within it? */
798 switch (f->fx_r_type)
799 {
800 case BFD_RELOC_ALPHA_GPDISP_HI16:
801 case BFD_RELOC_ALPHA_GPDISP_LO16:
802 return 0;
803 case BFD_RELOC_GPREL32:
804 return 1;
805 default:
806 return !alpha_force_relocation (f);
807 }
808 /*NOTREACHED*/
809 }
810
811 valueT
812 md_section_align (seg, size)
813 segT seg;
814 valueT size;
815 {
816 #ifdef OBJ_ECOFF
817 /* This should probably be handled within BFD, or by pulling the
818 number from BFD at least. */
819 #define MIN 15
820 size += MIN;
821 size &= ~MIN;
822 #endif
823 return size;
824 }
825
826 /* Add this thing to the .lita section and produce a LITERAL reloc referring
827 to it. */
828
829 /* Are we currently eligible to emit a LITUSE reloc for the literal
830 references just generated? */
831 static int lituse_pending;
832
833 static void
834 load_symbol_address (reg, insn)
835 int reg;
836 struct alpha_it *insn;
837 {
838 static symbolS *lita_sym;
839
840 int x;
841 valueT retval;
842
843 if (!lita_sym)
844 {
845 lita_sym = section_symbol (lita_sec);
846 S_CLEAR_EXTERNAL (lita_sym);
847 }
848
849 retval = add_to_literal_pool (insn->reloc[0].exp.X_add_symbol,
850 insn->reloc[0].exp.X_add_number,
851 lita_sec, 8);
852
853 /* Now emit a LITERAL relocation for the original section. */
854 insn->reloc[0].exp.X_op = O_symbol;
855 insn->reloc[0].exp.X_add_symbol = lita_sym;
856 insn->reloc[0].exp.X_add_number = retval;
857 insn->reloc[0].code = BFD_RELOC_ALPHA_LITERAL;
858 lituse_pending = 1;
859
860 if (retval == 0x8000)
861 /* Overflow? */
862 as_fatal ("overflow in literal (.lita) table");
863 x = retval;
864 if (addr32)
865 insn->opcode = (0xa0000000 /* ldl */
866 | (reg << SA)
867 | (base_register << SB)
868 | (x & 0xffff));
869 else
870 insn->opcode = (0xa4000000 /* ldq */
871 | (reg << SA)
872 | (base_register << SB)
873 | (x & 0xffff));
874 note_gpreg (base_register);
875 }
876
877 /* To load an address with a single instruction,
878 emit a LITERAL reloc in this section, and a REFQUAD
879 for the .lita section, so that we'll be able to access
880 it via $gp:
881 lda REG, xx -> ldq REG, -32752(gp)
882 lda REG, xx+4 -> ldq REG, -32752(gp)
883 lda REG, 4(REG)
884
885 The offsets need to start near -0x8000, and the generated LITERAL
886 relocations should negate the offset. I don't completely grok the
887 scheme yet. */
888
889 static int
890 load_expression (reg, insn)
891 int reg;
892 struct alpha_it *insn;
893 {
894 valueT addend, addendhi, addendlo;
895 int num_insns = 1;
896
897 if (insn->reloc[0].exp.X_add_symbol->bsym->flags & BSF_SECTION_SYM)
898 {
899 addend = 0;
900 }
901 else
902 {
903 addend = insn->reloc[0].exp.X_add_number;
904 insn->reloc[0].exp.X_add_number = 0;
905 }
906 load_symbol_address (reg, insn);
907 if (addend)
908 {
909 if ((addend & ~0x7fffffff) != 0
910 && (addend & ~0x7fffffff) + 0x80000000 != 0)
911 {
912 as_bad ("assembler not prepared to handle constants >32 bits yet");
913 addend = 0;
914 }
915 addendlo = addend & 0xffff;
916 addend -= addendlo;
917 addendhi = addend >> 16;
918 if (addendlo & 0x8000)
919 addendhi++;
920 /* It appears that the BASEREG LITUSE reloc should not be used on
921 an LDAH instruction. */
922 if (addendlo)
923 {
924 insn[1].opcode = (0x20000000 /* lda */
925 | (reg << SA)
926 | (reg << SB)
927 | (addendlo & 0xffff));
928 insn[1].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
929 insn[1].reloc[0].exp = lituse_basereg;
930 num_insns++;
931 }
932 if (addendhi)
933 {
934 insn[num_insns].opcode = (0x24000000
935 | (reg << SA)
936 | (reg << SB)
937 | (addendhi & 0xffff));
938 num_insns++;
939 }
940 if (num_insns == 1)
941 abort ();
942 lituse_pending = 0;
943 }
944 return num_insns;
945 }
946
947 static inline void
948 getExpression (str, this_insn)
949 char *str;
950 struct alpha_it *this_insn;
951 {
952 char *save_in;
953 segT seg;
954
955 #if 0 /* Not converted to bfd yet, and I don't think we need them
956 for ECOFF. Re-adding a.out support will probably require
957 them though. */
958 static const struct am {
959 char *name;
960 bfd_reloc_code_real_type reloc;
961 } macro[] = {
962 { "hi", RELOC_48_63 },
963 { "lo", RELOC_0_15 },
964 { "ml", RELOC_16_31 },
965 { "mh", RELOC_32_47 },
966 { "uhi", RELOC_U_48_63 },
967 { "uml", RELOC_U_16_31 },
968 { "umh", RELOC_U_32_47 },
969 { 0, }
970 };
971
972 /* Handle macros: "%macroname(expr)" */
973 if (*str == '%')
974 {
975 struct am *m;
976 char *p, *q;
977
978 str++;
979 m = &macro[0];
980 while (q = m->name)
981 {
982 p = str;
983 while (*q && *p == *q)
984 p++, q++;
985 if (*q == 0)
986 break;
987 m++;
988 }
989 if (q)
990 {
991 str = p; /* keep the '(' */
992 this_insn->reloc = m->reloc;
993 }
994 }
995 #endif
996
997 save_in = input_line_pointer;
998 input_line_pointer = str;
999
1000 seg = expression (&this_insn->reloc[0].exp);
1001 /* XXX validate seg and exp, make sure they're reasonable */
1002 expr_end = input_line_pointer;
1003 input_line_pointer = save_in;
1004 }
1005
1006 static void
1007 emit_unaligned_io (dir, addr_reg, addr_offset, reg)
1008 char *dir;
1009 int addr_reg, reg;
1010 valueT addr_offset;
1011 {
1012 char buf[90];
1013 sprintf (buf, "%sq_u $%d,%ld($%d)", dir, reg, (long) addr_offset, addr_reg);
1014 md_assemble (buf);
1015 }
1016
1017 static void
1018 emit_load_unal (addr_reg, addr_offset, reg)
1019 int addr_reg, reg;
1020 valueT addr_offset;
1021 {
1022 emit_unaligned_io ("ld", addr_reg, addr_offset, reg);
1023 }
1024
1025 static void
1026 emit_store_unal (addr_reg, addr_offset, reg)
1027 int addr_reg, reg;
1028 valueT addr_offset;
1029 {
1030 emit_unaligned_io ("st", addr_reg, addr_offset, reg);
1031 }
1032
1033 static void
1034 emit_byte_manip_r (op, in, mask, out, mode, which)
1035 char *op;
1036 int in, mask, out, mode, which;
1037 {
1038 char buf[90];
1039 sprintf (buf, "%s%c%c $%d,$%d,$%d", op, mode, which, in, mask, out);
1040 md_assemble (buf);
1041 }
1042
1043 static void
1044 emit_extract_r (in, mask, out, mode, which)
1045 int in, mask, out, mode, which;
1046 {
1047 emit_byte_manip_r ("ext", in, mask, out, mode, which);
1048 }
1049
1050 static void
1051 emit_insert_r (in, mask, out, mode, which)
1052 int in, mask, out, mode, which;
1053 {
1054 emit_byte_manip_r ("ins", in, mask, out, mode, which);
1055 }
1056
1057 static void
1058 emit_mask_r (in, mask, out, mode, which)
1059 int in, mask, out, mode, which;
1060 {
1061 emit_byte_manip_r ("msk", in, mask, out, mode, which);
1062 }
1063
1064 static void
1065 emit_sign_extend (reg, size)
1066 int reg, size;
1067 {
1068 char buf[90];
1069 sprintf (buf, "sll $%d,0x%x,$%d", reg, 64 - size, reg);
1070 md_assemble (buf);
1071 sprintf (buf, "sra $%d,0x%x,$%d", reg, 64 - size, reg);
1072 md_assemble (buf);
1073 }
1074
1075 static void
1076 emit_bis_r (in1, in2, out)
1077 int in1, in2, out;
1078 {
1079 char buf[90];
1080 sprintf (buf, "bis $%d,$%d,$%d", in1, in2, out);
1081 md_assemble (buf);
1082 }
1083
1084 static int
1085 build_mem (opc, ra, rb, disp)
1086 int opc, ra, rb;
1087 bfd_signed_vma disp;
1088 {
1089 if ((disp >> 15) != 0
1090 && (disp >> 15) + 1 != 0)
1091 abort ();
1092 return ((opc << 26) | (ra << SA) | (rb << SB) | (disp & 0xffff));
1093 }
1094
1095 static int
1096 build_operate_n (opc, fn, ra, lit, rc)
1097 int opc, fn, ra, rc;
1098 int lit;
1099 {
1100 if (lit & ~0xff)
1101 abort ();
1102 return ((opc << 26) | (fn << 5) | (ra << SA) | (lit << SN) | (1 << 12) | (rc << SC));
1103 }
1104
1105 static void
1106 emit_sll_n (dest, disp, src)
1107 int dest, disp, src;
1108 {
1109 struct alpha_it insn = clear_insn;
1110 insn.opcode = build_operate_n (0x12, 0x39, src, disp, dest);
1111 emit_insn (&insn);
1112 }
1113
1114 static void
1115 emit_ldah_num (dest, addend, src)
1116 int dest, src;
1117 bfd_vma addend;
1118 {
1119 struct alpha_it insn = clear_insn;
1120 insn.opcode = build_mem (0x09, dest, src, addend);
1121 emit_insn (&insn);
1122 }
1123
1124 static void
1125 emit_addq_r (in1, in2, out)
1126 int in1, in2, out;
1127 {
1128 struct alpha_it insn = clear_insn;
1129 insn.opcode = 0x40000400 | (in1 << SA) | (in2 << SB) | (out << SC);
1130 emit_insn (&insn);
1131 }
1132
1133 static void
1134 emit_lda_n (dest, addend, src)
1135 int dest, src;
1136 bfd_vma addend;
1137 {
1138 struct alpha_it insn = clear_insn;
1139 insn.opcode = build_mem (0x08, dest, src, addend);
1140 emit_insn (&insn);
1141 }
1142
1143 static void
1144 emit_add64 (in, out, num)
1145 int in, out;
1146 bfd_vma num;
1147 {
1148 bfd_signed_vma snum = num;
1149
1150 if (in_range_signed (num, 16))
1151 {
1152 emit_lda_n (out, num, in);
1153 return;
1154 }
1155 if ((num & 0xffff) == 0
1156 && in == ZERO
1157 && in_range_signed (snum >> 16, 16))
1158 {
1159 emit_ldah_num (out, snum >> 16, in);
1160 return;
1161 }
1162 /* I'm not sure this one is getting invoked when it could. */
1163 if ((num & 1) == 0 && in == ZERO)
1164 {
1165 if (in_range_signed (snum >> 1, 16))
1166 {
1167 emit_lda_n (out, snum >> 1, in);
1168 emit_addq_r (out, out, out);
1169 return;
1170 }
1171 else if (num & 0x1fffe == 0
1172 && in_range_signed (snum >> 17, 16))
1173 {
1174 emit_ldah_num (out, snum >> 17, in);
1175 emit_addq_r (out, out, out);
1176 return;
1177 }
1178 }
1179 if (in_range_signed (num, 32))
1180 {
1181 bfd_vma lo = num & 0xffff;
1182 if (lo & 0x8000)
1183 lo -= 0x10000;
1184 num -= lo;
1185 emit_ldah_num (out, snum >> 16, in);
1186 if (lo)
1187 emit_lda_n (out, lo, out);
1188 return;
1189 }
1190
1191 if (in != ZERO && in != AT && out != AT && at_ok)
1192 {
1193 emit_add64 (ZERO, AT, num);
1194 emit_addq_r (AT, in, out);
1195 return;
1196 }
1197
1198 if (in != ZERO)
1199 as_bad ("load expression too complex to expand");
1200
1201 /* Could check also for loading 16- or 32-bit value and shifting by
1202 arbitrary displacement. */
1203
1204 {
1205 bfd_vma lo = snum & 0xffffffff;
1206 if (lo & 0x80000000)
1207 lo -= ((bfd_vma)0x10000000 << 4);
1208 snum -= lo;
1209 emit_add64 (ZERO, out, snum >> 32);
1210 emit_sll_n (out, 32, out);
1211 if (lo != 0)
1212 emit_add64 (out, out, lo);
1213 }
1214 }
1215
1216 static int
1217 alpha_ip (str, insns)
1218 char *str;
1219 struct alpha_it insns[];
1220 {
1221 char *s;
1222 const char *args;
1223 char c;
1224 unsigned long i;
1225 struct alpha_opcode *pattern;
1226 char *argsStart;
1227 unsigned int opcode;
1228 unsigned int mask;
1229 int match = 0, num_gen = 1;
1230 int comma = 0;
1231 int do_add64, add64_in, add64_out;
1232 bfd_vma add64_addend;
1233
1234 for (s = str;
1235 islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
1236 ++s)
1237 ;
1238 switch (*s)
1239 {
1240
1241 case '\0':
1242 break;
1243
1244 case ',':
1245 comma = 1;
1246
1247 /*FALLTHROUGH*/
1248
1249 case ' ':
1250 *s++ = '\0';
1251 break;
1252
1253 default:
1254 as_fatal ("Unknown opcode: `%s'", str);
1255 }
1256 if ((pattern = (struct alpha_opcode *) hash_find (op_hash, str)) == NULL)
1257 {
1258 as_bad ("Unknown opcode: `%s'", str);
1259 return -1;
1260 }
1261 if (comma)
1262 *--s = ',';
1263
1264 argsStart = s;
1265 for (;;)
1266 {
1267 do_add64 = 0;
1268 opcode = pattern->match;
1269 num_gen = 1;
1270 for (i = 0; i < MAX_INSNS; i++)
1271 insns[i] = clear_insn;
1272
1273 /* Build the opcode, checking as we go to make sure that the
1274 operands match. */
1275 for (args = pattern->args;; ++args)
1276 {
1277 switch (*args)
1278 {
1279
1280 case '\0': /* end of args */
1281 if (*s == '\0')
1282 {
1283 match = 1;
1284 }
1285 break;
1286
1287 case '+':
1288 if (*s == '+')
1289 {
1290 ++s;
1291 continue;
1292 }
1293 if (*s == '-')
1294 {
1295 continue;
1296 }
1297 break;
1298
1299 case '(': /* these must match exactly */
1300 case ')':
1301 case ',':
1302 case ' ':
1303 case '0':
1304 if (*s++ == *args)
1305 continue;
1306 break;
1307
1308 case '1': /* next operand must be a register */
1309 case '2':
1310 case '3':
1311 case 'r':
1312 case 'R':
1313 if (*s++ == '$')
1314 {
1315 switch (c = *s++)
1316 {
1317
1318 case 'a': /* $at: as temporary */
1319 if (*s++ != 't')
1320 goto error;
1321 mask = AT;
1322 break;
1323
1324 case 'g': /* $gp: base register */
1325 if (*s++ != 'p')
1326 goto error;
1327 mask = base_register;
1328 break;
1329
1330 case 's': /* $sp: stack pointer */
1331 if (*s++ != 'p')
1332 goto error;
1333 mask = SP;
1334 break;
1335
1336
1337 case 'r': /* any register */
1338 if (!isdigit (c = *s++))
1339 {
1340 goto error;
1341 }
1342 /* FALLTHROUGH */
1343 case '0':
1344 case '1':
1345 case '2':
1346 case '3':
1347 case '4':
1348 case '5':
1349 case '6':
1350 case '7':
1351 case '8':
1352 case '9':
1353 if (isdigit (*s))
1354 {
1355 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
1356 {
1357 goto error;
1358 }
1359 }
1360 else
1361 {
1362 c -= '0';
1363 }
1364 if ((c == GP) && first_32bit_quadrant)
1365 c = ZERO;
1366
1367 mask = c;
1368 break;
1369
1370 default:
1371 goto error;
1372 }
1373 note_gpreg (mask);
1374 /* Got the register, now figure out where it goes in
1375 the opcode. */
1376 doregister:
1377 switch (*args)
1378 {
1379
1380 case '1':
1381 case 'e':
1382 opcode |= mask << SA;
1383 continue;
1384
1385 case '2':
1386 case 'f':
1387 opcode |= mask << SB;
1388 continue;
1389
1390 case '3':
1391 case 'g':
1392 opcode |= mask;
1393 continue;
1394
1395 case 'r':
1396 opcode |= (mask << SA) | mask;
1397 continue;
1398
1399 case 'R': /* ra and rb are the same */
1400 opcode |= (mask << SA) | (mask << SB);
1401 continue;
1402
1403 case 'E':
1404 opcode |= (mask << SA) | (mask << SB) | (mask);
1405 continue;
1406 }
1407 }
1408 break;
1409
1410 case 'e': /* next operand is a floating point register */
1411 case 'f':
1412 case 'g':
1413 case 'E':
1414 if (*s++ == '$' && *s++ == 'f' && isdigit (*s))
1415 {
1416 mask = *s++;
1417 if (isdigit (*s))
1418 {
1419 mask = 10 * (mask - '0') + (*s++ - '0');
1420 if (mask >= 32)
1421 {
1422 break;
1423 }
1424 }
1425 else
1426 {
1427 mask -= '0';
1428 }
1429 note_fpreg (mask);
1430 /* same encoding as gp registers */
1431 goto doregister;
1432 }
1433 break;
1434
1435 #if 0
1436 case 'h': /* bits 16..31 */
1437 insns[0].reloc = RELOC_16_31;
1438 goto immediate;
1439 #endif
1440
1441 case 'l': /* bits 0..15 */
1442 insns[0].reloc[0].code = BFD_RELOC_16;
1443 goto immediate;
1444
1445 case 'L': /* 21 bit PC relative immediate */
1446 insns[0].reloc[0].code = BFD_RELOC_23_PCREL_S2;
1447 insns[0].reloc[0].pcrel = 1;
1448 goto immediate;
1449
1450 case 'i': /* 14 bit immediate */
1451 if (OPCODE (opcode) != 0x1a)
1452 /* Not a jmp variant?? */
1453 abort ();
1454 else if (opcode & 0x8000)
1455 /* ret or jsr_coroutine */
1456 {
1457 insns[0].reloc[0].code = BFD_RELOC_14;
1458 insns[0].reloc[0].pcrel = 0;
1459 }
1460 else
1461 /* jmp or jsr */
1462 {
1463 insns[0].reloc[0].code = BFD_RELOC_ALPHA_HINT;
1464 insns[0].reloc[0].pcrel = 1;
1465 }
1466 goto immediate;
1467
1468 case 'b': /* 8 bit immediate */
1469 insns[0].reloc[0].code = BFD_RELOC_8;
1470 goto immediate;
1471
1472 case 'I': /* 26 bit immediate, for PALcode */
1473 insns[0].reloc[0].code = BFD_RELOC_26;
1474 goto immediate;
1475
1476 case 't': /* 12 bit displacement, for PALcode */
1477 insns[0].reloc[0].code = BFD_RELOC_12_PCREL;
1478 goto immediate;
1479
1480 case '8': /* 8 bit 0...7 */
1481 insns[0].reloc[0].code = BFD_RELOC_8;
1482 goto immediate;
1483
1484 immediate:
1485 if (*s == ' ')
1486 s++;
1487 getExpression (s, &insns[0]);
1488 s = expr_end;
1489 /* Handle overflow in certain instructions by converting
1490 to other instructions. */
1491 if (insns[0].reloc[0].code == BFD_RELOC_8
1492 && insns[0].reloc[0].exp.X_op == O_constant
1493 && (insns[0].reloc[0].exp.X_add_number < 0
1494 || insns[0].reloc[0].exp.X_add_number > 0xff))
1495 {
1496 if (OPCODE (opcode) == 0x10
1497 && (OP_FCN (opcode) == 0x00 /* addl */
1498 || OP_FCN (opcode) == 0x40 /* addl/v */
1499 || OP_FCN (opcode) == 0x20 /* addq */
1500 || OP_FCN (opcode) == 0x60 /* addq/v */
1501 || OP_FCN (opcode) == 0x09 /* subl */
1502 || OP_FCN (opcode) == 0x49 /* subl/v */
1503 || OP_FCN (opcode) == 0x29 /* subq */
1504 || OP_FCN (opcode) == 0x69 /* subq/v */
1505 || OP_FCN (opcode) == 0x02 /* s4addl */
1506 || OP_FCN (opcode) == 0x22 /* s4addq */
1507 || OP_FCN (opcode) == 0x0b /* s4subl */
1508 || OP_FCN (opcode) == 0x2b /* s4subq */
1509 || OP_FCN (opcode) == 0x12 /* s8addl */
1510 || OP_FCN (opcode) == 0x32 /* s8addq */
1511 || OP_FCN (opcode) == 0x1b /* s8subl */
1512 || OP_FCN (opcode) == 0x3b /* s8subq */
1513 )
1514 /* Can we make it fit by negating? */
1515 && -insns[0].reloc[0].exp.X_add_number < 0xff
1516 && -insns[0].reloc[0].exp.X_add_number > 0)
1517 {
1518 opcode ^= 0x120; /* convert add<=>sub */
1519 insns[0].reloc[0].exp.X_add_number *= -1;
1520 }
1521 else if (at_ok && macro_ok)
1522 {
1523 /* Constant value supplied, but it's too large. */
1524 do_add64 = 1;
1525 add64_in = ZERO;
1526 add64_out = AT;
1527 add64_addend = insns[0].reloc[0].exp.X_add_number;
1528 opcode &= ~ 0x1000;
1529 opcode |= (AT << SB);
1530 insns[0].reloc[0].code = BFD_RELOC_NONE;
1531 }
1532 else
1533 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1534 }
1535 else if (insns[0].reloc[0].code == BFD_RELOC_16
1536 && insns[0].reloc[0].exp.X_op == O_constant
1537 && !in_range_signed (insns[0].reloc[0].exp.X_add_number,
1538 16))
1539 {
1540 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1541 if (OPCODE (opcode) == 0x08)
1542 {
1543 do_add64 = 1;
1544 add64_in = ZERO;
1545 add64_out = AT;
1546 add64_addend = val;
1547 opcode &= ~0x1000;
1548 opcode |= (AT << SB);
1549 insns[0].reloc[0].code = BFD_RELOC_NONE;
1550 }
1551 else if (OPCODE (opcode) == 0x09
1552 && in_range_signed (val >> 16, 16))
1553 {
1554 /* ldah with high operand - convert to low */
1555 insns[0].reloc[0].exp.X_add_number >>= 16;
1556 }
1557 else
1558 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1559 }
1560 else if (insns[0].reloc[0].code == BFD_RELOC_32
1561 && insns[0].reloc[0].exp.X_op == O_constant)
1562 {
1563 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1564 bfd_signed_vma sval = val;
1565 if (val >> 32 != 0
1566 && sval >> 32 != 0
1567 && sval >> 32 != -1)
1568 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1569 }
1570 continue;
1571
1572 case 'F':
1573 {
1574 int format, length, mode, i;
1575 char temp[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1576 char *err;
1577 static const char formats[4] = "FGfd";
1578 bfd_vma bits, offset;
1579 char *old_input_line_pointer = input_line_pointer;
1580
1581 input_line_pointer = s;
1582 SKIP_WHITESPACE ();
1583 memset (temp, 0, sizeof (temp));
1584 mode = (opcode >> 26) & 3;
1585 format = formats[mode];
1586 err = md_atof (format, temp, &length);
1587 if (err)
1588 {
1589 as_bad ("Bad floating literal: %s", err);
1590 bits = 0;
1591 }
1592 else
1593 {
1594 /* Generate little-endian number from byte sequence. */
1595 bits = 0;
1596 for (i = length - 1; i >= 0; i--)
1597 bits += ((bfd_vma)(temp[i] & 0xff)) << (i * 8);
1598 }
1599 switch (length)
1600 {
1601 case 8:
1602 offset = get_lit8_offset (bits) - 0x8000;
1603 insns[0].reloc[0].exp.X_add_symbol = lit8_sym;
1604 insns[0].reloc[0].exp.X_add_number = 0x8000;
1605 break;
1606 case 4:
1607 offset = get_lit4_offset (bits) - 0x8000;
1608 insns[0].reloc[0].exp.X_add_symbol = lit4_sym;
1609 insns[0].reloc[0].exp.X_add_number = 0x8000;
1610 break;
1611 default:
1612 abort ();
1613 }
1614 insns[0].reloc[0].exp.X_op = O_symbol;
1615 offset &= 0xffff;
1616 num_gen = load_expression (AT, &insns[0]);
1617 if (lituse_pending)
1618 {
1619 insns[num_gen].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1620 insns[num_gen].reloc[0].exp = lituse_basereg;
1621 lituse_pending = 0;
1622 }
1623 insns[num_gen++].opcode = opcode | (AT << SB) | offset;
1624 opcode = insns[0].opcode;
1625 s = input_line_pointer;
1626 input_line_pointer = old_input_line_pointer;
1627 }
1628 continue;
1629
1630 /* The following two.. take advantage of the fact that
1631 opcode already contains most of what we need to know.
1632 We just prepend to the instr an "ldah
1633 $r,%ml(expr)($base)" and turn this one (done later
1634 after we return) into something like "stq
1635 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1636
1637 NOTE: This can fail later on at link time if the
1638 offset from $base actually turns out to be more than
1639 2**31 or 2**47 if use_large_offsets is set. */
1640 case 'P': /* Addressing macros: PUT */
1641 mask = AT; /* register 'at' */
1642 /* fall through */
1643
1644 case 'G': /* Addressing macros: GET */
1645 /* All it is missing is the expression, which is what we
1646 will get now */
1647
1648 if (*s == ' ')
1649 s++;
1650 getExpression (s, &insns[0]);
1651 s = expr_end;
1652
1653 /* Must check for "lda ..,number" too */
1654 if (insns[0].reloc[0].exp.X_op == O_big)
1655 {
1656 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1657 return -1;
1658 }
1659 if (insns[0].reloc[0].exp.X_op == O_constant)
1660 {
1661 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1662 bfd_vma top, low;
1663
1664 insns[0].reloc[0].code = BFD_RELOC_NONE;
1665 insns[1].reloc[0].code = BFD_RELOC_NONE;
1666
1667 low = val & 0xffff;
1668 if (low & 0x8000)
1669 low -= 0x10000;
1670 top = val - low;
1671 if (top)
1672 {
1673 do_add64 = 1;
1674 add64_in = ZERO;
1675 add64_out = AT;
1676 add64_addend = top;
1677 opcode |= AT << SB;
1678 }
1679 else
1680 opcode |= ZERO << SB;
1681 opcode &= ~0x1000;
1682 opcode |= low & 0xffff;
1683 }
1684 else if (insns[0].reloc[0].exp.X_op == O_symbol)
1685 {
1686 unsigned long old_opcode = opcode;
1687 int tmp_reg;
1688
1689 if (!macro_ok)
1690 as_bad ("insn requires expansion but `nomacro' specified");
1691 else if (*args == 'G')
1692 tmp_reg = mask;
1693 else if (!at_ok)
1694 as_bad ("insn expansion requires AT use, but `noat' specified");
1695 else
1696 tmp_reg = AT;
1697 num_gen = load_expression (tmp_reg, insns);
1698 opcode = insns[0].opcode;
1699 /* lda is opcode 8, 0x20000000, and the macros that use
1700 this code have an opcode field of 0. The latter
1701 require further processing, and we don't have the
1702 true opcode here. */
1703 if (OPCODE (old_opcode) != 0
1704 && OPCODE (old_opcode) != 0x08)
1705 {
1706 struct alpha_it *i;
1707 i = &insns[num_gen++];
1708 i->opcode = old_opcode | (tmp_reg << SB);
1709
1710 if (lituse_pending)
1711 {
1712 i->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1713 i->reloc[0].exp = lituse_basereg;
1714 lituse_pending = 0;
1715 }
1716 }
1717 }
1718 else
1719 {
1720 /* Not a number */
1721 num_gen = 2;
1722 insns[1].reloc[0].exp = insns[0].reloc[0].exp;
1723
1724 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1725
1726 abort (); /* relocs need fixing */
1727 #if 0
1728 insns[1].reloc = RELOC_0_15;
1729 insns[1].opcode = opcode | mask << SB;
1730
1731 insns[0].reloc = RELOC_16_31;
1732 opcode = 0x24000000 /*ldah*/ | mask << SA | (base_register << SB);
1733 #endif
1734 }
1735
1736 continue;
1737
1738 /* Same failure modes as above, actually most of the
1739 same code shared. */
1740 case 'B': /* Builtins */
1741 args++;
1742 switch (*args)
1743 {
1744
1745 case 'a': /* ldgp */
1746
1747 if (first_32bit_quadrant || no_mixed_code)
1748 return -1;
1749 switch (OUTPUT_FLAVOR)
1750 {
1751 case bfd_target_aout_flavour:
1752 /* this is cmu's a.out version */
1753 insns[0].reloc[0].code = BFD_RELOC_NONE;
1754 /* generate "zap %r,0xf,%r" to take high 32 bits */
1755 opcode |= 0x48001600 /* zap ?,#,?*/ | (0xf << SN);
1756 break;
1757 case bfd_target_ecoff_flavour:
1758 /* Given "ldgp R1,N(R2)", turn it into something
1759 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1760 appropriate constants and relocations. */
1761 {
1762 unsigned long r1, r2;
1763 unsigned long addend = 0;
1764
1765 num_gen = 2;
1766 r2 = mask;
1767 r1 = opcode & 0x3f;
1768 insns[0].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_HI16;
1769 insns[0].reloc[0].pcrel = 1;
1770 insns[0].reloc[0].exp.X_op = O_symbol;
1771 insns[0].reloc[0].exp.X_add_symbol = gp;
1772 insns[0].reloc[0].exp.X_add_number = 0;
1773 insns[0].opcode = (0x24000000 /* ldah */
1774 | (r1 << SA)
1775 | (r2 << SB));
1776 insns[1].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_LO16;
1777 insns[1].reloc[0].exp.X_op = O_symbol;
1778 insns[1].reloc[0].exp.X_add_symbol = gp;
1779 insns[1].reloc[0].exp.X_add_number = 4;
1780 insns[1].reloc[0].pcrel = 1;
1781 insns[1].opcode = 0x20000000 | (r1 << SA) | (r1 << SB);
1782 opcode = insns[0].opcode;
1783 /* merge in addend */
1784 insns[1].opcode |= addend & 0xffff;
1785 insns[0].opcode |= ((addend >> 16)
1786 + (addend & 0x8000 ? 1 : 0));
1787 if (r2 == PV)
1788 ecoff_set_gp_prolog_size (0);
1789 }
1790 break;
1791 default:
1792 abort ();
1793 }
1794 continue;
1795
1796
1797 case 'b': /* setgp */
1798 switch (OUTPUT_FLAVOR)
1799 {
1800 case bfd_target_aout_flavour:
1801 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1802 opcode |= 0x48001600 /* zap ?,#,?*/
1803 | (0xf << SN) | (base_register);
1804 break;
1805 default:
1806 abort ();
1807 }
1808 continue;
1809
1810 case 'c': /* jsr $r,foo becomes
1811 lda $27,foo
1812 jsr $r,($27),foo
1813 Register 27, t12, is used by convention
1814 here. */
1815 {
1816 struct alpha_it *jsr;
1817 expressionS etmp;
1818 struct reloc_data *r;
1819
1820 /* We still have to parse the function name */
1821 if (*s == ' ')
1822 s++;
1823 getExpression (s, &insns[0]);
1824 etmp = insns[0].reloc[0].exp;
1825 s = expr_end;
1826 num_gen = load_expression (PV, &insns[0]);
1827 note_gpreg (PV);
1828
1829 jsr = &insns[num_gen++];
1830 jsr->opcode = (pattern->match
1831 | (mask << SA)
1832 | (PV << SB)
1833 | 0);
1834 if (lituse_pending)
1835 {
1836 /* LITUSE wasn't emitted yet */
1837 jsr->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1838 jsr->reloc[0].exp = lituse_jsr;
1839 r = &jsr->reloc[1];
1840 lituse_pending = 0;
1841 }
1842 else
1843 r = &jsr->reloc[0];
1844 r->exp = etmp;
1845 r->code = BFD_RELOC_ALPHA_HINT;
1846 r->pcrel = 1;
1847 opcode = insns[0].opcode;
1848 }
1849 continue;
1850
1851 case 'd':
1852 /* Sub-word loads and stores. We load the address into
1853 $at, which might involve using the `P' parameter
1854 processing too, then emit a sequence to get the job
1855 done, using unaligned memory accesses and byte
1856 manipulation, with t9 and t10 as temporaries. */
1857 {
1858 /* Characteristics of access. */
1859 int is_load, is_unsigned = 0, is_unaligned = 0;
1860 int mode_size, mode;
1861 /* Register operand. */
1862 int reg;
1863 /* Addend for loads and stores. */
1864 valueT addend;
1865 /* Which register do we use for the address? */
1866 int addr;
1867
1868 {
1869 /* Pick apart name and set flags. */
1870 const char *s = pattern->name;
1871
1872 if (*s == 'u')
1873 {
1874 is_unaligned = 1;
1875 s++;
1876 }
1877
1878 if (s[0] == 'l' && s[1] == 'd')
1879 is_load = 1;
1880 else if (s[0] == 's' && s[1] == 't')
1881 is_load = 0;
1882 else
1883 as_fatal ("unrecognized sub-word access insn `%s'",
1884 str);
1885 s += 2;
1886
1887 mode = *s++;
1888 if (mode == 'b') mode_size = 1;
1889 else if (mode == 'w') mode_size = 2;
1890 else if (mode == 'l') mode_size = 4;
1891 else if (mode == 'q') mode_size = 8;
1892 else abort ();
1893
1894 if (*s == 'u')
1895 {
1896 is_unsigned = 1;
1897 s++;
1898 }
1899
1900 assert (*s == 0);
1901
1902 /* Longwords are always kept sign-extended. */
1903 if (mode == 'l' && is_unsigned)
1904 abort ();
1905 /* There's no special unaligned byte handling. */
1906 if (mode == 'b' && is_unaligned)
1907 abort ();
1908 /* Stores don't care about signedness. */
1909 if (!is_load && is_unsigned)
1910 abort ();
1911 }
1912
1913 if (args[-2] == 'P')
1914 {
1915 addr = AT;
1916 addend = 0;
1917 }
1918 else
1919 {
1920 /* foo r1,num(r2)
1921 r2 -> mask
1922 r1 -> (opcode >> SA) & 31
1923 num -> insns->reloc[0].*
1924
1925 We want to emit "lda at,num(r2)", since these
1926 operations require the use of a single register
1927 with the starting address of the memory operand
1928 we want to access.
1929
1930 We could probably get away without doing this
1931 (and use r2 below, with the addend for the
1932 actual reads and writes) in cases where the
1933 addend is known to be a multiple of 8. */
1934 int r2 = mask;
1935 int r1 = (opcode >> SA) & 31;
1936
1937 if (insns[0].reloc[0].code == BFD_RELOC_NONE)
1938 addend = 0;
1939 else if (insns[0].reloc[0].code == BFD_RELOC_16)
1940 {
1941 if (insns[0].reloc[0].exp.X_op != O_constant)
1942 abort ();
1943 addend = insns[0].reloc[0].exp.X_add_number;
1944 }
1945 else
1946 abort ();
1947
1948 if (addend + mode_size - 1 < 0x7fff
1949 && (addend % 8) == 0
1950 && (r2 < T9 || r2 > T12))
1951 {
1952 addr = r2;
1953 num_gen = 0;
1954 }
1955 else
1956 {
1957 /* Let later relocation processing deal
1958 with the addend field. */
1959 insns[num_gen-1].opcode = (0x20000000 /* lda */
1960 | (AT << SA)
1961 | (r2 << SB));
1962 addr = AT;
1963 addend = 0;
1964 }
1965 reg = r1;
1966 }
1967
1968 /* Because the emit_* routines append directly to
1969 the current frag, we now need to flush any
1970 pending insns. */
1971 {
1972 int i;
1973 for (i = 0; i < num_gen; i++)
1974 emit_insn (&insns[i]);
1975 num_gen = 0;
1976 }
1977
1978 if (is_load)
1979 {
1980 int reg2, reg3;
1981
1982 if (is_unaligned)
1983 reg2 = T9, reg3 = T10;
1984 else
1985 reg2 = reg;
1986
1987 emit_load_unal (addr, addend, T9);
1988 if (is_unaligned)
1989 emit_load_unal (addr, addend + mode_size - 1, T10);
1990 emit_extract_r (T9, addr, reg2, mode, 'l');
1991 if (is_unaligned)
1992 {
1993 emit_extract_r (T10, addr, reg3, mode, 'h');
1994 emit_bis_r (T9, T10, reg);
1995 }
1996 if (!is_unsigned)
1997 emit_sign_extend (reg, mode_size * 8);
1998 }
1999 else
2000 {
2001 /* The second word gets processed first
2002 because if the address does turn out to be
2003 aligned, the processing for the second word
2004 will be pushing around all-zeros, and the
2005 entire value will be handled as the `first'
2006 word. So we want to store the `first' word
2007 last. */
2008 /* Pair these up so that the memory loads get
2009 separated from each other, as well as being
2010 well in advance of the uses of the values
2011 loaded. */
2012 if (is_unaligned)
2013 {
2014 emit_load_unal (addr, addend + mode_size - 1, T11);
2015 emit_insert_r (reg, addr, T12, mode, 'h');
2016 }
2017 emit_load_unal (addr, addend, T9);
2018 emit_insert_r (reg, addr, T10, mode, 'l');
2019 if (is_unaligned)
2020 emit_mask_r (T12, addr, T12, mode, 'h');
2021 emit_mask_r (T10, addr, T10, mode, 'l');
2022 if (is_unaligned)
2023 emit_bis_r (T11, T12, T11);
2024 emit_bis_r (T9, T10, T9);
2025 if (is_unaligned)
2026 emit_store_unal (addr, addend + mode_size - 1, T11);
2027 emit_store_unal (addr, addend, T9);
2028 }
2029 }
2030 return 0;
2031
2032 /* DIVISION and MODULUS. Yech.
2033 Convert OP x,y,result
2034 to mov x,t10
2035 mov y,t11
2036 jsr t9, __OP
2037 mov t12,result
2038
2039 with appropriate optimizations if t10,t11,t12
2040 are the registers specified by the compiler.
2041 We are missing an obvious optimization
2042 opportunity here; if the ldq generated by the
2043 jsr assembly requires a cycle or two to make
2044 the value available, initiating it before one
2045 or two of the mov instructions would result in
2046 faster execution. */
2047 case '0': /* reml */
2048 case '1': /* divl */
2049 case '2': /* remq */
2050 case '3': /* divq */
2051 case '4': /* remlu */
2052 case '5': /* divlu */
2053 case '6': /* remqu */
2054 case '7': /* divqu */
2055 {
2056 static char func[8][6] = {
2057 "reml", "divl", "remq", "divq",
2058 "remlu", "divlu", "remqu", "divqu"
2059 };
2060 char expansion[64];
2061 int reg;
2062
2063 /* All regs parsed, in opcode */
2064
2065 /* Do the expansions, one instr at a time */
2066
2067 reg = (opcode >> SA) & 31;
2068 if (reg != T10)
2069 {
2070 /* x->t10 */
2071 sprintf (expansion, "mov $%d,$%d", reg, T10);
2072 md_assemble (expansion);
2073 }
2074 reg = (opcode >> SB) & 31;
2075 if (reg == T10)
2076 /* we already overwrote it! */
2077 abort ();
2078 else if (reg != T11)
2079 {
2080 /* y->t11 */
2081 sprintf (expansion, "mov $%d,$%d", reg, T11);
2082 md_assemble (expansion);
2083 }
2084 sprintf (expansion, "lda $%d,__%s", PV, func[*args - '0']);
2085 md_assemble (expansion);
2086 sprintf (expansion, "jsr $%d,($%d),__%s", T9, PV,
2087 func[*args - '0']);
2088 md_assemble (expansion);
2089 #if 0 /* huh? */
2090 if (!first_32bit_quadrant)
2091 {
2092 sprintf (expansion,
2093 "zap $%d,0xf,$%d",
2094 T9, base_register);
2095 md_assemble (expansion);
2096 }
2097 #endif
2098 sprintf (expansion, "ldgp $%d,0($%d)",
2099 base_register, T9);
2100 md_assemble (expansion);
2101
2102 /* Use insns[0] to get at the result */
2103 if ((reg = (opcode & 31)) != PV)
2104 opcode = (0x47e00400 /* or zero,zero,zero */
2105 | (PV << SB)
2106 | reg /* Rc */ ); /* pv->z */
2107 else
2108 num_gen = 0;
2109 }
2110 continue;
2111 }
2112 /* fall through */
2113
2114 default:
2115 abort ();
2116 }
2117 break;
2118 }
2119 error:
2120 if (match == 0)
2121 {
2122 /* Args don't match. */
2123 if (&pattern[1] - alpha_opcodes < NUMOPCODES
2124 && !strcmp (pattern->name, pattern[1].name))
2125 {
2126 ++pattern;
2127 s = argsStart;
2128 continue;
2129 }
2130 else
2131 {
2132 as_warn ("Illegal operands");
2133 return -1;
2134 }
2135 }
2136 else
2137 {
2138 /* Args match, see if a float instructions and -nofloats */
2139 if (nofloats && pattern->isa_float)
2140 return -1;
2141 }
2142 break;
2143 }
2144
2145 if (do_add64)
2146 {
2147 emit_add64 (add64_in, add64_out, add64_addend);
2148 }
2149
2150 insns[0].opcode = opcode;
2151 return num_gen;
2152 }
2153
2154 /* Turn a string in input_line_pointer into a floating point constant
2155 of type type, and store the appropriate bytes in *litP. The number
2156 of LITTLENUMS emitted is stored in *sizeP. An error message is
2157 returned, or NULL on OK. */
2158
2159 /* Equal to MAX_PRECISION in atof-ieee.c */
2160 #define MAX_LITTLENUMS 6
2161
2162 char *
2163 md_atof (type, litP, sizeP)
2164 char type;
2165 char *litP;
2166 int *sizeP;
2167 {
2168 int prec;
2169 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2170 LITTLENUM_TYPE *wordP;
2171 char *t;
2172 char *atof_ieee (), *vax_md_atof ();
2173
2174 switch (type)
2175 {
2176 /* VAX floats */
2177 case 'G':
2178 /* VAX md_atof doesn't like "G" for some reason. */
2179 type = 'g';
2180 case 'F':
2181 case 'D':
2182 return vax_md_atof (type, litP, sizeP);
2183
2184 /* IEEE floats */
2185 case 'f':
2186 prec = 2;
2187 break;
2188
2189 case 'd':
2190 prec = 4;
2191 break;
2192
2193 case 'x':
2194 case 'X':
2195 prec = 6;
2196 break;
2197
2198 case 'p':
2199 case 'P':
2200 prec = 6;
2201 break;
2202
2203 default:
2204 *sizeP = 0;
2205 return "Bad call to MD_ATOF()";
2206 }
2207 t = atof_ieee (input_line_pointer, type, words);
2208 if (t)
2209 input_line_pointer = t;
2210 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2211
2212 for (wordP = words + prec - 1; prec--;)
2213 {
2214 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
2215 litP += sizeof (LITTLENUM_TYPE);
2216 }
2217
2218 return 0;
2219 }
2220
2221 void
2222 md_bignum_to_chars (buf, bignum, nchars)
2223 char *buf;
2224 LITTLENUM_TYPE *bignum;
2225 int nchars;
2226 {
2227 while (nchars)
2228 {
2229 LITTLENUM_TYPE work = *bignum++;
2230 int nb = CHARS_PER_LITTLENUM;
2231
2232 do
2233 {
2234 *buf++ = work & ((1 << BITS_PER_CHAR) - 1);
2235 if (--nchars == 0)
2236 return;
2237 work >>= BITS_PER_CHAR;
2238 }
2239 while (--nb);
2240 }
2241 }
2242 \f
2243 CONST char *md_shortopts = "Fm:";
2244 struct option md_longopts[] = {
2245 #define OPTION_32ADDR (OPTION_MD_BASE)
2246 {"32addr", no_argument, NULL, OPTION_32ADDR},
2247 {NULL, no_argument, NULL, 0}
2248 };
2249 size_t md_longopts_size = sizeof(md_longopts);
2250
2251 int
2252 md_parse_option (c, arg)
2253 int c;
2254 char *arg;
2255 {
2256 switch (c)
2257 {
2258 case 'F':
2259 nofloats = 1;
2260 break;
2261
2262 case OPTION_32ADDR:
2263 addr32 = 1;
2264 break;
2265
2266 case 'm':
2267 {
2268 unsigned long mach;
2269
2270 if (!strcmp (arg, "21064"))
2271 mach = 21064;
2272 else if (!strcmp (arg, "21066"))
2273 mach = 21066;
2274 else if (!strcmp (arg, "21164"))
2275 mach = 21164;
2276 else
2277 {
2278 as_bad ("invalid architecture %s", arg);
2279 return 0;
2280 }
2281
2282 if (machine != 0 && machine != mach)
2283 {
2284 as_warn ("machine type %lu already chosen, overriding with %lu",
2285 machine, mach);
2286 }
2287 machine = mach;
2288 }
2289 break;
2290
2291 default:
2292 return 0;
2293 }
2294
2295 return 1;
2296 }
2297
2298 void
2299 md_show_usage (stream)
2300 FILE *stream;
2301 {
2302 fprintf(stream, "\
2303 Alpha options:\n\
2304 -32addr treat addresses as 32-bit values\n\
2305 -F lack floating point instructions support\n\
2306 -m21064 | -m21066 | -m21164\n\
2307 specify variant of Alpha architecture\n");
2308 }
2309 \f
2310 static void
2311 s_proc (is_static)
2312 int is_static;
2313 {
2314 /* XXXX Align to cache linesize XXXXX */
2315 char *name;
2316 char c;
2317 char *p;
2318 symbolS *symbolP;
2319 int temp;
2320
2321 /* Takes ".proc name,nargs" */
2322 name = input_line_pointer;
2323 c = get_symbol_end ();
2324 p = input_line_pointer;
2325 symbolP = symbol_find_or_make (name);
2326 *p = c;
2327 SKIP_WHITESPACE ();
2328 if (*input_line_pointer != ',')
2329 {
2330 *p = 0;
2331 as_warn ("Expected comma after name \"%s\"", name);
2332 *p = c;
2333 temp = 0;
2334 ignore_rest_of_line ();
2335 }
2336 else
2337 {
2338 input_line_pointer++;
2339 temp = get_absolute_expression ();
2340 }
2341 /* symbolP->sy_other = (signed char) temp; */
2342 as_warn ("unhandled: .proc %s,%d", name, temp);
2343 demand_empty_rest_of_line ();
2344 }
2345
2346 static void
2347 s_alpha_set (x)
2348 int x;
2349 {
2350 char *name = input_line_pointer, ch, *s;
2351 int yesno = 1;
2352
2353 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2354 input_line_pointer++;
2355 ch = *input_line_pointer;
2356 *input_line_pointer = '\0';
2357
2358 s = name;
2359 if (s[0] == 'n' && s[1] == 'o')
2360 {
2361 yesno = 0;
2362 s += 2;
2363 }
2364 if (!strcmp ("reorder", s))
2365 /* ignore */ ;
2366 else if (!strcmp ("at", s))
2367 at_ok = yesno;
2368 else if (!strcmp ("macro", s))
2369 macro_ok = yesno;
2370 else if (!strcmp ("move", s))
2371 /* ignore */ ;
2372 else if (!strcmp ("volatile", s))
2373 /* ignore */ ;
2374 else
2375 as_warn ("Tried to .set unrecognized mode `%s'", name);
2376 *input_line_pointer = ch;
2377 demand_empty_rest_of_line ();
2378 }
2379
2380 /* @@ Is this right?? */
2381 long
2382 md_pcrel_from (fixP)
2383 fixS *fixP;
2384 {
2385 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
2386 switch (fixP->fx_r_type)
2387 {
2388 case BFD_RELOC_ALPHA_GPDISP_HI16:
2389 case BFD_RELOC_ALPHA_GPDISP_LO16:
2390 return addr;
2391 default:
2392 return fixP->fx_size + addr;
2393 }
2394 }
2395
2396 int
2397 alpha_do_align (n, fill)
2398 int n;
2399 const char *fill;
2400 {
2401 if (!fill
2402 && (now_seg == text_section
2403 || !strcmp (now_seg->name, ".init")
2404 || !strcmp (now_seg->name, ".fini")))
2405 {
2406 static const unsigned char nop_pattern[] = { 0x1f, 0x04, 0xff, 0x47 };
2407 frag_align_pattern (n, nop_pattern, sizeof (nop_pattern));
2408 return 1;
2409 }
2410 return 0;
2411 }
2412
2413 int
2414 md_apply_fix (fixP, valueP)
2415 fixS *fixP;
2416 valueT *valueP;
2417 {
2418 valueT value;
2419 int size;
2420 valueT addend;
2421 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
2422
2423 value = *valueP;
2424
2425 switch (fixP->fx_r_type)
2426 {
2427 /* The GPDISP relocations are processed internally with a symbol
2428 referring to the current function; we need to drop in a value
2429 which, when added to the address of the start of the function,
2430 gives the desired GP. */
2431 case BFD_RELOC_ALPHA_GPDISP_HI16:
2432 case BFD_RELOC_ALPHA_GPDISP_LO16:
2433 addend = value;
2434 if (fixP->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
2435 {
2436 assert (fixP->fx_next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
2437 #ifdef DEBUG1
2438 printf ("hi16: ");
2439 fprintf_vma (stdout, addend);
2440 printf ("\n");
2441 #endif
2442 if (addend & 0x8000)
2443 addend += 0x10000;
2444 addend >>= 16;
2445 fixP->fx_offset = 4; /* @@ Compute this using fx_next. */
2446 }
2447 else
2448 {
2449 #ifdef DEBUG1
2450 printf ("lo16: ");
2451 fprintf_vma (stdout, addend);
2452 printf ("\n");
2453 #endif
2454 addend &= 0xffff;
2455 fixP->fx_offset = 0;
2456 }
2457 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2458 addend, 2);
2459 fixP->fx_addsy = section_symbol (absolute_section);
2460 fixP->fx_offset += fixP->fx_frag->fr_address + fixP->fx_where;
2461 break;
2462
2463 case BFD_RELOC_8:
2464 /* Write 8 bits, shifted left 13 bit positions. */
2465 value &= 0xff;
2466 p++;
2467 *p &= 0x1f;
2468 *p |= (value << 5) & 0xe0;
2469 value >>= 3;
2470 p++;
2471 *p &= 0xe0;
2472 *p |= value;
2473 value >>= 5;
2474 fixP->fx_done = 1;
2475 if (value != 0)
2476 as_bad_where (fixP->fx_file, fixP->fx_line,
2477 "overflow in type-%d reloc", (int) fixP->fx_r_type);
2478 return 3;
2479
2480 case BFD_RELOC_32:
2481 size = 4;
2482 goto do_it;
2483 case BFD_RELOC_64:
2484 size = 8;
2485 goto do_it;
2486 case BFD_RELOC_16:
2487 /* Don't want overflow checking. */
2488 size = 2;
2489 do_it:
2490 if (fixP->fx_pcrel == 0
2491 && fixP->fx_addsy == 0)
2492 {
2493 md_number_to_chars (p, value, size);
2494 /* @@ Overflow checks?? */
2495 goto done;
2496 }
2497 break;
2498
2499 case BFD_RELOC_26:
2500 if (fixP->fx_addsy != 0
2501 && fixP->fx_addsy->bsym->section != absolute_section)
2502 as_bad_where (fixP->fx_file, fixP->fx_line,
2503 "PALcode instructions require immediate constant function code");
2504 else if (value >> 26 != 0)
2505 as_bad_where (fixP->fx_file, fixP->fx_line,
2506 "overflow in 26-bit PALcode function field");
2507 *p++ = value & 0xff;
2508 value >>= 8;
2509 *p++ = value & 0xff;
2510 value >>= 8;
2511 *p++ = value & 0xff;
2512 value >>= 8;
2513 {
2514 char x = *p;
2515 x &= ~3;
2516 x |= (value & 3);
2517 *p++ = x;
2518 }
2519 goto done;
2520
2521 case BFD_RELOC_14:
2522 if (fixP->fx_addsy != 0
2523 && fixP->fx_addsy->bsym->section != absolute_section)
2524 as_bad_where (fixP->fx_file, fixP->fx_line,
2525 "ret/jsr_coroutine requires constant in displacement field");
2526 else if (value >> 14 != 0)
2527 as_bad_where (fixP->fx_file, fixP->fx_line,
2528 "overflow in 14-bit operand field of ret or jsr_coroutine");
2529 *p++ = value & 0xff;
2530 value >>= 8;
2531 *p = (*p & 0xc0) | (value & 0x3f);
2532 goto done;
2533
2534 case BFD_RELOC_23_PCREL_S2:
2535 /* Write 21 bits only. */
2536 value >>= 2;
2537 *p++ = value & 0xff;
2538 value >>= 8;
2539 *p++ = value & 0xff;
2540 value >>= 8;
2541 *p &= 0xe0;
2542 *p |= (value & 0x1f);
2543 goto done;
2544
2545 case BFD_RELOC_12_PCREL:
2546 *p++ = value & 0xff;
2547 value >>= 8;
2548 *p &= 0xf0;
2549 *p |= (value & 0x0f);
2550 goto done;
2551
2552 case BFD_RELOC_ALPHA_LITERAL:
2553 case BFD_RELOC_ALPHA_LITUSE:
2554 return 2;
2555
2556 case BFD_RELOC_GPREL32:
2557 assert (fixP->fx_subsy == gp);
2558 value = - alpha_gp_value; /* huh? this works... */
2559 fixP->fx_subsy = 0;
2560 md_number_to_chars (p, value, 4);
2561 break;
2562
2563 case BFD_RELOC_ALPHA_HINT:
2564 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
2565 {
2566 size = 2;
2567 goto do_it;
2568 }
2569 return 2;
2570
2571 default:
2572 as_fatal ("unhandled relocation type %s",
2573 bfd_get_reloc_code_name (fixP->fx_r_type));
2574 return 9;
2575 }
2576
2577 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
2578 {
2579 printf ("type %d reloc done?\n", fixP->fx_r_type);
2580 done:
2581 fixP->fx_done = 1;
2582 return 42;
2583 }
2584
2585 return 0x12345678;
2586 }
2587
2588 void
2589 alpha_frob_ecoff_data ()
2590 {
2591 select_gp_value ();
2592 /* $zero and $f31 are read-only */
2593 alpha_gprmask &= ~1;
2594 alpha_fprmask &= ~1;
2595 }
2596
2597 /* The Alpha has support for some VAX floating point types, as well as for
2598 IEEE floating point. We consider IEEE to be the primary floating point
2599 format, and sneak in the VAX floating point support here. */
2600 #define md_atof vax_md_atof
2601 #include "config/atof-vax.c"