Support for Toshiba MeP and for complex relocations.
This commit is contained in:
parent
bd2f2e55ad
commit
280d71bf40
116
gas/ChangeLog
116
gas/ChangeLog
@ -1,3 +1,119 @@
|
||||
2007-02-05 Dave Brolley <brolley@redhat.com>
|
||||
|
||||
* Makefile.am: Add support for Toshiba MeP.
|
||||
* configure.in: Likewise
|
||||
* config/tc-mep.c:
|
||||
* config/obj-elf.c: New file.
|
||||
* config/tc-mep.c: New file.
|
||||
* config/tc-mep.h: New file.
|
||||
* testsuite/gas/mep: New testsuite with content.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
|
||||
2007-02-05 Dave Brolley <brolley@redhat.com>
|
||||
|
||||
* cgen.c (gas_cgen_install_complex_reloc): Removed.
|
||||
(complex_reloc_installation_howto): Removed.
|
||||
|
||||
2007-02-05 Dave Brolley <brolley@redhat.com>
|
||||
|
||||
* Contribute the following changes:
|
||||
2002-06-06 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* symbols.c (use_complex_relocs_for): Tighten up conditions on
|
||||
resolving expression symbols.
|
||||
|
||||
2002-04-04 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* symbols.c (use_complex_relocs_for): New, to decide
|
||||
when to use complex relocs.
|
||||
(resolve_symbol_value): Use it.
|
||||
|
||||
2002-03-07 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* cgen.c: Minor debugging touchups, warning removal.
|
||||
|
||||
2002-02-17 Catherine Moore <clm@redhat.com>
|
||||
|
||||
* cgen.c (gas_cgen_md_apply_fix3): Only set signed_p if RELC.
|
||||
|
||||
2002-01-23 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* cgen.c (gas_cgen_parse_operand): Add signed RELC support.
|
||||
(queue_fixup_recursively): Likewise.
|
||||
(make_right_shifted_expr): Likewise.
|
||||
* symbols.c (resolve_symbol_value): Likewise.
|
||||
|
||||
2002-01-15 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* write.h (struct fix): Add msb_field_p to fx_cgen sub-struct.
|
||||
* cgen.c (make_masked_expr): Remove.
|
||||
(gas_cgen_encode_addend): Add oplen, signed_p, trunc_p params.
|
||||
(gas_cgen_md_apply_fix3): Call encode_addend with new args.
|
||||
(queue_fixup_recursively): Change from masked expr to trunc flag.
|
||||
(queue_fixup_recursively): Restore assignment of sub-field value to
|
||||
temporary in fixups array (lost in recent merge).
|
||||
|
||||
2002-01-01 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* cgen.c (make_masked_expr): Add.
|
||||
(queue_fixup_recursively): Call make_masked_expr on non-rightmost
|
||||
fragments of multi-ifield complex relocs.
|
||||
(gas_cgen_parse_operand): Reflect changed meaning of last arg to
|
||||
queue_fixup_recursively.
|
||||
|
||||
2001-12-18 Graydon Hoare <graydon@redhat.com>
|
||||
|
||||
* cgen.c (weak_operand_overflow_check): Improve accuracy of
|
||||
detecting overflows.
|
||||
|
||||
2001-12-17 Nick Clifton <nickc@cambridge.redhat.com>
|
||||
|
||||
* cgen.c: Tidy up RELC code after the merge.
|
||||
|
||||
2001-11-15 graydon hoare <graydon@redhat.com>
|
||||
|
||||
* cgen.c (fixup): Add cgen_maybe_multi_ifield member.
|
||||
(make_right_shifted_expr): New function.
|
||||
(queue_fixup): Change to recursive function that fragments
|
||||
fixups if operand has a multi-ifield.
|
||||
(gas_cgen_parse_operand): Add RELC code to wrap expressions in
|
||||
symbols, call weak_operand_overflow_check, and fragment call
|
||||
queue_fixup with operand fields.
|
||||
(gas_cgen_finish_insn) Modify to manage ifield pointer.
|
||||
(gas_cgen_md_apply_fix3) Modify to get start, length from
|
||||
ifield whenever it is set. Also change condition on which
|
||||
self-describing relocs are encoded.
|
||||
(weak_operand_overflow_check): New function to try to select
|
||||
insns correctly.
|
||||
* cgen.h (GAS_CGEN_MAX_FIXUPS): Bump from 3 up to 32.
|
||||
* write.h (struct fix): Add cgen_maybe_multi_ifield field to
|
||||
fx_cgen substructure
|
||||
* config/tc-mep.c (md_cgen_lookup_reloc): Fall back to
|
||||
BFD_RELOC_RELC when no other reloc types can be found.
|
||||
|
||||
2001-10-03 graydon hoare <graydon@redhat.com>
|
||||
|
||||
* symbols.c (resolve_symbol_value): Unconditionally encode
|
||||
expression symbols as mangled complex relocation symbols (when
|
||||
compiled with -DOBJ_COMPLEX_RELOC)
|
||||
|
||||
* cgen.c (gas_cgen_encode_addend): New function for relc.
|
||||
(gas_cgen_install_complex_reloc): Likewise.
|
||||
(gas_cgen_md_apply_fix3): Add hook into gas_cgen_encode_addend.
|
||||
(gas_cgen_tc_gen_reloc): Add hook into gas_cgen_install_complex_reloc.
|
||||
|
||||
2001-06-24 Michael Chastain <chastain@redhat.com>
|
||||
|
||||
* symbols.c (symbol_relc_make_expr): Conform to K & R C.
|
||||
|
||||
2001-06-20 Frank Ch. Eigler <fche@redhat.com>
|
||||
|
||||
* symbols.c (resolve_symbol_value): Conditionally generate relc
|
||||
symbols from unresolved expressions.
|
||||
(symbol_relc_make_sym,value,expr): New traversal/conversion routines.
|
||||
* symbols.h: Declare them.
|
||||
|
||||
2007-02-03 DJ Delorie <dj@delorie.com>
|
||||
|
||||
* config/tc-m32c.c (m32c_cons_fix_new): New. Added to support 3
|
||||
|
@ -68,6 +68,7 @@ CPU_TYPES = \
|
||||
m68k \
|
||||
maxq \
|
||||
mcore \
|
||||
mep \
|
||||
mips \
|
||||
mmix \
|
||||
mn10200 \
|
||||
@ -258,6 +259,7 @@ TARGET_CPU_CFILES = \
|
||||
config/tc-m68hc11.c \
|
||||
config/tc-m68k.c \
|
||||
config/tc-mcore.c \
|
||||
config/tc-mep.c \
|
||||
config/tc-mips.c \
|
||||
config/tc-mmix.c \
|
||||
config/tc-mn10200.c \
|
||||
@ -311,6 +313,7 @@ TARGET_CPU_HFILES = \
|
||||
config/tc-m68hc11.h \
|
||||
config/tc-m68k.h \
|
||||
config/tc-mcore.h \
|
||||
config/tc-mep.h \
|
||||
config/tc-mips.h \
|
||||
config/tc-mmix.h \
|
||||
config/tc-mn10200.h \
|
||||
@ -1426,6 +1429,20 @@ DEPTC_i386_multi = $(DEPTC_i386_aout) $(DEPTC_i386_coff) \
|
||||
DEPTC_mips_multi = $(DEPTC_mips_coff) $(DEPTC_mips_ecoff) \
|
||||
$(DEPTC_mips_elf)
|
||||
DEPTC_cris_multi = $(DEPTC_cris_aout) $(DEPTC_cris_elf)
|
||||
DEPTC_mep_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
|
||||
$(srcdir)/config/tc-mep.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h dwarf2dbg.h \
|
||||
subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mep-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/mep-opc.h \
|
||||
cgen.h $(INCDIR)/elf/common.h $(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/safe-ctype.h
|
||||
DEPTC_mep_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mep-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/mep-opc.h \
|
||||
cgen.h $(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/safe-ctype.h
|
||||
DEPOBJ_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
|
||||
ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
|
||||
$(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
|
||||
@ -1782,6 +1799,16 @@ DEPOBJ_i386_multi = $(DEPOBJ_i386_aout) $(DEPOBJ_i386_coff) \
|
||||
DEPOBJ_mips_multi = $(DEPOBJ_mips_coff) $(DEPOBJ_mips_ecoff) \
|
||||
$(DEPOBJ_mips_elf)
|
||||
DEPOBJ_cris_multi = $(DEPOBJ_cris_aout) $(DEPOBJ_cris_elf)
|
||||
DEPOBJ_mep_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
|
||||
$(srcdir)/config/tc-mep.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
|
||||
subsegs.h $(INCDIR)/safe-ctype.h
|
||||
DEPOBJ_mep_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
$(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h \
|
||||
$(INCDIR)/safe-ctype.h
|
||||
DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
|
||||
ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
|
||||
DEP_alpha_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
|
||||
@ -2078,6 +2105,13 @@ DEP_i386_multi = $(DEP_i386_aout) $(DEP_i386_coff) \
|
||||
DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
|
||||
$(DEP_mips_elf)
|
||||
DEP_cris_multi = $(DEP_cris_aout) $(DEP_cris_elf)
|
||||
DEP_mep_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h
|
||||
DEP_mep_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/safe-ctype.h
|
||||
BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
|
||||
#MKDEP DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
|
||||
app.o: app.c
|
||||
|
@ -302,6 +302,7 @@ CPU_TYPES = \
|
||||
m68k \
|
||||
maxq \
|
||||
mcore \
|
||||
mep \
|
||||
mips \
|
||||
mmix \
|
||||
mn10200 \
|
||||
@ -490,6 +491,7 @@ TARGET_CPU_CFILES = \
|
||||
config/tc-m68hc11.c \
|
||||
config/tc-m68k.c \
|
||||
config/tc-mcore.c \
|
||||
config/tc-mep.c \
|
||||
config/tc-mips.c \
|
||||
config/tc-mmix.c \
|
||||
config/tc-mn10200.c \
|
||||
@ -543,6 +545,7 @@ TARGET_CPU_HFILES = \
|
||||
config/tc-m68hc11.h \
|
||||
config/tc-m68k.h \
|
||||
config/tc-mcore.h \
|
||||
config/tc-mep.h \
|
||||
config/tc-mips.h \
|
||||
config/tc-mmix.h \
|
||||
config/tc-mn10200.h \
|
||||
@ -1254,6 +1257,22 @@ DEPTC_mips_multi = $(DEPTC_mips_coff) $(DEPTC_mips_ecoff) \
|
||||
$(DEPTC_mips_elf)
|
||||
|
||||
DEPTC_cris_multi = $(DEPTC_cris_aout) $(DEPTC_cris_elf)
|
||||
DEPTC_mep_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
|
||||
$(srcdir)/config/tc-mep.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h dwarf2dbg.h \
|
||||
subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mep-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/mep-opc.h \
|
||||
cgen.h $(INCDIR)/elf/common.h $(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/safe-ctype.h
|
||||
|
||||
DEPTC_mep_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
dwarf2dbg.h subsegs.h $(INCDIR)/obstack.h $(srcdir)/../opcodes/mep-desc.h \
|
||||
$(INCDIR)/opcode/cgen.h $(srcdir)/../opcodes/mep-opc.h \
|
||||
cgen.h $(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h \
|
||||
$(BFDDIR)/libbfd.h $(INCDIR)/safe-ctype.h
|
||||
|
||||
DEPOBJ_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
|
||||
ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h \
|
||||
$(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h \
|
||||
@ -1688,6 +1707,18 @@ DEPOBJ_mips_multi = $(DEPOBJ_mips_coff) $(DEPOBJ_mips_ecoff) \
|
||||
$(DEPOBJ_mips_elf)
|
||||
|
||||
DEPOBJ_cris_multi = $(DEPOBJ_cris_aout) $(DEPOBJ_cris_elf)
|
||||
DEPOBJ_mep_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
|
||||
$(srcdir)/config/tc-mep.h $(INCDIR)/coff/internal.h \
|
||||
$(BFDDIR)/libcoff.h $(INCDIR)/bfdlink.h $(INCDIR)/obstack.h \
|
||||
subsegs.h $(INCDIR)/safe-ctype.h
|
||||
|
||||
DEPOBJ_mep_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
|
||||
$(INCDIR)/elf/mep.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/aout/aout64.h \
|
||||
$(INCDIR)/safe-ctype.h
|
||||
|
||||
DEP_alpha_ecoff = $(srcdir)/config/obj-ecoff.h $(srcdir)/config/tc-alpha.h \
|
||||
ecoff.h $(INCDIR)/coff/sym.h $(INCDIR)/coff/ecoff.h
|
||||
|
||||
@ -2061,6 +2092,15 @@ DEP_mips_multi = $(DEP_mips_coff) $(DEP_mips_ecoff) \
|
||||
$(DEP_mips_elf)
|
||||
|
||||
DEP_cris_multi = $(DEP_cris_aout) $(DEP_cris_elf)
|
||||
DEP_mep_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/symcat.h $(INCDIR)/coff/internal.h $(BFDDIR)/libcoff.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h
|
||||
|
||||
DEP_mep_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
|
||||
$(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-mep.h \
|
||||
$(INCDIR)/safe-ctype.h
|
||||
|
||||
BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
327
gas/cgen.c
327
gas/cgen.c
@ -26,6 +26,27 @@
|
||||
#include "cgen.h"
|
||||
#include "dwarf2dbg.h"
|
||||
|
||||
#include "symbols.h"
|
||||
#include "struc-symbol.h"
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
static expressionS * make_right_shifted_expr
|
||||
(expressionS *, const int, const int);
|
||||
|
||||
static unsigned long gas_cgen_encode_addend
|
||||
(const unsigned long, const unsigned long, const unsigned long, \
|
||||
const unsigned long, const unsigned long, const unsigned long, \
|
||||
const unsigned long);
|
||||
|
||||
static char * weak_operand_overflow_check
|
||||
(const expressionS *, const CGEN_OPERAND *);
|
||||
|
||||
static void queue_fixup_recursively
|
||||
(const int, const int, expressionS *, \
|
||||
const CGEN_MAYBE_MULTI_IFLD *, const int, const int);
|
||||
|
||||
static int rightshift = 0;
|
||||
#endif
|
||||
static void queue_fixup (int, int, expressionS *);
|
||||
|
||||
/* Opcode table descriptor, must be set by md_begin. */
|
||||
@ -63,6 +84,8 @@ struct fixup
|
||||
int opindex;
|
||||
int opinfo;
|
||||
expressionS exp;
|
||||
struct cgen_maybe_multi_ifield * field;
|
||||
int msb_field_p;
|
||||
};
|
||||
|
||||
static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
|
||||
@ -246,6 +269,8 @@ gas_cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offse
|
||||
+ (int) operand->type));
|
||||
fixP->fx_cgen.insn = insn;
|
||||
fixP->fx_cgen.opinfo = opinfo;
|
||||
fixP->fx_cgen.field = NULL;
|
||||
fixP->fx_cgen.msb_field_p = 0;
|
||||
|
||||
return fixP;
|
||||
}
|
||||
@ -284,10 +309,26 @@ gas_cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
|
||||
+ (int) operand->type));
|
||||
fixP->fx_cgen.insn = insn;
|
||||
fixP->fx_cgen.opinfo = opinfo;
|
||||
fixP->fx_cgen.field = NULL;
|
||||
fixP->fx_cgen.msb_field_p = 0;
|
||||
|
||||
return fixP;
|
||||
}
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
static symbolS *
|
||||
expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
|
||||
{
|
||||
expressionS e;
|
||||
|
||||
e.X_op = op;
|
||||
e.X_add_symbol = s1;
|
||||
e.X_op_symbol = s2;
|
||||
e.X_add_number = 0;
|
||||
return make_expr_symbol (& e);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Used for communication between the next two procedures. */
|
||||
static jmp_buf expr_jmp_buf;
|
||||
static int expr_jmp_buf_p;
|
||||
@ -305,7 +346,12 @@ static int expr_jmp_buf_p;
|
||||
|
||||
const char *
|
||||
gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
CGEN_CPU_DESC cd;
|
||||
#else
|
||||
CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
|
||||
#endif
|
||||
enum cgen_parse_operand_type want;
|
||||
const char **strP;
|
||||
int opindex;
|
||||
@ -326,6 +372,13 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
|
||||
const char *errmsg;
|
||||
expressionS exp;
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
volatile int signed_p = 0;
|
||||
symbolS * stmp = NULL;
|
||||
bfd_reloc_code_real_type reloc_type;
|
||||
const CGEN_OPERAND * operand;
|
||||
fixS dummy_fixup;
|
||||
#endif
|
||||
if (want == CGEN_PARSE_OPERAND_INIT)
|
||||
{
|
||||
gas_cgen_init_parse ();
|
||||
@ -383,9 +436,82 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP)
|
||||
break;
|
||||
de_fault:
|
||||
default:
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
/* Look up operand, check to see if there's an obvious
|
||||
overflow (this helps disambiguate some insn parses). */
|
||||
operand = cgen_operand_lookup_by_num (cd, opindex);
|
||||
errmsg = weak_operand_overflow_check (& exp, operand);
|
||||
|
||||
if (! errmsg)
|
||||
{
|
||||
/* Fragment the expression as necessary, and queue a reloc. */
|
||||
memset (& dummy_fixup, 0, sizeof (fixS));
|
||||
|
||||
reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
|
||||
|
||||
if (exp.X_op == O_symbol
|
||||
&& reloc_type == BFD_RELOC_RELC
|
||||
&& exp.X_add_symbol->sy_value.X_op == O_constant
|
||||
&& exp.X_add_symbol->bsym->section != expr_section
|
||||
&& exp.X_add_symbol->bsym->section != absolute_section
|
||||
&& exp.X_add_symbol->bsym->section != undefined_section)
|
||||
{
|
||||
/* Local labels will have been (eagerly) turned into constants
|
||||
by now, due to the inappropriately deep insight of the
|
||||
expression parser. Unfortunately make_expr_symbol
|
||||
prematurely dives into the symbol evaluator, and in this
|
||||
case it gets a bad answer, so we manually create the
|
||||
expression symbol we want here. */
|
||||
stmp = symbol_create (FAKE_LABEL_NAME, expr_section, 0,
|
||||
& zero_address_frag);
|
||||
symbol_set_value_expression (stmp, & exp);
|
||||
}
|
||||
else
|
||||
stmp = make_expr_symbol (& exp);
|
||||
|
||||
/* If this is a pc-relative RELC operand, we
|
||||
need to subtract "." from the expression. */
|
||||
if (reloc_type == BFD_RELOC_RELC
|
||||
&& CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
|
||||
stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
|
||||
|
||||
/* FIXME: this is not a perfect heuristic for figuring out
|
||||
whether an operand is signed: it only works when the operand
|
||||
is an immediate. it's not terribly likely that any other
|
||||
values will be signed relocs, but it's possible. */
|
||||
if (operand && (operand->hw_type == HW_H_SINT))
|
||||
signed_p = 1;
|
||||
|
||||
if (stmp->bsym && (stmp->bsym->section == expr_section))
|
||||
{
|
||||
if (signed_p)
|
||||
stmp->bsym->flags |= BSF_SRELC;
|
||||
else
|
||||
stmp->bsym->flags |= BSF_RELC;
|
||||
}
|
||||
|
||||
/* Now package it all up for the fixup emitter. */
|
||||
exp.X_op = O_symbol;
|
||||
exp.X_op_symbol = 0;
|
||||
exp.X_add_symbol = stmp;
|
||||
exp.X_add_number = 0;
|
||||
|
||||
/* Re-init rightshift quantity, just in case. */
|
||||
rightshift = operand->length;
|
||||
queue_fixup_recursively (opindex, opinfo_1, & exp,
|
||||
(reloc_type == BFD_RELOC_RELC) ?
|
||||
& (operand->index_fields) : 0,
|
||||
signed_p, -1);
|
||||
}
|
||||
* resultP = errmsg
|
||||
? CGEN_PARSE_OPERAND_RESULT_ERROR
|
||||
: CGEN_PARSE_OPERAND_RESULT_QUEUED;
|
||||
*valueP = 0;
|
||||
#else
|
||||
queue_fixup (opindex, opinfo_1, &exp);
|
||||
*valueP = 0;
|
||||
*resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -553,6 +679,8 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
|
||||
insn, length, operand,
|
||||
fixups[i].opinfo,
|
||||
&fixups[i].exp);
|
||||
fixP->fx_cgen.field = fixups[i].field;
|
||||
fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
|
||||
if (result)
|
||||
result->fixups[i] = fixP;
|
||||
}
|
||||
@ -564,6 +692,167 @@ gas_cgen_finish_insn (insn, buf, length, relax_p, result)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
/* Queue many fixups, recursively. If the field is a multi-ifield,
|
||||
repeatedly queue its sub-parts, right shifted to fit into the field (we
|
||||
assume here multi-fields represent a left-to-right, MSB0-LSB0
|
||||
reading). */
|
||||
|
||||
static void
|
||||
queue_fixup_recursively (const int opindex,
|
||||
const int opinfo,
|
||||
expressionS * expP,
|
||||
const CGEN_MAYBE_MULTI_IFLD * field,
|
||||
const int signed_p,
|
||||
const int part_of_multi)
|
||||
{
|
||||
if (field && field->count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < field->count; ++ i)
|
||||
queue_fixup_recursively (opindex, opinfo, expP,
|
||||
& (field->val.multi[i]), signed_p, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
expressionS * new_exp = expP;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf ("queueing fixup for field %s\n",
|
||||
(field ? field->val.leaf->name : "??"));
|
||||
print_symbol_value (expP->X_add_symbol);
|
||||
#endif
|
||||
if (field && part_of_multi != -1)
|
||||
{
|
||||
rightshift -= field->val.leaf->length;
|
||||
|
||||
/* Shift reloc value by number of bits remaining after this
|
||||
field. */
|
||||
if (rightshift)
|
||||
new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
|
||||
}
|
||||
|
||||
/* Truncate reloc values to length, *after* leftmost one. */
|
||||
fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
|
||||
fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
|
||||
|
||||
queue_fixup (opindex, opinfo, new_exp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Encode the self-describing RELC reloc format's addend. */
|
||||
|
||||
static unsigned long
|
||||
gas_cgen_encode_addend (const unsigned long start, /* in bits */
|
||||
const unsigned long len, /* in bits */
|
||||
const unsigned long oplen, /* in bits */
|
||||
const unsigned long wordsz, /* in bytes */
|
||||
const unsigned long chunksz, /* in bytes */
|
||||
const unsigned long signed_p,
|
||||
const unsigned long trunc_p)
|
||||
{
|
||||
unsigned long res = 0L;
|
||||
|
||||
res |= start & 0x3F;
|
||||
res |= (oplen & 0x3F) << 6;
|
||||
res |= (len & 0x3F) << 12;
|
||||
res |= (wordsz & 0xF) << 18;
|
||||
res |= (chunksz & 0xF) << 22;
|
||||
res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
|
||||
res |= signed_p << 28;
|
||||
res |= trunc_p << 29;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Purpose: make a weak check that the expression doesn't overflow the
|
||||
operand it's to be inserted into.
|
||||
|
||||
Rationale: some insns used to use %operators to disambiguate during a
|
||||
parse. when these %operators are translated to expressions by the macro
|
||||
expander, the ambiguity returns. we attempt to disambiguate by field
|
||||
size.
|
||||
|
||||
Method: check to see if the expression's top node is an O_and operator,
|
||||
and the mask is larger than the operand length. This would be an
|
||||
overflow, so signal it by returning an error string. Any other case is
|
||||
ambiguous, so we assume it's OK and return NULL. */
|
||||
|
||||
static char *
|
||||
weak_operand_overflow_check (const expressionS * exp,
|
||||
const CGEN_OPERAND * operand)
|
||||
{
|
||||
const unsigned long len = operand->length;
|
||||
unsigned long mask;
|
||||
unsigned long opmask = (((1L << (len - 1)) - 1) << 1) | 1;
|
||||
|
||||
if (!exp)
|
||||
return NULL;
|
||||
|
||||
if (exp->X_op != O_bit_and)
|
||||
{
|
||||
/* Check for implicit overflow flag. */
|
||||
if (CGEN_OPERAND_ATTR_VALUE
|
||||
(operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
|
||||
return _("a reloc on this operand implies an overflow");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mask = exp->X_add_number;
|
||||
|
||||
if (exp->X_add_symbol &&
|
||||
exp->X_add_symbol->sy_value.X_op == O_constant)
|
||||
mask |= exp->X_add_symbol->sy_value.X_add_number;
|
||||
|
||||
if (exp->X_op_symbol &&
|
||||
exp->X_op_symbol->sy_value.X_op == O_constant)
|
||||
mask |= exp->X_op_symbol->sy_value.X_add_number;
|
||||
|
||||
/* Want to know if mask covers more bits than opmask.
|
||||
this is the same as asking if mask has any bits not in opmask,
|
||||
or whether (mask & ~opmask) is nonzero. */
|
||||
if (mask && (mask & ~opmask))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
|
||||
mask, ~opmask, (mask & ~opmask));
|
||||
#endif
|
||||
return _("operand mask overflow");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static expressionS *
|
||||
make_right_shifted_expr (expressionS * exp,
|
||||
const int amount,
|
||||
const int signed_p)
|
||||
{
|
||||
symbolS * stmp = 0;
|
||||
expressionS * new_exp;
|
||||
|
||||
stmp = expr_build_binary (O_right_shift,
|
||||
make_expr_symbol (exp),
|
||||
expr_build_uconstant (amount));
|
||||
|
||||
if (signed_p)
|
||||
stmp->bsym->flags |= BSF_SRELC;
|
||||
else
|
||||
stmp->bsym->flags |= BSF_RELC;
|
||||
|
||||
/* Then wrap that in a "symbol expr" for good measure. */
|
||||
new_exp = xmalloc (sizeof (expressionS));
|
||||
memset (new_exp, 0, sizeof (expressionS));
|
||||
new_exp->X_op = O_symbol;
|
||||
new_exp->X_op_symbol = 0;
|
||||
new_exp->X_add_symbol = stmp;
|
||||
new_exp->X_add_number = 0;
|
||||
|
||||
return new_exp;
|
||||
}
|
||||
#endif
|
||||
/* Apply a fixup to the object code. This is called for all the
|
||||
fixups we generated by the call to fix_new_exp, above. In the call
|
||||
above we used a reloc code which was the largest legal reloc code
|
||||
@ -602,6 +891,30 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
|
||||
bfd_reloc_code_real_type reloc_type;
|
||||
CGEN_FIELDS *fields = alloca (CGEN_CPU_SIZEOF_FIELDS (cd));
|
||||
const CGEN_INSN *insn = fixP->fx_cgen.insn;
|
||||
int start;
|
||||
int length;
|
||||
int signed_p = 0;
|
||||
|
||||
if (fixP->fx_cgen.field)
|
||||
{
|
||||
/* Use the twisty little pointer path
|
||||
back to the ifield if it exists. */
|
||||
start = fixP->fx_cgen.field->val.leaf->start;
|
||||
length = fixP->fx_cgen.field->val.leaf->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Or the far less useful operand-size guesstimate. */
|
||||
start = operand->start;
|
||||
length = operand->length;
|
||||
}
|
||||
|
||||
/* FIXME: this is not a perfect heuristic for figuring out
|
||||
whether an operand is signed: it only works when the operand
|
||||
is an immediate. it's not terribly likely that any other
|
||||
values will be signed relocs, but it's possible. */
|
||||
if (operand && (operand->hw_type == HW_H_SINT))
|
||||
signed_p = 1;
|
||||
|
||||
/* If the reloc has been fully resolved finish the operand here. */
|
||||
/* FIXME: This duplicates the capabilities of code in BFD. */
|
||||
@ -644,6 +957,18 @@ gas_cgen_md_apply_fix (fixP, valP, seg)
|
||||
partial_inplace == false. */
|
||||
|
||||
reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
if (reloc_type == BFD_RELOC_RELC)
|
||||
{
|
||||
/* Change addend to "self-describing" form,
|
||||
for BFD to handle in the linker. */
|
||||
value = gas_cgen_encode_addend (start, operand->length,
|
||||
length, fixP->fx_size,
|
||||
cd->insn_chunk_bitsize / 8,
|
||||
signed_p,
|
||||
! (fixP->fx_cgen.msb_field_p));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (reloc_type != BFD_RELOC_NONE)
|
||||
fixP->fx_r_type = reloc_type;
|
||||
@ -699,7 +1024,6 @@ gas_cgen_tc_gen_reloc (section, fixP)
|
||||
fixS * fixP;
|
||||
{
|
||||
arelent *reloc;
|
||||
|
||||
reloc = (arelent *) xmalloc (sizeof (arelent));
|
||||
|
||||
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
|
||||
@ -737,3 +1061,4 @@ gas_cgen_begin ()
|
||||
else
|
||||
cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,10 @@
|
||||
#include "elf/x86-64.h"
|
||||
#endif
|
||||
|
||||
#ifdef TC_MEP
|
||||
#include "elf/mep.h"
|
||||
#endif
|
||||
|
||||
static void obj_elf_line (int);
|
||||
static void obj_elf_size (int);
|
||||
static void obj_elf_type (int);
|
||||
|
1886
gas/config/tc-mep.c
Normal file
1886
gas/config/tc-mep.c
Normal file
File diff suppressed because it is too large
Load Diff
119
gas/config/tc-mep.h
Normal file
119
gas/config/tc-mep.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* tc-mep.h -- Header file for tc-mep.c.
|
||||
Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
GAS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GAS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#define TC_MEP
|
||||
|
||||
/* Support computed relocations. */
|
||||
#define OBJ_COMPLEX_RELC
|
||||
|
||||
/* Support many operands per instruction. */
|
||||
#define GAS_CGEN_MAX_FIXUPS 10
|
||||
|
||||
#define LISTING_HEADER "MEP GAS "
|
||||
|
||||
/* The target BFD architecture. */
|
||||
#define TARGET_ARCH bfd_arch_mep
|
||||
|
||||
#define TARGET_FORMAT (target_big_endian ? "elf32-mep" : "elf32-mep-little")
|
||||
|
||||
/* This is the default. */
|
||||
#define TARGET_BYTES_BIG_ENDIAN 1
|
||||
|
||||
/* Permit temporary numeric labels. */
|
||||
#define LOCAL_LABELS_FB 1
|
||||
|
||||
/* .-foo gets turned into PC relative relocs. */
|
||||
#define DIFF_EXPR_OK
|
||||
|
||||
/* We don't need to handle .word strangely. */
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
/* Values passed to md_apply_fix don't include the symbol value. */
|
||||
#define MD_APPLY_SYM_VALUE(FIX) 0
|
||||
|
||||
#define MD_APPLY_FIX
|
||||
#define md_apply_fix mep_apply_fix
|
||||
extern void mep_apply_fix (struct fix *, valueT *, segT);
|
||||
|
||||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
||||
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section (FIXP, SEC)
|
||||
extern long md_pcrel_from_section (struct fix *, segT);
|
||||
|
||||
#define tc_frob_file() mep_frob_file ()
|
||||
extern void mep_frob_file (void);
|
||||
|
||||
#define tc_fix_adjustable(fixP) mep_fix_adjustable (fixP)
|
||||
extern bfd_boolean mep_fix_adjustable (struct fix *);
|
||||
|
||||
/* After creating a fixup for an instruction operand, we need
|
||||
to check for HI16 relocs and queue them up for later sorting. */
|
||||
#define md_cgen_record_fixup_exp mep_cgen_record_fixup_exp
|
||||
|
||||
/* When relaxing, we need to emit various relocs we otherwise wouldn't. */
|
||||
#define TC_FORCE_RELOCATION(fix) mep_force_relocation (fix)
|
||||
extern int mep_force_relocation (struct fix *);
|
||||
|
||||
#define tc_gen_reloc gas_cgen_tc_gen_reloc
|
||||
|
||||
extern void gas_cgen_md_operand (expressionS *);
|
||||
#define md_operand(x) gas_cgen_md_operand (x)
|
||||
|
||||
#define md_flush_pending_output() mep_flush_pending_output()
|
||||
extern int mep_flush_pending_output(void);
|
||||
|
||||
extern const struct relax_type md_relax_table[];
|
||||
#define TC_GENERIC_RELAX_TABLE md_relax_table
|
||||
|
||||
/* Account for inserting a jmp after the insn. */
|
||||
#define TC_CGEN_MAX_RELAX(insn, len) ((len) + 4)
|
||||
|
||||
extern void mep_prepare_relax_scan (fragS *, offsetT *, relax_substateT);
|
||||
#define md_prepare_relax_scan(FRAGP, ADDR, AIM, STATE, TYPE) \
|
||||
mep_prepare_relax_scan (FRAGP, &AIM, STATE)
|
||||
|
||||
#define skip_whitespace(str) while (*(str) == ' ') ++(str)
|
||||
|
||||
/* Support for core/vliw mode switching. */
|
||||
#define CORE 0
|
||||
#define VLIW 1
|
||||
#define MAX_PARALLEL_INSNS 56 /* From email from Toshiba. */
|
||||
#define VTEXT_SECTION_NAME ".vtext"
|
||||
|
||||
/* Needed to process pending instructions when a label is encountered. */
|
||||
#define TC_START_LABEL(ch, ptr) ((ch == ':') && mep_flush_pending_output ())
|
||||
|
||||
#define tc_unrecognized_line(c) mep_unrecognized_line (c)
|
||||
extern int mep_unrecognized_line (int);
|
||||
#define md_cleanup mep_cleanup
|
||||
extern void mep_cleanup (void);
|
||||
|
||||
#define md_elf_section_letter mep_elf_section_letter
|
||||
extern int mep_elf_section_letter (int, char **);
|
||||
#define md_elf_section_flags mep_elf_section_flags
|
||||
extern flagword mep_elf_section_flags (flagword, int, int);
|
||||
|
||||
#define ELF_TC_SPECIAL_SECTIONS \
|
||||
{ VTEXT_SECTION_NAME, SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR|SHF_MEP_VLIW },
|
||||
|
||||
/* The values of the following enum are for use with parinsnum, which
|
||||
is a variable in md_assemble that keeps track of whether or not the
|
||||
next instruction is expected to be the first or second instrucion in
|
||||
a parallelization group. */
|
||||
typedef enum exp_par_insn_{FIRST, SECOND} EXP_PAR_INSN;
|
4
gas/configure
vendored
4
gas/configure
vendored
@ -4778,6 +4778,10 @@ _ACEOF
|
||||
esac
|
||||
;;
|
||||
|
||||
mep)
|
||||
using_cgen=yes
|
||||
;;
|
||||
|
||||
mips)
|
||||
echo ${extra_objects} | grep -s "itbl-parse.o"
|
||||
if test $? -ne 0 ; then
|
||||
|
@ -304,6 +304,10 @@ changequote([,])dnl
|
||||
esac
|
||||
;;
|
||||
|
||||
mep)
|
||||
using_cgen=yes
|
||||
;;
|
||||
|
||||
mips)
|
||||
echo ${extra_objects} | grep -s "itbl-parse.o"
|
||||
if test $? -ne 0 ; then
|
||||
|
@ -52,6 +52,7 @@ case ${cpu} in
|
||||
m6811|m6812|m68hc12) cpu_type=m68hc11 ;;
|
||||
m683??) cpu_type=m68k ;;
|
||||
maxq) cpu_type=maxq ;;
|
||||
mep-*-elf) cpu_type=mep endian=big ;;
|
||||
mips*el) cpu_type=mips endian=little ;;
|
||||
mips*) cpu_type=mips endian=big ;;
|
||||
mt) cpu_type=mt endian=big ;;
|
||||
@ -257,6 +258,8 @@ case ${generic_target} in
|
||||
|
||||
maxq-*-coff) fmt=coff bfd_gas=yes ;;
|
||||
|
||||
mep-*-elf) fmt=elf ;;
|
||||
|
||||
mcore-*-elf) fmt=elf ;;
|
||||
mcore-*-pe) fmt=coff em=pe bfd_gas=yes ;;
|
||||
|
||||
|
326
gas/symbols.c
326
gas/symbols.c
@ -881,6 +881,69 @@ verify_symbol_chain (symbolS *rootP, symbolS *lastP)
|
||||
assert (lastP == symbolP);
|
||||
}
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
|
||||
static int
|
||||
use_complex_relocs_for (symbolS * symp)
|
||||
{
|
||||
switch (symp->sy_value.X_op)
|
||||
{
|
||||
case O_constant:
|
||||
return 0;
|
||||
|
||||
case O_symbol:
|
||||
case O_symbol_rva:
|
||||
case O_uminus:
|
||||
case O_bit_not:
|
||||
case O_logical_not:
|
||||
if ( (S_IS_COMMON (symp->sy_value.X_add_symbol)
|
||||
|| S_IS_LOCAL (symp->sy_value.X_add_symbol))
|
||||
&&
|
||||
(S_IS_DEFINED (symp->sy_value.X_add_symbol)
|
||||
&& S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case O_multiply:
|
||||
case O_divide:
|
||||
case O_modulus:
|
||||
case O_left_shift:
|
||||
case O_right_shift:
|
||||
case O_bit_inclusive_or:
|
||||
case O_bit_or_not:
|
||||
case O_bit_exclusive_or:
|
||||
case O_bit_and:
|
||||
case O_add:
|
||||
case O_subtract:
|
||||
case O_eq:
|
||||
case O_ne:
|
||||
case O_lt:
|
||||
case O_le:
|
||||
case O_ge:
|
||||
case O_gt:
|
||||
case O_logical_and:
|
||||
case O_logical_or:
|
||||
|
||||
if ( (S_IS_COMMON (symp->sy_value.X_add_symbol)
|
||||
|| S_IS_LOCAL (symp->sy_value.X_add_symbol))
|
||||
&&
|
||||
(S_IS_COMMON (symp->sy_value.X_op_symbol)
|
||||
|| S_IS_LOCAL (symp->sy_value.X_op_symbol))
|
||||
|
||||
&& S_IS_DEFINED (symp->sy_value.X_add_symbol)
|
||||
&& S_IS_DEFINED (symp->sy_value.X_op_symbol)
|
||||
&& S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section
|
||||
&& S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
report_op_error (symbolS *symp, symbolS *left, symbolS *right)
|
||||
{
|
||||
@ -983,6 +1046,53 @@ resolve_symbol_value (symbolS *symp)
|
||||
final_val = 0;
|
||||
resolved = 1;
|
||||
}
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
else if (final_seg == expr_section
|
||||
&& use_complex_relocs_for (symp))
|
||||
{
|
||||
symbolS * relc_symbol = NULL;
|
||||
char * relc_symbol_name = NULL;
|
||||
|
||||
relc_symbol_name = symbol_relc_make_expr (& symp->sy_value);
|
||||
|
||||
/* For debugging, print out conversion input & output. */
|
||||
#ifdef DEBUG_SYMS
|
||||
print_expr (& symp->sy_value);
|
||||
if (relc_symbol_name)
|
||||
fprintf (stderr, "-> relc symbol: %s\n", relc_symbol_name);
|
||||
#endif
|
||||
|
||||
if (relc_symbol_name != NULL)
|
||||
relc_symbol = symbol_new (relc_symbol_name, undefined_section,
|
||||
0, & zero_address_frag);
|
||||
|
||||
if (relc_symbol == NULL)
|
||||
{
|
||||
as_bad (_("cannot convert expression symbol %s to complex relocation"),
|
||||
S_GET_NAME (symp));
|
||||
resolved = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol_table_insert (relc_symbol);
|
||||
|
||||
/* S_CLEAR_EXTERNAL (relc_symbol); */
|
||||
if (symp->bsym->flags & BSF_SRELC)
|
||||
relc_symbol->bsym->flags |= BSF_SRELC;
|
||||
else
|
||||
relc_symbol->bsym->flags |= BSF_RELC;
|
||||
/* symp->bsym->flags |= BSF_RELC; */
|
||||
copy_symbol_attributes (symp, relc_symbol);
|
||||
symp->sy_value.X_op = O_symbol;
|
||||
symp->sy_value.X_add_symbol = relc_symbol;
|
||||
symp->sy_value.X_add_number = 0;
|
||||
resolved = 1;
|
||||
}
|
||||
|
||||
final_seg = undefined_section;
|
||||
goto exit_dont_set_value;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
symbolS *add_symbol, *op_symbol;
|
||||
@ -2827,3 +2937,219 @@ symbol_print_statistics (FILE *file)
|
||||
fprintf (file, "%lu mini local symbols created, %lu converted\n",
|
||||
local_symbol_count, local_symbol_conversion_count);
|
||||
}
|
||||
|
||||
#ifdef OBJ_COMPLEX_RELC
|
||||
|
||||
/* Convert given symbol to a new complex-relocation symbol name. This
|
||||
may bee a recursive function, since it might be called for non-leaf
|
||||
nodes (plain symbols) in the expression tree. The caller owns the
|
||||
returning string, so should free() it eventually. Errors are
|
||||
indicated via as_bad() and a NULL return value. The given symbol
|
||||
is marked with sy_used_in_reloc. */
|
||||
|
||||
char *
|
||||
symbol_relc_make_sym (symbolS * sym)
|
||||
{
|
||||
char * terminal = NULL;
|
||||
const char * sname;
|
||||
char typetag;
|
||||
int sname_len;
|
||||
|
||||
assert (sym != NULL);
|
||||
|
||||
/* Recurse to symbol_relc_make_expr if this symbol
|
||||
is defined as an expression or a plain value. */
|
||||
if ( S_GET_SEGMENT (sym) == expr_section
|
||||
|| S_GET_SEGMENT (sym) == absolute_section)
|
||||
return symbol_relc_make_expr (& sym->sy_value);
|
||||
|
||||
/* This may be a "fake symbol" L0\001, referring to ".".
|
||||
Write out a special null symbol to refer to this position. */
|
||||
if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME))
|
||||
return xstrdup (".");
|
||||
|
||||
/* We hope this is a plain leaf symbol. Construct the encoding
|
||||
as {S,s}II...:CCCCCCC....
|
||||
where 'S'/'s' means section symbol / plain symbol
|
||||
III is decimal for the symbol name length
|
||||
CCC is the symbol name itself. */
|
||||
symbol_mark_used_in_reloc (sym);
|
||||
|
||||
sname = S_GET_NAME (sym);
|
||||
sname_len = strlen (sname);
|
||||
typetag = symbol_section_p (sym) ? 'S' : 's';
|
||||
|
||||
terminal = xmalloc (1 /* S or s */
|
||||
+ 8 /* sname_len in decimal */
|
||||
+ 1 /* _ spacer */
|
||||
+ sname_len /* name itself */
|
||||
+ 1 /* \0 */ );
|
||||
|
||||
sprintf (terminal, "%c%d:%s", typetag, sname_len, sname);
|
||||
return terminal;
|
||||
}
|
||||
|
||||
/* Convert given value to a new complex-relocation symbol name. This
|
||||
is a non-recursive function, since it is be called for leaf nodes
|
||||
(plain values) in the expression tree. The caller owns the
|
||||
returning string, so should free() it eventually. No errors. */
|
||||
|
||||
char *
|
||||
symbol_relc_make_value (offsetT val)
|
||||
{
|
||||
char * terminal = xmalloc (28); /* Enough for long long. */
|
||||
|
||||
terminal[0] = '#';
|
||||
sprintf_vma (& terminal[1], val);
|
||||
return terminal;
|
||||
}
|
||||
|
||||
/* Convert given expression to a new complex-relocation symbol name.
|
||||
This is a recursive function, since it traverses the entire given
|
||||
expression tree. The caller owns the returning string, so should
|
||||
free() it eventually. Errors are indicated via as_bad() and a NULL
|
||||
return value. */
|
||||
|
||||
char *
|
||||
symbol_relc_make_expr (expressionS * exp)
|
||||
{
|
||||
char * opstr = NULL; /* Operator prefix string. */
|
||||
int arity = 0; /* Arity of this operator. */
|
||||
char * operands[3]; /* Up to three operands. */
|
||||
char * concat_string = NULL;
|
||||
|
||||
operands[0] = operands[1] = operands[2] = NULL;
|
||||
|
||||
assert (exp != NULL);
|
||||
|
||||
/* Match known operators -> fill in opstr, arity, operands[] and fall
|
||||
through to construct subexpression fragments; may instead return
|
||||
string directly for leaf nodes. */
|
||||
|
||||
/* See expr.h for the meaning of all these enums. Many operators
|
||||
have an unnatural arity (X_add_number implicitly added). The
|
||||
conversion logic expands them to explicit "+" subexpressions. */
|
||||
|
||||
switch (exp->X_op)
|
||||
{
|
||||
default:
|
||||
as_bad ("Unknown expression operator (enum %d)", exp->X_op);
|
||||
break;
|
||||
|
||||
/* Leaf nodes. */
|
||||
case O_constant:
|
||||
return symbol_relc_make_value (exp->X_add_number);
|
||||
|
||||
case O_symbol:
|
||||
if (exp->X_add_number)
|
||||
{
|
||||
arity = 2;
|
||||
opstr = "+";
|
||||
operands[0] = symbol_relc_make_sym (exp->X_add_symbol);
|
||||
operands[1] = symbol_relc_make_value (exp->X_add_number);
|
||||
break;
|
||||
}
|
||||
else
|
||||
return symbol_relc_make_sym (exp->X_add_symbol);
|
||||
|
||||
/* Helper macros for nesting nodes. */
|
||||
|
||||
#define HANDLE_XADD_OPT1(str_) \
|
||||
if (exp->X_add_number) \
|
||||
{ \
|
||||
arity = 2; \
|
||||
opstr = "+:" str_; \
|
||||
operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \
|
||||
operands[1] = symbol_relc_make_value (exp->X_add_number); \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
arity = 1; \
|
||||
opstr = str_; \
|
||||
operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \
|
||||
} \
|
||||
break
|
||||
|
||||
#define HANDLE_XADD_OPT2(str_) \
|
||||
if (exp->X_add_number) \
|
||||
{ \
|
||||
arity = 3; \
|
||||
opstr = "+:" str_; \
|
||||
operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \
|
||||
operands[1] = symbol_relc_make_sym (exp->X_op_symbol); \
|
||||
operands[2] = symbol_relc_make_value (exp->X_add_number); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
arity = 2; \
|
||||
opstr = str_; \
|
||||
operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \
|
||||
operands[1] = symbol_relc_make_sym (exp->X_op_symbol); \
|
||||
} \
|
||||
break
|
||||
|
||||
/* Nesting nodes. */
|
||||
|
||||
case O_uminus: HANDLE_XADD_OPT1 ("0-");
|
||||
case O_bit_not: HANDLE_XADD_OPT1 ("~");
|
||||
case O_logical_not: HANDLE_XADD_OPT1 ("!");
|
||||
case O_multiply: HANDLE_XADD_OPT2 ("*");
|
||||
case O_divide: HANDLE_XADD_OPT2 ("/");
|
||||
case O_modulus: HANDLE_XADD_OPT2 ("%");
|
||||
case O_left_shift: HANDLE_XADD_OPT2 ("<<");
|
||||
case O_right_shift: HANDLE_XADD_OPT2 (">>");
|
||||
case O_bit_inclusive_or: HANDLE_XADD_OPT2 ("|");
|
||||
case O_bit_exclusive_or: HANDLE_XADD_OPT2 ("^");
|
||||
case O_bit_and: HANDLE_XADD_OPT2 ("&");
|
||||
case O_add: HANDLE_XADD_OPT2 ("+");
|
||||
case O_subtract: HANDLE_XADD_OPT2 ("-");
|
||||
case O_eq: HANDLE_XADD_OPT2 ("==");
|
||||
case O_ne: HANDLE_XADD_OPT2 ("!=");
|
||||
case O_lt: HANDLE_XADD_OPT2 ("<");
|
||||
case O_le: HANDLE_XADD_OPT2 ("<=");
|
||||
case O_ge: HANDLE_XADD_OPT2 (">=");
|
||||
case O_gt: HANDLE_XADD_OPT2 (">");
|
||||
case O_logical_and: HANDLE_XADD_OPT2 ("&&");
|
||||
case O_logical_or: HANDLE_XADD_OPT2 ("||");
|
||||
}
|
||||
|
||||
/* Validate & reject early. */
|
||||
if (arity >= 1 && ((operands[0] == NULL) || (strlen (operands[0]) == 0)))
|
||||
opstr = NULL;
|
||||
if (arity >= 2 && ((operands[1] == NULL) || (strlen (operands[1]) == 0)))
|
||||
opstr = NULL;
|
||||
if (arity >= 3 && ((operands[2] == NULL) || (strlen (operands[2]) == 0)))
|
||||
opstr = NULL;
|
||||
|
||||
if (opstr == NULL)
|
||||
concat_string = NULL;
|
||||
else
|
||||
{
|
||||
/* Allocate new string; include inter-operand padding gaps etc. */
|
||||
concat_string = xmalloc (strlen (opstr)
|
||||
+ 1
|
||||
+ (arity >= 1 ? (strlen (operands[0]) + 1 ) : 0)
|
||||
+ (arity >= 2 ? (strlen (operands[1]) + 1 ) : 0)
|
||||
+ (arity >= 3 ? (strlen (operands[2]) + 0 ) : 0)
|
||||
+ 1);
|
||||
assert (concat_string != NULL);
|
||||
|
||||
/* Format the thing. */
|
||||
sprintf (concat_string,
|
||||
(arity == 0 ? "%s" :
|
||||
arity == 1 ? "%s:%s" :
|
||||
arity == 2 ? "%s:%s:%s" :
|
||||
/* arity == 3 */ "%s:%s:%s:%s"),
|
||||
opstr, operands[0], operands[1], operands[2]);
|
||||
}
|
||||
|
||||
/* Free operand strings (not opstr). */
|
||||
if (arity >= 1) xfree (operands[0]);
|
||||
if (arity >= 2) xfree (operands[1]);
|
||||
if (arity >= 3) xfree (operands[2]);
|
||||
|
||||
return concat_string;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,9 @@ extern int symbol_table_frozen;
|
||||
default. */
|
||||
extern int symbols_case_sensitive;
|
||||
|
||||
char * symbol_relc_make_expr (expressionS *);
|
||||
char * symbol_relc_make_sym (symbolS *);
|
||||
char * symbol_relc_make_value (offsetT);
|
||||
char *decode_local_label_name (char *s);
|
||||
symbolS *symbol_find (const char *name);
|
||||
symbolS *symbol_find_noref (const char *name, int noref);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2007-02-05 Dave Brolley <brolley@redhat.com>
|
||||
|
||||
* gas/mep/relocs-junk1.s: Add a .data section.
|
||||
* gas/mep/relocs.d: Updated to match above.
|
||||
|
||||
2007-02-04 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR gas/3961
|
||||
|
@ -16,7 +16,10 @@ gas_test "p2425.s" "" "" "pcrel values in assignment"
|
||||
# The ".space" directive is taken care of in the C54x-specific tests, so fail
|
||||
# here
|
||||
#
|
||||
if { [istarget hppa*-*-*] || [istarget *c54x*-*-*] } then {
|
||||
# The test also doesn't work on mep targets, since they use RELC, and it
|
||||
# will avoid simplifying the expression since it conservatively assumes
|
||||
# ugly expressions can be saved until link-time.
|
||||
if { [istarget hppa*-*-*] || [istarget *c54x*-*-*] || [istarget mep*-*-*]} then {
|
||||
setup_xfail *-*-*
|
||||
fail "simplifiable double subtraction"
|
||||
} else {
|
||||
|
1345
gas/testsuite/gas/mep/allinsn.d
Normal file
1345
gas/testsuite/gas/mep/allinsn.d
Normal file
File diff suppressed because it is too large
Load Diff
9
gas/testsuite/gas/mep/allinsn.exp
Normal file
9
gas/testsuite/gas/mep/allinsn.exp
Normal file
@ -0,0 +1,9 @@
|
||||
# MEP assembler testsuite. -*- Tcl -*-
|
||||
|
||||
if [istarget mep*-*-*] {
|
||||
foreach test {allinsn dj1 dj2} {
|
||||
run_dump_test $test
|
||||
run_dump_test $test.le
|
||||
}
|
||||
run_dump_test branch1
|
||||
}
|
1346
gas/testsuite/gas/mep/allinsn.le.d
Normal file
1346
gas/testsuite/gas/mep/allinsn.le.d
Normal file
File diff suppressed because it is too large
Load Diff
1536
gas/testsuite/gas/mep/allinsn.s
Normal file
1536
gas/testsuite/gas/mep/allinsn.s
Normal file
File diff suppressed because it is too large
Load Diff
14
gas/testsuite/gas/mep/branch1.d
Normal file
14
gas/testsuite/gas/mep/branch1.d
Normal file
@ -0,0 +1,14 @@
|
||||
#objdump: -dzr
|
||||
|
||||
.*: *file format elf32-mep
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
.* <.*>:
|
||||
.*: 00 00 * nop
|
||||
.*: e4 51 00 04 * beq \$4,\$5,.* <foo>
|
||||
.*: 00 00 * nop
|
||||
.*: 00 00 * nop
|
||||
|
||||
.* <foo>:
|
||||
.*: 00 00 * nop
|
7
gas/testsuite/gas/mep/branch1.s
Normal file
7
gas/testsuite/gas/mep/branch1.s
Normal file
@ -0,0 +1,7 @@
|
||||
.globl foo
|
||||
nop
|
||||
beq $4,$5,foo
|
||||
nop
|
||||
nop
|
||||
foo:
|
||||
nop
|
42
gas/testsuite/gas/mep/complex-relocs.exp
Normal file
42
gas/testsuite/gas/mep/complex-relocs.exp
Normal file
@ -0,0 +1,42 @@
|
||||
# complex relocations testsuite
|
||||
|
||||
proc ld_test { objects ldflags dest test } {
|
||||
set ld_output [target_link $objects $dest $ldflags]
|
||||
if [string match "" $ld_output] then { pass $test } else { fail $test }
|
||||
}
|
||||
|
||||
proc ld_test_error { objects ldflags dest test } {
|
||||
set ld_output [target_link $objects $dest $ldflags]
|
||||
if [string match "" $ld_output] then { fail $test } else { pass $test }
|
||||
}
|
||||
|
||||
proc objdump_test { exec flags dest test } {
|
||||
set objdump [find_binutils_prog objdump]
|
||||
verbose -log "$objdump $flags $exec > $dest"
|
||||
catch "exec $objdump $flags $exec > $dest" objdump_output
|
||||
if [string match "" $objdump_output] then { pass $test } else { fail $test }
|
||||
}
|
||||
|
||||
proc regexp_test { file1 file2 test } {
|
||||
if [regexp_diff $file1 $file2] then { fail $test } else { pass $test }
|
||||
}
|
||||
|
||||
|
||||
global srcdir subdir
|
||||
if [istarget mep*-*-*] {
|
||||
|
||||
# test that complex relocs between files work, generally
|
||||
gas_test relocs-junk1.s {-mconfig=fmax -o relocs-junk1.o} {} {assembling relocs-junk1}
|
||||
gas_test relocs-syms.s {-mconfig=fmax -o relocs-syms.o} {} {assembling relocs-syms}
|
||||
gas_test relocs-junk2.s {-mconfig=fmax -o relocs-junk2.o} {} {assembling relocs-junk2}
|
||||
gas_test relocs-refs.s {-mconfig=fmax -o relocs-refs.o} {} {assembling relocs-refs}
|
||||
ld_test {relocs-junk1.o relocs-syms.o relocs-junk2.o relocs-refs.o} {--defsym __stack=0x1ffff0 --defsym __sbss_end=0x1000 -e 1233} {relocs.x} {linking relocs.x}
|
||||
objdump_test {relocs.x} {-dzs} {relocs.dump} {disassembling relocs.x}
|
||||
regexp_test {relocs.dump} "$srcdir/$subdir/relocs.d" {matching disassembly for relocs.x}
|
||||
|
||||
foreach test {3} {
|
||||
# perform specific negative boundary tests
|
||||
gas_test "relocs-bad$test.s" [list -mconfig=fmax -o "relocs-bad$test.o"] {} [list assembling "relocs-bad$test"]
|
||||
ld_test_error "relocs-bad$test.o" {-e 1233} "relocs-bad$test.x" [list linking "relocs-bad$test"]
|
||||
}
|
||||
}
|
1393
gas/testsuite/gas/mep/dj1.d
Normal file
1393
gas/testsuite/gas/mep/dj1.d
Normal file
File diff suppressed because it is too large
Load Diff
1393
gas/testsuite/gas/mep/dj1.le.d
Normal file
1393
gas/testsuite/gas/mep/dj1.le.d
Normal file
File diff suppressed because it is too large
Load Diff
1306
gas/testsuite/gas/mep/dj1.s
Normal file
1306
gas/testsuite/gas/mep/dj1.s
Normal file
File diff suppressed because it is too large
Load Diff
11
gas/testsuite/gas/mep/dj2.d
Normal file
11
gas/testsuite/gas/mep/dj2.d
Normal file
@ -0,0 +1,11 @@
|
||||
#as:
|
||||
#objdump: -dr
|
||||
#name: dj2
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <.text>:
|
||||
0: 07 88 sb \$7,\(\$8\)
|
||||
2: 05 98 sb \$5,\(\$9\)
|
12
gas/testsuite/gas/mep/dj2.le.d
Normal file
12
gas/testsuite/gas/mep/dj2.le.d
Normal file
@ -0,0 +1,12 @@
|
||||
#as: -EL
|
||||
#objdump: -dr
|
||||
#source: dj2.s
|
||||
#name: dj2.le
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000000 <.text>:
|
||||
0: 88 07 sb \$7,\(\$8\)
|
||||
2: 98 05 sb \$5,\(\$9\)
|
5
gas/testsuite/gas/mep/dj2.s
Normal file
5
gas/testsuite/gas/mep/dj2.s
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
.text
|
||||
sb $7,($fp)
|
||||
sb $5,($9)
|
||||
|
15
gas/testsuite/gas/mep/relocs-bad3.s
Normal file
15
gas/testsuite/gas/mep/relocs-bad3.s
Normal file
@ -0,0 +1,15 @@
|
||||
.global main
|
||||
|
||||
test:
|
||||
mov $0,0
|
||||
|
||||
# negative test from case 106708
|
||||
|
||||
L1:
|
||||
mov $1,1
|
||||
mov $1,((L1 & 0x00007fff) | 0x00008000)
|
||||
ret
|
||||
mov $0,0
|
||||
main:
|
||||
mov $0,0
|
||||
ret
|
8
gas/testsuite/gas/mep/relocs-junk1.s
Normal file
8
gas/testsuite/gas/mep/relocs-junk1.s
Normal file
@ -0,0 +1,8 @@
|
||||
junk1:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
.data
|
||||
foodata: .word 42
|
7
gas/testsuite/gas/mep/relocs-junk2.s
Normal file
7
gas/testsuite/gas/mep/relocs-junk2.s
Normal file
@ -0,0 +1,7 @@
|
||||
junk2:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
55
gas/testsuite/gas/mep/relocs-refs.s
Normal file
55
gas/testsuite/gas/mep/relocs-refs.s
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
.global main
|
||||
.global foo
|
||||
.global bar
|
||||
main:
|
||||
nop
|
||||
nop
|
||||
lb $5, foo($3)
|
||||
bsr foo
|
||||
repeat $5, foo
|
||||
|
||||
nop
|
||||
nop
|
||||
lb $5, (-foo & 0xffff)($3)
|
||||
bsr -foo
|
||||
repeat $5, -foo
|
||||
|
||||
nop
|
||||
nop
|
||||
lb $5, (foo + bar)($3)
|
||||
bsr (foo + bar)
|
||||
repeat $5, (foo + bar)
|
||||
|
||||
jmp (foo << 3)
|
||||
jmp (foo >> 3)
|
||||
jmp (foo - bar) & 0x7fffff
|
||||
jmp (foo - main) & 0x7fffff
|
||||
jmp (.text - foo) & 0x7fffff
|
||||
jmp (.data - foo) & 0x7fffff
|
||||
jmp (foo - %sizeof(.text))
|
||||
jmp (foo * 7)
|
||||
jmp (foo / 7)
|
||||
jmp (foo % 7)
|
||||
jmp (foo ^ bar)
|
||||
jmp (foo | bar)
|
||||
jmp (foo & bar)
|
||||
jmp (foo == bar) << 5
|
||||
jmp (foo < bar) << 5
|
||||
jmp (foo <= bar) << 5
|
||||
jmp (foo > bar) << 5
|
||||
jmp (foo >= bar) << 5
|
||||
# jmp (foo != bar) # FIXME this appears to not work atm.
|
||||
jmp (foo && bar) << 5
|
||||
jmp (foo || bar) << 5
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
jmp %sizeof(.data) >> (((main ^ (bar + 0xf)) - ((foo | .text) << 2)) / 3)
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
18
gas/testsuite/gas/mep/relocs-syms.s
Normal file
18
gas/testsuite/gas/mep/relocs-syms.s
Normal file
@ -0,0 +1,18 @@
|
||||
.global foo
|
||||
.global bar
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
foo:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
bar:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
98
gas/testsuite/gas/mep/relocs.d
Normal file
98
gas/testsuite/gas/mep/relocs.d
Normal file
@ -0,0 +1,98 @@
|
||||
|
||||
relocs.x: file format elf32-mep
|
||||
|
||||
Contents of section .text:
|
||||
1000 00000000 00000000 00000000 00000000 ................
|
||||
1010 00000000 00000000 00000000 00000000 ................
|
||||
1020 00000000 00000000 00000000 00000000 ................
|
||||
1030 0000c53c 1012dee9 ffffe509 ffec0000 ...<............
|
||||
1040 0000c53c efeedd49 ffdfe509 efd20000 ...<...I........
|
||||
1050 0000c53c 202cdeb9 000fe509 07e9dc88 ...< ,..........
|
||||
1060 0080d818 0002dfc8 7fffdf28 7fffdf78 ...........\(...x
|
||||
1070 7fffdd98 0001da98 000fdbf8 0070da58 .............p.X
|
||||
1080 0002d828 0000d848 0000d8d8 0010d898 ...\(...H........
|
||||
1090 0010d808 0000d908 0000d908 0000d808 ................
|
||||
10a0 0000d808 0000d908 0000d908 00000000 ................
|
||||
10b0 00000000 0000d808 00000000 00000000 ................
|
||||
Contents of section .rostacktab:
|
||||
10c0 001ffff0 ....
|
||||
Contents of section .data:
|
||||
11c4 0000002a ...*
|
||||
Disassembly of section .text:
|
||||
|
||||
00001000 <junk1>:
|
||||
1000: 00 00 nop
|
||||
1002: 00 00 nop
|
||||
1004: 00 00 nop
|
||||
1006: 00 00 nop
|
||||
1008: 00 00 nop
|
||||
100a: 00 00 nop
|
||||
100c: 00 00 nop
|
||||
100e: 00 00 nop
|
||||
1010: 00 00 nop
|
||||
|
||||
00001012 <foo>:
|
||||
1012: 00 00 nop
|
||||
1014: 00 00 nop
|
||||
1016: 00 00 nop
|
||||
1018: 00 00 nop
|
||||
|
||||
0000101a <bar>:
|
||||
101a: 00 00 nop
|
||||
101c: 00 00 nop
|
||||
101e: 00 00 nop
|
||||
1020: 00 00 nop
|
||||
1022: 00 00 nop
|
||||
|
||||
00001024 <junk2>:
|
||||
1024: 00 00 nop
|
||||
1026: 00 00 nop
|
||||
1028: 00 00 nop
|
||||
102a: 00 00 nop
|
||||
102c: 00 00 nop
|
||||
|
||||
0000102e <main>:
|
||||
102e: 00 00 nop
|
||||
1030: 00 00 nop
|
||||
1032: c5 3c 10 12 lb \$5,4114\(\$3\)
|
||||
1036: de e9 ff ff bsr 1012 <&:s3:foo:s3:bar>
|
||||
103a: e5 09 ff ec repeat \$5,1012 <&:s3:foo:s3:bar>
|
||||
103e: 00 00 nop
|
||||
1040: 00 00 nop
|
||||
1042: c5 3c ef ee lb \$5,-4114\(\$3\)
|
||||
1046: dd 49 ff df bsr ffffefee <0-:s3:foo>
|
||||
104a: e5 09 ef d2 repeat \$5,ffffefee <0-:s3:foo>
|
||||
104e: 00 00 nop
|
||||
1050: 00 00 nop
|
||||
1052: c5 3c 20 2c lb \$5,8236\(\$3\)
|
||||
1056: de b9 00 0f bsr 202c <\+:s3:foo:s3:bar>
|
||||
105a: e5 09 07 e9 repeat \$5,202c <\+:s3:foo:s3:bar>
|
||||
105e: dc 88 00 80 jmp 8090 <<<:s3:foo:#00000003>
|
||||
1062: d8 18 00 02 jmp 202 <>>:s3:foo:#00000003>
|
||||
1066: df c8 7f ff jmp 7ffff8 <&:-:s3:foo:s3:bar:#007fffff>
|
||||
106a: df 28 7f ff jmp 7fffe4 <&:-:s3:foo:s4:main:#007fffff>
|
||||
106e: df 78 7f ff jmp 7fffee <&:-:S5:.text:s3:foo:#007fffff>
|
||||
1072: dd 98 00 01 jmp 1b2 <&:-:S5:.data:s3:foo:#007fffff>
|
||||
1076: da 98 00 0f jmp f52 <-:s3:foo:\+:s9:.text.end:0-:S5:.text>
|
||||
107a: db f8 00 70 jmp 707e <\*:s3:foo:#00000007>
|
||||
107e: da 58 00 02 jmp 24a <>>:s3:foo:#00000003\+0x48>
|
||||
1082: d8 28 00 00 jmp 4 <__assert_based_size\+0x3>
|
||||
1086: d8 48 00 00 jmp 8 <\^:s3:foo:s3:bar>
|
||||
108a: d8 d8 00 10 jmp 101a <|:s3:foo:s3:bar>
|
||||
108e: d8 98 00 10 jmp 1012 <&:s3:foo:s3:bar>
|
||||
1092: d8 08 00 00 jmp 0 <<<:==:s3:foo:s3:bar:#00000005>
|
||||
1096: d9 08 00 00 jmp 20 <<<:&&:s3:foo:s3:bar:#00000005>
|
||||
109a: d9 08 00 00 jmp 20 <<<:&&:s3:foo:s3:bar:#00000005>
|
||||
109e: d8 08 00 00 jmp 0 <<<:==:s3:foo:s3:bar:#00000005>
|
||||
10a2: d8 08 00 00 jmp 0 <<<:==:s3:foo:s3:bar:#00000005>
|
||||
10a6: d9 08 00 00 jmp 20 <<<:&&:s3:foo:s3:bar:#00000005>
|
||||
10aa: d9 08 00 00 jmp 20 <<<:&&:s3:foo:s3:bar:#00000005>
|
||||
10ae: 00 00 nop
|
||||
10b0: 00 00 nop
|
||||
10b2: 00 00 nop
|
||||
10b4: 00 00 nop
|
||||
10b6: d8 08 00 00 jmp 0 <<<:==:s3:foo:s3:bar:#00000005>
|
||||
10ba: 00 00 nop
|
||||
10bc: 00 00 nop
|
||||
10be: 00 00 nop
|
||||
#pass
|
@ -126,6 +126,10 @@ struct fix
|
||||
const struct cgen_insn *insn;
|
||||
/* Target specific data, usually reloc number. */
|
||||
int opinfo;
|
||||
/* Which ifield this fixup applies to. */
|
||||
struct cgen_maybe_multi_ifield * field;
|
||||
/* is this field is the MSB field in a set? */
|
||||
int msb_field_p;
|
||||
} fx_cgen;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user