gas TC_PARSE_CONS_EXPRESSION communication with TC_CONS_FIX_NEW
authorAlan Modra <amodra@gmail.com>
Tue, 8 Apr 2014 05:08:22 +0000 (14:38 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 9 Apr 2014 04:59:05 +0000 (14:29 +0930)
A number of targets pass extra information from TC_PARSE_CONS_EXPRESSION
to TC_CONS_FIX_NEW via static variables.  That's OK, but not best
practice.  tc-ppc.c goes further in implementing its own replacement
for cons(), because the generic one doesn't allow relocation modifiers
on constants.  This patch fixes both of these warts.

* gas/config/tc-alpha.h (TC_CONS_FIX_NEW): Add RELOC parameter.
* gas/config/tc-arc.c (arc_cons_fix_new): Add reloc parameter.
* gas/config/tc-arc.h (arc_cons_fix_new): Update prototype.
(TC_CONS_FIX_NEW): Add RELOC parameter.
* gas/config/tc-arm.c (cons_fix_new_arm): Similarly
* gas/config/tc-arm.h (cons_fix_new_arm, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-cr16.c (cr16_cons_fix_new): Similarly.
* gas/config/tc-cr16.h (cr16_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-crx.h (TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-m32c.c (m32c_cons_fix_new): Similarly.
* gas/config/tc-m32c.h (m32c_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-mn10300.c (mn10300_cons_fix_new): Similarly.
* gas/config/tc-mn10300.h (mn10300_cons_fix_new, TC_CONS_FIX_NEW):
Similarly.
* gas/config/tc-ns32k.c (cons_fix_new_ns32k): Similarly.
* gas/config/tc-ns32k.h (cons_fix_new_ns32k): Similarly.
* gas/config/tc-pj.c (pj_cons_fix_new_pj): Similarly.
* gas/config/tc-pj.h (pj_cons_fix_new_pj, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-rx.c (rx_cons_fix_new): Similarly.
* gas/config/tc-rx.h (rx_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-sh.c (sh_cons_fix_new): Similarly.
* gas/config/tc-sh.h (sh_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
* gas/config/tc-tic54x.c (tic54x_cons_fix_new): Similarly.
* gas/config/tc-tic54x.h (tic54x_cons_fix_new, TC_CONS_FIX_NEW):
Similarly.
* gas/config/tc-tic6x.c (tic6x_cons_fix_new): Similarly.
* gas/config/tc-tic6x.h (tic6x_cons_fix_new, TC_CONS_FIX_NEW):
Similarly.
* gas/config/tc-arc.c (arc_parse_cons_expression): Return reloc.
* gas/config/tc-arc.h (arc_parse_cons_expression): Update proto.
* gas/config/tc-avr.c (exp_mod_data): Make global.
(pexp_mod_data): Delete.
(avr_parse_cons_expression): Return exp_mod_data pointer.
(avr_cons_fix_new): Add exp_mod_data_t pointer param.
(exp_mod_data_t): Move typedef..
* gas/config/tc-avr.h: ..to here.
(exp_mod_data): Declare.
(TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define.
(avr_parse_cons_expression, avr_cons_fix_new): Update prototype.
(TC_CONS_FIX_NEW): Update.
* gas/config/tc-hppa.c (hppa_field_selector): Delete static var.
(cons_fix_new_hppa): Add hppa_field_selector param.
(fix_new_hppa): Adjust.
(parse_cons_expression_hppa): Return field selector.
* gas/config/tc-hppa.h (parse_cons_expression_hppa): Update proto.
(cons_fix_new_hppa): Likewise.
(TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define.
* gas/config/tc-i386.c (got_reloc): Delete static var.
(x86_cons_fix_new): Add reloc param.
(x86_cons): Return got reloc.
* gas/config/tc-i386.h (x86_cons, x86_cons_fix_new): Update proto.
(TC_CONS_FIX_NEW): Add RELOC param.
* gas/config/tc-ia64.c (ia64_cons_fix_new): Add reloc param.  Adjust
calls.
* gas/config/tc-ia64.h (ia64_cons_fix_new): Update prototype.
(TC_CONS_FIX_NEW): Add reloc param.
* gas/config/tc-microblaze.c (parse_cons_expression_microblaze):
Return reloc.
(cons_fix_new_microblaze): Add reloc param.
* gas/config/tc-microblaze.h: Formatting.
(parse_cons_expression_microblaze): Update proto.
(cons_fix_new_microblaze): Likewise.
* gas/config/tc-nios2.c (nios2_tls_ldo_reloc): Delete static var.
(nios2_cons): Return ldo reloc.
(nios2_cons_fix_new): Delete.
* gas/config/tc-nios2.h (nios2_cons): Update prototype.
(nios2_cons_fix_new, TC_CONS_FIX_NEW): Delete.
* gas/config/tc-ppc.c (md_pseudo_table): Remove quad, long, word,
short.  Make llong use cons.
(ppc_elf_suffix): Return BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
(ppc_elf_cons): Delete.
(ppc_elf_parse_cons): New function.
(ppc_elf_validate_fix): Don't check for BFD_RELOC_UNUSED.
(md_assemble): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
* gas/config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): Define
(ppc_elf_parse_cons): Declare.
* gas/config/tc-sparc.c (sparc_cons_special_reloc): Delete static var.
(sparc_cons): Return reloc specifier.
(cons_fix_new_sparc): Add reloc specifier param.
(sparc_cfi_emit_pcrel_expr): Use emit_expr_with_reloc.
* gas/config/tc-sparc.h (TC_PARSE_CONS_RETURN_TYPE): Define.
(TC_PARSE_CONS_RETURN_NONE): Define.
(sparc_cons, cons_fix_new_sparc): Update prototype.
* gas/config/tc-v850.c (hold_cons_reloc): Delete static var.
(v850_reloc_prefix): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
(md_assemble): Likewise.
(parse_cons_expression_v850): Return reloc.
(cons_fix_new_v850): Add reloc parameter.
* gas/config/tc-v850.h (parse_cons_expression_v850): Update proto.
(cons_fix_new_v850): Likewise.
* gas/config/tc-vax.c (vax_cons_special_reloc): Delete static var.
(vax_cons): Return reloc.
(vax_cons_fix_new): Add reloc parameter.
* gas/config/tc-vax.h (vax_cons, vax_cons_fix_new): Update proto.
* gas/config/tc-xstormy16.c (xstormy16_cons_fix_new): Add reloc param.
* gas/config/tc-xstormy16.h (xstormy16_cons_fix_new): Update proto.
* gas/dwarf2dbg.c (TC_PARSE_CONS_RETURN_NONE): Provide default.
(emit_fixed_inc_line_addr): Adjust exmit_expr_fix calls.
* gas/read.c (TC_PARSE_CONS_EXPRESSION): Return value.
(do_parse_cons_expression): Adjust.
(cons_worker): Pass return value from TC_PARSE_CONS_EXPRESSION
to emit_expr_with_reloc.
(emit_expr_with_reloc): New function handling reloc, mostly
extracted from..
(emit_expr): ..here.
(emit_expr_fix): Add reloc param.  Adjust TC_CONS_FIX_NEW invocation.
Handle reloc.
(parse_mri_cons): Convert to ISO.
* gas/read.h (TC_PARSE_CONS_RETURN_TYPE): Define.
(TC_PARSE_CONS_RETURN_NONE): Define.
(emit_expr_with_reloc): Declare.
(emit_expr_fix): Update prototype.
* gas/write.c (write_object_file): Update TC_CONS_FIX_NEW invocation.

51 files changed:
gas/ChangeLog
gas/config/tc-alpha.h
gas/config/tc-arc.c
gas/config/tc-arc.h
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/config/tc-avr.c
gas/config/tc-avr.h
gas/config/tc-cr16.c
gas/config/tc-cr16.h
gas/config/tc-crx.h
gas/config/tc-hppa.c
gas/config/tc-hppa.h
gas/config/tc-i386.c
gas/config/tc-i386.h
gas/config/tc-ia64.c
gas/config/tc-ia64.h
gas/config/tc-m32c.c
gas/config/tc-m32c.h
gas/config/tc-microblaze.c
gas/config/tc-microblaze.h
gas/config/tc-mn10300.c
gas/config/tc-mn10300.h
gas/config/tc-nios2.c
gas/config/tc-nios2.h
gas/config/tc-ns32k.c
gas/config/tc-ns32k.h
gas/config/tc-pj.c
gas/config/tc-pj.h
gas/config/tc-ppc.c
gas/config/tc-ppc.h
gas/config/tc-rx.c
gas/config/tc-rx.h
gas/config/tc-sh.c
gas/config/tc-sh.h
gas/config/tc-sparc.c
gas/config/tc-sparc.h
gas/config/tc-tic54x.c
gas/config/tc-tic54x.h
gas/config/tc-tic6x.c
gas/config/tc-tic6x.h
gas/config/tc-v850.c
gas/config/tc-v850.h
gas/config/tc-vax.c
gas/config/tc-vax.h
gas/config/tc-xstormy16.c
gas/config/tc-xstormy16.h
gas/dwarf2dbg.c
gas/read.c
gas/read.h
gas/write.c

index 8ccea2e..36242a8 100644 (file)
@@ -1,3 +1,119 @@
+2014-04-09  Alan Modra  <amodra@gmail.com>
+
+       * gas/config/tc-alpha.h (TC_CONS_FIX_NEW): Add RELOC parameter.
+       * gas/config/tc-arc.c (arc_cons_fix_new): Add reloc parameter.
+       * gas/config/tc-arc.h (arc_cons_fix_new): Update prototype.
+       (TC_CONS_FIX_NEW): Add RELOC parameter.
+       * gas/config/tc-arm.c (cons_fix_new_arm): Similarly
+       * gas/config/tc-arm.h (cons_fix_new_arm, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-cr16.c (cr16_cons_fix_new): Similarly.
+       * gas/config/tc-cr16.h (cr16_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-crx.h (TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-m32c.c (m32c_cons_fix_new): Similarly.
+       * gas/config/tc-m32c.h (m32c_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-mn10300.c (mn10300_cons_fix_new): Similarly.
+       * gas/config/tc-mn10300.h (mn10300_cons_fix_new, TC_CONS_FIX_NEW):
+       Similarly.
+       * gas/config/tc-ns32k.c (cons_fix_new_ns32k): Similarly.
+       * gas/config/tc-ns32k.h (cons_fix_new_ns32k): Similarly.
+       * gas/config/tc-pj.c (pj_cons_fix_new_pj): Similarly.
+       * gas/config/tc-pj.h (pj_cons_fix_new_pj, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-rx.c (rx_cons_fix_new): Similarly.
+       * gas/config/tc-rx.h (rx_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-sh.c (sh_cons_fix_new): Similarly.
+       * gas/config/tc-sh.h (sh_cons_fix_new, TC_CONS_FIX_NEW): Similarly.
+       * gas/config/tc-tic54x.c (tic54x_cons_fix_new): Similarly.
+       * gas/config/tc-tic54x.h (tic54x_cons_fix_new, TC_CONS_FIX_NEW):
+       Similarly.
+       * gas/config/tc-tic6x.c (tic6x_cons_fix_new): Similarly.
+       * gas/config/tc-tic6x.h (tic6x_cons_fix_new, TC_CONS_FIX_NEW):
+       Similarly.
+       * gas/config/tc-arc.c (arc_parse_cons_expression): Return reloc.
+       * gas/config/tc-arc.h (arc_parse_cons_expression): Update proto.
+       * gas/config/tc-avr.c (exp_mod_data): Make global.
+       (pexp_mod_data): Delete.
+       (avr_parse_cons_expression): Return exp_mod_data pointer.
+       (avr_cons_fix_new): Add exp_mod_data_t pointer param.
+       (exp_mod_data_t): Move typedef..
+       * gas/config/tc-avr.h: ..to here.
+       (exp_mod_data): Declare.
+       (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define.
+       (avr_parse_cons_expression, avr_cons_fix_new): Update prototype.
+       (TC_CONS_FIX_NEW): Update.
+       * gas/config/tc-hppa.c (hppa_field_selector): Delete static var.
+       (cons_fix_new_hppa): Add hppa_field_selector param.
+       (fix_new_hppa): Adjust.
+       (parse_cons_expression_hppa): Return field selector.
+       * gas/config/tc-hppa.h (parse_cons_expression_hppa): Update proto.
+       (cons_fix_new_hppa): Likewise.
+       (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define.
+       * gas/config/tc-i386.c (got_reloc): Delete static var.
+       (x86_cons_fix_new): Add reloc param.
+       (x86_cons): Return got reloc.
+       * gas/config/tc-i386.h (x86_cons, x86_cons_fix_new): Update proto.
+       (TC_CONS_FIX_NEW): Add RELOC param.
+       * gas/config/tc-ia64.c (ia64_cons_fix_new): Add reloc param.  Adjust
+       calls.
+       * gas/config/tc-ia64.h (ia64_cons_fix_new): Update prototype.
+       (TC_CONS_FIX_NEW): Add reloc param.
+       * gas/config/tc-microblaze.c (parse_cons_expression_microblaze):
+       Return reloc.
+       (cons_fix_new_microblaze): Add reloc param.
+       * gas/config/tc-microblaze.h: Formatting.
+       (parse_cons_expression_microblaze): Update proto.
+       (cons_fix_new_microblaze): Likewise.
+       * gas/config/tc-nios2.c (nios2_tls_ldo_reloc): Delete static var.
+       (nios2_cons): Return ldo reloc.
+       (nios2_cons_fix_new): Delete.
+       * gas/config/tc-nios2.h (nios2_cons): Update prototype.
+       (nios2_cons_fix_new, TC_CONS_FIX_NEW): Delete.
+       * gas/config/tc-ppc.c (md_pseudo_table): Remove quad, long, word,
+       short.  Make llong use cons.
+       (ppc_elf_suffix): Return BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
+       (ppc_elf_cons): Delete.
+       (ppc_elf_parse_cons): New function.
+       (ppc_elf_validate_fix): Don't check for BFD_RELOC_UNUSED.
+       (md_assemble): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
+       * gas/config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): Define
+       (ppc_elf_parse_cons): Declare.
+       * gas/config/tc-sparc.c (sparc_cons_special_reloc): Delete static var.
+       (sparc_cons): Return reloc specifier.
+       (cons_fix_new_sparc): Add reloc specifier param.
+       (sparc_cfi_emit_pcrel_expr): Use emit_expr_with_reloc.
+       * gas/config/tc-sparc.h (TC_PARSE_CONS_RETURN_TYPE): Define.
+       (TC_PARSE_CONS_RETURN_NONE): Define.
+       (sparc_cons, cons_fix_new_sparc): Update prototype.
+       * gas/config/tc-v850.c (hold_cons_reloc): Delete static var.
+       (v850_reloc_prefix): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED.
+       (md_assemble): Likewise.
+       (parse_cons_expression_v850): Return reloc.
+       (cons_fix_new_v850): Add reloc parameter.
+       * gas/config/tc-v850.h (parse_cons_expression_v850): Update proto.
+       (cons_fix_new_v850): Likewise.
+       * gas/config/tc-vax.c (vax_cons_special_reloc): Delete static var.
+       (vax_cons): Return reloc.
+       (vax_cons_fix_new): Add reloc parameter.
+       * gas/config/tc-vax.h (vax_cons, vax_cons_fix_new): Update proto.
+       * gas/config/tc-xstormy16.c (xstormy16_cons_fix_new): Add reloc param.
+       * gas/config/tc-xstormy16.h (xstormy16_cons_fix_new): Update proto.
+       * gas/dwarf2dbg.c (TC_PARSE_CONS_RETURN_NONE): Provide default.
+       (emit_fixed_inc_line_addr): Adjust exmit_expr_fix calls.
+       * gas/read.c (TC_PARSE_CONS_EXPRESSION): Return value.
+       (do_parse_cons_expression): Adjust.
+       (cons_worker): Pass return value from TC_PARSE_CONS_EXPRESSION
+       to emit_expr_with_reloc.
+       (emit_expr_with_reloc): New function handling reloc, mostly
+       extracted from..
+       (emit_expr): ..here.
+       (emit_expr_fix): Add reloc param.  Adjust TC_CONS_FIX_NEW invocation.
+       Handle reloc.
+       (parse_mri_cons): Convert to ISO.
+       * gas/read.h (TC_PARSE_CONS_RETURN_TYPE): Define.
+       (TC_PARSE_CONS_RETURN_NONE): Define.
+       (emit_expr_with_reloc): Declare.
+       (emit_expr_fix): Update prototype.
+       * gas/write.c (write_object_file): Update TC_CONS_FIX_NEW invocation.
+
 2014-04-03  Ilya Tocar  <ilya.tocar@intel.com>
 
        * config/tc-i386.c (cpu_arch): Add .se1.
index 443eff4..98f81f5 100644 (file)
@@ -71,7 +71,8 @@ extern valueT alpha_gp_value;
 
 #define tc_canonicalize_symbol_name evax_shorten_name
 
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \
+#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP,RELOC)        \
+      (void) RELOC,                            \
       fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \
        LEN == 2 ? BFD_RELOC_16 \
        : LEN == 4 ? BFD_RELOC_32 \
index e8de1bb..5499d88 100644 (file)
@@ -1160,7 +1160,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    Values for the status register are specified with %st(label).
    `label' will be right shifted by 2.  */
 
-void
+bfd_reloc_code_real_type
 arc_parse_cons_expression (expressionS *exp,
                           unsigned int nbytes ATTRIBUTE_UNUSED)
 {
@@ -1179,6 +1179,7 @@ arc_parse_cons_expression (expressionS *exp,
       arc_code_symbol (exp);
       input_line_pointer = p;
     }
+  return BFD_RELOC_NONE;
 }
 
 /* Record a fixup for a cons expression.  */
@@ -1187,7 +1188,8 @@ void
 arc_cons_fix_new (fragS *frag,
                  int where,
                  int nbytes,
-                 expressionS *exp)
+                 expressionS *exp,
+                 bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
 {
   if (nbytes == 4)
     {
index 63cf826..a2789e6 100644 (file)
@@ -54,13 +54,15 @@ extern const char * arc_target_format;
 
 /* The ARC needs to parse reloc specifiers in .word.  */
 
-extern void arc_parse_cons_expression (struct expressionS *, unsigned);
+extern bfd_reloc_code_real_type arc_parse_cons_expression (struct expressionS *,
+                                                          unsigned);
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
   arc_parse_cons_expression (EXP, NBYTES)
 
-extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *);
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
-  arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
+extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *,
+                             bfd_reloc_code_real_type);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC)       \
+  arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
 
 #define DWARF2_LINE_MIN_INSN_LENGTH 4
 
index 1795d37..9ccacbc 100644 (file)
@@ -23159,9 +23159,9 @@ void
 cons_fix_new_arm (fragS *      frag,
                  int           where,
                  int           size,
-                 expressionS * exp)
+                 expressionS * exp,
+                 bfd_reloc_code_real_type reloc)
 {
-  bfd_reloc_code_real_type type;
   int pcrel = 0;
 
   /* Pick a reloc.
@@ -23169,17 +23169,17 @@ cons_fix_new_arm (fragS *     frag,
   switch (size)
     {
     case 1:
-      type = BFD_RELOC_8;
+      reloc = BFD_RELOC_8;
       break;
     case 2:
-      type = BFD_RELOC_16;
+      reloc = BFD_RELOC_16;
       break;
     case 4:
     default:
-      type = BFD_RELOC_32;
+      reloc = BFD_RELOC_32;
       break;
     case 8:
-      type = BFD_RELOC_64;
+      reloc = BFD_RELOC_64;
       break;
     }
 
@@ -23187,11 +23187,11 @@ cons_fix_new_arm (fragS *     frag,
   if (exp->X_op == O_secrel)
   {
     exp->X_op = O_symbol;
-    type = BFD_RELOC_32_SECREL;
+    reloc = BFD_RELOC_32_SECREL;
   }
 #endif
 
-  fix_new_exp (frag, where, (int) size, exp, pcrel, type);
+  fix_new_exp (frag, where, size, exp, pcrel, reloc);
 }
 
 #if defined (OBJ_COFF)
index f88fa29..a7a0cd0 100644 (file)
@@ -348,7 +348,8 @@ extern int arm_data_in_code (void);
 extern char * arm_canonicalize_symbol_name (char *);
 extern void arm_adjust_symtab (void);
 extern void armelf_frob_symbol (symbolS *, int *);
-extern void cons_fix_new_arm (fragS *, int, int, expressionS *);
+extern void cons_fix_new_arm (fragS *, int, int, expressionS *,
+                             bfd_reloc_code_real_type);
 extern void arm_init_frag (struct frag *, int);
 extern void arm_handle_align (struct frag *);
 extern bfd_boolean arm_fix_adjustable (struct fix *);
index 5049d11..ce9708e 100644 (file)
@@ -1521,22 +1521,7 @@ md_assemble (char *str)
   }
 }
 
-typedef struct
-{
-  /* Name of the expression modifier allowed with .byte, .word, etc.  */
-  const char *name;
-
-  /* Only allowed with n bytes of data.  */
-  int nbytes;
-
-  /* Associated RELOC.  */
-  bfd_reloc_code_real_type reloc;
-
-  /* Part of the error message.  */
-  const char *error;
-} exp_mod_data_t;
-
-static const exp_mod_data_t exp_mod_data[] =
+const exp_mod_data_t exp_mod_data[] =
 {
   /* Default, must be first.  */
   { "", 0, BFD_RELOC_16, "" },
@@ -1557,21 +1542,16 @@ static const exp_mod_data_t exp_mod_data[] =
   { NULL, 0, 0, NULL }
 };
 
-/* Data to pass between `avr_parse_cons_expression' and `avr_cons_fix_new'.  */
-static const exp_mod_data_t *pexp_mod_data = &exp_mod_data[0];
-
 /* Parse special CONS expression: pm (expression) or alternatively
    gs (expression).  These are used for addressing program memory.  Moreover,
    define lo8 (expression), hi8 (expression) and hlo8 (expression).  */
 
-void
+const exp_mod_data_t *
 avr_parse_cons_expression (expressionS *exp, int nbytes)
 {
   const exp_mod_data_t *pexp = &exp_mod_data[0];
   char *tmp;
 
-  pexp_mod_data = pexp;
-
   tmp = input_line_pointer = skip_space (input_line_pointer);
 
   /* The first entry of exp_mod_data[] contains an entry if no
@@ -1589,18 +1569,18 @@ avr_parse_cons_expression (expressionS *exp, int nbytes)
          if (*input_line_pointer == '(')
            {
              input_line_pointer = skip_space (input_line_pointer + 1);
-             pexp_mod_data = pexp;
              expression (exp);
 
              if (*input_line_pointer == ')')
-               ++input_line_pointer;
+               {
+                 ++input_line_pointer;
+                 return pexp;
+               }
              else
                {
                  as_bad (_("`)' required"));
-                 pexp_mod_data = &exp_mod_data[0];
+                 return &exp_mod_data[0];
                }
-
-             return;
            }
 
          input_line_pointer = tmp;
@@ -1610,13 +1590,15 @@ avr_parse_cons_expression (expressionS *exp, int nbytes)
     }
 
   expression (exp);
+  return &exp_mod_data[0];
 }
 
 void
 avr_cons_fix_new (fragS *frag,
                  int where,
                  int nbytes,
-                 expressionS *exp)
+                 expressionS *exp,
+                 const exp_mod_data_t *pexp_mod_data)
 {
   int bad = 0;
 
@@ -1646,8 +1628,6 @@ avr_cons_fix_new (fragS *frag,
 
   if (bad)
     as_bad (_("illegal %srelocation size: %d"), pexp_mod_data->error, nbytes);
-
-  pexp_mod_data = &exp_mod_data[0];
 }
 
 static bfd_boolean
index caa058f..df75ac7 100644 (file)
    will point to the start of the expression.  */
 #define md_operand(x)
 
+typedef struct
+{
+  /* Name of the expression modifier allowed with .byte, .word, etc.  */
+  const char *name;
+
+  /* Only allowed with n bytes of data.  */
+  int nbytes;
+
+  /* Associated RELOC.  */
+  bfd_reloc_code_real_type reloc;
+
+  /* Part of the error message.  */
+  const char *error;
+} exp_mod_data_t;
+
+extern const exp_mod_data_t exp_mod_data[];
+#define TC_PARSE_CONS_RETURN_TYPE const exp_mod_data_t *
+#define TC_PARSE_CONS_RETURN_NONE exp_mod_data
+
 /* You may define this macro to parse an expression used in a data
    allocation pseudo-op such as `.word'.  You can use this to
    recognize relocation directives that may appear in such directives.  */
 #define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR, N)
-extern void avr_parse_cons_expression (expressionS *, int);
+extern const exp_mod_data_t *avr_parse_cons_expression (expressionS *, int);
 
 /* You may define this macro to generate a fixup for a data
    allocation pseudo-op.  */
-#define TC_CONS_FIX_NEW(FRAG,WHERE,N,EXP) avr_cons_fix_new (FRAG, WHERE, N, EXP)
-extern void avr_cons_fix_new (fragS *,int, int, expressionS *);
+#define TC_CONS_FIX_NEW avr_cons_fix_new
+extern void avr_cons_fix_new (fragS *,int, int, expressionS *,
+                             const exp_mod_data_t *);
 
 /* This should just call either `number_to_chars_bigendian' or
    `number_to_chars_littleendian', whichever is appropriate.  On
index 4aed8a7..bcdf978 100644 (file)
@@ -492,10 +492,9 @@ cr16_force_relocation (fixS *fix)
 /* Record a fixup for a cons expression.  */
 
 void
-cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp)
+cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp,
+                  bfd_reloc_code_real_type rtype)
 {
-  int rtype = BFD_RELOC_UNUSED;
-
   switch (len)
     {
     default: rtype = BFD_RELOC_NONE; break;
index 6867191..9da8cb7 100644 (file)
@@ -57,12 +57,13 @@ extern int cr16_force_relocation (struct fix *);
    of two bytes long.  */
 #define DWARF2_LINE_MIN_INSN_LENGTH 2
 
-extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *);
+extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *,
+                              bfd_reloc_code_real_type);
 /* This is called by emit_expr when creating a reloc for a cons.
    We could use the definition there, except that we want to handle 
    the CR16 reloc type specially, rather than the BFD_RELOC type.  */
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
-  cr16_cons_fix_new (FRAG, OFF, LEN, EXP
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  cr16_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC)
 
 /* Give an error if a frag containing code is not aligned to a 2-byte 
    boundary.  */
index 1777ab0..da6d710 100644 (file)
@@ -60,7 +60,8 @@ extern int crx_force_relocation (struct fix *);
 /* This is called by emit_expr when creating a reloc for a cons.
    We could use the definition there, except that we want to handle 
    the CRX reloc type specially, rather than the BFD_RELOC type.  */
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \
+      (void) RELOC, \
       fix_new_exp (FRAG, OFF, (int) LEN, EXP, 0, \
        LEN == 1 ? BFD_RELOC_CRX_NUM8 \
        : LEN == 2 ? BFD_RELOC_CRX_NUM16 \
index cc5ea9a..5ee7f72 100644 (file)
@@ -606,9 +606,6 @@ static int within_procedure;
    seen in each subspace.  */
 static label_symbol_struct *label_symbols_rootp = NULL;
 
-/* Holds the last field selector.  */
-static int hppa_field_selector;
-
 /* Nonzero when strict matching is enabled.  Zero otherwise.
 
    Each opcode in the table has a flag which indicates whether or
@@ -1263,7 +1260,8 @@ fix_new_hppa (fragS *frag,
    hppa_field_selector is set by the parse_cons_expression_hppa.  */
 
 void
-cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
+cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp,
+                  int hppa_field_selector)
 {
   unsigned int rel_type;
 
@@ -1300,9 +1298,6 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
   fix_new_hppa (frag, where, size,
                (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
                hppa_field_selector, size * 8, 0, 0);
-
-  /* Reset field selector to its default state.  */
-  hppa_field_selector = 0;
 }
 
 /* Mark (via expr_end) the end of an expression (I think).  FIXME.  */
@@ -2517,11 +2512,12 @@ pa_chk_field_selector (char **str)
 /* Parse a .byte, .word, .long expression for the HPPA.  Called by
    cons via the TC_PARSE_CONS_EXPRESSION macro.  */
 
-void
+int
 parse_cons_expression_hppa (expressionS *exp)
 {
-  hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
+  int hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
   expression (exp);
+  return hppa_field_selector;
 }
 
 /* Evaluate an absolute expression EXP which may be modified by
index a31ebf8..4277e10 100644 (file)
@@ -90,8 +90,8 @@
 
 /* pa_define_label gets used outside of tc-hppa.c via tc_frob_label.  */
 extern void pa_define_label (symbolS *);
-extern void parse_cons_expression_hppa (expressionS *);
-extern void cons_fix_new_hppa (fragS *, int, int, expressionS *);
+extern int parse_cons_expression_hppa (expressionS *);
+extern void cons_fix_new_hppa (fragS *, int, int, expressionS *, int);
 extern int hppa_force_relocation (struct fix *);
 
 /* This gets called before writing the object file to make sure
@@ -112,6 +112,8 @@ extern const char   hppa_symbol_chars[];
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
   parse_cons_expression_hppa (EXP)
 #define TC_CONS_FIX_NEW cons_fix_new_hppa
+#define TC_PARSE_CONS_RETURN_TYPE int
+#define TC_PARSE_CONS_RETURN_NONE e_fsel
 
 /* On the PA, an exclamation point can appear in an instruction.  It is
    used in FP comparison instructions and as an end of line marker.
index 38857cc..cb62cf5 100644 (file)
@@ -7334,16 +7334,13 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off)
 \f
 /* x86_cons_fix_new is called via the expression parsing code when a
    reloc is needed.  We use this hook to get the correct .got reloc.  */
-static enum bfd_reloc_code_real got_reloc = NO_RELOC;
 static int cons_sign = -1;
 
 void
 x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
-                 expressionS *exp)
+                 expressionS *exp, bfd_reloc_code_real_type r)
 {
-  enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, 0, got_reloc);
-
-  got_reloc = NO_RELOC;
+  r = reloc (len, 0, cons_sign, 0, r);
 
 #ifdef TE_PE
   if (exp->X_op == O_secrel)
@@ -7639,9 +7636,11 @@ lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED,
 
 #endif /* TE_PE */
 
-void
+bfd_reloc_code_real_type
 x86_cons (expressionS *exp, int size)
 {
+  bfd_reloc_code_real_type got_reloc = NO_RELOC;
+
   intel_syntax = -intel_syntax;
 
   exp->X_md = 0;
@@ -7688,6 +7687,8 @@ x86_cons (expressionS *exp, int size)
 
   if (intel_syntax)
     i386_intel_simplify (exp);
+
+  return got_reloc;
 }
 
 static void
index 17be268..8b5c7d7 100644 (file)
@@ -132,11 +132,12 @@ extern const char *i386_comment_chars;
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT)
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
 #endif
-extern void x86_cons (expressionS *, int);
+extern bfd_reloc_code_real_type x86_cons (expressionS *, int);
 
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  x86_cons_fix_new(FRAG, OFF, LEN, EXP, RELOC)
 extern void x86_cons_fix_new
-  (fragS *, unsigned int, unsigned int, expressionS *);
+(fragS *, unsigned int, unsigned int, expressionS *, bfd_reloc_code_real_type);
 
 #define TC_ADDRESS_BYTES x86_address_bytes
 extern int x86_address_bytes (void);
index e6da535..38b6b67 100644 (file)
@@ -4466,14 +4466,15 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
                                          symbol_get_frag (unwind.proc_pending.sym));
       else
        e.X_add_symbol = unwind.proc_pending.sym;
-      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e);
+      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e,
+                        BFD_RELOC_NONE);
 
       e.X_op = O_pseudo_fixup;
       e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
       e.X_add_number = 0;
       e.X_add_symbol = proc_end;
       ia64_cons_fix_new (frag_now, where + bytes_per_address,
-                        bytes_per_address, &e);
+                        bytes_per_address, &e, BFD_RELOC_NONE);
 
       if (unwind.info)
        {
@@ -4482,7 +4483,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
          e.X_add_number = 0;
          e.X_add_symbol = unwind.info;
          ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
-                            bytes_per_address, &e);
+                            bytes_per_address, &e, BFD_RELOC_NONE);
        }
     }
   subseg_set (saved_seg, saved_subseg);
@@ -11056,9 +11057,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
    fixup.  We pick the right reloc code depending on the byteorder
    currently in effect.  */
 void
-ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp)
+ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp,
+                  bfd_reloc_code_real_type code)
 {
-  bfd_reloc_code_real_type code;
   fixS *fix;
 
   switch (nbytes)
index c6cc29f..6884c59 100644 (file)
@@ -106,7 +106,8 @@ extern void ia64_cons_align (int);
 extern void ia64_flush_insns (void);
 extern int ia64_fix_adjustable (struct fix *);
 extern int ia64_force_relocation (struct fix *);
-extern void ia64_cons_fix_new (fragS *, int, int, expressionS *);
+extern void ia64_cons_fix_new (fragS *, int, int, expressionS *,
+                              bfd_reloc_code_real_type);
 extern void ia64_validate_fix (struct fix *);
 extern char * ia64_canonicalize_symbol_name (char *);
 extern bfd_vma ia64_elf_section_letter (int, char **);
@@ -148,7 +149,7 @@ extern void ia64_convert_frag (fragS *);
 #define md_elf_section_flags           ia64_elf_section_flags
 #define TC_FIX_TYPE                    struct ia64_fix
 #define TC_INIT_FIX_DATA(f)            { f->tc_fix_data.opnd = 0; }
-#define TC_CONS_FIX_NEW(f,o,l,e)       ia64_cons_fix_new (f, o, l, e)
+#define TC_CONS_FIX_NEW(f,o,l,e,r)     ia64_cons_fix_new (f, o, l, e, r)
 #define TC_VALIDATE_FIX(fix,seg,skip)  ia64_validate_fix (fix)
 #define MD_PCREL_FROM_SECTION(fix,sec) ia64_pcrel_from_section (fix, sec)
 #define md_section_align(seg,size)     (size)
index 664b167..8e24edb 100644 (file)
@@ -1019,10 +1019,9 @@ void
 m32c_cons_fix_new (fragS *     frag,
                   int          where,
                   int          size,
-                  expressionS *exp)
+                  expressionS *exp,
+                  bfd_reloc_code_real_type type)
 {
-  bfd_reloc_code_real_type type;
-
   switch (size)
     {
     case 1:
index 0534603..3af0092 100644 (file)
@@ -57,9 +57,10 @@ extern bfd_boolean m32c_fix_adjustable (struct fix *);
 #define TC_FORCE_RELOCATION(fix) m32c_force_relocation (fix)
 extern int m32c_force_relocation (struct fix *);
 
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
-  m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
-extern void m32c_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC)       \
+  m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
+extern void m32c_cons_fix_new (fragS *, int, int, expressionS *,
+                              bfd_reloc_code_real_type);
 
 extern const struct relax_type md_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_relax_table
index 13f9f84..cf4ee44 100644 (file)
@@ -802,7 +802,7 @@ check_got (int * got_type, int * got_len)
   return tmpbuf;
 }
 
-extern void
+extern bfd_reloc_code_real_type
 parse_cons_expression_microblaze (expressionS *exp, int size)
 {
   if (size == 4)
@@ -828,6 +828,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size)
     }
   else
     expression (exp);
+  return BFD_RELOC_NONE;
 }
 
 /* This is the guts of the machine-dependent assembler.  STR points to a
@@ -2485,11 +2486,9 @@ void
 cons_fix_new_microblaze (fragS * frag,
                         int where,
                         int size,
-                        expressionS *exp)
+                        expressionS *exp,
+                        bfd_reloc_code_real_type r)
 {
-
-  bfd_reloc_code_real_type r;
-
   if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
       (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
       && (!S_IS_LOCAL (exp->X_op_symbol)))
index 91a9a21..d44f2fa 100644 (file)
    relocs for such expressions as -relax in linker can change the value
    of such expressions */
 #define TC_CONS_FIX_NEW cons_fix_new_microblaze
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_microblaze (EXP, NBYTES)
-extern void parse_cons_expression_microblaze (expressionS *, int);
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  parse_cons_expression_microblaze (EXP, NBYTES)
+extern bfd_reloc_code_real_type parse_cons_expression_microblaze
+  (expressionS *, int);
 
 #define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) 1
 #define UNDEFINED_DIFFERENCE_OK 1
@@ -108,7 +110,9 @@ extern void      md_number_to_chars            (char *, valueT, int);
 extern valueT    md_section_align              (segT, valueT);
 extern long      md_pcrel_from_section         (fixS *, segT);
 extern arelent * tc_gen_reloc                  (asection *, fixS *);
-extern void     cons_fix_new_microblaze       (fragS *, int, int, expressionS *);
+extern void     cons_fix_new_microblaze       (fragS *, int, int,
+                                               expressionS *,
+                                               bfd_reloc_code_real_type);
 extern void     md_apply_fix3                 (fixS *, valueT *, segT);
 
 #define EXTERN_FORCE_RELOC -1
index 2fce19c..3d159b1 100644 (file)
@@ -1013,7 +1013,8 @@ mn10300_check_fixup (struct mn10300_fixup *fixup)
 }
 
 void
-mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
+mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp,
+                     bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
 {
   struct mn10300_fixup fixup;
 
index 4a89f74..d502430 100644 (file)
@@ -39,9 +39,10 @@ extern bfd_boolean mn10300_force_relocation (struct fix *);
     mn10300_parse_name ((NAME), (EXPRP), (MODE), (NEXTCHARP))
 int mn10300_parse_name (char const *, expressionS *, enum expr_mode, char *);
 
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
-     mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
-void mn10300_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC))
+void mn10300_cons_fix_new (fragS *, int, int, expressionS *,
+                          bfd_reloc_code_real_type);
 
 /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
    symbols.  The relocation type is stored in X_md.  */
