]> Git Repo - binutils.git/blob - gas/config/tc-alpha.c
(load_expression): Parenthesize operations in range checking, to avoid
[binutils.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  [email protected]
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.131751 seconds and 4 git commands to generate.