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