index 9cb290d..754947c 100644 (file)
@@ -3003,12 +3003,10 @@ nios2_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
 }
 
 /* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */
-static int nios2_tls_ldo_reloc;
-
-void
+bfd_reloc_code_real_type
 nios2_cons (expressionS *exp, int size)
 {
-  nios2_tls_ldo_reloc = 0;
+  bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE;
 
   SKIP_WHITESPACE ();
   if (input_line_pointer[0] == '%')
@@ -3021,10 +3019,10 @@ nios2_cons (expressionS *exp, int size)
          else
            {
              input_line_pointer += 8;
-             nios2_tls_ldo_reloc = 1;
+             nios2_tls_ldo_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
            }
        }
-      if (nios2_tls_ldo_reloc)
+      if (nios2_tls_ldo_reloc != BFD_RELOC_NONE)
        {
          SKIP_WHITESPACE ();
          if (input_line_pointer[0] != '(')
@@ -3066,26 +3064,9 @@ nios2_cons (expressionS *exp, int size)
            }
        }
     }
-  if (!nios2_tls_ldo_reloc)
+  if (nios2_tls_ldo_reloc == BFD_RELOC_NONE)
     expression (exp);
-}
-
-/* Implement TC_CONS_FIX_NEW.  */
-void
-nios2_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
-                   expressionS *exp)
-{
-  bfd_reloc_code_real_type r;
-
-  r = (nbytes == 1 ? BFD_RELOC_8
-       : (nbytes == 2 ? BFD_RELOC_16
-         : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
-
-  if (nios2_tls_ldo_reloc)
-    r = BFD_RELOC_NIOS2_TLS_DTPREL;
-
-  fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
-  nios2_tls_ldo_reloc = 0;
+  return nios2_tls_ldo_reloc;
 }
 
 /* Implement HANDLE_ALIGN.  */
index 4332649..82bb624 100644 (file)
@@ -107,11 +107,7 @@ extern flagword nios2_elf_section_flags (flagword, int, int);
 #define CFI_DIFF_EXPR_OK 0
 
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) nios2_cons (EXP, NBYTES)
-extern void nios2_cons (expressionS *exp, int size);
-
-#define TC_CONS_FIX_NEW nios2_cons_fix_new
-extern void nios2_cons_fix_new (struct frag *frag, int where,
-                               unsigned int nbytes, struct expressionS *exp);
+extern bfd_reloc_code_real_type nios2_cons (expressionS *exp, int size);
 
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
 #define TARGET_USE_CFIPOP 1
index d66a062..1c97d43 100644 (file)
@@ -2181,7 +2181,8 @@ void
 cons_fix_new_ns32k (fragS *frag,       /* Which frag? */
                    int where,          /* Where in that frag? */
                    int size,           /* 1, 2  or 4 usually.  */
-                   expressionS *exp)   /* Expression.  */
+                   expressionS *exp,   /* Expression.  */
+                   bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
 {
   fix_new_ns32k_exp (frag, where, size, exp,
                     0, 2, 0, 0, 0, 0);
index 7b093ec..02d7196 100644 (file)
@@ -54,7 +54,8 @@ extern int md_pcrel_adjust (fragS *);
 #define ARG_LEN 50
 
 #define TC_CONS_FIX_NEW cons_fix_new_ns32k
-extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *);
+extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *,
+                               bfd_reloc_code_real_type);
 
 /* The NS32x32 has a non 0 nop instruction which should be used in aligns.  */
 #define NOP_OPCODE 0xa2
