f35ea2033874afc77d43c46e91f299a3898f1f16
[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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <ctype.h>
58
59 #include "as.h"
60 #include "alpha-opcode.h"
61 #include "subsegs.h"
62
63 /* The OSF/1 V2.0 Alpha compiler can't compile this file with inline
64 functions. */
65 #ifndef __GNUC__
66 #undef inline
67 #define inline
68 #endif
69
70 /* @@ Will a simple 0x8000 work here? If not, why not? */
71 #define GP_ADJUSTMENT (0x8000 - 0x10)
72
73 /* These are exported to relaxing code, even though we don't do any
74 relaxing on this processor currently. */
75 int md_short_jump_size = 4;
76 int md_long_jump_size = 4;
77
78 /* handle of the OPCODE hash table */
79 static struct hash_control *op_hash;
80
81 /* Sections and symbols we'll want to keep track of. */
82 static segT lita_sec, rdata, sdata, lit8_sec, lit4_sec;
83 static symbolS *lit8_sym, *lit4_sym;
84
85 /* Setting for ".set [no]{at,macro}". */
86 static int at_ok = 1, macro_ok = 1;
87
88 /* Keep track of global pointer. */
89 valueT alpha_gp_value;
90 static symbolS *gp;
91
92 /* We'll probably be using this relocation frequently, and we
93 will want to compare for it. */
94 static reloc_howto_type *gpdisp_hi16_howto;
95
96 /* These are exported to ECOFF code. */
97 unsigned long alpha_gprmask, alpha_fprmask;
98
99 /* Used for LITUSE relocations. */
100 static expressionS lituse_basereg, lituse_byteoff, lituse_jsr;
101
102 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
103 cause all addresses to be treated as 32-bit values in memory. (The
104 in-register versions are all sign-extended to 64 bits, of course.)
105 Some other systems may want this option too. */
106 static int addr32;
107
108 /* Symbol labelling the current insn. When the Alpha gas sees
109 foo:
110 .quad 0
111 and the section happens to not be on an eight byte boundary, it
112 will align both the symbol and the .quad to an eight byte boundary. */
113 static symbolS *insn_label;
114
115 /* Whether we should automatically align data generation pseudo-ops.
116 .align 0 will turn this off. */
117 static int auto_align = 1;
118
119 /* Imported functions -- they should be defined in header files somewhere. */
120 extern segT subseg_get ();
121 extern PTR bfd_alloc_by_size_t ();
122 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
123 s_data (), float_cons ();
124
125 /* Static functions, needing forward declarations. */
126 static void s_base (), s_proc (), s_alpha_set ();
127 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
128 static void s_alpha_text PARAMS ((int));
129 static void s_alpha_data PARAMS ((int));
130 static void s_alpha_align PARAMS ((int));
131 static void s_alpha_cons PARAMS ((int));
132 static void s_alpha_float_cons PARAMS ((int));
133 static int alpha_ip ();
134
135 static void emit_unaligned_io PARAMS ((char *, int, valueT, int));
136 static void emit_load_unal PARAMS ((int, valueT, int));
137 static void emit_store_unal PARAMS ((int, valueT, int));
138 static void emit_byte_manip_r PARAMS ((char *, int, int, int, int, int));
139 static void emit_extract_r PARAMS ((int, int, int, int, int));
140 static void emit_insert_r PARAMS ((int, int, int, int, int));
141 static void emit_mask_r PARAMS ((int, int, int, int, int));
142 static void emit_sign_extend PARAMS ((int, int));
143 static void emit_bis_r PARAMS ((int, int, int));
144 static int build_mem PARAMS ((int, int, int, bfd_signed_vma));
145 static int build_operate_n PARAMS ((int, int, int, int, int));
146 static void emit_sll_n PARAMS ((int, int, int));
147 static void emit_ldah_num PARAMS ((int, bfd_vma, int));
148 static void emit_addq_r PARAMS ((int, int, int));
149 static void emit_lda_n PARAMS ((int, bfd_vma, int));
150 static void emit_add64 PARAMS ((int, int, bfd_vma));
151 static int in_range_signed PARAMS ((bfd_vma, int));
152 static void alpha_align PARAMS ((int, int, symbolS *));
153
154 const pseudo_typeS md_pseudo_table[] =
155 {
156 {"common", s_comm, 0}, /* is this used? */
157 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
158 {"text", s_alpha_text, 0},
159 {"data", s_alpha_data, 0},
160 {"rdata", s_rdata, 0},
161 {"sdata", s_sdata, 0},
162 {"gprel32", s_gprel32, 0},
163 {"t_floating", s_alpha_float_cons, 'd'},
164 {"s_floating", s_alpha_float_cons, 'f'},
165 {"f_floating", s_alpha_float_cons, 'F'},
166 {"g_floating", s_alpha_float_cons, 'G'},
167 {"d_floating", s_alpha_float_cons, 'D'},
168
169 {"proc", s_proc, 0},
170 {"aproc", s_proc, 1},
171 {"set", s_alpha_set, 0},
172 {"reguse", s_ignore, 0},
173 {"livereg", s_ignore, 0},
174 {"base", s_base, 0}, /*??*/
175 {"option", s_ignore, 0},
176 {"prologue", s_ignore, 0},
177 {"aent", s_ignore, 0},
178 {"ugen", s_ignore, 0},
179
180 {"align", s_alpha_align, 0},
181 {"byte", s_alpha_cons, 0},
182 {"hword", s_alpha_cons, 1},
183 {"int", s_alpha_cons, 2},
184 {"long", s_alpha_cons, 2},
185 {"octa", s_alpha_cons, 4},
186 {"quad", s_alpha_cons, 3},
187 {"short", s_alpha_cons, 1},
188 {"word", s_alpha_cons, 1},
189 {"double", s_alpha_float_cons, 'd'},
190 {"float", s_alpha_float_cons, 'f'},
191 {"single", s_alpha_float_cons, 'f'},
192
193 /* We don't do any optimizing, so we can safely ignore these. */
194 {"noalias", s_ignore, 0},
195 {"alias", s_ignore, 0},
196
197 {NULL, 0, 0},
198 };
199
200 #define SA 21 /* shift for register Ra */
201 #define SB 16 /* shift for register Rb */
202 #define SC 0 /* shift for register Rc */
203 #define SN 13 /* shift for 8 bit immediate # */
204
205 #define T9 23
206 #define T10 24
207 #define T11 25
208 #define T12 26
209 #define RA 26 /* note: same as T12 */
210 #define PV 27
211 #define AT 28
212 #define GP 29
213 #define SP 30
214 #define ZERO 31
215
216 #define OPCODE(X) (((X) >> 26) & 0x3f)
217 #define OP_FCN(X) (((X) >> 5) & 0x7f)
218
219 #ifndef FIRST_32BIT_QUADRANT
220 #define FIRST_32BIT_QUADRANT 0
221 #endif
222
223 int first_32bit_quadrant = FIRST_32BIT_QUADRANT;
224 int base_register = FIRST_32BIT_QUADRANT ? ZERO : GP;
225
226 int no_mixed_code = 0;
227 int nofloats = 0;
228
229 /* This array holds the chars that always start a comment. If the
230 pre-processor is disabled, these aren't very useful */
231 const char comment_chars[] = "#";
232
233 /* This array holds the chars that only start a comment at the beginning of
234 a line. If the line seems to have the form '# 123 filename'
235 .line and .file directives will appear in the pre-processed output */
236 /* Note that input_file.c hand checks for '#' at the beginning of the
237 first line of the input file. This is because the compiler outputs
238 #NO_APP at the beginning of its output. */
239 /* Also note that C style comments are always recognized. */
240 const char line_comment_chars[] = "#!";
241
242 /* Chars that can be used to separate mant from exp in floating point nums */
243 const char EXP_CHARS[] = "eE";
244
245 const char line_separator_chars[1];
246
247 /* Chars that mean this number is a floating point constant, as in
248 "0f12.456" or "0d1.2345e12". */
249 /* @@ Do all of these really get used on the alpha?? */
250 char FLT_CHARS[] = "rRsSfFdDxXpP";
251
252 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
253 changed in read.c. Ideally it shouldn't have to know about it at all,
254 but nothing is ideal around here. */
255
256 struct reloc_data {
257 expressionS exp;
258 int pcrel;
259 bfd_reloc_code_real_type code;
260 };
261
262 /* Occasionally, two relocations will be desired for one address.
263 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
264 and a HINT reloc. */
265 #define MAX_RELOCS 2
266
267 struct alpha_it {
268 unsigned long opcode; /* need at least 32 bits */
269 struct reloc_data reloc[MAX_RELOCS];
270 };
271
272 static void getExpression (char *str, struct alpha_it *insn);
273 static char *expr_end;
274
275 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
276 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
277
278 int
279 tc_get_register (frame)
280 int frame;
281 {
282 int framereg = SP;
283
284 SKIP_WHITESPACE ();
285 if (*input_line_pointer == '$')
286 {
287 input_line_pointer++;
288 if (input_line_pointer[0] == 's'
289 && input_line_pointer[1] == 'p')
290 {
291 input_line_pointer += 2;
292 framereg = SP;
293 }
294 else
295 framereg = get_absolute_expression ();
296 framereg &= 31; /* ? */
297 }
298 else
299 as_warn ("frame reg expected, using $%d.", framereg);
300
301 note_gpreg (framereg);
302 return framereg;
303 }
304
305 /* Handle the .text pseudo-op. This is like the usual one, but it
306 clears insn_label and restores auto alignment. */
307
308 static void
309 s_alpha_text (i)
310 int i;
311 {
312 s_text (i);
313 insn_label = NULL;
314 auto_align = 1;
315 }
316
317 /* Handle the .data pseudo-op. This is like the usual one, but it
318 clears insn_label and restores auto alignment. */
319
320 static void
321 s_alpha_data (i)
322 int i;
323 {
324 s_data (i);
325 insn_label = NULL;
326 auto_align = 1;
327 }
328
329 static void
330 s_rdata (ignore)
331 int ignore;
332 {
333 int temp;
334
335 temp = get_absolute_expression ();
336 #if 0
337 if (!rdata)
338 rdata = subseg_get (".rdata", 0);
339 subseg_set (rdata, (subsegT) temp);
340 #else
341 rdata = subseg_new (".rdata", 0);
342 #endif
343 demand_empty_rest_of_line ();
344 insn_label = NULL;
345 auto_align = 1;
346 }
347
348 static void
349 s_sdata (ignore)
350 int ignore;
351 {
352 int temp;
353
354 temp = get_absolute_expression ();
355 #if 0
356 if (!sdata)
357 sdata = subseg_get (".sdata", 0);
358 subseg_set (sdata, (subsegT) temp);
359 #else
360 sdata = subseg_new (".sdata", 0);
361 #endif
362 demand_empty_rest_of_line ();
363 insn_label = NULL;
364 auto_align = 1;
365 }
366
367 static void
368 s_alpha_comm (ignore)
369 int ignore;
370 {
371 register char *name;
372 register char c;
373 register char *p;
374 offsetT temp;
375 register symbolS *symbolP;
376
377 name = input_line_pointer;
378 c = get_symbol_end ();
379 /* just after name is now '\0' */
380 p = input_line_pointer;
381 *p = c;
382 SKIP_WHITESPACE ();
383 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
384 if (*input_line_pointer == ',')
385 {
386 input_line_pointer++;
387 SKIP_WHITESPACE ();
388 }
389 if ((temp = get_absolute_expression ()) < 0)
390 {
391 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
392 ignore_rest_of_line ();
393 return;
394 }
395 *p = 0;
396 symbolP = symbol_find_or_make (name);
397 *p = c;
398 if (S_IS_DEFINED (symbolP))
399 {
400 as_bad ("Ignoring attempt to re-define symbol");
401 ignore_rest_of_line ();
402 return;
403 }
404 if (S_GET_VALUE (symbolP))
405 {
406 if (S_GET_VALUE (symbolP) != (valueT) temp)
407 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
408 S_GET_NAME (symbolP),
409 (long) S_GET_VALUE (symbolP),
410 (long) temp);
411 }
412 else
413 {
414 S_SET_VALUE (symbolP, (valueT) temp);
415 S_SET_EXTERNAL (symbolP);
416 }
417
418 know (symbolP->sy_frag == &zero_address_frag);
419 demand_empty_rest_of_line ();
420 }
421
422 arelent *
423 tc_gen_reloc (sec, fixp)
424 asection *sec;
425 fixS *fixp;
426 {
427 arelent *reloc;
428
429 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
430 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
431 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
432
433 if (fixp->fx_r_type > BFD_RELOC_UNUSED)
434 abort ();
435
436 if (fixp->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
437 {
438 if (!gpdisp_hi16_howto)
439 gpdisp_hi16_howto = bfd_reloc_type_lookup (stdoutput,
440 fixp->fx_r_type);
441 reloc->howto = gpdisp_hi16_howto;
442 }
443 else
444 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
445 if (reloc->howto == NULL)
446 {
447 as_bad_where (fixp->fx_file, fixp->fx_line,
448 "cannot represent `%s' relocation in object file",
449 bfd_get_reloc_code_name (fixp->fx_r_type));
450 return NULL;
451 }
452 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
453 {
454 as_fatal ("internal error? cannot generate `%s' relocation",
455 bfd_get_reloc_code_name (fixp->fx_r_type));
456 }
457 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
458
459 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
460 {
461 /* fake out bfd_perform_relocation. sigh */
462 reloc->addend = -alpha_gp_value;
463 }
464 else if (reloc->howto->pc_relative && reloc->howto->pcrel_offset)
465 {
466 reloc->addend = fixp->fx_offset - reloc->address;
467 }
468 else
469 reloc->addend = fixp->fx_offset;
470 return reloc;
471 }
472
473 static void
474 s_base ()
475 {
476 if (first_32bit_quadrant)
477 {
478 /* not fatal, but it might not work in the end */
479 as_warn ("File overrides no-base-register option.");
480 first_32bit_quadrant = 0;
481 }
482
483 SKIP_WHITESPACE ();
484 if (*input_line_pointer == '$')
485 { /* $rNN form */
486 input_line_pointer++;
487 if (*input_line_pointer == 'r')
488 input_line_pointer++;
489 }
490
491 base_register = get_absolute_expression ();
492 if (base_register < 0 || base_register > 31)
493 {
494 base_register = GP;
495 as_warn ("Bad base register, using $%d.", base_register);
496 }
497 demand_empty_rest_of_line ();
498 }
499
500 static int in_range_signed (val, nbits)
501 bfd_vma val;
502 int nbits;
503 {
504 /* Look at top bit of value that would be stored, figure out how it
505 would be extended by the hardware, and see if that matches the
506 original supplied value. */
507 bfd_vma mask;
508 bfd_vma one = 1;
509 bfd_vma top_bit, stored_value, missing_bits;
510
511 mask = (one << nbits) - 1;
512 stored_value = val & mask;
513 top_bit = stored_value & (one << (nbits - 1));
514 missing_bits = val & ~mask;
515 /* will sign-extend */
516 if (top_bit)
517 {
518 /* all remaining bits beyond mask should be one */
519 missing_bits |= mask;
520 return missing_bits + 1 == 0;
521 }
522 else
523 {
524 /* all other bits should be zero */
525 return missing_bits == 0;
526 }
527 }
528
529 #if 0
530 static int in_range_unsigned (val, nbits)
531 bfd_vma val;
532 int nbits;
533 {
534 /* Look at top bit of value that would be stored, figure out how it
535 would be extended by the hardware, and see if that matches the
536 original supplied value. */
537 bfd_vma mask;
538 bfd_vma one = 1;
539 bfd_vma top_bit, stored_value, missing_bits;
540
541 mask = (one << nbits) - 1;
542 stored_value = val & mask;
543 top_bit = stored_value & (one << nbits - 1);
544 missing_bits = val & ~mask;
545 return missing_bits == 0;
546 }
547 #endif
548
549 static void
550 s_gprel32 ()
551 {
552 expressionS e;
553 char *p;
554
555 SKIP_WHITESPACE ();
556 expression (&e);
557 switch (e.X_op)
558 {
559 case O_constant:
560 e.X_add_symbol = section_symbol (absolute_section);
561 /* fall through */
562 case O_symbol:
563 e.X_op = O_subtract;
564 e.X_op_symbol = gp;
565 break;
566 default:
567 abort ();
568 }
569 if (auto_align)
570 alpha_align (2, 0, insn_label);
571 p = frag_more (4);
572 memset (p, 0, 4);
573 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &e, 0,
574 BFD_RELOC_GPREL32);
575 insn_label = NULL;
576 }
577
578 static void
579 create_literal_section (secp, name)
580 segT *secp;
581 const char *name;
582 {
583 segT current_section = now_seg;
584 int current_subsec = now_subseg;
585 segT new_sec;
586
587 *secp = new_sec = subseg_new (name, 0);
588 subseg_set (current_section, current_subsec);
589 bfd_set_section_alignment (stdoutput, new_sec, 3);
590 bfd_set_section_flags (stdoutput, new_sec,
591 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
592 | SEC_DATA);
593 }
594
595 static valueT
596 get_lit8_offset (val)
597 bfd_vma val;
598 {
599 valueT retval;
600 if (lit8_sec == 0)
601 {
602 create_literal_section (&lit8_sec, ".lit8");
603 lit8_sym = section_symbol (lit8_sec);
604 }
605 retval = add_to_literal_pool ((symbolS *) 0, val, lit8_sec, 8);
606 if (retval >= 0xfff0)
607 as_fatal ("overflow in fp literal (.lit8) table");
608 return retval;
609 }
610
611 static valueT
612 get_lit4_offset (val)
613 bfd_vma val;
614 {
615 valueT retval;
616 if (lit4_sec == 0)
617 {
618 create_literal_section (&lit4_sec, ".lit4");
619 lit4_sym = section_symbol (lit4_sec);
620 }
621 retval = add_to_literal_pool ((symbolS *) 0, val, lit4_sec, 4);
622 if (retval >= 0xfff0)
623 as_fatal ("overflow in fp literal (.lit4) table");
624 return retval;
625 }
626
627 static struct alpha_it clear_insn;
628
629 /* This function is called once, at assembler startup time. It should
630 set up all the tables, etc. that the MD part of the assembler will
631 need, that can be determined before arguments are parsed. */
632 void
633 md_begin ()
634 {
635 const char *retval, *name;
636 unsigned int i = 0;
637
638 op_hash = hash_new ();
639
640 for (i = 0; i < NUMOPCODES; )
641 {
642 const char *name = alpha_opcodes[i].name;
643 retval = hash_insert (op_hash, name, (PTR) &alpha_opcodes[i]);
644 if (retval)
645 as_fatal ("internal error: can't hash opcode `%s': %s",
646 name, retval);
647
648 do
649 i++;
650 while (i < NUMOPCODES
651 && (alpha_opcodes[i].name == name
652 || !strcmp (alpha_opcodes[i].name, name)));
653 }
654 /* Some opcodes include modifiers of various sorts with a "/mod"
655 syntax, like the architecture documentation suggests. However,
656 for use with gcc at least, we also need to access those same
657 opcodes without the "/". */
658 for (i = 0; i < NUMOPCODES; )
659 {
660 name = alpha_opcodes[i].name;
661
662 if (strchr (name, '/'))
663 {
664 char *p = xmalloc (strlen (name));
665 const char *q = name;
666 char *q2 = p;
667
668 for (; *q; q++)
669 if (*q != '/')
670 *q2++ = *q;
671
672 *q2++ = 0;
673 retval = hash_insert (op_hash, p, (PTR) &alpha_opcodes[i]);
674 /* Ignore failures -- the opcode table does duplicate some
675 variants in different forms, like "hw_stq" and "hw_st/q".
676 Maybe the variants can be eliminated, and this error
677 checking restored. */
678 }
679
680 do
681 i++;
682 while (i < NUMOPCODES
683 && (alpha_opcodes[i].name == name
684 || !strcmp (alpha_opcodes[i].name, name)));
685 }
686
687 lituse_basereg.X_op = O_constant;
688 lituse_basereg.X_add_number = 1;
689 lituse_byteoff.X_op = O_constant;
690 lituse_byteoff.X_add_number = 2;
691 lituse_jsr.X_op = O_constant;
692 lituse_jsr.X_add_number = 3;
693
694 /* So .sbss will get used for tiny objects. */
695 bfd_set_gp_size (stdoutput, 8);
696 create_literal_section (&lita_sec, ".lita");
697 /* For handling the GP, create a symbol that won't be output in the
698 symbol table. We'll edit it out of relocs later. */
699 gp = symbol_create ("<GP value>", lita_sec, 0x8000, &zero_address_frag);
700
701 memset (&clear_insn, 0, sizeof (clear_insn));
702 for (i = 0; i < MAX_RELOCS; i++)
703 clear_insn.reloc[i].code = BFD_RELOC_NONE;
704 }
705
706 int optnum = 1;
707
708 static void
709 emit_insn (insn)
710 struct alpha_it *insn;
711 {
712 char *toP;
713 int j;
714
715 toP = frag_more (4);
716
717 /* put out the opcode */
718 md_number_to_chars (toP, insn->opcode, 4);
719
720 /* put out the symbol-dependent stuff */
721 for (j = 0; j < MAX_RELOCS; j++)
722 {
723 struct reloc_data *r = &insn->reloc[j];
724 fixS *f;
725
726 if (r->code != BFD_RELOC_NONE)
727 {
728 if (r->exp.X_op == O_constant)
729 {
730 r->exp.X_add_symbol = section_symbol (absolute_section);
731 r->exp.X_op = O_symbol;
732 }
733 f = fix_new_exp (frag_now, (toP - frag_now->fr_literal), 4,
734 &r->exp, r->pcrel, r->code);
735 if (r->code == BFD_RELOC_ALPHA_GPDISP_LO16)
736 {
737 static bit_fixS cookie;
738 /* @@ This'll make the range checking in write.c shut up. */
739 f->fx_bit_fixP = &cookie;
740 }
741 }
742 }
743
744 insn_label = NULL;
745 }
746
747 void
748 md_assemble (str)
749 char *str;
750 {
751 int i, count;
752 #define MAX_INSNS 5
753 struct alpha_it insns[MAX_INSNS];
754
755 count = alpha_ip (str, insns);
756 if (count <= 0)
757 return;
758
759 for (i = 0; i < count; i++)
760 emit_insn (&insns[i]);
761 }
762
763 static inline void
764 maybe_set_gp (sec)
765 asection *sec;
766 {
767 bfd_vma vma;
768 if (!sec)
769 return;
770 vma = bfd_get_section_vma (foo, sec);
771 if (vma && vma < alpha_gp_value)
772 alpha_gp_value = vma;
773 }
774
775 static void
776 select_gp_value ()
777 {
778 if (alpha_gp_value != 0)
779 abort ();
780
781 /* Get minus-one in whatever width... */
782 alpha_gp_value = 0; alpha_gp_value--;
783
784 /* Select the smallest VMA of these existing sections. */
785 maybe_set_gp (lita_sec);
786 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
787 #if 0
788 maybe_set_gp (lit8_sec);
789 maybe_set_gp (lit4_sec);
790 #endif
791
792 alpha_gp_value += GP_ADJUSTMENT;
793
794 S_SET_VALUE (gp, alpha_gp_value);
795
796 #ifdef DEBUG1
797 printf ("Chose GP value of %lx\n", alpha_gp_value);
798 #endif
799 }
800
801 int
802 alpha_force_relocation (f)
803 fixS *f;
804 {
805 switch (f->fx_r_type)
806 {
807 case BFD_RELOC_ALPHA_GPDISP_HI16:
808 case BFD_RELOC_ALPHA_GPDISP_LO16:
809 case BFD_RELOC_ALPHA_LITERAL:
810 case BFD_RELOC_ALPHA_LITUSE:
811 case BFD_RELOC_GPREL32:
812 return 1;
813 case BFD_RELOC_ALPHA_HINT:
814 case BFD_RELOC_64:
815 case BFD_RELOC_32:
816 case BFD_RELOC_16:
817 case BFD_RELOC_8:
818 case BFD_RELOC_23_PCREL_S2:
819 case BFD_RELOC_14:
820 case BFD_RELOC_26:
821 case BFD_RELOC_12_PCREL:
822 return 0;
823 default:
824 abort ();
825 return 0;
826 }
827 }
828
829 int
830 alpha_fix_adjustable (f)
831 fixS *f;
832 {
833 /* Are there any relocation types for which we must generate a reloc
834 but we can adjust the values contained within it? */
835 switch (f->fx_r_type)
836 {
837 case BFD_RELOC_ALPHA_GPDISP_HI16:
838 case BFD_RELOC_ALPHA_GPDISP_LO16:
839 return 0;
840 case BFD_RELOC_GPREL32:
841 return 1;
842 default:
843 return !alpha_force_relocation (f);
844 }
845 /*NOTREACHED*/
846 }
847
848 valueT
849 md_section_align (seg, size)
850 segT seg;
851 valueT size;
852 {
853 #ifdef OBJ_ECOFF
854 /* This should probably be handled within BFD, or by pulling the
855 number from BFD at least. */
856 #define MIN 15
857 size += MIN;
858 size &= ~MIN;
859 #endif
860 return size;
861 }
862
863 static int
864 build_mem (opc, ra, rb, disp)
865 int opc, ra, rb;
866 bfd_signed_vma disp;
867 {
868 if ((disp >> 15) != 0
869 && (disp >> 15) + 1 != 0)
870 abort ();
871 return ((opc << 26) | (ra << SA) | (rb << SB) | (disp & 0xffff));
872 }
873
874 static int
875 build_operate_n (opc, fn, ra, lit, rc)
876 int opc, fn, ra, rc;
877 int lit;
878 {
879 if (lit & ~0xff)
880 abort ();
881 return ((opc << 26) | (fn << 5) | (ra << SA) | (lit << SN) | (1 << 12) | (rc << SC));
882 }
883
884 static int
885 build_operate (opc, fn, ra, rb, rc)
886 int opc, fn, ra, rb, rc;
887 {
888 return ((opc << 26) | (fn << 5) | (ra << SA) | (rb << SB) | (rc << SC));
889 }
890
891 /* Add this thing to the .lita section and produce a LITERAL reloc referring
892 to it. */
893
894 /* Are we currently eligible to emit a LITUSE reloc for the literal
895 references just generated? */
896 static int lituse_pending;
897
898 static void
899 load_symbol_address (reg, insn)
900 int reg;
901 struct alpha_it *insn;
902 {
903 static symbolS *lita_sym;
904
905 int x;
906 valueT retval;
907
908 if (!lita_sym)
909 {
910 lita_sym = section_symbol (lita_sec);
911 S_CLEAR_EXTERNAL (lita_sym);
912 }
913
914 retval = add_to_literal_pool (insn->reloc[0].exp.X_add_symbol,
915 insn->reloc[0].exp.X_add_number,
916 lita_sec, 8);
917
918 /* Now emit a LITERAL relocation for the original section. */
919 insn->reloc[0].exp.X_op = O_symbol;
920 insn->reloc[0].exp.X_add_symbol = lita_sym;
921 insn->reloc[0].exp.X_add_number = retval;
922 insn->reloc[0].code = BFD_RELOC_ALPHA_LITERAL;
923 lituse_pending = 1;
924
925 if (retval == 0x8000)
926 /* Overflow? */
927 as_fatal ("overflow in literal (.lita) table");
928 x = retval;
929 insn->opcode = build_mem (addr32 ? 0x28 : 0x29, /* ldl or ldq */
930 reg, base_register, x & 0xffff);
931 note_gpreg (base_register);
932 }
933
934 /* To load an address with a single instruction,
935 emit a LITERAL reloc in this section, and a REFQUAD
936 for the .lita section, so that we'll be able to access
937 it via $gp:
938 lda REG, xx -> ldq REG, -32752(gp)
939 lda REG, xx+4 -> ldq REG, -32752(gp)
940 lda REG, 4(REG)
941
942 The offsets need to start near -0x8000, and the generated LITERAL
943 relocations should negate the offset. I don't completely grok the
944 scheme yet. */
945
946 static int
947 load_expression (reg, insn)
948 int reg;
949 struct alpha_it *insn;
950 {
951 valueT addend, addendhi, addendlo;
952 int num_insns = 1;
953
954 if (insn->reloc[0].exp.X_add_symbol->bsym->flags & BSF_SECTION_SYM)
955 {
956 addend = 0;
957 }
958 else
959 {
960 addend = insn->reloc[0].exp.X_add_number;
961 insn->reloc[0].exp.X_add_number = 0;
962 }
963 load_symbol_address (reg, insn);
964 if (addend)
965 {
966 if ((addend & ~0x7fffffff) != 0
967 && (addend & ~0x7fffffff) + 0x80000000 != 0)
968 {
969 as_bad ("assembler not prepared to handle constants >32 bits yet");
970 addend = 0;
971 }
972 addendlo = addend & 0xffff;
973 addend -= addendlo;
974 addendhi = addend >> 16;
975 if (addendlo & 0x8000)
976 addendhi++;
977 /* It appears that the BASEREG LITUSE reloc should not be used on
978 an LDAH instruction. */
979 if (addendlo)
980 {
981 insn[1].opcode = build_mem (0x08, reg, reg, addendlo & 0xffff);
982 insn[1].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
983 insn[1].reloc[0].exp = lituse_basereg;
984 num_insns++;
985 }
986 if (addendhi)
987 {
988 insn[num_insns].opcode = build_mem (0x09, reg, reg,
989 addendhi & 0xffff);
990 num_insns++;
991 }
992 if (num_insns == 1)
993 abort ();
994 lituse_pending = 0;
995 }
996 return num_insns;
997 }
998
999 static inline void
1000 getExpression (str, this_insn)
1001 char *str;
1002 struct alpha_it *this_insn;
1003 {
1004 char *save_in;
1005 segT seg;
1006
1007 #if 0 /* Not converted to bfd yet, and I don't think we need them
1008 for ECOFF. Re-adding a.out support will probably require
1009 them though. */
1010 static const struct am {
1011 char *name;
1012 bfd_reloc_code_real_type reloc;
1013 } macro[] = {
1014 { "hi", RELOC_48_63 },
1015 { "lo", RELOC_0_15 },
1016 { "ml", RELOC_16_31 },
1017 { "mh", RELOC_32_47 },
1018 { "uhi", RELOC_U_48_63 },
1019 { "uml", RELOC_U_16_31 },
1020 { "umh", RELOC_U_32_47 },
1021 { 0, }
1022 };
1023
1024 /* Handle macros: "%macroname(expr)" */
1025 if (*str == '%')
1026 {
1027 struct am *m;
1028 char *p, *q;
1029
1030 str++;
1031 m = &macro[0];
1032 while (q = m->name)
1033 {
1034 p = str;
1035 while (*q && *p == *q)
1036 p++, q++;
1037 if (*q == 0)
1038 break;
1039 m++;
1040 }
1041 if (q)
1042 {
1043 str = p; /* keep the '(' */
1044 this_insn->reloc = m->reloc;
1045 }
1046 }
1047 #endif
1048
1049 save_in = input_line_pointer;
1050 input_line_pointer = str;
1051
1052 seg = expression (&this_insn->reloc[0].exp);
1053 /* XXX validate seg and exp, make sure they're reasonable */
1054 expr_end = input_line_pointer;
1055 input_line_pointer = save_in;
1056 }
1057
1058 static void
1059 emit_unaligned_io (dir, addr_reg, addr_offset, reg)
1060 char *dir;
1061 int addr_reg, reg;
1062 valueT addr_offset;
1063 {
1064 char buf[90];
1065 sprintf (buf, "%sq_u $%d,%ld($%d)", dir, reg, (long) addr_offset, addr_reg);
1066 md_assemble (buf);
1067 }
1068
1069 static void
1070 emit_load_unal (addr_reg, addr_offset, reg)
1071 int addr_reg, reg;
1072 valueT addr_offset;
1073 {
1074 emit_unaligned_io ("ld", addr_reg, addr_offset, reg);
1075 }
1076
1077 static void
1078 emit_store_unal (addr_reg, addr_offset, reg)
1079 int addr_reg, reg;
1080 valueT addr_offset;
1081 {
1082 emit_unaligned_io ("st", addr_reg, addr_offset, reg);
1083 }
1084
1085 static void
1086 emit_byte_manip_r (op, in, mask, out, mode, which)
1087 char *op;
1088 int in, mask, out, mode, which;
1089 {
1090 char buf[90];
1091 sprintf (buf, "%s%c%c $%d,$%d,$%d", op, mode, which, in, mask, out);
1092 md_assemble (buf);
1093 }
1094
1095 static void
1096 emit_extract_r (in, mask, out, mode, which)
1097 int in, mask, out, mode, which;
1098 {
1099 emit_byte_manip_r ("ext", in, mask, out, mode, which);
1100 }
1101
1102 static void
1103 emit_insert_r (in, mask, out, mode, which)
1104 int in, mask, out, mode, which;
1105 {
1106 emit_byte_manip_r ("ins", in, mask, out, mode, which);
1107 }
1108
1109 static void
1110 emit_mask_r (in, mask, out, mode, which)
1111 int in, mask, out, mode, which;
1112 {
1113 emit_byte_manip_r ("msk", in, mask, out, mode, which);
1114 }
1115
1116 static void
1117 emit_sign_extend (reg, size)
1118 int reg, size;
1119 {
1120 char buf[90];
1121 sprintf (buf, "sll $%d,0x%x,$%d", reg, 64 - size, reg);
1122 md_assemble (buf);
1123 sprintf (buf, "sra $%d,0x%x,$%d", reg, 64 - size, reg);
1124 md_assemble (buf);
1125 }
1126
1127 static void
1128 emit_bis_r (in1, in2, out)
1129 int in1, in2, out;
1130 {
1131 char buf[90];
1132 sprintf (buf, "bis $%d,$%d,$%d", in1, in2, out);
1133 md_assemble (buf);
1134 }
1135
1136 static void
1137 emit_sll_n (dest, disp, src)
1138 int dest, disp, src;
1139 {
1140 struct alpha_it insn = clear_insn;
1141 insn.opcode = build_operate_n (0x12, 0x39, src, disp, dest);
1142 emit_insn (&insn);
1143 }
1144
1145 static void
1146 emit_ldah_num (dest, addend, src)
1147 int dest, src;
1148 bfd_vma addend;
1149 {
1150 struct alpha_it insn = clear_insn;
1151 insn.opcode = build_mem (0x09, dest, src, addend);
1152 emit_insn (&insn);
1153 }
1154
1155 static void
1156 emit_addq_r (in1, in2, out)
1157 int in1, in2, out;
1158 {
1159 struct alpha_it insn = clear_insn;
1160 insn.opcode = build_operate (0x10, 0x20, in1, in2, out);
1161 emit_insn (&insn);
1162 }
1163
1164 static void
1165 emit_lda_n (dest, addend, src)
1166 int dest, src;
1167 bfd_vma addend;
1168 {
1169 struct alpha_it insn = clear_insn;
1170 insn.opcode = build_mem (0x08, dest, src, addend);
1171 emit_insn (&insn);
1172 }
1173
1174 static void
1175 emit_add64 (in, out, num)
1176 int in, out;
1177 bfd_vma num;
1178 {
1179 bfd_signed_vma snum = num;
1180
1181 if (in_range_signed (num, 16))
1182 {
1183 emit_lda_n (out, num, in);
1184 return;
1185 }
1186 if ((num & 0xffff) == 0
1187 && in == ZERO
1188 && in_range_signed (snum >> 16, 16))
1189 {
1190 emit_ldah_num (out, snum >> 16, in);
1191 return;
1192 }
1193 /* I'm not sure this one is getting invoked when it could. */
1194 if ((num & 1) == 0 && in == ZERO)
1195 {
1196 if (in_range_signed (snum >> 1, 16))
1197 {
1198 emit_lda_n (out, snum >> 1, in);
1199 emit_addq_r (out, out, out);
1200 return;
1201 }
1202 else if (num & 0x1fffe == 0
1203 && in_range_signed (snum >> 17, 16))
1204 {
1205 emit_ldah_num (out, snum >> 17, in);
1206 emit_addq_r (out, out, out);
1207 return;
1208 }
1209 }
1210 if (in_range_signed (num, 32))
1211 {
1212 bfd_vma lo = num & 0xffff;
1213 if (lo & 0x8000)
1214 lo -= 0x10000;
1215 num -= lo;
1216 emit_ldah_num (out, snum >> 16, in);
1217 if (lo)
1218 emit_lda_n (out, lo, out);
1219 return;
1220 }
1221
1222 if (in != ZERO && in != AT && out != AT && at_ok)
1223 {
1224 emit_add64 (ZERO, AT, num);
1225 emit_addq_r (AT, in, out);
1226 return;
1227 }
1228
1229 if (in != ZERO)
1230 as_bad ("load expression too complex to expand");
1231
1232 /* Could check also for loading 16- or 32-bit value and shifting by
1233 arbitrary displacement. */
1234
1235 {
1236 bfd_vma lo = snum & 0xffffffff;
1237 if (lo & 0x80000000)
1238 lo -= ((bfd_vma)0x10000000 << 4);
1239 snum -= lo;
1240 emit_add64 (ZERO, out, snum >> 32);
1241 emit_sll_n (out, 32, out);
1242 if (lo != 0)
1243 emit_add64 (out, out, lo);
1244 }
1245 }
1246
1247 static int
1248 alpha_ip (str, insns)
1249 char *str;
1250 struct alpha_it insns[];
1251 {
1252 char *s;
1253 const char *args;
1254 char c;
1255 unsigned long i;
1256 struct alpha_opcode *pattern;
1257 char *argsStart;
1258 unsigned int opcode;
1259 unsigned int mask = 0;
1260 int match = 0, num_gen = 1;
1261 int comma = 0;
1262 int do_add64, add64_in = 0, add64_out = 0;
1263 bfd_vma add64_addend = 0;
1264
1265 for (s = str;
1266 islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
1267 ++s)
1268 ;
1269 switch (*s)
1270 {
1271
1272 case '\0':
1273 break;
1274
1275 case ',':
1276 comma = 1;
1277
1278 /*FALLTHROUGH*/
1279
1280 case ' ':
1281 *s++ = '\0';
1282 break;
1283
1284 default:
1285 as_fatal ("Unknown opcode: `%s'", str);
1286 }
1287 if ((pattern = (struct alpha_opcode *) hash_find (op_hash, str)) == NULL)
1288 {
1289 as_bad ("Unknown opcode: `%s'", str);
1290 return -1;
1291 }
1292 if (comma)
1293 *--s = ',';
1294
1295 argsStart = s;
1296 for (;;)
1297 {
1298 do_add64 = 0;
1299 opcode = pattern->match;
1300 num_gen = 1;
1301 for (i = 0; i < MAX_INSNS; i++)
1302 insns[i] = clear_insn;
1303
1304 /* Build the opcode, checking as we go to make sure that the
1305 operands match. */
1306 for (args = pattern->args;; ++args)
1307 {
1308 switch (*args)
1309 {
1310
1311 case '\0': /* end of args */
1312 if (*s == '\0')
1313 {
1314 match = 1;
1315 }
1316 break;
1317
1318 case '+':
1319 if (*s == '+')
1320 {
1321 ++s;
1322 continue;
1323 }
1324 if (*s == '-')
1325 {
1326 continue;
1327 }
1328 break;
1329
1330 case '(': /* these must match exactly */
1331 case ')':
1332 case ',':
1333 case ' ':
1334 case '0':
1335 if (*s++ == *args)
1336 continue;
1337 break;
1338
1339 case '1': /* next operand must be a register */
1340 case '2':
1341 case '3':
1342 case 'r':
1343 case 'R':
1344 if (*s++ == '$')
1345 {
1346 switch (c = *s++)
1347 {
1348
1349 case 'a': /* $at: as temporary */
1350 if (*s++ != 't')
1351 goto error;
1352 mask = AT;
1353 break;
1354
1355 case 'g': /* $gp: base register */
1356 if (*s++ != 'p')
1357 goto error;
1358 mask = base_register;
1359 break;
1360
1361 case 's': /* $sp: stack pointer */
1362 if (*s++ != 'p')
1363 goto error;
1364 mask = SP;
1365 break;
1366
1367
1368 case 'r': /* any register */
1369 if (!isdigit (c = *s++))
1370 {
1371 goto error;
1372 }
1373 /* FALLTHROUGH */
1374 case '0':
1375 case '1':
1376 case '2':
1377 case '3':
1378 case '4':
1379 case '5':
1380 case '6':
1381 case '7':
1382 case '8':
1383 case '9':
1384 if (isdigit (*s))
1385 {
1386 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
1387 {
1388 goto error;
1389 }
1390 }
1391 else
1392 {
1393 c -= '0';
1394 }
1395 if ((c == GP) && first_32bit_quadrant)
1396 c = ZERO;
1397
1398 mask = c;
1399 break;
1400
1401 default:
1402 goto error;
1403 }
1404 note_gpreg (mask);
1405 /* Got the register, now figure out where it goes in
1406 the opcode. */
1407 doregister:
1408 switch (*args)
1409 {
1410
1411 case '1':
1412 case 'e':
1413 opcode |= mask << SA;
1414 continue;
1415
1416 case '2':
1417 case 'f':
1418 opcode |= mask << SB;
1419 continue;
1420
1421 case '3':
1422 case 'g':
1423 opcode |= mask;
1424 continue;
1425
1426 case 'r':
1427 opcode |= (mask << SA) | mask;
1428 continue;
1429
1430 case 'R': /* ra and rb are the same */
1431 opcode |= (mask << SA) | (mask << SB);
1432 continue;
1433
1434 case 'E':
1435 opcode |= (mask << SA) | (mask << SB) | (mask);
1436 continue;
1437 }
1438 }
1439 break;
1440
1441 case 'e': /* next operand is a floating point register */
1442 case 'f':
1443 case 'g':
1444 case 'E':
1445 if (*s++ == '$' && *s++ == 'f' && isdigit (*s))
1446 {
1447 mask = *s++;
1448 if (isdigit (*s))
1449 {
1450 mask = 10 * (mask - '0') + (*s++ - '0');
1451 if (mask >= 32)
1452 {
1453 break;
1454 }
1455 }
1456 else
1457 {
1458 mask -= '0';
1459 }
1460 note_fpreg (mask);
1461 /* same encoding as gp registers */
1462 goto doregister;
1463 }
1464 break;
1465
1466 #if 0
1467 case 'h': /* bits 16..31 */
1468 insns[0].reloc = RELOC_16_31;
1469 goto immediate;
1470 #endif
1471
1472 case 'l': /* bits 0..15 */
1473 insns[0].reloc[0].code = BFD_RELOC_16;
1474 goto immediate;
1475
1476 case 'L': /* 21 bit PC relative immediate */
1477 insns[0].reloc[0].code = BFD_RELOC_23_PCREL_S2;
1478 insns[0].reloc[0].pcrel = 1;
1479 goto immediate;
1480
1481 case 'i': /* 14 bit immediate */
1482 if (OPCODE (opcode) != 0x1a)
1483 /* Not a jmp variant?? */
1484 abort ();
1485 else if (opcode & 0x8000)
1486 /* ret or jsr_coroutine */
1487 {
1488 insns[0].reloc[0].code = BFD_RELOC_14;
1489 insns[0].reloc[0].pcrel = 0;
1490 }
1491 else
1492 /* jmp or jsr */
1493 {
1494 insns[0].reloc[0].code = BFD_RELOC_ALPHA_HINT;
1495 insns[0].reloc[0].pcrel = 1;
1496 }
1497 goto immediate;
1498
1499 case 'b': /* 8 bit immediate */
1500 insns[0].reloc[0].code = BFD_RELOC_8;
1501 goto immediate;
1502
1503 case 'I': /* 26 bit immediate, for PALcode */
1504 insns[0].reloc[0].code = BFD_RELOC_26;
1505 goto immediate;
1506
1507 case 't': /* 12 bit displacement, for PALcode */
1508 insns[0].reloc[0].code = BFD_RELOC_12_PCREL;
1509 goto immediate;
1510
1511 case '8': /* 8 bit 0...7 */
1512 insns[0].reloc[0].code = BFD_RELOC_8;
1513 goto immediate;
1514
1515 immediate:
1516 if (*s == ' ')
1517 s++;
1518 getExpression (s, &insns[0]);
1519 s = expr_end;
1520 /* Handle overflow in certain instructions by converting
1521 to other instructions. */
1522 if (insns[0].reloc[0].code == BFD_RELOC_8
1523 && insns[0].reloc[0].exp.X_op == O_constant
1524 && (insns[0].reloc[0].exp.X_add_number < 0
1525 || insns[0].reloc[0].exp.X_add_number > 0xff))
1526 {
1527 if (OPCODE (opcode) == 0x10
1528 && (OP_FCN (opcode) == 0x00 /* addl */
1529 || OP_FCN (opcode) == 0x40 /* addl/v */
1530 || OP_FCN (opcode) == 0x20 /* addq */
1531 || OP_FCN (opcode) == 0x60 /* addq/v */
1532 || OP_FCN (opcode) == 0x09 /* subl */
1533 || OP_FCN (opcode) == 0x49 /* subl/v */
1534 || OP_FCN (opcode) == 0x29 /* subq */
1535 || OP_FCN (opcode) == 0x69 /* subq/v */
1536 || OP_FCN (opcode) == 0x02 /* s4addl */
1537 || OP_FCN (opcode) == 0x22 /* s4addq */
1538 || OP_FCN (opcode) == 0x0b /* s4subl */
1539 || OP_FCN (opcode) == 0x2b /* s4subq */
1540 || OP_FCN (opcode) == 0x12 /* s8addl */
1541 || OP_FCN (opcode) == 0x32 /* s8addq */
1542 || OP_FCN (opcode) == 0x1b /* s8subl */
1543 || OP_FCN (opcode) == 0x3b /* s8subq */
1544 )
1545 /* Can we make it fit by negating? */
1546 && -insns[0].reloc[0].exp.X_add_number < 0xff
1547 && -insns[0].reloc[0].exp.X_add_number > 0)
1548 {
1549 opcode ^= 0x120; /* convert add<=>sub */
1550 insns[0].reloc[0].exp.X_add_number *= -1;
1551 }
1552 else if (at_ok && macro_ok)
1553 {
1554 /* Constant value supplied, but it's too large. */
1555 do_add64 = 1;
1556 add64_in = ZERO;
1557 add64_out = AT;
1558 add64_addend = insns[0].reloc[0].exp.X_add_number;
1559 opcode &= ~ 0x1000;
1560 opcode |= (AT << SB);
1561 insns[0].reloc[0].code = BFD_RELOC_NONE;
1562 }
1563 else
1564 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1565 }
1566 else if (insns[0].reloc[0].code == BFD_RELOC_16
1567 && insns[0].reloc[0].exp.X_op == O_constant
1568 && !in_range_signed (insns[0].reloc[0].exp.X_add_number,
1569 16))
1570 {
1571 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1572 if (OPCODE (opcode) == 0x08)
1573 {
1574 do_add64 = 1;
1575 add64_in = ZERO;
1576 add64_out = AT;
1577 add64_addend = val;
1578 opcode &= ~0x1000;
1579 opcode |= (AT << SB);
1580 insns[0].reloc[0].code = BFD_RELOC_NONE;
1581 }
1582 else if (OPCODE (opcode) == 0x09
1583 && in_range_signed (val >> 16, 16))
1584 {
1585 /* ldah with high operand - convert to low */
1586 insns[0].reloc[0].exp.X_add_number >>= 16;
1587 }
1588 else
1589 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1590 }
1591 else if (insns[0].reloc[0].code == BFD_RELOC_32
1592 && insns[0].reloc[0].exp.X_op == O_constant)
1593 {
1594 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1595 bfd_signed_vma sval = val;
1596 if (val >> 32 != 0
1597 && sval >> 32 != 0
1598 && sval >> 32 != -1)
1599 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1600 }
1601 continue;
1602
1603 case 'F':
1604 {
1605 int format, length, mode, i;
1606 char temp[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1607 char *err;
1608 static const char formats[4] = "FGfd";
1609 bfd_vma bits, offset;
1610 char *old_input_line_pointer = input_line_pointer;
1611
1612 input_line_pointer = s;
1613 SKIP_WHITESPACE ();
1614 memset (temp, 0, sizeof (temp));
1615 mode = (opcode >> 26) & 3;
1616 format = formats[mode];
1617 err = md_atof (format, temp, &length);
1618 if (err)
1619 {
1620 as_bad ("Bad floating literal: %s", err);
1621 bits = 0;
1622 }
1623 else
1624 {
1625 /* Generate little-endian number from byte sequence. */
1626 bits = 0;
1627 for (i = length - 1; i >= 0; i--)
1628 bits += ((bfd_vma)(temp[i] & 0xff)) << (i * 8);
1629 }
1630 switch (length)
1631 {
1632 case 8:
1633 offset = get_lit8_offset (bits) - 0x8000;
1634 insns[0].reloc[0].exp.X_add_symbol = lit8_sym;
1635 insns[0].reloc[0].exp.X_add_number = 0x8000;
1636 break;
1637 case 4:
1638 offset = get_lit4_offset (bits) - 0x8000;
1639 insns[0].reloc[0].exp.X_add_symbol = lit4_sym;
1640 insns[0].reloc[0].exp.X_add_number = 0x8000;
1641 break;
1642 default:
1643 abort ();
1644 }
1645 insns[0].reloc[0].exp.X_op = O_symbol;
1646 offset &= 0xffff;
1647 num_gen = load_expression (AT, &insns[0]);
1648 if (lituse_pending)
1649 {
1650 insns[num_gen].reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1651 insns[num_gen].reloc[0].exp = lituse_basereg;
1652 lituse_pending = 0;
1653 }
1654 insns[num_gen++].opcode = opcode | (AT << SB) | offset;
1655 opcode = insns[0].opcode;
1656 s = input_line_pointer;
1657 input_line_pointer = old_input_line_pointer;
1658 }
1659 continue;
1660
1661 /* The following two.. take advantage of the fact that
1662 opcode already contains most of what we need to know.
1663 We just prepend to the instr an "ldah
1664 $r,%ml(expr)($base)" and turn this one (done later
1665 after we return) into something like "stq
1666 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1667
1668 NOTE: This can fail later on at link time if the
1669 offset from $base actually turns out to be more than
1670 2**31 or 2**47 if use_large_offsets is set. */
1671 case 'P': /* Addressing macros: PUT */
1672 mask = AT; /* register 'at' */
1673 /* fall through */
1674
1675 case 'G': /* Addressing macros: GET */
1676 /* All it is missing is the expression, which is what we
1677 will get now */
1678
1679 if (*s == ' ')
1680 s++;
1681 getExpression (s, &insns[0]);
1682 s = expr_end;
1683
1684 /* Must check for "lda ..,number" too */
1685 if (insns[0].reloc[0].exp.X_op == O_big)
1686 {
1687 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1688 return -1;
1689 }
1690 if (insns[0].reloc[0].exp.X_op == O_constant)
1691 {
1692 bfd_vma val = insns[0].reloc[0].exp.X_add_number;
1693 bfd_vma top, low;
1694
1695 insns[0].reloc[0].code = BFD_RELOC_NONE;
1696 insns[1].reloc[0].code = BFD_RELOC_NONE;
1697
1698 low = val & 0xffff;
1699 if (low & 0x8000)
1700 low -= 0x10000;
1701 top = val - low;
1702 if (top)
1703 {
1704 do_add64 = 1;
1705 add64_in = ZERO;
1706 add64_out = AT;
1707 add64_addend = top;
1708 opcode |= AT << SB;
1709 }
1710 else
1711 opcode |= ZERO << SB;
1712 opcode &= ~0x1000;
1713 opcode |= low & 0xffff;
1714 }
1715 else if (insns[0].reloc[0].exp.X_op == O_symbol)
1716 {
1717 unsigned long old_opcode = opcode;
1718 int tmp_reg = -1;
1719
1720 if (!macro_ok)
1721 as_bad ("insn requires expansion but `nomacro' specified");
1722 else if (*args == 'G')
1723 tmp_reg = mask;
1724 else if (!at_ok)
1725 as_bad ("insn expansion requires AT use, but `noat' specified");
1726 else
1727 tmp_reg = AT;
1728 num_gen = load_expression (tmp_reg, insns);
1729 opcode = insns[0].opcode;
1730 /* lda is opcode 8, 0x20000000, and the macros that use
1731 this code have an opcode field of 0. The latter
1732 require further processing, and we don't have the
1733 true opcode here. */
1734 if (OPCODE (old_opcode) != 0
1735 && OPCODE (old_opcode) != 0x08)
1736 {
1737 struct alpha_it *i;
1738 i = &insns[num_gen++];
1739 i->opcode = old_opcode | (tmp_reg << SB);
1740
1741 if (lituse_pending)
1742 {
1743 i->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1744 i->reloc[0].exp = lituse_basereg;
1745 lituse_pending = 0;
1746 }
1747 }
1748 }
1749 else
1750 {
1751 /* Not a number */
1752 num_gen = 2;
1753 insns[1].reloc[0].exp = insns[0].reloc[0].exp;
1754
1755 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1756
1757 abort (); /* relocs need fixing */
1758 #if 0
1759 insns[1].reloc = RELOC_0_15;
1760 insns[1].opcode = opcode | mask << SB;
1761
1762 insns[0].reloc = RELOC_16_31;
1763 opcode = 0x24000000 /*ldah*/ | mask << SA | (base_register << SB);
1764 #endif
1765 }
1766
1767 continue;
1768
1769 /* Same failure modes as above, actually most of the
1770 same code shared. */
1771 case 'B': /* Builtins */
1772 args++;
1773 switch (*args)
1774 {
1775
1776 case 'a': /* ldgp */
1777
1778 if (first_32bit_quadrant || no_mixed_code)
1779 return -1;
1780 switch (OUTPUT_FLAVOR)
1781 {
1782 case bfd_target_aout_flavour:
1783 /* this is cmu's a.out version */
1784 insns[0].reloc[0].code = BFD_RELOC_NONE;
1785 /* generate "zap %r,0xf,%r" to take high 32 bits */
1786 opcode |= 0x48001600 /* zap ?,#,?*/ | (0xf << SN);
1787 break;
1788 case bfd_target_ecoff_flavour:
1789 /* Given "ldgp R1,N(R2)", turn it into something
1790 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1791 appropriate constants and relocations. */
1792 {
1793 unsigned long r1, r2;
1794 unsigned long addend = 0;
1795
1796 num_gen = 2;
1797 r2 = mask;
1798 r1 = opcode & 0x3f;
1799 insns[0].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_HI16;
1800 insns[0].reloc[0].pcrel = 1;
1801 insns[0].reloc[0].exp.X_op = O_symbol;
1802 insns[0].reloc[0].exp.X_add_symbol = gp;
1803 insns[0].reloc[0].exp.X_add_number = 0;
1804 insns[0].opcode = (0x24000000 /* ldah */
1805 | (r1 << SA)
1806 | (r2 << SB));
1807 insns[1].reloc[0].code = BFD_RELOC_ALPHA_GPDISP_LO16;
1808 insns[1].reloc[0].exp.X_op = O_symbol;
1809 insns[1].reloc[0].exp.X_add_symbol = gp;
1810 insns[1].reloc[0].exp.X_add_number = 4;
1811 insns[1].reloc[0].pcrel = 1;
1812 insns[1].opcode = 0x20000000 | (r1 << SA) | (r1 << SB);
1813 opcode = insns[0].opcode;
1814 /* merge in addend */
1815 insns[1].opcode |= addend & 0xffff;
1816 insns[0].opcode |= ((addend >> 16)
1817 + (addend & 0x8000 ? 1 : 0));
1818 if (r2 == PV)
1819 ecoff_set_gp_prolog_size (0);
1820 }
1821 break;
1822 default:
1823 abort ();
1824 }
1825 continue;
1826
1827
1828 case 'b': /* setgp */
1829 switch (OUTPUT_FLAVOR)
1830 {
1831 case bfd_target_aout_flavour:
1832 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1833 opcode |= 0x48001600 /* zap ?,#,?*/
1834 | (0xf << SN) | (base_register);
1835 break;
1836 default:
1837 abort ();
1838 }
1839 continue;
1840
1841 case 'c': /* jsr $r,foo becomes
1842 lda $27,foo
1843 jsr $r,($27),foo
1844 Register 27, t12, is used by convention
1845 here. */
1846 {
1847 struct alpha_it *jsr;
1848 expressionS etmp;
1849 struct reloc_data *r;
1850
1851 /* We still have to parse the function name */
1852 if (*s == ' ')
1853 s++;
1854 getExpression (s, &insns[0]);
1855 etmp = insns[0].reloc[0].exp;
1856 s = expr_end;
1857 num_gen = load_expression (PV, &insns[0]);
1858 note_gpreg (PV);
1859
1860 jsr = &insns[num_gen++];
1861 jsr->opcode = (pattern->match
1862 | (mask << SA)
1863 | (PV << SB)
1864 | 0);
1865 if (lituse_pending)
1866 {
1867 /* LITUSE wasn't emitted yet */
1868 jsr->reloc[0].code = BFD_RELOC_ALPHA_LITUSE;
1869 jsr->reloc[0].exp = lituse_jsr;
1870 r = &jsr->reloc[1];
1871 lituse_pending = 0;
1872 }
1873 else
1874 r = &jsr->reloc[0];
1875 r->exp = etmp;
1876 r->code = BFD_RELOC_ALPHA_HINT;
1877 r->pcrel = 1;
1878 opcode = insns[0].opcode;
1879 }
1880 continue;
1881
1882 case 'd':
1883 /* Sub-word loads and stores. We load the address into
1884 $at, which might involve using the `P' parameter
1885 processing too, then emit a sequence to get the job
1886 done, using unaligned memory accesses and byte
1887 manipulation, with t9 and t10 as temporaries. */
1888 {
1889 /* Characteristics of access. */
1890 int is_load = 99, is_unsigned = 0, is_unaligned = 0;
1891 int mode_size, mode;
1892 /* Register operand. */
1893 int reg = -1;
1894 /* Addend for loads and stores. */
1895 valueT addend;
1896 /* Which register do we use for the address? */
1897 int addr;
1898
1899 {
1900 /* Pick apart name and set flags. */
1901 const char *s = pattern->name;
1902
1903 if (*s == 'u')
1904 {
1905 is_unaligned = 1;
1906 s++;
1907 }
1908
1909 if (s[0] == 'l' && s[1] == 'd')
1910 is_load = 1;
1911 else if (s[0] == 's' && s[1] == 't')
1912 is_load = 0;
1913 else
1914 as_fatal ("unrecognized sub-word access insn `%s'",
1915 str);
1916 s += 2;
1917
1918 mode = *s++;
1919 if (mode == 'b') mode_size = 1;
1920 else if (mode == 'w') mode_size = 2;
1921 else if (mode == 'l') mode_size = 4;
1922 else if (mode == 'q') mode_size = 8;
1923 else abort ();
1924
1925 if (*s == 'u')
1926 {
1927 is_unsigned = 1;
1928 s++;
1929 }
1930
1931 assert (*s == 0);
1932
1933 /* Longwords are always kept sign-extended. */
1934 if (mode == 'l' && is_unsigned)
1935 abort ();
1936 /* There's no special unaligned byte handling. */
1937 if (mode == 'b' && is_unaligned)
1938 abort ();
1939 /* Stores don't care about signedness. */
1940 if (!is_load && is_unsigned)
1941 abort ();
1942 }
1943
1944 if (args[-2] == 'P')
1945 {
1946 addr = AT;
1947 addend = 0;
1948 }
1949 else
1950 {
1951 /* foo r1,num(r2)
1952 r2 -> mask
1953 r1 -> (opcode >> SA) & 31
1954 num -> insns->reloc[0].*
1955
1956 We want to emit "lda at,num(r2)", since these
1957 operations require the use of a single register
1958 with the starting address of the memory operand
1959 we want to access.
1960
1961 We could probably get away without doing this
1962 (and use r2 below, with the addend for the
1963 actual reads and writes) in cases where the
1964 addend is known to be a multiple of 8. */
1965 int r2 = mask;
1966 int r1 = (opcode >> SA) & 31;
1967
1968 if (insns[0].reloc[0].code == BFD_RELOC_NONE)
1969 addend = 0;
1970 else if (insns[0].reloc[0].code == BFD_RELOC_16)
1971 {
1972 if (insns[0].reloc[0].exp.X_op != O_constant)
1973 abort ();
1974 addend = insns[0].reloc[0].exp.X_add_number;
1975 }
1976 else
1977 abort ();
1978
1979 if (addend + mode_size - 1 < 0x7fff
1980 && (addend % 8) == 0
1981 && (r2 < T9 || r2 > T12))
1982 {
1983 addr = r2;
1984 num_gen = 0;
1985 }
1986 else
1987 {
1988 /* Let later relocation processing deal
1989 with the addend field. */
1990 insns[num_gen-1].opcode = (0x20000000 /* lda */
1991 | (AT << SA)
1992 | (r2 << SB));
1993 addr = AT;
1994 addend = 0;
1995 }
1996 reg = r1;
1997 }
1998
1999 /* Because the emit_* routines append directly to
2000 the current frag, we now need to flush any
2001 pending insns. */
2002 {
2003 int i;
2004 for (i = 0; i < num_gen; i++)
2005 emit_insn (&insns[i]);
2006 num_gen = 0;
2007 }
2008
2009 if (is_load)
2010 {
2011 int reg2, reg3 = -1;
2012
2013 if (is_unaligned)
2014 reg2 = T9, reg3 = T10;
2015 else
2016 reg2 = reg;
2017
2018 emit_load_unal (addr, addend, T9);
2019 if (is_unaligned)
2020 emit_load_unal (addr, addend + mode_size - 1, T10);
2021 emit_extract_r (T9, addr, reg2, mode, 'l');
2022 if (is_unaligned)
2023 {
2024 emit_extract_r (T10, addr, reg3, mode, 'h');
2025 emit_bis_r (T9, T10, reg);
2026 }
2027 if (!is_unsigned)
2028 emit_sign_extend (reg, mode_size * 8);
2029 }
2030 else
2031 {
2032 /* The second word gets processed first
2033 because if the address does turn out to be
2034 aligned, the processing for the second word
2035 will be pushing around all-zeros, and the
2036 entire value will be handled as the `first'
2037 word. So we want to store the `first' word
2038 last. */
2039 /* Pair these up so that the memory loads get
2040 separated from each other, as well as being
2041 well in advance of the uses of the values
2042 loaded. */
2043 if (is_unaligned)
2044 {
2045 emit_load_unal (addr, addend + mode_size - 1, T11);
2046 emit_insert_r (reg, addr, T12, mode, 'h');
2047 }
2048 emit_load_unal (addr, addend, T9);
2049 emit_insert_r (reg, addr, T10, mode, 'l');
2050 if (is_unaligned)
2051 emit_mask_r (T12, addr, T12, mode, 'h');
2052 emit_mask_r (T10, addr, T10, mode, 'l');
2053 if (is_unaligned)
2054 emit_bis_r (T11, T12, T11);
2055 emit_bis_r (T9, T10, T9);
2056 if (is_unaligned)
2057 emit_store_unal (addr, addend + mode_size - 1, T11);
2058 emit_store_unal (addr, addend, T9);
2059 }
2060 }
2061 return 0;
2062
2063 /* DIVISION and MODULUS. Yech.
2064 Convert OP x,y,result
2065 to mov x,t10
2066 mov y,t11
2067 jsr t9, __OP
2068 mov t12,result
2069
2070 with appropriate optimizations if t10,t11,t12
2071 are the registers specified by the compiler.
2072 We are missing an obvious optimization
2073 opportunity here; if the ldq generated by the
2074 jsr assembly requires a cycle or two to make
2075 the value available, initiating it before one
2076 or two of the mov instructions would result in
2077 faster execution. */
2078 case '0': /* reml */
2079 case '1': /* divl */
2080 case '2': /* remq */
2081 case '3': /* divq */
2082 case '4': /* remlu */
2083 case '5': /* divlu */
2084 case '6': /* remqu */
2085 case '7': /* divqu */
2086 {
2087 static char func[8][6] = {
2088 "reml", "divl", "remq", "divq",
2089 "remlu", "divlu", "remqu", "divqu"
2090 };
2091 char expansion[64];
2092 int reg;
2093
2094 /* All regs parsed, in opcode */
2095
2096 /* Do the expansions, one instr at a time */
2097
2098 reg = (opcode >> SA) & 31;
2099 if (reg != T10)
2100 {
2101 /* x->t10 */
2102 sprintf (expansion, "mov $%d,$%d", reg, T10);
2103 md_assemble (expansion);
2104 }
2105 reg = (opcode >> SB) & 31;
2106 if (reg == T10)
2107 /* we already overwrote it! */
2108 abort ();
2109 else if (reg != T11)
2110 {
2111 /* y->t11 */
2112 sprintf (expansion, "mov $%d,$%d", reg, T11);
2113 md_assemble (expansion);
2114 }
2115 sprintf (expansion, "lda $%d,__%s", PV, func[*args - '0']);
2116 md_assemble (expansion);
2117 sprintf (expansion, "jsr $%d,($%d),__%s", T9, PV,
2118 func[*args - '0']);
2119 md_assemble (expansion);
2120 #if 0 /* huh? */
2121 if (!first_32bit_quadrant)
2122 {
2123 sprintf (expansion,
2124 "zap $%d,0xf,$%d",
2125 T9, base_register);
2126 md_assemble (expansion);
2127 }
2128 #endif
2129 sprintf (expansion, "ldgp $%d,0($%d)",
2130 base_register, T9);
2131 md_assemble (expansion);
2132
2133 /* Use insns[0] to get at the result */
2134 if ((reg = (opcode & 31)) != PV)
2135 opcode = (0x47e00400 /* or zero,zero,zero */
2136 | (PV << SB)
2137 | reg /* Rc */ ); /* pv->z */
2138 else
2139 num_gen = 0;
2140 }
2141 continue;
2142 }
2143 /* fall through */
2144
2145 default:
2146 abort ();
2147 }
2148 break;
2149 }
2150 error:
2151 if (match == 0)
2152 {
2153 /* Args don't match. */
2154 if (&pattern[1] - alpha_opcodes < NUMOPCODES
2155 && !strcmp (pattern->name, pattern[1].name))
2156 {
2157 ++pattern;
2158 s = argsStart;
2159 continue;
2160 }
2161 else
2162 {
2163 as_warn ("Illegal operands");
2164 return -1;
2165 }
2166 }
2167 else
2168 {
2169 /* Args match, see if a float instructions and -nofloats */
2170 if (nofloats && pattern->isa_float)
2171 return -1;
2172 }
2173 break;
2174 }
2175
2176 if (do_add64)
2177 {
2178 /* If opcode represents an addq instruction, and the addend we
2179 are using fits in a 16 bit range, we can change the addq
2180 directly into an lda rather than emitting an lda followed by
2181 an addq. */
2182 if (OPCODE (opcode) == 0x10
2183 && OP_FCN (opcode) == 0x20 /* addq */
2184 && add64_in == ZERO
2185 && add64_out == AT
2186 && in_range_signed (add64_addend, 16))
2187 {
2188 opcode = (0x20000000 /* lda */
2189 | (((opcode >> SC) & 0x1f) << SA)
2190 | (((opcode >> SA) & 0x1f) << SB)
2191 | (add64_addend & 0xffff));
2192 }
2193 else
2194 emit_add64 (add64_in, add64_out, add64_addend);
2195 }
2196
2197 insns[0].opcode = opcode;
2198 return num_gen;
2199 }
2200
2201 /* Turn a string in input_line_pointer into a floating point constant
2202 of type type, and store the appropriate bytes in *litP. The number
2203 of LITTLENUMS emitted is stored in *sizeP. An error message is
2204 returned, or NULL on OK. */
2205
2206 /* Equal to MAX_PRECISION in atof-ieee.c */
2207 #define MAX_LITTLENUMS 6
2208
2209 char *
2210 md_atof (type, litP, sizeP)
2211 char type;
2212 char *litP;
2213 int *sizeP;
2214 {
2215 int prec;
2216 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2217 LITTLENUM_TYPE *wordP;
2218 char *t;
2219 char *atof_ieee (), *vax_md_atof ();
2220
2221 switch (type)
2222 {
2223 /* VAX floats */
2224 case 'G':
2225 /* VAX md_atof doesn't like "G" for some reason. */
2226 type = 'g';
2227 case 'F':
2228 case 'D':
2229 return vax_md_atof (type, litP, sizeP);
2230
2231 /* IEEE floats */
2232 case 'f':
2233 prec = 2;
2234 break;
2235
2236 case 'd':
2237 prec = 4;
2238 break;
2239
2240 case 'x':
2241 case 'X':
2242 prec = 6;
2243 break;
2244
2245 case 'p':
2246 case 'P':
2247 prec = 6;
2248 break;
2249
2250 default:
2251 *sizeP = 0;
2252 return "Bad call to MD_ATOF()";
2253 }
2254 t = atof_ieee (input_line_pointer, type, words);
2255 if (t)
2256 input_line_pointer = t;
2257 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2258
2259 for (wordP = words + prec - 1; prec--;)
2260 {
2261 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
2262 litP += sizeof (LITTLENUM_TYPE);
2263 }
2264
2265 return 0;
2266 }
2267
2268 void
2269 md_bignum_to_chars (buf, bignum, nchars)
2270 char *buf;
2271 LITTLENUM_TYPE *bignum;
2272 int nchars;
2273 {
2274 while (nchars)
2275 {
2276 LITTLENUM_TYPE work = *bignum++;
2277 int nb = CHARS_PER_LITTLENUM;
2278
2279 do
2280 {
2281 *buf++ = work & ((1 << BITS_PER_CHAR) - 1);
2282 if (--nchars == 0)
2283 return;
2284 work >>= BITS_PER_CHAR;
2285 }
2286 while (--nb);
2287 }
2288 }
2289 \f
2290 CONST char *md_shortopts = "Fm:g";
2291 struct option md_longopts[] = {
2292 #define OPTION_32ADDR (OPTION_MD_BASE)
2293 {"32addr", no_argument, NULL, OPTION_32ADDR},
2294 {NULL, no_argument, NULL, 0}
2295 };
2296 size_t md_longopts_size = sizeof(md_longopts);
2297
2298 int
2299 md_parse_option (c, arg)
2300 int c;
2301 char *arg;
2302 {
2303 switch (c)
2304 {
2305 case 'F':
2306 nofloats = 1;
2307 break;
2308
2309 case OPTION_32ADDR:
2310 addr32 = 1;
2311 break;
2312
2313 case 'g':
2314 /* Ignore `-g' so gcc can provide this option to the Digital
2315 UNIX assembler, which otherwise would throw away info that
2316 mips-tfile needs. */
2317 break;
2318
2319 default:
2320 return 0;
2321 }
2322
2323 return 1;
2324 }
2325
2326 void
2327 md_show_usage (stream)
2328 FILE *stream;
2329 {
2330 fprintf(stream, "\
2331 Alpha options:\n\
2332 -32addr treat addresses as 32-bit values\n\
2333 -F lack floating point instructions support\n\
2334 -m21064 | -m21066 | -m21164\n\
2335 specify variant of Alpha architecture\n");
2336 }
2337 \f
2338 static void
2339 s_proc (is_static)
2340 int is_static;
2341 {
2342 /* XXXX Align to cache linesize XXXXX */
2343 char *name;
2344 char c;
2345 char *p;
2346 symbolS *symbolP;
2347 int temp;
2348
2349 /* Takes ".proc name,nargs" */
2350 name = input_line_pointer;
2351 c = get_symbol_end ();
2352 p = input_line_pointer;
2353 symbolP = symbol_find_or_make (name);
2354 *p = c;
2355 SKIP_WHITESPACE ();
2356 if (*input_line_pointer != ',')
2357 {
2358 *p = 0;
2359 as_warn ("Expected comma after name \"%s\"", name);
2360 *p = c;
2361 temp = 0;
2362 ignore_rest_of_line ();
2363 }
2364 else
2365 {
2366 input_line_pointer++;
2367 temp = get_absolute_expression ();
2368 }
2369 /* symbolP->sy_other = (signed char) temp; */
2370 as_warn ("unhandled: .proc %s,%d", name, temp);
2371 demand_empty_rest_of_line ();
2372 }
2373
2374 static void
2375 s_alpha_set (x)
2376 int x;
2377 {
2378 char *name = input_line_pointer, ch, *s;
2379 int yesno = 1;
2380
2381 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2382 input_line_pointer++;
2383 ch = *input_line_pointer;
2384 *input_line_pointer = '\0';
2385
2386 s = name;
2387 if (s[0] == 'n' && s[1] == 'o')
2388 {
2389 yesno = 0;
2390 s += 2;
2391 }
2392 if (!strcmp ("reorder", s))
2393 /* ignore */ ;
2394 else if (!strcmp ("at", s))
2395 at_ok = yesno;
2396 else if (!strcmp ("macro", s))
2397 macro_ok = yesno;
2398 else if (!strcmp ("move", s))
2399 /* ignore */ ;
2400 else if (!strcmp ("volatile", s))
2401 /* ignore */ ;
2402 else
2403 as_warn ("Tried to .set unrecognized mode `%s'", name);
2404 *input_line_pointer = ch;
2405 demand_empty_rest_of_line ();
2406 }
2407
2408 /* @@ Is this right?? */
2409 long
2410 md_pcrel_from (fixP)
2411 fixS *fixP;
2412 {
2413 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
2414 switch (fixP->fx_r_type)
2415 {
2416 case BFD_RELOC_ALPHA_GPDISP_HI16:
2417 case BFD_RELOC_ALPHA_GPDISP_LO16:
2418 return addr;
2419 default:
2420 return fixP->fx_size + addr;
2421 }
2422 }
2423
2424 /* Handle the .align pseudo-op. This aligns to a power of two. It
2425 also adjusts any current instruction label. We treat this the same
2426 way the MIPS port does: .align 0 turns off auto alignment. */
2427
2428 static void
2429 s_alpha_align (ignore)
2430 int ignore;
2431 {
2432 register int temp;
2433 register long temp_fill;
2434 long max_alignment = 15;
2435
2436 temp = get_absolute_expression ();
2437 if (temp > max_alignment)
2438 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
2439 else if (temp < 0)
2440 {
2441 as_warn ("Alignment negative: 0 assumed.");
2442 temp = 0;
2443 }
2444 if (*input_line_pointer == ',')
2445 {
2446 input_line_pointer++;
2447 temp_fill = get_absolute_expression ();
2448 }
2449 else
2450 temp_fill = 0;
2451 if (temp)
2452 {
2453 auto_align = 1;
2454 alpha_align (temp, (int) temp_fill, insn_label);
2455 }
2456 else
2457 {
2458 auto_align = 0;
2459 }
2460
2461 demand_empty_rest_of_line ();
2462 }
2463
2464 static void
2465 alpha_align (n, fill, label)
2466 int n;
2467 int fill;
2468 symbolS *label;
2469 {
2470 if (fill == 0
2471 && (now_seg == text_section
2472 || !strcmp (now_seg->name, ".init")
2473 || !strcmp (now_seg->name, ".fini"))
2474 && n > 2)
2475 {
2476 static const unsigned char nop_pattern[] = { 0x1f, 0x04, 0xff, 0x47 };
2477 /* First, make sure we're on a four-byte boundary, in case
2478 someone has been putting .byte values into the text section.
2479 The DEC assembler silently fills with unaligned no-op
2480 instructions. This will zero-fill, then nop-fill with proper
2481 alignment. */
2482 frag_align (2, fill);
2483 frag_align_pattern (n, nop_pattern, sizeof (nop_pattern));
2484 }
2485 else
2486 frag_align (n, fill);
2487
2488 if (label != NULL)
2489 {
2490 assert (S_GET_SEGMENT (label) == now_seg);
2491 label->sy_frag = frag_now;
2492 S_SET_VALUE (label, (valueT) frag_now_fix ());
2493 }
2494 }
2495
2496 /* This function is called just before the generic pseudo-ops output
2497 something. It just clears insn_label. */
2498
2499 void
2500 alpha_flush_pending_output ()
2501 {
2502 insn_label = NULL;
2503 }
2504
2505 /* Handle data allocation pseudo-ops. This is like the generic
2506 version, but it makes sure the current label, if any, is correctly
2507 aligned. */
2508
2509 static void
2510 s_alpha_cons (log_size)
2511 int log_size;
2512 {
2513 if (log_size > 0 && auto_align)
2514 alpha_align (log_size, 0, insn_label);
2515 insn_label = NULL;
2516 cons (1 << log_size);
2517 }
2518
2519 /* Handle floating point allocation pseudo-ops. This is like the
2520 generic vresion, but it makes sure the current label, if any, is
2521 correctly aligned. */
2522
2523 static void
2524 s_alpha_float_cons (type)
2525 int type;
2526 {
2527 if (auto_align)
2528 {
2529 int log_size;
2530
2531 switch (type)
2532 {
2533 default:
2534 case 'f':
2535 case 'F':
2536 log_size = 2;
2537 break;
2538
2539 case 'd':
2540 case 'D':
2541 case 'G':
2542 log_size = 3;
2543 break;
2544
2545 case 'x':
2546 case 'X':
2547 case 'p':
2548 case 'P':
2549 log_size = 4;
2550 break;
2551 }
2552
2553 alpha_align (log_size, 0, insn_label);
2554 }
2555
2556 insn_label = NULL;
2557 float_cons (type);
2558 }
2559
2560 /* This function is called whenever a label is defined. It is used to
2561 adjust the label when an automatic alignment occurs. */
2562
2563 void
2564 alpha_define_label (sym)
2565 symbolS *sym;
2566 {
2567 insn_label = sym;
2568 }
2569
2570 int
2571 md_apply_fix (fixP, valueP)
2572 fixS *fixP;
2573 valueT *valueP;
2574 {
2575 valueT value;
2576 int size;
2577 valueT addend;
2578 char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
2579
2580 value = *valueP;
2581
2582 switch (fixP->fx_r_type)
2583 {
2584 /* The GPDISP relocations are processed internally with a symbol
2585 referring to the current function; we need to drop in a value
2586 which, when added to the address of the start of the function,
2587 gives the desired GP. */
2588 case BFD_RELOC_ALPHA_GPDISP_HI16:
2589 case BFD_RELOC_ALPHA_GPDISP_LO16:
2590 addend = value;
2591 if (fixP->fx_r_type == BFD_RELOC_ALPHA_GPDISP_HI16)
2592 {
2593 assert (fixP->fx_next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
2594 #ifdef DEBUG1
2595 printf ("hi16: ");
2596 fprintf_vma (stdout, addend);
2597 printf ("\n");
2598 #endif
2599 if (addend & 0x8000)
2600 addend += 0x10000;
2601 addend >>= 16;
2602 fixP->fx_offset = 4; /* @@ Compute this using fx_next. */
2603 }
2604 else
2605 {
2606 #ifdef DEBUG1
2607 printf ("lo16: ");
2608 fprintf_vma (stdout, addend);
2609 printf ("\n");
2610 #endif
2611 addend &= 0xffff;
2612 fixP->fx_offset = 0;
2613 }
2614 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
2615 addend, 2);
2616 fixP->fx_addsy = section_symbol (absolute_section);
2617 fixP->fx_offset += fixP->fx_frag->fr_address + fixP->fx_where;
2618 break;
2619
2620 case BFD_RELOC_8:
2621 /* Write 8 bits, shifted left 13 bit positions. */
2622 value &= 0xff;
2623 p++;
2624 *p &= 0x1f;
2625 *p |= (value << 5) & 0xe0;
2626 value >>= 3;
2627 p++;
2628 *p &= 0xe0;
2629 *p |= value;
2630 value >>= 5;
2631 fixP->fx_done = 1;
2632 if (value != 0)
2633 as_bad_where (fixP->fx_file, fixP->fx_line,
2634 "overflow in type-%d reloc", (int) fixP->fx_r_type);
2635 return 3;
2636
2637 case BFD_RELOC_32:
2638 size = 4;
2639 goto do_it;
2640 case BFD_RELOC_64:
2641 size = 8;
2642 goto do_it;
2643 case BFD_RELOC_16:
2644 /* Don't want overflow checking. */
2645 size = 2;
2646 do_it:
2647 if (fixP->fx_pcrel == 0
2648 && fixP->fx_addsy == 0)
2649 {
2650 md_number_to_chars (p, value, size);
2651 /* @@ Overflow checks?? */
2652 goto done;
2653 }
2654 break;
2655
2656 case BFD_RELOC_26:
2657 if (fixP->fx_addsy != 0
2658 && fixP->fx_addsy->bsym->section != absolute_section)
2659 as_bad_where (fixP->fx_file, fixP->fx_line,
2660 "PALcode instructions require immediate constant function code");
2661 else if (value >> 26 != 0)
2662 as_bad_where (fixP->fx_file, fixP->fx_line,
2663 "overflow in 26-bit PALcode function field");
2664 *p++ = value & 0xff;
2665 value >>= 8;
2666 *p++ = value & 0xff;
2667 value >>= 8;
2668 *p++ = value & 0xff;
2669 value >>= 8;
2670 {
2671 char x = *p;
2672 x &= ~3;
2673 x |= (value & 3);
2674 *p++ = x;
2675 }
2676 goto done;
2677
2678 case BFD_RELOC_14:
2679 if (fixP->fx_addsy != 0
2680 && fixP->fx_addsy->bsym->section != absolute_section)
2681 as_bad_where (fixP->fx_file, fixP->fx_line,
2682 "ret/jsr_coroutine requires constant in displacement field");
2683 else if (value >> 14 != 0)
2684 as_bad_where (fixP->fx_file, fixP->fx_line,
2685 "overflow in 14-bit operand field of ret or jsr_coroutine");
2686 *p++ = value & 0xff;
2687 value >>= 8;
2688 *p = (*p & 0xc0) | (value & 0x3f);
2689 goto done;
2690
2691 case BFD_RELOC_23_PCREL_S2:
2692 /* Write 21 bits only. */
2693 value >>= 2;
2694 *p++ = value & 0xff;
2695 value >>= 8;
2696 *p++ = value & 0xff;
2697 value >>= 8;
2698 *p &= 0xe0;
2699 *p |= (value & 0x1f);
2700 goto done;
2701
2702 case BFD_RELOC_12_PCREL:
2703 *p++ = value & 0xff;
2704 value >>= 8;
2705 *p &= 0xf0;
2706 *p |= (value & 0x0f);
2707 goto done;
2708
2709 case BFD_RELOC_ALPHA_LITERAL:
2710 case BFD_RELOC_ALPHA_LITUSE:
2711 return 2;
2712
2713 case BFD_RELOC_GPREL32:
2714 assert (fixP->fx_subsy == gp);
2715 value = - alpha_gp_value; /* huh? this works... */
2716 fixP->fx_subsy = 0;
2717 md_number_to_chars (p, value, 4);
2718 break;
2719
2720 case BFD_RELOC_ALPHA_HINT:
2721 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
2722 {
2723 size = 2;
2724 goto do_it;
2725 }
2726 return 2;
2727
2728 default:
2729 as_fatal ("unhandled relocation type %s",
2730 bfd_get_reloc_code_name (fixP->fx_r_type));
2731 return 9;
2732 }
2733
2734 if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
2735 {
2736 printf ("type %d reloc done?\n", fixP->fx_r_type);
2737 done:
2738 fixP->fx_done = 1;
2739 return 42;
2740 }
2741
2742 return 0x12345678;
2743 }
2744
2745 void
2746 alpha_frob_ecoff_data ()
2747 {
2748 select_gp_value ();
2749 /* $zero and $f31 are read-only */
2750 alpha_gprmask &= ~1;
2751 alpha_fprmask &= ~1;
2752 }
2753
2754 /* The Alpha has support for some VAX floating point types, as well as for
2755 IEEE floating point. We consider IEEE to be the primary floating point
2756 format, and sneak in the VAX floating point support here. */
2757 #define md_atof vax_md_atof
2758 #include "config/atof-vax.c"
This page took 0.107067 seconds and 4 git commands to generate.