Support for Toshiba MeP and for complex relocations.

This commit is contained in:
Dave Brolley 2007-02-05 20:10:25 +00:00
parent bd2f2e55ad
commit 280d71bf40
34 changed files with 11498 additions and 2 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

119
gas/config/tc-mep.h Normal file
View 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
View File

@ -4778,6 +4778,10 @@ _ACEOF
esac
;;
mep)
using_cgen=yes
;;
mips)
echo ${extra_objects} | grep -s "itbl-parse.o"
if test $? -ne 0 ; then

View File

@ -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

View File

@ -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 ;;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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 {

File diff suppressed because it is too large Load Diff

View 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
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

View File

@ -0,0 +1,7 @@
.globl foo
nop
beq $4,$5,foo
nop
nop
foo:
nop

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1306
gas/testsuite/gas/mep/dj1.s Normal file

File diff suppressed because it is too large Load Diff

View 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\)

View 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\)

View File

@ -0,0 +1,5 @@
.text
sb $7,($fp)
sb $5,($9)

View 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

View File

@ -0,0 +1,8 @@
junk1:
nop
nop
nop
nop
nop
.data
foodata: .word 42

View File

@ -0,0 +1,7 @@
junk2:
nop
nop
nop
nop
nop

View 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

View File

@ -0,0 +1,18 @@
.global foo
.global bar
nop
nop
nop
nop
foo:
nop
nop
nop
nop
bar:
nop
nop
nop
nop
nop

View 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

View File

@ -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