* config/tc-hppa.c (pa_equ): Handle both .reg and .equ correctly.
[deliverable/binutils-gdb.git] / gas / config / tc-alpha.c
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha CPU.
2 Copyright (C) 1989, 1993, 1994 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 /*
24 * Mach Operating System
25 * Copyright (c) 1993 Carnegie Mellon University
26 * All Rights Reserved.
27 *
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
33 *
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
37 *
38 * Carnegie Mellon requests users of this software to return to
39 *
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
44 *
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
47 */
48 /*
49 * HISTORY
50 * 5-Oct-93 Alessandro Forin (af) at Carnegie-Mellon University
51 * First Checkin
52 *
53 * Author: Alessandro Forin, Carnegie Mellon University
54 * Date: Jan 1993
55 */
56
57 #include "as.h"
58 #include "alpha-opcode.h"
59 #include "subsegs.h"
60
61 /* @@ Will a simple 0x8000 work here? If not, why not? */
62 #define GP_ADJUSTMENT (0x8000 - 0x10)
63
64 /* These are exported to relaxing code, even though we don't do any
65 relaxing on this processor currently. */
66 const relax_typeS md_relax_table[1];
67 int md_short_jump_size = 4;
68 int md_long_jump_size = 4;
69
70 /* handle of the OPCODE hash table */
71 static struct hash_control *op_hash;
72
73 /* Sections and symbols we'll want to keep track of. */
74 static segT lita_sec, rdata, sdata, lit8_sec, lit4_sec;
75 static symbolS *lit8_sym, *lit4_sym;
76
77 /* Setting for ".set [no]{at,macro}". */
78 static int at_ok = 1, macro_ok = 1;
79
80 /* Keep track of global pointer. */
81 valueT alpha_gp_value;
82 static symbolS *gp;
83
84 /* We'll probably be using this relocation frequently, and we
85 will want to compare for it. */
86 static reloc_howto_type *gpdisp_hi16_howto;
87
88 /* These are exported to ECOFF code. */
89 unsigned long alpha_gprmask, alpha_fprmask;
90
91 /* Used for LITUSE relocations. */
92 static expressionS lituse_basereg, lituse_byteoff, lituse_jsr;
93
94 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
95 cause all addresses to be treated as 32-bit values in memory. (The
96 in-register versions are all sign-extended to 64 bits, of course.)
97 Some other systems may want this option too. */
98 static int addr32;
99
100 /* Imported functions -- they should be defined in header files somewhere. */
101 extern segT subseg_get ();
102 extern PTR bfd_alloc_by_size_t ();
103 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
104 s_data (), float_cons ();
105
106 /* Static functions, needing forward declarations. */
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 void 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 arelent *
337 tc_gen_reloc (sec, fixp)
338 asection *sec;
339 fixS *fixp;
340 {
341 arelent *reloc;
342
343 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
344 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
345 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
346
347 if (fixp->fx_r_type > BFD_RELOC_UNUSED || fixp->fx_r_type < 0)
348 abort ();
349
350 if (fixp->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
351 {
352 if (!gpdisp_hi16_howto)
353 gpdisp_hi16_howto = bfd_reloc_type_lookup (stdoutput,
354 fixp->fx_r_type);
355 reloc->howto = gpdisp_hi16_howto;
356 }
357 else
358 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
359 assert (reloc->howto != 0);
360 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
361 {
362 as_fatal ("bug in handling type-%d relocs", fixp->fx_r_type);
363 abort ();
364 }
365 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
366
367 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
368 {
369 /* fake out bfd_perform_relocation. sigh */
370 reloc->addend = -alpha_gp_value;
371 }
372 else if (reloc->howto->pc_relative && reloc->howto->pcrel_offset)
373 {
374 reloc->addend = fixp->fx_offset - reloc->address;
375 }
376 else
377 reloc->addend = fixp->fx_offset;
378 return reloc;
379 }
380
381 static void
382 s_base ()
383 {
384 if (first_32bit_quadrant)
385 {
386 /* not fatal, but it might not work in the end */
387 as_warn ("File overrides no-base-register option.");
388 first_32bit_quadrant = 0;
389 }
390
391 SKIP_WHITESPACE ();
392 if (*input_line_pointer == '$')
393 { /* $rNN form */
394 input_line_pointer++;
395 if (*input_line_pointer == 'r')
396 input_line_pointer++;
397 }
398
399 base_register = get_absolute_expression ();
400 if (base_register < 0 || base_register > 31)
401 {
402 base_register = GP;
403 as_warn ("Bad base register, using $r.", base_register);
404 }
405 demand_empty_rest_of_line ();
406 }
407
408 static void
409 s_gprel32 ()
410 {
411 expressionS e;
412 char *p;
413
414 SKIP_WHITESPACE ();
415 expression (&e);
416 switch (e.X_op)
417 {
418 case O_constant:
419 e.X_add_symbol = section_symbol (absolute_section);
420 /* fall through */
421 case O_symbol:
422 e.X_op = O_subtract;
423 e.X_op_symbol = gp;
424 break;
425 default:
426 abort ();
427 }
428 p = frag_more (4);
429 memset (p, 0, 4);
430 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &e, 0,
431 BFD_RELOC_GPREL32);
432 }
433
434 static void
435 create_literal_section (secp, name)
436 segT *secp;
437 const char *name;
438 {
439 segT current_section = now_seg;
440 int current_subsec = now_subseg;
441 segT new_sec;
442
443 *secp = new_sec = subseg_new (name, 0);
444 subseg_set (current_section, current_subsec);
445 bfd_set_section_alignment (stdoutput, new_sec, 3);
446 bfd_set_section_flags (stdoutput, new_sec,
447 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
448 | SEC_DATA);
449 }
450
451 #define create_lita_section() create_literal_section (&lita_sec, ".lita")
452
453 static valueT
454 get_lit8_offset (val)
455 bfd_vma val;
456 {
457 valueT retval;
458 if (lit8_sec == 0)
459 {
460 create_literal_section (&lit8_sec, ".lit8");
461 lit8_sym = section_symbol (lit8_sec);
462 }
463 retval = add_to_literal_pool ((symbolS *) 0, val, lit8_sec, 8);
464 if (retval >= 0xfff0)
465 as_fatal ("overflow in fp literal (.lit8) table");
466 return retval;
467 }
468
469 static valueT
470 get_lit4_offset (val)
471 bfd_vma val;
472 {
473 valueT retval;
474 if (lit4_sec == 0)
475 {
476 create_literal_section (&lit4_sec, ".lit4");
477 lit4_sym = section_symbol (lit4_sec);
478 }
479 retval = add_to_literal_pool ((symbolS *) 0, val, lit4_sec, 4);
480 if (retval >= 0xfff0)
481 as_fatal ("overflow in fp literal (.lit4) table");
482 return retval;
483 }
484
485 /* This function is called once, at assembler startup time. It should
486 set up all the tables, etc. that the MD part of the assembler will need. */
487 void
488 md_begin ()
489 {
490 const char *retval;
491 int lose = 0;
492 unsigned int i = 0;
493
494 op_hash = hash_new ();
495
496 for (i = 0; i < NUMOPCODES; )
497 {
498 const char *name = alpha_opcodes[i].name;
499 retval = hash_insert (op_hash, name, (PTR) & alpha_opcodes[i]);
500 if (retval)
501 {
502 as_bad ("internal error: can't hash opcode `%s': %s",
503 alpha_opcodes[i].name, retval);
504 lose = 1;
505 }
506 do
507 ++i;
508 while (i < NUMOPCODES
509 && (alpha_opcodes[i].name == name
510 || !strcmp (alpha_opcodes[i].name, name)));
511 }
512 /* Some opcodes include modifiers of various sorts with a "/mod"
513 syntax, like the architecture documentation suggests. However,
514 for use with gcc at least, we also need to access those same
515 opcodes without the "/". */
516 for (i = 0; i < NUMOPCODES; )
517 {
518 const char *name = alpha_opcodes[i].name;
519 if (strchr (name, '/'))
520 {
521 char *p = xmalloc (strlen (name));
522 const char *q = name;
523 char *q2 = p;
524
525 for (; *q; q++)
526 if (*q != '/')
527 *q2++ = *q;
528
529 *q2++ = 0;
530 retval = hash_insert (op_hash, p, (PTR) & alpha_opcodes[i]);
531 if (retval)
532 {
533 /* Ignore failures -- the opcode table does duplicate
534 some variants in different forms, like "hw_st/q" and
535 "hw_stq". */
536 #if 0
537 as_bad ("internal error: can't hash opcode variant `%s': %s",
538 p, retval);
539 lose = 1;
540 #endif
541 }
542 }
543 do
544 ++i;
545 while (i < NUMOPCODES
546 && (alpha_opcodes[i].name == name
547 || !strcmp (alpha_opcodes[i].name, name)));
548 }
549
550
551 if (lose)
552 as_fatal ("Broken assembler. No assembly attempted.");
553
554 lituse_basereg.X_op = O_constant;
555 lituse_basereg.X_add_number = 1;
556 lituse_byteoff.X_op = O_constant;
557 lituse_byteoff.X_add_number = 2;
558 lituse_jsr.X_op = O_constant;
559 lituse_jsr.X_add_number = 3;
560
561 /* So .sbss will get used for tiny objects. */
562 bfd_set_gp_size (stdoutput, 8);
563 create_lita_section ();
564 /* For handling the GP, create a symbol that won't be output in the
565 symbol table. We'll edit it out of relocs later. */
566 gp = symbol_new ("<GP value>", lita_sec, 0x8000, &zero_address_frag);
567 symbol_remove (gp, &symbol_rootP, &symbol_lastP);
568 }
569
570 int optnum = 1;
571
572 void
573 md_assemble (str)
574 char *str;
575 {
576 char *toP;
577 int i, j, count;
578 #define MAX_INSNS 5
579 struct alpha_it insns[MAX_INSNS];
580
581 count = alpha_ip (str, insns);
582 if (count <= 0)
583 return;
584
585 for (i = 0; i < count; i++)
586 {
587 toP = frag_more (4);
588
589 /* put out the opcode */
590 md_number_to_chars (toP, insns[i].opcode, 4);
591
592 /* put out the symbol-dependent stuff */
593 for (j = 0; j < MAX_RELOCS; j++)
594 {
595 struct reloc_data *r = &insns[i].reloc[j];
596 fixS *f;
597
598 if (r->code != BFD_RELOC_NONE)
599 {
600 if (r->exp.X_op == O_constant)
601 {
602 r->exp.X_add_symbol = section_symbol (absolute_section);
603 r->exp.X_op = O_symbol;
604 }
605 f = fix_new_exp (frag_now, (toP - frag_now->fr_literal), 4,
606 &r->exp, r->pcrel, r->code);
607 }
608 if (r->code == BFD_RELOC_ALPHA_GPDISP_LO16)
609 {
610 static bit_fixS cookie;
611 /* This'll make the range checking in write.c shut up. */
612 f->fx_bit_fixP = &cookie;
613 }
614 }
615 }
616 }
617
618 static inline void
619 maybe_set_gp (sec)
620 asection *sec;
621 {
622 bfd_vma vma;
623 if (!sec)
624 return;
625 vma = bfd_get_section_vma (foo, sec);
626 if (vma && vma < alpha_gp_value)
627 alpha_gp_value = vma;
628 }
629
630 static void
631 select_gp_value ()
632 {
633 if (alpha_gp_value != 0)
634 abort ();
635
636 /* Get minus-one in whatever width... */
637 alpha_gp_value = 0; alpha_gp_value--;
638
639 /* Select the smallest VMA of these existing sections. */
640 maybe_set_gp (lita_sec);
641 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
642 #if 0
643 maybe_set_gp (lit8_sec);
644 maybe_set_gp (lit4_sec);
645 #endif
646
647 alpha_gp_value += GP_ADJUSTMENT;
648
649 S_SET_VALUE (gp, alpha_gp_value);
650
651 #ifdef DEBUG1
652 printf ("Chose GP value of %lx\n", alpha_gp_value);
653 #endif
654 }
655
656 int
657 alpha_force_relocation (f)
658 fixS *f;
659 {
660 switch (f->fx_r_type)
661 {
662 case BFD_RELOC_ALPHA_GPDISP_HI16:
663 case BFD_RELOC_ALPHA_GPDISP_LO16:
664 case BFD_RELOC_ALPHA_LITERAL:
665 case BFD_RELOC_ALPHA_LITUSE:
666 case BFD_RELOC_GPREL32:
667 return 1;
668 case BFD_RELOC_ALPHA_HINT:
669 case BFD_RELOC_64:
670 case BFD_RELOC_32:
671 case BFD_RELOC_16:
672 case BFD_RELOC_8:
673 case BFD_RELOC_23_PCREL_S2:
674 case BFD_RELOC_14:
675 return 0;
676 default:
677 abort ();
678 return 0;
679 }
680 }
681
682 int
683 alpha_fix_adjustable (f)
684 fixS *f;
685 {
686 /* Are there any relocation types for which we must generate a reloc
687 but we can adjust the values contained within it? */
688 switch (f->fx_r_type)
689 {
690 case BFD_RELOC_ALPHA_GPDISP_HI16:
691 case BFD_RELOC_ALPHA_GPDISP_LO16:
692 return 0;
693 case BFD_RELOC_GPREL32:
694 return 1;
695 }
696 return !alpha_force_relocation (f);
697 }
698
699 valueT
700 md_section_align (seg, size)
701 segT seg;
702 valueT size;
703 {
704 #ifdef OBJ_ECOFF
705 /* This should probably be handled within BFD, or by pulling the
706 number from BFD at least. */
707 #define MIN 15
708 size += MIN;
709 size &= ~MIN;
710 #endif
711 return size;
712 }
713
714 /* Add this thing to the .lita section and produce a LITERAL reloc referring
715 to it.
716
717 TODO:
718 Remove duplicates.
719 Set GP value properly, and have values in LITERAL references set
720 accordingly.
721 */
722
723 static void
724 load_symbol_address (reg, insn)
725 int reg;
726 struct alpha_it *insn;
727 {
728 static symbolS *lita_sym;
729
730 int x;
731 addressT reloc_addr;
732 valueT retval;
733 char *p;
734 symbolS *sym;
735 valueT addend;
736
737 if (!lita_sym)
738 {
739 lita_sym = section_symbol (lita_sec);
740 S_CLEAR_EXTERNAL (lita_sym);
741 }
742
743 retval = add_to_literal_pool (insn->reloc[0].exp.X_add_symbol,
744 insn->reloc[0].exp.X_add_number,
745 lita_sec, 8);
746
747 /* Now emit a LITERAL relocation for the original section. */
748 insn->reloc[0].exp.X_op = O_symbol;
749 insn->reloc[0].exp.X_add_symbol = lita_sym;
750 insn->reloc[0].exp.X_add_number = retval;
751 insn->reloc[0].code = BFD_RELOC_ALPHA_LITERAL;
752
753 if (retval == 0x8000)
754 /* Overflow? */
755 as_fatal ("overflow in literal (.lita) table");
756 x = retval;
757 if (addr32)
758 insn->opcode = (0xa0000000 /* ldl */
759 | (reg << SA)
760 | (base_register << SB)
761 | (x & 0xffff));
762 else
763 insn->opcode = (0xa4000000 /* ldq */
764 | (reg << SA)
765 | (base_register << SB)
766 | (x & 0xffff));
767 note_gpreg (base_register);
768 }
769
770 /* To load an address with a single instruction,
771 emit a LITERAL reloc in this section, and a REFQUAD
772 for the .lita section, so that we'll be able to access
773 it via $gp:
774 lda REG, xx -> ldq REG, -32752(gp)
775 lda REG, xx+4 -> ldq REG, -32752(gp)
776 lda REG, 4(REG)
777
778 The offsets need to start near -0x8000, and the generated LITERAL
779 relocations should negate the offset. I don't completely grok the
780 scheme yet. */
781
782 static int
783 load_expression (reg, insn)
784 int reg;
785 struct alpha_it *insn;
786 {
787 valueT addend;
788 int num_insns = 1;
789
790 if (insn->reloc[0].exp.X_add_symbol->bsym->flags & BSF_SECTION_SYM)
791 {
792 addend = 0;
793 }
794 else
795 {
796 addend = insn->reloc[0].exp.X_add_number;
797 insn->reloc[0].exp.X_add_number = 0;
798 }
799 load_symbol_address (reg, insn);
800 if (addend)
801 {
802 num_insns++;
803 {
804 valueT x = addend;
805 if ((x & ~0x7fff) != 0
806 && (x & ~0x7fff) + 0x8000 != 0)
807 {
808 as_bad ("assembler not prepared to handle constants >16 bits yet");
809 addend = 0;
810 }
811 }
812 insn[1].opcode = (0x20000000 /* lda */
813 | (reg << SA)
814 | (reg << SB)
815 | (addend & 0xffff));
816 insn[1].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
817 insn[1].reloc[0].exp = lituse_basereg;
818 }
819 return num_insns;
820 }
821
822 static inline void
823 getExpression (str, this_insn)
824 char *str;
825 struct alpha_it *this_insn;
826 {
827 char *save_in;
828 segT seg;
829
830 #if 0 /* Not converted to bfd yet, and I don't think we need them
831 for ECOFF. Re-adding a.out support will probably require
832 them though. */
833 static const struct am {
834 char *name;
835 bfd_reloc_code_real_type reloc;
836 } macro[] = {
837 { "hi", RELOC_48_63 },
838 { "lo", RELOC_0_15 },
839 { "ml", RELOC_16_31 },
840 { "mh", RELOC_32_47 },
841 { "uhi", RELOC_U_48_63 },
842 { "uml", RELOC_U_16_31 },
843 { "umh", RELOC_U_32_47 },
844 { 0, }
845 };
846
847 /* Handle macros: "%macroname(expr)" */
848 if (*str == '%')
849 {
850 struct am *m;
851 char *p, *q;
852
853 str++;
854 m = &macro[0];
855 while (q = m->name)
856 {
857 p = str;
858 while (*q && *p == *q)
859 p++, q++;
860 if (*q == 0)
861 break;
862 m++;
863 }
864 if (q)
865 {
866 str = p; /* keep the '(' */
867 this_insn->reloc = m->reloc;
868 }
869 }
870 #endif
871
872 save_in = input_line_pointer;
873 input_line_pointer = str;
874
875 seg = expression (&this_insn->reloc[0].exp);
876 /* XXX validate seg and exp, make sure they're reasonable */
877 expr_end = input_line_pointer;
878 input_line_pointer = save_in;
879 }
880
881 /* Note that for now, this function is called recursively (by way of
882 calling md_assemble again). Some of the macros defined as part of
883 the assembly language are currently rewritten as sequences of
884 strings to be assembled. See, for example, the handling of "divq".
885
886 For efficiency, this should be fixed someday. */
887 static int
888 alpha_ip (str, insns)
889 char *str;
890 struct alpha_it insns[];
891 {
892 char *s;
893 const char *args;
894 char c;
895 unsigned long i;
896 struct alpha_opcode *pattern;
897 char *argsStart;
898 unsigned int opcode;
899 unsigned int mask;
900 int match = 0, num_gen = 1;
901 int comma = 0;
902
903 for (s = str;
904 islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
905 ++s)
906 ;
907 switch (*s)
908 {
909
910 case '\0':
911 break;
912
913 case ',':
914 comma = 1;
915
916 /*FALLTHROUGH*/
917
918 case ' ':
919 *s++ = '\0';
920 break;
921
922 default:
923 as_warn ("Unknown opcode: `%s'", str);
924 exit (1);
925 }
926 if ((pattern = (struct alpha_opcode *) hash_find (op_hash, str)) == NULL)
927 {
928 as_warn ("Unknown opcode: `%s'", str);
929 return -1;
930 }
931 if (comma)
932 *--s = ',';
933
934 argsStart = s;
935 for (;;)
936 {
937 opcode = pattern->match;
938 num_gen = 1;
939 memset (insns, 0, sizeof (*insns));
940 for (i = 0; i < MAX_RELOCS; i++)
941 insns[0].reloc[i].code = BFD_RELOC_NONE;
942 for (i = 1; i < MAX_INSNS; i++)
943 insns[i] = insns[0];
944
945 /* Build the opcode, checking as we go to make sure that the
946 operands match. */
947 for (args = pattern->args;; ++args)
948 {
949 switch (*args)
950 {
951
952 case '\0': /* end of args */
953 if (*s == '\0')
954 {
955 match = 1;
956 }
957 break;
958
959 case '+':
960 if (*s == '+')
961 {
962 ++s;
963 continue;
964 }
965 if (*s == '-')
966 {
967 continue;
968 }
969 break;
970
971 case '(': /* these must match exactly */
972 case ')':
973 case ',':
974 case ' ':
975 case '0':
976 if (*s++ == *args)
977 continue;
978 break;
979
980 case '1': /* next operand must be a register */
981 case '2':
982 case '3':
983 case 'r':
984 case 'R':
985 if (*s++ == '$')
986 {
987 switch (c = *s++)
988 {
989
990 case 'a': /* $at: as temporary */
991 if (*s++ != 't')
992 goto error;
993 mask = AT;
994 break;
995
996 case 'g': /* $gp: base register */
997 if (*s++ != 'p')
998 goto error;
999 mask = base_register;
1000 break;
1001
1002 case 's': /* $sp: stack pointer */
1003 if (*s++ != 'p')
1004 goto error;
1005 mask = SP;
1006 break;
1007
1008
1009 case 'r': /* any register */
1010 if (!isdigit (c = *s++))
1011 {
1012 goto error;
1013 }
1014 /* FALLTHROUGH */
1015 case '0':
1016 case '1':
1017 case '2':
1018 case '3':
1019 case '4':
1020 case '5':
1021 case '6':
1022 case '7':
1023 case '8':
1024 case '9':
1025 if (isdigit (*s))
1026 {
1027 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
1028 {
1029 goto error;
1030 }
1031 }
1032 else
1033 {
1034 c -= '0';
1035 }
1036 if ((c == GP) && first_32bit_quadrant)
1037 c = ZERO;
1038
1039 mask = c;
1040 break;
1041
1042 default:
1043 goto error;
1044 }
1045 note_gpreg (mask);
1046 /* Got the register, now figure out where it goes in
1047 the opcode. */
1048 doregister:
1049 switch (*args)
1050 {
1051
1052 case '1':
1053 case 'e':
1054 opcode |= mask << SA;
1055 continue;
1056
1057 case '2':
1058 case 'f':
1059 opcode |= mask << SB;
1060 continue;
1061
1062 case '3':
1063 case 'g':
1064 opcode |= mask;
1065 continue;
1066
1067 case 'r':
1068 opcode |= (mask << SA) | mask;
1069 continue;
1070
1071 case 'R': /* ra and rb are the same */
1072 opcode |= (mask << SA) | (mask << SB);
1073 continue;
1074
1075 case 'E':
1076 opcode |= (mask << SA) | (mask << SB) | (mask);
1077 continue;
1078 }
1079 }
1080 break;
1081
1082 case 'e': /* next operand is a floating point register */
1083 case 'f':
1084 case 'g':
1085 case 'E':
1086 if (*s++ == '$' && *s++ == 'f' && isdigit (*s))
1087 {
1088 mask = *s++;
1089 if (isdigit (*s))
1090 {
1091 mask = 10 * (mask - '0') + (*s++ - '0');
1092 if (mask >= 32)
1093 {
1094 break;
1095 }
1096 }
1097 else
1098 {
1099 mask -= '0';
1100 }
1101 note_fpreg (mask);
1102 /* same encoding as gp registers */
1103 goto doregister;
1104 }
1105 break;
1106
1107 #if 0
1108 case 'h': /* bits 16..31 */
1109 insns[0].reloc = RELOC_16_31;
1110 goto immediate;
1111 #endif
1112
1113 case 'l': /* bits 0..15 */
1114 insns[0].reloc[0].code = BFD_RELOC_16;
1115 goto immediate;
1116
1117 case 'L': /* 21 bit PC relative immediate */
1118 insns[0].reloc[0].code = BFD_RELOC_23_PCREL_S2;
1119 insns[0].reloc[0].pcrel = 1;
1120 goto immediate;
1121
1122 case 'i': /* 14 bit immediate */
1123 if (OPCODE (opcode) != 0x1a)
1124 /* Not a jmp variant?? */
1125 abort ();
1126 else if (opcode & 0x8000)
1127 /* ret or jsr_coroutine */
1128 {
1129 insns[0].reloc[0].code = BFD_RELOC_14;
1130 insns[0].reloc[0].pcrel = 0;
1131 }
1132 else
1133 /* jmp or jsr */
1134 {
1135 insns[0].reloc[0].code = BFD_RELOC_ALPHA_HINT;
1136 insns[0].reloc[0].pcrel = 1;
1137 }
1138 goto immediate;
1139
1140 case 'b': /* 8 bit immediate */
1141 insns[0].reloc[0].code = BFD_RELOC_8;
1142 goto immediate;
1143
1144 #if 0
1145 case 't': /* 12 bit 0...11 */
1146 insns[0].reloc = RELOC_0_12;
1147 goto immediate;
1148
1149 case '8': /* 8 bit 0...7 */
1150 insns[0].reloc = RELOC_0_8;
1151 goto immediate;
1152
1153 case 'I': /* 26 bit immediate */
1154 insns[0].reloc = RELOC_0_25;
1155 #else
1156 case 't':
1157 case '8':
1158 case 'I':
1159 abort ();
1160 #endif
1161 /*FALLTHROUGH*/
1162
1163 immediate:
1164 if (*s == ' ')
1165 s++;
1166 getExpression (s, &insns[0]);
1167 s = expr_end;
1168 /* Handle overflow in certain instructions by converting
1169 to other instructions. */
1170 if (insns[0].reloc[0].code == BFD_RELOC_8
1171 && insns[0].reloc[0].exp.X_op == O_constant
1172 && (insns[0].reloc[0].exp.X_add_number < 0
1173 || insns[0].reloc[0].exp.X_add_number > 0xff))
1174 {
1175 if (OPCODE (opcode) == 0x10
1176 && (OP_FCN (opcode) == 0x00 /* addl */
1177 || OP_FCN (opcode) == 0x40 /* addl/v */
1178 || OP_FCN (opcode) == 0x20 /* addq */
1179 || OP_FCN (opcode) == 0x60 /* addq/v */
1180 || OP_FCN (opcode) == 0x09 /* subl */
1181 || OP_FCN (opcode) == 0x49 /* subl/v */
1182 || OP_FCN (opcode) == 0x29 /* subq */
1183 || OP_FCN (opcode) == 0x69 /* subq/v */
1184 || OP_FCN (opcode) == 0x02 /* s4addl */
1185 || OP_FCN (opcode) == 0x22 /* s4addq */
1186 || OP_FCN (opcode) == 0x0b /* s4subl */
1187 || OP_FCN (opcode) == 0x2b /* s4subq */
1188 || OP_FCN (opcode) == 0x12 /* s8addl */
1189 || OP_FCN (opcode) == 0x32 /* s8addq */
1190 || OP_FCN (opcode) == 0x1b /* s8subl */
1191 || OP_FCN (opcode) == 0x3b /* s8subq */
1192 )
1193 /* Can we make it fit by negating? */
1194 && -insns[0].reloc[0].exp.X_add_number < 0xff
1195 && -insns[0].reloc[0].exp.X_add_number > 0)
1196 {
1197 opcode ^= 0x120; /* convert add<=>sub */
1198 insns[0].reloc[0].exp.X_add_number *= -1;
1199 }
1200 else if (at_ok && macro_ok)
1201 {
1202 /* Constant value supplied, but it's too large. */
1203 char expansion[64];
1204 sprintf (expansion, "lda $%d,%d($%d)", AT,
1205 insns[0].reloc[0].exp.X_add_number, ZERO);
1206 md_assemble (expansion);
1207 opcode |= 0x1000 /* use reg */ | (AT << SB);
1208 insns[0].reloc[0].code = BFD_RELOC_NONE;
1209 }
1210 else
1211 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1212 }
1213 continue;
1214
1215 case 'F':
1216 {
1217 int format, length, mode, i, size;
1218 char temp[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1219 char *err;
1220 static const char formats[4] = "FGfd";
1221 bfd_vma bits, offset;
1222 char *old_input_line_pointer = input_line_pointer;
1223
1224 input_line_pointer = s;
1225 SKIP_WHITESPACE ();
1226 memset (temp, 0, sizeof (temp));
1227 mode = (opcode >> 26) & 3;
1228 format = formats[mode];
1229 err = md_atof (format, temp, &length);
1230 if (err)
1231 {
1232 as_bad ("Bad floating literal: %s", err);
1233 bits = 0;
1234 }
1235 else
1236 {
1237 /* Generate little-endian number from byte sequence. */
1238 bits = 0;
1239 for (i = length - 1; i >= 0; i--)
1240 bits += ((bfd_vma)(temp[i] & 0xff)) << (i * 8);
1241 }
1242 switch (length)
1243 {
1244 case 8:
1245 offset = get_lit8_offset (bits) - 0x8000;
1246 insns[0].reloc[0].exp.X_add_symbol = lit8_sym;
1247 insns[0].reloc[0].exp.X_add_number = 0x8000;
1248 break;
1249 case 4:
1250 offset = get_lit4_offset (bits) - 0x8000;
1251 insns[0].reloc[0].exp.X_add_symbol = lit4_sym;
1252 insns[0].reloc[0].exp.X_add_number = 0x8000;
1253 break;
1254 default:
1255 abort ();
1256 }
1257 insns[0].reloc[0].exp.X_op = O_symbol;
1258 offset &= 0xffff;
1259 num_gen = load_expression (AT, &insns[0]);
1260 insns[num_gen].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1261 insns[num_gen].reloc[0].exp = lituse_basereg;
1262 insns[num_gen++].opcode = opcode | (AT << SB) | offset;
1263 opcode = insns[0].opcode;
1264 s = input_line_pointer;
1265 input_line_pointer = old_input_line_pointer;
1266 }
1267 continue;
1268
1269 /* The following two.. take advantage of the fact that
1270 opcode already contains most of what we need to know.
1271 We just prepend to the instr an "ldah
1272 $r,%ml(expr)($base)" and turn this one (done later
1273 after we return) into something like "stq
1274 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1275
1276 NOTE: This can fail later on at link time if the
1277 offset from $base actually turns out to be more than
1278 2**31 or 2**47 if use_large_offsets is set. */
1279 case 'P': /* Addressing macros: PUT */
1280 mask = AT; /* register 'at' */
1281 /* fall through */
1282
1283 case 'G': /* Addressing macros: GET */
1284 get_macro:
1285 /* All it is missing is the expression, which is what we
1286 will get now */
1287
1288 if (*s == ' ')
1289 s++;
1290 getExpression (s, &insns[0]);
1291 s = expr_end;
1292
1293 /* Must check for "lda ..,number" too */
1294 if (insns[0].reloc[0].exp.X_op == O_big)
1295 {
1296 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1297 return -1;
1298 }
1299 if (insns[0].reloc[0].exp.X_op == O_constant)
1300 {
1301 /* This only handles 32bit numbers */
1302 register int val = insns[0].reloc[0].exp.X_add_number;
1303 register short sval;
1304
1305 insns[0].reloc[0].code = BFD_RELOC_NONE;
1306 insns[1].reloc[0].code = BFD_RELOC_NONE;
1307
1308 sval = val;
1309 if ((sval != val) && (val & 0x8000))
1310 {
1311 val += 0x10000;
1312 sval = val;
1313 }
1314
1315 if (optnum && (sval == val))
1316 {
1317 /* optimize away the ldah */
1318 num_gen = 1;
1319 opcode |= (ZERO << SB) | (val & 0xffff);
1320 }
1321 else
1322 {
1323 num_gen = 2;
1324 insns[1].opcode = opcode | (mask << SB) | (val & 0xffff);
1325 opcode = 0x24000000 /*ldah*/ |
1326 mask << SA | (ZERO << SB) |
1327 ((val >> 16) & 0xffff);
1328 }
1329 }
1330 else if (insns[0].reloc[0].exp.X_op == O_symbol)
1331 {
1332 unsigned long old_opcode = opcode;
1333 int tmp_reg;
1334
1335 if (!macro_ok)
1336 as_bad ("insn requires expansion but `nomacro' specified");
1337 else if (*args == 'G')
1338 tmp_reg = mask;
1339 else if (!at_ok)
1340 as_bad ("insn expansion requires AT use, but `noat' specified");
1341 else
1342 tmp_reg = AT;
1343 num_gen = load_expression (tmp_reg, insns);
1344 opcode = insns[0].opcode;
1345 /* lda is opcode 8, 0x20000000 */
1346 if (OPCODE (old_opcode) != 0x08)
1347 {
1348 struct alpha_it *i;
1349 i = &insns[num_gen++];
1350 i->opcode = old_opcode | (tmp_reg << SB);
1351
1352 i->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1353 i->reloc[0].exp = lituse_basereg;
1354 }
1355 }
1356 else
1357 {
1358 /* Not a number */
1359 num_gen = 2;
1360 insns[1].reloc[0].exp = insns[0].reloc[0].exp;
1361
1362 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1363
1364 abort (); /* relocs need fixing */
1365 #if 0
1366 insns[1].reloc = RELOC_0_15;
1367 insns[1].opcode = opcode | mask << SB;
1368
1369 insns[0].reloc = RELOC_16_31;
1370 opcode = 0x24000000 /*ldah*/ | mask << SA | (base_register << SB);
1371 #endif
1372 }
1373
1374 continue;
1375
1376 /* Same failure modes as above, actually most of the
1377 same code shared. */
1378 case 'B': /* Builtins */
1379 args++;
1380 switch (*args)
1381 {
1382
1383 case 'a': /* ldgp */
1384
1385 if (first_32bit_quadrant || no_mixed_code)
1386 return -1;
1387 switch (OUTPUT_FLAVOR)
1388 {
1389 case bfd_target_aout_flavour:
1390 /* this is cmu's a.out version */
1391 insns[0].reloc[0].code = BFD_RELOC_NONE;
1392 /* generate "zap %r,0xf,%r" to take high 32 bits */
1393 opcode |= 0x48001600 /* zap ?,#,?*/ | (0xf << SN);
1394 break;
1395 case bfd_target_ecoff_flavour:
1396 /* Given "ldgp R1,N(R2)", turn it into something
1397 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1398 appropriate constants and relocations. */
1399 {
1400 unsigned long r1, r2;
1401 unsigned long addend = 0;
1402
1403 num_gen = 2;
1404 r2 = mask;
1405 r1 = opcode & 0x3f;
1406 insns[0].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_HI16;
1407 insns[0].reloc[0].pcrel = 1;
1408 insns[0].reloc[0].exp.X_op = O_symbol;
1409 insns[0].reloc[0].exp.X_add_symbol = gp;
1410 insns[0].reloc[0].exp.X_add_number = 0;
1411 insns[0].opcode = (0x24000000 /* ldah */
1412 | (r1 << SA)
1413 | (r2 << SB));
1414 insns[1].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_LO16;
1415 insns[1].reloc[0].exp.X_op = O_symbol;
1416 insns[1].reloc[0].exp.X_add_symbol = gp;
1417 insns[1].reloc[0].exp.X_add_number = 4;
1418 insns[1].reloc[0].pcrel = 1;
1419 insns[1].opcode = 0x20000000 | (r1 << SA) | (r1 << SB);
1420 opcode = insns[0].opcode;
1421 /* merge in addend */
1422 insns[1].opcode |= addend & 0xffff;
1423 insns[0].opcode |= ((addend >> 16)
1424 + (addend & 0x8000 ? 1 : 0));
1425 ecoff_set_gp_prolog_size (0);
1426 }
1427 break;
1428 default:
1429 abort ();
1430 }
1431 continue;
1432
1433
1434 case 'b': /* setgp */
1435 switch (OUTPUT_FLAVOR)
1436 {
1437 case bfd_target_aout_flavour:
1438 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1439 opcode |= 0x48001600 /* zap ?,#,?*/
1440 | (0xf << SN) | (base_register);
1441 break;
1442 default:
1443 abort ();
1444 }
1445 continue;
1446
1447 case 'c': /* jsr $r,foo becomes
1448 lda $27,foo
1449 jsr $r,($27),foo
1450 Register 27, t12, is used by convention
1451 here. */
1452 {
1453 struct alpha_it *jsr;
1454 expressionS etmp;
1455 struct reloc_data *r;
1456
1457 /* We still have to parse the function name */
1458 if (*s == ' ')
1459 s++;
1460 getExpression (s, &insns[0]);
1461 etmp = insns[0].reloc[0].exp;
1462 s = expr_end;
1463 num_gen = load_expression (PV, &insns[0]);
1464 note_gpreg (PV);
1465
1466 jsr = &insns[num_gen++];
1467 jsr->opcode = (0x68004000 /* jsr */
1468 | (mask << SA)
1469 | (PV << SB)
1470 | 0);
1471 if (num_gen == 2)
1472 {
1473 /* LITUSE wasn't emitted yet */
1474 jsr->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1475 jsr->reloc[0].exp = lituse_jsr;
1476 r = &jsr->reloc[1];
1477 }
1478 else
1479 r = &jsr->reloc[0];
1480 r->exp = etmp;
1481 r->code = BFD_RELOC_ALPHA_HINT;
1482 r->pcrel = 1;
1483 opcode = insns[0].opcode;
1484 }
1485 continue;
1486
1487 /* DIVISION and MODULUS. Yech.
1488 Convert OP x,y,result
1489 to mov x,t10
1490 mov y,t11
1491 jsr t9, __OP
1492 mov t12,result
1493
1494 with appropriate optimizations if t10,t11,t12
1495 are the registers specified by the compiler.
1496 We are missing an obvious optimization
1497 opportunity here; if the ldq generated by the
1498 jsr assembly requires a cycle or two to make
1499 the value available, initiating it before one
1500 or two of the mov instructions would result in
1501 faster execution. */
1502 case '0': /* reml */
1503 case '1': /* divl */
1504 case '2': /* remq */
1505 case '3': /* divq */
1506 case '4': /* remlu */
1507 case '5': /* divlu */
1508 case '6': /* remqu */
1509 case '7': /* divqu */
1510 {
1511 static char func[8][6] = {
1512 "reml", "divl", "remq", "divq",
1513 "remlu", "divlu", "remqu", "divqu"
1514 };
1515 char expansion[64];
1516 int reg;
1517
1518 /* All regs parsed, in opcode */
1519
1520 /* Do the expansions, one instr at a time */
1521
1522 reg = (opcode >> SA) & 31;
1523 if (reg != T10)
1524 {
1525 /* x->t10 */
1526 sprintf (expansion, "mov $%d,$%d", reg, T10);
1527 md_assemble (expansion);
1528 }
1529 reg = (opcode >> SB) & 31;
1530 if (reg == T10)
1531 /* we already overwrote it! */
1532 abort ();
1533 else if (reg != T11)
1534 {
1535 /* y->t11 */
1536 sprintf (expansion, "mov $%d,$%d", reg, T11);
1537 md_assemble (expansion);
1538 }
1539 sprintf (expansion, "lda $%d,__%s", PV, func[*args - '0']);
1540 md_assemble (expansion);
1541 sprintf (expansion, "jsr $%d,($%d),__%s", T9, PV,
1542 func[*args - '0']);
1543 md_assemble (expansion);
1544 #if 0 /* huh? */
1545 if (!first_32bit_quadrant)
1546 {
1547 sprintf (expansion,
1548 "zap $%d,0xf,$%d",
1549 T9, base_register);
1550 md_assemble (expansion);
1551 }
1552 #endif
1553 sprintf (expansion, "ldgp $%d,0($%d)",
1554 base_register, T9);
1555 md_assemble (expansion);
1556
1557 /* Use insns[0] to get at the result */
1558 if ((reg = (opcode & 31)) != PV)
1559 opcode = (0x47e00400 /* or zero,zero,zero */
1560 | (PV << SB)
1561 | reg /* Rc */ ); /* pv->z */
1562 else
1563 num_gen = 0;
1564 }
1565 continue;
1566 }
1567 /* fall through */
1568
1569 default:
1570 abort ();
1571 }
1572 break;
1573 }
1574 error:
1575 if (match == 0)
1576 {
1577 /* Args don't match. */
1578 if (&pattern[1] - alpha_opcodes < NUMOPCODES
1579 && !strcmp (pattern->name, pattern[1].name))
1580 {
1581 ++pattern;
1582 s = argsStart;
1583 continue;
1584 }
1585 else
1586 {
1587 as_warn ("Illegal operands");
1588 return -1;
1589 }
1590 }
1591 else
1592 {
1593 /* Args match, see if a float instructions and -nofloats */
1594 if (nofloats && pattern->isa_float)
1595 return -1;
1596 }
1597 break;
1598 }
1599
1600 insns[0].opcode = opcode;
1601 return num_gen;
1602 }
1603
1604 /* Turn a string in input_line_pointer into a floating point constant
1605 of type type, and store the appropriate bytes in *litP. The number
1606 of LITTLENUMS emitted is stored in *sizeP. An error message is
1607 returned, or NULL on OK. */
1608
1609 /* Equal to MAX_PRECISION in atof-ieee.c */
1610 #define MAX_LITTLENUMS 6
1611
1612 char *
1613 md_atof (type, litP, sizeP)
1614 char type;
1615 char *litP;
1616 int *sizeP;
1617 {
1618 int prec;
1619 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1620 LITTLENUM_TYPE *wordP;
1621 char *t;
1622 char *atof_ieee (), *vax_md_atof ();
1623
1624 switch (type)
1625 {
1626 /* VAX floats */
1627 case 'G':
1628 /* VAX md_atof doesn't like "G" for some reason. */
1629 type = 'g';
1630 case 'F':
1631 case 'D':
1632 return vax_md_atof (type, litP, sizeP);
1633
1634 /* IEEE floats */
1635 case 'f':
1636 prec = 2;
1637 break;
1638
1639 case 'd':
1640 prec = 4;
1641 break;
1642
1643 case 'x':
1644 case 'X':
1645 prec = 6;
1646 break;
1647
1648 case 'p':
1649 case 'P':
1650 prec = 6;
1651 break;
1652
1653 default:
1654 *sizeP = 0;
1655 return "Bad call to MD_ATOF()";
1656 }
1657 t = atof_ieee (input_line_pointer, type, words);
1658 if (t)
1659 input_line_pointer = t;
1660 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1661
1662 for (wordP = words + prec - 1; prec--;)
1663 {
1664 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
1665 litP += sizeof (LITTLENUM_TYPE);
1666 }
1667
1668 return 0;
1669 }
1670
1671 void
1672 md_bignum_to_chars (buf, bignum, nchars)
1673 char *buf;
1674 LITTLENUM_TYPE *bignum;
1675 int nchars;
1676 {
1677 while (nchars)
1678 {
1679 LITTLENUM_TYPE work = *bignum++;
1680 int nb = CHARS_PER_LITTLENUM;
1681
1682 do
1683 {
1684 *buf++ = work & ((1 << BITS_PER_CHAR) - 1);
1685 if (--nchars == 0)
1686 return;
1687 work >>= BITS_PER_CHAR;
1688 }
1689 while (--nb);
1690 }
1691 }
1692
1693 int
1694 md_parse_option (argP, cntP, vecP)
1695 char **argP;
1696 int *cntP;
1697 char ***vecP;
1698 {
1699 if (**argP == 'F')
1700 {
1701 nofloats = 1;
1702 return 1;
1703 }
1704 #if 0 /* I have no idea if this stuff would work any more. And it's
1705 probably not right for ECOFF anyways. */
1706 /* Use base-register addressing, e.g. PIC code */
1707 if (**argP == 'B')
1708 {
1709 if (first_32bit_quadrant)
1710 {
1711 first_32bit_quadrant = 0;
1712 base_register = GP;
1713 }
1714 else
1715 {
1716 first_32bit_quadrant = 1;
1717 base_register = ZERO;
1718 }
1719 if (argP[0][1] == 'k')
1720 no_mixed_code = 1;
1721 argP[0][1] = 0;
1722 return 1;
1723 }
1724 #endif
1725 if (!strcmp (*argP, "32addr"))
1726 {
1727 addr32 = 1;
1728 *argP += 6;
1729 return 1;
1730 }
1731 if (!strcmp (*argP, "nocpp"))
1732 {
1733 *argP += 5;
1734 return 1;
1735 }
1736 return 0;
1737 }
1738
1739 static void
1740 s_proc (is_static)
1741 {
1742 /* XXXX Align to cache linesize XXXXX */
1743 char *name;
1744 char c;
1745 char *p;
1746 symbolS *symbolP;
1747 int temp;
1748
1749 /* Takes ".proc name,nargs" */
1750 name = input_line_pointer;
1751 c = get_symbol_end ();
1752 p = input_line_pointer;
1753 symbolP = symbol_find_or_make (name);
1754 *p = c;
1755 SKIP_WHITESPACE ();
1756 if (*input_line_pointer != ',')
1757 {
1758 *p = 0;
1759 as_warn ("Expected comma after name \"%s\"", name);
1760 *p = c;
1761 temp = 0;
1762 ignore_rest_of_line ();
1763 }
1764 else
1765 {
1766 input_line_pointer++;
1767 temp = get_absolute_expression ();
1768 }
1769 /* symbolP->sy_other = (signed char) temp; */
1770 as_warn ("unhandled: .proc %s,%d", name, temp);
1771 demand_empty_rest_of_line ();
1772 }
1773
1774 static void
1775 s_alpha_set (x)
1776 int x;
1777 {
1778 char *name = input_line_pointer, ch, *s;
1779 int yesno = 1;
1780
1781 while (!is_end_of_line[(unsigned char) *input_line_pointer])
1782 input_line_pointer++;
1783 ch = *input_line_pointer;
1784 *input_line_pointer = '\0';
1785
1786 s = name;
1787 if (s[0] == 'n' && s[1] == 'o')
1788 {
1789 yesno = 0;
1790 s += 2;
1791 }
1792 if (!strcmp ("reorder", s))
1793 /* ignore */ ;
1794 else if (!strcmp ("at", s))
1795 at_ok = yesno;
1796 else if (!strcmp ("macro", s))
1797 macro_ok = yesno;
1798 else
1799 as_warn ("Tried to set unrecognized symbol: %s", name);
1800 *input_line_pointer = ch;
1801 demand_empty_rest_of_line ();
1802 }
1803
1804 /* @@ Is this right?? */
1805 long
1806 md_pcrel_from (fixP)
1807 fixS *fixP;
1808 {
1809 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1810 switch (fixP->fx_r_type)
1811 {
1812 case BFD_RELOC_ALPHA_GPDISP_HI16:
1813 case BFD_RELOC_ALPHA_GPDISP_LO16:
1814 return addr;
1815 default:
1816 return fixP->fx_size + addr;
1817 }
1818 }
1819
1820 int
1821 alpha_do_align (n, fill)
1822 int n;
1823 char *fill;
1824 {
1825 if (!fill
1826 && (now_seg == text_section
1827 || !strcmp (now_seg->name, ".init")
1828 || !strcmp (now_seg->name, ".fini")))
1829 {
1830 static const unsigned char nop_pattern[] = { 0x1f, 0x04, 0xff, 0x47 };
1831 frag_align_pattern (n, nop_pattern, sizeof (nop_pattern));
1832 return 1;
1833 }
1834 return 0;
1835 }
1836
1837 int
1838 md_apply_fix (fixP, valueP)
1839 fixS *fixP;
1840 valueT *valueP;
1841 {
1842 valueT value;
1843 int size;
1844 valueT addend;
1845 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
1846
1847 value = *valueP;
1848
1849 switch (fixP->fx_r_type)
1850 {
1851 /* The GPDISP relocations are processed internally with a symbol
1852 referring to the current function; we need to drop in a value
1853 which, when added to the address of the start of the function,
1854 gives the desired GP. */
1855 case BFD_RELOC_ALPHA_GPDISP_HI16:
1856 case BFD_RELOC_ALPHA_GPDISP_LO16:
1857 addend = value;
1858 if (fixP->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
1859 {
1860 assert (fixP->fx_next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
1861 #ifdef DEBUG1
1862 printf ("hi16: ");
1863 fprintf_vma (stdout, addend);
1864 printf ("\n");
1865 #endif
1866 if (addend & 0x8000)
1867 addend += 0x10000;
1868 addend >>= 16;
1869 fixP->fx_offset = 4; /* @@ Compute this using fx_next. */
1870 }
1871 else
1872 {
1873 #ifdef DEBUG1
1874 printf ("lo16: ");
1875 fprintf_vma (stdout, addend);
1876 printf ("\n");
1877 #endif
1878 addend &= 0xffff;
1879 fixP->fx_offset = 0;
1880 }
1881 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
1882 addend, 2);
1883 fixP->fx_addsy = section_symbol (absolute_section);
1884 fixP->fx_offset += fixP->fx_frag->fr_address + fixP->fx_where;
1885 break;
1886
1887 case BFD_RELOC_8:
1888 /* Write 8 bits, shifted left 13 bit positions. */
1889 value &= 0xff;
1890 p++;
1891 *p &= 0x1f;
1892 *p |= (value << 5) & 0xe0;
1893 value >>= 3;
1894 p++;
1895 *p &= 0xe0;
1896 *p |= value;
1897 value >>= 5;
1898 fixP->fx_done = 1;
1899 check_zov:
1900 if (value != 0)
1901 as_bad_where (fixP->fx_file, fixP->fx_line,
1902 "overflow in type-%d reloc", (int) fixP->fx_r_type);
1903 return 3;
1904
1905 case BFD_RELOC_32:
1906 size = 4;
1907 goto do_it;
1908 case BFD_RELOC_64:
1909 size = 8;
1910 goto do_it;
1911 case BFD_RELOC_16:
1912 /* Don't want overflow checking. */
1913 size = 2;
1914 do_it:
1915 if (fixP->fx_pcrel == 0
1916 && fixP->fx_addsy == 0)
1917 {
1918 md_number_to_chars (p, value, size);
1919 /* @@ Overflow checks?? */
1920 goto done;
1921 }
1922 break;
1923
1924 case BFD_RELOC_14:
1925 if (fixP->fx_addsy != 0
1926 && fixP->fx_addsy->bsym->section != absolute_section)
1927 as_bad_where (fixP->fx_file, fixP->fx_line,
1928 "ret/jsr_coroutine requires constant in displacement field");
1929 else if (value >> 14 != 0)
1930 as_bad_where (fixP->fx_file, fixP->fx_line,
1931 "overflow in 14-bit operand field of ret or jsr_coroutine");
1932 *p++ = value & 0xff;
1933 value >>= 8;
1934 *p = (*p & 0xc0) | (value & 0x3f);
1935 goto done;
1936
1937 case BFD_RELOC_23_PCREL_S2:
1938 /* Write 21 bits only. */
1939 value >>= 2;
1940 *p++ = value & 0xff;
1941 value >>= 8;
1942 *p++ = value & 0xff;
1943 value >>= 8;
1944 *p &= 0xe0;
1945 *p |= (value & 0x1f);
1946 goto done;
1947
1948 case BFD_RELOC_ALPHA_LITERAL:
1949 case BFD_RELOC_ALPHA_LITUSE:
1950 return 2;
1951
1952 case BFD_RELOC_GPREL32:
1953 assert (fixP->fx_subsy == gp);
1954 value = - alpha_gp_value; /* huh? this works... */
1955 fixP->fx_subsy = 0;
1956 md_number_to_chars (p, value, 4);
1957 break;
1958
1959 case BFD_RELOC_ALPHA_HINT:
1960 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
1961 {
1962 size = 2;
1963 goto do_it;
1964 }
1965 return 2;
1966
1967 default:
1968 as_fatal ("unknown relocation type %d?", fixP->fx_r_type);
1969 return 9;
1970 }
1971
1972 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
1973 {
1974 printf ("type %d reloc done?\n", fixP->fx_r_type);
1975 done:
1976 fixP->fx_done = 1;
1977 return 42;
1978 }
1979
1980 return 0x12345678;
1981 }
1982
1983 void
1984 alpha_frob_ecoff_data ()
1985 {
1986 select_gp_value ();
1987 /* $zero and $f31 are read-only */
1988 alpha_gprmask &= ~1;
1989 alpha_fprmask &= ~1;
1990 }
1991
1992 /* The Alpha has support for some VAX floating point types, as well as for
1993 IEEE floating point. We consider IEEE to be the primary floating point
1994 format, and sneak in the VAX floating point support here. */
1995 #define md_atof vax_md_atof
1996 #include "config/atof-vax.c"
This page took 0.106197 seconds and 4 git commands to generate.