This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

alpha elf reloc fixes, part 1


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]