From f865a31d1ed571ccb8d17653b150e3a30f22b30d Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Thu, 11 Jun 2009 11:27:58 +0000 Subject: [PATCH] Add PC-relative branch instructions to moxie port. --- bfd/ChangeLog | 10 +++++++ bfd/bfd-in2.h | 4 +++ bfd/elf32-moxie.c | 21 ++++++++++++-- bfd/libbfd.h | 2 ++ bfd/reloc.c | 6 ++++ gas/ChangeLog | 10 +++++++ gas/config/tc-moxie.c | 60 +++++++++++++++++++++++++++++++++++++--- include/elf/ChangeLog | 4 +++ include/elf/moxie.h | 1 + include/opcode/ChangeLog | 5 ++++ include/opcode/moxie.h | 8 ++++-- opcodes/ChangeLog | 7 +++++ opcodes/moxie-dis.c | 9 ++++-- opcodes/moxie-opc.c | 49 ++++++++++++++++++++------------ 14 files changed, 165 insertions(+), 31 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8d590689f4..e5e3d97bc0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2009-06-11 Anthony Green + + * reloc.c: Add BFD_RELOC_MOXIE_10_PCREL. + * bfd-in2.h: Rebuilt. + * libbfd.h: Rebuilt. + * elf32-moxie.c (moxie_elf_howto_table): Add R_MOXIE_PCREL10 + relocation support. + (moxie_reloc_map): Ditto. + Clean up copyright notice. + 2009-06-10 Paul Pluzhnikov * bfd-in2.h: bfd_mmap prototype. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 6583aa61bb..4baa1a4f34 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2737,6 +2737,10 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_MIPS_JUMP_SLOT, +/* Moxie ELF relocations. */ + BFD_RELOC_MOXIE_10_PCREL, + + /* Fujitsu Frv Relocations. */ BFD_RELOC_FRV_LABEL16, BFD_RELOC_FRV_LABEL24, diff --git a/bfd/elf32-moxie.c b/bfd/elf32-moxie.c index e3f01d2e8c..23a16ffe44 100644 --- a/bfd/elf32-moxie.c +++ b/bfd/elf32-moxie.c @@ -1,5 +1,4 @@ /* moxie-specific support for 32-bit ELF. - Copyright 2008 Anthony Green. Copyright 2009 Free Software Foundation, Inc. Copied from elf32-fr30.c which is.. @@ -62,6 +61,21 @@ static reloc_howto_type moxie_elf_howto_table [] = 0x00000000, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* A 10 bit PC-relative relocation. */ + HOWTO (R_MOXIE_PCREL10, /* type. */ + 1, /* rightshift. */ + 1, /* size (0 = byte, 1 = short, 2 = long). */ + 10, /* bitsize. */ + TRUE, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_MOXIE_PCREL10", /* name. */ + FALSE, /* partial_inplace. */ + 0, /* src_mask. */ + 0x000003FF, /* dst_mask. */ + TRUE), /* pcrel_offset. */ }; /* Map BFD reloc types to MOXIE ELF reloc types. */ @@ -74,8 +88,9 @@ struct moxie_reloc_map static const struct moxie_reloc_map moxie_reloc_map [] = { - { BFD_RELOC_NONE, R_MOXIE_NONE }, - { BFD_RELOC_32, R_MOXIE_32 }, + { BFD_RELOC_NONE, R_MOXIE_NONE }, + { BFD_RELOC_32, R_MOXIE_32 }, + { BFD_RELOC_MOXIE_10_PCREL, R_MOXIE_PCREL10 }, }; static reloc_howto_type * diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 7d72e3b9d0..a3bb5809e9 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1033,6 +1033,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MIPS_COPY", "BFD_RELOC_MIPS_JUMP_SLOT", + "BFD_RELOC_MOXIE_10_PCREL", + "BFD_RELOC_FRV_LABEL16", "BFD_RELOC_FRV_LABEL24", "BFD_RELOC_FRV_LO16", diff --git a/bfd/reloc.c b/bfd/reloc.c index ad002d73de..fd82c2db06 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2315,6 +2315,12 @@ ENUMDOC MIPS ELF relocations (VxWorks and PLT extensions). COMMENT +ENUM + BFD_RELOC_MOXIE_10_PCREL +ENUMDOC + Moxie ELF relocations. +COMMENT + ENUM BFD_RELOC_FRV_LABEL16 ENUMX diff --git a/gas/ChangeLog b/gas/ChangeLog index ffae37d549..4aa9d03481 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2009-06-11 Anthony Green + + * config/tc-moxie.c (md_chars_to_number): Define. + (md_begin): Populate opcode hashtable with more form 3 opcodes. + (md_assemble): Assemble MOXIE_F3_PCREL encoded instructions. + (md_apply_fix): Handle BFD_RELOC_MOXIE_10_PCREL relocations. + (tc_gen_reloc): Ditto. + (md_pcrel_from): Ditto. + (md_chars_to_number): New function. + 2009-06-10 Anthony Green * config/tc-moxie.c (md_assemble): Handle MOXIE_F1_M encoded diff --git a/gas/config/tc-moxie.c b/gas/config/tc-moxie.c index b791078af0..281b69ad40 100644 --- a/gas/config/tc-moxie.c +++ b/gas/config/tc-moxie.c @@ -43,6 +43,8 @@ const pseudo_typeS md_pseudo_table[] = const char FLT_CHARS[] = "rRsSfFdDxXpP"; const char EXP_CHARS[] = "eE"; +static int md_chars_to_number (char *val, int n); + void md_operand (expressionS *op __attribute__((unused))) { @@ -67,7 +69,7 @@ md_begin (void) for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++) hash_insert (opcode_hash_control, opcode->name, (char *) opcode); - for (count = 0, opcode = moxie_form3_opc_info; count++ < 4; opcode++) + for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++) hash_insert (opcode_hash_control, opcode->name, (char *) opcode); bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0); @@ -513,6 +515,22 @@ md_assemble (char *str) if (*op_end != 0) as_warn ("extra stuff on line ignored"); break; + case MOXIE_F3_PCREL: + iword = (3<<14) | (opcode->opcode << 10); + while (ISSPACE (*op_end)) + op_end++; + { + expressionS arg; + + op_end = parse_exp_save_ilp (op_end, &arg); + fix_new_exp (frag_now, + (p - frag_now->fr_literal), + 2, + &arg, + TRUE, + BFD_RELOC_MOXIE_10_PCREL); + } + break; default: abort(); } @@ -596,10 +614,12 @@ md_show_usage (FILE *stream ATTRIBUTE_UNUSED) /* Apply a fixup to the object file. */ void -md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED) +md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED, + valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED) { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; long val = *valP; + long newval; long max, min; int shift; @@ -623,6 +643,19 @@ md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED, valueT * valP ATTRIBUTE_UNUSED, segT *buf++ = val; break; + case BFD_RELOC_MOXIE_10_PCREL: + if (!val) + break; + if (val < -1024 || val > 1022) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("pcrel too far BFD_RELOC_MOXIE_10")); + /* 11 bit offset even numbered, so we remove right bit. */ + val >>= 1; + newval = md_chars_to_number (buf, 2); + newval |= val & 0x03ff; + md_number_to_chars (buf, newval, 2); + break; + default: abort (); } @@ -642,6 +675,22 @@ md_number_to_chars (char *ptr, valueT use, int nbytes) number_to_chars_bigendian (ptr, use, nbytes); } +/* Convert from target byte order to host byte order. */ + +static int +md_chars_to_number (char *val, int n) +{ + int retval = 0; + + while (n--) + { + retval <<= 8; + retval |= (*val++ & 255); + } + + return retval; +} + /* Generate a machine-dependent relocation. */ arelent * tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP) @@ -654,6 +703,9 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP) case BFD_RELOC_32: code = fixP->fx_r_type; break; + case BFD_RELOC_MOXIE_10_PCREL: + code = fixP->fx_r_type; + break; default: as_bad_where (fixP->fx_file, fixP->fx_line, _("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant")); @@ -719,12 +771,12 @@ md_pcrel_from (fixS *fixP) { valueT addr = fixP->fx_where + fixP->fx_frag->fr_address; - fprintf (stderr, "md_pcrel_from 0x%d\n", fixP->fx_r_type); - switch (fixP->fx_r_type) { case BFD_RELOC_32: return addr + 4; + case BFD_RELOC_MOXIE_10_PCREL: + return addr; default: abort (); return addr; diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index ff92f5cf95..a8821a2e19 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2009-06-11 Anthony Green + + * moxie.h (R_MOXIE_PCREL10): New. + 2009-06-01 H.J. Lu PR ld/10205 diff --git a/include/elf/moxie.h b/include/elf/moxie.h index 49781a6c1d..62adab8003 100644 --- a/include/elf/moxie.h +++ b/include/elf/moxie.h @@ -26,6 +26,7 @@ START_RELOC_NUMBERS (elf_moxie_reloc_type) RELOC_NUMBER (R_MOXIE_NONE, 0) RELOC_NUMBER (R_MOXIE_32, 1) + RELOC_NUMBER (R_MOXIE_PCREL10, 2) END_RELOC_NUMBERS (R_MOXIE_max) #endif /* _ELF_MOXIE_H */ diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index df8a7e6064..71adbeaecf 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2009-06-11 Anthony Green + + * moxie.h (MOXIE_F3_PCREL): Define. + (moxie_form3_opc_info): Grow. + 2009-06-06 Anthony Green * moxie.h (MOXIE_F1_M): Define. diff --git a/include/opcode/moxie.h b/include/opcode/moxie.h index 0035f5f757..e2bc374f04 100644 --- a/include/opcode/moxie.h +++ b/include/opcode/moxie.h @@ -38,7 +38,8 @@ Form 3 instructions also come in different flavors: - Some have no arguments (MOXIE_F3_NARG). */ + Some have no arguments (MOXIE_F3_NARG) + Some have a 10-bit PC relative operand (MOXIE_F3_PCREL). */ #define MOXIE_F1_NARG 0x100 #define MOXIE_F1_A 0x101 @@ -56,7 +57,8 @@ #define MOXIE_F2_NARG 0x200 #define MOXIE_F2_A8V 0x201 -#define MOXIE_F3_NARG 0x300 +#define MOXIE_F3_NARG 0x300 +#define MOXIE_F3_PCREL 0x301 typedef struct moxie_opc_info_t { @@ -67,4 +69,4 @@ typedef struct moxie_opc_info_t extern const moxie_opc_info_t moxie_form1_opc_info[64]; extern const moxie_opc_info_t moxie_form2_opc_info[4]; -extern const moxie_opc_info_t moxie_form3_opc_info[4]; +extern const moxie_opc_info_t moxie_form3_opc_info[16]; diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 8333e32821..1bb84a9600 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2009-06-11 Anthony Green + + * moxie-opc.c (moxie_form1_opc_info): Remove branch instructions. + (moxie_form3_opc_info): Add branch instructions. + * moxie-dis.c (print_insn_moxie): Disassemble MOXIE_F3_PCREL + encoded instructions. + 2009-06-06 Anthony Green * moxie-opc.c: Recode some MOXIE_F1_4 opcodes as MOXIE_F1_M. diff --git a/opcodes/moxie-dis.c b/opcodes/moxie-dis.c index d63eb2db45..4e67e2c555 100644 --- a/opcodes/moxie-dis.c +++ b/opcodes/moxie-dis.c @@ -33,6 +33,7 @@ static void *stream; /* Macros to extract operands from the instruction word. */ #define OP_A(i) ((i >> 4) & 0xf) #define OP_B(i) (i & 0xf) +#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1) static const char * reg_names[16] = { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", @@ -176,11 +177,13 @@ print_insn_moxie (bfd_vma addr, struct disassemble_info * info) else { /* Extract the Form 3 opcode. */ - opcode = &moxie_form2_opc_info[(iword >> 12) & 3]; + opcode = &moxie_form3_opc_info[(iword >> 10) & 15]; switch (opcode->itype) { - case MOXIE_F3_NARG: - fpr (stream, "%s", opcode->name); + case MOXIE_F3_PCREL: + fpr (stream, "%s\t", opcode->name); + info->print_address_func ((bfd_vma) (addr + INST2OFFSET(iword)), + info); break; default: abort(); diff --git a/opcodes/moxie-opc.c b/opcodes/moxie-opc.c index 7275e3aa79..819476085a 100644 --- a/opcodes/moxie-opc.c +++ b/opcodes/moxie-opc.c @@ -44,11 +44,11 @@ FORM 3 instructions start with a bits "11"... - 11oovvvvvvvvvvvv + 11oooovvvvvvvvvv 0 F - oo - form 3 opcode number - vvvvvvvvvvvv - 12-bit immediate value. */ + oooo - form 3 opcode number + vvvvvvvvvv - 10-bit immediate value. */ const moxie_opc_info_t moxie_form1_opc_info[64] = { @@ -67,16 +67,16 @@ const moxie_opc_info_t moxie_form1_opc_info[64] = { 0x0c, MOXIE_F1_ABi4, "ldo.l" }, { 0x0d, MOXIE_F1_AiB4, "sto.l" }, { 0x0e, MOXIE_F1_AB, "cmp" }, - { 0x0f, MOXIE_F1_M, "beq" }, - { 0x10, MOXIE_F1_M, "bne" }, - { 0x11, MOXIE_F1_M, "blt" }, - { 0x12, MOXIE_F1_M, "bgt" }, - { 0x13, MOXIE_F1_M, "bltu" }, - { 0x14, MOXIE_F1_M, "bgtu" }, - { 0x15, MOXIE_F1_M, "bge" }, - { 0x16, MOXIE_F1_M, "ble" }, - { 0x17, MOXIE_F1_M, "bgeu" }, - { 0x18, MOXIE_F1_M, "bleu" }, + { 0x0f, MOXIE_F1_NARG, "bad" }, + { 0x10, MOXIE_F1_NARG, "bad" }, + { 0x11, MOXIE_F1_NARG, "bad" }, + { 0x12, MOXIE_F1_NARG, "bad" }, + { 0x13, MOXIE_F1_NARG, "bad" }, + { 0x14, MOXIE_F1_NARG, "bad" }, + { 0x15, MOXIE_F1_NARG, "bad" }, + { 0x16, MOXIE_F1_NARG, "bad" }, + { 0x17, MOXIE_F1_NARG, "bad" }, + { 0x18, MOXIE_F1_NARG, "bad" }, { 0x19, MOXIE_F1_A, "jsr" }, { 0x1a, MOXIE_F1_M, "jmpa" }, { 0x1b, MOXIE_F1_A4, "ldi.b" }, @@ -126,11 +126,24 @@ const moxie_opc_info_t moxie_form2_opc_info[4] = { 0x03, MOXIE_F2_A8V, "ssr" } }; -const moxie_opc_info_t moxie_form3_opc_info[4] = +const moxie_opc_info_t moxie_form3_opc_info[16] = { - { 0x00, MOXIE_F2_NARG, "bad" }, - { 0x01, MOXIE_F2_NARG, "bad" }, - { 0x02, MOXIE_F2_NARG, "bad" }, - { 0x03, MOXIE_F2_NARG, "bad" } + { 0x00, MOXIE_F3_PCREL,"beq" }, + { 0x01, MOXIE_F3_PCREL,"bne" }, + { 0x02, MOXIE_F3_PCREL,"blt" }, + { 0x03, MOXIE_F3_PCREL,"bgt" }, + { 0x04, MOXIE_F3_PCREL,"bltu" }, + { 0x05, MOXIE_F3_PCREL,"bgtu" }, + { 0x06, MOXIE_F3_PCREL,"bge" }, + { 0x07, MOXIE_F3_PCREL,"ble" }, + { 0x08, MOXIE_F3_PCREL,"bgeu" }, + { 0x09, MOXIE_F3_PCREL,"bleu" }, + { 0x0a, MOXIE_F3_NARG, "bad" }, + { 0x0b, MOXIE_F3_NARG, "bad" }, + { 0x0c, MOXIE_F3_NARG, "bad" }, + { 0x0d, MOXIE_F3_NARG, "bad" }, + { 0x0e, MOXIE_F3_NARG, "bad" }, + { 0x0f, MOXIE_F3_NARG, "bad" } }; + -- 2.34.1