alpha elf reloc fixes, part 1
Richard Henderson
rth@redhat.com
Tue Sep 4 19:46:00 GMT 2001
Some time ago (1999?) some code was added for explicit user relocations,
much like is supported by DU 4.0. Anyway, I never noticed, since this
weekend I went to implement this and discovered that it already existed.
Except that it didn't actually work in most cases.
Here's fixes for the assembler, plus test cases.
r~
* config/tc-alpha.c (struct alpha_insn): Make sequence scalar long.
(MACRO_LITERAL, MACRO_BASE, MACRO_BYTOFF, MACRO_JSR): Remove.
(alpha_macros): Remove occurrences of same.
(O_lituse_addr, O_gprel): New.
(DUMMY_RELOC_LITUSE_*): New.
(s_alpha_ucons, s_alpha_arch): Prototype.
(alpha_reloc_op): Construct elements via DEF macro.
(ALPHA_RELOC_SEQUENCE_OK): Remove.
(struct alpha_reloc_tag): Rename from alpha_literal_tag; rename
members to not be literal specific.
(next_sequence_num): New.
(md_apply_fix3): Cope with missing GPDISP_LO16. Adjust for
added/removed BFD relocations.
(alpha_force_relocation, alpha_fix_adjustable): Likewise.
(alpha_adjust_symtab_relocs): Handle GPDISP relocs as well.
(tokenize_arguments): Parse ! relocations properly.
(find_macro_match): Delete unused macro argument types.
(assemble_insn): Add reloc parameter; emit that instead of the
default as appropriate.
(get_alpha_reloc_tag): New. Split from ...
(emit_insn): ... here. Allocate a reloc tag for GPDISP.
(assemble_tokens): Don't search macros if user relocation present.
Copy reloc sequence number to insn struct.
(emit_ldgp): Remove user reloc handling.
(load_expression, emit_lda, emit_ldah, emit_ir_load): Likewise.
(emit_loadstore, emit_ldXu, emit_ldil, emit_stX): Likewise.
(emit_sextX, emit_division, emit_jsrjmp, emit_retjcr): Likewise.
* config/tc-alpha.h (tc_adjust_symtab): Always define.
(struct alpha_fix_tag): Name members less literal specific.
* gas/alpha/alpha.exp: New file.
* gas/alpha/elf-reloc-1.[sd]: New test.
* gas/alpha/elf-reloc-2.[sl]: New test.
* gas/alpha/elf-reloc-3.[sl]: New test.
* gas/alpha/elf-reloc-4.[sd]: New test.
* gas/alpha/fp.exp: Remove file.
* gas/alpha/fp.s: Output to .data not .rdata.
* gas/alpha/fp.d: Adjust to match.
Index: config/tc-alpha.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-alpha.c,v
retrieving revision 1.25
diff -c -p -d -r1.25 tc-alpha.c
*** tc-alpha.c 2001/08/21 00:22:23 1.25
--- tc-alpha.c 2001/09/05 02:39:09
*************** struct alpha_insn {
*** 81,87 ****
unsigned insn;
int nfixups;
struct alpha_fixup fixups[MAX_INSN_FIXUPS];
! unsigned sequence[MAX_INSN_FIXUPS];
};
enum alpha_macro_arg {
--- 81,87 ----
unsigned insn;
int nfixups;
struct alpha_fixup fixups[MAX_INSN_FIXUPS];
! long sequence;
};
enum alpha_macro_arg {
*************** enum alpha_macro_arg {
*** 92,101 ****
MACRO_CPIR,
MACRO_FPR,
MACRO_EXP,
- MACRO_LITERAL,
- MACRO_BASE,
- MACRO_BYTOFF,
- MACRO_JSR
};
struct alpha_macro {
--- 92,97 ----
*************** struct alpha_macro {
*** 110,129 ****
#define O_pregister O_md1 /* O_register, in parentheses */
#define O_cpregister O_md2 /* + a leading comma */
- #ifdef RELOC_OP_P
/* Note, the alpha_reloc_op table below depends on the ordering
! of O_literal .. O_gprelow. */
#define O_literal O_md3 /* !literal relocation */
! #define O_lituse_base O_md4 /* !lituse_base relocation */
! #define O_lituse_bytoff O_md5 /* !lituse_bytoff relocation */
! #define O_lituse_jsr O_md6 /* !lituse_jsr relocation */
! #define O_gpdisp O_md7 /* !gpdisp relocation */
! #define O_gprelhigh O_md8 /* !gprelhigh relocation */
! #define O_gprellow O_md9 /* !gprellow relocation */
! #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprellow)
! #endif
/* Macros for extracting the type and number of encoded register tokens */
#define is_ir_num(x) (((x) & 32) == 0)
--- 106,135 ----
#define O_pregister O_md1 /* O_register, in parentheses */
#define O_cpregister O_md2 /* + a leading comma */
/* Note, the alpha_reloc_op table below depends on the ordering
! of O_literal .. O_gpre16. */
#define O_literal O_md3 /* !literal relocation */
! #define O_lituse_addr O_md4 /* !lituse_addr relocation */
! #define O_lituse_base O_md5 /* !lituse_base relocation */
! #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
! #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
! #define O_gpdisp O_md8 /* !gpdisp relocation */
! #define O_gprelhigh O_md9 /* !gprelhigh relocation */
! #define O_gprellow O_md10 /* !gprellow relocation */
! #define O_gprel O_md11 /* !gprel relocation */
! #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
! #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
! #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
! #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
+ #define LITUSE_ADDR 0
+ #define LITUSE_BASE 1
+ #define LITUSE_BYTOFF 2
+ #define LITUSE_JSR 3
+
+ #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
+
/* Macros for extracting the type and number of encoded register tokens */
#define is_ir_num(x) (((x) & 32) == 0)
*************** struct alpha_macro {
*** 188,193 ****
--- 194,202 ----
/* Prototypes for all local functions */
+ static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
+ static void alpha_adjust_symtab_relocs PARAMS ((bfd *, asection *, PTR));
+
static int tokenize_arguments PARAMS ((char *, expressionS *, int));
static const struct alpha_opcode *find_opcode_match
PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
*************** static unsigned insert_operand
*** 197,212 ****
PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
static void assemble_insn
PARAMS ((const struct alpha_opcode *, const expressionS *, int,
! struct alpha_insn *));
static void emit_insn PARAMS ((struct alpha_insn *));
static void assemble_tokens_to_insn
PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
static void assemble_tokens
PARAMS ((const char *, const expressionS *, int, int));
! static int load_expression
! PARAMS ((int, const expressionS *, int *, expressionS *,
! const expressionS *));
static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
static void emit_division PARAMS ((const expressionS *, int, const PTR));
--- 206,220 ----
PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
static void assemble_insn
PARAMS ((const struct alpha_opcode *, const expressionS *, int,
! struct alpha_insn *, bfd_reloc_code_real_type));
static void emit_insn PARAMS ((struct alpha_insn *));
static void assemble_tokens_to_insn
PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
static void assemble_tokens
PARAMS ((const char *, const expressionS *, int, int));
! static long load_expression
! PARAMS ((int, const expressionS *, int *, expressionS *));
static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
static void emit_division PARAMS ((const expressionS *, int, const PTR));
*************** static void s_alpha_base PARAMS ((int));
*** 257,272 ****
static void s_alpha_align PARAMS ((int));
static void s_alpha_stringer PARAMS ((int));
static void s_alpha_space PARAMS ((int));
static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
#ifndef OBJ_ELF
static void select_gp_value PARAMS ((void));
#endif
static void alpha_align PARAMS ((int, char *, symbolS *, int));
-
- #ifdef RELOC_OP_P
- static void alpha_adjust_symtab_relocs PARAMS ((bfd *, asection *, PTR));
- #endif
/* Generic assembler global variables which must be defined by all
targets. */
--- 265,278 ----
static void s_alpha_align PARAMS ((int));
static void s_alpha_stringer PARAMS ((int));
static void s_alpha_space PARAMS ((int));
+ static void s_alpha_ucons PARAMS ((int));
+ static void s_alpha_arch PARAMS ((int));
static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
#ifndef OBJ_ELF
static void select_gp_value PARAMS ((void));
#endif
static void alpha_align PARAMS ((int, char *, symbolS *, int));
/* Generic assembler global variables which must be defined by all
targets. */
*************** static int alpha_flag_show_after_trunc =
*** 469,571 ****
that op-O_literal indexes into it. */
#define ALPHA_RELOC_TABLE(op) \
! &alpha_reloc_op[ ((!USER_RELOC_P (op)) \
? (abort (), 0) \
! : (int) (op) - (int) O_literal) ]
! #define LITUSE_BASE 1
! #define LITUSE_BYTOFF 2
! #define LITUSE_JSR 3
static const struct alpha_reloc_op_tag {
const char *name; /* string to lookup */
size_t length; /* size of the string */
- bfd_reloc_code_real_type reloc; /* relocation before frob */
operatorT op; /* which operator to use */
! int lituse; /* addened to specify lituse */
} alpha_reloc_op[] = {
!
! {
! "literal", /* name */
! sizeof ("literal")-1, /* length */
! BFD_RELOC_ALPHA_USER_LITERAL, /* reloc */
! O_literal, /* op */
! 0, /* lituse */
! },
!
! {
! "lituse_base", /* name */
! sizeof ("lituse_base")-1, /* length */
! BFD_RELOC_ALPHA_USER_LITUSE_BASE, /* reloc */
! O_lituse_base, /* op */
! LITUSE_BASE, /* lituse */
! },
!
! {
! "lituse_bytoff", /* name */
! sizeof ("lituse_bytoff")-1, /* length */
! BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF, /* reloc */
! O_lituse_bytoff, /* op */
! LITUSE_BYTOFF, /* lituse */
! },
!
! {
! "lituse_jsr", /* name */
! sizeof ("lituse_jsr")-1, /* length */
! BFD_RELOC_ALPHA_USER_LITUSE_JSR, /* reloc */
! O_lituse_jsr, /* op */
! LITUSE_JSR, /* lituse */
! },
!
! {
! "gpdisp", /* name */
! sizeof ("gpdisp")-1, /* length */
! BFD_RELOC_ALPHA_USER_GPDISP, /* reloc */
! O_gpdisp, /* op */
! 0, /* lituse */
! },
!
! {
! "gprelhigh", /* name */
! sizeof ("gprelhigh")-1, /* length */
! BFD_RELOC_ALPHA_USER_GPRELHIGH, /* reloc */
! O_gprelhigh, /* op */
! 0, /* lituse */
! },
!
! {
! "gprellow", /* name */
! sizeof ("gprellow")-1, /* length */
! BFD_RELOC_ALPHA_USER_GPRELLOW, /* reloc */
! O_gprellow, /* op */
! 0, /* lituse */
! },
};
static const int alpha_num_reloc_op
= sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
/* Maximum # digits needed to hold the largest sequence # */
#define ALPHA_RELOC_DIGITS 25
- /* Whether a sequence number is valid. */
- #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned) (X)) == (X))
-
/* Structure to hold explict sequence information. */
! struct alpha_literal_tag
{
! fixS *lituse; /* head of linked list of !literals */
segT segment; /* segment relocs are in or undefined_section*/
! int multi_section_p; /* True if more than one section was used */
! unsigned sequence; /* sequence # */
! unsigned n_literals; /* # of literals */
! unsigned n_lituses; /* # of lituses */
char string[1]; /* printable form of sequence to hash with */
};
/* Hash table to link up literals with the appropriate lituse */
static struct hash_control *alpha_literal_hash;
! #endif
/* A table of CPU names and opcode sets. */
--- 475,531 ----
that op-O_literal indexes into it. */
#define ALPHA_RELOC_TABLE(op) \
! (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
? (abort (), 0) \
! : (int) (op) - (int) O_literal) ])
! #define DEF(NAME, RELOC, NEED_SEQ) \
! { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, NEED_SEQ }
static const struct alpha_reloc_op_tag {
const char *name; /* string to lookup */
size_t length; /* size of the string */
operatorT op; /* which operator to use */
! bfd_reloc_code_real_type reloc; /* relocation before frob */
! unsigned int need_seq : 1; /* require a sequence number */
} alpha_reloc_op[] = {
! DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 1),
! DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1),
! DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1),
! DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1),
! DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1),
! DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1),
! DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0),
! DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0),
! DEF(gprel, BFD_RELOC_GPREL16, 0)
};
+ #undef DEF
+
static const int alpha_num_reloc_op
= sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
+ #endif /* RELOC_OP_P */
/* Maximum # digits needed to hold the largest sequence # */
#define ALPHA_RELOC_DIGITS 25
/* Structure to hold explict sequence information. */
! struct alpha_reloc_tag
{
! fixS *slaves; /* head of linked list of !literals */
segT segment; /* segment relocs are in or undefined_section*/
! long sequence; /* sequence # */
! unsigned n_master; /* # of literals */
! unsigned n_slaves; /* # of lituses */
! char multi_section_p; /* True if more than one section was used */
char string[1]; /* printable form of sequence to hash with */
};
/* Hash table to link up literals with the appropriate lituse */
static struct hash_control *alpha_literal_hash;
!
! /* Sequence numbers for internal use by macros. */
! static long next_sequence_num = -1;
/* A table of CPU names and opcode sets. */
*************** static const struct cpu_type {
*** 606,653 ****
static const struct alpha_macro alpha_macros[] = {
/* Load/Store macros */
{ "lda", emit_lda, NULL,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_LITERAL, MACRO_BASE, MACRO_EOA } },
{ "ldah", emit_ldah, NULL,
{ MACRO_IR, MACRO_EXP, MACRO_EOA } },
{ "ldl", emit_ir_load, "ldl",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldl_l", emit_ir_load, "ldl_l",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldq", emit_ir_load, "ldq",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_LITERAL, MACRO_EOA } },
{ "ldq_l", emit_ir_load, "ldq_l",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldq_u", emit_ir_load, "ldq_u",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldf", emit_loadstore, "ldf",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldg", emit_loadstore, "ldg",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "lds", emit_loadstore, "lds",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldt", emit_loadstore, "ldt",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldb", emit_ldX, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldbu", emit_ldXu, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldw", emit_ldX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldwu", emit_ldXu, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "uldw", emit_uldX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "uldwu", emit_uldXu, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "uldl", emit_uldX, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "uldlu", emit_uldXu, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "uldq", emit_uldXu, (PTR) 3,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ldgp", emit_ldgp, NULL,
{ MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
--- 566,613 ----
static const struct alpha_macro alpha_macros[] = {
/* Load/Store macros */
{ "lda", emit_lda, NULL,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldah", emit_ldah, NULL,
{ MACRO_IR, MACRO_EXP, MACRO_EOA } },
{ "ldl", emit_ir_load, "ldl",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldl_l", emit_ir_load, "ldl_l",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldq", emit_ir_load, "ldq",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldq_l", emit_ir_load, "ldq_l",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldq_u", emit_ir_load, "ldq_u",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldf", emit_loadstore, "ldf",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldg", emit_loadstore, "ldg",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "lds", emit_loadstore, "lds",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldt", emit_loadstore, "ldt",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldb", emit_ldX, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldbu", emit_ldXu, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldw", emit_ldX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldwu", emit_ldXu, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "uldw", emit_uldX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "uldwu", emit_uldXu, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "uldl", emit_uldX, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "uldlu", emit_uldXu, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "uldq", emit_uldXu, (PTR) 3,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ldgp", emit_ldgp, NULL,
{ MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
*************** static const struct alpha_macro alpha_ma
*** 672,705 ****
#endif
{ "stl", emit_loadstore, "stl",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stl_c", emit_loadstore, "stl_c",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stq", emit_loadstore, "stq",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stq_c", emit_loadstore, "stq_c",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stq_u", emit_loadstore, "stq_u",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stf", emit_loadstore, "stf",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stg", emit_loadstore, "stg",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "sts", emit_loadstore, "sts",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stt", emit_loadstore, "stt",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stb", emit_stX, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "stw", emit_stX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ustw", emit_ustX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ustl", emit_ustX, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
{ "ustq", emit_ustX, (PTR) 3,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_BASE, MACRO_EOA } },
/* Arithmetic macros */
#if 0
--- 632,665 ----
#endif
{ "stl", emit_loadstore, "stl",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stl_c", emit_loadstore, "stl_c",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stq", emit_loadstore, "stq",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stq_c", emit_loadstore, "stq_c",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stq_u", emit_loadstore, "stq_u",
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stf", emit_loadstore, "stf",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stg", emit_loadstore, "stg",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "sts", emit_loadstore, "sts",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stt", emit_loadstore, "stt",
! { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stb", emit_stX, (PTR) 0,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "stw", emit_stX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ustw", emit_ustX, (PTR) 1,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ustl", emit_ustX, (PTR) 2,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
{ "ustq", emit_ustX, (PTR) 3,
! { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
/* Arithmetic macros */
#if 0
*************** static const struct alpha_macro alpha_ma
*** 762,776 ****
MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
{ "jsr", emit_jsrjmp, "jsr",
! { MACRO_PIR, MACRO_EXP, MACRO_JSR, MACRO_EOA,
! MACRO_PIR, MACRO_JSR, MACRO_EOA,
! MACRO_IR, MACRO_EXP, MACRO_JSR, MACRO_EOA,
! MACRO_EXP, MACRO_JSR, MACRO_EOA } },
{ "jmp", emit_jsrjmp, "jmp",
! { MACRO_PIR, MACRO_EXP, MACRO_JSR, MACRO_EOA,
! MACRO_PIR, MACRO_JSR, MACRO_EOA,
! MACRO_IR, MACRO_EXP, MACRO_JSR, MACRO_EOA,
! MACRO_EXP, MACRO_JSR, MACRO_EOA } },
{ "ret", emit_retjcr, "ret",
{ MACRO_IR, MACRO_EXP, MACRO_EOA,
MACRO_IR, MACRO_EOA,
--- 722,736 ----
MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
{ "jsr", emit_jsrjmp, "jsr",
! { MACRO_PIR, MACRO_EXP, MACRO_EOA,
! MACRO_PIR, MACRO_EOA,
! MACRO_IR, MACRO_EXP, MACRO_EOA,
! MACRO_EXP, MACRO_EOA } },
{ "jmp", emit_jsrjmp, "jmp",
! { MACRO_PIR, MACRO_EXP, MACRO_EOA,
! MACRO_PIR, MACRO_EOA,
! MACRO_IR, MACRO_EXP, MACRO_EOA,
! MACRO_EXP, MACRO_EOA } },
{ "ret", emit_retjcr, "ret",
{ MACRO_IR, MACRO_EXP, MACRO_EOA,
MACRO_IR, MACRO_EOA,
*************** md_begin ()
*** 825,831 ****
name = alpha_opcodes[i].name;
retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
if (retval)
! as_fatal (_("internal error: can't hash opcode `%s': %s"), name, retval);
/* Some opcodes include modifiers of various sorts with a "/mod"
syntax, like the architecture manual suggests. However, for
--- 785,792 ----
name = alpha_opcodes[i].name;
retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
if (retval)
! as_fatal (_("internal error: can't hash opcode `%s': %s"),
! name, retval);
/* Some opcodes include modifiers of various sorts with a "/mod"
syntax, like the architecture manual suggests. However, for
*************** md_begin ()
*** 912,923 ****
}
#endif /* OBJ_ELF */
- subseg_set (text_section, 0);
-
- #ifdef RELOC_OP_P
/* Create literal lookup hash table. */
alpha_literal_hash = hash_new ();
! #endif
}
/* The public interface to the instruction assembler. */
--- 873,882 ----
}
#endif /* OBJ_ELF */
/* Create literal lookup hash table. */
alpha_literal_hash = hash_new ();
!
! subseg_set (text_section, 0);
}
/* The public interface to the instruction assembler. */
*************** md_apply_fix3 (fixP, valueP, seg)
*** 1177,1186 ****
case BFD_RELOC_ALPHA_GPDISP_HI16:
{
fixS *next = fixP->fx_next;
- assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
! fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
! - fixP->fx_frag->fr_address - fixP->fx_where);
value = (value - sign_extend_16 (value)) >> 16;
}
--- 1136,1148 ----
case BFD_RELOC_ALPHA_GPDISP_HI16:
{
fixS *next = fixP->fx_next;
! /* With user-specified !gpdisp relocations, we can be missing
! the matching LO16 reloc. We will have already issued an
! error message. */
! if (next)
! fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
! - fixP->fx_frag->fr_address - fixP->fx_where);
value = (value - sign_extend_16 (value)) >> 16;
}
*************** md_apply_fix3 (fixP, valueP, seg)
*** 1230,1240 ****
/* FIXME: inherited this obliviousness of `value' -- why? */
md_number_to_chars (fixpos, -alpha_gp_value, 4);
break;
! #endif
! #ifdef OBJ_ELF
case BFD_RELOC_GPREL32:
- return 1;
#endif
case BFD_RELOC_23_PCREL_S2:
if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
--- 1192,1204 ----
/* FIXME: inherited this obliviousness of `value' -- why? */
md_number_to_chars (fixpos, -alpha_gp_value, 4);
break;
! #else
case BFD_RELOC_GPREL32:
#endif
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
+ return 1;
case BFD_RELOC_23_PCREL_S2:
if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
*************** md_apply_fix3 (fixP, valueP, seg)
*** 1258,1291 ****
case BFD_RELOC_ALPHA_LITERAL:
md_number_to_chars (fixpos, value, 2);
return 1;
-
- case BFD_RELOC_ALPHA_LITUSE:
- return 1;
#endif
- #ifdef OBJ_ELF
case BFD_RELOC_ALPHA_ELF_LITERAL:
case BFD_RELOC_ALPHA_LITUSE:
- return 1;
- #endif
- #ifdef OBJ_EVAX
case BFD_RELOC_ALPHA_LINKAGE:
case BFD_RELOC_ALPHA_CODEADDR:
return 1;
- #endif
-
- #ifdef RELOC_OP_P
- case BFD_RELOC_ALPHA_USER_LITERAL:
- case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
- case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
- case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
- return 1;
- case BFD_RELOC_ALPHA_USER_GPDISP:
- case BFD_RELOC_ALPHA_USER_GPRELHIGH:
- case BFD_RELOC_ALPHA_USER_GPRELLOW:
- abort ();
- #endif
-
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
return 1;
--- 1222,1234 ----
*************** alpha_force_relocation (f)
*** 1438,1464 ****
case BFD_RELOC_ALPHA_GPDISP_HI16:
case BFD_RELOC_ALPHA_GPDISP_LO16:
case BFD_RELOC_ALPHA_GPDISP:
- #ifdef OBJ_ECOFF
case BFD_RELOC_ALPHA_LITERAL:
- #endif
- #ifdef OBJ_ELF
case BFD_RELOC_ALPHA_ELF_LITERAL:
- #endif
case BFD_RELOC_ALPHA_LITUSE:
case BFD_RELOC_GPREL32:
! #ifdef OBJ_EVAX
case BFD_RELOC_ALPHA_LINKAGE:
case BFD_RELOC_ALPHA_CODEADDR:
- #endif
- #ifdef RELOC_OP_P
- case BFD_RELOC_ALPHA_USER_LITERAL:
- case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
- case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
- case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
- case BFD_RELOC_ALPHA_USER_GPDISP:
- case BFD_RELOC_ALPHA_USER_GPRELHIGH:
- case BFD_RELOC_ALPHA_USER_GPRELLOW:
- #endif
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
return 1;
--- 1381,1395 ----
case BFD_RELOC_ALPHA_GPDISP_HI16:
case BFD_RELOC_ALPHA_GPDISP_LO16:
case BFD_RELOC_ALPHA_GPDISP:
case BFD_RELOC_ALPHA_LITERAL:
case BFD_RELOC_ALPHA_ELF_LITERAL:
case BFD_RELOC_ALPHA_LITUSE:
+ case BFD_RELOC_GPREL16:
case BFD_RELOC_GPREL32:
! case BFD_RELOC_ALPHA_GPREL_HI16:
! case BFD_RELOC_ALPHA_GPREL_LO16:
case BFD_RELOC_ALPHA_LINKAGE:
case BFD_RELOC_ALPHA_CODEADDR:
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
return 1;
*************** alpha_fix_adjustable (f)
*** 1497,1531 ****
case BFD_RELOC_ALPHA_GPDISP:
return 0;
- #ifdef OBJ_ECOFF
case BFD_RELOC_ALPHA_LITERAL:
- #endif
- #ifdef OBJ_ELF
case BFD_RELOC_ALPHA_ELF_LITERAL:
! #endif
! #ifdef RELOC_OP_P
! case BFD_RELOC_ALPHA_USER_LITERAL:
! #endif
! #ifdef OBJ_EVAX
case BFD_RELOC_ALPHA_LINKAGE:
case BFD_RELOC_ALPHA_CODEADDR:
- #endif
return 1;
- case BFD_RELOC_ALPHA_LITUSE:
- #ifdef RELOC_OP_P
- case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
- case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
- case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
- case BFD_RELOC_ALPHA_USER_GPDISP:
- case BFD_RELOC_ALPHA_USER_GPRELHIGH:
- case BFD_RELOC_ALPHA_USER_GPRELLOW:
- #endif
case BFD_RELOC_VTABLE_ENTRY:
case BFD_RELOC_VTABLE_INHERIT:
return 0;
case BFD_RELOC_GPREL32:
case BFD_RELOC_23_PCREL_S2:
case BFD_RELOC_32:
case BFD_RELOC_64:
--- 1428,1448 ----
case BFD_RELOC_ALPHA_GPDISP:
return 0;
case BFD_RELOC_ALPHA_LITERAL:
case BFD_RELOC_ALPHA_ELF_LITERAL:
! case BFD_RELOC_ALPHA_LITUSE:
case BFD_RELOC_ALPHA_LINKAGE:
case BFD_RELOC_ALPHA_CODEADDR:
return 1;
case BFD_RELOC_VTABLE_ENTRY:
case BFD_RELOC_VTABLE_INHERIT:
return 0;
+ case BFD_RELOC_GPREL16:
case BFD_RELOC_GPREL32:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
case BFD_RELOC_23_PCREL_S2:
case BFD_RELOC_32:
case BFD_RELOC_64:
*************** alpha_frob_file_before_adjust ()
*** 1651,1681 ****
#endif /* OBJ_ECOFF */
! #ifdef RELOC_OP_P
/* Before the relocations are written, reorder them, so that user
supplied !lituse relocations follow the appropriate !literal
! relocations. Also convert the gas-internal relocations to the
! appropriate linker relocations. */
void
alpha_adjust_symtab ()
{
if (alpha_literal_hash)
! {
! #ifdef DEBUG2_ALPHA
! fprintf (stderr, "alpha_adjust_symtab called\n");
! #endif
!
! /* Go over each section, reordering the relocations so that all
! of the explicit LITUSE's are adjacent to the explicit
! LITERAL's. */
! bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs,
! (char *) 0);
! }
}
-
- /* Inner function to move LITUSE's next to the LITERAL. */
static void
alpha_adjust_symtab_relocs (abfd, sec, ptr)
--- 1568,1612 ----
#endif /* OBJ_ECOFF */
! static struct alpha_reloc_tag *
! get_alpha_reloc_tag (sequence)
! long sequence;
! {
! char buffer[ALPHA_RELOC_DIGITS];
! struct alpha_reloc_tag *info;
!
! sprintf (buffer, "!%ld", sequence);
!
! info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
! if (! info)
! {
! size_t len = strlen (buffer);
! const char *errmsg;
!
! info = (struct alpha_reloc_tag *)
! xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
!
! info->segment = now_seg;
! info->sequence = sequence;
! strcpy (info->string, buffer);
! errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
! if (errmsg)
! as_fatal (errmsg);
! }
+ return info;
+ }
+
/* Before the relocations are written, reorder them, so that user
supplied !lituse relocations follow the appropriate !literal
! relocations, and similarly for !gpdisp relocations. */
void
alpha_adjust_symtab ()
{
if (alpha_literal_hash)
! bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
}
static void
alpha_adjust_symtab_relocs (abfd, sec, ptr)
*************** alpha_adjust_symtab_relocs (abfd, sec, p
*** 1687,1700 ****
fixS **prevP;
fixS *fixp;
fixS *next;
! fixS *lituse;
! int n_lituses = 0;
!
! #ifdef DEBUG2_ALPHA
! int n = 0;
! int n_literals = 0;
! int n_dup_literals = 0;
! #endif
/* If seginfo is NULL, we did not create this section; don't do
anything with it. By using a pointer to a pointer, we can update
--- 1618,1625 ----
fixS **prevP;
fixS *fixp;
fixS *next;
! fixS *slave;
! unsigned long n_slaves = 0;
/* If seginfo is NULL, we did not create this section; don't do
anything with it. By using a pointer to a pointer, we can update
*************** alpha_adjust_symtab_relocs (abfd, sec, p
*** 1706,1826 ****
if (! seginfo->fix_root)
return;
! /* First rebuild the fixup chain without the expicit lituse's. */
! prevP = &(seginfo->fix_root);
for (fixp = seginfo->fix_root; fixp; fixp = next)
{
next = fixp->fx_next;
fixp->fx_next = (fixS *) 0;
- #ifdef DEBUG2_ALPHA
- n++;
- #endif
switch (fixp->fx_r_type)
{
! default:
! *prevP = fixp;
! prevP = &(fixp->fx_next);
! #ifdef DEBUG2_ALPHA
! fprintf (stderr,
! "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
! (long) fixp,
! bfd_get_reloc_code_name (fixp->fx_r_type));
! #endif
! break;
!
! case BFD_RELOC_ALPHA_USER_LITERAL:
! *prevP = fixp;
! prevP = &(fixp->fx_next);
! /* prevent assembler from trying to adjust the offset */
! #ifdef DEBUG2_ALPHA
! n_literals++;
! if (fixp->tc_fix_data.info->n_literals != 1)
! n_dup_literals++;
! fprintf (stderr,
! "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
! (long) fixp,
! fixp->tc_fix_data.info->sequence,
! fixp->tc_fix_data.info->n_literals);
! #endif
break;
! /* do not link in lituse's */
! case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
! case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
! case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
! n_lituses++;
! if (fixp->tc_fix_data.info->n_literals == 0)
as_bad_where (fixp->fx_file, fixp->fx_line,
! _("No !literal!%d was found"),
fixp->tc_fix_data.info->sequence);
! #ifdef DEBUG2_ALPHA
! fprintf (stderr,
! "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
! (long) fixp,
! fixp->tc_fix_data.info->sequence,
! fixp->tc_fix_data.info->n_lituses,
! (long) fixp->tc_fix_data.next_lituse);
! #endif
break;
}
}
! /* If there were any lituses, go and add them to the chain, unless there is
! more than one !literal for a given sequence number. They are linked
! through the next_lituse field in reverse order, so as we go through the
! next_lituse chain, we effectively reverse the chain once again. If there
! was more than one !literal, we fall back to loading up the address w/o
! optimization. Also, if the !literals/!lituses are spread in different
! segments (happens in the Linux kernel semaphores), suppress the
! optimization. */
! if (n_lituses)
{
! for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
{
! switch (fixp->fx_r_type)
{
! default:
! break;
!
! case BFD_RELOC_ALPHA_USER_LITERAL:
! #ifdef OBJ_ELF
! fixp->fx_r_type = BFD_RELOC_ALPHA_ELF_LITERAL;
! #else
! fixp->fx_r_type = BFD_RELOC_ALPHA_LITERAL; /* XXX check this */
! #endif
! if (fixp->tc_fix_data.info->n_literals == 1
! && ! fixp->tc_fix_data.info->multi_section_p)
{
! for (lituse = fixp->tc_fix_data.info->lituse;
! lituse != (fixS *) 0;
! lituse = lituse->tc_fix_data.next_lituse)
! {
! lituse->fx_next = fixp->fx_next;
! fixp->fx_next = lituse;
! }
}
! break;
! case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
! case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
! case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
! fixp->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
! break;
}
}
}
-
- #ifdef DEBUG2_ALPHA
- fprintf (stderr, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
- sec->name,
- n_literals, (n_literals == 1) ? "" : "s",
- n_dup_literals, (n_dup_literals == 1) ? "" : "s",
- n_lituses, (n_lituses == 1) ? "" : "s");
- #endif
}
-
- #endif /* RELOC_OP_P */
#ifdef DEBUG_ALPHA
static void
--- 1631,1724 ----
if (! seginfo->fix_root)
return;
! /* First rebuild the fixup chain without the expicit lituse and
! gpdisp_lo16 relocs. */
! prevP = &seginfo->fix_root;
for (fixp = seginfo->fix_root; fixp; fixp = next)
{
next = fixp->fx_next;
fixp->fx_next = (fixS *) 0;
switch (fixp->fx_r_type)
{
! case BFD_RELOC_ALPHA_LITUSE:
! n_slaves++;
! if (fixp->tc_fix_data.info->n_master == 0)
! as_bad_where (fixp->fx_file, fixp->fx_line,
! _("No !literal!%ld was found"),
! fixp->tc_fix_data.info->sequence);
break;
! case BFD_RELOC_ALPHA_GPDISP_LO16:
! n_slaves++;
! if (fixp->tc_fix_data.info->n_master == 0)
as_bad_where (fixp->fx_file, fixp->fx_line,
! _("No ldah !gpdisp!%ld was found"),
fixp->tc_fix_data.info->sequence);
! break;
!
! default:
! *prevP = fixp;
! prevP = &fixp->fx_next;
break;
}
}
! /* If there were any dependent relocations, go and add them back to
! the chain. They are linked through the next_reloc field in
! reverse order, so as we go through the next_reloc chain, we
! effectively reverse the chain once again.
!
! Except if there is more than one !literal for a given sequence
! number. In that case, the programmer and/or compiler is not sure
! how control flows from literal to lituse, and we can't be sure to
! get the relaxation correct.
!
! ??? Well, actually we could, if there are enough lituses such that
! we can make each literal have at least one of each lituse type
! present. Not implemented.
!
! Also suppress the optimization if the !literals/!lituses are spread
! in different segments. This can happen with "intersting" uses of
! inline assembly; examples are present in the Linux kernel semaphores. */
!
! for (fixp = seginfo->fix_root; fixp; fixp = next)
{
! next = fixp->fx_next;
! switch (fixp->fx_r_type)
{
! case BFD_RELOC_ALPHA_ELF_LITERAL:
! if (fixp->tc_fix_data.info->n_master == 1
! && ! fixp->tc_fix_data.info->multi_section_p)
{
! for (slave = fixp->tc_fix_data.info->slaves;
! slave != (fixS *) 0;
! slave = slave->tc_fix_data.next_reloc)
{
! slave->fx_next = fixp->fx_next;
! fixp->fx_next = slave;
}
! }
! break;
! case BFD_RELOC_ALPHA_GPDISP_HI16:
! if (fixp->tc_fix_data.info->n_slaves == 0)
! as_bad_where (fixp->fx_file, fixp->fx_line,
! _("No lda !gpdisp!%ld was found"),
! fixp->tc_fix_data.info->sequence);
! else
! {
! slave = fixp->tc_fix_data.info->slaves;
! slave->fx_next = next;
! fixp->fx_next = slave;
}
+ break;
+
+ default:
+ break;
}
}
}
#ifdef DEBUG_ALPHA
static void
*************** debug_exp (tok, ntok)
*** 1877,1883 ****
case O_gpdisp: name = "O_gpdisp"; break;
case O_gprelhigh: name = "O_gprelhigh"; break;
case O_gprellow: name = "O_gprellow"; break;
! case O_md10: name = "O_md10"; break;
case O_md11: name = "O_md11"; break;
case O_md12: name = "O_md12"; break;
case O_md13: name = "O_md13"; break;
--- 1775,1781 ----
case O_gpdisp: name = "O_gpdisp"; break;
case O_gprelhigh: name = "O_gprelhigh"; break;
case O_gprellow: name = "O_gprellow"; break;
! case O_gprel: name = "O_gprel"; break;
case O_md11: name = "O_md11"; break;
case O_md12: name = "O_md12"; break;
case O_md13: name = "O_md13"; break;
*************** tokenize_arguments (str, tok, ntok)
*** 1910,1922 ****
#ifdef DEBUG_ALPHA
expressionS *orig_tok = tok;
#endif
- #ifdef RELOC_OP_P
char *p;
const struct alpha_reloc_op_tag *r;
int c, i;
size_t len;
int reloc_found_p = 0;
- #endif
memset (tok, 0, sizeof (*tok) * ntok);
--- 1808,1818 ----
*************** tokenize_arguments (str, tok, ntok)
*** 1924,1929 ****
--- 1820,1830 ----
old_input_line_pointer = input_line_pointer;
input_line_pointer = str;
+ #ifdef RELOC_OP_P
+ /* ??? Wrest control of ! away from the regular expression parser. */
+ is_end_of_line[(unsigned char) '!'] = 1;
+ #endif
+
while (tok < end_tok && *input_line_pointer)
{
SKIP_WHITESPACE ();
*************** tokenize_arguments (str, tok, ntok)
*** 1946,1993 ****
if (!saw_arg)
goto err;
! for (p = ++input_line_pointer;
! ((c = *p) != '!' && c != ';' && c != '#' && c != ','
! && !is_end_of_line[c]);
! p++)
! ;
/* Parse !relocation_type */
! len = p - input_line_pointer;
if (len == 0)
{
as_bad (_("No relocation operand"));
goto err_report;
}
- if (c != '!')
- {
- as_bad (_("No !sequence-number after !%s"), input_line_pointer);
- goto err_report;
- }
-
r = &alpha_reloc_op[0];
for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
! {
! if (len == r->length
! && memcmp (input_line_pointer, r->name, len) == 0)
! break;
! }
if (i < 0)
{
! as_bad (_("Unknown relocation operand: !%s"),
! input_line_pointer);
goto err_report;
}
! input_line_pointer = ++p;
/* Parse !sequence_number */
- memset (tok, '\0', sizeof (expressionS));
expression (tok);
!
! if (tok->X_op != O_constant
! || ! ALPHA_RELOC_SEQUENCE_OK (tok->X_add_number))
{
as_bad (_("Bad sequence number: !%s!%s"),
r->name, input_line_pointer);
--- 1847,1898 ----
if (!saw_arg)
goto err;
! ++input_line_pointer;
! SKIP_WHITESPACE ();
! p = input_line_pointer;
! c = get_symbol_end ();
/* Parse !relocation_type */
! len = input_line_pointer - p;
if (len == 0)
{
as_bad (_("No relocation operand"));
goto err_report;
}
r = &alpha_reloc_op[0];
for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
! if (len == r->length && memcmp (p, r->name, len) == 0)
! break;
if (i < 0)
{
! as_bad (_("Unknown relocation operand: !%s"), p);
goto err_report;
}
! *input_line_pointer = c;
! SKIP_WHITESPACE ();
! if (*input_line_pointer != '!')
! {
! if (r->need_seq)
! {
! as_bad (_("No !sequence-number after !%s"),
! input_line_pointer);
! goto err_report;
! }
+ tok->X_op = r->op;
+ tok->X_add_number = 0;
+ reloc_found_p = 1;
+ ++tok;
+ break;
+ }
+
+ input_line_pointer++;
+
/* Parse !sequence_number */
expression (tok);
! if (tok->X_op != O_constant || tok->X_add_number <= 0)
{
as_bad (_("Bad sequence number: !%s!%s"),
r->name, input_line_pointer);
*************** tokenize_arguments (str, tok, ntok)
*** 1998,2004 ****
reloc_found_p = 1;
++tok;
break;
! #endif
case ',':
++input_line_pointer;
--- 1903,1909 ----
reloc_found_p = 1;
++tok;
break;
! #endif /* RELOC_OP_P */
case ',':
++input_line_pointer;
*************** fini:
*** 2050,2067 ****
#ifdef DEBUG_ALPHA
debug_exp (orig_tok, ntok - (end_tok - tok));
#endif
return ntok - (end_tok - tok);
err:
input_line_pointer = old_input_line_pointer;
return TOKENIZE_ERROR;
- #ifdef RELOC_OP_P
err_report:
input_line_pointer = old_input_line_pointer;
return TOKENIZE_ERROR_REPORT;
- #endif
}
/* Search forward through all variants of an opcode looking for a
--- 1955,1979 ----
#ifdef DEBUG_ALPHA
debug_exp (orig_tok, ntok - (end_tok - tok));
#endif
+ #ifdef RELOC_OP_P
+ is_end_of_line[(unsigned char) '!'] = 0;
+ #endif
return ntok - (end_tok - tok);
err:
+ #ifdef RELOC_OP_P
+ is_end_of_line[(unsigned char) '!'] = 0;
+ #endif
input_line_pointer = old_input_line_pointer;
return TOKENIZE_ERROR;
err_report:
+ #ifdef RELOC_OP_P
+ is_end_of_line[(unsigned char) '!'] = 0;
+ #endif
input_line_pointer = old_input_line_pointer;
return TOKENIZE_ERROR_REPORT;
}
/* Search forward through all variants of an opcode looking for a
*************** find_macro_match (first_macro, tok, pnto
*** 2249,2255 ****
case O_register:
case O_pregister:
case O_cpregister:
- #ifdef RELOC_OP_P
case O_literal:
case O_lituse_base:
case O_lituse_bytoff:
--- 2161,2166 ----
*************** find_macro_match (first_macro, tok, pnto
*** 2257,2263 ****
case O_gpdisp:
case O_gprelhigh:
case O_gprellow:
! #endif
goto match_failed;
default:
--- 2168,2174 ----
case O_gpdisp:
case O_gprelhigh:
case O_gprellow:
! case O_gprel:
goto match_failed;
default:
*************** find_macro_match (first_macro, tok, pnto
*** 2266,2303 ****
++tokidx;
break;
- /* optional !literal!<number> */
- case MACRO_LITERAL:
- #ifdef RELOC_OP_P
- if (tokidx < ntok && tok[tokidx].X_op == O_literal)
- tokidx++;
- #endif
- break;
-
- /* optional !lituse_base!<number> */
- case MACRO_BASE:
- #ifdef RELOC_OP_P
- if (tokidx < ntok && tok[tokidx].X_op == O_lituse_base)
- tokidx++;
- #endif
- break;
-
- /* optional !lituse_bytoff!<number> */
- case MACRO_BYTOFF:
- #ifdef RELOC_OP_P
- if (tokidx < ntok && tok[tokidx].X_op == O_lituse_bytoff)
- tokidx++;
- #endif
- break;
-
- /* optional !lituse_jsr!<number> */
- case MACRO_JSR:
- #ifdef RELOC_OP_P
- if (tokidx < ntok && tok[tokidx].X_op == O_lituse_jsr)
- tokidx++;
- #endif
- break;
-
match_failed:
while (*arg != MACRO_EOA)
++arg;
--- 2177,2182 ----
*************** insert_operand (insn, operand, val, file
*** 2372,2383 ****
*/
static void
! assemble_insn (opcode, tok, ntok, insn)
const struct alpha_opcode *opcode;
const expressionS *tok;
int ntok;
struct alpha_insn *insn;
{
const unsigned char *argidx;
unsigned image;
int tokidx = 0;
--- 2251,2265 ----
*/
static void
! assemble_insn (opcode, tok, ntok, insn, reloc)
const struct alpha_opcode *opcode;
const expressionS *tok;
int ntok;
struct alpha_insn *insn;
+ bfd_reloc_code_real_type reloc;
{
+ const struct alpha_operand *reloc_operand = NULL;
+ const expressionS *reloc_exp = NULL;
const unsigned char *argidx;
unsigned image;
int tokidx = 0;
*************** assemble_insn (opcode, tok, ntok, insn)
*** 2433,2456 ****
case O_constant:
image = insert_operand (image, operand, t->X_add_number, NULL, 0);
break;
default:
! {
! struct alpha_fixup *fixup;
! if (insn->nfixups >= MAX_INSN_FIXUPS)
! as_fatal (_("too many fixups"));
! fixup = &insn->fixups[insn->nfixups++];
! fixup->exp = *t;
! fixup->reloc = operand->default_reloc;
! }
break;
}
}
insn->insn = image;
}
--- 2315,2399 ----
case O_constant:
image = insert_operand (image, operand, t->X_add_number, NULL, 0);
+ assert (reloc_operand == NULL);
+ reloc_operand = operand;
+ reloc_exp = t;
break;
default:
! /* This is only 0 for fields that should contain registers,
! which means this pattern shouldn't have matched. */
! if (operand->default_reloc == 0)
! abort ();
! /* There is one special case for which an insn receives two
! relocations, and thus the user-supplied reloc does not
! override the operand reloc. */
! if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
! {
! struct alpha_fixup *fixup;
! if (insn->nfixups >= MAX_INSN_FIXUPS)
! as_fatal (_("too many fixups"));
! fixup = &insn->fixups[insn->nfixups++];
! fixup->exp = *t;
! fixup->reloc = BFD_RELOC_ALPHA_HINT;
! }
! else
! {
! if (reloc == BFD_RELOC_UNUSED)
! reloc = operand->default_reloc;
!
! assert (reloc_operand == NULL);
! reloc_operand = operand;
! reloc_exp = t;
! }
break;
}
}
+ if (reloc != BFD_RELOC_UNUSED)
+ {
+ struct alpha_fixup *fixup;
+
+ if (insn->nfixups >= MAX_INSN_FIXUPS)
+ as_fatal (_("too many fixups"));
+
+ /* ??? My but this is hacky. But the OSF/1 assembler uses the same
+ relocation tag for both ldah and lda with gpdisp. Choose the
+ correct internal relocation based on the opcode. */
+ if (reloc == BFD_RELOC_ALPHA_GPDISP)
+ {
+ if (strcmp (opcode->name, "ldah") == 0)
+ reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
+ else if (strcmp (opcode->name, "lda") == 0)
+ reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
+ else
+ as_bad (_("invalid relocation for instruction"));
+ }
+
+ /* If this is a real relocation (as opposed to a lituse hint), then
+ the relocation width should match the operand width. */
+ else if (reloc < BFD_RELOC_UNUSED)
+ {
+ reloc_howto_type *reloc_howto
+ = bfd_reloc_type_lookup (stdoutput, reloc);
+ if (reloc_howto->bitsize != reloc_operand->bits)
+ {
+ as_bad (_("invalid relocation for field"));
+ return;
+ }
+ }
+
+ fixup = &insn->fixups[insn->nfixups++];
+ if (reloc_exp)
+ fixup->exp = *reloc_exp;
+ else
+ fixup->exp.X_op = O_absent;
+ fixup->reloc = reloc;
+ }
+
insn->insn = image;
}
*************** emit_insn (insn)
*** 2485,2496 ****
{
const struct alpha_operand *operand = (const struct alpha_operand *) 0;
struct alpha_fixup *fixup = &insn->fixups[i];
int size, pcrel;
fixS *fixP;
- #ifdef RELOC_OP_P
- char buffer[ALPHA_RELOC_DIGITS];
- struct alpha_literal_tag *info;
- #endif
/* Some fixups are only used internally and so have no howto */
if ((int) fixup->reloc < 0)
--- 2428,2436 ----
{
const struct alpha_operand *operand = (const struct alpha_operand *) 0;
struct alpha_fixup *fixup = &insn->fixups[i];
+ struct alpha_reloc_tag *info;
int size, pcrel;
fixS *fixP;
/* Some fixups are only used internally and so have no howto */
if ((int) fixup->reloc < 0)
*************** emit_insn (insn)
*** 2499,2541 ****
size = 4;
pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
}
else
! switch (fixup->reloc)
! {
! #ifdef OBJ_ELF
! /* These relocation types are only used internally. */
! case BFD_RELOC_ALPHA_GPDISP_HI16:
! case BFD_RELOC_ALPHA_GPDISP_LO16:
! size = 2;
! pcrel = 0;
! break;
! #endif
! #ifdef RELOC_OP_P
! /* and these also are internal only relocations */
! case BFD_RELOC_ALPHA_USER_LITERAL:
! case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
! case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
! case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
! case BFD_RELOC_ALPHA_USER_GPDISP:
! case BFD_RELOC_ALPHA_USER_GPRELHIGH:
! case BFD_RELOC_ALPHA_USER_GPRELLOW:
! size = 2;
! pcrel = 0;
! break;
! #endif
! default:
! {
! reloc_howto_type *reloc_howto
! = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
! assert (reloc_howto);
! size = bfd_get_reloc_size (reloc_howto);
! pcrel = reloc_howto->pc_relative;
! }
! assert (size >= 1 && size <= 4);
! break;
! }
fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
&fixup->exp, pcrel, fixup->reloc);
--- 2439,2462 ----
size = 4;
pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
}
+ else if (fixup->reloc > BFD_RELOC_UNUSED
+ || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
+ || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
+ {
+ size = 2;
+ pcrel = 0;
+ }
else
! {
! reloc_howto_type *reloc_howto
! = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
! assert (reloc_howto);
! size = bfd_get_reloc_size (reloc_howto);
! assert (size >= 1 && size <= 4);
! pcrel = reloc_howto->pc_relative;
! }
fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
&fixup->exp, pcrel, fixup->reloc);
*************** emit_insn (insn)
*** 2544,2622 ****
and copy in the sequence number for the explicit relocations. */
switch (fixup->reloc)
{
! case BFD_RELOC_ALPHA_GPDISP_LO16:
! #ifdef OBJ_ECOFF
! case BFD_RELOC_ALPHA_LITERAL:
! #endif
! #ifdef OBJ_ELF
! case BFD_RELOC_ALPHA_ELF_LITERAL:
! #endif
case BFD_RELOC_GPREL32:
fixP->fx_no_overflow = 1;
break;
! #ifdef RELOC_OP_P
! case BFD_RELOC_ALPHA_USER_LITERAL:
fixP->fx_no_overflow = 1;
! sprintf (buffer, "!%u", insn->sequence[i]);
! info = ((struct alpha_literal_tag *)
! hash_find (alpha_literal_hash, buffer));
! if (! info)
! {
! size_t len = strlen (buffer);
! const char *errmsg;
! info = ((struct alpha_literal_tag *)
! xcalloc (sizeof (struct alpha_literal_tag) + len, 1));
! info->segment = now_seg;
! info->sequence = insn->sequence[i];
! strcpy (info->string, buffer);
! errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
! if (errmsg)
! as_bad (errmsg);
! }
! ++info->n_literals;
if (info->segment != now_seg)
info->multi_section_p = 1;
-
fixP->tc_fix_data.info = info;
break;
! case BFD_RELOC_ALPHA_USER_LITUSE_BASE:
! case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF:
! case BFD_RELOC_ALPHA_USER_LITUSE_JSR:
! sprintf (buffer, "!%u", insn->sequence[i]);
! info = ((struct alpha_literal_tag *)
! hash_find (alpha_literal_hash, buffer));
!
! if (! info)
! {
! size_t len = strlen (buffer);
! const char *errmsg;
!
! info = ((struct alpha_literal_tag *)
! xcalloc (sizeof (struct alpha_literal_tag) + len, 1));
! info->segment = now_seg;
! info->sequence = insn->sequence[i];
! strcpy (info->string, buffer);
! errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
! if (errmsg)
! as_bad (errmsg);
! }
! info->n_lituses++;
fixP->tc_fix_data.info = info;
! fixP->tc_fix_data.next_lituse = info->lituse;
! info->lituse = fixP;
if (info->segment != now_seg)
info->multi_section_p = 1;
-
break;
- #endif
default:
if ((int) fixup->reloc < 0)
--- 2465,2539 ----
and copy in the sequence number for the explicit relocations. */
switch (fixup->reloc)
{
! case BFD_RELOC_ALPHA_HINT:
case BFD_RELOC_GPREL32:
+ case BFD_RELOC_GPREL16:
+ case BFD_RELOC_ALPHA_GPREL_HI16:
+ case BFD_RELOC_ALPHA_GPREL_LO16:
fixP->fx_no_overflow = 1;
break;
! case BFD_RELOC_ALPHA_GPDISP_HI16:
fixP->fx_no_overflow = 1;
! fixP->fx_addsy = section_symbol (now_seg);
! fixP->fx_offset = 0;
! info = get_alpha_reloc_tag (insn->sequence);
! if (++info->n_master > 1)
! as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
! if (info->segment != now_seg)
! as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
! insn->sequence);
! fixP->tc_fix_data.info = info;
! break;
! case BFD_RELOC_ALPHA_GPDISP_LO16:
! fixP->fx_no_overflow = 1;
! info = get_alpha_reloc_tag (insn->sequence);
! if (++info->n_slaves > 1)
! as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
! if (info->segment != now_seg)
! as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
! insn->sequence);
! fixP->tc_fix_data.info = info;
! info->slaves = fixP;
! break;
! case BFD_RELOC_ALPHA_LITERAL:
! case BFD_RELOC_ALPHA_ELF_LITERAL:
! fixP->fx_no_overflow = 1;
+ info = get_alpha_reloc_tag (insn->sequence);
+ info->n_master++;
if (info->segment != now_seg)
info->multi_section_p = 1;
fixP->tc_fix_data.info = info;
break;
! case DUMMY_RELOC_LITUSE_ADDR:
! fixP->fx_offset = LITUSE_ADDR;
! goto do_lituse;
! case DUMMY_RELOC_LITUSE_BASE:
! fixP->fx_offset = LITUSE_BASE;
! goto do_lituse;
! case DUMMY_RELOC_LITUSE_BYTOFF:
! fixP->fx_offset = LITUSE_BYTOFF;
! goto do_lituse;
! case DUMMY_RELOC_LITUSE_JSR:
! fixP->fx_offset = LITUSE_JSR;
! do_lituse:
! fixP->fx_addsy = section_symbol (now_seg);
! fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
! info = get_alpha_reloc_tag (insn->sequence);
! info->n_slaves++;
fixP->tc_fix_data.info = info;
! fixP->tc_fix_data.next_reloc = info->slaves;
! info->slaves = fixP;
if (info->segment != now_seg)
info->multi_section_p = 1;
break;
default:
if ((int) fixup->reloc < 0)
*************** assemble_tokens_to_insn (opname, tok, nt
*** 2652,2658 ****
opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
if (opcode)
{
! assemble_insn (opcode, tok, ntok, insn);
return;
}
else if (cpumatch)
--- 2569,2575 ----
opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
if (opcode)
{
! assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
return;
}
else if (cpumatch)
*************** assemble_tokens (opname, tok, ntok, loca
*** 2679,2688 ****
const struct alpha_opcode *opcode;
const struct alpha_macro *macro;
int cpumatch = 1;
! /* search macros */
! if (local_macros_on)
{
macro = ((const struct alpha_macro *)
hash_find (alpha_macro_hash, opname));
if (macro)
--- 2596,2611 ----
const struct alpha_opcode *opcode;
const struct alpha_macro *macro;
int cpumatch = 1;
+ bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
! /* If a user-specified relocation is present, this is not a macro. */
! if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
{
+ reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
+ ntok--;
+ }
+ else if (local_macros_on)
+ {
macro = ((const struct alpha_macro *)
hash_find (alpha_macro_hash, opname));
if (macro)
*************** assemble_tokens (opname, tok, ntok, loca
*** 2697,2713 ****
}
}
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, opname);
- ntok--;
- }
- #endif
-
/* search opcodes */
opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
if (opcode)
--- 2620,2625 ----
*************** assemble_tokens (opname, tok, ntok, loca
*** 2717,2734 ****
if (opcode)
{
struct alpha_insn insn;
! assemble_insn (opcode, tok, ntok, &insn);
emit_insn (&insn);
return;
}
}
if (found_something)
! if (cpumatch)
! as_bad (_("inappropriate arguments for opcode `%s'"), opname);
! else
! as_bad (_("opcode `%s' not supported for target %s"), opname,
! alpha_target_name);
else
as_bad (_("unknown opcode `%s'"), opname);
}
--- 2629,2653 ----
if (opcode)
{
struct alpha_insn insn;
! assemble_insn (opcode, tok, ntok, &insn, reloc);
!
! /* Copy the sequence number for the reloc from the reloc token. */
! if (reloc != BFD_RELOC_UNUSED)
! insn.sequence = tok[ntok].X_add_number;
!
emit_insn (&insn);
return;
}
}
if (found_something)
! {
! if (cpumatch)
! as_bad (_("inappropriate arguments for opcode `%s'"), opname);
! else
! as_bad (_("opcode `%s' not supported for target %s"), opname,
! alpha_target_name);
! }
else
as_bad (_("unknown opcode `%s'"), opname);
}
*************** FIXME
*** 2763,2779 ****
expressionS newtok[3];
expressionS addend;
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, "ldgp");
- ntok--;
- }
- #endif
-
#ifdef OBJ_ECOFF
if (regno (tok[2].X_add_number) == AXP_REG_PV)
ecoff_set_gp_prolog_size (0);
--- 2682,2687 ----
*************** FIXME
*** 2797,2802 ****
--- 2705,2711 ----
insn.nfixups = 1;
insn.fixups[0].exp = addend;
insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
+ insn.sequence = next_sequence_num;
emit_insn (&insn);
*************** FIXME
*** 2811,2816 ****
--- 2720,2726 ----
insn.nfixups = 1;
insn.fixups[0].exp = addend;
insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
+ insn.sequence = next_sequence_num--;
emit_insn (&insn);
#endif /* OBJ_ECOFF || OBJ_ELF */
*************** add_to_link_pool (basesym, sym, addend)
*** 2890,2907 ****
If explicit relocations of the form !literal!<number> are allowed,
and used, then explict_reloc with be an expression pointer.
! Finally, the return value is true if the calling macro may emit a
! LITUSE reloc if otherwise appropriate. */
! static int
! load_expression (targreg, exp, pbasereg, poffset, explicit_reloc)
int targreg;
const expressionS *exp;
int *pbasereg;
expressionS *poffset;
- const expressionS *explicit_reloc;
{
! int emit_lituse = 0;
offsetT addend = exp->X_add_number;
int basereg = *pbasereg;
struct alpha_insn insn;
--- 2800,2817 ----
If explicit relocations of the form !literal!<number> are allowed,
and used, then explict_reloc with be an expression pointer.
! Finally, the return value is nonzero if the calling macro may emit
! a LITUSE reloc if otherwise appropriate; the return value is the
! sequence number to use. */
! static long
! load_expression (targreg, exp, pbasereg, poffset)
int targreg;
const expressionS *exp;
int *pbasereg;
expressionS *poffset;
{
! long emit_lituse = 0;
offsetT addend = exp->X_add_number;
int basereg = *pbasereg;
struct alpha_insn insn;
*************** load_expression (targreg, exp, pbasereg,
*** 2951,2959 ****
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
- assert (explicit_reloc == (const expressionS *) 0);
assert (insn.nfixups == 1);
insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
#endif /* OBJ_ECOFF */
#ifdef OBJ_ELF
/* emit "ldq r, gotoff(gp)" */
--- 2861,2869 ----
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
assert (insn.nfixups == 1);
insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
+ insn.sequence = emit_lituse = next_sequence_num--;
#endif /* OBJ_ECOFF */
#ifdef OBJ_ELF
/* emit "ldq r, gotoff(gp)" */
*************** load_expression (targreg, exp, pbasereg,
*** 2990,3014 ****
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
assert (insn.nfixups == 1);
! if (!explicit_reloc)
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
! else
! {
! #ifdef RELOC_OP_P
! insn.fixups[0].reloc
! = (ALPHA_RELOC_TABLE (explicit_reloc->X_op))->reloc;
! insn.sequence[0] = explicit_reloc->X_add_number;
! #else
! abort ();
! #endif
! }
#endif /* OBJ_ELF */
#ifdef OBJ_EVAX
offsetT link;
/* Find symbol or symbol pointer in link section. */
- assert (explicit_reloc == (const expressionS *) 0);
if (exp->X_add_symbol == alpha_evax_proc.symbol)
{
if (range_signed_16 (addend))
--- 2900,2913 ----
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
assert (insn.nfixups == 1);
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
! insn.sequence = emit_lituse = next_sequence_num--;
#endif /* OBJ_ELF */
#ifdef OBJ_EVAX
offsetT link;
/* Find symbol or symbol pointer in link section. */
if (exp->X_add_symbol == alpha_evax_proc.symbol)
{
if (range_signed_16 (addend))
*************** load_expression (targreg, exp, pbasereg,
*** 3050,3057 ****
emit_insn (&insn);
#ifndef OBJ_EVAX
- emit_lituse = 1;
-
if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
{
/* emit "addq r, base, r" */
--- 2949,2954 ----
*************** load_expression (targreg, exp, pbasereg,
*** 3067,3080 ****
break;
case O_constant:
- assert (explicit_reloc == (const expressionS *) 0);
break;
case O_subtract:
/* Assume that this difference expression will be resolved to an
absolute value and that that value will fit in 16 bits. */
- assert (explicit_reloc == (const expressionS *) 0);
set_tok_reg (newtok[0], targreg);
newtok[1] = *exp;
set_tok_preg (newtok[2], basereg);
--- 2964,2975 ----
*************** load_expression (targreg, exp, pbasereg,
*** 3101,3108 ****
if (!range_signed_32 (addend))
{
offsetT lit;
! /* for 64-bit addends, just put it in the literal pool */
#ifdef OBJ_EVAX
/* emit "ldq targreg, lit(basereg)" */
--- 2996,3004 ----
if (!range_signed_32 (addend))
{
offsetT lit;
+ long seq_num = next_sequence_num--;
! /* For 64-bit addends, just put it in the literal pool. */
#ifdef OBJ_EVAX
/* emit "ldq targreg, lit(basereg)" */
*************** load_expression (targreg, exp, pbasereg,
*** 3162,3167 ****
--- 3058,3064 ----
#ifdef OBJ_ELF
insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
#endif
+ insn.sequence = seq_num;
emit_insn (&insn);
*************** load_expression (targreg, exp, pbasereg,
*** 3173,3188 ****
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
assert (insn.nfixups < MAX_INSN_FIXUPS);
! if (insn.nfixups > 0)
! {
! memmove (&insn.fixups[1], &insn.fixups[0],
! sizeof (struct alpha_fixup) * insn.nfixups);
! }
insn.nfixups++;
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
! insn.fixups[0].exp.X_op = O_symbol;
! insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg);
! insn.fixups[0].exp.X_add_number = LITUSE_BASE;
emit_lituse = 0;
emit_insn (&insn);
--- 3070,3079 ----
assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
! insn.sequence = seq_num;
emit_lituse = 0;
emit_insn (&insn);
*************** load_expression (targreg, exp, pbasereg,
*** 3262,3327 ****
large constants. */
static void
! emit_lda (tok, ntok, opname)
const expressionS *tok;
int ntok;
! const PTR opname;
{
int basereg;
- const expressionS *reloc = (const expressionS *) 0;
-
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const struct alpha_reloc_op_tag *r;
-
- reloc = &tok[ntok - 1];
- r = ALPHA_RELOC_TABLE (reloc->X_op);
- switch (reloc->X_op)
- {
- default:
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc->X_add_number, (const char *) opname);
-
- reloc = (const expressionS *) 0;
- ntok--;
- break;
-
- case O_literal:
- ntok--;
- break;
-
- /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
- it is really too general for our needs. Instead just generate the
- lda directly. */
- case O_lituse_base:
- if (ntok != 4
- || tok[0].X_op != O_register
- || !is_ir_num (tok[0].X_add_number)
- || tok[1].X_op != O_constant
- || tok[2].X_op != O_pregister
- || !is_ir_num (tok[2].X_add_number))
- {
- as_bad (_("bad instruction format for lda !%s!%ld"), r->name,
- (long) reloc->X_add_number);
-
- reloc = (const expressionS *) 0;
- ntok--;
- break;
- }
-
- emit_loadstore (tok, ntok, "lda");
- return;
- }
- }
- #endif
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
basereg = tok[2].X_add_number;
! (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, reloc);
}
/* The ldah macro differs from the ldah instruction in that it has $31
--- 3153,3171 ----
large constants. */
static void
! emit_lda (tok, ntok, unused)
const expressionS *tok;
int ntok;
! const PTR unused ATTRIBUTE_UNUSED;
{
int basereg;
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
basereg = tok[2].X_add_number;
! (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
}
/* The ldah macro differs from the ldah instruction in that it has $31
*************** emit_ldah (tok, ntok, unused)
*** 3335,3351 ****
{
expressionS newtok[3];
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, "ldah");
- ntok--;
- }
- #endif
-
newtok[0] = tok[0];
newtok[1] = tok[1];
set_tok_preg (newtok[2], AXP_REG_ZERO);
--- 3179,3184 ----
*************** emit_ir_load (tok, ntok, opname)
*** 3363,3445 ****
int ntok;
const PTR opname;
{
! int basereg, lituse;
expressionS newtok[3];
struct alpha_insn insn;
- #ifdef RELOC_OP_P
- const expressionS *reloc = (const expressionS *) 0;
-
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const struct alpha_reloc_op_tag *r;
-
- reloc = &tok[ntok - 1];
- switch (reloc->X_op)
- {
- case O_lituse_base:
- ntok--;
- break;
-
- case O_literal:
- if (strcmp ((const char *) opname, "ldq") == 0)
- {
- emit_lda (tok, ntok, opname);
- return;
- }
-
- /* fall through */
- default:
- ntok--;
- r = ALPHA_RELOC_TABLE (reloc->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc->X_add_number, (const char *) opname);
- }
- }
- #endif
-
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
basereg = tok[2].X_add_number;
lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
! &newtok[1], (const expressionS *) 0);
newtok[0] = tok[0];
set_tok_preg (newtok[2], basereg);
assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
- #ifdef RELOC_OP_P
- if (reloc)
- {
- int nfixups = insn.nfixups;
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc->X_op);
-
- assert (nfixups < MAX_INSN_FIXUPS);
- insn.fixups[nfixups].reloc = r->reloc;
- insn.fixups[nfixups].exp.X_op = O_symbol;
- insn.fixups[nfixups].exp.X_add_symbol = section_symbol (now_seg);
- insn.fixups[nfixups].exp.X_add_number = r->lituse;
- insn.sequence[nfixups] = reloc->X_add_number;
- insn.nfixups++;
- }
- #endif
-
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! if (insn.nfixups > 0)
! {
! memmove (&insn.fixups[1], &insn.fixups[0],
! sizeof (struct alpha_fixup) * insn.nfixups);
! }
insn.nfixups++;
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
! insn.fixups[0].exp.X_op = O_symbol;
! insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg);
! insn.fixups[0].exp.X_add_number = LITUSE_BASE;
}
emit_insn (&insn);
--- 3196,3226 ----
int ntok;
const PTR opname;
{
! int basereg;
! long lituse;
expressionS newtok[3];
struct alpha_insn insn;
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
basereg = tok[2].X_add_number;
lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
! &newtok[1]);
newtok[0] = tok[0];
set_tok_preg (newtok[2], basereg);
assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
! insn.sequence = lituse;
}
emit_insn (&insn);
*************** emit_loadstore (tok, ntok, opname)
*** 3454,3478 ****
int ntok;
const PTR opname;
{
! int basereg, lituse;
expressionS newtok[3];
struct alpha_insn insn;
- #ifdef RELOC_OP_P
- const expressionS *reloc = (const expressionS *) 0;
-
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- reloc = &tok[--ntok];
- if (reloc->X_op != O_lituse_base)
- {
- const struct alpha_reloc_op_tag *r = &alpha_reloc_op[reloc->X_md];
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc->X_add_number, (const char *) opname);
- }
- }
- #endif
-
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
--- 3235,3245 ----
int ntok;
const PTR opname;
{
! int basereg;
! long lituse;
expressionS newtok[3];
struct alpha_insn insn;
if (ntok == 2)
basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
else
*************** emit_loadstore (tok, ntok, opname)
*** 3483,3490 ****
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
! lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1],
! (const expressionS *) 0);
}
else
{
--- 3250,3256 ----
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
! lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
}
else
{
*************** emit_loadstore (tok, ntok, opname)
*** 3497,3531 ****
assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
- #ifdef RELOC_OP_P
- if (reloc)
- {
- int nfixups = insn.nfixups;
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc->X_op);
-
- assert (nfixups < MAX_INSN_FIXUPS);
- insn.fixups[nfixups].reloc = r->reloc;
- insn.fixups[nfixups].exp.X_op = O_symbol;
- insn.fixups[nfixups].exp.X_add_symbol = section_symbol (now_seg);
- insn.fixups[nfixups].exp.X_add_number = r->lituse;
- insn.sequence[nfixups] = reloc->X_add_number;
- insn.nfixups++;
- }
- #endif
-
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! if (insn.nfixups > 0)
! {
! memmove (&insn.fixups[1], &insn.fixups[0],
! sizeof (struct alpha_fixup) * insn.nfixups);
! }
insn.nfixups++;
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
! insn.fixups[0].exp.X_op = O_symbol;
! insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg);
! insn.fixups[0].exp.X_add_number = LITUSE_BASE;
}
emit_insn (&insn);
--- 3263,3275 ----
assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
! insn.sequence = lituse;
}
emit_insn (&insn);
*************** emit_ldXu (tok, ntok, vlgsize)
*** 3544,3584 ****
else
{
expressionS newtok[3];
!
! #ifdef RELOC_OP_P
! if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
! {
! const expressionS *reloc_exp = &tok[ntok - 1];
! const struct alpha_reloc_op_tag *r
! = ALPHA_RELOC_TABLE (reloc_exp->X_op);
!
! as_bad (_("Cannot use !%s!%d with %s"), r->name,
! (int) reloc_exp->X_add_number, "ldbu/ldwu");
! ntok--;
! }
! #endif
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
/* emit "lda $at, exp" */
! memcpy (newtok, tok, sizeof (expressionS) * ntok);
! newtok[0].X_add_number = AXP_REG_AT;
! assemble_tokens ("lda", newtok, ntok, 1);
/* emit "ldq_u targ, 0($at)" */
newtok[0] = tok[0];
set_tok_const (newtok[1], 0);
! set_tok_preg (newtok[2], AXP_REG_AT);
! assemble_tokens ("ldq_u", newtok, 3, 1);
/* emit "extXl targ, $at, targ" */
! set_tok_reg (newtok[1], AXP_REG_AT);
newtok[2] = newtok[0];
! assemble_tokens (extXl_op[(long) vlgsize], newtok, 3, 1);
}
}
--- 3288,3344 ----
else
{
expressionS newtok[3];
! struct alpha_insn insn;
! int basereg;
! long lituse;
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant
+ ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
/* emit "lda $at, exp" */
! lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
/* emit "ldq_u targ, 0($at)" */
newtok[0] = tok[0];
set_tok_const (newtok[1], 0);
! set_tok_preg (newtok[2], basereg);
! assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
/* emit "extXl targ, $at, targ" */
! set_tok_reg (newtok[1], basereg);
newtok[2] = newtok[0];
! assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
!
! if (lituse)
! {
! assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
! insn.nfixups++;
! insn.sequence = lituse;
! }
!
! emit_insn (&insn);
}
}
*************** emit_ldil (tok, ntok, unused)
*** 3673,3689 ****
{
expressionS newtok[2];
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, "ldil");
- ntok--;
- }
- #endif
-
memcpy (newtok, tok, sizeof (newtok));
newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
--- 3433,3438 ----
*************** emit_stX (tok, ntok, vlgsize)
*** 3705,3740 ****
else
{
expressionS newtok[3];
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
/* emit "lda $at, exp" */
! memcpy (newtok, tok, sizeof (expressionS) * ntok);
! newtok[0].X_add_number = AXP_REG_AT;
! assemble_tokens ("lda", newtok, ntok, 1);
/* emit "ldq_u $t9, 0($at)" */
set_tok_reg (newtok[0], AXP_REG_T9);
set_tok_const (newtok[1], 0);
! set_tok_preg (newtok[2], AXP_REG_AT);
! assemble_tokens ("ldq_u", newtok, 3, 1);
/* emit "insXl src, $at, $t10" */
newtok[0] = tok[0];
! set_tok_reg (newtok[1], AXP_REG_AT);
set_tok_reg (newtok[2], AXP_REG_T10);
! assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
/* emit "mskXl $t9, $at, $t9" */
set_tok_reg (newtok[0], AXP_REG_T9);
newtok[2] = newtok[0];
! assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
/* emit "or $t9, $t10, $t9" */
set_tok_reg (newtok[1], AXP_REG_T10);
--- 3454,3529 ----
else
{
expressionS newtok[3];
+ struct alpha_insn insn;
+ int basereg;
+ long lituse;
if (alpha_noat_on)
as_bad (_("macro requires $at register while noat in effect"));
+ if (ntok == 2)
+ basereg = (tok[1].X_op == O_constant
+ ? AXP_REG_ZERO : alpha_gp_register);
+ else
+ basereg = tok[2].X_add_number;
+
/* emit "lda $at, exp" */
! lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
/* emit "ldq_u $t9, 0($at)" */
set_tok_reg (newtok[0], AXP_REG_T9);
set_tok_const (newtok[1], 0);
! set_tok_preg (newtok[2], basereg);
! assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
!
! if (lituse)
! {
! assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
! insn.nfixups++;
! insn.sequence = lituse;
! }
!
! emit_insn (&insn);
/* emit "insXl src, $at, $t10" */
newtok[0] = tok[0];
! set_tok_reg (newtok[1], basereg);
set_tok_reg (newtok[2], AXP_REG_T10);
! assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
!
! if (lituse)
! {
! assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
! insn.nfixups++;
! insn.sequence = lituse;
! }
+ emit_insn (&insn);
+
/* emit "mskXl $t9, $at, $t9" */
set_tok_reg (newtok[0], AXP_REG_T9);
newtok[2] = newtok[0];
! assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
+ if (lituse)
+ {
+ assert (insn.nfixups < MAX_INSN_FIXUPS);
+ insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
+ insn.fixups[insn.nfixups].exp.X_op = O_absent;
+ insn.nfixups++;
+ insn.sequence = lituse;
+ }
+
+ emit_insn (&insn);
+
/* emit "or $t9, $t10, $t9" */
set_tok_reg (newtok[1], AXP_REG_T10);
*************** emit_stX (tok, ntok, vlgsize)
*** 3742,3750 ****
/* emit "stq_u $t9, 0($at) */
! set_tok_const (newtok[1], 0);
set_tok_preg (newtok[2], AXP_REG_AT);
! assemble_tokens ("stq_u", newtok, 3, 1);
}
}
--- 3531,3550 ----
/* emit "stq_u $t9, 0($at) */
! set_tok_const(newtok[1], 0);
set_tok_preg (newtok[2], AXP_REG_AT);
! assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
!
! if (lituse)
! {
! assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
! insn.nfixups++;
! insn.sequence = lituse;
! }
!
! emit_insn (&insn);
}
}
*************** emit_sextX (tok, ntok, vlgsize)
*** 3848,3866 ****
int bitshift = 64 - 8 * (1 << lgsize);
expressionS newtok[3];
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r
- = ALPHA_RELOC_TABLE (reloc_exp->X_op);
-
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, "setxt");
- ntok--;
- }
- #endif
-
/* emit "sll src,bits,dst" */
newtok[0] = tok[0];
--- 3648,3653 ----
*************** emit_division (tok, ntok, symname)
*** 3907,3923 ****
symbolS *sym;
expressionS newtok[3];
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, (char char *) symname);
- ntok--;
- }
- #endif
-
xr = regno (tok[0].X_add_number);
yr = regno (tok[1].X_add_number);
--- 3694,3699 ----
*************** emit_division (tok, ntok, symname)
*** 4017,4033 ****
symbolS *sym;
expressionS newtok[3];
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, (const char *) symname);
- ntok--;
- }
- #endif
-
xr = regno (tok[0].X_add_number);
yr = regno (tok[1].X_add_number);
--- 3793,3798 ----
*************** emit_jsrjmp (tok, ntok, vopname)
*** 4122,4139 ****
const char *opname = (const char *) vopname;
struct alpha_insn insn;
expressionS newtok[3];
! int r, tokidx = 0, lituse = 0;
!
! #ifdef RELOC_OP_P
! if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
! {
! const expressionS *reloc_exp = &tok[ntok - 1];
! const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
! as_bad (_("Cannot use !%s!%d with %s"), r->name,
! (int) reloc_exp->X_add_number, opname);
! ntok--;
! }
! #endif
if (tokidx < ntok && tok[tokidx].X_op == O_register)
r = regno (tok[tokidx++].X_add_number);
--- 3887,3894 ----
const char *opname = (const char *) vopname;
struct alpha_insn insn;
expressionS newtok[3];
! int r, tokidx = 0;
! long lituse = 0;
if (tokidx < ntok && tok[tokidx].X_op == O_register)
r = regno (tok[tokidx++].X_add_number);
*************** emit_jsrjmp (tok, ntok, vopname)
*** 4151,4158 ****
else
{
int basereg = alpha_gp_register;
! lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL,
! (const expressionS *) 0);
}
#endif
--- 3906,3912 ----
else
{
int basereg = alpha_gp_register;
! lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
}
#endif
*************** emit_jsrjmp (tok, ntok, vopname)
*** 4169,4188 ****
assemble_tokens_to_insn (opname, newtok, 3, &insn);
- /* add the LITUSE fixup */
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! if (insn.nfixups > 0)
! {
! memmove (&insn.fixups[1], &insn.fixups[0],
! sizeof (struct alpha_fixup) * insn.nfixups);
! }
insn.nfixups++;
! insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
! insn.fixups[0].exp.X_op = O_symbol;
! insn.fixups[0].exp.X_add_symbol = section_symbol (now_seg);
! insn.fixups[0].exp.X_add_number = LITUSE_JSR;
}
emit_insn (&insn);
--- 3923,3935 ----
assemble_tokens_to_insn (opname, newtok, 3, &insn);
if (lituse)
{
assert (insn.nfixups < MAX_INSN_FIXUPS);
! insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
! insn.fixups[insn.nfixups].exp.X_op = O_absent;
insn.nfixups++;
! insn.sequence = lituse;
}
emit_insn (&insn);
*************** emit_retjcr (tok, ntok, vopname)
*** 4200,4216 ****
const char *opname = (const char *) vopname;
expressionS newtok[3];
int r, tokidx = 0;
-
- #ifdef RELOC_OP_P
- if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
- {
- const expressionS *reloc_exp = &tok[ntok - 1];
- const struct alpha_reloc_op_tag *r = ALPHA_RELOC_TABLE (reloc_exp->X_op);
- as_bad (_("Cannot use !%s!%d with %s"), r->name,
- (int) reloc_exp->X_add_number, opname);
- ntok--;
- }
- #endif
if (tokidx < ntok && tok[tokidx].X_op == O_register)
r = regno (tok[tokidx++].X_add_number);
--- 3947,3952 ----
Index: config/tc-alpha.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-alpha.h,v
retrieving revision 1.8
diff -c -p -d -r1.8 tc-alpha.h
*** tc-alpha.h 2001/08/21 00:22:23 1.8
--- tc-alpha.h 2001/09/05 02:39:09
*************** extern void alpha_frob_file_before_adjus
*** 117,127 ****
#define RELOC_OP_P
#endif
! #ifdef RELOC_OP_P
! /* Before the relocations are written, reorder them, so that user supplied
! !lituse relocations follow the appropriate !literal relocations. Also
! convert the gas-internal relocations to the appropriate linker relocations.
! */
#define tc_adjust_symtab() alpha_adjust_symtab ()
extern void alpha_adjust_symtab PARAMS ((void));
--- 117,126 ----
#define RELOC_OP_P
#endif
! /* Before the relocations are written, reorder them, so that user
! supplied !lituse relocations follow the appropriate !literal
! relocations. Also convert the gas-internal relocations to the
! appropriate linker relocations. */
#define tc_adjust_symtab() alpha_adjust_symtab ()
extern void alpha_adjust_symtab PARAMS ((void));
*************** extern void alpha_adjust_symtab PARAMS (
*** 133,146 ****
struct alpha_fix_tag
{
! struct fix *next_lituse; /* next !lituse */
! struct alpha_literal_tag *info; /* other members with same sequence */
};
/* Initialize the TC_FIX_TYPE field. */
#define TC_INIT_FIX_DATA(fixP) \
do { \
! fixP->tc_fix_data.next_lituse = (struct fix *)0; \
fixP->tc_fix_data.info = (struct alpha_literal_tag *)0; \
} while (0)
--- 132,145 ----
struct alpha_fix_tag
{
! struct fix *next_reloc; /* next !lituse or !gpdisp */
! struct alpha_reloc_tag *info; /* other members with same sequence */
};
/* Initialize the TC_FIX_TYPE field. */
#define TC_INIT_FIX_DATA(fixP) \
do { \
! fixP->tc_fix_data.next_reloc = (struct fix *)0; \
fixP->tc_fix_data.info = (struct alpha_literal_tag *)0; \
} while (0)
*************** do { \
*** 148,157 ****
#define TC_FIX_DATA_PRINT(stream,fixP) \
do { \
if (fixP->tc_fix_data.info) \
! fprintf (stderr, "\tinfo = 0x%lx, next_lituse = 0x%lx\n", \
(long)fixP->tc_fix_data.info, \
! (long)fixP->tc_fix_data.next_lituse); \
} while (0)
- #endif
#define DWARF2_LINE_MIN_INSN_LENGTH 4
--- 147,155 ----
#define TC_FIX_DATA_PRINT(stream,fixP) \
do { \
if (fixP->tc_fix_data.info) \
! fprintf (stderr, "\tinfo = 0x%lx, next_reloc = 0x%lx\n", \
(long)fixP->tc_fix_data.info, \
! (long)fixP->tc_fix_data.next_reloc); \
} while (0)
#define DWARF2_LINE_MIN_INSN_LENGTH 4
Index: testsuite/gas/alpha/alpha.exp
===================================================================
RCS file: alpha.exp
diff -N alpha.exp
*** /dev/null Tue May 5 13:32:27 1998
--- alpha.exp Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,33 ----
+ #
+ # Some generic alpha tests
+ #
+
+ proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "alpha $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+ }
+
+ if { [istarget alpha*-*-*] } then {
+
+ set elf [expr [istarget *-*-elf*] \
+ || [istarget *-*-linux*] \
+ || [istarget *-*-freebsd*] \
+ || [istarget *-*-netbsd*] ]
+
+ if $elf {
+ run_dump_test "elf-reloc-1"
+ run_list_test "elf-reloc-2" ""
+ run_list_test "elf-reloc-3" ""
+ run_dump_test "elf-reloc-4"
+ }
+
+ run_dump_test "fp"
+ }
Index: testsuite/gas/alpha/elf-reloc-1.d
===================================================================
RCS file: elf-reloc-1.d
diff -N elf-reloc-1.d
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-1.d Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,21 ----
+ #objdump: -r
+ #name: alpha elf-reloc-1
+
+ .*: file format elf64-alpha
+
+ RELOCATION RECORDS FOR \[\.text\]:
+ OFFSET TYPE VALUE
+ 0*0000004 ELF_LITERAL a
+ 0*0000000 LITUSE \.text\+0x0*0000002
+ 0*000000c LITUSE \.text\+0x0*0000001
+ 0*0000008 ELF_LITERAL b
+ 0*0000010 ELF_LITERAL f
+ 0*0000014 LITUSE \.text\+0x0*0000003
+ 0*0000014 HINT f
+ 0*0000018 GPREL16 c
+ 0*000001c GPRELHIGH d
+ 0*0000020 GPRELLOW e
+ 0*0000024 GPDISP \.text\+0x0*0000008
+ 0*0000030 GPDISP \.text\+0xf*ffffff8
+
+
Index: testsuite/gas/alpha/elf-reloc-1.s
===================================================================
RCS file: elf-reloc-1.s
diff -N elf-reloc-1.s
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-1.s Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,16 ----
+ .set nomacro
+ extbl $3, $2, $3 ! lituse_bytoff ! 1
+ ldq $2, a($29) !literal!1
+ ldq $4, b($29) !literal!2
+ ldq_u $3, 0($2) !lituse_base!1
+ ldq $27, f($29) !literal!5
+ jsr $26, ($27), f !lituse_jsr!5
+
+ lda $0, c($29) !gprel
+ ldah $1, d($29) !gprelhigh
+ lda $1, e($1) !gprellow
+
+ ldah $29, 0($26) !gpdisp!3
+ lda $29, 0($29) !gpdisp!4
+ lda $29, 0($29) !gpdisp!3
+ ldah $29, 0($26) !gpdisp!4
Index: testsuite/gas/alpha/elf-reloc-2.l
===================================================================
RCS file: elf-reloc-2.l
diff -N elf-reloc-2.l
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-2.l Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,4 ----
+ .*: Assembler messages:
+ .*:4: Error: too many ldah insns for !gpdisp!3
+ .*:5: Error: too many lda insns for !gpdisp!3
+ .*:8: Error: both insns for !gpdisp!4 must be in the same section
Index: testsuite/gas/alpha/elf-reloc-2.s
===================================================================
RCS file: elf-reloc-2.s
diff -N elf-reloc-2.s
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-2.s Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,8 ----
+ .text
+ ldah $29,0($26) !gpdisp!3
+ lda $29,0($26) !gpdisp!3
+ ldah $29,0($26) !gpdisp!3
+ lda $29,0($26) !gpdisp!3
+ ldah $29,0($26) !gpdisp!4
+ .section .text2
+ lda $29,0($26) !gpdisp!4
Index: testsuite/gas/alpha/elf-reloc-3.l
===================================================================
RCS file: elf-reloc-3.l
diff -N elf-reloc-3.l
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-3.l Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,3 ----
+ .*: Assembler messages:
+ .*:2: Error: No ldah !gpdisp!2 was found
+ .*:1: Error: No lda !gpdisp!1 was found
Index: testsuite/gas/alpha/elf-reloc-3.s
===================================================================
RCS file: elf-reloc-3.s
diff -N elf-reloc-3.s
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-3.s Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,2 ----
+ ldah $29,0($26) !gpdisp!1
+ lda $29,0($26) !gpdisp!2
Index: testsuite/gas/alpha/elf-reloc-4.d
===================================================================
RCS file: elf-reloc-4.d
diff -N elf-reloc-4.d
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-4.d Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,25 ----
+ #objdump: -r
+ #name: alpha elf-reloc-4
+
+ .*: file format elf64-alpha
+
+ RELOCATION RECORDS FOR \[\.text\]:
+ OFFSET TYPE VALUE
+ 0*0000000 ELF_LITERAL a
+ 0*0000004 LITUSE \.text\+0x0*0000001
+ 0*0000008 LITUSE \.text\+0x0*0000002
+ 0*000000c ELF_LITERAL b
+ 0*0000010 LITUSE \.text\+0x0*0000001
+ 0*0000014 LITUSE \.text\+0x0*0000002
+ 0*0000018 ELF_LITERAL c
+ 0*000001c LITUSE \.text\+0x0*0000001
+ 0*0000020 LITUSE \.text\+0x0*0000002
+ 0*0000024 LITUSE \.text\+0x0*0000002
+ 0*000002c LITUSE \.text\+0x0*0000001
+ 0*0000030 ELF_LITERAL d
+ 0*0000034 LITUSE \.text\+0x0*0000001
+ 0*0000038 LITUSE \.text\+0x0*0000002
+ 0*000003c LITUSE \.text\+0x0*0000002
+ 0*0000044 LITUSE \.text\+0x0*0000001
+
+
Index: testsuite/gas/alpha/elf-reloc-4.s
===================================================================
RCS file: elf-reloc-4.s
diff -N elf-reloc-4.s
*** /dev/null Tue May 5 13:32:27 1998
--- elf-reloc-4.s Tue Sep 4 19:39:09 2001
***************
*** 0 ****
--- 1,4 ----
+ ldbu $1, a
+ ldwu $2, b
+ stb $3, c
+ stw $4, d
Index: testsuite/gas/alpha/fp.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/alpha/fp.d,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 fp.d
*** fp.d 1999/05/03 07:28:48 1.1.1.1
--- fp.d 2001/09/05 02:39:09
***************
*** 1,7 ****
! .*: file format ecoff-littlealpha
! Contents of section .rdata:
0000 71a37909 4f930a40 5441789a cd4b881b q.y.O..@TAx..K..
0010 2a404f93 790971a3 789a5440 5441789a .@O.y.q.x.T@TAx.
0020 00000000 00000000 00000000 00000000 ................
--- 1,9 ----
+ #objdump: -s -j .data
+ #name: alpha fp
! .*: file format .*
! Contents of section .data:
0000 71a37909 4f930a40 5441789a cd4b881b q.y.O..@TAx..K..
0010 2a404f93 790971a3 789a5440 5441789a .@O.y.q.x.T@TAx.
0020 00000000 00000000 00000000 00000000 ................
Index: testsuite/gas/alpha/fp.exp
===================================================================
RCS file: fp.exp
diff -N fp.exp
*** /sourceware/cvs-tmp/cvs2QlnwA Tue Sep 4 19:39:10 2001
--- /dev/null Tue May 5 13:32:27 1998
***************
*** 1,15 ****
- #
- # Alpha OSF/1 tests
- #
-
- if [istarget alpha-*-osf*] then {
- set testname "fp constants (part 2)"
- if [gas_test_old "fp.s" "" "fp constants (part 1)"] then {
- objdump "-s -j .rdata > a.dump"
- if { [regexp_diff "a.dump" "$srcdir/$subdir/fp.d"] == 0 } then {
- pass $testname
- } else {
- fail $testname
- }
- }
- }
--- 0 ----
Index: testsuite/gas/alpha/fp.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/alpha/fp.s,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 fp.s
*** fp.s 1999/05/03 07:28:48 1.1.1.1
--- fp.s 2001/09/05 02:39:09
***************
*** 1,4 ****
! .rdata
# These three formats are 8 bytes each.
.t_floating 3.32192809488736218171e0
# .byte 0x71, 0xa3, 0x79, 0x09, 0x4f, 0x93, 0x0a, 0x40
--- 1,4 ----
! .data
# These three formats are 8 bytes each.
.t_floating 3.32192809488736218171e0
# .byte 0x71, 0xa3, 0x79, 0x09, 0x4f, 0x93, 0x0a, 0x40
More information about the Binutils
mailing list