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