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