index 408dde6..dba4cbc 100644 (file)
@@ -96,7 +96,8 @@ parse_exp_save_ilp (char *s, expressionS *op)
    we want to handle magic pending reloc expressions specially.  */
 
 void
-pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp)
+pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp,
+                   bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
 {
   static int rv[5][2] =
   { { 0, 0 },
index 522db5b..eda1792 100644 (file)
@@ -31,7 +31,8 @@
    ? "Pico Java GAS Big Endian"                                        \
    : "Pico Java GAS Little Endian")
 
-void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *);
+void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *,
+                        bfd_reloc_code_real_type);
 arelent *tc_gen_reloc (asection *, struct fix *);
 
 #define md_section_align(SEGMENT, SIZE)     (SIZE)
@@ -45,8 +46,8 @@ arelent *tc_gen_reloc (asection *, struct fix *);
 #define md_pcrel_from(FIX)                                             \
        ((FIX)->fx_where + (FIX)->fx_frag->fr_address - 1)
 
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
-       pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP)
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC)       \
+       pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP, RELOC)
 
 /* No shared lib support, so we don't need to ensure externally
    visible symbols can be overridden.  */
index 9f24f3f..5cfe1db 100644 (file)
@@ -129,7 +129,6 @@ static void ppc_vbyte (int);
 #endif
 
 #ifdef OBJ_ELF
