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