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