-static void ppc_elf_cons (int);
 static void ppc_elf_rdata (int);
 static void ppc_elf_lcomm (int);
 static void ppc_elf_localentry (int);
@@ -257,11 +256,7 @@ const pseudo_typeS md_pseudo_table[] =
 #endif
 
 #ifdef OBJ_ELF
-  { "llong",   ppc_elf_cons,   8 },
-  { "quad",    ppc_elf_cons,   8 },
-  { "long",    ppc_elf_cons,   4 },
-  { "word",    ppc_elf_cons,   2 },
-  { "short",   ppc_elf_cons,   2 },
+  { "llong",   cons,           8 },
   { "rdata",   ppc_elf_rdata,  0 },
   { "rodata",  ppc_elf_rdata,  0 },
   { "lcomm",   ppc_elf_lcomm,  0 },
@@ -1957,11 +1952,11 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
     MAP64 ("tprel@highera",    BFD_RELOC_PPC64_TPREL16_HIGHERA),
     MAP64 ("tprel@highest",    BFD_RELOC_PPC64_TPREL16_HIGHEST),
     MAP64 ("tprel@highesta",   BFD_RELOC_PPC64_TPREL16_HIGHESTA),
-    { (char *) 0, 0, 0, 0,     BFD_RELOC_UNUSED }
+    { (char *) 0, 0, 0, 0,     BFD_RELOC_NONE }
   };
 
   if (*str++ != '@')
