source: trunk/binutils/gas/config/tc-alpha.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 143.9 KB
Line 
1/* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
9
10 This file is part of GAS, the GNU Assembler.
11
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
16
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26
27/*
28 * Mach Operating System
29 * Copyright (c) 1993 Carnegie Mellon University
30 * All Rights Reserved.
31 *
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
37 *
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 *
42 * Carnegie Mellon requests users of this software to return to
43 *
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
48 *
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
51 */
52
53#include "as.h"
54#include "subsegs.h"
55#include "struc-symbol.h"
56#include "ecoff.h"
57
58#include "opcode/alpha.h"
59
60#ifdef OBJ_ELF
61#include "elf/alpha.h"
62#include "dwarf2dbg.h"
63#endif
64
65#include "safe-ctype.h"
66
67
68/* Local types. */
69
70#define TOKENIZE_ERROR -1
71#define TOKENIZE_ERROR_REPORT -2
72
73#define MAX_INSN_FIXUPS 2
74#define MAX_INSN_ARGS 5
75
76struct alpha_fixup
77{
78 expressionS exp;
79 bfd_reloc_code_real_type reloc;
80};
81
82struct alpha_insn
83{
84 unsigned insn;
85 int nfixups;
86 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
87 long sequence;
88};
89
90enum alpha_macro_arg
91 {
92 MACRO_EOA = 1,
93 MACRO_IR,
94 MACRO_PIR,
95 MACRO_OPIR,
96 MACRO_CPIR,
97 MACRO_FPR,
98 MACRO_EXP,
99 };
100
101struct alpha_macro
102{
103 const char *name;
104 void (*emit) PARAMS ((const expressionS *, int, const PTR));
105 const PTR arg;
106 enum alpha_macro_arg argsets[16];
107};
108
109/* Extra expression types. */
110
111#define O_pregister O_md1 /* O_register, in parentheses */
112#define O_cpregister O_md2 /* + a leading comma */
113
114/* The alpha_reloc_op table below depends on the ordering of these. */
115#define O_literal O_md3 /* !literal relocation */
116#define O_lituse_addr O_md4 /* !lituse_addr relocation */
117#define O_lituse_base O_md5 /* !lituse_base relocation */
118#define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
119#define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
120#define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
121#define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
122#define O_gpdisp O_md10 /* !gpdisp relocation */
123#define O_gprelhigh O_md11 /* !gprelhigh relocation */
124#define O_gprellow O_md12 /* !gprellow relocation */
125#define O_gprel O_md13 /* !gprel relocation */
126#define O_samegp O_md14 /* !samegp relocation */
127#define O_tlsgd O_md15 /* !tlsgd relocation */
128#define O_tlsldm O_md16 /* !tlsldm relocation */
129#define O_gotdtprel O_md17 /* !gotdtprel relocation */
130#define O_dtprelhi O_md18 /* !dtprelhi relocation */
131#define O_dtprello O_md19 /* !dtprello relocation */
132#define O_dtprel O_md20 /* !dtprel relocation */
133#define O_gottprel O_md21 /* !gottprel relocation */
134#define O_tprelhi O_md22 /* !tprelhi relocation */
135#define O_tprello O_md23 /* !tprello relocation */
136#define O_tprel O_md24 /* !tprel relocation */
137
138#define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
139#define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
140#define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
141#define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
142#define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
143#define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
144
145#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
146
147/* Macros for extracting the type and number of encoded register tokens. */
148
149#define is_ir_num(x) (((x) & 32) == 0)
150#define is_fpr_num(x) (((x) & 32) != 0)
151#define regno(x) ((x) & 31)
152
153/* Something odd inherited from the old assembler. */
154
155#define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
156#define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
157
158/* Predicates for 16- and 32-bit ranges */
159/* XXX: The non-shift version appears to trigger a compiler bug when
160 cross-assembling from x86 w/ gcc 2.7.2. */
161
162#if 1
163#define range_signed_16(x) \
164 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
165#define range_signed_32(x) \
166 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
167#else
168#define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
169 (offsetT) (x) <= (offsetT) 0x7FFF)
170#define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
171 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
172#endif
173
174/* Macros for sign extending from 16- and 32-bits. */
175/* XXX: The cast macros will work on all the systems that I care about,
176 but really a predicate should be found to use the non-cast forms. */
177
178#if 1
179#define sign_extend_16(x) ((short) (x))
180#define sign_extend_32(x) ((int) (x))
181#else
182#define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
183#define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
184 ^ 0x80000000) - 0x80000000)
185#endif
186
187/* Macros to build tokens. */
188
189#define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
190 (t).X_op = O_register, \
191 (t).X_add_number = (r))
192#define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_pregister, \
194 (t).X_add_number = (r))
195#define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
196 (t).X_op = O_cpregister, \
197 (t).X_add_number = (r))
198#define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
199 (t).X_op = O_register, \
200 (t).X_add_number = (r) + 32)
201#define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
202 (t).X_op = O_symbol, \
203 (t).X_add_symbol = (s), \
204 (t).X_add_number = (a))
205#define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
206 (t).X_op = O_constant, \
207 (t).X_add_number = (n))
208
209
210/* Prototypes for all local functions. */
211
212static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
213static void alpha_adjust_relocs PARAMS ((bfd *, asection *, PTR));
214
215static int tokenize_arguments PARAMS ((char *, expressionS *, int));
216static const struct alpha_opcode *find_opcode_match
217 PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
218static const struct alpha_macro *find_macro_match
219 PARAMS ((const struct alpha_macro *, const expressionS *, int *));
220static unsigned insert_operand
221 PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
222static void assemble_insn
223 PARAMS ((const struct alpha_opcode *, const expressionS *, int,
224 struct alpha_insn *, bfd_reloc_code_real_type));
225static void emit_insn PARAMS ((struct alpha_insn *));
226static void assemble_tokens_to_insn
227 PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
228static void assemble_tokens
229 PARAMS ((const char *, const expressionS *, int, int));
230
231static long load_expression
232 PARAMS ((int, const expressionS *, int *, expressionS *));
233
234static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
235static void emit_division PARAMS ((const expressionS *, int, const PTR));
236static void emit_lda PARAMS ((const expressionS *, int, const PTR));
237static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
238static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
239static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
240static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
241static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
242static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
243static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
244static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
245static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
246static void emit_stX PARAMS ((const expressionS *, int, const PTR));
247static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
248static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
249static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
250
251static void s_alpha_text PARAMS ((int));
252static void s_alpha_data PARAMS ((int));
253#ifndef OBJ_ELF
254static void s_alpha_comm PARAMS ((int));
255static void s_alpha_rdata PARAMS ((int));
256#endif
257#ifdef OBJ_ECOFF
258static void s_alpha_sdata PARAMS ((int));
259#endif
260#ifdef OBJ_ELF
261static void s_alpha_section PARAMS ((int));
262static void s_alpha_ent PARAMS ((int));
263static void s_alpha_end PARAMS ((int));
264static void s_alpha_mask PARAMS ((int));
265static void s_alpha_frame PARAMS ((int));
266static void s_alpha_prologue PARAMS ((int));
267static void s_alpha_file PARAMS ((int));
268static void s_alpha_loc PARAMS ((int));
269static void s_alpha_stab PARAMS ((int));
270static void s_alpha_coff_wrapper PARAMS ((int));
271#endif
272#ifdef OBJ_EVAX
273static void s_alpha_section PARAMS ((int));
274#endif
275static void s_alpha_gprel32 PARAMS ((int));
276static void s_alpha_float_cons PARAMS ((int));
277static void s_alpha_proc PARAMS ((int));
278static void s_alpha_set PARAMS ((int));
279static void s_alpha_base PARAMS ((int));
280static void s_alpha_align PARAMS ((int));
281static void s_alpha_stringer PARAMS ((int));
282static void s_alpha_space PARAMS ((int));
283static void s_alpha_ucons PARAMS ((int));
284static void s_alpha_arch PARAMS ((int));
285
286static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
287#ifndef OBJ_ELF
288static void select_gp_value PARAMS ((void));
289#endif
290static void alpha_align PARAMS ((int, char *, symbolS *, int));
291
292
293/* Generic assembler global variables which must be defined by all
294 targets. */
295
296/* Characters which always start a comment. */
297const char comment_chars[] = "#";
298
299/* Characters which start a comment at the beginning of a line. */
300const char line_comment_chars[] = "#";
301
302/* Characters which may be used to separate multiple commands on a
303 single line. */
304const char line_separator_chars[] = ";";
305
306/* Characters which are used to indicate an exponent in a floating
307 point number. */
308const char EXP_CHARS[] = "eE";
309
310/* Characters which mean that a number is a floating point constant,
311 as in 0d1.0. */
312#if 0
313const char FLT_CHARS[] = "dD";
314#else
315/* XXX: Do all of these really get used on the alpha?? */
316char FLT_CHARS[] = "rRsSfFdDxXpP";
317#endif
318
319#ifdef OBJ_EVAX
320const char *md_shortopts = "Fm:g+1h:HG:";
321#else
322const char *md_shortopts = "Fm:gG:";
323#endif
324
325struct option md_longopts[] =
326 {
327#define OPTION_32ADDR (OPTION_MD_BASE)
328 { "32addr", no_argument, NULL, OPTION_32ADDR },
329#define OPTION_RELAX (OPTION_32ADDR + 1)
330 { "relax", no_argument, NULL, OPTION_RELAX },
331#ifdef OBJ_ELF
332#define OPTION_MDEBUG (OPTION_RELAX + 1)
333#define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
334 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
335 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
336#endif
337 { NULL, no_argument, NULL, 0 }
338 };
339
340size_t md_longopts_size = sizeof (md_longopts);
341
342
343#ifdef OBJ_EVAX
344#define AXP_REG_R0 0
345#define AXP_REG_R16 16
346#define AXP_REG_R17 17
347#undef AXP_REG_T9
348#define AXP_REG_T9 22
349#undef AXP_REG_T10
350#define AXP_REG_T10 23
351#undef AXP_REG_T11
352#define AXP_REG_T11 24
353#undef AXP_REG_T12
354#define AXP_REG_T12 25
355#define AXP_REG_AI 25
356#undef AXP_REG_FP
357#define AXP_REG_FP 29
358
359#undef AXP_REG_GP
360#define AXP_REG_GP AXP_REG_PV
361#endif /* OBJ_EVAX */
362
363/* The cpu for which we are generating code. */
364static unsigned alpha_target = AXP_OPCODE_BASE;
365static const char *alpha_target_name = "<all>";
366
367/* The hash table of instruction opcodes. */
368static struct hash_control *alpha_opcode_hash;
369
370/* The hash table of macro opcodes. */
371static struct hash_control *alpha_macro_hash;
372
373#ifdef OBJ_ECOFF
374/* The $gp relocation symbol. */
375static symbolS *alpha_gp_symbol;
376
377/* XXX: what is this, and why is it exported? */
378valueT alpha_gp_value;
379#endif
380
381/* The current $gp register. */
382static int alpha_gp_register = AXP_REG_GP;
383
384/* A table of the register symbols. */
385static symbolS *alpha_register_table[64];
386
387/* Constant sections, or sections of constants. */
388#ifdef OBJ_ECOFF
389static segT alpha_lita_section;
390#endif
391#ifdef OBJ_EVAX
392static segT alpha_link_section;
393static segT alpha_ctors_section;
394static segT alpha_dtors_section;
395#endif
396static segT alpha_lit8_section;
397
398/* Symbols referring to said sections. */
399#ifdef OBJ_ECOFF
400static symbolS *alpha_lita_symbol;
401#endif
402#ifdef OBJ_EVAX
403static symbolS *alpha_link_symbol;
404static symbolS *alpha_ctors_symbol;
405static symbolS *alpha_dtors_symbol;
406#endif
407static symbolS *alpha_lit8_symbol;
408
409/* Literal for .litX+0x8000 within .lita. */
410#ifdef OBJ_ECOFF
411static offsetT alpha_lit8_literal;
412#endif
413
414#ifdef OBJ_ELF
415/* The active .ent symbol. */
416static symbolS *alpha_cur_ent_sym;
417#endif
418
419/* Is the assembler not allowed to use $at? */
420static int alpha_noat_on = 0;
421
422/* Are macros enabled? */
423static int alpha_macros_on = 1;
424
425/* Are floats disabled? */
426static int alpha_nofloats_on = 0;
427
428/* Are addresses 32 bit? */
429static int alpha_addr32_on = 0;
430
431/* Symbol labelling the current insn. When the Alpha gas sees
432 foo:
433 .quad 0
434 and the section happens to not be on an eight byte boundary, it
435 will align both the symbol and the .quad to an eight byte boundary. */
436static symbolS *alpha_insn_label;
437
438/* Whether we should automatically align data generation pseudo-ops.
439 .align 0 will turn this off. */
440static int alpha_auto_align_on = 1;
441
442/* The known current alignment of the current section. */
443static int alpha_current_align;
444
445/* These are exported to ECOFF code. */
446unsigned long alpha_gprmask, alpha_fprmask;
447
448/* Whether the debugging option was seen. */
449static int alpha_debug;
450
451#ifdef OBJ_ELF
452/* Whether we are emitting an mdebug section. */
453int alpha_flag_mdebug = -1;
454#endif
455
456/* Don't fully resolve relocations, allowing code movement in the linker. */
457static int alpha_flag_relax;
458
459/* What value to give to bfd_set_gp_size. */
460static int g_switch_value = 8;
461
462#ifdef OBJ_EVAX
463/* Collect information about current procedure here. */
464static struct {
465 symbolS *symbol; /* proc pdesc symbol */
466 int pdsckind;
467 int framereg; /* register for frame pointer */
468 int framesize; /* size of frame */
469 int rsa_offset;
470 int ra_save;
471 int fp_save;
472 long imask;
473 long fmask;
474 int type;
475 int prologue;
476} alpha_evax_proc;
477
478static int alpha_flag_hash_long_names = 0; /* -+ */
479static int alpha_flag_show_after_trunc = 0; /* -H */
480
481/* If the -+ switch is given, then a hash is appended to any name that is
482 longer than 64 characters, else longer symbol names are truncated. */
483
484#endif
485
486
487#ifdef RELOC_OP_P
488/* A table to map the spelling of a relocation operand into an appropriate
489 bfd_reloc_code_real_type type. The table is assumed to be ordered such
490 that op-O_literal indexes into it. */
491
492#define ALPHA_RELOC_TABLE(op) \
493(&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
494 ? (abort (), 0) \
495 : (int) (op) - (int) O_literal) ])
496
497#define DEF(NAME, RELOC, REQ, ALLOW) \
498 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
499
500static const struct alpha_reloc_op_tag
501{
502 const char *name; /* string to lookup */
503 size_t length; /* size of the string */
504 operatorT op; /* which operator to use */
505 bfd_reloc_code_real_type reloc; /* relocation before frob */
506 unsigned int require_seq : 1; /* require a sequence number */
507 unsigned int allow_seq : 1; /* allow a sequence number */
508}
509alpha_reloc_op[] =
510{
511 DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
512 DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
513 DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
514 DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
515 DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
516 DEF(lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
517 DEF(lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
518 DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
519 DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
520 DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
521 DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
522 DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
523 DEF(tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
524 DEF(tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
525 DEF(gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
526 DEF(dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
527 DEF(dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
528 DEF(dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
529 DEF(gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
530 DEF(tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
531 DEF(tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
532 DEF(tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
533};
534
535#undef DEF
536
537static const int alpha_num_reloc_op
538 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
539#endif /* RELOC_OP_P */
540
541/* Maximum # digits needed to hold the largest sequence # */
542#define ALPHA_RELOC_DIGITS 25
543
544/* Structure to hold explict sequence information. */
545struct alpha_reloc_tag
546{
547 fixS *master; /* the literal reloc */
548 fixS *slaves; /* head of linked list of lituses */
549 segT segment; /* segment relocs are in or undefined_section*/
550 long sequence; /* sequence # */
551 unsigned n_master; /* # of literals */
552 unsigned n_slaves; /* # of lituses */
553 unsigned saw_tlsgd : 1; /* true if ... */
554 unsigned saw_tlsldm : 1;
555 unsigned saw_lu_tlsgd : 1;
556 unsigned saw_lu_tlsldm : 1;
557 unsigned multi_section_p : 1; /* true if more than one section was used */
558 char string[1]; /* printable form of sequence to hash with */
559};
560
561/* Hash table to link up literals with the appropriate lituse */
562static struct hash_control *alpha_literal_hash;
563
564/* Sequence numbers for internal use by macros. */
565static long next_sequence_num = -1;
566
567
568/* A table of CPU names and opcode sets. */
569
570static const struct cpu_type
571{
572 const char *name;
573 unsigned flags;
574}
575cpu_types[] =
576{
577 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
578 This supports usage under DU 4.0b that does ".arch ev4", and
579 usage in MILO that does -m21064. Probably something more
580 specific like -m21064-pal should be used, but oh well. */
581
582 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
583 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
584 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
585 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
586 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
587 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
588 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
589 |AXP_OPCODE_MAX) },
590 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
591 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
592 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
593 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
594 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
595 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
596
597 { "ev4", AXP_OPCODE_BASE },
598 { "ev45", AXP_OPCODE_BASE },
599 { "lca45", AXP_OPCODE_BASE },
600 { "ev5", AXP_OPCODE_BASE },
601 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
602 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
603 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
604 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
605 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
606
607 { "all", AXP_OPCODE_BASE },
608 { 0, 0 }
609};
610
611/* The macro table */
612
613static const struct alpha_macro alpha_macros[] =
614{
615/* Load/Store macros */
616 { "lda", emit_lda, NULL,
617 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
618 { "ldah", emit_ldah, NULL,
619 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
620
621 { "ldl", emit_ir_load, "ldl",
622 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
623 { "ldl_l", emit_ir_load, "ldl_l",
624 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
625 { "ldq", emit_ir_load, "ldq",
626 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
627 { "ldq_l", emit_ir_load, "ldq_l",
628 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
629 { "ldq_u", emit_ir_load, "ldq_u",
630 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
631 { "ldf", emit_loadstore, "ldf",
632 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
633 { "ldg", emit_loadstore, "ldg",
634 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
635 { "lds", emit_loadstore, "lds",
636 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
637 { "ldt", emit_loadstore, "ldt",
638 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
639
640 { "ldb", emit_ldX, (PTR) 0,
641 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
642 { "ldbu", emit_ldXu, (PTR) 0,
643 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
644 { "ldw", emit_ldX, (PTR) 1,
645 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
646 { "ldwu", emit_ldXu, (PTR) 1,
647 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
648
649 { "uldw", emit_uldX, (PTR) 1,
650 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
651 { "uldwu", emit_uldXu, (PTR) 1,
652 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
653 { "uldl", emit_uldX, (PTR) 2,
654 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
655 { "uldlu", emit_uldXu, (PTR) 2,
656 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
657 { "uldq", emit_uldXu, (PTR) 3,
658 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
659
660 { "ldgp", emit_ldgp, NULL,
661 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
662
663 { "ldi", emit_lda, NULL,
664 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
665 { "ldil", emit_ldil, NULL,
666 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
667 { "ldiq", emit_lda, NULL,
668 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
669#if 0
670 { "ldif" emit_ldiq, NULL,
671 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
672 { "ldid" emit_ldiq, NULL,
673 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
674 { "ldig" emit_ldiq, NULL,
675 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
676 { "ldis" emit_ldiq, NULL,
677 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
678 { "ldit" emit_ldiq, NULL,
679 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
680#endif
681
682 { "stl", emit_loadstore, "stl",
683 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
684 { "stl_c", emit_loadstore, "stl_c",
685 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
686 { "stq", emit_loadstore, "stq",
687 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
688 { "stq_c", emit_loadstore, "stq_c",
689 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
690 { "stq_u", emit_loadstore, "stq_u",
691 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
692 { "stf", emit_loadstore, "stf",
693 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
694 { "stg", emit_loadstore, "stg",
695 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
696 { "sts", emit_loadstore, "sts",
697 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
698 { "stt", emit_loadstore, "stt",
699 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
700
701 { "stb", emit_stX, (PTR) 0,
702 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
703 { "stw", emit_stX, (PTR) 1,
704 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
705 { "ustw", emit_ustX, (PTR) 1,
706 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
707 { "ustl", emit_ustX, (PTR) 2,
708 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
709 { "ustq", emit_ustX, (PTR) 3,
710 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
711
712/* Arithmetic macros */
713#if 0
714 { "absl" emit_absl, 1, { IR } },
715 { "absl" emit_absl, 2, { IR, IR } },
716 { "absl" emit_absl, 2, { EXP, IR } },
717 { "absq" emit_absq, 1, { IR } },
718 { "absq" emit_absq, 2, { IR, IR } },
719 { "absq" emit_absq, 2, { EXP, IR } },
720#endif
721
722 { "sextb", emit_sextX, (PTR) 0,
723 { MACRO_IR, MACRO_IR, MACRO_EOA,
724 MACRO_IR, MACRO_EOA,
725 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
726 { "sextw", emit_sextX, (PTR) 1,
727 { MACRO_IR, MACRO_IR, MACRO_EOA,
728 MACRO_IR, MACRO_EOA,
729 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
730
731 { "divl", emit_division, "__divl",
732 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
733 MACRO_IR, MACRO_IR, MACRO_EOA,
734 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
735 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
736 { "divlu", emit_division, "__divlu",
737 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
738 MACRO_IR, MACRO_IR, MACRO_EOA,
739 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
740 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
741 { "divq", emit_division, "__divq",
742 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
743 MACRO_IR, MACRO_IR, MACRO_EOA,
744 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
745 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
746 { "divqu", emit_division, "__divqu",
747 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
748 MACRO_IR, MACRO_IR, MACRO_EOA,
749 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
750 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
751 { "reml", emit_division, "__reml",
752 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
753 MACRO_IR, MACRO_IR, MACRO_EOA,
754 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
755 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
756 { "remlu", emit_division, "__remlu",
757 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
758 MACRO_IR, MACRO_IR, MACRO_EOA,
759 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
760 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
761 { "remq", emit_division, "__remq",
762 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
763 MACRO_IR, MACRO_IR, MACRO_EOA,
764 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
765 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
766 { "remqu", emit_division, "__remqu",
767 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
768 MACRO_IR, MACRO_IR, MACRO_EOA,
769 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
770 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
771
772 { "jsr", emit_jsrjmp, "jsr",
773 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
774 MACRO_PIR, MACRO_EOA,
775 MACRO_IR, MACRO_EXP, MACRO_EOA,
776 MACRO_EXP, MACRO_EOA } },
777 { "jmp", emit_jsrjmp, "jmp",
778 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
779 MACRO_PIR, MACRO_EOA,
780 MACRO_IR, MACRO_EXP, MACRO_EOA,
781 MACRO_EXP, MACRO_EOA } },
782 { "ret", emit_retjcr, "ret",
783 { MACRO_IR, MACRO_EXP, MACRO_EOA,
784 MACRO_IR, MACRO_EOA,
785 MACRO_PIR, MACRO_EXP, MACRO_EOA,
786 MACRO_PIR, MACRO_EOA,
787 MACRO_EXP, MACRO_EOA,
788 MACRO_EOA } },
789 { "jcr", emit_retjcr, "jcr",
790 { MACRO_IR, MACRO_EXP, MACRO_EOA,
791 MACRO_IR, MACRO_EOA,
792 MACRO_PIR, MACRO_EXP, MACRO_EOA,
793 MACRO_PIR, MACRO_EOA,
794 MACRO_EXP, MACRO_EOA,
795 MACRO_EOA } },
796 { "jsr_coroutine", emit_retjcr, "jcr",
797 { MACRO_IR, MACRO_EXP, MACRO_EOA,
798 MACRO_IR, MACRO_EOA,
799 MACRO_PIR, MACRO_EXP, MACRO_EOA,
800 MACRO_PIR, MACRO_EOA,
801 MACRO_EXP, MACRO_EOA,
802 MACRO_EOA } },
803};
804
805static const unsigned int alpha_num_macros
806 = sizeof (alpha_macros) / sizeof (*alpha_macros);
807
808
809/* Public interface functions */
810
811/* This function is called once, at assembler startup time. It sets
812 up all the tables, etc. that the MD part of the assembler will
813 need, that can be determined before arguments are parsed. */
814
815void
816md_begin ()
817{
818 unsigned int i;
819
820 /* Verify that X_op field is wide enough. */
821 {
822 expressionS e;
823 e.X_op = O_max;
824 assert (e.X_op == O_max);
825 }
826
827 /* Create the opcode hash table. */
828 alpha_opcode_hash = hash_new ();
829 for (i = 0; i < alpha_num_opcodes;)
830 {
831 const char *name, *retval, *slash;
832
833 name = alpha_opcodes[i].name;
834 retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
835 if (retval)
836 as_fatal (_("internal error: can't hash opcode `%s': %s"),
837 name, retval);
838
839 /* Some opcodes include modifiers of various sorts with a "/mod"
840 syntax, like the architecture manual suggests. However, for
841 use with gcc at least, we also need access to those same opcodes
842 without the "/". */
843
844 if ((slash = strchr (name, '/')) != NULL)
845 {
846 char *p = xmalloc (strlen (name));
847 memcpy (p, name, slash - name);
848 strcpy (p + (slash - name), slash + 1);
849
850 (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
851 /* Ignore failures -- the opcode table does duplicate some
852 variants in different forms, like "hw_stq" and "hw_st/q". */
853 }
854
855 while (++i < alpha_num_opcodes
856 && (alpha_opcodes[i].name == name
857 || !strcmp (alpha_opcodes[i].name, name)))
858 continue;
859 }
860
861 /* Create the macro hash table. */
862 alpha_macro_hash = hash_new ();
863 for (i = 0; i < alpha_num_macros;)
864 {
865 const char *name, *retval;
866
867 name = alpha_macros[i].name;
868 retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
869 if (retval)
870 as_fatal (_("internal error: can't hash macro `%s': %s"),
871 name, retval);
872
873 while (++i < alpha_num_macros
874 && (alpha_macros[i].name == name
875 || !strcmp (alpha_macros[i].name, name)))
876 continue;
877 }
878
879 /* Construct symbols for each of the registers. */
880 for (i = 0; i < 32; ++i)
881 {
882 char name[4];
883
884 sprintf (name, "$%d", i);
885 alpha_register_table[i] = symbol_create (name, reg_section, i,
886 &zero_address_frag);
887 }
888 for (; i < 64; ++i)
889 {
890 char name[5];
891
892 sprintf (name, "$f%d", i - 32);
893 alpha_register_table[i] = symbol_create (name, reg_section, i,
894 &zero_address_frag);
895 }
896
897 /* Create the special symbols and sections we'll be using. */
898
899 /* So .sbss will get used for tiny objects. */
900 bfd_set_gp_size (stdoutput, g_switch_value);
901
902#ifdef OBJ_ECOFF
903 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
904
905 /* For handling the GP, create a symbol that won't be output in the
906 symbol table. We'll edit it out of relocs later. */
907 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
908 &zero_address_frag);
909#endif
910
911#ifdef OBJ_EVAX
912 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
913#endif
914
915#ifdef OBJ_ELF
916 if (ECOFF_DEBUGGING)
917 {
918 segT sec = subseg_new (".mdebug", (subsegT) 0);
919 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
920 bfd_set_section_alignment (stdoutput, sec, 3);
921 }
922#endif /* OBJ_ELF */
923
924 /* Create literal lookup hash table. */
925 alpha_literal_hash = hash_new ();
926
927 subseg_set (text_section, 0);
928}
929
930/* The public interface to the instruction assembler. */
931
932void
933md_assemble (str)
934 char *str;
935{
936 char opname[32]; /* Current maximum is 13. */
937 expressionS tok[MAX_INSN_ARGS];
938 int ntok, trunclen;
939 size_t opnamelen;
940
941 /* Split off the opcode. */
942 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
943 trunclen = (opnamelen < sizeof (opname) - 1
944 ? opnamelen
945 : sizeof (opname) - 1);
946 memcpy (opname, str, trunclen);
947 opname[trunclen] = '\0';
948
949 /* Tokenize the rest of the line. */
950 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
951 {
952 if (ntok != TOKENIZE_ERROR_REPORT)
953 as_bad (_("syntax error"));
954
955 return;
956 }
957
958 /* Finish it off. */
959 assemble_tokens (opname, tok, ntok, alpha_macros_on);
960}
961
962/* Round up a section's size to the appropriate boundary. */
963
964valueT
965md_section_align (seg, size)
966 segT seg;
967 valueT size;
968{
969 int align = bfd_get_section_alignment (stdoutput, seg);
970 valueT mask = ((valueT) 1 << align) - 1;
971
972 return (size + mask) & ~mask;
973}
974
975/* Turn a string in input_line_pointer into a floating point constant
976 of type TYPE, and store the appropriate bytes in *LITP. The number
977 of LITTLENUMS emitted is stored in *SIZEP. An error message is
978 returned, or NULL on OK. */
979
980/* Equal to MAX_PRECISION in atof-ieee.c. */
981#define MAX_LITTLENUMS 6
982
983extern char *vax_md_atof PARAMS ((int, char *, int *));
984
985char *
986md_atof (type, litP, sizeP)
987 char type;
988 char *litP;
989 int *sizeP;
990{
991 int prec;
992 LITTLENUM_TYPE words[MAX_LITTLENUMS];
993 LITTLENUM_TYPE *wordP;
994 char *t;
995
996 switch (type)
997 {
998 /* VAX floats */
999 case 'G':
1000 /* VAX md_atof doesn't like "G" for some reason. */
1001 type = 'g';
1002 case 'F':
1003 case 'D':
1004 return vax_md_atof (type, litP, sizeP);
1005
1006 /* IEEE floats */
1007 case 'f':
1008 prec = 2;
1009 break;
1010
1011 case 'd':
1012 prec = 4;
1013 break;
1014
1015 case 'x':
1016 case 'X':
1017 prec = 6;
1018 break;
1019
1020 case 'p':
1021 case 'P':
1022 prec = 6;
1023 break;
1024
1025 default:
1026 *sizeP = 0;
1027 return _("Bad call to MD_ATOF()");
1028 }
1029 t = atof_ieee (input_line_pointer, type, words);
1030 if (t)
1031 input_line_pointer = t;
1032 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1033
1034 for (wordP = words + prec - 1; prec--;)
1035 {
1036 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
1037 litP += sizeof (LITTLENUM_TYPE);
1038 }
1039
1040 return 0;
1041}
1042
1043/* Take care of the target-specific command-line options. */
1044
1045int
1046md_parse_option (c, arg)
1047 int c;
1048 char *arg;
1049{
1050 switch (c)
1051 {
1052 case 'F':
1053 alpha_nofloats_on = 1;
1054 break;
1055
1056 case OPTION_32ADDR:
1057 alpha_addr32_on = 1;
1058 break;
1059
1060 case 'g':
1061 alpha_debug = 1;
1062 break;
1063
1064 case 'G':
1065 g_switch_value = atoi (arg);
1066 break;
1067
1068 case 'm':
1069 {
1070 const struct cpu_type *p;
1071 for (p = cpu_types; p->name; ++p)
1072 if (strcmp (arg, p->name) == 0)
1073 {
1074 alpha_target_name = p->name, alpha_target = p->flags;
1075 goto found;
1076 }
1077 as_warn (_("Unknown CPU identifier `%s'"), arg);
1078 found:;
1079 }
1080 break;
1081
1082#ifdef OBJ_EVAX
1083 case '+': /* For g++. Hash any name > 63 chars long. */
1084 alpha_flag_hash_long_names = 1;
1085 break;
1086
1087 case 'H': /* Show new symbol after hash truncation */
1088 alpha_flag_show_after_trunc = 1;
1089 break;
1090
1091 case 'h': /* for gnu-c/vax compatibility. */
1092 break;
1093#endif
1094
1095 case OPTION_RELAX:
1096 alpha_flag_relax = 1;
1097 break;
1098
1099#ifdef OBJ_ELF
1100 case OPTION_MDEBUG:
1101 alpha_flag_mdebug = 1;
1102 break;
1103 case OPTION_NO_MDEBUG:
1104 alpha_flag_mdebug = 0;
1105 break;
1106#endif
1107
1108 default:
1109 return 0;
1110 }
1111
1112 return 1;
1113}
1114
1115/* Print a description of the command-line options that we accept. */
1116
1117void
1118md_show_usage (stream)
1119 FILE *stream;
1120{
1121 fputs (_("\
1122Alpha options:\n\
1123-32addr treat addresses as 32-bit values\n\
1124-F lack floating point instructions support\n\
1125-mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
1126 specify variant of Alpha architecture\n\
1127-m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
1128 these variants include PALcode opcodes\n"),
1129 stream);
1130#ifdef OBJ_EVAX
1131 fputs (_("\
1132VMS options:\n\
1133-+ hash encode (don't truncate) names longer than 64 characters\n\
1134-H show new symbol after hash truncation\n"),
1135 stream);
1136#endif
1137}
1138
1139/* Decide from what point a pc-relative relocation is relative to,
1140 relative to the pc-relative fixup. Er, relatively speaking. */
1141
1142long
1143md_pcrel_from (fixP)
1144 fixS *fixP;
1145{
1146 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1147 switch (fixP->fx_r_type)
1148 {
1149 case BFD_RELOC_23_PCREL_S2:
1150 case BFD_RELOC_ALPHA_HINT:
1151 case BFD_RELOC_ALPHA_BRSGP:
1152 return addr + 4;
1153 default:
1154 return addr;
1155 }
1156}
1157
1158/* Attempt to simplify or even eliminate a fixup. The return value is
1159 ignored; perhaps it was once meaningful, but now it is historical.
1160 To indicate that a fixup has been eliminated, set fixP->fx_done.
1161
1162 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1163 internally into the GPDISP reloc used externally. We had to do
1164 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1165 the distance to the "lda" instruction for setting the addend to
1166 GPDISP. */
1167
1168void
1169md_apply_fix3 (fixP, valP, seg)
1170 fixS *fixP;
1171 valueT * valP;
1172 segT seg;
1173{
1174 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1175 valueT value = * valP;
1176 unsigned image, size;
1177
1178 switch (fixP->fx_r_type)
1179 {
1180 /* The GPDISP relocations are processed internally with a symbol
1181 referring to the current function's section; we need to drop
1182 in a value which, when added to the address of the start of
1183 the function, gives the desired GP. */
1184 case BFD_RELOC_ALPHA_GPDISP_HI16:
1185 {
1186 fixS *next = fixP->fx_next;
1187
1188 /* With user-specified !gpdisp relocations, we can be missing
1189 the matching LO16 reloc. We will have already issued an
1190 error message. */
1191 if (next)
1192 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1193 - fixP->fx_frag->fr_address - fixP->fx_where);
1194
1195 value = (value - sign_extend_16 (value)) >> 16;
1196 }
1197#ifdef OBJ_ELF
1198 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1199#endif
1200 goto do_reloc_gp;
1201
1202 case BFD_RELOC_ALPHA_GPDISP_LO16:
1203 value = sign_extend_16 (value);
1204 fixP->fx_offset = 0;
1205#ifdef OBJ_ELF
1206 fixP->fx_done = 1;
1207#endif
1208
1209 do_reloc_gp:
1210 fixP->fx_addsy = section_symbol (seg);
1211 md_number_to_chars (fixpos, value, 2);
1212 break;
1213
1214 case BFD_RELOC_16:
1215 if (fixP->fx_pcrel)
1216 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1217 size = 2;
1218 goto do_reloc_xx;
1219 case BFD_RELOC_32:
1220 if (fixP->fx_pcrel)
1221 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1222 size = 4;
1223 goto do_reloc_xx;
1224 case BFD_RELOC_64:
1225 if (fixP->fx_pcrel)
1226 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1227 size = 8;
1228 do_reloc_xx:
1229 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1230 {
1231 md_number_to_chars (fixpos, value, size);
1232 goto done;
1233 }
1234 return;
1235
1236#ifdef OBJ_ECOFF
1237 case BFD_RELOC_GPREL32:
1238 assert (fixP->fx_subsy == alpha_gp_symbol);
1239 fixP->fx_subsy = 0;
1240 /* FIXME: inherited this obliviousness of `value' -- why? */
1241 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1242 break;
1243#else
1244 case BFD_RELOC_GPREL32:
1245#endif
1246 case BFD_RELOC_GPREL16:
1247 case BFD_RELOC_ALPHA_GPREL_HI16:
1248 case BFD_RELOC_ALPHA_GPREL_LO16:
1249 return;
1250
1251 case BFD_RELOC_23_PCREL_S2:
1252 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1253 {
1254 image = bfd_getl32 (fixpos);
1255 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1256 goto write_done;
1257 }
1258 return;
1259
1260 case BFD_RELOC_ALPHA_HINT:
1261 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1262 {
1263 image = bfd_getl32 (fixpos);
1264 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1265 goto write_done;
1266 }
1267 return;
1268
1269#ifdef OBJ_ELF
1270 case BFD_RELOC_ALPHA_BRSGP:
1271 return;
1272
1273 case BFD_RELOC_ALPHA_TLSGD:
1274 case BFD_RELOC_ALPHA_TLSLDM:
1275 case BFD_RELOC_ALPHA_GOTDTPREL16:
1276 case BFD_RELOC_ALPHA_DTPREL_HI16:
1277 case BFD_RELOC_ALPHA_DTPREL_LO16:
1278 case BFD_RELOC_ALPHA_DTPREL16:
1279 case BFD_RELOC_ALPHA_GOTTPREL16:
1280 case BFD_RELOC_ALPHA_TPREL_HI16:
1281 case BFD_RELOC_ALPHA_TPREL_LO16:
1282 case BFD_RELOC_ALPHA_TPREL16:
1283 if (fixP->fx_addsy)
1284 S_SET_THREAD_LOCAL (fixP->fx_addsy);
1285 return;
1286#endif
1287
1288#ifdef OBJ_ECOFF
1289 case BFD_RELOC_ALPHA_LITERAL:
1290 md_number_to_chars (fixpos, value, 2);
1291 return;
1292#endif
1293 case BFD_RELOC_ALPHA_ELF_LITERAL:
1294 case BFD_RELOC_ALPHA_LITUSE:
1295 case BFD_RELOC_ALPHA_LINKAGE:
1296 case BFD_RELOC_ALPHA_CODEADDR:
1297 return;
1298
1299 case BFD_RELOC_VTABLE_INHERIT:
1300 case BFD_RELOC_VTABLE_ENTRY:
1301 return;
1302
1303 default:
1304 {
1305 const struct alpha_operand *operand;
1306
1307 if ((int) fixP->fx_r_type >= 0)
1308 as_fatal (_("unhandled relocation type %s"),
1309 bfd_get_reloc_code_name (fixP->fx_r_type));
1310
1311 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1312 operand = &alpha_operands[-(int) fixP->fx_r_type];
1313
1314 /* The rest of these fixups only exist internally during symbol
1315 resolution and have no representation in the object file.
1316 Therefore they must be completely resolved as constants. */
1317
1318 if (fixP->fx_addsy != 0
1319 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1320 as_bad_where (fixP->fx_file, fixP->fx_line,
1321 _("non-absolute expression in constant field"));
1322
1323 image = bfd_getl32 (fixpos);
1324 image = insert_operand (image, operand, (offsetT) value,
1325 fixP->fx_file, fixP->fx_line);
1326 }
1327 goto write_done;
1328 }
1329
1330 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1331 return;
1332 else
1333 {
1334 as_warn_where (fixP->fx_file, fixP->fx_line,
1335 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1336 goto done;
1337 }
1338
1339write_done:
1340 md_number_to_chars (fixpos, image, 4);
1341
1342done:
1343 fixP->fx_done = 1;
1344}
1345
1346/* Look for a register name in the given symbol. */
1347
1348symbolS *
1349md_undefined_symbol (name)
1350 char *name;
1351{
1352 if (*name == '$')
1353 {
1354 int is_float = 0, num;
1355
1356 switch (*++name)
1357 {
1358 case 'f':
1359 if (name[1] == 'p' && name[2] == '\0')
1360 return alpha_register_table[AXP_REG_FP];
1361 is_float = 32;
1362 /* FALLTHRU */
1363
1364 case 'r':
1365 if (!ISDIGIT (*++name))
1366 break;
1367 /* FALLTHRU */
1368
1369 case '0': case '1': case '2': case '3': case '4':
1370 case '5': case '6': case '7': case '8': case '9':
1371 if (name[1] == '\0')
1372 num = name[0] - '0';
1373 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1374 {
1375 num = (name[0] - '0') * 10 + name[1] - '0';
1376 if (num >= 32)
1377 break;
1378 }
1379 else
1380 break;
1381
1382 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1383 as_warn (_("Used $at without \".set noat\""));
1384 return alpha_register_table[num + is_float];
1385
1386 case 'a':
1387 if (name[1] == 't' && name[2] == '\0')
1388 {
1389 if (!alpha_noat_on)
1390 as_warn (_("Used $at without \".set noat\""));
1391 return alpha_register_table[AXP_REG_AT];
1392 }
1393 break;
1394
1395 case 'g':
1396 if (name[1] == 'p' && name[2] == '\0')
1397 return alpha_register_table[alpha_gp_register];
1398 break;
1399
1400 case 's':
1401 if (name[1] == 'p' && name[2] == '\0')
1402 return alpha_register_table[AXP_REG_SP];
1403 break;
1404 }
1405 }
1406 return NULL;
1407}
1408
1409#ifdef OBJ_ECOFF
1410/* @@@ Magic ECOFF bits. */
1411
1412void
1413alpha_frob_ecoff_data ()
1414{
1415 select_gp_value ();
1416 /* $zero and $f31 are read-only */
1417 alpha_gprmask &= ~1;
1418 alpha_fprmask &= ~1;
1419}
1420#endif
1421
1422/* Hook to remember a recently defined label so that the auto-align
1423 code can adjust the symbol after we know what alignment will be
1424 required. */
1425
1426void
1427alpha_define_label (sym)
1428 symbolS *sym;
1429{
1430 alpha_insn_label = sym;
1431}
1432
1433/* Return true if we must always emit a reloc for a type and false if
1434 there is some hope of resolving it at assembly time. */
1435
1436int
1437alpha_force_relocation (f)
1438 fixS *f;
1439{
1440 if (alpha_flag_relax)
1441 return 1;
1442
1443 switch (f->fx_r_type)
1444 {
1445 case BFD_RELOC_ALPHA_GPDISP_HI16:
1446 case BFD_RELOC_ALPHA_GPDISP_LO16:
1447 case BFD_RELOC_ALPHA_GPDISP:
1448 case BFD_RELOC_ALPHA_LITERAL:
1449 case BFD_RELOC_ALPHA_ELF_LITERAL:
1450 case BFD_RELOC_ALPHA_LITUSE:
1451 case BFD_RELOC_GPREL16:
1452 case BFD_RELOC_GPREL32:
1453 case BFD_RELOC_ALPHA_GPREL_HI16:
1454 case BFD_RELOC_ALPHA_GPREL_LO16:
1455 case BFD_RELOC_ALPHA_LINKAGE:
1456 case BFD_RELOC_ALPHA_CODEADDR:
1457 case BFD_RELOC_ALPHA_BRSGP:
1458 case BFD_RELOC_ALPHA_TLSGD:
1459 case BFD_RELOC_ALPHA_TLSLDM:
1460 case BFD_RELOC_ALPHA_GOTDTPREL16:
1461 case BFD_RELOC_ALPHA_DTPREL_HI16:
1462 case BFD_RELOC_ALPHA_DTPREL_LO16:
1463 case BFD_RELOC_ALPHA_DTPREL16:
1464 case BFD_RELOC_ALPHA_GOTTPREL16:
1465 case BFD_RELOC_ALPHA_TPREL_HI16:
1466 case BFD_RELOC_ALPHA_TPREL_LO16:
1467 case BFD_RELOC_ALPHA_TPREL16:
1468 return 1;
1469
1470 default:
1471 break;
1472 }
1473
1474 return generic_force_reloc (f);
1475}
1476
1477/* Return true if we can partially resolve a relocation now. */
1478
1479int
1480alpha_fix_adjustable (f)
1481 fixS *f;
1482{
1483 /* Are there any relocation types for which we must generate a reloc
1484 but we can adjust the values contained within it? */
1485 switch (f->fx_r_type)
1486 {
1487 case BFD_RELOC_ALPHA_GPDISP_HI16:
1488 case BFD_RELOC_ALPHA_GPDISP_LO16:
1489 case BFD_RELOC_ALPHA_GPDISP:
1490 return 0;
1491
1492 case BFD_RELOC_ALPHA_LITERAL:
1493 case BFD_RELOC_ALPHA_ELF_LITERAL:
1494 case BFD_RELOC_ALPHA_LITUSE:
1495 case BFD_RELOC_ALPHA_LINKAGE:
1496 case BFD_RELOC_ALPHA_CODEADDR:
1497 return 1;
1498
1499 case BFD_RELOC_VTABLE_ENTRY:
1500 case BFD_RELOC_VTABLE_INHERIT:
1501 return 0;
1502
1503 case BFD_RELOC_GPREL16:
1504 case BFD_RELOC_GPREL32:
1505 case BFD_RELOC_ALPHA_GPREL_HI16:
1506 case BFD_RELOC_ALPHA_GPREL_LO16:
1507 case BFD_RELOC_23_PCREL_S2:
1508 case BFD_RELOC_32:
1509 case BFD_RELOC_64:
1510 case BFD_RELOC_ALPHA_HINT:
1511 return 1;
1512
1513 case BFD_RELOC_ALPHA_TLSGD:
1514 case BFD_RELOC_ALPHA_TLSLDM:
1515 case BFD_RELOC_ALPHA_GOTDTPREL16:
1516 case BFD_RELOC_ALPHA_DTPREL_HI16:
1517 case BFD_RELOC_ALPHA_DTPREL_LO16:
1518 case BFD_RELOC_ALPHA_DTPREL16:
1519 case BFD_RELOC_ALPHA_GOTTPREL16:
1520 case BFD_RELOC_ALPHA_TPREL_HI16:
1521 case BFD_RELOC_ALPHA_TPREL_LO16:
1522 case BFD_RELOC_ALPHA_TPREL16:
1523 /* ??? No idea why we can't return a reference to .tbss+10, but
1524 we're preventing this in the other assemblers. Follow for now. */
1525 return 0;
1526
1527#ifdef OBJ_ELF
1528 case BFD_RELOC_ALPHA_BRSGP:
1529 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1530 let it get resolved at assembly time. */
1531 {
1532 symbolS *sym = f->fx_addsy;
1533 const char *name;
1534 int offset = 0;
1535
1536 if (generic_force_reloc (f))
1537 return 0;
1538
1539 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
1540 {
1541 case STO_ALPHA_NOPV:
1542 break;
1543 case STO_ALPHA_STD_GPLOAD:
1544 offset = 8;
1545 break;
1546 default:
1547 if (S_IS_LOCAL (sym))
1548 name = "<local>";
1549 else
1550 name = S_GET_NAME (sym);
1551 as_bad_where (f->fx_file, f->fx_line,
1552 _("!samegp reloc against symbol without .prologue: %s"),
1553 name);
1554 break;
1555 }
1556 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
1557 f->fx_offset += offset;
1558 return 1;
1559 }
1560#endif
1561
1562 default:
1563 return 1;
1564 }
1565 /*NOTREACHED*/
1566}
1567
1568/* Generate the BFD reloc to be stuck in the object file from the
1569 fixup used internally in the assembler. */
1570
1571arelent *
1572tc_gen_reloc (sec, fixp)
1573 asection *sec ATTRIBUTE_UNUSED;
1574 fixS *fixp;
1575{
1576 arelent *reloc;
1577
1578 reloc = (arelent *) xmalloc (sizeof (arelent));
1579 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1580 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1581 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1582
1583 /* Make sure none of our internal relocations make it this far.
1584 They'd better have been fully resolved by this point. */
1585 assert ((int) fixp->fx_r_type > 0);
1586
1587 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1588 if (reloc->howto == NULL)
1589 {
1590 as_bad_where (fixp->fx_file, fixp->fx_line,
1591 _("cannot represent `%s' relocation in object file"),
1592 bfd_get_reloc_code_name (fixp->fx_r_type));
1593 return NULL;
1594 }
1595
1596 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1597 {
1598 as_fatal (_("internal error? cannot generate `%s' relocation"),
1599 bfd_get_reloc_code_name (fixp->fx_r_type));
1600 }
1601 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1602
1603#ifdef OBJ_ECOFF
1604 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1605 {
1606 /* Fake out bfd_perform_relocation. sigh. */
1607 reloc->addend = -alpha_gp_value;
1608 }
1609 else
1610#endif
1611 {
1612 reloc->addend = fixp->fx_offset;
1613#ifdef OBJ_ELF
1614 /* Ohhh, this is ugly. The problem is that if this is a local global
1615 symbol, the relocation will entirely be performed at link time, not
1616 at assembly time. bfd_perform_reloc doesn't know about this sort
1617 of thing, and as a result we need to fake it out here. */
1618 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1619 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
1620 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
1621 && !S_IS_COMMON (fixp->fx_addsy))
1622 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1623#endif
1624 }
1625
1626 return reloc;
1627}
1628
1629/* Parse a register name off of the input_line and return a register
1630 number. Gets md_undefined_symbol above to do the register name
1631 matching for us.
1632
1633 Only called as a part of processing the ECOFF .frame directive. */
1634
1635int
1636tc_get_register (frame)
1637 int frame ATTRIBUTE_UNUSED;
1638{
1639 int framereg = AXP_REG_SP;
1640
1641 SKIP_WHITESPACE ();
1642 if (*input_line_pointer == '$')
1643 {
1644 char *s = input_line_pointer;
1645 char c = get_symbol_end ();
1646 symbolS *sym = md_undefined_symbol (s);
1647
1648 *strchr (s, '\0') = c;
1649 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1650 goto found;
1651 }
1652 as_warn (_("frame reg expected, using $%d."), framereg);
1653
1654found:
1655 note_gpreg (framereg);
1656 return framereg;
1657}
1658
1659/* This is called before the symbol table is processed. In order to
1660 work with gcc when using mips-tfile, we must keep all local labels.
1661 However, in other cases, we want to discard them. If we were
1662 called with -g, but we didn't see any debugging information, it may
1663 mean that gcc is smuggling debugging information through to
1664 mips-tfile, in which case we must generate all local labels. */
1665
1666#ifdef OBJ_ECOFF
1667
1668void
1669alpha_frob_file_before_adjust ()
1670{
1671 if (alpha_debug != 0
1672 && ! ecoff_debugging_seen)
1673 flag_keep_locals = 1;
1674}
1675
1676#endif /* OBJ_ECOFF */
1677
1678
1679static struct alpha_reloc_tag *
1680get_alpha_reloc_tag (sequence)
1681 long sequence;
1682{
1683 char buffer[ALPHA_RELOC_DIGITS];
1684 struct alpha_reloc_tag *info;
1685
1686 sprintf (buffer, "!%ld", sequence);
1687
1688 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1689 if (! info)
1690 {
1691 size_t len = strlen (buffer);
1692 const char *errmsg;
1693
1694 info = (struct alpha_reloc_tag *)
1695 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1696
1697 info->segment = now_seg;
1698 info->sequence = sequence;
1699 strcpy (info->string, buffer);
1700 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1701 if (errmsg)
1702 as_fatal (errmsg);
1703 }
1704
1705 return info;
1706}
1707
1708/* Before the relocations are written, reorder them, so that user
1709 supplied !lituse relocations follow the appropriate !literal
1710 relocations, and similarly for !gpdisp relocations. */
1711
1712void
1713alpha_before_fix ()
1714{
1715 if (alpha_literal_hash)
1716 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
1717}
1718
1719static void
1720alpha_adjust_relocs (abfd, sec, ptr)
1721 bfd *abfd ATTRIBUTE_UNUSED;
1722 asection *sec;
1723 PTR ptr ATTRIBUTE_UNUSED;
1724{
1725 segment_info_type *seginfo = seg_info (sec);
1726 fixS **prevP;
1727 fixS *fixp;
1728 fixS *next;
1729 fixS *slave;
1730
1731 /* If seginfo is NULL, we did not create this section; don't do
1732 anything with it. By using a pointer to a pointer, we can update
1733 the links in place. */
1734 if (seginfo == NULL)
1735 return;
1736
1737 /* If there are no relocations, skip the section. */
1738 if (! seginfo->fix_root)
1739 return;
1740
1741 /* First rebuild the fixup chain without the expicit lituse and
1742 gpdisp_lo16 relocs. */
1743 prevP = &seginfo->fix_root;
1744 for (fixp = seginfo->fix_root; fixp; fixp = next)
1745 {
1746 next = fixp->fx_next;
1747 fixp->fx_next = (fixS *) 0;
1748
1749 switch (fixp->fx_r_type)
1750 {
1751 case BFD_RELOC_ALPHA_LITUSE:
1752 if (fixp->tc_fix_data.info->n_master == 0)
1753 as_bad_where (fixp->fx_file, fixp->fx_line,
1754 _("No !literal!%ld was found"),
1755 fixp->tc_fix_data.info->sequence);
1756#ifdef RELOC_OP_P
1757 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
1758 {
1759 if (! fixp->tc_fix_data.info->saw_tlsgd)
1760 as_bad_where (fixp->fx_file, fixp->fx_line,
1761 _("No !tlsgd!%ld was found"),
1762 fixp->tc_fix_data.info->sequence);
1763 }
1764 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
1765 {
1766 if (! fixp->tc_fix_data.info->saw_tlsldm)
1767 as_bad_where (fixp->fx_file, fixp->fx_line,
1768 _("No !tlsldm!%ld was found"),
1769 fixp->tc_fix_data.info->sequence);
1770 }
1771#endif
1772 break;
1773
1774 case BFD_RELOC_ALPHA_GPDISP_LO16:
1775 if (fixp->tc_fix_data.info->n_master == 0)
1776 as_bad_where (fixp->fx_file, fixp->fx_line,
1777 _("No ldah !gpdisp!%ld was found"),
1778 fixp->tc_fix_data.info->sequence);
1779 break;
1780
1781 case BFD_RELOC_ALPHA_ELF_LITERAL:
1782 if (fixp->tc_fix_data.info
1783 && (fixp->tc_fix_data.info->saw_tlsgd
1784 || fixp->tc_fix_data.info->saw_tlsldm))
1785 break;
1786 /* FALLTHRU */
1787
1788 default:
1789 *prevP = fixp;
1790 prevP = &fixp->fx_next;
1791 break;
1792 }
1793 }
1794
1795 /* Go back and re-chain dependent relocations. They are currently
1796 linked through the next_reloc field in reverse order, so as we
1797 go through the next_reloc chain, we effectively reverse the chain
1798 once again.
1799
1800 Except if there is more than one !literal for a given sequence
1801 number. In that case, the programmer and/or compiler is not sure
1802 how control flows from literal to lituse, and we can't be sure to
1803 get the relaxation correct.
1804
1805 ??? Well, actually we could, if there are enough lituses such that
1806 we can make each literal have at least one of each lituse type
1807 present. Not implemented.
1808
1809 Also suppress the optimization if the !literals/!lituses are spread
1810 in different segments. This can happen with "intersting" uses of
1811 inline assembly; examples are present in the Linux kernel semaphores. */
1812
1813 for (fixp = seginfo->fix_root; fixp; fixp = next)
1814 {
1815 next = fixp->fx_next;
1816 switch (fixp->fx_r_type)
1817 {
1818 case BFD_RELOC_ALPHA_TLSGD:
1819 case BFD_RELOC_ALPHA_TLSLDM:
1820 if (!fixp->tc_fix_data.info)
1821 break;
1822 if (fixp->tc_fix_data.info->n_master == 0)
1823 break;
1824 else if (fixp->tc_fix_data.info->n_master > 1)
1825 {
1826 as_bad_where (fixp->fx_file, fixp->fx_line,
1827 _("too many !literal!%ld for %s"),
1828 fixp->tc_fix_data.info->sequence,
1829 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
1830 ? "!tlsgd" : "!tlsldm"));
1831 break;
1832 }
1833
1834 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
1835 fixp->fx_next = fixp->tc_fix_data.info->master;
1836 fixp = fixp->fx_next;
1837 /* FALLTHRU */
1838
1839 case BFD_RELOC_ALPHA_ELF_LITERAL:
1840 if (fixp->tc_fix_data.info
1841 && fixp->tc_fix_data.info->n_master == 1
1842 && ! fixp->tc_fix_data.info->multi_section_p)
1843 {
1844 for (slave = fixp->tc_fix_data.info->slaves;
1845 slave != (fixS *) 0;
1846 slave = slave->tc_fix_data.next_reloc)
1847 {
1848 slave->fx_next = fixp->fx_next;
1849 fixp->fx_next = slave;
1850 }
1851 }
1852 break;
1853
1854 case BFD_RELOC_ALPHA_GPDISP_HI16:
1855 if (fixp->tc_fix_data.info->n_slaves == 0)
1856 as_bad_where (fixp->fx_file, fixp->fx_line,
1857 _("No lda !gpdisp!%ld was found"),
1858 fixp->tc_fix_data.info->sequence);
1859 else
1860 {
1861 slave = fixp->tc_fix_data.info->slaves;
1862 slave->fx_next = next;
1863 fixp->fx_next = slave;
1864 }
1865 break;
1866
1867 default:
1868 break;
1869 }
1870 }
1871}
1872
1873
1874#ifdef DEBUG_ALPHA
1875static void
1876debug_exp (tok, ntok)
1877 expressionS tok[];
1878 int ntok;
1879{
1880 int i;
1881
1882 fprintf (stderr, "debug_exp: %d tokens", ntok);
1883 for (i = 0; i < ntok; i++)
1884 {
1885 expressionS *t = &tok[i];
1886 const char *name;
1887
1888 switch (t->X_op)
1889 {
1890 default: name = "unknown"; break;
1891 case O_illegal: name = "O_illegal"; break;
1892 case O_absent: name = "O_absent"; break;
1893 case O_constant: name = "O_constant"; break;
1894 case O_symbol: name = "O_symbol"; break;
1895 case O_symbol_rva: name = "O_symbol_rva"; break;
1896 case O_register: name = "O_register"; break;
1897 case O_big: name = "O_big"; break;
1898 case O_uminus: name = "O_uminus"; break;
1899 case O_bit_not: name = "O_bit_not"; break;
1900 case O_logical_not: name = "O_logical_not"; break;
1901 case O_multiply: name = "O_multiply"; break;
1902 case O_divide: name = "O_divide"; break;
1903 case O_modulus: name = "O_modulus"; break;
1904 case O_left_shift: name = "O_left_shift"; break;
1905 case O_right_shift: name = "O_right_shift"; break;
1906 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1907 case O_bit_or_not: name = "O_bit_or_not"; break;
1908 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1909 case O_bit_and: name = "O_bit_and"; break;
1910 case O_add: name = "O_add"; break;
1911 case O_subtract: name = "O_subtract"; break;
1912 case O_eq: name = "O_eq"; break;
1913 case O_ne: name = "O_ne"; break;
1914 case O_lt: name = "O_lt"; break;
1915 case O_le: name = "O_le"; break;
1916 case O_ge: name = "O_ge"; break;
1917 case O_gt: name = "O_gt"; break;
1918 case O_logical_and: name = "O_logical_and"; break;
1919 case O_logical_or: name = "O_logical_or"; break;
1920 case O_index: name = "O_index"; break;
1921 case O_pregister: name = "O_pregister"; break;
1922 case O_cpregister: name = "O_cpregister"; break;
1923 case O_literal: name = "O_literal"; break;
1924 case O_lituse_addr: name = "O_lituse_addr"; break;
1925 case O_lituse_base: name = "O_lituse_base"; break;
1926 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1927 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1928 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
1929 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
1930 case O_gpdisp: name = "O_gpdisp"; break;
1931 case O_gprelhigh: name = "O_gprelhigh"; break;
1932 case O_gprellow: name = "O_gprellow"; break;
1933 case O_gprel: name = "O_gprel"; break;
1934 case O_samegp: name = "O_samegp"; break;
1935 case O_tlsgd: name = "O_tlsgd"; break;
1936 case O_tlsldm: name = "O_tlsldm"; break;
1937 case O_gotdtprel: name = "O_gotdtprel"; break;
1938 case O_dtprelhi: name = "O_dtprelhi"; break;
1939 case O_dtprello: name = "O_dtprello"; break;
1940 case O_dtprel: name = "O_dtprel"; break;
1941 case O_gottprel: name = "O_gottprel"; break;
1942 case O_tprelhi: name = "O_tprelhi"; break;
1943 case O_tprello: name = "O_tprello"; break;
1944 case O_tprel: name = "O_tprel"; break;
1945 }
1946
1947 fprintf (stderr, ", %s(%s, %s, %d)", name,
1948 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1949 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1950 (int) t->X_add_number);
1951 }
1952 fprintf (stderr, "\n");
1953 fflush (stderr);
1954}
1955#endif
1956
1957/* Parse the arguments to an opcode. */
1958
1959static int
1960tokenize_arguments (str, tok, ntok)
1961 char *str;
1962 expressionS tok[];
1963 int ntok;
1964{
1965 expressionS *end_tok = tok + ntok;
1966 char *old_input_line_pointer;
1967 int saw_comma = 0, saw_arg = 0;
1968#ifdef DEBUG_ALPHA
1969 expressionS *orig_tok = tok;
1970#endif
1971#ifdef RELOC_OP_P
1972 char *p;
1973 const struct alpha_reloc_op_tag *r;
1974 int c, i;
1975 size_t len;
1976 int reloc_found_p = 0;
1977#endif
1978
1979 memset (tok, 0, sizeof (*tok) * ntok);
1980
1981 /* Save and restore input_line_pointer around this function. */
1982 old_input_line_pointer = input_line_pointer;
1983 input_line_pointer = str;
1984
1985#ifdef RELOC_OP_P
1986 /* ??? Wrest control of ! away from the regular expression parser. */
1987 is_end_of_line[(unsigned char) '!'] = 1;
1988#endif
1989
1990 while (tok < end_tok && *input_line_pointer)
1991 {
1992 SKIP_WHITESPACE ();
1993 switch (*input_line_pointer)
1994 {
1995 case '\0':
1996 goto fini;
1997
1998#ifdef RELOC_OP_P
1999 case '!':
2000 /* A relocation operand can be placed after the normal operand on an
2001 assembly language statement, and has the following form:
2002 !relocation_type!sequence_number. */
2003 if (reloc_found_p)
2004 {
2005 /* Only support one relocation op per insn. */
2006 as_bad (_("More than one relocation op per insn"));
2007 goto err_report;
2008 }
2009
2010 if (!saw_arg)
2011 goto err;
2012
2013 ++input_line_pointer;
2014 SKIP_WHITESPACE ();
2015 p = input_line_pointer;
2016 c = get_symbol_end ();
2017
2018 /* Parse !relocation_type. */
2019 len = input_line_pointer - p;
2020 if (len == 0)
2021 {
2022 as_bad (_("No relocation operand"));
2023 goto err_report;
2024 }
2025
2026 r = &alpha_reloc_op[0];
2027 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
2028 if (len == r->length && memcmp (p, r->name, len) == 0)
2029 break;
2030 if (i < 0)
2031 {
2032 as_bad (_("Unknown relocation operand: !%s"), p);
2033 goto err_report;
2034 }
2035
2036 *input_line_pointer = c;
2037 SKIP_WHITESPACE ();
2038 if (*input_line_pointer != '!')
2039 {
2040 if (r->require_seq)
2041 {
2042 as_bad (_("no sequence number after !%s"), p);
2043 goto err_report;
2044 }
2045
2046 tok->X_add_number = 0;
2047 }
2048 else
2049 {
2050 if (! r->allow_seq)
2051 {
2052 as_bad (_("!%s does not use a sequence number"), p);
2053 goto err_report;
2054 }
2055
2056 input_line_pointer++;
2057
2058 /* Parse !sequence_number. */
2059 expression (tok);
2060 if (tok->X_op != O_constant || tok->X_add_number <= 0)
2061 {
2062 as_bad (_("Bad sequence number: !%s!%s"),
2063 r->name, input_line_pointer);
2064 goto err_report;
2065 }
2066 }
2067
2068 tok->X_op = r->op;
2069 reloc_found_p = 1;
2070 ++tok;
2071 break;
2072#endif /* RELOC_OP_P */
2073
2074 case ',':
2075 ++input_line_pointer;
2076 if (saw_comma || !saw_arg)
2077 goto err;
2078 saw_comma = 1;
2079 break;
2080
2081 case '(':
2082 {
2083 char *hold = input_line_pointer++;
2084
2085 /* First try for parenthesized register ... */
2086 expression (tok);
2087 if (*input_line_pointer == ')' && tok->X_op == O_register)
2088 {
2089 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
2090 saw_comma = 0;
2091 saw_arg = 1;
2092 ++input_line_pointer;
2093 ++tok;
2094 break;
2095 }
2096
2097 /* ... then fall through to plain expression. */
2098 input_line_pointer = hold;
2099 }
2100
2101 default:
2102 if (saw_arg && !saw_comma)
2103 goto err;
2104
2105 expression (tok);
2106 if (tok->X_op == O_illegal || tok->X_op == O_absent)
2107 goto err;
2108
2109 saw_comma = 0;
2110 saw_arg = 1;
2111 ++tok;
2112 break;
2113 }
2114 }
2115
2116fini:
2117 if (saw_comma)
2118 goto err;
2119 input_line_pointer = old_input_line_pointer;
2120
2121#ifdef DEBUG_ALPHA
2122 debug_exp (orig_tok, ntok - (end_tok - tok));
2123#endif
2124#ifdef RELOC_OP_P
2125 is_end_of_line[(unsigned char) '!'] = 0;
2126#endif
2127
2128 return ntok - (end_tok - tok);
2129
2130err:
2131#ifdef RELOC_OP_P
2132 is_end_of_line[(unsigned char) '!'] = 0;
2133#endif
2134 input_line_pointer = old_input_line_pointer;
2135 return TOKENIZE_ERROR;
2136
2137#ifdef RELOC_OP_P
2138err_report:
2139 is_end_of_line[(unsigned char) '!'] = 0;
2140#endif
2141 input_line_pointer = old_input_line_pointer;
2142 return TOKENIZE_ERROR_REPORT;
2143}
2144
2145/* Search forward through all variants of an opcode looking for a
2146 syntax match. */
2147
2148static const struct alpha_opcode *
2149find_opcode_match (first_opcode, tok, pntok, pcpumatch)
2150 const struct alpha_opcode *first_opcode;
2151 const expressionS *tok;
2152 int *pntok;
2153 int *pcpumatch;
2154{
2155 const struct alpha_opcode *opcode = first_opcode;
2156 int ntok = *pntok;
2157 int got_cpu_match = 0;
2158
2159 do
2160 {
2161 const unsigned char *opidx;
2162 int tokidx = 0;
2163
2164 /* Don't match opcodes that don't exist on this architecture. */
2165 if (!(opcode->flags & alpha_target))
2166 goto match_failed;
2167
2168 got_cpu_match = 1;
2169
2170 for (opidx = opcode->operands; *opidx; ++opidx)
2171 {
2172 const struct alpha_operand *operand = &alpha_operands[*opidx];
2173
2174 /* Only take input from real operands. */
2175 if (operand->flags & AXP_OPERAND_FAKE)
2176 continue;
2177
2178 /* When we expect input, make sure we have it. */
2179 if (tokidx >= ntok)
2180 {
2181 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2182 goto match_failed;
2183 continue;
2184 }
2185
2186 /* Match operand type with expression type. */
2187 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2188 {
2189 case AXP_OPERAND_IR:
2190 if (tok[tokidx].X_op != O_register
2191 || !is_ir_num (tok[tokidx].X_add_number))
2192 goto match_failed;
2193 break;
2194 case AXP_OPERAND_FPR:
2195 if (tok[tokidx].X_op != O_register
2196 || !is_fpr_num (tok[tokidx].X_add_number))
2197 goto match_failed;
2198 break;
2199 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2200 if (tok[tokidx].X_op != O_pregister
2201 || !is_ir_num (tok[tokidx].X_add_number))
2202 goto match_failed;
2203 break;
2204 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2205 if (tok[tokidx].X_op != O_cpregister
2206 || !is_ir_num (tok[tokidx].X_add_number))
2207 goto match_failed;
2208 break;
2209
2210 case AXP_OPERAND_RELATIVE:
2211 case AXP_OPERAND_SIGNED:
2212 case AXP_OPERAND_UNSIGNED:
2213 switch (tok[tokidx].X_op)
2214 {
2215 case O_illegal:
2216 case O_absent:
2217 case O_register:
2218 case O_pregister:
2219 case O_cpregister:
2220 goto match_failed;
2221
2222 default:
2223 break;
2224 }
2225 break;
2226
2227 default:
2228 /* Everything else should have been fake. */
2229 abort ();
2230 }
2231 ++tokidx;
2232 }
2233
2234 /* Possible match -- did we use all of our input? */
2235 if (tokidx == ntok)
2236 {
2237 *pntok = ntok;
2238 return opcode;
2239 }
2240
2241 match_failed:;
2242 }
2243 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
2244 && !strcmp (opcode->name, first_opcode->name));
2245
2246 if (*pcpumatch)
2247 *pcpumatch = got_cpu_match;
2248
2249 return NULL;
2250}
2251
2252/* Search forward through all variants of a macro looking for a syntax
2253 match. */
2254
2255static const struct alpha_macro *
2256find_macro_match (first_macro, tok, pntok)
2257 const struct alpha_macro *first_macro;
2258 const expressionS *tok;
2259 int *pntok;
2260{
2261 const struct alpha_macro *macro = first_macro;
2262 int ntok = *pntok;
2263
2264 do
2265 {
2266 const enum alpha_macro_arg *arg = macro->argsets;
2267 int tokidx = 0;
2268
2269 while (*arg)
2270 {
2271 switch (*arg)
2272 {
2273 case MACRO_EOA:
2274 if (tokidx == ntok)
2275 return macro;
2276 else
2277 tokidx = 0;
2278 break;
2279
2280 /* Index register. */
2281 case MACRO_IR:
2282 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2283 || !is_ir_num (tok[tokidx].X_add_number))
2284 goto match_failed;
2285 ++tokidx;
2286 break;
2287
2288 /* Parenthesized index register. */
2289 case MACRO_PIR:
2290 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2291 || !is_ir_num (tok[tokidx].X_add_number))
2292 goto match_failed;
2293 ++tokidx;
2294 break;
2295
2296 /* Optional parenthesized index register. */
2297 case MACRO_OPIR:
2298 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2299 && is_ir_num (tok[tokidx].X_add_number))
2300 ++tokidx;
2301 break;
2302
2303 /* Leading comma with a parenthesized index register. */
2304 case MACRO_CPIR:
2305 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2306 || !is_ir_num (tok[tokidx].X_add_number))
2307 goto match_failed;
2308 ++tokidx;
2309 break;
2310
2311 /* Floating point register. */
2312 case MACRO_FPR:
2313 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2314 || !is_fpr_num (tok[tokidx].X_add_number))
2315 goto match_failed;
2316 ++tokidx;
2317 break;
2318
2319 /* Normal expression. */
2320 case MACRO_EXP:
2321 if (tokidx >= ntok)
2322 goto match_failed;
2323 switch (tok[tokidx].X_op)
2324 {
2325 case O_illegal:
2326 case O_absent:
2327 case O_register:
2328 case O_pregister:
2329 case O_cpregister:
2330 case O_literal:
2331 case O_lituse_base:
2332 case O_lituse_bytoff:
2333 case O_lituse_jsr:
2334 case O_gpdisp:
2335 case O_gprelhigh:
2336 case O_gprellow:
2337 case O_gprel:
2338 case O_samegp:
2339 goto match_failed;
2340
2341 default:
2342 break;
2343 }
2344 ++tokidx;
2345 break;
2346
2347 match_failed:
2348 while (*arg != MACRO_EOA)
2349 ++arg;
2350 tokidx = 0;
2351 break;
2352 }
2353 ++arg;
2354 }
2355 }
2356 while (++macro - alpha_macros < (int) alpha_num_macros
2357 && !strcmp (macro->name, first_macro->name));
2358
2359 return NULL;
2360}
2361
2362/* Insert an operand value into an instruction. */
2363
2364static unsigned
2365insert_operand (insn, operand, val, file, line)
2366 unsigned insn;
2367 const struct alpha_operand *operand;
2368 offsetT val;
2369 char *file;
2370 unsigned line;
2371{
2372 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2373 {
2374 offsetT min, max;
2375
2376 if (operand->flags & AXP_OPERAND_SIGNED)
2377 {
2378 max = (1 << (operand->bits - 1)) - 1;
2379 min = -(1 << (operand->bits - 1));
2380 }
2381 else
2382 {
2383 max = (1 << operand->bits) - 1;
2384 min = 0;
2385 }
2386
2387 if (val < min || val > max)
2388 {
2389 const char *err =
2390 _("operand out of range (%s not between %d and %d)");
2391 char buf[sizeof (val) * 3 + 2];
2392
2393 sprint_value (buf, val);
2394 if (file)
2395 as_warn_where (file, line, err, buf, min, max);
2396 else
2397 as_warn (err, buf, min, max);
2398 }
2399 }
2400
2401 if (operand->insert)
2402 {
2403 const char *errmsg = NULL;
2404
2405 insn = (*operand->insert) (insn, val, &errmsg);
2406 if (errmsg)
2407 as_warn (errmsg);
2408 }
2409 else
2410 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2411
2412 return insn;
2413}
2414
2415/* Turn an opcode description and a set of arguments into
2416 an instruction and a fixup. */
2417
2418static void
2419assemble_insn (opcode, tok, ntok, insn, reloc)
2420 const struct alpha_opcode *opcode;
2421 const expressionS *tok;
2422 int ntok;
2423 struct alpha_insn *insn;
2424 bfd_reloc_code_real_type reloc;
2425{
2426 const struct alpha_operand *reloc_operand = NULL;
2427 const expressionS *reloc_exp = NULL;
2428 const unsigned char *argidx;
2429 unsigned image;
2430 int tokidx = 0;
2431
2432 memset (insn, 0, sizeof (*insn));
2433 image = opcode->opcode;
2434
2435 for (argidx = opcode->operands; *argidx; ++argidx)
2436 {
2437 const struct alpha_operand *operand = &alpha_operands[*argidx];
2438 const expressionS *t = (const expressionS *) 0;
2439
2440 if (operand->flags & AXP_OPERAND_FAKE)
2441 {
2442 /* fake operands take no value and generate no fixup */
2443 image = insert_operand (image, operand, 0, NULL, 0);
2444 continue;
2445 }
2446
2447 if (tokidx >= ntok)
2448 {
2449 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2450 {
2451 case AXP_OPERAND_DEFAULT_FIRST:
2452 t = &tok[0];
2453 break;
2454 case AXP_OPERAND_DEFAULT_SECOND:
2455 t = &tok[1];
2456 break;
2457 case AXP_OPERAND_DEFAULT_ZERO:
2458 {
2459 static expressionS zero_exp;
2460 t = &zero_exp;
2461 zero_exp.X_op = O_constant;
2462 zero_exp.X_unsigned = 1;
2463 }
2464 break;
2465 default:
2466 abort ();
2467 }
2468 }
2469 else
2470 t = &tok[tokidx++];
2471
2472 switch (t->X_op)
2473 {
2474 case O_register:
2475 case O_pregister:
2476 case O_cpregister:
2477 image = insert_operand (image, operand, regno (t->X_add_number),
2478 NULL, 0);
2479 break;
2480
2481 case O_constant:
2482 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2483 assert (reloc_operand == NULL);
2484 reloc_operand = operand;
2485 reloc_exp = t;
2486 break;
2487
2488 default:
2489 /* This is only 0 for fields that should contain registers,
2490 which means this pattern shouldn't have matched. */
2491 if (operand->default_reloc == 0)
2492 abort ();
2493
2494 /* There is one special case for which an insn receives two
2495 relocations, and thus the user-supplied reloc does not
2496 override the operand reloc. */
2497 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2498 {
2499 struct alpha_fixup *fixup;
2500
2501 if (insn->nfixups >= MAX_INSN_FIXUPS)
2502 as_fatal (_("too many fixups"));
2503
2504 fixup = &insn->fixups[insn->nfixups++];
2505 fixup->exp = *t;
2506 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2507 }
2508 else
2509 {
2510 if (reloc == BFD_RELOC_UNUSED)
2511 reloc = operand->default_reloc;
2512
2513 assert (reloc_operand == NULL);
2514 reloc_operand = operand;
2515 reloc_exp = t;
2516 }
2517 break;
2518 }
2519 }
2520
2521 if (reloc != BFD_RELOC_UNUSED)
2522 {
2523 struct alpha_fixup *fixup;
2524
2525 if (insn->nfixups >= MAX_INSN_FIXUPS)
2526 as_fatal (_("too many fixups"));
2527
2528 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2529 relocation tag for both ldah and lda with gpdisp. Choose the
2530 correct internal relocation based on the opcode. */
2531 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2532 {
2533 if (strcmp (opcode->name, "ldah") == 0)
2534 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2535 else if (strcmp (opcode->name, "lda") == 0)
2536 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2537 else
2538 as_bad (_("invalid relocation for instruction"));
2539 }
2540
2541 /* If this is a real relocation (as opposed to a lituse hint), then
2542 the relocation width should match the operand width. */
2543 else if (reloc < BFD_RELOC_UNUSED)
2544 {
2545 reloc_howto_type *reloc_howto
2546 = bfd_reloc_type_lookup (stdoutput, reloc);
2547 if (reloc_howto->bitsize != reloc_operand->bits)
2548 {
2549 as_bad (_("invalid relocation for field"));
2550 return;
2551 }
2552 }
2553
2554 fixup = &insn->fixups[insn->nfixups++];
2555 if (reloc_exp)
2556 fixup->exp = *reloc_exp;
2557 else
2558 fixup->exp.X_op = O_absent;
2559 fixup->reloc = reloc;
2560 }
2561
2562 insn->insn = image;
2563}
2564
2565/* Actually output an instruction with its fixup. */
2566
2567static void
2568emit_insn (insn)
2569 struct alpha_insn *insn;
2570{
2571 char *f;
2572 int i;
2573
2574 /* Take care of alignment duties. */
2575 if (alpha_auto_align_on && alpha_current_align < 2)
2576 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2577 if (alpha_current_align > 2)
2578 alpha_current_align = 2;
2579 alpha_insn_label = NULL;
2580
2581 /* Write out the instruction. */
2582 f = frag_more (4);
2583 md_number_to_chars (f, insn->insn, 4);
2584
2585#ifdef OBJ_ELF
2586 dwarf2_emit_insn (4);
2587#endif
2588
2589 /* Apply the fixups in order. */
2590 for (i = 0; i < insn->nfixups; ++i)
2591 {
2592 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2593 struct alpha_fixup *fixup = &insn->fixups[i];
2594 struct alpha_reloc_tag *info = NULL;
2595 int size, pcrel;
2596 fixS *fixP;
2597
2598 /* Some fixups are only used internally and so have no howto. */
2599 if ((int) fixup->reloc < 0)
2600 {
2601 operand = &alpha_operands[-(int) fixup->reloc];
2602 size = 4;
2603 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2604 }
2605 else if (fixup->reloc > BFD_RELOC_UNUSED
2606 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2607 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2608 {
2609 size = 2;
2610 pcrel = 0;
2611 }
2612 else
2613 {
2614 reloc_howto_type *reloc_howto
2615 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2616 assert (reloc_howto);
2617
2618 size = bfd_get_reloc_size (reloc_howto);
2619 assert (size >= 1 && size <= 4);
2620
2621 pcrel = reloc_howto->pc_relative;
2622 }
2623
2624 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2625 &fixup->exp, pcrel, fixup->reloc);
2626
2627 /* Turn off complaints that the addend is too large for some fixups,
2628 and copy in the sequence number for the explicit relocations. */
2629 switch (fixup->reloc)
2630 {
2631 case BFD_RELOC_ALPHA_HINT:
2632 case BFD_RELOC_GPREL32:
2633 case BFD_RELOC_GPREL16:
2634 case BFD_RELOC_ALPHA_GPREL_HI16:
2635 case BFD_RELOC_ALPHA_GPREL_LO16:
2636 case BFD_RELOC_ALPHA_GOTDTPREL16:
2637 case BFD_RELOC_ALPHA_DTPREL_HI16:
2638 case BFD_RELOC_ALPHA_DTPREL_LO16:
2639 case BFD_RELOC_ALPHA_DTPREL16:
2640 case BFD_RELOC_ALPHA_GOTTPREL16:
2641 case BFD_RELOC_ALPHA_TPREL_HI16:
2642 case BFD_RELOC_ALPHA_TPREL_LO16:
2643 case BFD_RELOC_ALPHA_TPREL16:
2644 fixP->fx_no_overflow = 1;
2645 break;
2646
2647 case BFD_RELOC_ALPHA_GPDISP_HI16:
2648 fixP->fx_no_overflow = 1;
2649 fixP->fx_addsy = section_symbol (now_seg);
2650 fixP->fx_offset = 0;
2651
2652 info = get_alpha_reloc_tag (insn->sequence);
2653 if (++info->n_master > 1)
2654 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2655 if (info->segment != now_seg)
2656 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2657 insn->sequence);
2658 fixP->tc_fix_data.info = info;
2659 break;
2660
2661 case BFD_RELOC_ALPHA_GPDISP_LO16:
2662 fixP->fx_no_overflow = 1;
2663
2664 info = get_alpha_reloc_tag (insn->sequence);
2665 if (++info->n_slaves > 1)
2666 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2667 if (info->segment != now_seg)
2668 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2669 insn->sequence);
2670 fixP->tc_fix_data.info = info;
2671 info->slaves = fixP;
2672 break;
2673
2674 case BFD_RELOC_ALPHA_LITERAL:
2675 case BFD_RELOC_ALPHA_ELF_LITERAL:
2676 fixP->fx_no_overflow = 1;
2677
2678 if (insn->sequence == 0)
2679 break;
2680 info = get_alpha_reloc_tag (insn->sequence);
2681 info->master = fixP;
2682 info->n_master++;
2683 if (info->segment != now_seg)
2684 info->multi_section_p = 1;
2685 fixP->tc_fix_data.info = info;
2686 break;
2687
2688#ifdef RELOC_OP_P
2689 case DUMMY_RELOC_LITUSE_ADDR:
2690 fixP->fx_offset = LITUSE_ALPHA_ADDR;
2691 goto do_lituse;
2692 case DUMMY_RELOC_LITUSE_BASE:
2693 fixP->fx_offset = LITUSE_ALPHA_BASE;
2694 goto do_lituse;
2695 case DUMMY_RELOC_LITUSE_BYTOFF:
2696 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
2697 goto do_lituse;
2698 case DUMMY_RELOC_LITUSE_JSR:
2699 fixP->fx_offset = LITUSE_ALPHA_JSR;
2700 goto do_lituse;
2701 case DUMMY_RELOC_LITUSE_TLSGD:
2702 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
2703 goto do_lituse;
2704 case DUMMY_RELOC_LITUSE_TLSLDM:
2705 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
2706 goto do_lituse;
2707 do_lituse:
2708 fixP->fx_addsy = section_symbol (now_seg);
2709 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2710
2711 info = get_alpha_reloc_tag (insn->sequence);
2712 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
2713 info->saw_lu_tlsgd = 1;
2714 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
2715 info->saw_lu_tlsldm = 1;
2716 if (++info->n_slaves > 1)
2717 {
2718 if (info->saw_lu_tlsgd)
2719 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2720 insn->sequence);
2721 else if (info->saw_lu_tlsldm)
2722 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2723 insn->sequence);
2724 }
2725 fixP->tc_fix_data.info = info;
2726 fixP->tc_fix_data.next_reloc = info->slaves;
2727 info->slaves = fixP;
2728 if (info->segment != now_seg)
2729 info->multi_section_p = 1;
2730 break;
2731
2732 case BFD_RELOC_ALPHA_TLSGD:
2733 fixP->fx_no_overflow = 1;
2734
2735 if (insn->sequence == 0)
2736 break;
2737 info = get_alpha_reloc_tag (insn->sequence);
2738 if (info->saw_tlsgd)
2739 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
2740 else if (info->saw_tlsldm)
2741 as_bad (_("sequence number in use for !tlsldm!%ld"),
2742 insn->sequence);
2743 else
2744 info->saw_tlsgd = 1;
2745 fixP->tc_fix_data.info = info;
2746 break;
2747
2748 case BFD_RELOC_ALPHA_TLSLDM:
2749 fixP->fx_no_overflow = 1;
2750
2751 if (insn->sequence == 0)
2752 break;
2753 info = get_alpha_reloc_tag (insn->sequence);
2754 if (info->saw_tlsldm)
2755 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
2756 else if (info->saw_tlsgd)
2757 as_bad (_("sequence number in use for !tlsgd!%ld"),
2758 insn->sequence);
2759 else
2760 info->saw_tlsldm = 1;
2761 fixP->tc_fix_data.info = info;
2762 break;
2763#endif
2764 default:
2765 if ((int) fixup->reloc < 0)
2766 {
2767 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2768 fixP->fx_no_overflow = 1;
2769 }
2770 break;
2771 }
2772 }
2773}
2774
2775/* Given an opcode name and a pre-tokenized set of arguments, assemble
2776 the insn, but do not emit it.
2777
2778 Note that this implies no macros allowed, since we can't store more
2779 than one insn in an insn structure. */
2780
2781static void
2782assemble_tokens_to_insn (opname, tok, ntok, insn)
2783 const char *opname;
2784 const expressionS *tok;
2785 int ntok;
2786 struct alpha_insn *insn;
2787{
2788 const struct alpha_opcode *opcode;
2789
2790 /* search opcodes */
2791 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2792 if (opcode)
2793 {
2794 int cpumatch;
2795 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2796 if (opcode)
2797 {
2798 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2799 return;
2800 }
2801 else if (cpumatch)
2802 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2803 else
2804 as_bad (_("opcode `%s' not supported for target %s"), opname,
2805 alpha_target_name);
2806 }
2807 else
2808 as_bad (_("unknown opcode `%s'"), opname);
2809}
2810
2811/* Given an opcode name and a pre-tokenized set of arguments, take the
2812 opcode all the way through emission. */
2813
2814static void
2815assemble_tokens (opname, tok, ntok, local_macros_on)
2816 const char *opname;
2817 const expressionS *tok;
2818 int ntok;
2819 int local_macros_on;
2820{
2821 int found_something = 0;
2822 const struct alpha_opcode *opcode;
2823 const struct alpha_macro *macro;
2824 int cpumatch = 1;
2825 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2826
2827#ifdef RELOC_OP_P
2828 /* If a user-specified relocation is present, this is not a macro. */
2829 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2830 {
2831 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2832 ntok--;
2833 }
2834 else
2835#endif
2836 if (local_macros_on)
2837 {
2838 macro = ((const struct alpha_macro *)
2839 hash_find (alpha_macro_hash, opname));
2840 if (macro)
2841 {
2842 found_something = 1;
2843 macro = find_macro_match (macro, tok, &ntok);
2844 if (macro)
2845 {
2846 (*macro->emit) (tok, ntok, macro->arg);
2847 return;
2848 }
2849 }
2850 }
2851
2852 /* Search opcodes. */
2853 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2854 if (opcode)
2855 {
2856 found_something = 1;
2857 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2858 if (opcode)
2859 {
2860 struct alpha_insn insn;
2861 assemble_insn (opcode, tok, ntok, &insn, reloc);
2862
2863 /* Copy the sequence number for the reloc from the reloc token. */
2864 if (reloc != BFD_RELOC_UNUSED)
2865 insn.sequence = tok[ntok].X_add_number;
2866
2867 emit_insn (&insn);
2868 return;
2869 }
2870 }
2871
2872 if (found_something)
2873 {
2874 if (cpumatch)
2875 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2876 else
2877 as_bad (_("opcode `%s' not supported for target %s"), opname,
2878 alpha_target_name);
2879 }
2880 else
2881 as_bad (_("unknown opcode `%s'"), opname);
2882}
2883
2884
2885/* Some instruction sets indexed by lg(size). */
2886static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2887static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2888static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2889static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2890static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2891static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2892static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2893static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2894static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2895
2896/* Implement the ldgp macro. */
2897
2898static void
2899emit_ldgp (tok, ntok, unused)
2900 const expressionS *tok;
2901 int ntok ATTRIBUTE_UNUSED;
2902 const PTR unused ATTRIBUTE_UNUSED;
2903{
2904#ifdef OBJ_AOUT
2905FIXME
2906#endif
2907#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2908 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2909 with appropriate constants and relocations. */
2910 struct alpha_insn insn;
2911 expressionS newtok[3];
2912 expressionS addend;
2913
2914#ifdef OBJ_ECOFF
2915 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2916 ecoff_set_gp_prolog_size (0);
2917#endif
2918
2919 newtok[0] = tok[0];
2920 set_tok_const (newtok[1], 0);
2921 newtok[2] = tok[2];
2922
2923 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2924
2925 addend = tok[1];
2926
2927#ifdef OBJ_ECOFF
2928 if (addend.X_op != O_constant)
2929 as_bad (_("can not resolve expression"));
2930 addend.X_op = O_symbol;
2931 addend.X_add_symbol = alpha_gp_symbol;
2932#endif
2933
2934 insn.nfixups = 1;
2935 insn.fixups[0].exp = addend;
2936 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2937 insn.sequence = next_sequence_num;
2938
2939 emit_insn (&insn);
2940
2941 set_tok_preg (newtok[2], tok[0].X_add_number);
2942
2943 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2944
2945#ifdef OBJ_ECOFF
2946 addend.X_add_number += 4;
2947#endif
2948
2949 insn.nfixups = 1;
2950 insn.fixups[0].exp = addend;
2951 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2952 insn.sequence = next_sequence_num--;
2953
2954 emit_insn (&insn);
2955#endif /* OBJ_ECOFF || OBJ_ELF */
2956}
2957
2958#ifdef OBJ_EVAX
2959
2960/* Add symbol+addend to link pool.
2961 Return offset from basesym to entry in link pool.
2962
2963 Add new fixup only if offset isn't 16bit. */
2964
2965valueT
2966add_to_link_pool (basesym, sym, addend)
2967 symbolS *basesym;
2968 symbolS *sym;
2969 offsetT addend;
2970{
2971 segT current_section = now_seg;
2972 int current_subsec = now_subseg;
2973 valueT offset;
2974 bfd_reloc_code_real_type reloc_type;
2975 char *p;
2976 segment_info_type *seginfo = seg_info (alpha_link_section);
2977 fixS *fixp;
2978
2979 offset = - *symbol_get_obj (basesym);
2980
2981 /* @@ This assumes all entries in a given section will be of the same
2982 size... Probably correct, but unwise to rely on. */
2983 /* This must always be called with the same subsegment. */
2984
2985 if (seginfo->frchainP)
2986 for (fixp = seginfo->frchainP->fix_root;
2987 fixp != (fixS *) NULL;
2988 fixp = fixp->fx_next, offset += 8)
2989 {
2990 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2991 {
2992 if (range_signed_16 (offset))
2993 {
2994 return offset;
2995 }
2996 }
2997 }
2998
2999 /* Not found in 16bit signed range. */
3000
3001 subseg_set (alpha_link_section, 0);
3002 p = frag_more (8);
3003 memset (p, 0, 8);
3004
3005 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3006 BFD_RELOC_64);
3007
3008 subseg_set (current_section, current_subsec);
3009 seginfo->literal_pool_size += 8;
3010 return offset;
3011}
3012
3013#endif /* OBJ_EVAX */
3014
3015/* Load a (partial) expression into a target register.
3016
3017 If poffset is not null, after the call it will either contain
3018 O_constant 0, or a 16-bit offset appropriate for any MEM format
3019 instruction. In addition, pbasereg will be modified to point to
3020 the base register to use in that MEM format instruction.
3021
3022 In any case, *pbasereg should contain a base register to add to the
3023 expression. This will normally be either AXP_REG_ZERO or
3024 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3025 so "foo($0)" is interpreted as adding the address of foo to $0;
3026 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3027 but this is what OSF/1 does.
3028
3029 If explicit relocations of the form !literal!<number> are allowed,
3030 and used, then explict_reloc with be an expression pointer.
3031
3032 Finally, the return value is nonzero if the calling macro may emit
3033 a LITUSE reloc if otherwise appropriate; the return value is the
3034 sequence number to use. */
3035
3036static long
3037load_expression (targreg, exp, pbasereg, poffset)
3038 int targreg;
3039 const expressionS *exp;
3040 int *pbasereg;
3041 expressionS *poffset;
3042{
3043 long emit_lituse = 0;
3044 offsetT addend = exp->X_add_number;
3045 int basereg = *pbasereg;
3046 struct alpha_insn insn;
3047 expressionS newtok[3];
3048
3049 switch (exp->X_op)
3050 {
3051 case O_symbol:
3052 {
3053#ifdef OBJ_ECOFF
3054 offsetT lit;
3055
3056 /* Attempt to reduce .lit load by splitting the offset from
3057 its symbol when possible, but don't create a situation in
3058 which we'd fail. */
3059 if (!range_signed_32 (addend) &&
3060 (alpha_noat_on || targreg == AXP_REG_AT))
3061 {
3062 lit = add_to_literal_pool (exp->X_add_symbol, addend,
3063 alpha_lita_section, 8);
3064 addend = 0;
3065 }
3066 else
3067 {
3068 lit = add_to_literal_pool (exp->X_add_symbol, 0,
3069 alpha_lita_section, 8);
3070 }
3071
3072 if (lit >= 0x8000)
3073 as_fatal (_("overflow in literal (.lita) table"));
3074
3075 /* emit "ldq r, lit(gp)" */
3076
3077 if (basereg != alpha_gp_register && targreg == basereg)
3078 {
3079 if (alpha_noat_on)
3080 as_bad (_("macro requires $at register while noat in effect"));
3081 if (targreg == AXP_REG_AT)
3082 as_bad (_("macro requires $at while $at in use"));
3083
3084 set_tok_reg (newtok[0], AXP_REG_AT);
3085 }
3086 else
3087 set_tok_reg (newtok[0], targreg);
3088 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
3089 set_tok_preg (newtok[2], alpha_gp_register);
3090
3091 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3092
3093 assert (insn.nfixups == 1);
3094 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3095 insn.sequence = emit_lituse = next_sequence_num--;
3096#endif /* OBJ_ECOFF */
3097#ifdef OBJ_ELF
3098 /* emit "ldq r, gotoff(gp)" */
3099
3100 if (basereg != alpha_gp_register && targreg == basereg)
3101 {
3102 if (alpha_noat_on)
3103 as_bad (_("macro requires $at register while noat in effect"));
3104 if (targreg == AXP_REG_AT)
3105 as_bad (_("macro requires $at while $at in use"));
3106
3107 set_tok_reg (newtok[0], AXP_REG_AT);
3108 }
3109 else
3110 set_tok_reg (newtok[0], targreg);
3111
3112 /* XXX: Disable this .got minimizing optimization so that we can get
3113 better instruction offset knowledge in the compiler. This happens
3114 very infrequently anyway. */
3115 if (1
3116 || (!range_signed_32 (addend)
3117 && (alpha_noat_on || targreg == AXP_REG_AT)))
3118 {
3119 newtok[1] = *exp;
3120 addend = 0;
3121 }
3122 else
3123 {
3124 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
3125 }
3126
3127 set_tok_preg (newtok[2], alpha_gp_register);
3128
3129 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3130
3131 assert (insn.nfixups == 1);
3132 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3133 insn.sequence = emit_lituse = next_sequence_num--;
3134#endif /* OBJ_ELF */
3135#ifdef OBJ_EVAX
3136 offsetT link;
3137
3138 /* Find symbol or symbol pointer in link section. */
3139
3140 if (exp->X_add_symbol == alpha_evax_proc.symbol)
3141 {
3142 if (range_signed_16 (addend))
3143 {
3144 set_tok_reg (newtok[0], targreg);
3145 set_tok_const (newtok[1], addend);
3146 set_tok_preg (newtok[2], basereg);
3147 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3148 addend = 0;
3149 }
3150 else
3151 {
3152 set_tok_reg (newtok[0], targreg);
3153 set_tok_const (newtok[1], 0);
3154 set_tok_preg (newtok[2], basereg);
3155 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3156 }
3157 }
3158 else
3159 {
3160 if (!range_signed_32 (addend))
3161 {
3162 link = add_to_link_pool (alpha_evax_proc.symbol,
3163 exp->X_add_symbol, addend);
3164 addend = 0;
3165 }
3166 else
3167 {
3168 link = add_to_link_pool (alpha_evax_proc.symbol,
3169 exp->X_add_symbol, 0);
3170 }
3171 set_tok_reg (newtok[0], targreg);
3172 set_tok_const (newtok[1], link);
3173 set_tok_preg (newtok[2], basereg);
3174 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3175 }
3176#endif /* OBJ_EVAX */
3177
3178 emit_insn (&insn);
3179
3180#ifndef OBJ_EVAX
3181 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
3182 {
3183 /* emit "addq r, base, r" */
3184
3185 set_tok_reg (newtok[1], basereg);
3186 set_tok_reg (newtok[2], targreg);
3187 assemble_tokens ("addq", newtok, 3, 0);
3188 }
3189#endif
3190
3191 basereg = targreg;
3192 }
3193 break;
3194
3195 case O_constant:
3196 break;
3197
3198 case O_subtract:
3199 /* Assume that this difference expression will be resolved to an
3200 absolute value and that that value will fit in 16 bits. */
3201
3202 set_tok_reg (newtok[0], targreg);
3203 newtok[1] = *exp;
3204 set_tok_preg (newtok[2], basereg);
3205 assemble_tokens ("lda", newtok, 3, 0);
3206
3207 if (poffset)
3208 set_tok_const (*poffset, 0);
3209 return 0;
3210
3211 case O_big:
3212 if (exp->X_add_number > 0)
3213 as_bad (_("bignum invalid; zero assumed"));
3214 else
3215 as_bad (_("floating point number invalid; zero assumed"));
3216 addend = 0;
3217 break;
3218
3219 default:
3220 as_bad (_("can't handle expression"));
3221 addend = 0;
3222 break;
3223 }
3224
3225 if (!range_signed_32 (addend))
3226 {
3227 offsetT lit;
3228 long seq_num = next_sequence_num--;
3229
3230 /* For 64-bit addends, just put it in the literal pool. */
3231
3232#ifdef OBJ_EVAX
3233 /* emit "ldq targreg, lit(basereg)" */
3234 lit = add_to_link_pool (alpha_evax_proc.symbol,
3235 section_symbol (absolute_section), addend);
3236 set_tok_reg (newtok[0], targreg);
3237 set_tok_const (newtok[1], lit);
3238 set_tok_preg (newtok[2], alpha_gp_register);
3239 assemble_tokens ("ldq", newtok, 3, 0);
3240#else
3241
3242 if (alpha_lit8_section == NULL)
3243 {
3244 create_literal_section (".lit8",
3245 &alpha_lit8_section,
3246 &alpha_lit8_symbol);
3247
3248#ifdef OBJ_ECOFF
3249 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3250 alpha_lita_section, 8);
3251 if (alpha_lit8_literal >= 0x8000)
3252 as_fatal (_("overflow in literal (.lita) table"));
3253#endif
3254 }
3255
3256 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3257 if (lit >= 0x8000)
3258 as_fatal (_("overflow in literal (.lit8) table"));
3259
3260 /* emit "lda litreg, .lit8+0x8000" */
3261
3262 if (targreg == basereg)
3263 {
3264 if (alpha_noat_on)
3265 as_bad (_("macro requires $at register while noat in effect"));
3266 if (targreg == AXP_REG_AT)
3267 as_bad (_("macro requires $at while $at in use"));
3268
3269 set_tok_reg (newtok[0], AXP_REG_AT);
3270 }
3271 else
3272 set_tok_reg (newtok[0], targreg);
3273#ifdef OBJ_ECOFF
3274 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3275#endif
3276#ifdef OBJ_ELF
3277 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3278#endif
3279 set_tok_preg (newtok[2], alpha_gp_register);
3280
3281 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3282
3283 assert (insn.nfixups == 1);
3284#ifdef OBJ_ECOFF
3285 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3286#endif
3287#ifdef OBJ_ELF
3288 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3289#endif
3290 insn.sequence = seq_num;
3291
3292 emit_insn (&insn);
3293
3294 /* emit "ldq litreg, lit(litreg)" */
3295
3296 set_tok_const (newtok[1], lit);
3297 set_tok_preg (newtok[2], newtok[0].X_add_number);
3298
3299 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3300
3301 assert (insn.nfixups < MAX_INSN_FIXUPS);
3302 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3303 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3304 insn.nfixups++;
3305 insn.sequence = seq_num;
3306 emit_lituse = 0;
3307
3308 emit_insn (&insn);
3309
3310 /* emit "addq litreg, base, target" */
3311
3312 if (basereg != AXP_REG_ZERO)
3313 {
3314 set_tok_reg (newtok[1], basereg);
3315 set_tok_reg (newtok[2], targreg);
3316 assemble_tokens ("addq", newtok, 3, 0);
3317 }
3318#endif /* !OBJ_EVAX */
3319
3320 if (poffset)
3321 set_tok_const (*poffset, 0);
3322 *pbasereg = targreg;
3323 }
3324 else
3325 {
3326 offsetT low, high, extra, tmp;
3327
3328 /* for 32-bit operands, break up the addend */
3329
3330 low = sign_extend_16 (addend);
3331 tmp = addend - low;
3332 high = sign_extend_16 (tmp >> 16);
3333
3334 if (tmp - (high << 16))
3335 {
3336 extra = 0x4000;
3337 tmp -= 0x40000000;
3338 high = sign_extend_16 (tmp >> 16);
3339 }
3340 else
3341 extra = 0;
3342
3343 set_tok_reg (newtok[0], targreg);
3344 set_tok_preg (newtok[2], basereg);
3345
3346 if (extra)
3347 {
3348 /* emit "ldah r, extra(r) */
3349 set_tok_const (newtok[1], extra);
3350 assemble_tokens ("ldah", newtok, 3, 0);
3351 set_tok_preg (newtok[2], basereg = targreg);
3352 }
3353
3354 if (high)
3355 {
3356 /* emit "ldah r, high(r) */
3357 set_tok_const (newtok[1], high);
3358 assemble_tokens ("ldah", newtok, 3, 0);
3359 basereg = targreg;
3360 set_tok_preg (newtok[2], basereg);
3361 }
3362
3363 if ((low && !poffset) || (!poffset && basereg != targreg))
3364 {
3365 /* emit "lda r, low(base)" */
3366 set_tok_const (newtok[1], low);
3367 assemble_tokens ("lda", newtok, 3, 0);
3368 basereg = targreg;
3369 low = 0;
3370 }
3371
3372 if (poffset)
3373 set_tok_const (*poffset, low);
3374 *pbasereg = basereg;
3375 }
3376
3377 return emit_lituse;
3378}
3379
3380/* The lda macro differs from the lda instruction in that it handles
3381 most simple expressions, particualrly symbol address loads and
3382 large constants. */
3383
3384static void
3385emit_lda (tok, ntok, unused)
3386 const expressionS *tok;
3387 int ntok;
3388 const PTR unused ATTRIBUTE_UNUSED;
3389{
3390 int basereg;
3391
3392 if (ntok == 2)
3393 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3394 else
3395 basereg = tok[2].X_add_number;
3396
3397 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3398}
3399
3400/* The ldah macro differs from the ldah instruction in that it has $31
3401 as an implied base register. */
3402
3403static void
3404emit_ldah (tok, ntok, unused)
3405 const expressionS *tok;
3406 int ntok ATTRIBUTE_UNUSED;
3407 const PTR unused ATTRIBUTE_UNUSED;
3408{
3409 expressionS newtok[3];
3410
3411 newtok[0] = tok[0];
3412 newtok[1] = tok[1];
3413 set_tok_preg (newtok[2], AXP_REG_ZERO);
3414
3415 assemble_tokens ("ldah", newtok, 3, 0);
3416}
3417
3418/* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3419 etc. They differ from the real instructions in that they do simple
3420 expressions like the lda macro. */
3421
3422static void
3423emit_ir_load (tok, ntok, opname)
3424 const expressionS *tok;
3425 int ntok;
3426 const PTR opname;
3427{
3428 int basereg;
3429 long lituse;
3430 expressionS newtok[3];
3431 struct alpha_insn insn;
3432
3433 if (ntok == 2)
3434 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3435 else
3436 basereg = tok[2].X_add_number;
3437
3438 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3439 &newtok[1]);
3440
3441 newtok[0] = tok[0];
3442 set_tok_preg (newtok[2], basereg);
3443
3444 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3445
3446 if (lituse)
3447 {
3448 assert (insn.nfixups < MAX_INSN_FIXUPS);
3449 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3450 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3451 insn.nfixups++;
3452 insn.sequence = lituse;
3453 }
3454
3455 emit_insn (&insn);
3456}
3457
3458/* Handle fp register loads, and both integer and fp register stores.
3459 Again, we handle simple expressions. */
3460
3461static void
3462emit_loadstore (tok, ntok, opname)
3463 const expressionS *tok;
3464 int ntok;
3465 const PTR opname;
3466{
3467 int basereg;
3468 long lituse;
3469 expressionS newtok[3];
3470 struct alpha_insn insn;
3471
3472 if (ntok == 2)
3473 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3474 else
3475 basereg = tok[2].X_add_number;
3476
3477 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3478 {
3479 if (alpha_noat_on)
3480 as_bad (_("macro requires $at register while noat in effect"));
3481
3482 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3483 }
3484 else
3485 {
3486 newtok[1] = tok[1];
3487 lituse = 0;
3488 }
3489
3490 newtok[0] = tok[0];
3491 set_tok_preg (newtok[2], basereg);
3492
3493 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3494
3495 if (lituse)
3496 {
3497 assert (insn.nfixups < MAX_INSN_FIXUPS);
3498 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3499 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3500 insn.nfixups++;
3501 insn.sequence = lituse;
3502 }
3503
3504 emit_insn (&insn);
3505}
3506
3507/* Load a half-word or byte as an unsigned value. */
3508
3509static void
3510emit_ldXu (tok, ntok, vlgsize)
3511 const expressionS *tok;
3512 int ntok;
3513 const PTR vlgsize;
3514{
3515 if (alpha_target & AXP_OPCODE_BWX)
3516 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3517 else
3518 {
3519 expressionS newtok[3];
3520 struct alpha_insn insn;
3521 int basereg;
3522 long lituse;
3523
3524 if (alpha_noat_on)
3525 as_bad (_("macro requires $at register while noat in effect"));
3526
3527 if (ntok == 2)
3528 basereg = (tok[1].X_op == O_constant
3529 ? AXP_REG_ZERO : alpha_gp_register);
3530 else
3531 basereg = tok[2].X_add_number;
3532
3533 /* emit "lda $at, exp" */
3534
3535 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3536
3537 /* emit "ldq_u targ, 0($at)" */
3538
3539 newtok[0] = tok[0];
3540 set_tok_const (newtok[1], 0);
3541 set_tok_preg (newtok[2], basereg);
3542 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3543
3544 if (lituse)
3545 {
3546 assert (insn.nfixups < MAX_INSN_FIXUPS);
3547 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3548 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3549 insn.nfixups++;
3550 insn.sequence = lituse;
3551 }
3552
3553 emit_insn (&insn);
3554
3555 /* emit "extXl targ, $at, targ" */
3556
3557 set_tok_reg (newtok[1], basereg);
3558 newtok[2] = newtok[0];
3559 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3560
3561 if (lituse)
3562 {
3563 assert (insn.nfixups < MAX_INSN_FIXUPS);
3564 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3565 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3566 insn.nfixups++;
3567 insn.sequence = lituse;
3568 }
3569
3570 emit_insn (&insn);
3571 }
3572}
3573
3574/* Load a half-word or byte as a signed value. */
3575
3576static void
3577emit_ldX (tok, ntok, vlgsize)
3578 const expressionS *tok;
3579 int ntok;
3580 const PTR vlgsize;
3581{
3582 emit_ldXu (tok, ntok, vlgsize);
3583 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3584}
3585
3586/* Load an integral value from an unaligned address as an unsigned
3587 value. */
3588
3589static void
3590emit_uldXu (tok, ntok, vlgsize)
3591 const expressionS *tok;
3592 int ntok;
3593 const PTR vlgsize;
3594{
3595 long lgsize = (long) vlgsize;
3596 expressionS newtok[3];
3597
3598 if (alpha_noat_on)
3599 as_bad (_("macro requires $at register while noat in effect"));
3600
3601 /* emit "lda $at, exp" */
3602
3603 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3604 newtok[0].X_add_number = AXP_REG_AT;
3605 assemble_tokens ("lda", newtok, ntok, 1);
3606
3607 /* emit "ldq_u $t9, 0($at)" */
3608
3609 set_tok_reg (newtok[0], AXP_REG_T9);
3610 set_tok_const (newtok[1], 0);
3611 set_tok_preg (newtok[2], AXP_REG_AT);
3612 assemble_tokens ("ldq_u", newtok, 3, 1);
3613
3614 /* emit "ldq_u $t10, size-1($at)" */
3615
3616 set_tok_reg (newtok[0], AXP_REG_T10);
3617 set_tok_const (newtok[1], (1 << lgsize) - 1);
3618 assemble_tokens ("ldq_u", newtok, 3, 1);
3619
3620 /* emit "extXl $t9, $at, $t9" */
3621
3622 set_tok_reg (newtok[0], AXP_REG_T9);
3623 set_tok_reg (newtok[1], AXP_REG_AT);
3624 set_tok_reg (newtok[2], AXP_REG_T9);
3625 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3626
3627 /* emit "extXh $t10, $at, $t10" */
3628
3629 set_tok_reg (newtok[0], AXP_REG_T10);
3630 set_tok_reg (newtok[2], AXP_REG_T10);
3631 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3632
3633 /* emit "or $t9, $t10, targ" */
3634
3635 set_tok_reg (newtok[0], AXP_REG_T9);
3636 set_tok_reg (newtok[1], AXP_REG_T10);
3637 newtok[2] = tok[0];
3638 assemble_tokens ("or", newtok, 3, 1);
3639}
3640
3641/* Load an integral value from an unaligned address as a signed value.
3642 Note that quads should get funneled to the unsigned load since we
3643 don't have to do the sign extension. */
3644
3645static void
3646emit_uldX (tok, ntok, vlgsize)
3647 const expressionS *tok;
3648 int ntok;
3649 const PTR vlgsize;
3650{
3651 emit_uldXu (tok, ntok, vlgsize);
3652 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3653}
3654
3655/* Implement the ldil macro. */
3656
3657static void
3658emit_ldil (tok, ntok, unused)
3659 const expressionS *tok;
3660 int ntok;
3661 const PTR unused ATTRIBUTE_UNUSED;
3662{
3663 expressionS newtok[2];
3664
3665 memcpy (newtok, tok, sizeof (newtok));
3666 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3667
3668 assemble_tokens ("lda", newtok, ntok, 1);
3669}
3670
3671/* Store a half-word or byte. */
3672
3673static void
3674emit_stX (tok, ntok, vlgsize)
3675 const expressionS *tok;
3676 int ntok;
3677 const PTR vlgsize;
3678{
3679 int lgsize = (int) (long) vlgsize;
3680
3681 if (alpha_target & AXP_OPCODE_BWX)
3682 emit_loadstore (tok, ntok, stX_op[lgsize]);
3683 else
3684 {
3685 expressionS newtok[3];
3686 struct alpha_insn insn;
3687 int basereg;
3688 long lituse;
3689
3690 if (alpha_noat_on)
3691 as_bad (_("macro requires $at register while noat in effect"));
3692
3693 if (ntok == 2)
3694 basereg = (tok[1].X_op == O_constant
3695 ? AXP_REG_ZERO : alpha_gp_register);
3696 else
3697 basereg = tok[2].X_add_number;
3698
3699 /* emit "lda $at, exp" */
3700
3701 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3702
3703 /* emit "ldq_u $t9, 0($at)" */
3704
3705 set_tok_reg (newtok[0], AXP_REG_T9);
3706 set_tok_const (newtok[1], 0);
3707 set_tok_preg (newtok[2], basereg);
3708 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3709
3710 if (lituse)
3711 {
3712 assert (insn.nfixups < MAX_INSN_FIXUPS);
3713 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3714 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3715 insn.nfixups++;
3716 insn.sequence = lituse;
3717 }
3718
3719 emit_insn (&insn);
3720
3721 /* emit "insXl src, $at, $t10" */
3722
3723 newtok[0] = tok[0];
3724 set_tok_reg (newtok[1], basereg);
3725 set_tok_reg (newtok[2], AXP_REG_T10);
3726 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3727
3728 if (lituse)
3729 {
3730 assert (insn.nfixups < MAX_INSN_FIXUPS);
3731 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3732 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3733 insn.nfixups++;
3734 insn.sequence = lituse;
3735 }
3736
3737 emit_insn (&insn);
3738
3739 /* emit "mskXl $t9, $at, $t9" */
3740
3741 set_tok_reg (newtok[0], AXP_REG_T9);
3742 newtok[2] = newtok[0];
3743 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3744
3745 if (lituse)
3746 {
3747 assert (insn.nfixups < MAX_INSN_FIXUPS);
3748 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3749 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3750 insn.nfixups++;
3751 insn.sequence = lituse;
3752 }
3753
3754 emit_insn (&insn);
3755
3756 /* emit "or $t9, $t10, $t9" */
3757
3758 set_tok_reg (newtok[1], AXP_REG_T10);
3759 assemble_tokens ("or", newtok, 3, 1);
3760
3761 /* emit "stq_u $t9, 0($at) */
3762
3763 set_tok_const(newtok[1], 0);
3764 set_tok_preg (newtok[2], AXP_REG_AT);
3765 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3766
3767 if (lituse)
3768 {
3769 assert (insn.nfixups < MAX_INSN_FIXUPS);
3770 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3771 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3772 insn.nfixups++;
3773 insn.sequence = lituse;
3774 }
3775
3776 emit_insn (&insn);
3777 }
3778}
3779
3780/* Store an integer to an unaligned address. */
3781
3782static void
3783emit_ustX (tok, ntok, vlgsize)
3784 const expressionS *tok;
3785 int ntok;
3786 const PTR vlgsize;
3787{
3788 int lgsize = (int) (long) vlgsize;
3789 expressionS newtok[3];
3790
3791 /* emit "lda $at, exp" */
3792
3793 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3794 newtok[0].X_add_number = AXP_REG_AT;
3795 assemble_tokens ("lda", newtok, ntok, 1);
3796
3797 /* emit "ldq_u $9, 0($at)" */
3798
3799 set_tok_reg (newtok[0], AXP_REG_T9);
3800 set_tok_const (newtok[1], 0);
3801 set_tok_preg (newtok[2], AXP_REG_AT);
3802 assemble_tokens ("ldq_u", newtok, 3, 1);
3803
3804 /* emit "ldq_u $10, size-1($at)" */
3805
3806 set_tok_reg (newtok[0], AXP_REG_T10);
3807 set_tok_const (newtok[1], (1 << lgsize) - 1);
3808 assemble_tokens ("ldq_u", newtok, 3, 1);
3809
3810 /* emit "insXl src, $at, $t11" */
3811
3812 newtok[0] = tok[0];
3813 set_tok_reg (newtok[1], AXP_REG_AT);
3814 set_tok_reg (newtok[2], AXP_REG_T11);
3815 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3816
3817 /* emit "insXh src, $at, $t12" */
3818
3819 set_tok_reg (newtok[2], AXP_REG_T12);
3820 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3821
3822 /* emit "mskXl $t9, $at, $t9" */
3823
3824 set_tok_reg (newtok[0], AXP_REG_T9);
3825 newtok[2] = newtok[0];
3826 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3827
3828 /* emit "mskXh $t10, $at, $t10" */
3829
3830 set_tok_reg (newtok[0], AXP_REG_T10);
3831 newtok[2] = newtok[0];
3832 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3833
3834 /* emit "or $t9, $t11, $t9" */
3835
3836 set_tok_reg (newtok[0], AXP_REG_T9);
3837 set_tok_reg (newtok[1], AXP_REG_T11);
3838 newtok[2] = newtok[0];
3839 assemble_tokens ("or", newtok, 3, 1);
3840
3841 /* emit "or $t10, $t12, $t10" */
3842
3843 set_tok_reg (newtok[0], AXP_REG_T10);
3844 set_tok_reg (newtok[1], AXP_REG_T12);
3845 newtok[2] = newtok[0];
3846 assemble_tokens ("or", newtok, 3, 1);
3847
3848 /* emit "stq_u $t9, 0($at)" */
3849
3850 set_tok_reg (newtok[0], AXP_REG_T9);
3851 set_tok_const (newtok[1], 0);
3852 set_tok_preg (newtok[2], AXP_REG_AT);
3853 assemble_tokens ("stq_u", newtok, 3, 1);
3854
3855 /* emit "stq_u $t10, size-1($at)" */
3856
3857 set_tok_reg (newtok[0], AXP_REG_T10);
3858 set_tok_const (newtok[1], (1 << lgsize) - 1);
3859 assemble_tokens ("stq_u", newtok, 3, 1);
3860}
3861
3862/* Sign extend a half-word or byte. The 32-bit sign extend is
3863 implemented as "addl $31, $r, $t" in the opcode table. */
3864
3865static void
3866emit_sextX (tok, ntok, vlgsize)
3867 const expressionS *tok;
3868 int ntok;
3869 const PTR vlgsize;
3870{
3871 long lgsize = (long) vlgsize;
3872
3873 if (alpha_target & AXP_OPCODE_BWX)
3874 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3875 else
3876 {
3877 int bitshift = 64 - 8 * (1 << lgsize);
3878 expressionS newtok[3];
3879
3880 /* emit "sll src,bits,dst" */
3881
3882 newtok[0] = tok[0];
3883 set_tok_const (newtok[1], bitshift);
3884 newtok[2] = tok[ntok - 1];
3885 assemble_tokens ("sll", newtok, 3, 1);
3886
3887 /* emit "sra dst,bits,dst" */
3888
3889 newtok[0] = newtok[2];
3890 assemble_tokens ("sra", newtok, 3, 1);
3891 }
3892}
3893
3894/* Implement the division and modulus macros. */
3895
3896#ifdef OBJ_EVAX
3897
3898/* Make register usage like in normal procedure call.
3899 Don't clobber PV and RA. */
3900
3901static void
3902emit_division (tok, ntok, symname)
3903 const expressionS *tok;
3904 int ntok;
3905 const PTR symname;
3906{
3907 /* DIVISION and MODULUS. Yech.
3908
3909 Convert
3910 OP x,y,result
3911 to
3912 mov x,R16 # if x != R16
3913 mov y,R17 # if y != R17
3914 lda AT,__OP
3915 jsr AT,(AT),0
3916 mov R0,result
3917
3918 with appropriate optimizations if R0,R16,R17 are the registers
3919 specified by the compiler. */
3920
3921 int xr, yr, rr;
3922 symbolS *sym;
3923 expressionS newtok[3];
3924
3925 xr = regno (tok[0].X_add_number);
3926 yr = regno (tok[1].X_add_number);
3927
3928 if (ntok < 3)
3929 rr = xr;
3930 else
3931 rr = regno (tok[2].X_add_number);
3932
3933 /* Move the operands into the right place. */
3934 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3935 {
3936 /* They are in exactly the wrong order -- swap through AT. */
3937
3938 if (alpha_noat_on)
3939 as_bad (_("macro requires $at register while noat in effect"));
3940
3941 set_tok_reg (newtok[0], AXP_REG_R16);
3942 set_tok_reg (newtok[1], AXP_REG_AT);
3943 assemble_tokens ("mov", newtok, 2, 1);
3944
3945 set_tok_reg (newtok[0], AXP_REG_R17);
3946 set_tok_reg (newtok[1], AXP_REG_R16);
3947 assemble_tokens ("mov", newtok, 2, 1);
3948
3949 set_tok_reg (newtok[0], AXP_REG_AT);
3950 set_tok_reg (newtok[1], AXP_REG_R17);
3951 assemble_tokens ("mov", newtok, 2, 1);
3952 }
3953 else
3954 {
3955 if (yr == AXP_REG_R16)
3956 {
3957 set_tok_reg (newtok[0], AXP_REG_R16);
3958 set_tok_reg (newtok[1], AXP_REG_R17);
3959 assemble_tokens ("mov", newtok, 2, 1);
3960 }
3961
3962 if (xr != AXP_REG_R16)
3963 {
3964 set_tok_reg (newtok[0], xr);
3965 set_tok_reg (newtok[1], AXP_REG_R16);
3966 assemble_tokens ("mov", newtok, 2, 1);
3967 }
3968
3969 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3970 {
3971 set_tok_reg (newtok[0], yr);
3972 set_tok_reg (newtok[1], AXP_REG_R17);
3973 assemble_tokens ("mov", newtok, 2, 1);
3974 }
3975 }
3976
3977 sym = symbol_find_or_make ((const char *) symname);
3978
3979 set_tok_reg (newtok[0], AXP_REG_AT);
3980 set_tok_sym (newtok[1], sym, 0);
3981 assemble_tokens ("lda", newtok, 2, 1);
3982
3983 /* Call the division routine. */
3984 set_tok_reg (newtok[0], AXP_REG_AT);
3985 set_tok_cpreg (newtok[1], AXP_REG_AT);
3986 set_tok_const (newtok[2], 0);
3987 assemble_tokens ("jsr", newtok, 3, 1);
3988
3989 /* Move the result to the right place. */
3990 if (rr != AXP_REG_R0)
3991 {
3992 set_tok_reg (newtok[0], AXP_REG_R0);
3993 set_tok_reg (newtok[1], rr);
3994 assemble_tokens ("mov", newtok, 2, 1);
3995 }
3996}
3997
3998#else /* !OBJ_EVAX */
3999
4000static void
4001emit_division (tok, ntok, symname)
4002 const expressionS *tok;
4003 int ntok;
4004 const PTR symname;
4005{
4006 /* DIVISION and MODULUS. Yech.
4007 Convert
4008 OP x,y,result
4009 to
4010 lda pv,__OP
4011 mov x,t10
4012 mov y,t11
4013 jsr t9,(pv),__OP
4014 mov t12,result
4015
4016 with appropriate optimizations if t10,t11,t12 are the registers
4017 specified by the compiler. */
4018
4019 int xr, yr, rr;
4020 symbolS *sym;
4021 expressionS newtok[3];
4022
4023 xr = regno (tok[0].X_add_number);
4024 yr = regno (tok[1].X_add_number);
4025
4026 if (ntok < 3)
4027 rr = xr;
4028 else
4029 rr = regno (tok[2].X_add_number);
4030
4031 sym = symbol_find_or_make ((const char *) symname);
4032
4033 /* Move the operands into the right place. */
4034 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
4035 {
4036 /* They are in exactly the wrong order -- swap through AT. */
4037 if (alpha_noat_on)
4038 as_bad (_("macro requires $at register while noat in effect"));
4039
4040 set_tok_reg (newtok[0], AXP_REG_T10);
4041 set_tok_reg (newtok[1], AXP_REG_AT);
4042 assemble_tokens ("mov", newtok, 2, 1);
4043
4044 set_tok_reg (newtok[0], AXP_REG_T11);
4045 set_tok_reg (newtok[1], AXP_REG_T10);
4046 assemble_tokens ("mov", newtok, 2, 1);
4047
4048 set_tok_reg (newtok[0], AXP_REG_AT);
4049 set_tok_reg (newtok[1], AXP_REG_T11);
4050 assemble_tokens ("mov", newtok, 2, 1);
4051 }
4052 else
4053 {
4054 if (yr == AXP_REG_T10)
4055 {
4056 set_tok_reg (newtok[0], AXP_REG_T10);
4057 set_tok_reg (newtok[1], AXP_REG_T11);
4058 assemble_tokens ("mov", newtok, 2, 1);
4059 }
4060
4061 if (xr != AXP_REG_T10)
4062 {
4063 set_tok_reg (newtok[0], xr);
4064 set_tok_reg (newtok[1], AXP_REG_T10);
4065 assemble_tokens ("mov", newtok, 2, 1);
4066 }
4067
4068 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
4069 {
4070 set_tok_reg (newtok[0], yr);
4071 set_tok_reg (newtok[1], AXP_REG_T11);
4072 assemble_tokens ("mov", newtok, 2, 1);
4073 }
4074 }
4075
4076 /* Call the division routine. */
4077 set_tok_reg (newtok[0], AXP_REG_T9);
4078 set_tok_sym (newtok[1], sym, 0);
4079 assemble_tokens ("jsr", newtok, 2, 1);
4080
4081 /* Reload the GP register. */
4082#ifdef OBJ_AOUT
4083FIXME
4084#endif
4085#if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4086 set_tok_reg (newtok[0], alpha_gp_register);
4087 set_tok_const (newtok[1], 0);
4088 set_tok_preg (newtok[2], AXP_REG_T9);
4089 assemble_tokens ("ldgp", newtok, 3, 1);
4090#endif
4091
4092 /* Move the result to the right place. */
4093 if (rr != AXP_REG_T12)
4094 {
4095 set_tok_reg (newtok[0], AXP_REG_T12);
4096 set_tok_reg (newtok[1], rr);
4097 assemble_tokens ("mov", newtok, 2, 1);
4098 }
4099}
4100
4101#endif /* !OBJ_EVAX */
4102
4103/* The jsr and jmp macros differ from their instruction counterparts
4104 in that they can load the target address and default most
4105 everything. */
4106
4107static void
4108emit_jsrjmp (tok, ntok, vopname)
4109 const expressionS *tok;
4110 int ntok;
4111 const PTR vopname;
4112{
4113 const char *opname = (const char *) vopname;
4114 struct alpha_insn insn;
4115 expressionS newtok[3];
4116 int r, tokidx = 0;
4117 long lituse = 0;
4118
4119 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4120 r = regno (tok[tokidx++].X_add_number);
4121 else
4122 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
4123
4124 set_tok_reg (newtok[0], r);
4125
4126 if (tokidx < ntok &&
4127 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4128 r = regno (tok[tokidx++].X_add_number);
4129#ifdef OBJ_EVAX
4130 /* keep register if jsr $n.<sym> */
4131#else
4132 else
4133 {
4134 int basereg = alpha_gp_register;
4135 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
4136 }
4137#endif
4138
4139 set_tok_cpreg (newtok[1], r);
4140
4141#ifdef OBJ_EVAX
4142 /* FIXME: Add hint relocs to BFD for evax. */
4143#else
4144 if (tokidx < ntok)
4145 newtok[2] = tok[tokidx];
4146 else
4147#endif
4148 set_tok_const (newtok[2], 0);
4149
4150 assemble_tokens_to_insn (opname, newtok, 3, &insn);
4151
4152 if (lituse)
4153 {
4154 assert (insn.nfixups < MAX_INSN_FIXUPS);
4155 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
4156 insn.fixups[insn.nfixups].exp.X_op = O_absent;
4157 insn.nfixups++;
4158 insn.sequence = lituse;
4159 }
4160
4161 emit_insn (&insn);
4162}
4163
4164/* The ret and jcr instructions differ from their instruction
4165 counterparts in that everything can be defaulted. */
4166
4167static void
4168emit_retjcr (tok, ntok, vopname)
4169 const expressionS *tok;
4170 int ntok;
4171 const PTR vopname;
4172{
4173 const char *opname = (const char *) vopname;
4174 expressionS newtok[3];
4175 int r, tokidx = 0;
4176
4177 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4178 r = regno (tok[tokidx++].X_add_number);
4179 else
4180 r = AXP_REG_ZERO;
4181
4182 set_tok_reg (newtok[0], r);
4183
4184 if (tokidx < ntok &&
4185 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4186 r = regno (tok[tokidx++].X_add_number);
4187 else
4188 r = AXP_REG_RA;
4189
4190 set_tok_cpreg (newtok[1], r);
4191
4192 if (tokidx < ntok)
4193 newtok[2] = tok[tokidx];
4194 else
4195 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
4196
4197 assemble_tokens (opname, newtok, 3, 0);
4198}
4199
4200
4201/* Assembler directives. */
4202
4203/* Handle the .text pseudo-op. This is like the usual one, but it
4204 clears alpha_insn_label and restores auto alignment. */
4205
4206static void
4207s_alpha_text (i)
4208 int i;
4209
4210{
4211#ifdef OBJ_ELF
4212 obj_elf_text (i);
4213#else
4214 s_text (i);
4215#endif
4216 alpha_insn_label = NULL;
4217 alpha_auto_align_on = 1;
4218 alpha_current_align = 0;
4219}
4220
4221/* Handle the .data pseudo-op. This is like the usual one, but it
4222 clears alpha_insn_label and restores auto alignment. */
4223
4224static void
4225s_alpha_data (i)
4226 int i;
4227{
4228#ifdef OBJ_ELF
4229 obj_elf_data (i);
4230#else
4231 s_data (i);
4232#endif
4233 alpha_insn_label = NULL;
4234 alpha_auto_align_on = 1;
4235 alpha_current_align = 0;
4236}
4237
4238#if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4239
4240/* Handle the OSF/1 and openVMS .comm pseudo quirks.
4241 openVMS constructs a section for every common symbol. */
4242
4243static void
4244s_alpha_comm (ignore)
4245 int ignore ATTRIBUTE_UNUSED;
4246{
4247 register char *name;
4248 register char c;
4249 register char *p;
4250 offsetT temp;
4251 register symbolS *symbolP;
4252
4253#ifdef OBJ_EVAX
4254 segT current_section = now_seg;
4255 int current_subsec = now_subseg;
4256 segT new_seg;
4257#endif
4258
4259 name = input_line_pointer;
4260 c = get_symbol_end ();
4261
4262 /* just after name is now '\0' */
4263 p = input_line_pointer;
4264 *p = c;
4265
4266 SKIP_WHITESPACE ();
4267
4268 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4269 if (*input_line_pointer == ',')
4270 {
4271 input_line_pointer++;
4272 SKIP_WHITESPACE ();
4273 }
4274 if ((temp = get_absolute_expression ()) < 0)
4275 {
4276 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4277 ignore_rest_of_line ();
4278 return;
4279 }
4280
4281 *p = 0;
4282 symbolP = symbol_find_or_make (name);
4283
4284#ifdef OBJ_EVAX
4285 /* Make a section for the common symbol. */
4286 new_seg = subseg_new (xstrdup (name), 0);
4287#endif
4288
4289 *p = c;
4290
4291#ifdef OBJ_EVAX
4292 /* alignment might follow */
4293 if (*input_line_pointer == ',')
4294 {
4295 offsetT align;
4296
4297 input_line_pointer++;
4298 align = get_absolute_expression ();
4299 bfd_set_section_alignment (stdoutput, new_seg, align);
4300 }
4301#endif
4302
4303 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4304 {
4305 as_bad (_("Ignoring attempt to re-define symbol"));
4306 ignore_rest_of_line ();
4307 return;
4308 }
4309
4310#ifdef OBJ_EVAX
4311 if (bfd_section_size (stdoutput, new_seg) > 0)
4312 {
4313 if (bfd_section_size (stdoutput, new_seg) != temp)
4314 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4315 S_GET_NAME (symbolP),
4316 (long) bfd_section_size (stdoutput, new_seg),
4317 (long) temp);
4318 }
4319#else
4320 if (S_GET_VALUE (symbolP))
4321 {
4322 if (S_GET_VALUE (symbolP) != (valueT) temp)
4323 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4324 S_GET_NAME (symbolP),
4325 (long) S_GET_VALUE (symbolP),
4326 (long) temp);
4327 }
4328#endif
4329 else
4330 {
4331#ifdef OBJ_EVAX
4332 subseg_set (new_seg, 0);
4333 p = frag_more (temp);
4334 new_seg->flags |= SEC_IS_COMMON;
4335 if (! S_IS_DEFINED (symbolP))
4336 S_SET_SEGMENT (symbolP, new_seg);
4337#else
4338 S_SET_VALUE (symbolP, (valueT) temp);
4339#endif
4340 S_SET_EXTERNAL (symbolP);
4341 }
4342
4343#ifdef OBJ_EVAX
4344 subseg_set (current_section, current_subsec);
4345#endif
4346
4347 know (symbol_get_frag (symbolP) == &zero_address_frag);
4348
4349 demand_empty_rest_of_line ();
4350}
4351
4352#endif /* ! OBJ_ELF */
4353
4354#ifdef OBJ_ECOFF
4355
4356/* Handle the .rdata pseudo-op. This is like the usual one, but it
4357 clears alpha_insn_label and restores auto alignment. */
4358
4359static void
4360s_alpha_rdata (ignore)
4361 int ignore ATTRIBUTE_UNUSED;
4362{
4363 int temp;
4364
4365 temp = get_absolute_expression ();
4366 subseg_new (".rdata", 0);
4367 demand_empty_rest_of_line ();
4368 alpha_insn_label = NULL;
4369 alpha_auto_align_on = 1;
4370 alpha_current_align = 0;
4371}
4372
4373#endif
4374
4375#ifdef OBJ_ECOFF
4376
4377/* Handle the .sdata pseudo-op. This is like the usual one, but it
4378 clears alpha_insn_label and restores auto alignment. */
4379
4380static void
4381s_alpha_sdata (ignore)
4382 int ignore ATTRIBUTE_UNUSED;
4383{
4384 int temp;
4385
4386 temp = get_absolute_expression ();
4387 subseg_new (".sdata", 0);
4388 demand_empty_rest_of_line ();
4389 alpha_insn_label = NULL;
4390 alpha_auto_align_on = 1;
4391 alpha_current_align = 0;
4392}
4393#endif
4394
4395#ifdef OBJ_ELF
4396
4397/* Handle the .section pseudo-op. This is like the usual one, but it
4398 clears alpha_insn_label and restores auto alignment. */
4399
4400static void
4401s_alpha_section (ignore)
4402 int ignore ATTRIBUTE_UNUSED;
4403{
4404 obj_elf_section (ignore);
4405
4406 alpha_insn_label = NULL;
4407 alpha_auto_align_on = 1;
4408 alpha_current_align = 0;
4409}
4410
4411static void
4412s_alpha_ent (dummy)
4413 int dummy ATTRIBUTE_UNUSED;
4414{
4415 if (ECOFF_DEBUGGING)
4416 ecoff_directive_ent (0);
4417 else
4418 {
4419 char *name, name_end;
4420 name = input_line_pointer;
4421 name_end = get_symbol_end ();
4422
4423 if (! is_name_beginner (*name))
4424 {
4425 as_warn (_(".ent directive has no name"));
4426 *input_line_pointer = name_end;
4427 }
4428 else
4429 {
4430 symbolS *sym;
4431
4432 if (alpha_cur_ent_sym)
4433 as_warn (_("nested .ent directives"));
4434
4435 sym = symbol_find_or_make (name);
4436 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4437 alpha_cur_ent_sym = sym;
4438
4439 /* The .ent directive is sometimes followed by a number. Not sure
4440 what it really means, but ignore it. */
4441 *input_line_pointer = name_end;
4442 SKIP_WHITESPACE ();
4443 if (*input_line_pointer == ',')
4444 {
4445 input_line_pointer++;
4446 SKIP_WHITESPACE ();
4447 }
4448 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4449 (void) get_absolute_expression ();
4450 }
4451 demand_empty_rest_of_line ();
4452 }
4453}
4454
4455static void
4456s_alpha_end (dummy)
4457 int dummy ATTRIBUTE_UNUSED;
4458{
4459 if (ECOFF_DEBUGGING)
4460 ecoff_directive_end (0);
4461 else
4462 {
4463 char *name, name_end;
4464 name = input_line_pointer;
4465 name_end = get_symbol_end ();
4466
4467 if (! is_name_beginner (*name))
4468 {
4469 as_warn (_(".end directive has no name"));
4470 *input_line_pointer = name_end;
4471 }
4472 else
4473 {
4474 symbolS *sym;
4475
4476 sym = symbol_find (name);
4477 if (sym != alpha_cur_ent_sym)
4478 as_warn (_(".end directive names different symbol than .ent"));
4479
4480 /* Create an expression to calculate the size of the function. */
4481 if (sym)
4482 {
4483 symbol_get_obj (sym)->size =
4484 (expressionS *) xmalloc (sizeof (expressionS));
4485 symbol_get_obj (sym)->size->X_op = O_subtract;
4486 symbol_get_obj (sym)->size->X_add_symbol
4487 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4488 symbol_get_obj (sym)->size->X_op_symbol = sym;
4489 symbol_get_obj (sym)->size->X_add_number = 0;
4490 }
4491
4492 alpha_cur_ent_sym = NULL;
4493
4494 *input_line_pointer = name_end;
4495 }
4496 demand_empty_rest_of_line ();
4497 }
4498}
4499
4500static void
4501s_alpha_mask (fp)
4502 int fp;
4503{
4504 if (ECOFF_DEBUGGING)
4505 {
4506 if (fp)
4507 ecoff_directive_fmask (0);
4508 else
4509 ecoff_directive_mask (0);
4510 }
4511 else
4512 discard_rest_of_line ();
4513}
4514
4515static void
4516s_alpha_frame (dummy)
4517 int dummy ATTRIBUTE_UNUSED;
4518{
4519 if (ECOFF_DEBUGGING)
4520 ecoff_directive_frame (0);
4521 else
4522 discard_rest_of_line ();
4523}
4524
4525static void
4526s_alpha_prologue (ignore)
4527 int ignore ATTRIBUTE_UNUSED;
4528{
4529 symbolS *sym;
4530 int arg;
4531
4532 arg = get_absolute_expression ();
4533 demand_empty_rest_of_line ();
4534
4535 if (ECOFF_DEBUGGING)
4536 sym = ecoff_get_cur_proc_sym ();
4537 else
4538 sym = alpha_cur_ent_sym;
4539
4540 if (sym == NULL)
4541 {
4542 as_bad (_(".prologue directive without a preceding .ent directive"));
4543 return;
4544 }
4545
4546 switch (arg)
4547 {
4548 case 0: /* No PV required. */
4549 S_SET_OTHER (sym, STO_ALPHA_NOPV
4550 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4551 break;
4552 case 1: /* Std GP load. */
4553 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4554 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4555 break;
4556 case 2: /* Non-std use of PV. */
4557 break;
4558
4559 default:
4560 as_bad (_("Invalid argument %d to .prologue."), arg);
4561 break;
4562 }
4563}
4564
4565static char *first_file_directive;
4566
4567static void
4568s_alpha_file (ignore)
4569 int ignore ATTRIBUTE_UNUSED;
4570{
4571 /* Save the first .file directive we see, so that we can change our
4572 minds about whether ecoff debugging should or shouldn't be enabled. */
4573 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4574 {
4575 char *start = input_line_pointer;
4576 size_t len;
4577
4578 discard_rest_of_line ();
4579
4580 len = input_line_pointer - start;
4581 first_file_directive = xmalloc (len + 1);
4582 memcpy (first_file_directive, start, len);
4583 first_file_directive[len] = '\0';
4584
4585 input_line_pointer = start;
4586 }
4587
4588 if (ECOFF_DEBUGGING)
4589 ecoff_directive_file (0);
4590 else
4591 dwarf2_directive_file (0);
4592}
4593
4594static void
4595s_alpha_loc (ignore)
4596 int ignore ATTRIBUTE_UNUSED;
4597{
4598 if (ECOFF_DEBUGGING)
4599 ecoff_directive_loc (0);
4600 else
4601 dwarf2_directive_loc (0);
4602}
4603
4604static void
4605s_alpha_stab (n)
4606 int n;
4607{
4608 /* If we've been undecided about mdebug, make up our minds in favour. */
4609 if (alpha_flag_mdebug < 0)
4610 {
4611 segT sec = subseg_new (".mdebug", 0);
4612 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4613 bfd_set_section_alignment (stdoutput, sec, 3);
4614
4615 ecoff_read_begin_hook ();
4616
4617 if (first_file_directive)
4618 {
4619 char *save_ilp = input_line_pointer;
4620 input_line_pointer = first_file_directive;
4621 ecoff_directive_file (0);
4622 input_line_pointer = save_ilp;
4623 free (first_file_directive);
4624 }
4625
4626 alpha_flag_mdebug = 1;
4627 }
4628 s_stab (n);
4629}
4630
4631static void
4632s_alpha_coff_wrapper (which)
4633 int which;
4634{
4635 static void (* const fns[]) PARAMS ((int)) = {
4636 ecoff_directive_begin,
4637 ecoff_directive_bend,
4638 ecoff_directive_def,
4639 ecoff_directive_dim,
4640 ecoff_directive_endef,
4641 ecoff_directive_scl,
4642 ecoff_directive_tag,
4643 ecoff_directive_val,
4644 };
4645
4646 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4647
4648 if (ECOFF_DEBUGGING)
4649 (*fns[which]) (0);
4650 else
4651 {
4652 as_bad (_("ECOFF debugging is disabled."));
4653 ignore_rest_of_line ();
4654 }
4655}
4656#endif /* OBJ_ELF */
4657
4658#ifdef OBJ_EVAX
4659
4660/* Handle the section specific pseudo-op. */
4661
4662static void
4663s_alpha_section (secid)
4664 int secid;
4665{
4666 int temp;
4667#define EVAX_SECTION_COUNT 5
4668 static char *section_name[EVAX_SECTION_COUNT + 1] =
4669 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4670
4671 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4672 {
4673 as_fatal (_("Unknown section directive"));
4674 demand_empty_rest_of_line ();
4675 return;
4676 }
4677 temp = get_absolute_expression ();
4678 subseg_new (section_name[secid], 0);
4679 demand_empty_rest_of_line ();
4680 alpha_insn_label = NULL;
4681 alpha_auto_align_on = 1;
4682 alpha_current_align = 0;
4683}
4684
4685/* Parse .ent directives. */
4686
4687static void
4688s_alpha_ent (ignore)
4689 int ignore ATTRIBUTE_UNUSED;
4690{
4691 symbolS *symbol;
4692 expressionS symexpr;
4693
4694 alpha_evax_proc.pdsckind = 0;
4695 alpha_evax_proc.framereg = -1;
4696 alpha_evax_proc.framesize = 0;
4697 alpha_evax_proc.rsa_offset = 0;
4698 alpha_evax_proc.ra_save = AXP_REG_RA;
4699 alpha_evax_proc.fp_save = -1;
4700 alpha_evax_proc.imask = 0;
4701 alpha_evax_proc.fmask = 0;
4702 alpha_evax_proc.prologue = 0;
4703 alpha_evax_proc.type = 0;
4704
4705 expression (&symexpr);
4706
4707 if (symexpr.X_op != O_symbol)
4708 {
4709 as_fatal (_(".ent directive has no symbol"));
4710 demand_empty_rest_of_line ();
4711 return;
4712 }
4713
4714 symbol = make_expr_symbol (&symexpr);
4715 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4716 alpha_evax_proc.symbol = symbol;
4717
4718 demand_empty_rest_of_line ();
4719 return;
4720}
4721
4722/* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4723
4724static void
4725s_alpha_frame (ignore)
4726 int ignore ATTRIBUTE_UNUSED;
4727{
4728 long val;
4729
4730 alpha_evax_proc.framereg = tc_get_register (1);
4731
4732 SKIP_WHITESPACE ();
4733 if (*input_line_pointer++ != ','
4734 || get_absolute_expression_and_terminator (&val) != ',')
4735 {
4736 as_warn (_("Bad .frame directive 1./2. param"));
4737 --input_line_pointer;
4738 demand_empty_rest_of_line ();
4739 return;
4740 }
4741
4742 alpha_evax_proc.framesize = val;
4743
4744 (void) tc_get_register (1);
4745 SKIP_WHITESPACE ();
4746 if (*input_line_pointer++ != ',')
4747 {
4748 as_warn (_("Bad .frame directive 3./4. param"));
4749 --input_line_pointer;
4750 demand_empty_rest_of_line ();
4751 return;
4752 }
4753 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4754
4755 return;
4756}
4757
4758static void
4759s_alpha_pdesc (ignore)
4760 int ignore ATTRIBUTE_UNUSED;
4761{
4762 char *name;
4763 char name_end;
4764 long val;
4765 register char *p;
4766 expressionS exp;
4767 symbolS *entry_sym;
4768 fixS *fixp;
4769 segment_info_type *seginfo = seg_info (alpha_link_section);
4770
4771 if (now_seg != alpha_link_section)
4772 {
4773 as_bad (_(".pdesc directive not in link (.link) section"));
4774 demand_empty_rest_of_line ();
4775 return;
4776 }
4777
4778 if ((alpha_evax_proc.symbol == 0)
4779 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4780 {
4781 as_fatal (_(".pdesc has no matching .ent"));
4782 demand_empty_rest_of_line ();
4783 return;
4784 }
4785
4786 *symbol_get_obj (alpha_evax_proc.symbol) =
4787 (valueT) seginfo->literal_pool_size;
4788
4789 expression (&exp);
4790 if (exp.X_op != O_symbol)
4791 {
4792 as_warn (_(".pdesc directive has no entry symbol"));
4793 demand_empty_rest_of_line ();
4794 return;
4795 }
4796
4797 entry_sym = make_expr_symbol (&exp);
4798 /* Save bfd symbol of proc desc in function symbol. */
4799 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4800 = symbol_get_bfdsym (entry_sym);
4801
4802 SKIP_WHITESPACE ();
4803 if (*input_line_pointer++ != ',')
4804 {
4805 as_warn (_("No comma after .pdesc <entryname>"));
4806 demand_empty_rest_of_line ();
4807 return;
4808 }
4809
4810 SKIP_WHITESPACE ();
4811 name = input_line_pointer;
4812 name_end = get_symbol_end ();
4813
4814 if (strncmp (name, "stack", 5) == 0)
4815 {
4816 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4817 }
4818 else if (strncmp (name, "reg", 3) == 0)
4819 {
4820 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4821 }
4822 else if (strncmp (name, "null", 4) == 0)
4823 {
4824 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4825 }
4826 else
4827 {
4828 as_fatal (_("unknown procedure kind"));
4829 demand_empty_rest_of_line ();
4830 return;
4831 }
4832
4833 *input_line_pointer = name_end;
4834 demand_empty_rest_of_line ();
4835
4836#ifdef md_flush_pending_output
4837 md_flush_pending_output ();
4838#endif
4839
4840 frag_align (3, 0, 0);
4841 p = frag_more (16);
4842 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4843 fixp->fx_done = 1;
4844 seginfo->literal_pool_size += 16;
4845
4846 *p = alpha_evax_proc.pdsckind
4847 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4848 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4849
4850 switch (alpha_evax_proc.pdsckind)
4851 {
4852 case PDSC_S_K_KIND_NULL:
4853 *(p + 2) = 0;
4854 *(p + 3) = 0;
4855 break;
4856 case PDSC_S_K_KIND_FP_REGISTER:
4857 *(p + 2) = alpha_evax_proc.fp_save;
4858 *(p + 3) = alpha_evax_proc.ra_save;
4859 break;
4860 case PDSC_S_K_KIND_FP_STACK:
4861 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4862 break;
4863 default: /* impossible */
4864 break;
4865 }
4866
4867 *(p + 4) = 0;
4868 *(p + 5) = alpha_evax_proc.type & 0x0f;
4869
4870 /* Signature offset. */
4871 md_number_to_chars (p + 6, (valueT) 0, 2);
4872
4873 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4874
4875 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4876 return;
4877
4878 /* Add dummy fix to make add_to_link_pool work. */
4879 p = frag_more (8);
4880 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4881 fixp->fx_done = 1;
4882 seginfo->literal_pool_size += 8;
4883
4884 /* pdesc+16: Size. */
4885 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4886
4887 md_number_to_chars (p + 4, (valueT) 0, 2);
4888
4889 /* Entry length. */
4890 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4891
4892 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4893 return;
4894
4895 /* Add dummy fix to make add_to_link_pool work. */
4896 p = frag_more (8);
4897 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4898 fixp->fx_done = 1;
4899 seginfo->literal_pool_size += 8;
4900
4901 /* pdesc+24: register masks. */
4902
4903 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4904 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4905
4906 return;
4907}
4908
4909/* Support for crash debug on vms. */
4910
4911static void
4912s_alpha_name (ignore)
4913 int ignore ATTRIBUTE_UNUSED;
4914{
4915 register char *p;
4916 expressionS exp;
4917 segment_info_type *seginfo = seg_info (alpha_link_section);
4918
4919 if (now_seg != alpha_link_section)
4920 {
4921 as_bad (_(".name directive not in link (.link) section"));
4922 demand_empty_rest_of_line ();
4923 return;
4924 }
4925
4926 expression (&exp);
4927 if (exp.X_op != O_symbol)
4928 {
4929 as_warn (_(".name directive has no symbol"));
4930 demand_empty_rest_of_line ();
4931 return;
4932 }
4933
4934 demand_empty_rest_of_line ();
4935
4936#ifdef md_flush_pending_output
4937 md_flush_pending_output ();
4938#endif
4939
4940 frag_align (3, 0, 0);
4941 p = frag_more (8);
4942 seginfo->literal_pool_size += 8;
4943
4944 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4945
4946 return;
4947}
4948
4949static void
4950s_alpha_linkage (ignore)
4951 int ignore ATTRIBUTE_UNUSED;
4952{
4953 expressionS exp;
4954 char *p;
4955
4956#ifdef md_flush_pending_output
4957 md_flush_pending_output ();
4958#endif
4959
4960 expression (&exp);
4961 if (exp.X_op != O_symbol)
4962 {
4963 as_fatal (_("No symbol after .linkage"));
4964 }
4965 else
4966 {
4967 p = frag_more (LKP_S_K_SIZE);
4968 memset (p, 0, LKP_S_K_SIZE);
4969 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4970 BFD_RELOC_ALPHA_LINKAGE);
4971 }
4972 demand_empty_rest_of_line ();
4973
4974 return;
4975}
4976
4977static void
4978s_alpha_code_address (ignore)
4979 int ignore ATTRIBUTE_UNUSED;
4980{
4981 expressionS exp;
4982 char *p;
4983
4984#ifdef md_flush_pending_output
4985 md_flush_pending_output ();
4986#endif
4987
4988 expression (&exp);
4989 if (exp.X_op != O_symbol)
4990 {
4991 as_fatal (_("No symbol after .code_address"));
4992 }
4993 else
4994 {
4995 p = frag_more (8);
4996 memset (p, 0, 8);
4997 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4998 BFD_RELOC_ALPHA_CODEADDR);
4999 }
5000 demand_empty_rest_of_line ();
5001
5002 return;
5003}
5004
5005static void
5006s_alpha_fp_save (ignore)
5007 int ignore ATTRIBUTE_UNUSED;
5008{
5009
5010 alpha_evax_proc.fp_save = tc_get_register (1);
5011
5012 demand_empty_rest_of_line ();
5013 return;
5014}
5015
5016static void
5017s_alpha_mask (ignore)
5018 int ignore ATTRIBUTE_UNUSED;
5019{
5020 long val;
5021
5022 if (get_absolute_expression_and_terminator (&val) != ',')
5023 {
5024 as_warn (_("Bad .mask directive"));
5025 --input_line_pointer;
5026 }
5027 else
5028 {
5029 alpha_evax_proc.imask = val;
5030 (void) get_absolute_expression ();
5031 }
5032 demand_empty_rest_of_line ();
5033
5034 return;
5035}
5036
5037static void
5038s_alpha_fmask (ignore)
5039 int ignore ATTRIBUTE_UNUSED;
5040{
5041 long val;
5042
5043 if (get_absolute_expression_and_terminator (&val) != ',')
5044 {
5045 as_warn (_("Bad .fmask directive"));
5046 --input_line_pointer;
5047 }
5048 else
5049 {
5050 alpha_evax_proc.fmask = val;
5051 (void) get_absolute_expression ();
5052 }
5053 demand_empty_rest_of_line ();
5054
5055 return;
5056}
5057
5058static void
5059s_alpha_end (ignore)
5060 int ignore ATTRIBUTE_UNUSED;
5061{
5062 char c;
5063
5064 c = get_symbol_end ();
5065 *input_line_pointer = c;
5066 demand_empty_rest_of_line ();
5067 alpha_evax_proc.symbol = 0;
5068
5069 return;
5070}
5071
5072static void
5073s_alpha_file (ignore)
5074 int ignore ATTRIBUTE_UNUSED;
5075{
5076 symbolS *s;
5077 int length;
5078 static char case_hack[32];
5079
5080 extern char *demand_copy_string PARAMS ((int *lenP));
5081
5082 sprintf (case_hack, "<CASE:%01d%01d>",
5083 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
5084
5085 s = symbol_find_or_make (case_hack);
5086 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5087
5088 get_absolute_expression ();
5089 s = symbol_find_or_make (demand_copy_string (&length));
5090 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5091 demand_empty_rest_of_line ();
5092
5093 return;
5094}
5095#endif /* OBJ_EVAX */
5096
5097/* Handle the .gprel32 pseudo op. */
5098
5099static void
5100s_alpha_gprel32 (ignore)
5101 int ignore ATTRIBUTE_UNUSED;
5102{
5103 expressionS e;
5104 char *p;
5105
5106 SKIP_WHITESPACE ();
5107 expression (&e);
5108
5109#ifdef OBJ_ELF
5110 switch (e.X_op)
5111 {
5112 case O_constant:
5113 e.X_add_symbol = section_symbol (absolute_section);
5114 e.X_op = O_symbol;
5115 /* FALLTHRU */
5116 case O_symbol:
5117 break;
5118 default:
5119 abort ();
5120 }
5121#else
5122#ifdef OBJ_ECOFF
5123 switch (e.X_op)
5124 {
5125 case O_constant:
5126 e.X_add_symbol = section_symbol (absolute_section);
5127 /* fall through */
5128 case O_symbol:
5129 e.X_op = O_subtract;
5130 e.X_op_symbol = alpha_gp_symbol;
5131 break;
5132 default:
5133 abort ();
5134 }
5135#endif
5136#endif
5137
5138 if (alpha_auto_align_on && alpha_current_align < 2)
5139 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
5140 if (alpha_current_align > 2)
5141 alpha_current_align = 2;
5142 alpha_insn_label = NULL;
5143
5144 p = frag_more (4);
5145 memset (p, 0, 4);
5146 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
5147 &e, 0, BFD_RELOC_GPREL32);
5148}
5149
5150/* Handle floating point allocation pseudo-ops. This is like the
5151 generic vresion, but it makes sure the current label, if any, is
5152 correctly aligned. */
5153
5154static void
5155s_alpha_float_cons (type)
5156 int type;
5157{
5158 int log_size;
5159
5160 switch (type)
5161 {
5162 default:
5163 case 'f':
5164 case 'F':
5165 log_size = 2;
5166 break;
5167
5168 case 'd':
5169 case 'D':
5170 case 'G':
5171 log_size = 3;
5172 break;
5173
5174 case 'x':
5175 case 'X':
5176 case 'p':
5177 case 'P':
5178 log_size = 4;
5179 break;
5180 }
5181
5182 if (alpha_auto_align_on && alpha_current_align < log_size)
5183 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5184 if (alpha_current_align > log_size)
5185 alpha_current_align = log_size;
5186 alpha_insn_label = NULL;
5187
5188 float_cons (type);
5189}
5190
5191/* Handle the .proc pseudo op. We don't really do much with it except
5192 parse it. */
5193
5194static void
5195s_alpha_proc (is_static)
5196 int is_static ATTRIBUTE_UNUSED;
5197{
5198 char *name;
5199 char c;
5200 char *p;
5201 symbolS *symbolP;
5202 int temp;
5203
5204 /* Takes ".proc name,nargs" */
5205 SKIP_WHITESPACE ();
5206 name = input_line_pointer;
5207 c = get_symbol_end ();
5208 p = input_line_pointer;
5209 symbolP = symbol_find_or_make (name);
5210 *p = c;
5211 SKIP_WHITESPACE ();
5212 if (*input_line_pointer != ',')
5213 {
5214 *p = 0;
5215 as_warn (_("Expected comma after name \"%s\""), name);
5216 *p = c;
5217 temp = 0;
5218 ignore_rest_of_line ();
5219 }
5220 else
5221 {
5222 input_line_pointer++;
5223 temp = get_absolute_expression ();
5224 }
5225 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5226 as_warn (_("unhandled: .proc %s,%d"), name, temp);
5227 demand_empty_rest_of_line ();
5228}
5229
5230/* Handle the .set pseudo op. This is used to turn on and off most of
5231 the assembler features. */
5232
5233static void
5234s_alpha_set (x)
5235 int x ATTRIBUTE_UNUSED;
5236{
5237 char *name, ch, *s;
5238 int yesno = 1;
5239
5240 SKIP_WHITESPACE ();
5241 name = input_line_pointer;
5242 ch = get_symbol_end ();
5243
5244 s = name;
5245 if (s[0] == 'n' && s[1] == 'o')
5246 {
5247 yesno = 0;
5248 s += 2;
5249 }
5250 if (!strcmp ("reorder", s))
5251 /* ignore */ ;
5252 else if (!strcmp ("at", s))
5253 alpha_noat_on = !yesno;
5254 else if (!strcmp ("macro", s))
5255 alpha_macros_on = yesno;
5256 else if (!strcmp ("move", s))
5257 /* ignore */ ;
5258 else if (!strcmp ("volatile", s))
5259 /* ignore */ ;
5260 else
5261 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5262
5263 *input_line_pointer = ch;
5264 demand_empty_rest_of_line ();
5265}
5266
5267/* Handle the .base pseudo op. This changes the assembler's notion of
5268 the $gp register. */
5269
5270static void
5271s_alpha_base (ignore)
5272 int ignore ATTRIBUTE_UNUSED;
5273{
5274#if 0
5275 if (first_32bit_quadrant)
5276 {
5277 /* not fatal, but it might not work in the end */
5278 as_warn (_("File overrides no-base-register option."));
5279 first_32bit_quadrant = 0;
5280 }
5281#endif
5282
5283 SKIP_WHITESPACE ();
5284 if (*input_line_pointer == '$')
5285 { /* $rNN form */
5286 input_line_pointer++;
5287 if (*input_line_pointer == 'r')
5288 input_line_pointer++;
5289 }
5290
5291 alpha_gp_register = get_absolute_expression ();
5292 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5293 {
5294 alpha_gp_register = AXP_REG_GP;
5295 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5296 }
5297
5298 demand_empty_rest_of_line ();
5299}
5300
5301/* Handle the .align pseudo-op. This aligns to a power of two. It
5302 also adjusts any current instruction label. We treat this the same
5303 way the MIPS port does: .align 0 turns off auto alignment. */
5304
5305static void
5306s_alpha_align (ignore)
5307 int ignore ATTRIBUTE_UNUSED;
5308{
5309 int align;
5310 char fill, *pfill;
5311 long max_alignment = 15;
5312
5313 align = get_absolute_expression ();
5314 if (align > max_alignment)
5315 {
5316 align = max_alignment;
5317 as_bad (_("Alignment too large: %d. assumed"), align);
5318 }
5319 else if (align < 0)
5320 {
5321 as_warn (_("Alignment negative: 0 assumed"));
5322 align = 0;
5323 }
5324
5325 if (*input_line_pointer == ',')
5326 {
5327 input_line_pointer++;
5328 fill = get_absolute_expression ();
5329 pfill = &fill;
5330 }
5331 else
5332 pfill = NULL;
5333
5334 if (align != 0)
5335 {
5336 alpha_auto_align_on = 1;
5337 alpha_align (align, pfill, alpha_insn_label, 1);
5338 }
5339 else
5340 {
5341 alpha_auto_align_on = 0;
5342 }
5343
5344 demand_empty_rest_of_line ();
5345}
5346
5347/* Hook the normal string processor to reset known alignment. */
5348
5349static void
5350s_alpha_stringer (terminate)
5351 int terminate;
5352{
5353 alpha_current_align = 0;
5354 alpha_insn_label = NULL;
5355 stringer (terminate);
5356}
5357
5358/* Hook the normal space processing to reset known alignment. */
5359
5360static void
5361s_alpha_space (ignore)
5362 int ignore;
5363{
5364 alpha_current_align = 0;
5365 alpha_insn_label = NULL;
5366 s_space (ignore);
5367}
5368
5369/* Hook into cons for auto-alignment. */
5370
5371void
5372alpha_cons_align (size)
5373 int size;
5374{
5375 int log_size;
5376
5377 log_size = 0;
5378 while ((size >>= 1) != 0)
5379 ++log_size;
5380
5381 if (alpha_auto_align_on && alpha_current_align < log_size)
5382 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5383 if (alpha_current_align > log_size)
5384 alpha_current_align = log_size;
5385 alpha_insn_label = NULL;
5386}
5387
5388/* Here come the .uword, .ulong, and .uquad explicitly unaligned
5389 pseudos. We just turn off auto-alignment and call down to cons. */
5390
5391static void
5392s_alpha_ucons (bytes)
5393 int bytes;
5394{
5395 int hold = alpha_auto_align_on;
5396 alpha_auto_align_on = 0;
5397 cons (bytes);
5398 alpha_auto_align_on = hold;
5399}
5400
5401/* Switch the working cpu type. */
5402
5403static void
5404s_alpha_arch (ignored)
5405 int ignored ATTRIBUTE_UNUSED;
5406{
5407 char *name, ch;
5408 const struct cpu_type *p;
5409
5410 SKIP_WHITESPACE ();
5411 name = input_line_pointer;
5412 ch = get_symbol_end ();
5413
5414 for (p = cpu_types; p->name; ++p)
5415 if (strcmp (name, p->name) == 0)
5416 {
5417 alpha_target_name = p->name, alpha_target = p->flags;
5418 goto found;
5419 }
5420 as_warn ("Unknown CPU identifier `%s'", name);
5421
5422found:
5423 *input_line_pointer = ch;
5424 demand_empty_rest_of_line ();
5425}
5426
5427
5428#ifdef DEBUG1
5429/* print token expression with alpha specific extension. */
5430
5431static void
5432alpha_print_token (f, exp)
5433 FILE *f;
5434 const expressionS *exp;
5435{
5436 switch (exp->X_op)
5437 {
5438 case O_cpregister:
5439 putc (',', f);
5440 /* FALLTHRU */
5441 case O_pregister:
5442 putc ('(', f);
5443 {
5444 expressionS nexp = *exp;
5445 nexp.X_op = O_register;
5446 print_expr (f, &nexp);
5447 }
5448 putc (')', f);
5449 break;
5450 default:
5451 print_expr (f, exp);
5452 break;
5453 }
5454 return;
5455}
5456#endif
5457
5458
5459/* The target specific pseudo-ops which we support. */
5460
5461const pseudo_typeS md_pseudo_table[] = {
5462#ifdef OBJ_ECOFF
5463 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5464 {"rdata", s_alpha_rdata, 0},
5465#endif
5466 {"text", s_alpha_text, 0},
5467 {"data", s_alpha_data, 0},
5468#ifdef OBJ_ECOFF
5469 {"sdata", s_alpha_sdata, 0},
5470#endif
5471#ifdef OBJ_ELF
5472 {"section", s_alpha_section, 0},
5473 {"section.s", s_alpha_section, 0},
5474 {"sect", s_alpha_section, 0},
5475 {"sect.s", s_alpha_section, 0},
5476#endif
5477#ifdef OBJ_EVAX
5478 { "pdesc", s_alpha_pdesc, 0},
5479 { "name", s_alpha_name, 0},
5480 { "linkage", s_alpha_linkage, 0},
5481 { "code_address", s_alpha_code_address, 0},
5482 { "ent", s_alpha_ent, 0},
5483 { "frame", s_alpha_frame, 0},
5484 { "fp_save", s_alpha_fp_save, 0},
5485 { "mask", s_alpha_mask, 0},
5486 { "fmask", s_alpha_fmask, 0},
5487 { "end", s_alpha_end, 0},
5488 { "file", s_alpha_file, 0},
5489 { "rdata", s_alpha_section, 1},
5490 { "comm", s_alpha_comm, 0},
5491 { "link", s_alpha_section, 3},
5492 { "ctors", s_alpha_section, 4},
5493 { "dtors", s_alpha_section, 5},
5494#endif
5495#ifdef OBJ_ELF
5496 /* Frame related pseudos. */
5497 {"ent", s_alpha_ent, 0},
5498 {"end", s_alpha_end, 0},
5499 {"mask", s_alpha_mask, 0},
5500 {"fmask", s_alpha_mask, 1},
5501 {"frame", s_alpha_frame, 0},
5502 {"prologue", s_alpha_prologue, 0},
5503 {"file", s_alpha_file, 5},
5504 {"loc", s_alpha_loc, 9},
5505 {"stabs", s_alpha_stab, 's'},
5506 {"stabn", s_alpha_stab, 'n'},
5507 /* COFF debugging related pseudos. */
5508 {"begin", s_alpha_coff_wrapper, 0},
5509 {"bend", s_alpha_coff_wrapper, 1},
5510 {"def", s_alpha_coff_wrapper, 2},
5511 {"dim", s_alpha_coff_wrapper, 3},
5512 {"endef", s_alpha_coff_wrapper, 4},
5513 {"scl", s_alpha_coff_wrapper, 5},
5514 {"tag", s_alpha_coff_wrapper, 6},
5515 {"val", s_alpha_coff_wrapper, 7},
5516#else
5517 {"prologue", s_ignore, 0},
5518#endif
5519 {"gprel32", s_alpha_gprel32, 0},
5520 {"t_floating", s_alpha_float_cons, 'd'},
5521 {"s_floating", s_alpha_float_cons, 'f'},
5522 {"f_floating", s_alpha_float_cons, 'F'},
5523 {"g_floating", s_alpha_float_cons, 'G'},
5524 {"d_floating", s_alpha_float_cons, 'D'},
5525
5526 {"proc", s_alpha_proc, 0},
5527 {"aproc", s_alpha_proc, 1},
5528 {"set", s_alpha_set, 0},
5529 {"reguse", s_ignore, 0},
5530 {"livereg", s_ignore, 0},
5531 {"base", s_alpha_base, 0}, /*??*/
5532 {"option", s_ignore, 0},
5533 {"aent", s_ignore, 0},
5534 {"ugen", s_ignore, 0},
5535 {"eflag", s_ignore, 0},
5536
5537 {"align", s_alpha_align, 0},
5538 {"double", s_alpha_float_cons, 'd'},
5539 {"float", s_alpha_float_cons, 'f'},
5540 {"single", s_alpha_float_cons, 'f'},
5541 {"ascii", s_alpha_stringer, 0},
5542 {"asciz", s_alpha_stringer, 1},
5543 {"string", s_alpha_stringer, 1},
5544 {"space", s_alpha_space, 0},
5545 {"skip", s_alpha_space, 0},
5546 {"zero", s_alpha_space, 0},
5547
5548/* Unaligned data pseudos. */
5549 {"uword", s_alpha_ucons, 2},
5550 {"ulong", s_alpha_ucons, 4},
5551 {"uquad", s_alpha_ucons, 8},
5552
5553#ifdef OBJ_ELF
5554/* Dwarf wants these versions of unaligned. */
5555 {"2byte", s_alpha_ucons, 2},
5556 {"4byte", s_alpha_ucons, 4},
5557 {"8byte", s_alpha_ucons, 8},
5558#endif
5559
5560/* We don't do any optimizing, so we can safely ignore these. */
5561 {"noalias", s_ignore, 0},
5562 {"alias", s_ignore, 0},
5563
5564 {"arch", s_alpha_arch, 0},
5565
5566 {NULL, 0, 0},
5567};
5568
5569
5570/* Build a BFD section with its flags set appropriately for the .lita,
5571 .lit8, or .lit4 sections. */
5572
5573static void
5574create_literal_section (name, secp, symp)
5575 const char *name;
5576 segT *secp;
5577 symbolS **symp;
5578{
5579 segT current_section = now_seg;
5580 int current_subsec = now_subseg;
5581 segT new_sec;
5582
5583 *secp = new_sec = subseg_new (name, 0);
5584 subseg_set (current_section, current_subsec);
5585 bfd_set_section_alignment (stdoutput, new_sec, 4);
5586 bfd_set_section_flags (stdoutput, new_sec,
5587 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5588 | SEC_DATA);
5589
5590 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5591}
5592
5593#ifdef OBJ_ECOFF
5594
5595/* @@@ GP selection voodoo. All of this seems overly complicated and
5596 unnecessary; which is the primary reason it's for ECOFF only. */
5597static inline void maybe_set_gp PARAMS ((asection *));
5598
5599static inline void
5600maybe_set_gp (sec)
5601 asection *sec;
5602{
5603 bfd_vma vma;
5604 if (!sec)
5605 return;
5606 vma = bfd_get_section_vma (foo, sec);
5607 if (vma && vma < alpha_gp_value)
5608 alpha_gp_value = vma;
5609}
5610
5611static void
5612select_gp_value ()
5613{
5614 assert (alpha_gp_value == 0);
5615
5616 /* Get minus-one in whatever width... */
5617 alpha_gp_value = 0;
5618 alpha_gp_value--;
5619
5620 /* Select the smallest VMA of these existing sections. */
5621 maybe_set_gp (alpha_lita_section);
5622#if 0
5623 /* These were disabled before -- should we use them? */
5624 maybe_set_gp (sdata);
5625 maybe_set_gp (lit8_sec);
5626 maybe_set_gp (lit4_sec);
5627#endif
5628
5629/* @@ Will a simple 0x8000 work here? If not, why not? */
5630#define GP_ADJUSTMENT (0x8000 - 0x10)
5631
5632 alpha_gp_value += GP_ADJUSTMENT;
5633
5634 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5635
5636#ifdef DEBUG1
5637 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5638#endif
5639}
5640#endif /* OBJ_ECOFF */
5641
5642#ifdef OBJ_ELF
5643/* Map 's' to SHF_ALPHA_GPREL. */
5644
5645int
5646alpha_elf_section_letter (letter, ptr_msg)
5647 int letter;
5648 char **ptr_msg;
5649{
5650 if (letter == 's')
5651 return SHF_ALPHA_GPREL;
5652
5653 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5654 return 0;
5655}
5656
5657/* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5658
5659flagword
5660alpha_elf_section_flags (flags, attr, type)
5661 flagword flags;
5662 int attr, type ATTRIBUTE_UNUSED;
5663{
5664 if (attr & SHF_ALPHA_GPREL)
5665 flags |= SEC_SMALL_DATA;
5666 return flags;
5667}
5668#endif /* OBJ_ELF */
5669
5670/* Called internally to handle all alignment needs. This takes care
5671 of eliding calls to frag_align if'n the cached current alignment
5672 says we've already got it, as well as taking care of the auto-align
5673 feature wrt labels. */
5674
5675static void
5676alpha_align (n, pfill, label, force)
5677 int n;
5678 char *pfill;
5679 symbolS *label;
5680 int force ATTRIBUTE_UNUSED;
5681{
5682 if (alpha_current_align >= n)
5683 return;
5684
5685 if (pfill == NULL)
5686 {
5687 if (subseg_text_p (now_seg))
5688 frag_align_code (n, 0);
5689 else
5690 frag_align (n, 0, 0);
5691 }
5692 else
5693 frag_align (n, *pfill, 0);
5694
5695 alpha_current_align = n;
5696
5697 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5698 {
5699 symbol_set_frag (label, frag_now);
5700 S_SET_VALUE (label, (valueT) frag_now_fix ());
5701 }
5702
5703 record_alignment (now_seg, n);
5704
5705 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5706 in a reloc for the linker to see. */
5707}
5708
5709/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5710 of an rs_align_code fragment. */
5711
5712void
5713alpha_handle_align (fragp)
5714 fragS *fragp;
5715{
5716 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5717 static char const nopunop[8] = {
5718 0x1f, 0x04, 0xff, 0x47,
5719 0x00, 0x00, 0xfe, 0x2f
5720 };
5721
5722 int bytes, fix;
5723 char *p;
5724
5725 if (fragp->fr_type != rs_align_code)
5726 return;
5727
5728 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5729 p = fragp->fr_literal + fragp->fr_fix;
5730 fix = 0;
5731
5732 if (bytes & 3)
5733 {
5734 fix = bytes & 3;
5735 memset (p, 0, fix);
5736 p += fix;
5737 bytes -= fix;
5738 }
5739
5740 if (bytes & 4)
5741 {
5742 memcpy (p, unop, 4);
5743 p += 4;
5744 bytes -= 4;
5745 fix += 4;
5746 }
5747
5748 memcpy (p, nopunop, 8);
5749
5750 fragp->fr_fix += fix;
5751 fragp->fr_var = 8;
5752}
5753
5754/* The Alpha has support for some VAX floating point types, as well as for
5755 IEEE floating point. We consider IEEE to be the primary floating point
5756 format, and sneak in the VAX floating point support here. */
5757#define md_atof vax_md_atof
5758#include "config/atof-vax.c"
Note: See TracBrowser for help on using the repository browser.