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