-    return BFD_RELOC_UNUSED;
+    return BFD_RELOC_NONE;
 
   for (ch = *str, str2 = ident;
        (str2 < ident + sizeof (ident) - 1
@@ -2047,63 +2042,18 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
        return (bfd_reloc_code_real_type) reloc;
       }
 
-  return BFD_RELOC_UNUSED;
+  return BFD_RELOC_NONE;
 }
 
-/* Like normal .long/.short/.word, except support @got, etc.
-   Clobbers input_line_pointer, checks end-of-line.  */
-static void
-ppc_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long, 8=.llong */)
-{
-  expressionS exp;
-  bfd_reloc_code_real_type reloc;
-
-  if (is_it_end_of_statement ())
-    {
-      demand_empty_rest_of_line ();
-      return;
-    }
-
-  do
-    {
-      expression (&exp);
-      if (*input_line_pointer == '@'
-         && (reloc = ppc_elf_suffix (&input_line_pointer,
-                                     &exp)) != BFD_RELOC_UNUSED)
-       {
-         reloc_howto_type *reloc_howto;
-         int size;
+/* Support @got, etc. on constants emitted via .short, .int etc.  */
 
-         reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc);
-         size = bfd_get_reloc_size (reloc_howto);
-
-         if (size > nbytes)
-           {
-             as_bad (_("%s relocations do not fit in %d bytes\n"),
-                     reloc_howto->name, nbytes);
-           }
-         else
-           {
-             char *p;
-             int offset;
-
-             p = frag_more (nbytes);
-             memset (p, 0, nbytes);
-             offset = 0;
-             if (target_big_endian)
-               offset = nbytes - size;
-             fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
-                          &exp, 0, reloc);
-           }
-       }
-      else
-       emit_expr (&exp, (unsigned int) nbytes);
-    }
-  while (*input_line_pointer++ == ',');
-
-  /* Put terminator back into stream.  */
-  input_line_pointer--;
-  demand_empty_rest_of_line ();
+bfd_reloc_code_real_type
+ppc_elf_parse_cons (expressionS *exp, unsigned int nbytes)
+{
+  expression (exp);
+  if (nbytes >= 2 && *input_line_pointer == '@')
+    return ppc_elf_suffix (&input_line_pointer, exp);
+  return BFD_RELOC_NONE;
 }
 
 /* Solaris pseduo op to change to the .rodata section.  */
@@ -2338,8 +2288,7 @@ ppc_elf_validate_fix (fixS *fixp, segT seg)
       return;
 
     case SHLIB_MRELOCATABLE:
-      if (fixp->fx_r_type <= BFD_RELOC_UNUSED
-         && fixp->fx_r_type != BFD_RELOC_16_GOTOFF
+      if (fixp->fx_r_type != BFD_RELOC_16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF
          && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF
@@ -2839,12 +2788,12 @@ md_assemble (char *str)
              /* FIXME: these next two specifically specify 32/64 bit
                 toc entries.  We don't support them today.  Is this
                 the right way to say that?  */
-             toc_reloc = BFD_RELOC_UNUSED;
+             toc_reloc = BFD_RELOC_NONE;
              as_bad (_("unimplemented toc32 expression modifier"));
              break;
            case must_be_64:
              /* FIXME: see above.  */
-             toc_reloc = BFD_RELOC_UNUSED;
+             toc_reloc = BFD_RELOC_NONE;
              as_bad (_("unimplemented toc64 expression modifier"));
              break;
            default:
@@ -2914,7 +2863,7 @@ md_assemble (char *str)
          bfd_reloc_code_real_type reloc;
          char *orig_str = str;
 
-         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
            switch (reloc)
              {
              default:
@@ -3000,7 +2949,7 @@ md_assemble (char *str)
        }
       else
        {
-         bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
+         bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
 #ifdef OBJ_ELF
          if (ex.X_op == O_symbol && str[0] == '(')
            {
@@ -3017,7 +2966,7 @@ md_assemble (char *str)
                  expression (&tls_exp);
                  if (tls_exp.X_op == O_symbol)
                    {
-                     reloc = BFD_RELOC_UNUSED;
+                     reloc = BFD_RELOC_NONE;
                      if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0)
                        {
                          reloc = BFD_RELOC_PPC_TLSGD;
@@ -3028,7 +2977,7 @@ md_assemble (char *str)
                          reloc = BFD_RELOC_PPC_TLSLD;
                          input_line_pointer += 7;
                        }
-                     if (reloc != BFD_RELOC_UNUSED)
+                     if (reloc != BFD_RELOC_NONE)
                        {
                          SKIP_WHITESPACE ();
                          str = input_line_pointer;
@@ -3045,7 +2994,7 @@ md_assemble (char *str)
                }
            }
 
-         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED)
+         if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
            {
              /* Some TLS tweaks.  */
              switch (reloc)
@@ -3144,7 +3093,7 @@ md_assemble (char *str)
            }
 #endif /* OBJ_ELF */
 
-         if (reloc != BFD_RELOC_UNUSED)
+         if (reloc != BFD_RELOC_NONE)
            ;
          /* Determine a BFD reloc value based on the operand information.
             We are only prepared to turn a few of the operands into
@@ -3405,7 +3354,7 @@ md_assemble (char *str)
   for (i = 0; i < fc; i++)
     {
       fixS *fixP;
-      if (fixups[i].reloc != BFD_RELOC_UNUSED)
+      if (fixups[i].reloc != BFD_RELOC_NONE)
        {
          reloc_howto_type *reloc_howto;
          int size;
@@ -3438,7 +3387,7 @@ md_assemble (char *str)
                              insn_length,
                              &fixups[i].exp,
                              (operand->flags & PPC_OPERAND_RELATIVE) != 0,
-                             BFD_RELOC_UNUSED);
+                             BFD_RELOC_NONE);
        }
       fixP->fx_pcrel_adjust = fixups[i].opindex;
     }
@@ -6462,7 +6411,7 @@ ppc_handle_align (struct frag *fragP)
    fixups we generated by the calls to fix_new_exp, above.  */
 
 void
-md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 {
   valueT value = * valP;
   offsetT fieldval;
@@ -6810,7 +6759,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        return;
 
       gas_assert (fixP->fx_addsy != NULL);
-      if (fixP->fx_r_type == BFD_RELOC_UNUSED)
+      if (fixP->fx_r_type == BFD_RELOC_NONE)
        {
          char *sfile;
          unsigned int sline;
index 09eb889..a5e69ca 100644 (file)
@@ -231,6 +231,10 @@ extern int ppc_fix_adjustable (struct fix *);
 /* Values passed to md_apply_fix don't include symbol values.  */
 #define MD_APPLY_SYM_VALUE(FIX) 0
 
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  ppc_elf_parse_cons (EXP, NBYTES)
+extern bfd_reloc_code_real_type ppc_elf_parse_cons (expressionS *,
+                                                   unsigned int);
 #define tc_frob_file_before_adjust ppc_frob_file_before_adjust
 extern void ppc_frob_file_before_adjust (void);
 
index 87b1e09..c4842f9 100644 (file)
@@ -2170,10 +2170,9 @@ void
 rx_cons_fix_new (fragS *       frag,
                 int            where,
                 int            size,
-                expressionS *  exp)
+                expressionS *  exp,
+                bfd_reloc_code_real_type type)
 {
-  bfd_reloc_code_real_type type;
-
   switch (size)
     {
     case 1:
index 937af25..b82812d 100644 (file)
@@ -68,9 +68,10 @@ extern long md_pcrel_from_section (struct fix *, segT);
   rx_validate_fix_sub (FIX)
 extern int rx_validate_fix_sub (struct fix *);
 
-#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \
-  rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP)
-extern void rx_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC)       \
+  rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC)
+extern void rx_cons_fix_new (fragS *, int, int, expressionS *,
+                            bfd_reloc_code_real_type);
 
 #define tc_fix_adjustable(x) 0
 
index da7d84a..a0cd212 100644 (file)
@@ -765,9 +765,10 @@ sh_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p)
 /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG.  */
 
 void
-sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
+sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp,
+                bfd_reloc_code_real_type r_type)
 {
-  bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED;
+  r_type = BFD_RELOC_UNUSED;
 
   if (sh_check_fixup (exp, &r_type))
     as_bad (_("Invalid PIC expression."));
index 40d8056..97b6b6d 100644 (file)
@@ -232,9 +232,10 @@ extern bfd_boolean sh_fix_adjustable (struct fix *);
 int sh_parse_name (char const *, expressionS *,
                   enum expr_mode, char *);
 
-#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \
-  sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP))
-void sh_cons_fix_new (fragS *, int, int, expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC))
+void sh_cons_fix_new (fragS *, int, int, expressionS *,
+                     bfd_reloc_code_real_type);
 
 /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT
    symbols.  The relocation type is stored in X_md.  */
index fdc2f03..5b0baad 100644 (file)
@@ -4268,11 +4268,6 @@ s_proc (int ignore ATTRIBUTE_UNUSED)
 
 static int sparc_no_align_cons = 0;
 
-/* This static variable is set by sparc_cons to emit requested types
-   of relocations in cons_fix_new_sparc.  */
-
-static const char *sparc_cons_special_reloc;
-
 /* This handles the unaligned space allocation pseudo-ops, such as
    .uaword.  .uaword is just like .word, but the value does not need
    to be aligned.  */
@@ -4540,13 +4535,13 @@ sparc_elf_final_processing (void)
     elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1|EF_SPARC_SUN_US3;
 }
 
-void
+const char *
 sparc_cons (expressionS *exp, int size)
 {
   char *save;
+  const char *sparc_cons_special_reloc = NULL;
 
   SKIP_WHITESPACE ();
-  sparc_cons_special_reloc = NULL;
   save = input_line_pointer;
   if (input_line_pointer[0] == '%'
       && input_line_pointer[1] == 'r'
@@ -4673,6 +4668,7 @@ sparc_cons (expressionS *exp, int size)
     }
   if (sparc_cons_special_reloc == NULL)
     expression (exp);
+  return sparc_cons_special_reloc;
 }
 
 #endif
@@ -4685,7 +4681,8 @@ void
 cons_fix_new_sparc (fragS *frag,
                    int where,
                    unsigned int nbytes,
-                   expressionS *exp)
+                   expressionS *exp,
+                   const char *sparc_cons_special_reloc)
 {
   bfd_reloc_code_real_type r;
 
@@ -4734,7 +4731,6 @@ cons_fix_new_sparc (fragS *frag,
    }
 
   fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
-  sparc_cons_special_reloc = NULL;
 }
 
 void
@@ -4788,9 +4784,7 @@ sparc_regname_to_dw2regnum (char *regname)
 void
 sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes)
 {
-  sparc_cons_special_reloc = "disp";
   sparc_no_align_cons = 1;
-  emit_expr (exp, nbytes);
+  emit_expr_with_reloc (exp, nbytes, "disp");
   sparc_no_align_cons = 0;
-  sparc_cons_special_reloc = NULL;
 }
index 10d4522..ef76c0b 100644 (file)
@@ -155,14 +155,17 @@ extern void sparc_md_end (void);
 
 #endif
 
+#define TC_PARSE_CONS_RETURN_TYPE const char *
+#define TC_PARSE_CONS_RETURN_NONE NULL
+
 #ifdef OBJ_ELF
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) sparc_cons (EXP, NBYTES)
-extern void sparc_cons (expressionS *, int);
+extern const char *sparc_cons (expressionS *, int);
 #endif
 
 #define TC_CONS_FIX_NEW cons_fix_new_sparc
 extern void cons_fix_new_sparc
-  (struct frag *, int, unsigned int, struct expressionS *);
+(struct frag *, int, unsigned int, struct expressionS *, const char *);
 
 #define TC_FIX_TYPE    valueT
 
index 27a2111..bba743c 100644 (file)
@@ -5121,10 +5121,9 @@ tc_gen_reloc (asection *section, fixS *fixP)
 /* Handle cons expressions.  */
 
 void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+                    bfd_reloc_code_real_type r)
 {
-  bfd_reloc_code_real_type r;
-
   switch (octets)
     {
     default:
index 84f343f..3fe8be8 100644 (file)
@@ -69,8 +69,10 @@ struct bit_info
 extern int tic54x_start_label (int, char *);
 
 /* custom handling for relocations in cons expressions */
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) tic54x_cons_fix_new(FRAG,OFF,LEN,EXP)
-extern void tic54x_cons_fix_new (fragS *,int,int,expressionS *);
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  tic54x_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC)
+extern void tic54x_cons_fix_new (fragS *, int, int, expressionS *,
+                                bfd_reloc_code_real_type);
 
 /* Define md_number_to_chars as the appropriate standard big endian or
    little endian function.  Mostly littleendian, but longwords and floats are
index 1ffbb68..aca07d3 100644 (file)
@@ -2012,10 +2012,9 @@ tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
    go through the error checking in tic6x_fix_new_exp.  */
 
 void
-tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp)
+tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp,
+                   bfd_reloc_code_real_type r_type)
 {
-  bfd_reloc_code_real_type r_type;
-
   switch (size)
     {
     case 1:
index 2612aab..dc110e8 100644 (file)
@@ -184,10 +184,10 @@ extern long tic6x_pcrel_from_section (struct fix *fixp, segT sec);
 #define md_start_line_hook() tic6x_start_line_hook ()
 extern void tic6x_start_line_hook (void);
 
-#define TC_CONS_FIX_NEW(frag, where, size, exp)        \
-  tic6x_cons_fix_new (frag, where, size, exp)
-extern void tic6x_cons_fix_new (fragS *frag, int where, int size,
-                               expressionS *exp);
+#define TC_CONS_FIX_NEW(frag, where, size, exp, reloc) \
+  tic6x_cons_fix_new (frag, where, size, exp, reloc)
+extern void tic6x_cons_fix_new (fragS *, int, int, expressionS *,
+                               bfd_reloc_code_real_type);
 
 #define tc_fix_adjustable(FIX) tic6x_fix_adjustable (FIX)
 extern bfd_boolean tic6x_fix_adjustable (struct fix *);
index d7bd99a..d5b9d7a 100644 (file)
@@ -27,9 +27,6 @@
 /* Sign-extend a 16-bit number.  */
 #define SEXT16(x)      ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
 
-/* Temporarily holds the reloc in a cons expression.  */
-static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;
-
 /* Set to TRUE if we want to be pedantic about signed overflows.  */
 static bfd_boolean warn_signed_overflows   = FALSE;
 static bfd_boolean warn_unsigned_overflows = FALSE;
@@ -2156,7 +2153,7 @@ v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg)
   if (paren_skipped)
     --input_line_pointer;
 
-  return BFD_RELOC_UNUSED;
+  return BFD_RELOC_NONE;
 }
 
 /* Insert an operand value into an instruction.  */
@@ -2407,7 +2404,7 @@ md_assemble (char *str)
          input_line_pointer = str;
 
          /* lo(), hi(), hi0(), etc...  */
-         if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_UNUSED)
+         if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_NONE)
            {
              /* This is a fake reloc, used to indicate an error condition.  */
              if (reloc == BFD_RELOC_64)
@@ -2977,7 +2974,7 @@ md_assemble (char *str)
 
                  fixups[fc].exp     = ex;
                  fixups[fc].opindex = *opindex_ptr;
-                 fixups[fc].reloc   = BFD_RELOC_UNUSED;
+                 fixups[fc].reloc   = BFD_RELOC_NONE;
                  ++fc;
                  break;
                }
@@ -3239,7 +3236,7 @@ md_assemble (char *str)
 
       reloc = fixups[i].reloc;
 
-      if (reloc != BFD_RELOC_UNUSED)
+      if (reloc != BFD_RELOC_NONE)
        {
          reloc_howto_type *reloc_howto =
            bfd_reloc_type_lookup (stdoutput, reloc);
@@ -3634,15 +3631,18 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
 /* Parse a cons expression.  We have to handle hi(), lo(), etc
    on the v850.  */
 
-void
+bfd_reloc_code_real_type
 parse_cons_expression_v850 (expressionS *exp)
 {
   const char *errmsg;
+  bfd_reloc_code_real_type r;
+
   /* See if there's a reloc prefix like hi() we have to handle.  */
-  hold_cons_reloc = v850_reloc_prefix (NULL, &errmsg);
+  r = v850_reloc_prefix (NULL, &errmsg);
 
   /* Do normal expression parsing.  */
   expression (exp);
+  return r;
 }
 
 /* Create a fixup for a cons expression.  If parse_cons_expression_v850
@@ -3653,24 +3653,23 @@ void
 cons_fix_new_v850 (fragS *frag,
                   int where,
                   int size,
-                  expressionS *exp)
+                  expressionS *exp,
+                  bfd_reloc_code_real_type r)
 {
-  if (hold_cons_reloc == BFD_RELOC_UNUSED)
+  if (r == BFD_RELOC_NONE)
     {
       if (size == 4)
-       hold_cons_reloc = BFD_RELOC_32;
+       r = BFD_RELOC_32;
       if (size == 2)
-       hold_cons_reloc = BFD_RELOC_16;
+       r = BFD_RELOC_16;
       if (size == 1)
-       hold_cons_reloc = BFD_RELOC_8;
+       r = BFD_RELOC_8;
     }
 
   if (exp != NULL)
-    fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
+    fix_new_exp (frag, where, size, exp, 0, r);
   else
-    fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
-
-  hold_cons_reloc = BFD_RELOC_UNUSED;
+    fix_new (frag, where, size, NULL, 0, 0, r);
 }
 
 bfd_boolean
index 1030ef3..a0aeeb4 100644 (file)
@@ -58,10 +58,11 @@ extern int v850_force_relocation (struct fix *);
 /* We need to handle lo(), hi(), etc etc in .hword, .word, etc
    directives, so we have to parse "cons" expressions ourselves.  */
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_v850 (EXP)
-extern void parse_cons_expression_v850 (expressionS *);
+extern bfd_reloc_code_real_type parse_cons_expression_v850 (expressionS *);
 
 #define TC_CONS_FIX_NEW cons_fix_new_v850
-extern void cons_fix_new_v850 (fragS *, int, int, expressionS *);
+extern void cons_fix_new_v850 (fragS *, int, int, expressionS *,
+                              bfd_reloc_code_real_type);
 
 #define TC_GENERIC_RELAX_TABLE md_relax_table
 extern const struct relax_type md_relax_table[];
index 7a9ef0b..0740a9b 100644 (file)
@@ -3264,12 +3264,11 @@ md_begin (void)
     }
 }
 
-static char *vax_cons_special_reloc;
-
-void
+bfd_reloc_code_real_type
 vax_cons (expressionS *exp, int size)
 {
   char *save;
+  char *vax_cons_special_reloc;
 
   SKIP_WHITESPACE ();
   vax_cons_special_reloc = NULL;
@@ -3373,35 +3372,29 @@ vax_cons (expressionS *exp, int size)
     }
   if (vax_cons_special_reloc == NULL)
     expression (exp);
+  else
+    switch (size)
+      {
+      case 1: return BFD_RELOC_8_PCREL;
+      case 2: return BFD_RELOC_16_PCREL;
+      case 4: return BFD_RELOC_32_PCREL;
+      }
+  return BFD_RELOC_NONE;
 }
 
 /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
    reloc for a cons.  */
 
 void
-vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp)
+vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp,
+                 bfd_reloc_code_real_type r)
 {
-  bfd_reloc_code_real_type r;
-
-  r = (nbytes == 1 ? BFD_RELOC_8 :
-       (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32));
-
-  if (vax_cons_special_reloc)
-    {
-      if (*vax_cons_special_reloc == 'p')
-       {
-         switch (nbytes)
-           {
-           case 1: r = BFD_RELOC_8_PCREL; break;
-           case 2: r = BFD_RELOC_16_PCREL; break;
-           case 4: r = BFD_RELOC_32_PCREL; break;
-           default: abort ();
-           }
-       }
-    }
+  if (r == BFD_RELOC_NONE)
+    r = (nbytes == 1 ? BFD_RELOC_8
+        : nbytes == 2 ? BFD_RELOC_16
+        : BFD_RELOC_32);
 
   fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
-  vax_cons_special_reloc = NULL;
 }
 
 char *
index b242fe0..cc94bb2 100644 (file)
@@ -49,8 +49,9 @@
 #ifdef OBJ_ELF
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) vax_cons (EXP, NBYTES)
 #define TC_CONS_FIX_NEW vax_cons_fix_new
-void vax_cons (expressionS *, int);
-void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *);
+bfd_reloc_code_real_type vax_cons (expressionS *, int);
+void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *,
+                      bfd_reloc_code_real_type);
 #endif
 
 extern const struct relax_type md_relax_table[];
index 1d57d60..e8eba89 100644 (file)
@@ -193,10 +193,9 @@ void
 xstormy16_cons_fix_new (fragS *f,
                        int where,
                        int nbytes,
-                       expressionS *exp)
+                       expressionS *exp,
+                       bfd_reloc_code_real_type code)
 {
-  bfd_reloc_code_real_type code;
-
   if (exp->X_op == O_fptr_symbol)
     {
       switch (nbytes)
index 31ec16c..064a85c 100644 (file)
@@ -57,7 +57,8 @@ extern int xstormy16_force_relocation (struct fix *);
 extern long md_pcrel_from_section (struct fix *, segT);
 
 #define TC_CONS_FIX_NEW xstormy16_cons_fix_new
-extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *);
+extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *,
+                                   bfd_reloc_code_real_type);
 
 #define md_cgen_record_fixup_exp  xstormy16_cgen_record_fixup_exp
 
index 4e9b654..5cc4662 100644 (file)
 /* The maximum address skip amount that can be encoded with a special op.  */
 #define MAX_SPECIAL_ADDR_DELTA         SPECIAL_ADDR(255)
 
+#ifndef TC_PARSE_CONS_RETURN_NONE
+#define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE
+#endif
+
 struct line_entry {
   struct line_entry *next;
   symbolS *label;
@@ -1144,13 +1148,13 @@ emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag,
       exp.X_op = O_symbol;
       exp.X_add_symbol = to_sym;
       exp.X_add_number = 0;
-      emit_expr_fix (&exp, sizeof_address, frag, p);
+      emit_expr_fix (&exp, sizeof_address, frag, p, TC_PARSE_CONS_RETURN_NONE);
       p += sizeof_address;
     }
   else
     {
       *p++ = DW_LNS_fixed_advance_pc;
-      emit_expr_fix (pexp, 2, frag, p);
+      emit_expr_fix (pexp, 2, frag, p, TC_PARSE_CONS_RETURN_NONE);
       p += 2;
     }
 
index 08b129f..306f7ec 100644 (file)
@@ -3851,19 +3851,22 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes);
 
 #ifndef TC_PARSE_CONS_EXPRESSION
 #ifdef BITFIELD_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_bitfield_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
 #endif
 #ifdef REPEAT_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_repeat_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_repeat_cons (expressionS *exp, unsigned int nbytes);
 #endif
 
 /* If we haven't gotten one yet, just call expression.  */
 #ifndef TC_PARSE_CONS_EXPRESSION
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (expression (EXP), TC_PARSE_CONS_RETURN_NONE)
 #endif
 #endif
 
@@ -3871,7 +3874,7 @@ void
 do_parse_cons_expression (expressionS *exp,
                          int nbytes ATTRIBUTE_UNUSED)
 {
-  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+  (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
 }
 
 
@@ -3914,6 +3917,8 @@ cons_worker (int nbytes,  /* 1=.byte, 2=.word, 4=.long.  */
   c = 0;
   do
     {
+      TC_PARSE_CONS_RETURN_TYPE ret = TC_PARSE_CONS_RETURN_NONE;
+
 #ifdef TC_M68K
       if (flag_m68k_mri)
        parse_mri_cons (&exp, (unsigned int) nbytes);
@@ -3926,7 +3931,7 @@ cons_worker (int nbytes,  /* 1=.byte, 2=.word, 4=.long.  */
              ignore_rest_of_line ();
              return;
            }
-         TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+         ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
        }
 
       if (rva)
@@ -3936,7 +3941,7 @@ cons_worker (int nbytes,  /* 1=.byte, 2=.word, 4=.long.  */
          else
            as_fatal (_("rva without symbol"));
        }
-      emit_expr (&exp, (unsigned int) nbytes);
+      emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret);
       ++c;
     }
   while (*input_line_pointer++ == ',');
@@ -4080,6 +4085,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
 void
 emit_expr (expressionS *exp, unsigned int nbytes)
 {
+  emit_expr_with_reloc (exp, nbytes, TC_PARSE_CONS_RETURN_NONE);
+}
+
+void
+emit_expr_with_reloc (expressionS *exp,
+                     unsigned int nbytes,
+                     TC_PARSE_CONS_RETURN_TYPE reloc)
+{
   operatorT op;
   char *p;
   valueT extra_digit = 0;
@@ -4221,6 +4234,12 @@ emit_expr (expressionS *exp, unsigned int nbytes)
 
   p = frag_more ((int) nbytes);
 
+  if (reloc != TC_PARSE_CONS_RETURN_NONE)
+    {
+      emit_expr_fix (exp, nbytes, frag_now, p, reloc);
+      return;
+    }
+
 #ifndef WORKING_DOT_WORD
   /* If we have the difference of two symbols in a word, save it on
      the broken_words list.  See the code in write.c.  */
@@ -4379,23 +4398,41 @@ emit_expr (expressionS *exp, unsigned int nbytes)
        }
     }
   else
-    emit_expr_fix (exp, nbytes, frag_now, p);
+    emit_expr_fix (exp, nbytes, frag_now, p, TC_PARSE_CONS_RETURN_NONE);
 }
 
 void
-emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
+emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p,
+              TC_PARSE_CONS_RETURN_TYPE r)
 {
-  memset (p, 0, nbytes);
+  int offset = 0;
+  unsigned int size = nbytes;
+
+  memset (p, 0, size);
 
   /* Generate a fixS to record the symbol value.  */
 
 #ifdef TC_CONS_FIX_NEW
-  TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp);
+  TC_CONS_FIX_NEW (frag, p - frag->fr_literal + offset, size, exp, r);
 #else
-  {
-    bfd_reloc_code_real_type r;
+  if (r != TC_PARSE_CONS_RETURN_NONE)
+    {
+      reloc_howto_type *reloc_howto;
 
-    switch (nbytes)
+      reloc_howto = bfd_reloc_type_lookup (stdoutput, r);
+      size = bfd_get_reloc_size (reloc_howto);
+
+      if (size > nbytes)
+       {
+         as_bad (_("%s relocations do not fit in %u bytes\n"),
+                 reloc_howto->name, nbytes);
+         return;
+       }
+      else if (target_big_endian)
+       offset = nbytes - size;
+    }
+  else
+    switch (size)
       {
       case 1:
        r = BFD_RELOC_8;
@@ -4413,13 +4450,11 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
        r = BFD_RELOC_64;
        break;
       default:
-       as_bad (_("unsupported BFD relocation size %u"), nbytes);
-       r = BFD_RELOC_32;
-       break;
+       as_bad (_("unsupported BFD relocation size %u"), size);
+       return;
       }
-    fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp,
-                0, r);
-  }
+  fix_new_exp (frag, p - frag->fr_literal + offset, size,
+              exp, 0, r);
 #endif
 }
 \f
@@ -4555,9 +4590,7 @@ parse_bitfield_cons (exp, nbytes)
 
 #ifdef TC_M68K
 static void
-parse_mri_cons (exp, nbytes)
-     expressionS *exp;
-     unsigned int nbytes;
+parse_mri_cons (expressionS *exp, unsigned int nbytes)
 {
   if (*input_line_pointer != '\''
       && (input_line_pointer[1] != '\''
index 59c0027..b85d3a9 100644 (file)
@@ -93,6 +93,11 @@ enum linkonce_type {
 extern char original_case_string[];
 #endif
 
+#ifndef TC_PARSE_CONS_RETURN_TYPE
+#define TC_PARSE_CONS_RETURN_TYPE bfd_reloc_code_real_type
+#define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE
+#endif
+
 extern void pop_insert (const pseudo_typeS *);
 extern unsigned int get_stab_string_offset
   (const char *string, const char *stabstr_secname);
@@ -109,7 +114,10 @@ extern void add_include_dir (char *path);
 extern void cons (int nbytes);
 extern void demand_empty_rest_of_line (void);
 extern void emit_expr (expressionS *exp, unsigned int nbytes);
-extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *);
+extern void emit_expr_with_reloc (expressionS *exp, unsigned int nbytes,
+                                 TC_PARSE_CONS_RETURN_TYPE);
+extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *,
+                          TC_PARSE_CONS_RETURN_TYPE);
 extern void equals (char *sym_name, int reassign);
 extern void float_cons (int float_type);
 extern void ignore_rest_of_line (void);
index c974121..4ab275d 100644 (file)
@@ -1883,7 +1883,7 @@ write_object_file (void)
 #ifdef TC_CONS_FIX_NEW
          TC_CONS_FIX_NEW (lie->frag,
                           lie->word_goes_here - lie->frag->fr_literal,
-                          2, &exp);
+                          2, &exp, TC_PARSE_CONS_RETURN_NONE);
 #else
          fix_new_exp (lie->frag,
                       lie->word_goes_here - lie->frag->fr_literal,