--- binutils-2.20/bfd/archures.c 2009-09-10 17:17:11.000000000 +0530 +++ binutils-2.20/bfd/archures.c 2010-05-17 19:40:42.071633629 +0530 @@ -307,7 +307,9 @@ DESCRIPTION . bfd_arch_v850, {* NEC V850 *} .#define bfd_mach_v850 1 .#define bfd_mach_v850e 'E' -.#define bfd_mach_v850e1 '1' +.#define bfd_mach_v850e1 '1' +.#define bfd_mach_v850e2 0x4532 {* ('E'<<8|'2') *} +.#define bfd_mach_v850e2v3 0x45325633 {* ('E'<<24|'2'<<16|'V'<<8|'3') *} . bfd_arch_arc, {* ARC Cores *} .#define bfd_mach_arc_5 5 .#define bfd_mach_arc_6 6 --- binutils-2.20/bfd/bfd-in2.h 2009-09-10 17:17:11.000000000 +0530 +++ binutils-2.20/bfd/bfd-in2.h 2010-05-17 19:40:53.550881823 +0530 @@ -1975,6 +1975,8 @@ enum bfd_architecture #define bfd_mach_v850 1 #define bfd_mach_v850e 'E' #define bfd_mach_v850e1 '1' +#define bfd_mach_v850e2 0x4532 /* ('E'<<8|'2') */ +#define bfd_mach_v850e2v3 0x45325633 /* ('E'<<24|'2'<<16|'V'<<8|'3') */ bfd_arch_arc, /* ARC Cores */ #define bfd_mach_arc_5 5 #define bfd_mach_arc_6 6 @@ -3532,12 +3534,40 @@ add3, load, and store instructions. */ /* This is a 9-bit reloc */ BFD_RELOC_V850_9_PCREL, +/* This is a 16-bit reloc */ + BFD_RELOC_V850_16_PCREL, + +/* This is a 17-bit reloc */ + BFD_RELOC_V850_17_PCREL, + /* This is a 22-bit reloc */ BFD_RELOC_V850_22_PCREL, +/* This is a 23-bit reloc */ + BFD_RELOC_V850_23, + +/* This is a 32-bit reloc */ + BFD_RELOC_V850_32_PCREL, + BFD_RELOC_V850_32_ABS, + +/* This is a 16-bit reloc */ + BFD_RELOC_V850_16_SPLIT_OFFSET, + BFD_RELOC_V850_16_S1, + +/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu +instructions. */ + BFD_RELOC_V850_LO16_SPLIT_OFFSET, + +/* Low 16 bits. 16 bit shifted by 1. */ + BFD_RELOC_V850_LO16_S1, + /* This is a 16 bit offset from the short data area pointer. */ BFD_RELOC_V850_SDA_16_16_OFFSET, +/* This is a 16 bit offset from the short data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, + /* This is a 16 bit offset (of which only 15 bits are used) from the short data area pointer. */ BFD_RELOC_V850_SDA_15_16_OFFSET, @@ -3545,6 +3575,10 @@ short data area pointer. */ /* This is a 16 bit offset from the zero data area pointer. */ BFD_RELOC_V850_ZDA_16_16_OFFSET, +/* This is a 16 bit offset from the zero data area pointer, with the +bits placed non-contiguously in the instruction. */ + BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, + /* This is a 16 bit offset (of which only 15 bits are used) from the zero data area pointer. */ BFD_RELOC_V850_ZDA_15_16_OFFSET, @@ -3570,20 +3604,26 @@ data area pointer. */ /* This is a 4 bit offset from the tiny data area pointer. */ BFD_RELOC_V850_TDA_4_4_OFFSET, -/* This is a 16 bit offset from the short data area pointer, with the -bits placed non-contiguously in the instruction. */ - BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, - -/* This is a 16 bit offset from the zero data area pointer, with the -bits placed non-contiguously in the instruction. */ - BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, - /* This is a 6 bit offset from the call table base pointer. */ BFD_RELOC_V850_CALLT_6_7_OFFSET, /* This is a 16 bit offset from the call table base pointer. */ + BFD_RELOC_V850_CALLT_15_16_OFFSET, BFD_RELOC_V850_CALLT_16_16_OFFSET, +/* DSO relocations. */ + BFD_RELOC_V850_32_GOTPCREL, + BFD_RELOC_V850_16_GOT, + BFD_RELOC_V850_32_GOT, + BFD_RELOC_V850_22_PLT_PCREL, + BFD_RELOC_V850_32_PLT_PCREL, + BFD_RELOC_V850_COPY, + BFD_RELOC_V850_GLOB_DAT, + BFD_RELOC_V850_JMP_SLOT, + BFD_RELOC_V850_RELATIVE, + BFD_RELOC_V850_16_GOTOFF, + BFD_RELOC_V850_32_GOTOFF, + /* Used for relaxing indirect function calls. */ BFD_RELOC_V850_LONGCALL, @@ -3593,9 +3633,11 @@ bits placed non-contiguously in the inst /* Used to maintain alignment whilst relaxing. */ BFD_RELOC_V850_ALIGN, -/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu -instructions. */ - BFD_RELOC_V850_LO16_SPLIT_OFFSET, +/* start code. */ + BFD_RELOC_V850_CODE, + +/* start data in text. */ + BFD_RELOC_V850_DATA, /* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the instruction. */ --- binutils-2.20/bfd/config.bfd 2009-08-06 23:08:00.000000000 +0530 +++ binutils-2.20/bfd/config.bfd 2010-05-17 19:40:25.540632469 +0530 @@ -1471,9 +1471,6 @@ case "${targ}" in v850e-*-*) targ_defvec=bfd_elf32_v850_vec ;; - v850ea-*-*) - targ_defvec=bfd_elf32_v850_vec - ;; vax-*-netbsdelf*) targ_defvec=bfd_elf32_vax_vec --- binutils-2.20/bfd/cpu-v850.c 2009-09-02 12:48:36.000000000 +0530 +++ binutils-2.20/bfd/cpu-v850.c 2010-05-17 19:53:51.861633592 +0530 @@ -32,8 +32,10 @@ static const bfd_arch_info_type arch_info_struct[] = { - N (bfd_mach_v850e1, "v850e1", FALSE, & arch_info_struct[1]), - N (bfd_mach_v850e, "v850e", FALSE, NULL) + N (bfd_mach_v850e2v3, "v850e2v3", FALSE, & arch_info_struct[1]), + N (bfd_mach_v850e2, "v850e2", FALSE, & arch_info_struct[2]), + N (bfd_mach_v850e1, "v850e1", FALSE, & arch_info_struct[3]), + N (bfd_mach_v850e, "v850e", FALSE, NULL) }; #undef NEXT --- binutils-2.20/bfd/doc/archures.texi 2009-10-16 17:22:10.000000000 +0530 +++ binutils-2.20/bfd/doc/archures.texi 2010-05-17 19:40:25.541631870 +0530 @@ -273,6 +273,8 @@ enum bfd_architecture #define bfd_mach_v850 1 #define bfd_mach_v850e 'E' #define bfd_mach_v850e1 '1' +#define bfd_mach_v850e2 0x4532 /* ('E'<<8|'2') */ +#define bfd_mach_v850e2v3 0x45325633 /* ('E'<<24|'2'<<16|'V'<<8|'3') */ bfd_arch_arc, /* ARC Cores */ #define bfd_mach_arc_5 5 #define bfd_mach_arc_6 6 --- binutils-2.20/bfd/elf32-v850.c 2009-09-02 12:48:36.000000000 +0530 +++ binutils-2.20/bfd/elf32-v850.c 2010-06-03 19:26:05.209882273 +0530 @@ -31,8 +31,11 @@ #include "elf/v850.h" #include "libiberty.h" -/* Sign-extend a 24-bit number. */ -#define SEXT24(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) +/* Sign-extend a 17-bit number. */ +#define SEXT17(x) ((((x) & 0x1ffff) ^ 0x10000) - 0x10000) + +/* Sign-extend a 22-bit number. */ +#define SEXT22(x) ((((x) & 0x3fffff) ^ 0x200000) - 0x200000) static reloc_howto_type v850_elf_howto_table[]; @@ -91,16 +94,24 @@ v850_elf_check_relocs (bfd *abfd, default: case R_V850_NONE: case R_V850_9_PCREL: + case R_V850_16_PCREL: + case R_V850_17_PCREL: case R_V850_22_PCREL: - case R_V850_HI16_S: + case R_V850_32_PCREL: + case R_V850_32_ABS: case R_V850_HI16: + case R_V850_HI16_S: case R_V850_LO16: + case R_V850_LO16_S1: case R_V850_LO16_SPLIT_OFFSET: - case R_V850_ABS32: - case R_V850_REL32: + case R_V850_32: + case R_V850_23: case R_V850_16: + case R_V850_16_S1: + case R_V850_16_SPLIT_OFFSET: case R_V850_8: case R_V850_CALLT_6_7_OFFSET: + case R_V850_CALLT_15_16_OFFSET: case R_V850_CALLT_16_16_OFFSET: break; @@ -134,11 +145,11 @@ v850_elf_check_relocs (bfd *abfd, common = ".zcommon"; goto small_data_common; - case R_V850_TDA_4_5_OFFSET: case R_V850_TDA_4_4_OFFSET: + case R_V850_TDA_4_5_OFFSET: + case R_V850_TDA_7_7_OFFSET: case R_V850_TDA_6_8_OFFSET: case R_V850_TDA_7_8_OFFSET: - case R_V850_TDA_7_7_OFFSET: case R_V850_TDA_16_16_OFFSET: other = V850_OTHER_TDA; common = ".tcommon"; @@ -506,11 +517,17 @@ v850_elf_perform_relocation (bfd *abfd, default: return bfd_reloc_notsupported; - case R_V850_REL32: - case R_V850_ABS32: + case R_V850_32: bfd_put_32 (abfd, addend, address); return bfd_reloc_ok; + case R_V850_23: + insn = bfd_get_32 (abfd, address); + insn &= ~((0x7f << 4) | (0x7fff80 << (16-7))); + insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7)); + bfd_put_32 (abfd, (bfd_vma) insn, address); + return bfd_reloc_ok; + case R_V850_22_PCREL: if (saddend > 0x1fffff || saddend < -0x200000) return bfd_reloc_overflow; @@ -524,6 +541,30 @@ v850_elf_perform_relocation (bfd *abfd, bfd_put_32 (abfd, (bfd_vma) insn, address); return bfd_reloc_ok; + case R_V850_17_PCREL: + if (saddend > 0xffff || saddend < -0x10000) + return bfd_reloc_overflow; + + if ((addend % 2) != 0) + return bfd_reloc_dangerous; + + insn = bfd_get_32 (abfd, address); + insn &= ~ 0xfffe0010; + insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4)); + break; + + case R_V850_16_PCREL: + if ((saddend < -0xffff) || (saddend > 0)) + return bfd_reloc_overflow; + + if ((addend % 2) != 0) + return bfd_reloc_dangerous; + + insn = bfd_get_16 (abfd, address); + insn &= ~0xfffe; + insn |= (-addend & 0xfffe); + break; + case R_V850_9_PCREL: if (saddend > 0xff || saddend < -0x100) return bfd_reloc_overflow; @@ -584,6 +625,36 @@ v850_elf_perform_relocation (bfd *abfd, insn = addend; break; + case R_V850_CALLT_15_16_OFFSET: + insn = bfd_get_16 (abfd, address); + + addend += insn & 0xfffe;; + + saddend = (bfd_signed_vma) addend; + + if (saddend > 0xffff || saddend < 0) + return bfd_reloc_overflow; + + insn = (0xfffe & addend) + | (insn & ~0xfffe); + break; + + case R_V850_CALLT_6_7_OFFSET: + insn = bfd_get_16 (abfd, address); + addend += ((insn & 0x3f) << 1); + + saddend = (bfd_signed_vma) addend; + + if (saddend > 0x7e || saddend < 0) + return bfd_reloc_overflow; + + if (addend & 1) + return bfd_reloc_dangerous; + + insn &= 0xff80; + insn |= (addend >> 1); + break; + case R_V850_16: case R_V850_SDA_16_16_OFFSET: case R_V850_ZDA_16_16_OFFSET: @@ -598,6 +669,7 @@ v850_elf_perform_relocation (bfd *abfd, insn = addend; break; + case R_V850_16_S1: case R_V850_SDA_15_16_OFFSET: case R_V850_ZDA_15_16_OFFSET: insn = bfd_get_16 (abfd, address); @@ -688,6 +760,18 @@ v850_elf_perform_relocation (bfd *abfd, insn |= addend; break; + case R_V850_LO16_S1: + insn = bfd_get_16 (abfd, address); + result = insn & 0xfffe; + if (! v850_elf_perform_lo16_relocation (abfd, &result, addend)) + return bfd_reloc_overflow; + if (result & 1) + return bfd_reloc_overflow; + insn = (result & 0xfffe) + | (insn & ~0xfffe); + bfd_put_16 (abfd, insn, address); + return bfd_reloc_ok; + case R_V850_LO16_SPLIT_OFFSET: insn = bfd_get_32 (abfd, address); result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5); @@ -699,8 +783,9 @@ v850_elf_perform_relocation (bfd *abfd, bfd_put_32 (abfd, insn, address); return bfd_reloc_ok; - case R_V850_ZDA_16_16_SPLIT_OFFSET: + case R_V850_16_SPLIT_OFFSET: case R_V850_SDA_16_16_SPLIT_OFFSET: + case R_V850_ZDA_16_16_SPLIT_OFFSET: insn = bfd_get_32 (abfd, address); addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5); @@ -716,22 +801,6 @@ v850_elf_perform_relocation (bfd *abfd, bfd_put_32 (abfd, (bfd_vma) insn, address); return bfd_reloc_ok; - case R_V850_CALLT_6_7_OFFSET: - insn = bfd_get_16 (abfd, address); - addend += ((insn & 0x3f) << 1); - - saddend = (bfd_signed_vma) addend; - - if (saddend > 0x7e || saddend < 0) - return bfd_reloc_overflow; - - if (addend & 1) - return bfd_reloc_dangerous; - - insn &= 0xff80; - insn |= (addend >> 1); - break; - case R_V850_GNU_VTINHERIT: case R_V850_GNU_VTENTRY: return bfd_reloc_ok; @@ -820,7 +889,8 @@ v850_elf_ignore_reloc (bfd *abfd ATTRIBU return bfd_reloc_ok; } /* Note: It is REQUIRED that the 'type' value of each entry - in this array match the index of the entry in the array. */ + in this array match the index of the entry in the array. + SeeAlso: RELOC_NUBMER in include/elf/v850.h */ static reloc_howto_type v850_elf_howto_table[] = { /* This reloc does nothing. */ @@ -838,11 +908,56 @@ static reloc_howto_type v850_elf_howto_t 0, /* Dst_mask. */ FALSE), /* PCrel_offset. */ + /* Simple 8bit reloc. */ + HOWTO (R_V850_8, /* Type. */ + 0, /* Rightshift. */ + 0, /* Size (0 = byte, 1 = short, 2 = long). */ + 8, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_V850_8", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xff, /* Src_mask. */ + 0xff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Simple 16bit reloc. */ + HOWTO (R_V850_16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_V850_16", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Simple 32bit reloc. */ + HOWTO (R_V850_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_32", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* A PC relative 9 bit branch. */ HOWTO (R_V850_9_PCREL, /* Type. */ - 2, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ - 26, /* Bitsize. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 9, /* Bitsize. */ TRUE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_bitfield, /* Complain_on_overflow. */ @@ -853,13 +968,43 @@ static reloc_howto_type v850_elf_howto_t 0x00ffffff, /* Dst_mask. */ TRUE), /* PCrel_offset. */ + /* A unsigned PC relative 16 bit loop. */ + HOWTO (R_V850_16_PCREL, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_16_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe, /* Src_mask. */ + 0xfffe, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A PC relative 17 bit branch. */ + HOWTO (R_V850_17_PCREL, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 17, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_17_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x0010fffe, /* Src_mask. */ + 0x0010fffe, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + /* A PC relative 22 bit branch. */ HOWTO (R_V850_22_PCREL, /* Type. */ - 2, /* Rightshift. */ + 0, /* Rightshift. */ 2, /* Size (0 = byte, 1 = short, 2 = long). */ 22, /* Bitsize. */ TRUE, /* PC_relative. */ - 7, /* Bitpos. */ + 0, /* Bitpos. */ complain_overflow_signed, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ "R_V850_22_PCREL", /* Name. */ @@ -868,8 +1013,39 @@ static reloc_howto_type v850_elf_howto_t 0x07ffff80, /* Dst_mask. */ TRUE), /* PCrel_offset. */ + /* A PC relative 32 bit branch. */ + HOWTO (R_V850_32_PCREL, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_32_PCREL", /* name */ + FALSE, /* partial_inplace */ + 0xfffffffe, /* src_mask */ + 0xfffffffe, /* dst_mask */ + TRUE), /* pcrel_offset */ + + + /* A absolute 32 bit branch. */ + HOWTO (R_V850_32_ABS, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_32_ABS", /* name */ + FALSE, /* partial_inplace */ + 0xfffffffe, /* src_mask */ + 0xfffffffe, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* High 16 bits of symbol value. */ - HOWTO (R_V850_HI16_S, /* Type. */ + HOWTO (R_V850_HI16, /* Type. */ 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ @@ -877,14 +1053,14 @@ static reloc_howto_type v850_elf_howto_t 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_HI16_S", /* Name. */ + "R_V850_HI16", /* Name. */ FALSE, /* Partial_inplace. */ 0xffff, /* Src_mask. */ 0xffff, /* Dst_mask. */ FALSE), /* PCrel_offset. */ /* High 16 bits of symbol value. */ - HOWTO (R_V850_HI16, /* Type. */ + HOWTO (R_V850_HI16_S, /* Type. */ 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ @@ -892,7 +1068,7 @@ static reloc_howto_type v850_elf_howto_t 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_HI16", /* Name. */ + "R_V850_HI16_S", /* Name. */ FALSE, /* Partial_inplace. */ 0xffff, /* Src_mask. */ 0xffff, /* Dst_mask. */ @@ -913,68 +1089,129 @@ static reloc_howto_type v850_elf_howto_t 0xffff, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* Simple 32bit reloc. */ - HOWTO (R_V850_ABS32, /* Type. */ - 0, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ - 32, /* Bitsize. */ + /* Low 16 bits of symbol value. */ + HOWTO (R_V850_LO16_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_LO16_S1", /* name */ + FALSE, /* partial_inplace */ + 0xfffe, /* src_mask */ + 0xfffe, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* An ld.bu version of R_V850_LO16. */ + HOWTO (R_V850_LO16_SPLIT_OFFSET, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_LO16_SPLIT_OFFSET", /* name */ + FALSE, /* partial_inplace */ + 0xfffe0020, /* src_mask */ + 0xfffe0020, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_V850_16_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_16_S1", /* name */ + FALSE, /* partial_inplace */ + 0xfffe, /* src_mask */ + 0xfffe, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* An ld.bu version of R_V850_LO16. */ + HOWTO (R_V850_16_SPLIT_OFFSET, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_16_SPLIT_OFFSET", /* name */ + FALSE, /* partial_inplace */ + 0xfffe0020, /* src_mask */ + 0xfffe0020, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A 23bit offset ld/st. */ + HOWTO (R_V850_23, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 23, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_23", /* name */ + FALSE, /* partial_inplace */ + 0xffff07f0, /* src_mask */ + 0xffff07f0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + + /* 15 bit offset from the short data area pointer. */ + HOWTO (R_V850_SDA_15_16_OFFSET, /* Type. */ + 1, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ FALSE, /* PC_relative. */ - 0, /* Bitpos. */ + 1, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_ABS32", /* Name. */ + "R_V850_SDA_15_16_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0xffffffff, /* Src_mask. */ - 0xffffffff, /* Dst_mask. */ + 0xfffe, /* Src_mask. */ + 0xfffe, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* Simple 16bit reloc. */ - HOWTO (R_V850_16, /* Type. */ + /* 16 bit offset from the short data area pointer. */ + HOWTO (R_V850_SDA_16_16_OFFSET, /* Type. */ 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ FALSE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ - bfd_elf_generic_reloc, /* Special_function. */ - "R_V850_16", /* Name. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_SDA_16_16_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ 0xffff, /* Src_mask. */ 0xffff, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* Simple 8bit reloc. */ - HOWTO (R_V850_8, /* Type. */ - 0, /* Rightshift. */ - 0, /* Size (0 = byte, 1 = short, 2 = long). */ - 8, /* Bitsize. */ - FALSE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_dont, /* Complain_on_overflow. */ - bfd_elf_generic_reloc, /* Special_function. */ - "R_V850_8", /* Name. */ - FALSE, /* Partial_inplace. */ - 0xff, /* Src_mask. */ - 0xff, /* Dst_mask. */ - FALSE), /* PCrel_offset. */ - /* 16 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_16_16_OFFSET, /* Type. */ + HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type. */ 0, /* Rightshift. */ - 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ FALSE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_SDA_16_16_OFFSET", /* Name. */ + "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name. */ FALSE, /* Partial_inplace. */ - 0xffff, /* Src_mask. */ - 0xffff, /* Dst_mask. */ + 0xfffe0020, /* Src_mask. */ + 0xfffe0020, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 15 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_15_16_OFFSET, /* Type. */ + /* 15 bit offset from the zero data area pointer. */ + HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type. */ 1, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ @@ -982,7 +1219,7 @@ static reloc_howto_type v850_elf_howto_t 1, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_SDA_15_16_OFFSET", /* Name. */ + "R_V850_ZDA_15_16_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ 0xfffe, /* Src_mask. */ 0xfffe, /* Dst_mask. */ @@ -1003,49 +1240,49 @@ static reloc_howto_type v850_elf_howto_t 0xffff, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 15 bit offset from the zero data area pointer. */ - HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type. */ - 1, /* Rightshift. */ - 1, /* Size (0 = byte, 1 = short, 2 = long). */ + /* 16 bit offset from the zero data area pointer. */ + HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ FALSE, /* PC_relative. */ - 1, /* Bitpos. */ + 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_ZDA_15_16_OFFSET", /* Name. */ + "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name. */ FALSE, /* Partial_inplace. */ - 0xfffe, /* Src_mask. */ - 0xfffe, /* Dst_mask. */ + 0xfffe0020, /* Src_mask. */ + 0xfffe0020, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 6 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_6_8_OFFSET, /* Type. */ - 2, /* Rightshift. */ + /* 4 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_4_4_OFFSET, /* Type. */ + 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 8, /* Bitsize. */ + 4, /* Bitsize. */ FALSE, /* PC_relative. */ - 1, /* Bitpos. */ + 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_TDA_6_8_OFFSET", /* Name. */ + "R_V850_TDA_4_4_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0x7e, /* Src_mask. */ - 0x7e, /* Dst_mask. */ + 0x0f, /* Src_mask. */ + 0x0f, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 8 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_7_8_OFFSET, /* Type. */ + /* 5 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_4_5_OFFSET, /* Type. */ 1, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 8, /* Bitsize. */ + 5, /* Bitsize. */ FALSE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_TDA_7_8_OFFSET", /* Name. */ + "R_V850_TDA_4_5_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0x7f, /* Src_mask. */ - 0x7f, /* Dst_mask. */ + 0x0f, /* Src_mask. */ + 0x0f, /* Dst_mask. */ FALSE), /* PCrel_offset. */ /* 7 bit offset from the tiny data area pointer. */ @@ -1063,79 +1300,49 @@ static reloc_howto_type v850_elf_howto_t 0x7f, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 16 bit offset from the tiny data area pointer! */ - HOWTO (R_V850_TDA_16_16_OFFSET, /* Type. */ - 0, /* Rightshift. */ - 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 16, /* Bitsize. */ - FALSE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_dont, /* Complain_on_overflow. */ - v850_elf_reloc, /* Special_function. */ - "R_V850_TDA_16_16_OFFSET", /* Name. */ - FALSE, /* Partial_inplace. */ - 0xffff, /* Src_mask. */ - 0xfff, /* Dst_mask. */ - FALSE), /* PCrel_offset. */ - - /* 5 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_4_5_OFFSET, /* Type. */ + /* 8 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_7_8_OFFSET, /* Type. */ 1, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 5, /* Bitsize. */ + 8, /* Bitsize. */ FALSE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_TDA_4_5_OFFSET", /* Name. */ + "R_V850_TDA_7_8_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0x0f, /* Src_mask. */ - 0x0f, /* Dst_mask. */ + 0x7f, /* Src_mask. */ + 0x7f, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 4 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_4_4_OFFSET, /* Type. */ - 0, /* Rightshift. */ + /* 6 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_6_8_OFFSET, /* Type. */ + 2, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 4, /* Bitsize. */ - FALSE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_dont, /* Complain_on_overflow. */ - v850_elf_reloc, /* Special_function. */ - "R_V850_TDA_4_4_OFFSET", /* Name. */ - FALSE, /* Partial_inplace. */ - 0x0f, /* Src_mask. */ - 0x0f, /* Dst_mask. */ - FALSE), /* PCrel_offset. */ - - /* 16 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type. */ - 0, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ - 16, /* Bitsize. */ + 8, /* Bitsize. */ FALSE, /* PC_relative. */ - 0, /* Bitpos. */ + 1, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name. */ + "R_V850_TDA_6_8_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0xfffe0020, /* Src_mask. */ - 0xfffe0020, /* Dst_mask. */ + 0x7e, /* Src_mask. */ + 0x7e, /* Dst_mask. */ FALSE), /* PCrel_offset. */ - /* 16 bit offset from the zero data area pointer. */ - HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type. */ + /* 16 bit offset from the tiny data area pointer! */ + HOWTO (R_V850_TDA_16_16_OFFSET, /* Type. */ 0, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ 16, /* Bitsize. */ FALSE, /* PC_relative. */ 0, /* Bitpos. */ complain_overflow_dont, /* Complain_on_overflow. */ v850_elf_reloc, /* Special_function. */ - "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name. */ + "R_V850_TDA_16_16_OFFSET", /* Name. */ FALSE, /* Partial_inplace. */ - 0xfffe0020, /* Src_mask. */ - 0xfffe0020, /* Dst_mask. */ + 0xffff, /* Src_mask. */ + 0xfff, /* Dst_mask. */ FALSE), /* PCrel_offset. */ /* 6 bit offset from the call table base pointer. */ @@ -1154,6 +1361,21 @@ static reloc_howto_type v850_elf_howto_t FALSE), /* PCrel_offset. */ /* 16 bit offset from the call table base pointer. */ + HOWTO (R_V850_CALLT_15_16_OFFSET, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_CALLT_15_16_OFFSET", /* name */ + FALSE, /* partial_inplace */ + 0xfffe, /* src_mask */ + 0xfffe, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 16 bit offset from the call table base pointer. */ HOWTO (R_V850_CALLT_16_16_OFFSET, /* Type. */ 0, /* Rightshift. */ 1, /* Size (0 = byte, 1 = short, 2 = long). */ @@ -1198,6 +1420,36 @@ static reloc_howto_type v850_elf_howto_t 0, /* Dst_mask. */ FALSE), /* PCrel_offset. */ + HOWTO (R_V850_ALIGN, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_unsigned, /* Complain_on_overflow. */ + v850_elf_ignore_reloc, /* Special_function. */ + "R_V850_ALIGN", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall + pseudo-op when it finds a function call which can be relaxed. */ + HOWTO (R_V850_LONGCALL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + v850_elf_ignore_reloc, /* special_function */ + "R_V850_LONGCALL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + TRUE), /* pcrel_offset */ + /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall pseudo-op when it finds a function call which can be relaxed. */ HOWTO (R_V850_LONGCALL, /* Type. */ @@ -1230,49 +1482,222 @@ static reloc_howto_type v850_elf_howto_t 0, /* Dst_mask. */ TRUE), /* PCrel_offset. */ - HOWTO (R_V850_ALIGN, /* Type. */ - 0, /* Rightshift. */ - 1, /* Size (0 = byte, 1 = short, 2 = long). */ - 0, /* Bitsize. */ - FALSE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_unsigned, /* Complain_on_overflow. */ - v850_elf_ignore_reloc, /* Special_function. */ - "R_V850_ALIGN", /* Name. */ - FALSE, /* Partial_inplace. */ - 0, /* Src_mask. */ - 0, /* Dst_mask. */ - TRUE), /* PCrel_offset. */ - - /* Simple pc-relative 32bit reloc. */ - HOWTO (R_V850_REL32, /* Type. */ - 0, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ - 32, /* Bitsize. */ - TRUE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_dont, /* Complain_on_overflow. */ - v850_elf_reloc, /* Special_function. */ - "R_V850_REL32", /* Name. */ - FALSE, /* Partial_inplace. */ - 0xffffffff, /* Src_mask. */ - 0xffffffff, /* Dst_mask. */ - FALSE), /* PCrel_offset. */ + /* Indicates a .longjump pseudo-op. The compiler will generate a + .longjump pseudo-op when it finds a branch which can be relaxed. */ + HOWTO (R_V850_LONGJUMP, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + v850_elf_ignore_reloc, /* special_function */ + "R_V850_LONGJUMP", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_V850_CODE, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + v850_elf_ignore_reloc, /* special_function */ + "R_V850_CODE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_V850_DATA, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + v850_elf_ignore_reloc, /* special_function */ + "R_V850_DATA", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + TRUE), /* pcrel_offset */ + + + /* Like R_V850_32 PCREL, but referring to the GOT table entry for + the symbol. */ + HOWTO (R_V850_32_GOTPCREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + v850_elf_reloc, /* special_function */ + "R_V850_32_GOTPCREL", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* Like R_V850_SDA_, but referring to the GOT table entry for + the symbol. */ + HOWTO (R_V850_16_GOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_16_GOT", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_V850_32_GOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_32_GOT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Like R_V850_22_PCREL, but referring to the procedure linkage table + entry for the symbol. */ + HOWTO (R_V850_22_PLT, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 22, /* bitsize */ + TRUE, /* pc_relative */ + 7, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_22_PLT", /* name */ + FALSE, /* partial_inplace */ + 0x07ffff80, /* src_mask */ + 0x07ffff80, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_V850_32_PLT, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 1, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_32_PLT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* This is used only by the dynamic linker. The symbol should exist + both in the object being run and in some shared library. The + dynamic linker copies the data addressed by the symbol from the + shared library into the object, because the object being + run has to have the data at some particular address. */ + HOWTO (R_V850_COPY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_COPY", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Like R_M32R_24, but used when setting global offset table + entries. */ + HOWTO (R_V850_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Marks a procedure linkage table entry for a symbol. */ + HOWTO (R_V850_JMP_SLOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_JMP_SLOT", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Used only by the dynamic linker. When the object is run, this + longword is set to the load address of the object, plus the + addend. */ + HOWTO (R_V850_RELATIVE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_RELATIVE", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_V850_16_GOTOFF, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_16_GOTOFF", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + HOWTO (R_V850_32_GOTOFF, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_V850_32_GOTOFF", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ - /* An ld.bu version of R_V850_LO16. */ - HOWTO (R_V850_LO16_SPLIT_OFFSET, /* Type. */ - 0, /* Rightshift. */ - 2, /* Size (0 = byte, 1 = short, 2 = long). */ - 16, /* Bitsize. */ - FALSE, /* PC_relative. */ - 0, /* Bitpos. */ - complain_overflow_dont, /* Complain_on_overflow. */ - v850_elf_reloc, /* Special_function. */ - "R_V850_LO16_SPLIT_OFFSET", /* Name. */ - FALSE, /* Partial_inplace. */ - 0xfffe0020, /* Src_mask. */ - 0xfffe0020, /* Dst_mask. */ - FALSE), /* PCrel_offset. */ }; /* Map BFD reloc types to V850 ELF reloc types. */ @@ -1287,37 +1712,67 @@ struct v850_elf_reloc_map static const struct v850_elf_reloc_map v850_elf_reloc_map[] = { - { BFD_RELOC_NONE, R_V850_NONE }, - { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL }, - { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL }, - { BFD_RELOC_HI16_S, R_V850_HI16_S }, - { BFD_RELOC_HI16, R_V850_HI16 }, - { BFD_RELOC_LO16, R_V850_LO16 }, - { BFD_RELOC_32, R_V850_ABS32 }, - { BFD_RELOC_32_PCREL, R_V850_REL32 }, - { BFD_RELOC_16, R_V850_16 }, - { BFD_RELOC_8, R_V850_8 }, - { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET }, - { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET }, - { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET }, - { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET }, - { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET }, - { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET }, - { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET }, - { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET }, - { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET }, - { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET }, - { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET }, + { BFD_RELOC_NONE, R_V850_NONE }, + { BFD_RELOC_8, R_V850_8 }, + { BFD_RELOC_16, R_V850_16 }, + { BFD_RELOC_32, R_V850_32 }, + + { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL }, + { BFD_RELOC_V850_16_PCREL, R_V850_16_PCREL }, + { BFD_RELOC_V850_17_PCREL, R_V850_17_PCREL }, + { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL }, + { BFD_RELOC_V850_32_PCREL, R_V850_32_PCREL }, + { BFD_RELOC_V850_32_ABS, R_V850_32_ABS }, + + { BFD_RELOC_HI16, R_V850_HI16 }, + { BFD_RELOC_HI16_S, R_V850_HI16_S }, + { BFD_RELOC_LO16, R_V850_LO16 }, + { BFD_RELOC_V850_LO16_S1, R_V850_LO16_S1 }, + { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET }, + + { BFD_RELOC_V850_16_S1, R_V850_16_S1 }, + { BFD_RELOC_V850_16_SPLIT_OFFSET, R_V850_16_SPLIT_OFFSET }, + { BFD_RELOC_V850_23, R_V850_23 }, + + { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET }, + { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET }, { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET }, + + { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET }, + { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET }, { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET }, - { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET }, - { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET }, - { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY }, - { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL }, - { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP }, - { BFD_RELOC_V850_ALIGN, R_V850_ALIGN }, + { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET }, + { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET }, + { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET }, + { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET }, + { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET }, + { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET }, + + { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET }, + { BFD_RELOC_V850_CALLT_15_16_OFFSET, R_V850_CALLT_15_16_OFFSET }, + { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET }, + + { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY }, + { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT }, + + { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL }, + { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP }, + { BFD_RELOC_V850_ALIGN, R_V850_ALIGN }, + { BFD_RELOC_V850_CODE, R_V850_CODE }, + { BFD_RELOC_V850_DATA, R_V850_DATA }, + + { BFD_RELOC_V850_32_GOTPCREL, R_V850_32_GOTPCREL }, + { BFD_RELOC_V850_16_GOT, R_V850_16_GOT }, + { BFD_RELOC_V850_32_GOT, R_V850_32_GOT }, + { BFD_RELOC_V850_22_PLT_PCREL, R_V850_22_PLT }, + { BFD_RELOC_V850_32_PLT_PCREL, R_V850_32_PLT }, + { BFD_RELOC_V850_COPY, R_V850_COPY }, + { BFD_RELOC_V850_GLOB_DAT, R_V850_GLOB_DAT }, + { BFD_RELOC_V850_JMP_SLOT, R_V850_JMP_SLOT }, + { BFD_RELOC_V850_RELATIVE, R_V850_RELATIVE }, + { BFD_RELOC_V850_16_GOTOFF, R_V850_16_GOTOFF }, + { BFD_RELOC_V850_32_GOTOFF, R_V850_32_GOTOFF }, }; /* Map a bfd relocation into the appropriate howto structure. */ @@ -1424,31 +1879,57 @@ v850_elf_final_link_relocate (reloc_howt value -= offset; break; + case R_V850_16_PCREL: + value -= (input_section->output_section->vma + + input_section->output_offset + + offset); + + /* If the sign extension will corrupt the value then we have overflowed. */ + if ((value & 0xffff0000) != 0xffff0000) + return bfd_reloc_overflow; + + break; + + case R_V850_17_PCREL: + value -= (input_section->output_section->vma + + input_section->output_offset + + offset); + + /* If the sign extension will corrupt the value then we have overflowed. */ + if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000)) + return bfd_reloc_overflow; + + value = SEXT17 (value); + break; + case R_V850_22_PCREL: value -= (input_section->output_section->vma + input_section->output_offset + offset); /* If the sign extension will corrupt the value then we have overflowed. */ - if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000)) + if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000)) return bfd_reloc_overflow; - /* Only the bottom 24 bits of the PC are valid. */ - value = SEXT24 (value); + /* Only the bottom 22 bits of the PC are valid. */ + value = SEXT22 (value); break; - case R_V850_REL32: + case R_V850_32_PCREL: value -= (input_section->output_section->vma + input_section->output_offset + offset); break; + case R_V850_32_ABS: + case R_V850_32: + case R_V850_23: case R_V850_HI16_S: case R_V850_HI16: case R_V850_LO16: + case R_V850_LO16_S1: case R_V850_LO16_SPLIT_OFFSET: case R_V850_16: - case R_V850_ABS32: case R_V850_8: break; @@ -1488,10 +1969,10 @@ v850_elf_final_link_relocate (reloc_howt case R_V850_TDA_4_4_OFFSET: case R_V850_TDA_4_5_OFFSET: - case R_V850_TDA_16_16_OFFSET: case R_V850_TDA_7_7_OFFSET: case R_V850_TDA_7_8_OFFSET: case R_V850_TDA_6_8_OFFSET: + case R_V850_TDA_16_16_OFFSET: { unsigned long ep; struct bfd_link_hash_entry * h; @@ -1528,6 +2009,7 @@ v850_elf_final_link_relocate (reloc_howt } break; + case R_V850_CALLT_15_16_OFFSET: case R_V850_CALLT_16_16_OFFSET: { unsigned long ctbp; @@ -1773,6 +2255,12 @@ v850_elf_object_p (bfd *abfd) case E_V850E1_ARCH: bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e1); break; + case E_V850E2_ARCH: + bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e2); + break; + case E_V850E2V3_ARCH: + bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e2v3); + break; } return TRUE; } @@ -1788,9 +2276,11 @@ v850_elf_final_write_processing (bfd *ab switch (bfd_get_mach (abfd)) { default: - case bfd_mach_v850: val = E_V850_ARCH; break; - case bfd_mach_v850e: val = E_V850E_ARCH; break; - case bfd_mach_v850e1: val = E_V850E1_ARCH; break; + case bfd_mach_v850: val = E_V850_ARCH; break; + case bfd_mach_v850e: val = E_V850E_ARCH; break; + case bfd_mach_v850e1: val = E_V850E1_ARCH; break; + case bfd_mach_v850e2: val = E_V850E2_ARCH; break; + case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break; } elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH; @@ -1854,20 +2344,40 @@ v850_elf_merge_private_bfd_data (bfd *ib if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH) && (in_flags & EF_V850_ARCH) != E_V850_ARCH) { + /* Allow v850e1 binaries to be linked with v850e binaries. Set the output binary to v850e. */ if ((in_flags & EF_V850_ARCH) == E_V850E1_ARCH - && (out_flags & EF_V850_ARCH) == E_V850E_ARCH) - return TRUE; + && (out_flags & EF_V850_ARCH) == E_V850E_ARCH) + return TRUE; - if ((in_flags & EF_V850_ARCH) == E_V850E_ARCH - && (out_flags & EF_V850_ARCH) == E_V850E1_ARCH) + if ((in_flags & EF_V850_ARCH) == E_V850_ARCH + && (out_flags & EF_V850_ARCH) == E_V850E_ARCH) { elf_elfheader (obfd)->e_flags = ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH); return TRUE; } + if (((in_flags & EF_V850_ARCH) == E_V850_ARCH + || (in_flags & EF_V850_ARCH) == E_V850E_ARCH) + && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH) + { + elf_elfheader (obfd)->e_flags = + ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH); + return TRUE; + } + + if (((in_flags & EF_V850_ARCH) == E_V850_ARCH + || (in_flags & EF_V850_ARCH) == E_V850E_ARCH + || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH) + && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH) + { + elf_elfheader (obfd)->e_flags = + ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH); + return TRUE; + } + _bfd_error_handler (_("%B: Architecture mismatch with previous modules"), ibfd); } @@ -1895,6 +2405,8 @@ v850_elf_print_private_bfd_data (bfd *ab case E_V850_ARCH: fprintf (file, _("v850 architecture")); break; case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break; case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break; + case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break; + case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break; } fputc ('\n', file); --- binutils-2.20/bfd/libbfd.h 2009-09-02 13:40:55.000000000 +0530 +++ binutils-2.20/bfd/libbfd.h 2010-05-17 19:40:25.545632554 +0530 @@ -1537,6 +1537,8 @@ static const char *const bfd_reloc_code_ "BFD_RELOC_M32R_GOTPC_HI_SLO", "BFD_RELOC_M32R_GOTPC_LO", "BFD_RELOC_V850_9_PCREL", + "BFD_RELOC_V850_16_PCREL", + "BFD_RELOC_V850_17_PCREL", "BFD_RELOC_V850_22_PCREL", "BFD_RELOC_V850_SDA_16_16_OFFSET", "BFD_RELOC_V850_SDA_15_16_OFFSET", --- binutils-2.20/bfd/reloc.c 2009-09-10 17:17:13.000000000 +0530 +++ binutils-2.20/bfd/reloc.c 2010-05-17 19:40:25.547631955 +0530 @@ -3618,6 +3618,14 @@ ENUM ENUMDOC This is a 9-bit reloc ENUM + BFD_RELOC_V850_16_PCREL +ENUMDOC + This is a 16-bit reloc +ENUM + BFD_RELOC_V850_17_PCREL +ENUMDOC + This is a 17-bit reloc +ENUM BFD_RELOC_V850_22_PCREL ENUMDOC This is a 22-bit reloc --- binutils-2.20/binutils/readelf.c 2009-09-22 21:10:59.000000000 +0530 +++ binutils-2.20/binutils/readelf.c 2010-06-03 19:27:21.626632439 +0530 @@ -2211,8 +2211,14 @@ get_machine_flags (unsigned e_flags, uns case EM_CYGNUS_V850: switch (e_flags & EF_V850_ARCH) { - case E_V850E1_ARCH: - strcat (buf, ", v850e1"); + case E_V850E2V3_ARCH: + strcat (buf, ", v850e2v3"); + break; + case E_V850E2_ARCH: + strcat (buf, ", v850e2"); + break; + case E_V850E1_ARCH: + strcat (buf, ", v850e1"); break; case E_V850E_ARCH: strcat (buf, ", v850e"); --- binutils-2.20/configure 2009-09-02 12:35:02.000000000 +0530 +++ binutils-2.20/configure 2010-05-17 19:40:25.556631883 +0530 @@ -3435,13 +3435,10 @@ case "${target}" in noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}" ;; v850-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + noconfigdirs="$noconfigdirs ${libgcj}" ;; v850e-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" - ;; - v850ea-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + noconfigdirs="$noconfigdirs ${libgcj}" ;; vax-*-vms) noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss ${libgcj}" --- binutils-2.20/configure.ac 2009-10-16 17:22:23.000000000 +0530 +++ binutils-2.20/configure.ac 2010-05-17 20:16:06.182633512 +0530 @@ -922,13 +922,10 @@ case "${target}" in noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}" ;; v850-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + noconfigdirs="$noconfigdirs ${libgcj}" ;; v850e-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" - ;; - v850ea-*-*) - noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" + noconfigdirs="$noconfigdirs ${libgcj}" ;; vax-*-vms) noconfigdirs="$noconfigdirs bfd binutils gdb ld target-newlib opcodes target-libgloss ${libgcj}" --- binutils-2.20/gas/config/tc-v850.c 2009-07-24 17:15:01.000000000 +0530 +++ binutils-2.20/gas/config/tc-v850.c 2010-06-04 11:19:28.406633794 +0530 @@ -39,13 +39,14 @@ static bfd_boolean warn_unsigned_overflo static int machine = -1; /* Indicates the target processor(s) for the assemble. */ -static int processor_mask = -1; +static int processor_mask = 0; /* Structure to hold information about predefined registers. */ struct reg_name { const char *name; int value; + unsigned int processors; }; /* Generic assembler global variables which must be defined by all @@ -69,17 +70,68 @@ const char EXP_CHARS[] = "eE"; as in 0d1.0. */ const char FLT_CHARS[] = "dD"; -const relax_typeS md_relax_table[] = -{ - /* Conditional branches. */ - {0xff, -0x100, 2, 1}, - {0x1fffff, -0x200000, 6, 0}, - /* Unconditional branches. */ - {0xff, -0x100, 2, 3}, - {0x1fffff, -0x200000, 4, 0}, +const relax_typeS md_relax_table[] = { + /* Conditional branches.(V850/V850E, max 22bit) */ +#define SUBYPTE_COND_9_22 0 + {0xfe, -0x100, 2, SUBYPTE_COND_9_22+1}, + {0x1ffffe + 2, -0x200000 + 2, 6, 0}, + /* Conditional branches.(V850/V850E, max 22bit) */ +#define SUBYPTE_SA_9_22 2 + {0xfe, -0x100, 2, SUBYPTE_SA_9_22+1}, + {0x1ffffe + 4, -0x200000+4, 8, 0}, + /* Unconditional branches.(V850/V850E, max 22bit) */ +#define SUBYPTE_UNCOND_9_22 4 + {0xfe, -0x100, 2, SUBYPTE_UNCOND_9_22+1}, + {0x1ffffe, -0x200000, 4, 0}, + /* Conditional branches.(V850E2, max 32bit) */ +#define SUBYPTE_COND_9_22_32 6 + {0xfe, -0x100, 2, SUBYPTE_COND_9_22_32+1}, + {0x1fffff+2, -0x200000+2, 6, SUBYPTE_COND_9_22_32+2}, + {0x7ffffffe, -0x80000000, 8, 0}, + /* Conditional branches.(V850E2, max 32bit) */ +#define SUBYPTE_SA_9_22_32 9 + {0xfe, -0x100, 2, SUBYPTE_SA_9_22_32+1}, + {0x1ffffe + 4, -0x200000+4, 8, SUBYPTE_SA_9_22_32+2}, + {0x7ffffffe, -0x80000000, 10, 0}, + /* Unconditional branches.(V850E2, max 32bit) */ +#define SUBYPTE_UNCOND_9_22_32 12 + {0xfe, -0x100, 2, SUBYPTE_UNCOND_9_22_32+1}, + {0x1ffffe, -0x200000, 4, SUBYPTE_UNCOND_9_22_32+2}, + {0x7ffffffe, -0x80000000, 6, 0}, + /* Conditional branches.(V850E2V3 max 22bit) */ +#define SUBYPTE_COND_9_17_22 15 + {0xfe, -0x100, 2, SUBYPTE_COND_9_17_22+1}, + {0xfffe, -0x10000, 4, SUBYPTE_COND_9_17_22+2}, + {0x1ffffe + 2, -0x200000+2, 6, 0}, + /* Conditional branches.(V850E2V3 max 22bit) */ +#define SUBYPTE_SA_9_17_22 18 + {0xfe, -0x100, 2, SUBYPTE_SA_9_17_22+1}, + {0xfffe, -0x10000, 4, SUBYPTE_SA_9_17_22+2}, + {0x1ffffe + 4, -0x200000+4, 8, 0}, + /* Conditional branches.(V850E2V3 max 32bit) */ +#define SUBYPTE_COND_9_17_22_32 21 + {0xfe, -0x100, 2, SUBYPTE_COND_9_17_22_32+1}, + {0xfffe, -0x10000, 4, SUBYPTE_COND_9_17_22_32+2}, + {0x1ffffe + 2, -0x200000+2, 6, SUBYPTE_COND_9_17_22_32+3}, + {0x7ffffffe, -0x80000000, 8, 0}, + /* Conditional branches.(V850E2V3 max 32bit) */ +#define SUBYPTE_SA_9_17_22_32 25 + {0xfe, -0x100, 2, SUBYPTE_SA_9_17_22_32+1}, + {0xfffe, -0x10000, 4, SUBYPTE_SA_9_17_22_32+2}, + {0x1ffffe + 4, -0x200000+4, 8, SUBYPTE_SA_9_17_22_32+3}, + {0x7ffffffe, -0x80000000, 10, 0}, }; -static int v850_relax = 0; +static int v850_relax = 0; + +/* defautl branch disp size 22 or 32 */ +static int default_disp_size = 22; + +/* defautl no using bcond17 */ +static int no_bcond17 = 0; + +/* defautl no using ld/st 23bit offset */ +static int no_stld23 = 0; /* Fixups. */ #define MAX_INSN_FIXUPS 5 @@ -463,9 +515,12 @@ set_machine (int number) switch (machine) { - case 0: processor_mask = PROCESSOR_V850; break; - case bfd_mach_v850e: processor_mask = PROCESSOR_V850E; break; - case bfd_mach_v850e1: processor_mask = PROCESSOR_V850E; break; + case 0: SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850); break; + case bfd_mach_v850: SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850); break; + case bfd_mach_v850e: SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E); break; + case bfd_mach_v850e1: SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E); break; + case bfd_mach_v850e2: SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E2); break; + case bfd_mach_v850e2v3:SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E2V3); break; } } @@ -523,7 +578,9 @@ const pseudo_typeS md_pseudo_table[] = { "call_table_data", v850_seg, CALL_TABLE_DATA_SECTION }, { "call_table_text", v850_seg, CALL_TABLE_TEXT_SECTION }, { "v850e", set_machine, bfd_mach_v850e }, - { "v850e1", set_machine, bfd_mach_v850e1 }, + { "v850e1", set_machine, bfd_mach_v850e1 }, + { "v850e2", set_machine, bfd_mach_v850e2 }, + { "v850e2v3", set_machine, bfd_mach_v850e2v3 }, { "longcall", v850_longcode, 1 }, { "longjump", v850_longcode, 2 }, { NULL, NULL, 0 } @@ -535,113 +592,305 @@ static struct hash_control *v850_hash; /* This table is sorted. Suitable for searching by a binary search. */ static const struct reg_name pre_defined_registers[] = { - { "ep", 30 }, /* ep - element ptr. */ - { "gp", 4 }, /* gp - global ptr. */ - { "hp", 2 }, /* hp - handler stack ptr. */ - { "lp", 31 }, /* lp - link ptr. */ - { "r0", 0 }, - { "r1", 1 }, - { "r10", 10 }, - { "r11", 11 }, - { "r12", 12 }, - { "r13", 13 }, - { "r14", 14 }, - { "r15", 15 }, - { "r16", 16 }, - { "r17", 17 }, - { "r18", 18 }, - { "r19", 19 }, - { "r2", 2 }, - { "r20", 20 }, - { "r21", 21 }, - { "r22", 22 }, - { "r23", 23 }, - { "r24", 24 }, - { "r25", 25 }, - { "r26", 26 }, - { "r27", 27 }, - { "r28", 28 }, - { "r29", 29 }, - { "r3", 3 }, - { "r30", 30 }, - { "r31", 31 }, - { "r4", 4 }, - { "r5", 5 }, - { "r6", 6 }, - { "r7", 7 }, - { "r8", 8 }, - { "r9", 9 }, - { "sp", 3 }, /* sp - stack ptr. */ - { "tp", 5 }, /* tp - text ptr. */ - { "zero", 0 }, + { "ep", 30, PROCESSOR_ALL }, /* ep - element ptr */ + { "gp", 4, PROCESSOR_ALL }, /* gp - global ptr */ + { "hp", 2, PROCESSOR_ALL }, /* hp - handler stack ptr */ + { "lp", 31, PROCESSOR_ALL }, /* lp - link ptr */ + { "r0", 0, PROCESSOR_ALL }, + { "r1", 1, PROCESSOR_ALL }, + { "r10", 10, PROCESSOR_ALL }, + { "r11", 11, PROCESSOR_ALL }, + { "r12", 12, PROCESSOR_ALL }, + { "r13", 13, PROCESSOR_ALL }, + { "r14", 14, PROCESSOR_ALL }, + { "r15", 15, PROCESSOR_ALL }, + { "r16", 16, PROCESSOR_ALL }, + { "r17", 17, PROCESSOR_ALL }, + { "r18", 18, PROCESSOR_ALL }, + { "r19", 19, PROCESSOR_ALL }, + { "r2", 2, PROCESSOR_ALL }, + { "r20", 20, PROCESSOR_ALL }, + { "r21", 21, PROCESSOR_ALL }, + { "r22", 22, PROCESSOR_ALL }, + { "r23", 23, PROCESSOR_ALL }, + { "r24", 24, PROCESSOR_ALL }, + { "r25", 25, PROCESSOR_ALL }, + { "r26", 26, PROCESSOR_ALL }, + { "r27", 27, PROCESSOR_ALL }, + { "r28", 28, PROCESSOR_ALL }, + { "r29", 29, PROCESSOR_ALL }, + { "r3", 3, PROCESSOR_ALL }, + { "r30", 30, PROCESSOR_ALL }, + { "r31", 31, PROCESSOR_ALL }, + { "r4", 4, PROCESSOR_ALL }, + { "r5", 5, PROCESSOR_ALL }, + { "r6", 6, PROCESSOR_ALL }, + { "r7", 7, PROCESSOR_ALL }, + { "r8", 8, PROCESSOR_ALL }, + { "r9", 9, PROCESSOR_ALL }, + { "sp", 3, PROCESSOR_ALL }, /* sp - stack ptr */ + { "tp", 5, PROCESSOR_ALL }, /* tp - text ptr */ + { "zero", 0, PROCESSOR_ALL }, }; #define REG_NAME_CNT \ (sizeof (pre_defined_registers) / sizeof (struct reg_name)) -static const struct reg_name system_registers[] = +static const struct reg_name vector_registers[] = { - { "asid", 23 }, - { "bpc", 22 }, - { "bpav", 24 }, - { "bpam", 25 }, - { "bpdv", 26 }, - { "bpdm", 27 }, - { "ctbp", 20 }, - { "ctpc", 16 }, - { "ctpsw", 17 }, - { "dbpc", 18 }, - { "dbpsw", 19 }, - { "dir", 21 }, - { "ecr", 4 }, - { "eipc", 0 }, - { "eipsw", 1 }, - { "fepc", 2 }, - { "fepsw", 3 }, - { "psw", 5 }, + { "vr0", 0, PROCESSOR_V850E2V3 }, + { "vr1", 1, PROCESSOR_V850E2V3 }, + { "vr10", 10, PROCESSOR_V850E2V3 }, + { "vr11", 11, PROCESSOR_V850E2V3 }, + { "vr12", 12, PROCESSOR_V850E2V3 }, + { "vr13", 13, PROCESSOR_V850E2V3 }, + { "vr14", 14, PROCESSOR_V850E2V3 }, + { "vr15", 15, PROCESSOR_V850E2V3 }, + { "vr16", 16, PROCESSOR_V850E2V3 }, + { "vr17", 17, PROCESSOR_V850E2V3 }, + { "vr18", 18, PROCESSOR_V850E2V3 }, + { "vr19", 19, PROCESSOR_V850E2V3 }, + { "vr2", 2, PROCESSOR_V850E2V3 }, + { "vr20", 20, PROCESSOR_V850E2V3 }, + { "vr21", 21, PROCESSOR_V850E2V3 }, + { "vr22", 22, PROCESSOR_V850E2V3 }, + { "vr23", 23, PROCESSOR_V850E2V3 }, + { "vr24", 24, PROCESSOR_V850E2V3 }, + { "vr25", 25, PROCESSOR_V850E2V3 }, + { "vr26", 26, PROCESSOR_V850E2V3 }, + { "vr27", 27, PROCESSOR_V850E2V3 }, + { "vr28", 28, PROCESSOR_V850E2V3 }, + { "vr29", 29, PROCESSOR_V850E2V3 }, + { "vr3", 3, PROCESSOR_V850E2V3 }, + { "vr30", 30, PROCESSOR_V850E2V3 }, + { "vr31", 31, PROCESSOR_V850E2V3 }, + { "vr4", 4, PROCESSOR_V850E2V3 }, + { "vr5", 5, PROCESSOR_V850E2V3 }, + { "vr6", 6, PROCESSOR_V850E2V3 }, + { "vr7", 7, PROCESSOR_V850E2V3 }, + { "vr8", 8, PROCESSOR_V850E2V3 }, + { "vr9", 9, PROCESSOR_V850E2V3 }, }; -#define SYSREG_NAME_CNT \ - (sizeof (system_registers) / sizeof (struct reg_name)) +#define VECTOR_REG_NAME_CNT \ + (sizeof (vector_registers) / sizeof (struct reg_name)) -static const struct reg_name system_list_registers[] = +static const struct reg_name system_registers[] = { - {"PS", 5 }, - {"SR", 0 + 1} + { "asid", 23, PROCESSOR_NOT_V850 }, + { "bpam", 25, PROCESSOR_NOT_V850 }, + { "bpav", 24, PROCESSOR_NOT_V850 }, + { "bpc", 22, PROCESSOR_NOT_V850 }, + { "bpdm", 27, PROCESSOR_NOT_V850 }, + { "bpdv", 26, PROCESSOR_NOT_V850 }, + { "bsel", 31, PROCESSOR_V850E2_ALL }, + { "cfg", 7, PROCESSOR_V850E2V3 }, + { "ctbp", 20, PROCESSOR_NOT_V850 }, + { "ctpc", 16, PROCESSOR_NOT_V850 }, + { "ctpsw", 17, PROCESSOR_NOT_V850 }, + { "dbic", 15, PROCESSOR_V850E2_ALL }, + { "dbpc", 18, PROCESSOR_NOT_V850 }, + { "dbpsw", 19, PROCESSOR_NOT_V850 }, + { "dbwr", 30, PROCESSOR_V850E2_ALL }, + { "dir", 21, PROCESSOR_NOT_V850 }, + { "dpa0l", 16, PROCESSOR_V850E2V3 }, + { "dpa0u", 17, PROCESSOR_V850E2V3 }, + { "dpa1l", 18, PROCESSOR_V850E2V3 }, + { "dpa1u", 19, PROCESSOR_V850E2V3 }, + { "dpa2l", 20, PROCESSOR_V850E2V3 }, + { "dpa2u", 21, PROCESSOR_V850E2V3 }, + { "dpa3l", 22, PROCESSOR_V850E2V3 }, + { "dpa3u", 23, PROCESSOR_V850E2V3 }, + { "dpa4l", 24, PROCESSOR_V850E2V3 }, + { "dpa4u", 25, PROCESSOR_V850E2V3 }, + { "dpa5l", 26, PROCESSOR_V850E2V3 }, + { "dpa5u", 27, PROCESSOR_V850E2V3 }, + { "ecr", 4, PROCESSOR_ALL }, + { "eh_base", 3, PROCESSOR_V850E2V3 }, + { "eh_cfg", 1, PROCESSOR_V850E2V3 }, + { "eh_reset", 2, PROCESSOR_V850E2V3 }, + { "eiic", 13, PROCESSOR_V850E2_ALL }, + { "eipc", 0, PROCESSOR_ALL }, + { "eipsw", 1, PROCESSOR_ALL }, + { "eiwr", 28, PROCESSOR_V850E2_ALL }, + { "feic", 14, PROCESSOR_V850E2_ALL }, + { "fepc", 2, PROCESSOR_ALL }, + { "fepsw", 3, PROCESSOR_ALL }, + { "fewr", 29, PROCESSOR_V850E2_ALL }, + { "fpcc", 9, PROCESSOR_V850E2V3 }, + { "fpcfg", 10, PROCESSOR_V850E2V3 }, + { "fpec", 11, PROCESSOR_V850E2V3 }, + { "fpepc", 7, PROCESSOR_V850E2V3 }, + { "fpspc", 27, PROCESSOR_V850E2V3 }, + { "fpsr", 6, PROCESSOR_V850E2V3 }, + { "fpst", 8, PROCESSOR_V850E2V3 }, + { "ipa0l", 6, PROCESSOR_V850E2V3 }, + { "ipa0u", 7, PROCESSOR_V850E2V3 }, + { "ipa1l", 8, PROCESSOR_V850E2V3 }, + { "ipa1u", 9, PROCESSOR_V850E2V3 }, + { "ipa2l", 10, PROCESSOR_V850E2V3 }, + { "ipa2u", 11, PROCESSOR_V850E2V3 }, + { "ipa3l", 12, PROCESSOR_V850E2V3 }, + { "ipa3u", 13, PROCESSOR_V850E2V3 }, + { "ipa4l", 14, PROCESSOR_V850E2V3 }, + { "ipa4u", 15, PROCESSOR_V850E2V3 }, + { "mca", 24, PROCESSOR_V850E2V3 }, + { "mcc", 26, PROCESSOR_V850E2V3 }, + { "mcr", 27, PROCESSOR_V850E2V3 }, + { "mcs", 25, PROCESSOR_V850E2V3 }, + { "mpc", 1, PROCESSOR_V850E2V3 }, + { "mpm", 0, PROCESSOR_V850E2V3 }, + { "mpu10_dpa0l", 16, PROCESSOR_V850E2V3 }, + { "mpu10_dpa0u", 17, PROCESSOR_V850E2V3 }, + { "mpu10_dpa1l", 18, PROCESSOR_V850E2V3 }, + { "mpu10_dpa1u", 19, PROCESSOR_V850E2V3 }, + { "mpu10_dpa2l", 20, PROCESSOR_V850E2V3 }, + { "mpu10_dpa2u", 21, PROCESSOR_V850E2V3 }, + { "mpu10_dpa3l", 22, PROCESSOR_V850E2V3 }, + { "mpu10_dpa3u", 23, PROCESSOR_V850E2V3 }, + { "mpu10_dpa4l", 24, PROCESSOR_V850E2V3 }, + { "mpu10_dpa4u", 25, PROCESSOR_V850E2V3 }, + { "mpu10_dpa5l", 26, PROCESSOR_V850E2V3 }, + { "mpu10_dpa5u", 27, PROCESSOR_V850E2V3 }, + { "mpu10_ipa0l", 6, PROCESSOR_V850E2V3 }, + { "mpu10_ipa0u", 7, PROCESSOR_V850E2V3 }, + { "mpu10_ipa1l", 8, PROCESSOR_V850E2V3 }, + { "mpu10_ipa1u", 9, PROCESSOR_V850E2V3 }, + { "mpu10_ipa2l", 10, PROCESSOR_V850E2V3 }, + { "mpu10_ipa2u", 11, PROCESSOR_V850E2V3 }, + { "mpu10_ipa3l", 12, PROCESSOR_V850E2V3 }, + { "mpu10_ipa3u", 13, PROCESSOR_V850E2V3 }, + { "mpu10_ipa4l", 14, PROCESSOR_V850E2V3 }, + { "mpu10_ipa4u", 15, PROCESSOR_V850E2V3 }, + { "mpu10_mpc", 1, PROCESSOR_V850E2V3 }, + { "mpu10_mpm", 0, PROCESSOR_V850E2V3 }, + { "mpu10_tid", 2, PROCESSOR_V850E2V3 }, + { "mpu10_vmadr", 5, PROCESSOR_V850E2V3 }, + { "mpu10_vmecr", 3, PROCESSOR_V850E2V3 }, + { "mpu10_vmtid", 4, PROCESSOR_V850E2V3 }, + { "pid", 6, PROCESSOR_V850E2V3 }, + { "pmcr0", 4, PROCESSOR_V850E2V3 }, + { "pmis2", 14, PROCESSOR_V850E2V3 }, + { "psw", 5, PROCESSOR_ALL }, + { "scbp", 12, PROCESSOR_V850E2V3 }, + { "sccfg", 11, PROCESSOR_V850E2V3 }, + { "sr0", 0, PROCESSOR_ALL }, + { "sr1", 1, PROCESSOR_ALL }, + { "sr10", 10, PROCESSOR_ALL }, + { "sr11", 11, PROCESSOR_ALL }, + { "sr12", 12, PROCESSOR_ALL }, + { "sr13", 13, PROCESSOR_ALL }, + { "sr14", 14, PROCESSOR_ALL }, + { "sr15", 15, PROCESSOR_ALL }, + { "sr16", 16, PROCESSOR_ALL }, + { "sr17", 17, PROCESSOR_ALL }, + { "sr18", 18, PROCESSOR_ALL }, + { "sr19", 19, PROCESSOR_ALL }, + { "sr2", 2, PROCESSOR_ALL }, + { "sr20", 20, PROCESSOR_ALL }, + { "sr21", 21, PROCESSOR_ALL }, + { "sr22", 22, PROCESSOR_ALL }, + { "sr23", 23, PROCESSOR_ALL }, + { "sr24", 24, PROCESSOR_ALL }, + { "sr25", 25, PROCESSOR_ALL }, + { "sr26", 26, PROCESSOR_ALL }, + { "sr27", 27, PROCESSOR_ALL }, + { "sr28", 28, PROCESSOR_ALL }, + { "sr29", 29, PROCESSOR_ALL }, + { "sr3", 3, PROCESSOR_ALL }, + { "sr30", 30, PROCESSOR_ALL }, + { "sr31", 31, PROCESSOR_ALL }, + { "sr4", 4, PROCESSOR_ALL }, + { "sr5", 5, PROCESSOR_ALL }, + { "sr6", 6, PROCESSOR_ALL }, + { "sr7", 7, PROCESSOR_ALL }, + { "sr8", 8, PROCESSOR_ALL }, + { "sr9", 9, PROCESSOR_ALL }, + { "sw_base", 3, PROCESSOR_V850E2V3 }, + { "sw_cfg", 1, PROCESSOR_V850E2V3 }, + { "sw_ctl", 0, PROCESSOR_V850E2V3 }, + { "tid", 2, PROCESSOR_V850E2V3 }, + { "vmadr", 6, PROCESSOR_V850E2V3 }, + { "vmecr", 4, PROCESSOR_V850E2V3 }, + { "vmtid", 5, PROCESSOR_V850E2V3 }, + { "vsadr", 2, PROCESSOR_V850E2V3 }, + { "vsecr", 0, PROCESSOR_V850E2V3 }, + { "vstid", 1, PROCESSOR_V850E2V3 }, }; -#define SYSREGLIST_NAME_CNT \ - (sizeof (system_list_registers) / sizeof (struct reg_name)) +#define SYSREG_NAME_CNT \ + (sizeof (system_registers) / sizeof (struct reg_name)) + static const struct reg_name cc_names[] = { - { "c", 0x1 }, - { "e", 0x2 }, - { "ge", 0xe }, - { "gt", 0xf }, - { "h", 0xb }, - { "l", 0x1 }, - { "le", 0x7 }, - { "lt", 0x6 }, - { "n", 0x4 }, - { "nc", 0x9 }, - { "ne", 0xa }, - { "nh", 0x3 }, - { "nl", 0x9 }, - { "ns", 0xc }, - { "nv", 0x8 }, - { "nz", 0xa }, - { "p", 0xc }, - { "s", 0x4 }, - { "sa", 0xd }, - { "t", 0x5 }, - { "v", 0x0 }, - { "z", 0x2 }, + { "c", 0x1, PROCESSOR_ALL }, + { "e", 0x2, PROCESSOR_ALL }, + { "ge", 0xe, PROCESSOR_ALL }, + { "gt", 0xf, PROCESSOR_ALL }, + { "h", 0xb, PROCESSOR_ALL }, + { "l", 0x1, PROCESSOR_ALL }, + { "le", 0x7, PROCESSOR_ALL }, + { "lt", 0x6, PROCESSOR_ALL }, + { "n", 0x4, PROCESSOR_ALL }, + { "nc", 0x9, PROCESSOR_ALL }, + { "ne", 0xa, PROCESSOR_ALL }, + { "nh", 0x3, PROCESSOR_ALL }, + { "nl", 0x9, PROCESSOR_ALL }, + { "ns", 0xc, PROCESSOR_ALL }, + { "nv", 0x8, PROCESSOR_ALL }, + { "nz", 0xa, PROCESSOR_ALL }, + { "p", 0xc, PROCESSOR_ALL }, + { "s", 0x4, PROCESSOR_ALL }, +#define COND_SA_NUM 0xd + { "sa", COND_SA_NUM, PROCESSOR_ALL }, + { "t", 0x5, PROCESSOR_ALL }, + { "v", 0x0, PROCESSOR_ALL }, + { "z", 0x2, PROCESSOR_ALL }, }; #define CC_NAME_CNT \ (sizeof (cc_names) / sizeof (struct reg_name)) +static const struct reg_name float_cc_names[] = +{ + { "eq", 0x2, PROCESSOR_V850E2V3 }, /* true */ + { "f", 0x0, PROCESSOR_V850E2V3 }, /* true */ + { "ge", 0xd, PROCESSOR_V850E2V3 }, /* false */ + { "gl", 0xb, PROCESSOR_V850E2V3 }, /* false */ + { "gle", 0x9, PROCESSOR_V850E2V3 }, /* false */ + { "gt", 0xf, PROCESSOR_V850E2V3 }, /* false */ + { "le", 0xe, PROCESSOR_V850E2V3 }, /* true */ + { "lt", 0xc, PROCESSOR_V850E2V3 }, /* true */ + { "neq", 0x2, PROCESSOR_V850E2V3 }, /* false */ + { "nge", 0xd, PROCESSOR_V850E2V3 }, /* true */ + { "ngl", 0xb, PROCESSOR_V850E2V3 }, /* true */ + { "ngle",0x9, PROCESSOR_V850E2V3 }, /* true */ + { "ngt", 0xf, PROCESSOR_V850E2V3 }, /* true */ + { "nle", 0xe, PROCESSOR_V850E2V3 }, /* false */ + { "nlt", 0xc, PROCESSOR_V850E2V3 }, /* false */ + { "oge", 0x5, PROCESSOR_V850E2V3 }, /* false */ + { "ogl", 0x3, PROCESSOR_V850E2V3 }, /* false */ + { "ogt", 0x7, PROCESSOR_V850E2V3 }, /* false */ + { "ole", 0x6, PROCESSOR_V850E2V3 }, /* true */ + { "olt", 0x4, PROCESSOR_V850E2V3 }, /* true */ + { "or", 0x1, PROCESSOR_V850E2V3 }, /* false */ + { "seq", 0xa, PROCESSOR_V850E2V3 }, /* true */ + { "sf", 0x8, PROCESSOR_V850E2V3 }, /* true */ + { "sne", 0xa, PROCESSOR_V850E2V3 }, /* false */ + { "st", 0x8, PROCESSOR_V850E2V3 }, /* false */ + { "t", 0x0, PROCESSOR_V850E2V3 }, /* false */ + { "ueq", 0x3, PROCESSOR_V850E2V3 }, /* true */ + { "uge", 0x4, PROCESSOR_V850E2V3 }, /* false */ + { "ugt", 0x6, PROCESSOR_V850E2V3 }, /* false */ + { "ule", 0x7, PROCESSOR_V850E2V3 }, /* true */ + { "ult", 0x5, PROCESSOR_V850E2V3 }, /* true */ + { "un", 0x1, PROCESSOR_V850E2V3 }, /* true */ +}; + +#define FLOAT_CC_NAME_CNT \ + (sizeof (float_cc_names) / sizeof (struct reg_name)) + /* Do a binary search of the given register table to see if NAME is a valid regiter name. Return the register number from the array on success, or -1 on failure. */ @@ -667,9 +916,7 @@ reg_name_search (const struct reg_name * else if (accept_numbers) { int reg = S_GET_VALUE (symbolP); - - if (reg >= 0 && reg <= 31) - return reg; + return reg; } /* Otherwise drop through and try parsing name normally. */ @@ -686,8 +933,10 @@ reg_name_search (const struct reg_name * high = middle - 1; else if (cmp > 0) low = middle + 1; - else - return regs[middle].value; + else + return ((regs[middle].processors & processor_mask) + ? regs[middle].value + : -1); } while (low <= high); return -1; @@ -722,25 +971,63 @@ register_name (expressionS *expressionP) /* Put back the delimiting char. */ *input_line_pointer = c; + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + /* Look to see if it's in the register table. */ if (reg_number >= 0) { expressionP->X_op = O_register; expressionP->X_add_number = reg_number; - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - return TRUE; } - else + + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + + expressionP->X_op = O_illegal; + + return FALSE; +} + +static bfd_boolean +vector_register_name (expressionS *expressionP) +{ + int reg_number; + char *name; + char *start; + char c; + + /* Find the spelling of the operand. */ + start = name = input_line_pointer; + + c = get_symbol_end (); + + reg_number = reg_name_search (vector_registers, VECTOR_REG_NAME_CNT, + name, FALSE); + + /* Put back the delimiting char. */ + *input_line_pointer = c; + + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + + /* Look to see if it's in the register table. */ + if (reg_number >= 0) { - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; + expressionP->X_op = O_register; + expressionP->X_add_number = reg_number; - return FALSE; + return TRUE; } + + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + + expressionP->X_op = O_illegal; + + return FALSE; } /* Summary of system_register_name(). @@ -748,8 +1035,6 @@ register_name (expressionS *expressionP) in: INPUT_LINE_POINTER points to 1st char of operand. EXPRESSIONP points to an expression structure to be filled in. ACCEPT_NUMBERS is true iff numerical register names may be used. - ACCEPT_LIST_NAMES is true iff the special names PS and SR may be - accepted. out: An expressionS structure in expressionP. The operand may have been a register: in this case, X_op == O_register, @@ -759,8 +1044,7 @@ register_name (expressionS *expressionP) static bfd_boolean system_register_name (expressionS *expressionP, - bfd_boolean accept_numbers, - bfd_boolean accept_list_names) + bfd_boolean accept_numbers) { int reg_number; char *name; @@ -785,44 +1069,28 @@ system_register_name (expressionS *expre if (ISDIGIT (*input_line_pointer)) { - reg_number = strtol (input_line_pointer, &input_line_pointer, 10); - - /* Make sure that the register number is allowable. */ - if (reg_number < 0 - || (reg_number > 5 && reg_number < 16) - || reg_number > 27) - reg_number = -1; - } - else if (accept_list_names) - { - c = get_symbol_end (); - reg_number = reg_name_search (system_list_registers, - SYSREGLIST_NAME_CNT, name, FALSE); - - /* Put back the delimiting char. */ - *input_line_pointer = c; + reg_number = strtol (input_line_pointer, &input_line_pointer, 0); } } + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + /* Look to see if it's in the register table. */ if (reg_number >= 0) { expressionP->X_op = O_register; expressionP->X_add_number = reg_number; - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - return TRUE; } - else - { - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return FALSE; - } + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + + expressionP->X_op = O_illegal; + + return FALSE; } /* Summary of cc_name(). @@ -836,7 +1104,8 @@ system_register_name (expressionS *expre its original state. */ static bfd_boolean -cc_name (expressionS *expressionP) +cc_name (expressionS *expressionP, + bfd_boolean accept_numbers) { int reg_number; char *name; @@ -847,30 +1116,93 @@ cc_name (expressionS *expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE); + reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, accept_numbers); /* Put back the delimiting char. */ *input_line_pointer = c; + if (reg_number < 0 + && accept_numbers) + { + /* Reset input_line pointer. */ + input_line_pointer = start; + + if (ISDIGIT (*input_line_pointer)) + { + reg_number = strtol (input_line_pointer, &input_line_pointer, 0); + } + } + + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + /* Look to see if it's in the register table. */ if (reg_number >= 0) { expressionP->X_op = O_constant; expressionP->X_add_number = reg_number; - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - return TRUE; } - else + + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + + expressionP->X_op = O_illegal; + expressionP->X_add_number = 0; + + return FALSE; +} + +static bfd_boolean +float_cc_name (expressionS *expressionP, + bfd_boolean accept_numbers) +{ + int reg_number; + char *name; + char *start; + char c; + + /* Find the spelling of the operand. */ + start = name = input_line_pointer; + + c = get_symbol_end (); + reg_number = reg_name_search (float_cc_names, FLOAT_CC_NAME_CNT, name, accept_numbers); + + /* Put back the delimiting char. */ + *input_line_pointer = c; + + if (reg_number < 0 + && accept_numbers) { - /* Reset the line as if we had not done anything. */ + /* Reset input_line pointer. */ input_line_pointer = start; - return FALSE; + if (ISDIGIT (*input_line_pointer)) + { + reg_number = strtol (input_line_pointer, &input_line_pointer, 0); + } + } + + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + + /* Look to see if it's in the register table. */ + if (reg_number >= 0) + { + expressionP->X_op = O_constant; + expressionP->X_add_number = reg_number; + + return TRUE; } + + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + + expressionP->X_op = O_illegal; + expressionP->X_add_number = 0; + + return FALSE; } static void @@ -915,16 +1247,7 @@ parse_register_list (unsigned long *insn 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 }; - static int type2_regs[32] = - { - 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 - }; - static int type3_regs[32] = - { - 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 - }; + int *regs; expressionS exp; @@ -932,8 +1255,6 @@ parse_register_list (unsigned long *insn switch (operand->shift) { case 0xffe00001: regs = type1_regs; break; - case 0xfff8000f: regs = type2_regs; break; - case 0xfff8001f: regs = type3_regs; break; default: as_bad (_("unknown operand shift: %x\n"), operand->shift); return _("internal failure in parse_register_list"); @@ -967,41 +1288,6 @@ parse_register_list (unsigned long *insn *insn |= (1 << i); } } - else if (regs == type2_regs) - { - if (exp.X_add_number & 0xFFFE0000) - return _("high bits set in register list expression"); - - for (reg = 1; reg < 16; reg++) - if (exp.X_add_number & (1 << (reg - 1))) - { - for (i = 0; i < 32; i++) - if (regs[i] == reg) - *insn |= (1 << i); - } - - if (exp.X_add_number & (1 << 15)) - *insn |= (1 << 3); - - if (exp.X_add_number & (1 << 16)) - *insn |= (1 << 19); - } - else /* regs == type3_regs */ - { - if (exp.X_add_number & 0xFFFE0000) - return _("high bits set in register list expression"); - - for (reg = 16; reg < 32; reg++) - if (exp.X_add_number & (1 << (reg - 16))) - { - for (i = 0; i < 32; i++) - if (regs[i] == reg) - *insn |= (1 << i); - } - - if (exp.X_add_number & (1 << 16)) - *insn |= (1 << 19); - } return NULL; } @@ -1012,6 +1298,8 @@ parse_register_list (unsigned long *insn new-line) is found. */ for (;;) { + skip_white_space (); + if (register_name (&exp)) { int i; @@ -1030,25 +1318,15 @@ parse_register_list (unsigned long *insn if (i == 32) return _("illegal register included in list"); } - else if (system_register_name (&exp, TRUE, TRUE)) + else if (system_register_name (&exp, TRUE)) { if (regs == type1_regs) { return _("system registers cannot be included in list"); } - else if (exp.X_add_number == 5) - { - if (regs == type2_regs) - return _("PSW cannot be included in list"); - else - *insn |= 0x8; - } - else if (exp.X_add_number < 4) - *insn |= 0x80000; - else - return _("High value system registers cannot be included in list"); } - else if (*input_line_pointer == '}') + + if (*input_line_pointer == '}') { input_line_pointer++; break; @@ -1071,7 +1349,11 @@ parse_register_list (unsigned long *insn if (! register_name (&exp2)) { return _("second register should follow dash in register list"); - exp2.X_add_number = exp.X_add_number; + } + + if (exp.X_add_number > exp2.X_add_number) + { + return _("second register should greater tahn first register"); } /* Add the rest of the registers in the range. */ @@ -1093,11 +1375,11 @@ parse_register_list (unsigned long *insn if (i == 32) return _("illegal register included in list"); } + + exp = exp2; } else break; - - skip_white_space (); } return NULL; @@ -1107,6 +1389,10 @@ const char *md_shortopts = "m:"; struct option md_longopts[] = { +#define OPTION_DISP_SIZE_DEFAULT_22 (OPTION_MD_BASE) + {"disp-size-default-22", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_22}, +#define OPTION_DISP_SIZE_DEFAULT_32 (OPTION_MD_BASE + 1) + {"disp-size-default-32", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_32}, {NULL, no_argument, NULL, 0} }; @@ -1121,15 +1407,33 @@ md_show_usage (FILE *stream) fprintf (stream, _(" -mv850 The code is targeted at the v850\n")); fprintf (stream, _(" -mv850e The code is targeted at the v850e\n")); fprintf (stream, _(" -mv850e1 The code is targeted at the v850e1\n")); - fprintf (stream, _(" -mv850any The code is generic, despite any processor specific instructions\n")); + fprintf (stream, _(" -mv850e2 The code is targeted at the v850e2\n")); + fprintf (stream, _(" -mv850e2v3 The code is targeted at the v850e2v3\n")); fprintf (stream, _(" -mrelax Enable relaxation\n")); + fprintf (stream, _(" --disp-size-default-22 branch displacement with unknown size is 22 bits (default)\n")); + fprintf (stream, _(" --disp-size-default-32 branch displacement with unknown size is 32 bits\n")); + fprintf (stream, _(" -mextension enable extension opcode support\n")); + fprintf (stream, _(" -mno-bcond17 disable b disp17 instruction\n")); + fprintf (stream, _(" -mno-stld23 disable st/ld offset23 instruction\n")); } int md_parse_option (int c, char *arg) { if (c != 'm') - return 0; + { + switch (c) + { + case OPTION_DISP_SIZE_DEFAULT_22: + default_disp_size = 22; + return 1; + + case OPTION_DISP_SIZE_DEFAULT_32: + default_disp_size = 32; + return 1; + } + return 0; + } if (strcmp (arg, "warn-signed-overflow") == 0) warn_signed_overflows = TRUE; @@ -1140,26 +1444,39 @@ md_parse_option (int c, char *arg) else if (strcmp (arg, "v850") == 0) { machine = 0; - processor_mask = PROCESSOR_V850; + SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850); } else if (strcmp (arg, "v850e") == 0) { machine = bfd_mach_v850e; - processor_mask = PROCESSOR_V850E; + SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E); } else if (strcmp (arg, "v850e1") == 0) { machine = bfd_mach_v850e1; - processor_mask = PROCESSOR_V850E1; + SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E1); } - else if (strcmp (arg, "v850any") == 0) + else if (strcmp (arg, "v850e2") == 0) { - /* Tell the world that this is for any v850 chip. */ - machine = 0; - - /* But support instructions for the extended versions. */ - processor_mask = PROCESSOR_V850E; - processor_mask |= PROCESSOR_V850E1; + machine = bfd_mach_v850e2; + SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E2); + } + else if (strcmp (arg, "v850e2v3") == 0) + { + machine = bfd_mach_v850e2v3; + SET_PROCESSOR_MASK(processor_mask, PROCESSOR_V850E2V3); + } + else if (strcmp (arg, "extension") == 0) + { + processor_mask |= PROCESSOR_OPTION_EXTENSION | PROCESSOR_OPTION_ALIAS;; + } + else if (strcmp (arg, "no-bcond17") == 0) + { + no_bcond17 = 1; + } + else if (strcmp (arg, "no-stld23") == 0) + { + no_stld23 = 1; } else if (strcmp (arg, "relax") == 0) v850_relax = 1; @@ -1188,33 +1505,50 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU asection *sec, fragS *fragP) { - /* This code performs some nasty type punning between the - fr_opcode field of the frag structure (a char *) and the - fx_r_type field of the fix structure (a bfd_reloc_code_real_type) - On a 64bit host this causes problems because these two fields - are not the same size, but since we know that we are only - ever storing small integers in the fields, it is safe to use - a union to convert between them. */ - union u - { - bfd_reloc_code_real_type fx_r_type; - char * fr_opcode; - } - opcode_converter; subseg_change (sec, 0); - opcode_converter.fr_opcode = fragP->fr_opcode; - /* In range conditional or unconditional branch. */ - if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2) + if (fragP->fr_subtype == SUBYPTE_COND_9_22 + || fragP->fr_subtype == SUBYPTE_UNCOND_9_22 + || fragP->fr_subtype == SUBYPTE_COND_9_22_32 + || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + || fragP->fr_subtype == SUBYPTE_SA_9_22 + || fragP->fr_subtype == SUBYPTE_SA_9_22_32 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32) + { fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, - fragP->fr_offset, 1, - BFD_RELOC_UNUSED + opcode_converter.fx_r_type); + fragP->fr_offset, 1, BFD_RELOC_V850_9_PCREL); fragP->fr_fix += 2; } - /* Out of range conditional branch. Emit a branch around a jump. */ - else if (fragP->fr_subtype == 1) + /* v850e2v3 17bit conditional branch */ + else if (fragP->fr_subtype == SUBYPTE_COND_9_17_22+1 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32+1 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22+1 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32+1) + { + unsigned char *buffer = + (unsigned char *) (fragP->fr_fix + fragP->fr_literal); + + buffer[0] &= 0x0f; /* use condition */ + buffer[0] |= 0xe0; + buffer[1] = 0x07; + + /* Now create the unconditional branch + fixup to the final + target. */ + md_number_to_chars ((char *) buffer + 2, 0x0001, 2); + fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, + fragP->fr_offset, 1, BFD_RELOC_V850_17_PCREL); + fragP->fr_fix += 4; + } + /* Out of range conditional branch. Emit a branch around a 22bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_COND_9_22+1 + || fragP->fr_subtype == SUBYPTE_COND_9_22_32+1 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22+2 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32+2) { unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal); @@ -1232,19 +1566,99 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU target. */ md_number_to_chars ((char *) buffer + 2, 0x00000780, 4); fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, - fragP->fr_offset, 1, - BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1); + fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL); fragP->fr_fix += 6; } - /* Out of range unconditional branch. Emit a jump. */ - else if (fragP->fr_subtype == 3) + /* Out of range conditional branch. Emit a branch around a 32bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_COND_9_22_32+2 + || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32+3) + { + unsigned char *buffer = + (unsigned char *) (fragP->fr_fix + fragP->fr_literal); + + /* Reverse the condition of the first branch. */ + buffer[0] ^= 0x08; + /* Mask off all the displacement bits. */ + buffer[0] &= 0x8f; + buffer[1] &= 0x07; + /* Now set the displacement bits so that we branch + around the unconditional branch. */ + buffer[0] |= 0x40; + + /* Now create the unconditional branch + fixup to the final + target. */ + md_number_to_chars ((char *) buffer + 2, 0x02e0, 2); + fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, + fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL); + fragP->fr_fix += 8; + } + /* Out of range unconditional branch. Emit a 22bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22+1 + || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32+1) { md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4); fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, - fragP->fr_offset, 1, - BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1); + fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL); fragP->fr_fix += 4; } + /* Out of range unconditional branch. Emit a 32bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32+2) + { + md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x02e0, 2); + fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, + fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL); + fragP->fr_fix += 6; + } + /* Out of range SA conditional branch. Emit a branch to a 22bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_SA_9_22+1 + || fragP->fr_subtype == SUBYPTE_SA_9_22_32+1 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22+2 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32+2) + { + unsigned char *buffer = + (unsigned char *) (fragP->fr_fix + fragP->fr_literal); + + /* bsa .+4 */ + buffer[0] &= 0x8f; + buffer[0] |= 0x20; + buffer[1] &= 0x07; + + /* br .+6 */ + md_number_to_chars ((char *) buffer + 2, 0x05b5, 2); + + /* Now create the unconditional branch + fixup to the final + target. */ + /* jr SYM */ + md_number_to_chars ((char *) buffer + 4, 0x00000780, 4); + fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, + fragP->fr_offset, 1, + BFD_RELOC_V850_22_PCREL); + fragP->fr_fix += 8; + } + /* Out of range SA conditional branch. Emit a branch around a 32bit jump. */ + else if (fragP->fr_subtype == SUBYPTE_SA_9_22_32+2 + || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32+3) + { + unsigned char *buffer = + (unsigned char *) (fragP->fr_fix + fragP->fr_literal); + + /* bsa .+2 */ + buffer[0] &= 0x8f; + buffer[0] |= 0x20; + buffer[1] &= 0x07; + + /* br .+8 */ + md_number_to_chars ((char *) buffer + 2, 0x05c5, 2); + + /* Now create the unconditional branch + fixup to the final + target. */ + /* jr SYM */ + md_number_to_chars ((char *) buffer + 4, 0x02e0, 2); + fix_new (fragP, fragP->fr_fix + 6, 4, fragP->fr_symbol, + fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL); + + fragP->fr_fix += 10; + } else abort (); } @@ -1262,29 +1676,45 @@ md_begin (void) char *prev_name = ""; const struct v850_opcode *op; - if (strncmp (TARGET_CPU, "v850e1", 6) == 0) + if (strncmp (TARGET_CPU, "v850e2v3", 8) == 0) + { + if (machine == -1) + machine = bfd_mach_v850e2v3; + + if (!processor_mask) + SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3); + } + else if (strncmp (TARGET_CPU, "v850e2", 6) == 0) + { + if (machine == -1) + machine = bfd_mach_v850e2; + + if (!processor_mask) + SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2); + } + else if (strncmp (TARGET_CPU, "v850e1", 6) == 0) { if (machine == -1) machine = bfd_mach_v850e1; - if (processor_mask == -1) - processor_mask = PROCESSOR_V850E1; + if (!processor_mask) + SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E1); } else if (strncmp (TARGET_CPU, "v850e", 5) == 0) { if (machine == -1) machine = bfd_mach_v850e; - if (processor_mask == -1) - processor_mask = PROCESSOR_V850E; + if (!processor_mask) + SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E); } else if (strncmp (TARGET_CPU, "v850", 4) == 0) { if (machine == -1) machine = 0; - if (processor_mask == -1) - processor_mask = PROCESSOR_V850; + if (!processor_mask) + SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850); } else /* xgettext:c-format */ @@ -1312,119 +1742,158 @@ md_begin (void) bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine); } + static bfd_reloc_code_real_type -handle_lo16 (const struct v850_operand *operand) +handle_hi016 (const struct v850_operand *operand, const char **errmsg) { - if (operand != NULL) - { - if (operand->bits == -1) - return BFD_RELOC_V850_LO16_SPLIT_OFFSET; + if (operand == NULL) + return BFD_RELOC_HI16; - if (!(operand->bits == 16 && operand->shift == 16) - && !(operand->bits == 15 && operand->shift == 17)) - { - as_bad (_("lo() relocation used on an instruction which does " - "not support it")); - return BFD_RELOC_64; /* Used to indicate an error condition. */ - } - } - return BFD_RELOC_LO16; + if (operand->default_reloc == BFD_RELOC_HI16) + return BFD_RELOC_HI16; + + if (operand->default_reloc == BFD_RELOC_HI16_S) + return BFD_RELOC_HI16; + + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_HI16; + + *errmsg = _("hi0() relocation used on an instruction which does " + "not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ } static bfd_reloc_code_real_type -handle_ctoff (const struct v850_operand *operand) +handle_hi16 (const struct v850_operand *operand, const char **errmsg) { if (operand == NULL) - return BFD_RELOC_V850_CALLT_16_16_OFFSET; + return BFD_RELOC_HI16_S; - if (operand->bits != 6 - || operand->shift != 0) - { - as_bad (_("ctoff() relocation used on an instruction which does not support it")); - return BFD_RELOC_64; /* Used to indicate an error condition. */ - } + if (operand->default_reloc == BFD_RELOC_HI16_S) + return BFD_RELOC_HI16_S; + + if (operand->default_reloc == BFD_RELOC_HI16) + return BFD_RELOC_HI16_S; + + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_HI16_S; - return BFD_RELOC_V850_CALLT_6_7_OFFSET; + *errmsg = _("hi() relocation used on an instruction which does " + "not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ } static bfd_reloc_code_real_type -handle_sdaoff (const struct v850_operand *operand) +handle_lo16 (const struct v850_operand *operand, const char **errmsg) { if (operand == NULL) - return BFD_RELOC_V850_SDA_16_16_OFFSET; + return BFD_RELOC_LO16; - if (operand->bits == 15 && operand->shift == 17) - return BFD_RELOC_V850_SDA_15_16_OFFSET; + if (operand->default_reloc == BFD_RELOC_LO16) + return BFD_RELOC_LO16; - if (operand->bits == -1) - return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET; + if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET) + return BFD_RELOC_V850_LO16_SPLIT_OFFSET; - if (operand->bits != 16 - || operand->shift != 16) - { - as_bad (_("sdaoff() relocation used on an instruction which does not support it")); - return BFD_RELOC_64; /* Used to indicate an error condition. */ - } + if (operand->default_reloc == BFD_RELOC_V850_16_S1) + return BFD_RELOC_V850_LO16_S1; + + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_LO16; - return BFD_RELOC_V850_SDA_16_16_OFFSET; + *errmsg = _("lo() relocation used on an instruction which does " + "not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ } static bfd_reloc_code_real_type -handle_zdaoff (const struct v850_operand *operand) +handle_ctoff (const struct v850_operand *operand, const char **errmsg) { if (operand == NULL) - return BFD_RELOC_V850_ZDA_16_16_OFFSET; + return BFD_RELOC_V850_CALLT_16_16_OFFSET; - if (operand->bits == 15 && operand->shift == 17) - return BFD_RELOC_V850_ZDA_15_16_OFFSET; + if (operand->default_reloc == BFD_RELOC_V850_CALLT_6_7_OFFSET) + return operand->default_reloc; - if (operand->bits == -1) - return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET; + if (operand->default_reloc == BFD_RELOC_V850_16_S1) + return BFD_RELOC_V850_CALLT_15_16_OFFSET; - if (operand->bits != 16 - || operand->shift != 16) - { - as_bad (_("zdaoff() relocation used on an instruction which does not support it")); - /* Used to indicate an error condition. */ - return BFD_RELOC_64; - } + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_V850_CALLT_16_16_OFFSET; - return BFD_RELOC_V850_ZDA_16_16_OFFSET; + *errmsg = _("ctoff() relocation used on an instruction which does not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ } static bfd_reloc_code_real_type -handle_tdaoff (const struct v850_operand *operand) +handle_sdaoff (const struct v850_operand *operand, const char **errmsg) { if (operand == NULL) - /* Data item, not an instruction. */ - return BFD_RELOC_V850_TDA_7_7_OFFSET; + return BFD_RELOC_V850_SDA_16_16_OFFSET; + + if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET) + return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET; + + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_V850_SDA_16_16_OFFSET; + + if (operand->default_reloc == BFD_RELOC_V850_16_S1) + return BFD_RELOC_V850_SDA_15_16_OFFSET; + + *errmsg = _("sdaoff() relocation used on an instruction which does not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ +} + +static bfd_reloc_code_real_type +handle_zdaoff (const struct v850_operand *operand, const char **errmsg) +{ + if (operand == NULL) + return BFD_RELOC_V850_ZDA_16_16_OFFSET; + + if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET) + return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET; + + if (operand->default_reloc == BFD_RELOC_16) + return BFD_RELOC_V850_ZDA_16_16_OFFSET; - if (operand->bits == 6 && operand->shift == 1) - /* sld.w/sst.w, operand: D8_6. */ - return BFD_RELOC_V850_TDA_6_8_OFFSET; - - if (operand->bits == 4 && operand->insert != NULL) - /* sld.hu, operand: D5-4. */ - return BFD_RELOC_V850_TDA_4_5_OFFSET; - - if (operand->bits == 4 && operand->insert == NULL) - /* sld.bu, operand: D4. */ - return BFD_RELOC_V850_TDA_4_4_OFFSET; + if (operand->default_reloc == BFD_RELOC_V850_16_S1) + return BFD_RELOC_V850_ZDA_15_16_OFFSET; + + *errmsg = _("zdaoff() relocation used on an instruction which does not support it"); + return BFD_RELOC_64; /* Used to indicate an error condition. */ +} - if (operand->bits == 16 && operand->shift == 16) - /* set1 & chums, operands: D16. */ +static bfd_reloc_code_real_type +handle_tdaoff (const struct v850_operand *operand, const char **errmsg) +{ + if (operand == NULL) + /* Data item, not an instruction. */ return BFD_RELOC_V850_TDA_16_16_OFFSET; - if (operand->bits != 7) + switch (operand->default_reloc) { - as_bad (_("tdaoff() relocation used on an instruction which does not support it")); - /* Used to indicate an error condition. */ - return BFD_RELOC_64; + /* sld.hu, operand: D5-4 */ + case BFD_RELOC_V850_TDA_4_5_OFFSET: + /* sld.bu, operand: D4 */ + case BFD_RELOC_V850_TDA_4_4_OFFSET: + /* sld.w/sst.w, operand: D8_6 */ + case BFD_RELOC_V850_TDA_6_8_OFFSET: + /* sld.h/sst.h, operand: D8_7 */ + case BFD_RELOC_V850_TDA_7_8_OFFSET: + /* sld.b/sst.b, operand: D7 */ + case BFD_RELOC_V850_TDA_7_7_OFFSET: + return operand->default_reloc; + default: + break; } - return operand->insert != NULL - ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7. */ - : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, operand: D7. */ + if (operand->default_reloc == BFD_RELOC_16 && operand->shift == 16) + /* set1 & chums, operands: D16 */ + return BFD_RELOC_V850_TDA_16_16_OFFSET; + + *errmsg = _("tdaoff() relocation used on an instruction which does not support it"); + /* Used to indicate an error condition. */ + return BFD_RELOC_64; } /* Warning: The code in this function relies upon the definitions @@ -1432,7 +1901,7 @@ handle_tdaoff (const struct v850_operand matching the hard coded values contained herein. */ static bfd_reloc_code_real_type -v850_reloc_prefix (const struct v850_operand *operand) +v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg) { bfd_boolean paren_skipped = FALSE; @@ -1450,14 +1919,15 @@ v850_reloc_prefix (const struct v850_ope return reloc; \ } - CHECK_ ("hi0", BFD_RELOC_HI16 ); - CHECK_ ("hi", BFD_RELOC_HI16_S ); - CHECK_ ("lo", handle_lo16 (operand) ); - CHECK_ ("sdaoff", handle_sdaoff (operand)); - CHECK_ ("zdaoff", handle_zdaoff (operand)); - CHECK_ ("tdaoff", handle_tdaoff (operand)); - CHECK_ ("hilo", BFD_RELOC_32 ); - CHECK_ ("ctoff", handle_ctoff (operand) ); + CHECK_ ("hi0", handle_hi016(operand, errmsg) ); + CHECK_ ("hi", handle_hi16(operand, errmsg) ); + CHECK_ ("lo", handle_lo16 (operand, errmsg) ); + CHECK_ ("sdaoff", handle_sdaoff (operand, errmsg)); + CHECK_ ("zdaoff", handle_zdaoff (operand, errmsg)); + CHECK_ ("tdaoff", handle_tdaoff (operand, errmsg)); + CHECK_ ("hilo", BFD_RELOC_32 ); + CHECK_ ("lo23", BFD_RELOC_V850_23 ); + CHECK_ ("ctoff", handle_ctoff (operand, errmsg) ); /* Restore skipped parenthesis. */ if (paren_skipped) @@ -1472,9 +1942,7 @@ static unsigned long v850_insert_operand (unsigned long insn, const struct v850_operand *operand, offsetT val, - char *file, - unsigned int line, - char *str) + const char **errmsg) { if (operand->insert) { @@ -1485,35 +1953,33 @@ v850_insert_operand (unsigned long insn, { if ((operand->flags & V850_OPERAND_SIGNED) && ! warn_signed_overflows - && strstr (message, "out of range") != NULL) + && v850_msg_is_out_of_range (message)) { /* Skip warning... */ } else if ((operand->flags & V850_OPERAND_SIGNED) == 0 && ! warn_unsigned_overflows - && strstr (message, "out of range") != NULL) + && v850_msg_is_out_of_range (message)) { /* Skip warning... */ } - else if (str) - { - if (file == (char *) NULL) - as_warn ("%s: %s", str, message); - else - as_warn_where (file, line, "%s: %s", str, message); - } else { - if (file == (char *) NULL) - as_warn ("%s", message); - else - as_warn_where (file, line, "%s", message); + if (errmsg != NULL) + *errmsg = message; } } } + else if (operand->bits == -1 + || operand->flags & V850E_IMMEDIATE16 + || operand->flags & V850E_IMMEDIATE23 + || operand->flags & V850E_IMMEDIATE32) + { + abort(); + } else { - if (operand->bits != 32) + if (operand->bits < 32) { long min, max; @@ -1536,9 +2002,11 @@ v850_insert_operand (unsigned long insn, min = 0; } - if (val < (offsetT) min || val > (offsetT) max) + if (errmsg != NULL + && (val < (offsetT) min || val > (offsetT) max)) { - char buf [128]; + static char buf [128]; + char *fmt; /* Restore min and mix to expected values for decimal ranges. */ if ((operand->flags & V850_OPERAND_SIGNED) @@ -1549,17 +2017,18 @@ v850_insert_operand (unsigned long insn, && ! warn_unsigned_overflows) min = 0; - if (str) - sprintf (buf, "%s: ", str); - else - buf[0] = 0; - strcat (buf, _("operand")); + fmt = _("%s out of range (%d is not between %d and %d)"); - as_bad_value_out_of_range (buf, val, (offsetT) min, (offsetT) max, file, line); + sprintf (buf, fmt, _("operand"), val, (offsetT) min, (offsetT) max); + *errmsg = buf; } - } - insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift); + insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift); + } + else + { + insn |= (((long) val) << operand->shift); + } } return insn; @@ -1586,8 +2055,11 @@ md_assemble (char *str) unsigned extra_data_len = 0; unsigned long extra_data = 0; char *saved_input_line_pointer; + char most_match_errmsg[1024]; + int most_match_count = -1; strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1); + most_match_errmsg[0] = 0; /* Get the opcode. */ for (s = str; *s != '\0' && ! ISSPACE (*s); s++) @@ -1617,10 +2089,26 @@ md_assemble (char *str) for (;;) { const char *errmsg = NULL; + const char *warningmsg = NULL; match = 0; + opindex_ptr = opcode->operands; + + if (no_stld23) + { + if ((strncmp (opcode->name, "st.", 3) == 0 + && v850_operands[opcode->operands[1]].bits == 23) + || (strncmp (opcode->name, "ld.", 3) == 0 + && v850_operands[opcode->operands[0]].bits == 23)) + { + errmsg = _("st/ld offset 23 instruction was disabled ."); + goto error; + } + } - if ((opcode->processors & processor_mask) == 0) + if ((opcode->processors & processor_mask & PROCESSOR_MASK) == 0 + || (((opcode->processors & ~PROCESSOR_MASK) != 0) + && ((opcode->processors & processor_mask & ~PROCESSOR_MASK) == 0))) { errmsg = _("Target processor does not support this instruction."); goto error; @@ -1630,6 +2118,7 @@ md_assemble (char *str) fc = 0; next_opindex = 0; insn = opcode->opcode; + extra_data_len = 0; extra_data_after_insn = FALSE; input_line_pointer = str = start_of_operands; @@ -1651,7 +2140,20 @@ md_assemble (char *str) errmsg = NULL; - while (*str == ' ' || *str == ',' || *str == '[' || *str == ']') + while (*str == ' ') + ++str; + + if (operand->flags & V850_OPERAND_BANG + && *str == '!') + ++str; + else if (operand->flags & V850_OPERAND_PERCENT + && *str == '%') + ++str; + + if (*str == ',' || *str == '[' || *str == ']') + ++str; + + while (*str == ' ') ++str; if (operand->flags & V850_OPERAND_RELAX) @@ -1662,12 +2164,12 @@ md_assemble (char *str) input_line_pointer = str; /* lo(), hi(), hi0(), etc... */ - if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED) + if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_UNUSED) { /* This is a fake reloc, used to indicate an error condition. */ if (reloc == BFD_RELOC_64) { - match = 1; + /* match = 1; */ goto error; } @@ -1678,11 +2180,14 @@ md_assemble (char *str) switch (reloc) { case BFD_RELOC_V850_ZDA_16_16_OFFSET: + case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET: + case BFD_RELOC_V850_ZDA_15_16_OFFSET: /* To cope with "not1 7, zdaoff(0xfffff006)[r0]" and the like. */ /* Fall through. */ case BFD_RELOC_LO16: + case BFD_RELOC_V850_LO16_S1: case BFD_RELOC_V850_LO16_SPLIT_OFFSET: { /* Truncate, then sign extend the value. */ @@ -1708,16 +2213,23 @@ md_assemble (char *str) break; } + case BFD_RELOC_V850_23: + if ((operand->flags & V850E_IMMEDIATE23) == 0) + { + errmsg = _("immediate operand is too large"); + goto error; + } + break; + case BFD_RELOC_32: + case BFD_RELOC_V850_32_ABS: + case BFD_RELOC_V850_32_PCREL: if ((operand->flags & V850E_IMMEDIATE32) == 0) { errmsg = _("immediate operand is too large"); goto error; } - extra_data_after_insn = TRUE; - extra_data_len = 4; - extra_data = 0; break; default: @@ -1726,6 +2238,45 @@ md_assemble (char *str) break; } + if (operand->flags & V850E_IMMEDIATE32) + { + extra_data_after_insn = TRUE; + extra_data_len = 4; + extra_data = 0; + } + else if (operand->flags & V850E_IMMEDIATE23) + { + if (reloc != BFD_RELOC_V850_23) + { + errmsg = _("immediate operand is too large"); + goto error; + } + extra_data_after_insn = TRUE; + extra_data_len = 2; + extra_data = 0; + } + else if ((operand->flags & V850E_IMMEDIATE16) + || (operand->flags & V850E_IMMEDIATE16HI)) + { + if (operand->flags & V850E_IMMEDIATE16HI + && reloc != BFD_RELOC_HI16 + && reloc != BFD_RELOC_HI16_S) + { + errmsg = _("immediate operand is too large"); + goto error; + } + else if (operand->flags & V850E_IMMEDIATE16 + && reloc != BFD_RELOC_LO16) + { + errmsg = _("immediate operand is too large"); + goto error; + } + + extra_data_after_insn = TRUE; + extra_data_len = 2; + extra_data = 0; + } + if (fc > MAX_INSN_FIXUPS) as_fatal (_("too many fixups")); @@ -1734,19 +2285,67 @@ md_assemble (char *str) fixups[fc].reloc = reloc; fc++; } - else + else /* ex.X_op != O_constant */ { - if (reloc == BFD_RELOC_32) + if ((reloc == BFD_RELOC_32 + || reloc == BFD_RELOC_V850_32_ABS + || reloc == BFD_RELOC_V850_32_PCREL) + && operand->bits < 32) { - if ((operand->flags & V850E_IMMEDIATE32) == 0) + errmsg = _("immediate operand is too large"); + goto error; + } + else if (reloc == BFD_RELOC_V850_23 + && (operand->flags & V850E_IMMEDIATE23) == 0) + { + errmsg = _("immediate operand is too large"); + goto error; + } + else if ((reloc == BFD_RELOC_HI16 + || reloc == BFD_RELOC_HI16_S) + && operand->bits < 16) + { + errmsg = _("immediate operand is too large"); + goto error; + } + + if (operand->flags & V850E_IMMEDIATE32) + { + extra_data_after_insn = TRUE; + extra_data_len = 4; + extra_data = 0; + } + else if (operand->flags & V850E_IMMEDIATE23) + { + if (reloc != BFD_RELOC_V850_23) + { + errmsg = _("immediate operand is too large"); + goto error; + } + extra_data_after_insn = TRUE; + extra_data_len = 2; + extra_data = 0; + } + else if ((operand->flags & V850E_IMMEDIATE16) + || (operand->flags & V850E_IMMEDIATE16HI)) + { + if (operand->flags & V850E_IMMEDIATE16HI + && reloc != BFD_RELOC_HI16 + && reloc != BFD_RELOC_HI16_S) + { + errmsg = _("immediate operand is too large"); + goto error; + } + else if (operand->flags & V850E_IMMEDIATE16 + && reloc != BFD_RELOC_LO16) { errmsg = _("immediate operand is too large"); goto error; } extra_data_after_insn = TRUE; - extra_data_len = 4; - extra_data = ex.X_add_number; + extra_data_len = 2; + extra_data = 0; } if (fc > MAX_INSN_FIXUPS) @@ -1758,6 +2357,140 @@ md_assemble (char *str) fc++; } } + else if (operand->flags & V850E_IMMEDIATE16 + || operand->flags & V850E_IMMEDIATE16HI) + { + expression (&ex); + + switch (ex.X_op) + { + case O_constant: + if (operand->flags & V850E_IMMEDIATE16HI) + { + if (ex.X_add_number & 0xffff) + { + errmsg = _("constant too big to fit into instruction"); + goto error; + } + + ex.X_add_number >>= 16; + } + if (operand->flags & V850E_IMMEDIATE16) + { + if (ex.X_add_number & 0xffff0000) + { + errmsg = _("constant too big to fit into instruction"); + goto error; + } + } + break; + + case O_illegal: + errmsg = _("illegal operand"); + goto error; + + case O_absent: + errmsg = _("missing operand"); + goto error; + + default: + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + + fixups[fc].exp = ex; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = operand->default_reloc; + ++fc; + + ex.X_add_number = 0; + break; + } + + extra_data_after_insn = TRUE; + extra_data_len = 2; + extra_data = ex.X_add_number; + } + else if (operand->flags & V850E_IMMEDIATE23) + { + expression (&ex); + + switch (ex.X_op) + { + case O_constant: + break; + + case O_illegal: + errmsg = _("illegal operand"); + goto error; + + case O_absent: + errmsg = _("missing operand"); + goto error; + + default: + break; + } + + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + + fixups[fc].exp = ex; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = operand->default_reloc; + ++fc; + + extra_data_after_insn = TRUE; + extra_data_len = 2; + extra_data = 0; + } + else if (operand->flags & V850E_IMMEDIATE32) + { + expression (&ex); + + switch (ex.X_op) + { + case O_constant: + if ((operand->default_reloc == BFD_RELOC_V850_32_ABS + || operand->default_reloc == BFD_RELOC_V850_32_PCREL) + && (ex.X_add_number & 1)) + { + errmsg = _("odd number cannot be used here"); + goto error; + } + break; + + case O_illegal: + errmsg = _("illegal operand"); + goto error; + + case O_absent: + errmsg = _("missing operand"); + goto error; + + default: + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + + fixups[fc].exp = ex; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = operand->default_reloc; + ++fc; + + ex.X_add_number = 0; + break; + } + + extra_data_after_insn = TRUE; + extra_data_len = 4; + extra_data = ex.X_add_number; + } + else if (operand->flags & V850E_OPERAND_REG_LIST) + { + errmsg = parse_register_list (&insn, operand); + + if (errmsg) + goto error; + } else { errmsg = NULL; @@ -1765,22 +2498,37 @@ md_assemble (char *str) if ((operand->flags & V850_OPERAND_REG) != 0) { if (!register_name (&ex)) - errmsg = _("invalid register name"); - else if ((operand->flags & V850_NOT_R0) + { + errmsg = _("invalid register name"); + } + + if ((operand->flags & V850_NOT_R0) && ex.X_add_number == 0) { errmsg = _("register r0 cannot be used here"); + } + + if (operand->flags & V850_REG_EVEN) + { + if (ex.X_add_number % 2) + errmsg = _("odd register cannot be used here"); + ex.X_add_number = ex.X_add_number / 2; + } - /* Force an error message to be generated by - skipping over any following potential matches - for this opcode. */ - opcode += 3; + } + else if ((operand->flags & V850_OPERAND_VREG) != 0) + { + if (!vector_register_name (&ex)) + { + errmsg = _("invalid vector register name"); } } else if ((operand->flags & V850_OPERAND_SRG) != 0) { - if (!system_register_name (&ex, TRUE, FALSE)) - errmsg = _("invalid system register name"); + if (!system_register_name (&ex, TRUE)) + { + errmsg = _("invalid system register name"); + } } else if ((operand->flags & V850_OPERAND_EP) != 0) { @@ -1807,53 +2555,28 @@ md_assemble (char *str) } else if ((operand->flags & V850_OPERAND_CC) != 0) { - if (!cc_name (&ex)) - errmsg = _("invalid condition code name"); - } - else if (operand->flags & V850E_PUSH_POP) - { - errmsg = parse_register_list (&insn, operand); - - /* The parse_register_list() function has already done - everything, so fake a dummy expression. */ - ex.X_op = O_constant; - ex.X_add_number = 0; - } - else if (operand->flags & V850E_IMMEDIATE16) - { - expression (&ex); - - if (ex.X_op != O_constant) - errmsg = _("constant expression expected"); - else if (ex.X_add_number & 0xffff0000) + if (!cc_name (&ex, TRUE)) { - if (ex.X_add_number & 0xffff) - errmsg = _("constant too big to fit into instruction"); - else if ((insn & 0x001fffc0) == 0x00130780) - ex.X_add_number >>= 16; - else - errmsg = _("constant too big to fit into instruction"); + errmsg = _("invalid condition code name"); } - extra_data_after_insn = TRUE; - extra_data_len = 2; - extra_data = ex.X_add_number; - ex.X_add_number = 0; + if ((operand->flags & V850_NOT_SA) + && ex.X_add_number == COND_SA_NUM) + { + errmsg = _("condition sa cannot be used here"); + } } - else if (operand->flags & V850E_IMMEDIATE32) + else if ((operand->flags & V850_OPERAND_FLOAT_CC) != 0) { - expression (&ex); - - if (ex.X_op != O_constant) - errmsg = _("constant expression expected"); - - extra_data_after_insn = TRUE; - extra_data_len = 4; - extra_data = ex.X_add_number; - ex.X_add_number = 0; + if (!float_cc_name (&ex, TRUE)) + { + errmsg = _("invalid condition code name"); + } } - else if (register_name (&ex) - && (operand->flags & V850_OPERAND_REG) == 0) + else if ((register_name (&ex) + && (operand->flags & V850_OPERAND_REG) == 0) + || (vector_register_name (&ex) + && (operand->flags & V850_OPERAND_VREG) == 0)) { char c; int exists = 0; @@ -1883,8 +2606,10 @@ md_assemble (char *str) the parsing of the instruction, (because another field is missing) then report this. */ if (opindex_ptr[1] != 0 - && (v850_operands[opindex_ptr[1]].flags - & V850_OPERAND_REG)) + && ((v850_operands[opindex_ptr[1]].flags + & V850_OPERAND_REG) + ||(v850_operands[opindex_ptr[1]].flags + & V850_OPERAND_VREG))) errmsg = _("syntax error: value is missing before the register name"); else errmsg = _("syntax error: register not expected"); @@ -1898,29 +2623,55 @@ md_assemble (char *str) &symbol_rootP, &symbol_lastP); } } - else if (system_register_name (&ex, FALSE, FALSE) + else if (system_register_name (&ex, FALSE) && (operand->flags & V850_OPERAND_SRG) == 0) - errmsg = _("syntax error: system register not expected"); - - else if (cc_name (&ex) + { + errmsg = _("syntax error: system register not expected"); + } + else if (cc_name (&ex, FALSE) && (operand->flags & V850_OPERAND_CC) == 0) - errmsg = _("syntax error: condition code not expected"); - + { + errmsg = _("syntax error: condition code not expected"); + } + else if (float_cc_name (&ex, FALSE) + && (operand->flags & V850_OPERAND_FLOAT_CC) == 0) + { + errmsg = _("syntax error: condition code not expected"); + } else { expression (&ex); + + if ((operand->flags & V850_NOT_IMM0) + && ex.X_op == O_constant + && ex.X_add_number == 0) + { + errmsg = _("immediate 0 cannot be used here"); + } + /* Special case: - If we are assembling a MOV instruction and the immediate + If we are assembling a MOV/JARL/JR instruction and the immediate value does not fit into the bits available then create a - fake error so that the next MOV instruction will be + fake error so that the next MOV/JARL/JR instruction will be selected. This one has a 32 bit immediate field. */ - if (((insn & 0x07e0) == 0x0200) - && operand->bits == 5 /* Do not match the CALLT instruction. */ + if ((strcmp (opcode->name, "mov") == 0 + || strcmp (opcode->name, "jarl") == 0 + || strcmp (opcode->name, "jr") == 0) && ex.X_op == O_constant && (ex.X_add_number < (-(1 << (operand->bits - 1))) || ex.X_add_number > ((1 << (operand->bits - 1)) - 1))) - errmsg = _("immediate operand is too large"); + { + errmsg = _("immediate operand is too large"); + } + + if ((strcmp (opcode->name, "jarl") == 0 + || strcmp (opcode->name, "jr") == 0) + && ex.X_op != O_constant + && operand->bits != default_disp_size) + { + errmsg = _("immediate operand is not match"); + } } if (errmsg) @@ -1936,18 +2687,21 @@ md_assemble (char *str) goto error; case O_register: if ((operand->flags - & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0) + & (V850_OPERAND_REG | V850_OPERAND_SRG | V850_OPERAND_VREG)) == 0) { errmsg = _("invalid operand"); goto error; } - insn = v850_insert_operand (insn, operand, ex.X_add_number, - NULL, 0, copy_of_instruction); + + insn = v850_insert_operand (insn, operand, + ex.X_add_number, + &warningmsg); + break; case O_constant: insn = v850_insert_operand (insn, operand, ex.X_add_number, - NULL, 0, copy_of_instruction); + &warningmsg); break; default: @@ -1970,11 +2724,23 @@ md_assemble (char *str) || *str == ')') ++str; } - match = 1; + while (ISSPACE (*str)) + ++str; + + if (*str == '\0') + match = 1; + error: if (match == 0) { + if ((opindex_ptr - opcode->operands) >= most_match_count) + { + most_match_count = opindex_ptr - opcode->operands; + if (errmsg != NULL) + strncpy (most_match_errmsg, errmsg, sizeof(most_match_errmsg)-1); + } + next_opcode = opcode + 1; if (next_opcode->name != NULL && strcmp (next_opcode->name, opcode->name) == 0) @@ -1989,7 +2755,11 @@ md_assemble (char *str) continue; } - as_bad ("%s: %s", copy_of_instruction, errmsg); + if (most_match_errmsg[0] == 0) + /* xgettext:c-format */ + as_bad (_("junk at end of line: `%s'"), str); + else + as_bad ("%s: %s", copy_of_instruction, most_match_errmsg); if (*input_line_pointer == ']') ++input_line_pointer; @@ -1998,16 +2768,12 @@ md_assemble (char *str) input_line_pointer = saved_input_line_pointer; return; } + + if (warningmsg != NULL) + as_warn (warningmsg); break; } - while (ISSPACE (*str)) - ++str; - - if (*str != '\0') - /* xgettext:c-format */ - as_bad (_("junk at end of line: `%s'"), str); - input_line_pointer = str; /* Tie dwarf2 debug info to the address at the start of the insn. @@ -2019,40 +2785,124 @@ md_assemble (char *str) if (relaxable && fc > 0) { - /* On a 64-bit host the size of an 'int' is not the same - as the size of a pointer, so we need a union to convert - the opindex field of the fr_cgen structure into a char * - so that it can be stored in the frag. We do not have - to worry about loosing accuracy as we are not going to - be even close to the 32bit limit of the int. */ - union - { - int opindex; - char * ptr; - } - opindex_converter; - - opindex_converter.opindex = fixups[0].opindex; insn_size = 2; fc = 0; - if (!strcmp (opcode->name, "br")) + if (strcmp (opcode->name, "br") == 0 + || strcmp (opcode->name, "jbr") == 0) { - f = frag_var (rs_machine_dependent, 4, 2, 2, - fixups[0].exp.X_add_symbol, - fixups[0].exp.X_add_number, - opindex_converter.ptr); - md_number_to_chars (f, insn, insn_size); - md_number_to_chars (f + 2, 0, 2); + if ((processor_mask & PROCESSOR_V850E2_ALL) == 0 || default_disp_size == 22) + { + f = frag_var (rs_machine_dependent, 4, 2, SUBYPTE_UNCOND_9_22, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 2); + } + else + { + f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_UNCOND_9_22_32, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 4); + } } - else + else /* b, j */ { - f = frag_var (rs_machine_dependent, 6, 4, 0, - fixups[0].exp.X_add_symbol, - fixups[0].exp.X_add_number, - opindex_converter.ptr); - md_number_to_chars (f, insn, insn_size); - md_number_to_chars (f + 2, 0, 4); + if (default_disp_size == 22 + || (processor_mask & PROCESSOR_V850E2_ALL) == 0) + { + if (processor_mask & PROCESSOR_V850E2V3 && !no_bcond17) + { + if(strcmp(opcode->name, "bsa") == 0) + { + f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_17_22, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 6); + } + else + { + f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_17_22, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 4); + } + } + else + { + if(strcmp(opcode->name, "bsa") == 0) + { + f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_22, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 6); + } + else + { + f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_22, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 4); + } + } + } + else + { + if (processor_mask & PROCESSOR_V850E2V3 && !no_bcond17) + { + if (strcmp (opcode->name, "bsa") == 0) + { + f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_17_22_32, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 8); + } + else + { + f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_17_22_32, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 6); + } + } + else + { + if (strcmp (opcode->name, "bsa") == 0) + { + f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_22_32, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 8); + } + else + { + f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_22_32, + fixups[0].exp.X_add_symbol, + fixups[0].exp.X_add_number, + (char *)(size_t) fixups[0].opindex); + md_number_to_chars (f, insn, insn_size); + md_number_to_chars (f + 2, 0, 6); + } + } + } } } else @@ -2067,6 +2917,12 @@ md_assemble (char *str) if ((insn & 0xffe0) == 0x0620) insn_size = 2; + /* Special case: 32 bit JARL,JMP,JR. */ + if ((insn & 0x1ffe0) == 0x2e0 /* JARL */ + || (insn & 0x1ffe0) == 0x6e0 /* JMP */ + || (insn & 0x1ffff) == 0x2e0) /* JR */ + insn_size = 2; + f = frag_more (insn_size); md_number_to_chars (f, insn, insn_size); @@ -2112,11 +2968,26 @@ md_assemble (char *str) if (size != 2 && size != 4) abort (); - address = (f - frag_now->fr_literal) + insn_size - size; + if (extra_data_len == 0) + { + address = (f - frag_now->fr_literal) + insn_size - size; + } + else + { + address = (f - frag_now->fr_literal) + extra_data_len - size; + } - if (reloc == BFD_RELOC_32) - address += 2; + if ((operand->flags & V850E_IMMEDIATE32) && (operand->flags & V850_PCREL)) + { + fixups[i].exp.X_add_number += 2; + } + else if (operand->default_reloc == BFD_RELOC_V850_16_PCREL) + { + fixups[i].exp.X_add_number += 2; + address += 2; + } + /* fprintf (stderr, "0x%x %d %ld\n", address, size, fixups[i].exp.X_add_number); */ fixP = fix_new_exp (frag_now, address, size, &fixups[i].exp, reloc_howto->pc_relative, @@ -2127,6 +2998,7 @@ md_assemble (char *str) switch (reloc) { case BFD_RELOC_LO16: + case BFD_RELOC_V850_LO16_S1: case BFD_RELOC_V850_LO16_SPLIT_OFFSET: case BFD_RELOC_HI16: case BFD_RELOC_HI16_S: @@ -2141,7 +3013,7 @@ md_assemble (char *str) fix_new_exp (frag_now, f - frag_now->fr_literal, 4, & fixups[i].exp, - (operand->flags & V850_OPERAND_DISP) != 0, + (operand->flags & V850_PCREL) != 0, (bfd_reloc_code_real_type) (fixups[i].opindex + (int) BFD_RELOC_UNUSED)); } @@ -2171,9 +3043,11 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UN reloc->addend = fixp->fx_offset; else { +#if 0 if (fixp->fx_r_type == BFD_RELOC_32 && fixp->fx_pcrel) fixp->fx_r_type = BFD_RELOC_32_PCREL; +#endif reloc->addend = fixp->fx_addnumber; } @@ -2278,6 +3152,7 @@ md_apply_fix (fixS *fixP, valueT *valueP int opindex; const struct v850_operand *operand; unsigned long insn; + const char *errmsg = NULL; opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED; operand = &v850_operands[opindex]; @@ -2289,10 +3164,20 @@ md_apply_fix (fixS *fixP, valueT *valueP format! */ where = fixP->fx_frag->fr_literal + fixP->fx_where; - insn = bfd_getl32 ((unsigned char *) where); + if (fixP->fx_size > 2) + insn = bfd_getl32 ((unsigned char *) where); + else + insn = bfd_getl16 ((unsigned char *) where); + insn = v850_insert_operand (insn, operand, (offsetT) value, - fixP->fx_file, fixP->fx_line, NULL); - bfd_putl32 ((bfd_vma) insn, (unsigned char *) where); + &errmsg); + if (errmsg) + as_warn_where (fixP->fx_file, fixP->fx_line, errmsg); + + if (fixP->fx_size > 2) + bfd_putl32 ((bfd_vma) insn, (unsigned char *) where); + else + bfd_putl16 ((bfd_vma) insn, (unsigned char *) where); if (fixP->fx_done) /* Nothing else to do here. */ @@ -2301,60 +3186,123 @@ md_apply_fix (fixS *fixP, valueT *valueP /* Determine a BFD reloc value based on the operand information. We are only prepared to turn a few of the operands into relocs. */ - if (operand->bits == 22) - fixP->fx_r_type = BFD_RELOC_V850_22_PCREL; - else if (operand->bits == 9) - fixP->fx_r_type = BFD_RELOC_V850_9_PCREL; - else + if (operand->default_reloc == BFD_RELOC_NONE) { as_bad_where (fixP->fx_file, fixP->fx_line, _("unresolved expression that must be resolved")); fixP->fx_done = 1; return; } + + { + fixP->fx_r_type = operand->default_reloc; + if (operand->default_reloc == BFD_RELOC_V850_16_PCREL) + { + fixP->fx_where += 2; + fixP->fx_size = 2; + fixP->fx_addnumber += 2; + } + } } else if (fixP->fx_done) { /* We still have to insert the value into memory! */ where = fixP->fx_frag->fr_literal + fixP->fx_where; - if (fixP->tc_fix_data != NULL - && ((struct v850_operand *) fixP->tc_fix_data)->insert != NULL) + switch (fixP->fx_r_type) { - const char * message = NULL; - struct v850_operand * operand = (struct v850_operand *) fixP->tc_fix_data; - unsigned long insn; - - /* The variable "where" currently points at the exact point inside - the insn where we need to insert the value. But we need to - extract the entire insn so we probably need to move "where" - back a few bytes. */ - if (fixP->fx_size == 2) - where -= 2; - else if (fixP->fx_size == 1) - where -= 3; - - insn = bfd_getl32 ((unsigned char *) where); - - /* Use the operand's insertion procedure, if present, in order to - make sure that the value is correctly stored in the insn. */ - insn = operand->insert (insn, (offsetT) value, & message); - /* Ignore message even if it is set. */ + case BFD_RELOC_V850_32_ABS: + case BFD_RELOC_V850_32_PCREL: + bfd_putl32 (value & 0xfffffffe, (unsigned char *) where); + break; - bfd_putl32 ((bfd_vma) insn, (unsigned char *) where); - } - else - { - if (fixP->fx_r_type == BFD_RELOC_V850_LO16_SPLIT_OFFSET) - bfd_putl32 (((value << 16) & 0xfffe0000) - | ((value << 5) & 0x20) - | (bfd_getl32 (where) & ~0xfffe0020), where); - else if (fixP->fx_size == 1) - *where = value & 0xff; - else if (fixP->fx_size == 2) - bfd_putl16 (value & 0xffff, (unsigned char *) where); - else if (fixP->fx_size == 4) - bfd_putl32 (value, (unsigned char *) where); + case BFD_RELOC_32: + bfd_putl32 (value, (unsigned char *) where); + break; + + case BFD_RELOC_V850_23: + bfd_putl32 (((value & 0x7f) << 4) | ((value & 0x7fff80) << (16-7)) + | (bfd_getl32 (where) & ~((0x7f << 4) | (0xffff << 16))), + (unsigned char *) where); + break; + + case BFD_RELOC_16: + case BFD_RELOC_HI16: + case BFD_RELOC_HI16_S: + case BFD_RELOC_LO16: + case BFD_RELOC_V850_ZDA_16_16_OFFSET: + case BFD_RELOC_V850_SDA_16_16_OFFSET: + case BFD_RELOC_V850_TDA_16_16_OFFSET: + case BFD_RELOC_V850_CALLT_16_16_OFFSET: + bfd_putl16 (value & 0xffff, (unsigned char *) where); + break; + + case BFD_RELOC_8: + *where = value & 0xff; + break; + + case BFD_RELOC_V850_9_PCREL: + bfd_putl16 (((value & 0x1f0) << 7) | ((value & 0x0e) << 3) + | (bfd_getl16 (where) & ~((0x1f0 << 7) | (0x0e << 3))), where); + break; + + case BFD_RELOC_V850_17_PCREL: + bfd_putl32 (((value & 0x10000) >> (16 - 4)) | ((value & 0xfffe) << 16) + | (bfd_getl32 (where) & ~((0x10000 >> (16 - 4)) | (0xfffe << 16))), where); + break; + + + case BFD_RELOC_V850_16_PCREL: + bfd_putl16 (-value & 0xfffe, (unsigned char *) where); + break; + + case BFD_RELOC_V850_22_PCREL: + bfd_putl32 (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16) + | (bfd_getl32 (where) & ~((0xfffe << 16) | (0x3f0000 >> 16))), where); + break; + + case BFD_RELOC_V850_16_S1: + case BFD_RELOC_V850_LO16_S1: + case BFD_RELOC_V850_ZDA_15_16_OFFSET: + case BFD_RELOC_V850_SDA_15_16_OFFSET: + bfd_putl16 (value & 0xfffe, (unsigned char *) where); + break; + + case BFD_RELOC_V850_16_SPLIT_OFFSET: + case BFD_RELOC_V850_LO16_SPLIT_OFFSET: + case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET: + case BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET: + bfd_putl32 (((value << 16) & 0xfffe0000) + | ((value << 5) & 0x20) + | (bfd_getl32 (where) & ~0xfffe0020), where); + break; + + case BFD_RELOC_V850_TDA_6_8_OFFSET: + *where = (*where & ~0x7e) | ((value >> 1) & 0x7e); + break; + + case BFD_RELOC_V850_TDA_7_8_OFFSET: + *where = (*where & ~0x7f) | ((value >> 1) & 0x7f); + break; + + case BFD_RELOC_V850_TDA_7_7_OFFSET: + *where = (*where & ~0x7f) | (value & 0x7f); + break; + + case BFD_RELOC_V850_TDA_4_5_OFFSET: + *where = (*where & ~0xf) | ((value >> 1) & 0xf); + break; + + case BFD_RELOC_V850_TDA_4_4_OFFSET: + *where = (*where & ~0xf) | (value & 0xf); + break; + + case BFD_RELOC_V850_CALLT_6_7_OFFSET: + *where = (*where & ~0x3f) | (value & 0x3f); + break; + + default: + abort(); } } } @@ -2365,8 +3313,9 @@ md_apply_fix (fixS *fixP, valueT *valueP void parse_cons_expression_v850 (expressionS *exp) { + const char *errmsg; /* See if there's a reloc prefix like hi() we have to handle. */ - hold_cons_reloc = v850_reloc_prefix (NULL); + hold_cons_reloc = v850_reloc_prefix (NULL, &errmsg); /* Do normal expression parsing. */ expression (exp); @@ -2428,8 +3377,11 @@ v850_force_relocation (struct fix *fixP) if (v850_relax && (fixP->fx_pcrel || fixP->fx_r_type == BFD_RELOC_V850_ALIGN - || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL + || fixP->fx_r_type == BFD_RELOC_V850_16_PCREL + || fixP->fx_r_type == BFD_RELOC_V850_17_PCREL + || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL + || fixP->fx_r_type == BFD_RELOC_V850_32_PCREL || fixP->fx_r_type >= BFD_RELOC_UNUSED)) return 1; --- binutils-2.20/gas/configure.tgt 2009-09-09 13:43:28.000000000 +0530 +++ binutils-2.20/gas/configure.tgt 2010-05-17 19:40:25.563631849 +0530 @@ -402,7 +402,6 @@ case ${generic_target} in v850-*-*) fmt=elf ;; v850e-*-*) fmt=elf ;; - v850ea-*-*) fmt=elf ;; vax-*-netbsdelf*) fmt=elf em=nbsd ;; vax-*-linux-*) fmt=elf em=linux ;; --- binutils-2.20/include/elf/v850.h 2008-03-12 04:51:08.000000000 +0530 +++ binutils-2.20/include/elf/v850.h 2010-06-03 20:17:21.786633835 +0530 @@ -39,6 +39,12 @@ /* v850e1 code. */ #define E_V850E1_ARCH 0x20000000 +/* v850e2 code. */ +#define E_V850E2_ARCH 0x30000000 + +/* v850e2v3 code. */ +#define E_V850E2V3_ARCH 0x40000000 + /* Flags for the st_other field. */ #define V850_OTHER_SDA 0x10 /* Symbol had SDA relocations. */ @@ -50,36 +56,67 @@ #include "elf/reloc-macros.h" START_RELOC_NUMBERS (v850_reloc_type) - RELOC_NUMBER (R_V850_NONE, 0) - RELOC_NUMBER (R_V850_9_PCREL, 1) - RELOC_NUMBER (R_V850_22_PCREL, 2) - RELOC_NUMBER (R_V850_HI16_S, 3) - RELOC_NUMBER (R_V850_HI16, 4) - RELOC_NUMBER (R_V850_LO16, 5) - RELOC_NUMBER (R_V850_ABS32, 6) - RELOC_NUMBER (R_V850_16, 7) - RELOC_NUMBER (R_V850_8, 8) - RELOC_NUMBER( R_V850_SDA_16_16_OFFSET, 9) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */ - RELOC_NUMBER( R_V850_SDA_15_16_OFFSET, 10) /* For ld.w, ld.h, ld.hu, st.w, st.h */ - RELOC_NUMBER( R_V850_ZDA_16_16_OFFSET, 11) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */ - RELOC_NUMBER( R_V850_ZDA_15_16_OFFSET, 12) /* For ld.w, ld.h, ld.hu, st.w, st.h */ - RELOC_NUMBER( R_V850_TDA_6_8_OFFSET, 13) /* For sst.w, sld.w */ - RELOC_NUMBER( R_V850_TDA_7_8_OFFSET, 14) /* For sst.h, sld.h */ - RELOC_NUMBER( R_V850_TDA_7_7_OFFSET, 15) /* For sst.b, sld.b */ - RELOC_NUMBER( R_V850_TDA_16_16_OFFSET, 16) /* For set1, clr1, not1, tst1, movea, movhi */ - RELOC_NUMBER( R_V850_TDA_4_5_OFFSET, 17) /* For sld.hu */ - RELOC_NUMBER( R_V850_TDA_4_4_OFFSET, 18) /* For sld.bu */ - RELOC_NUMBER( R_V850_SDA_16_16_SPLIT_OFFSET, 19) /* For ld.bu */ - RELOC_NUMBER( R_V850_ZDA_16_16_SPLIT_OFFSET, 20) /* For ld.bu */ - RELOC_NUMBER( R_V850_CALLT_6_7_OFFSET, 21) /* For callt */ - RELOC_NUMBER( R_V850_CALLT_16_16_OFFSET, 22) /* For callt */ - RELOC_NUMBER (R_V850_GNU_VTINHERIT, 23) - RELOC_NUMBER (R_V850_GNU_VTENTRY, 24) - RELOC_NUMBER (R_V850_LONGCALL, 25) - RELOC_NUMBER (R_V850_LONGJUMP, 26) - RELOC_NUMBER (R_V850_ALIGN, 27) - RELOC_NUMBER (R_V850_REL32, 28) - RELOC_NUMBER (R_V850_LO16_SPLIT_OFFSET, 29) /* For ld.bu */ + RELOC_NUMBER (R_V850_NONE, 0) + RELOC_NUMBER (R_V850_8, 1) /* .byte */ + RELOC_NUMBER (R_V850_16, 2) /* .hword */ + RELOC_NUMBER (R_V850_32, 3) /* .word */ + + RELOC_NUMBER (R_V850_9_PCREL, 4) /* For br */ + RELOC_NUMBER (R_V850_16_PCREL, 5) /* For loop */ + RELOC_NUMBER (R_V850_17_PCREL, 6) /* For br */ + RELOC_NUMBER (R_V850_22_PCREL, 7) /* For jr */ + RELOC_NUMBER (R_V850_32_PCREL, 8) /* For jr32, jarl32 */ + RELOC_NUMBER (R_V850_32_ABS, 9) /* For jmp32 */ + + RELOC_NUMBER (R_V850_HI16, 10) /* For movhi */ + RELOC_NUMBER (R_V850_HI16_S, 11) /* For movhi */ + RELOC_NUMBER (R_V850_LO16, 12) /* For movea */ + RELOC_NUMBER (R_V850_LO16_S1, 13) /* For ld.w, ld.h st.w st.h */ + RELOC_NUMBER (R_V850_LO16_SPLIT_OFFSET, 14) /* For ld.bu */ + RELOC_NUMBER (R_V850_16_S1, 15) /* For ld.w, ld.h st.w st.h */ + RELOC_NUMBER (R_V850_16_SPLIT_OFFSET, 16) /* For ld.bu */ + RELOC_NUMBER (R_V850_23, 17) /* For 23bit ld.[w,h,hu,b,bu],st.[w,h,b] */ + + RELOC_NUMBER( R_V850_SDA_15_16_OFFSET, 18) /* For ld.w, ld.h, ld.hu, st.w, st.h */ + RELOC_NUMBER( R_V850_SDA_16_16_OFFSET, 19) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */ + RELOC_NUMBER( R_V850_SDA_16_16_SPLIT_OFFSET, 20) /* For ld.bu */ + + RELOC_NUMBER( R_V850_ZDA_15_16_OFFSET, 21) /* For ld.w, ld.h, ld.hu, st.w, st.h */ + RELOC_NUMBER( R_V850_ZDA_16_16_OFFSET, 22) /* For ld.b, st.b, set1, clr1, not1, tst1, movea, movhi */ + RELOC_NUMBER( R_V850_ZDA_16_16_SPLIT_OFFSET, 23) /* For ld.bu */ + + RELOC_NUMBER( R_V850_TDA_4_4_OFFSET, 24) /* For sld.bu */ + RELOC_NUMBER( R_V850_TDA_4_5_OFFSET, 25) /* For sld.hu */ + RELOC_NUMBER( R_V850_TDA_7_7_OFFSET, 26) /* For sst.b, sld.b */ + RELOC_NUMBER( R_V850_TDA_7_8_OFFSET, 27) /* For sst.h, sld.h */ + RELOC_NUMBER( R_V850_TDA_6_8_OFFSET, 28) /* For sst.w, sld.w */ + RELOC_NUMBER( R_V850_TDA_16_16_OFFSET, 29) /* For set1, clr1, not1, tst1, movea, movhi */ + + RELOC_NUMBER( R_V850_CALLT_6_7_OFFSET, 30) /* For callt */ + RELOC_NUMBER( R_V850_CALLT_15_16_OFFSET, 31) /* For ld.w, ld.h, ld.hu, st.w, st.h */ + RELOC_NUMBER( R_V850_CALLT_16_16_OFFSET, 32) /* For callt */ + + RELOC_NUMBER (R_V850_GNU_VTINHERIT, 33) + RELOC_NUMBER (R_V850_GNU_VTENTRY, 34) + + RELOC_NUMBER (R_V850_LONGCALL, 35) + RELOC_NUMBER (R_V850_LONGJUMP, 36) + RELOC_NUMBER (R_V850_ALIGN, 37) + RELOC_NUMBER (R_V850_CODE, 38) + RELOC_NUMBER (R_V850_DATA, 39) + + RELOC_NUMBER( R_V850_32_GOTPCREL, 40) /* GLOBAL_OFFSET_TABLE from pc */ + RELOC_NUMBER( R_V850_16_GOT, 41) /* GOT ENTRY from gp */ + RELOC_NUMBER( R_V850_32_GOT, 42) + RELOC_NUMBER( R_V850_22_PLT, 43) /* For jr */ + RELOC_NUMBER( R_V850_32_PLT, 44) /* For jr32 */ + RELOC_NUMBER( R_V850_COPY, 45) + RELOC_NUMBER( R_V850_GLOB_DAT, 46) + RELOC_NUMBER( R_V850_JMP_SLOT, 47) + RELOC_NUMBER( R_V850_RELATIVE, 48) + RELOC_NUMBER( R_V850_16_GOTOFF, 49) /* from gp */ + RELOC_NUMBER( R_V850_32_GOTOFF, 50) + END_RELOC_NUMBERS (R_V850_max) --- binutils-2.20/include/opcode/v850.h 2005-05-10 15:51:13.000000000 +0530 +++ binutils-2.20/include/opcode/v850.h 2010-06-04 11:12:43.287633795 +0530 @@ -54,13 +54,18 @@ struct v850_opcode }; /* Values for the processors field in the v850_opcode structure. */ +#define PROCESSOR_MASK 0x1f +#define PROCESSOR_OPTION_EXTENSION (1 << 5) /* enable extension opcodes */ +#define PROCESSOR_OPTION_ALIAS (1 << 6) /* enable alias opcodes */ #define PROCESSOR_V850 (1 << 0) /* Just the V850. */ -#define PROCESSOR_ALL -1 /* Any processor. */ +#define PROCESSOR_ALL PROCESSOR_MASK /* Any processor. */ #define PROCESSOR_V850E (1 << 1) /* Just the V850E. */ -#define PROCESSOR_NOT_V850 (~ PROCESSOR_V850) /* Any processor except the V850. */ -#define PROCESSOR_V850EA (1 << 2) /* Just the V850EA. */ -#define PROCESSOR_V850E1 (1 << 3) /* Just the V850E1. */ - +#define PROCESSOR_NOT_V850 (PROCESSOR_ALL & (~ PROCESSOR_V850)) /* Any processor except the V850. */ +#define PROCESSOR_V850E1 (1 << 2) /* Just the V850E1. */ +#define PROCESSOR_V850E2 (1 << 3) /* Just the V850E2. */ +#define PROCESSOR_V850E2V3 (1 << 4) /* Just the V850E2V3. */ +#define PROCESSOR_V850E2_ALL (PROCESSOR_V850E2 | PROCESSOR_V850E2V3) /* V850E2 & V850E2V3 */ +#define SET_PROCESSOR_MASK(mask,set) ((mask) = ((mask) & ~PROCESSOR_MASK) | (set)) /* The table itself is sorted by major opcode number, and is otherwise in the order in which the disassembler should consider instructions. */ @@ -119,6 +124,8 @@ struct v850_operand /* One bit syntax flags. */ int flags; + + int default_reloc; }; /* Elements in the table are retrieved by indexing with values from @@ -131,36 +138,69 @@ extern const struct v850_operand v850_op /* This operand names a general purpose register */ #define V850_OPERAND_REG 0x01 +/* This operand is the ep register. */ +#define V850_OPERAND_EP 0x02 + /* This operand names a system register */ -#define V850_OPERAND_SRG 0x02 +#define V850_OPERAND_SRG 0x04 + +/* prologue eilogue type instruction, V850E specific. */ +#define V850E_OPERAND_REG_LIST 0x08 /* This operand names a condition code used in the setf instruction */ -#define V850_OPERAND_CC 0x04 +#define V850_OPERAND_CC 0x10 -/* This operand takes signed values */ -#define V850_OPERAND_SIGNED 0x08 +#define V850_OPERAND_FLOAT_CC 0x20 -/* This operand is the ep register. */ -#define V850_OPERAND_EP 0x10 +/* This operand names a vector purpose register */ +#define V850_OPERAND_VREG 0x40 -/* This operand is a PC displacement */ -#define V850_OPERAND_DISP 0x20 +/* 16 bit immediate follows instruction, V850E specific. */ +#define V850E_IMMEDIATE16 0x80 + +/* hi16 bit immediate follows instruction, V850E specific. */ +#define V850E_IMMEDIATE16HI 0x100 + +/* 23 bit immediate follows instruction, V850E specific. */ +#define V850E_IMMEDIATE23 0x200 + +/* 32 bit immediate follows instruction, V850E specific. */ +#define V850E_IMMEDIATE32 0x400 /* This is a relaxable operand. Only used for D9->D22 branch relaxing right now. We may need others in the future (or maybe handle them like promoted operands on the mn10300?) */ -#define V850_OPERAND_RELAX 0x40 +#define V850_OPERAND_RELAX 0x800 + +/* This operand takes signed values */ +#define V850_OPERAND_SIGNED 0x1000 + +/* This operand is a displacement */ +#define V850_OPERAND_DISP 0x2000 + +/* This operand is a PC displacement */ +#define V850_PCREL 0x4000 + +/* The register specified must be even number */ +#define V850_REG_EVEN 0x8000 /* The register specified must not be r0 */ -#define V850_NOT_R0 0x80 +#define V850_NOT_R0 0x20000 -/* push/pop type instruction, V850E specific. */ -#define V850E_PUSH_POP 0x100 +/* The register specified must not be 0 */ +#define V850_NOT_IMM0 0x40000 -/* 16 bit immediate follows instruction, V850E specific. */ -#define V850E_IMMEDIATE16 0x200 +/* The condition code must not be SA CONDITION */ +#define V850_NOT_SA 0x80000 + +/* The operand has '!' prefix */ +#define V850_OPERAND_BANG 0x100000 + +/* The operand has '%' prefix */ +#define V850_OPERAND_PERCENT 0x200000 + +int +v850_msg_is_out_of_range(const char* msg); -/* 32 bit immediate follows instruction, V850E specific. */ -#define V850E_IMMEDIATE32 0x400 #endif /* V850_H */ --- binutils-2.20/ld/configure.tgt 2009-08-06 23:08:03.000000000 +0530 +++ binutils-2.20/ld/configure.tgt 2010-05-17 19:40:25.564632050 +0530 @@ -622,8 +622,7 @@ tic54x-*-* | c54x*-*-*) targ_emul=tic54x tic80-*-*) targ_emul=tic80coff ;; v850-*-*) targ_emul=v850 ;; -v850e-*-*) targ_emul=v850 ;; -v850ea-*-*) targ_emul=v850 +v850e-*-*) targ_emul=v850 ;; vax-dec-ultrix* | vax-dec-bsd*) targ_emul=vax ;; vax-*-netbsdelf*) targ_emul=elf32vax --- binutils-2.20/ld/testsuite/ld-auto-import/dll.c 2002-12-18 21:35:10.000000000 +0530 +++ binutils-2.20/ld/testsuite/ld-auto-import/dll.c 2010-05-17 19:40:25.564632050 +0530 @@ -1,20 +1,20 @@ -int var = 123; -int foo = 121; - -int var2[2]= { 123, 456 }; - -#include - -void -print_var (void) -{ - printf ("DLL sees var = %d\n", var); -} - -void -print_foo (void) -{ - printf ("DLL sees foo = %d\n", foo); -} - -void (* func_ptr)(void) = print_foo; +int var = 123; +int foo = 121; + +int var2[2]= { 123, 456 }; + +#include + +void +print_var (void) +{ + printf ("DLL sees var = %d\n", var); +} + +void +print_foo (void) +{ + printf ("DLL sees foo = %d\n", foo); +} + +void (* func_ptr)(void) = print_foo; --- binutils-2.20/opcodes/br.s 1970-01-01 05:30:00.000000000 +0530 +++ binutils-2.20/opcodes/br.s 2010-05-17 19:40:25.564632050 +0530 @@ -0,0 +1,2 @@ + br 0x4 + \ No newline at end of file --- binutils-2.20/opcodes/configure 2009-09-07 17:38:04.000000000 +0530 +++ binutils-2.20/opcodes/configure 2010-05-17 19:40:25.569632054 +0530 @@ -12358,7 +12358,6 @@ if test x${all_targets} = xfalse ; then bfd_tic80_arch) ta="$ta tic80-dis.lo tic80-opc.lo" ;; bfd_v850_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; bfd_v850e_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; - bfd_v850ea_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; bfd_vax_arch) ta="$ta vax-dis.lo" ;; bfd_w65_arch) ta="$ta w65-dis.lo" ;; bfd_we32k_arch) ;; --- binutils-2.20/opcodes/configure.in 2009-09-07 17:37:53.000000000 +0530 +++ binutils-2.20/opcodes/configure.in 2010-05-17 20:33:41.166633581 +0530 @@ -297,7 +297,6 @@ if test x${all_targets} = xfalse ; then bfd_tic80_arch) ta="$ta tic80-dis.lo tic80-opc.lo" ;; bfd_v850_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; bfd_v850e_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; - bfd_v850ea_arch) ta="$ta v850-opc.lo v850-dis.lo" ;; bfd_vax_arch) ta="$ta vax-dis.lo" ;; bfd_w65_arch) ta="$ta w65-dis.lo" ;; bfd_we32k_arch) ;; --- binutils-2.20/opcodes/v850-dis.c 2007-07-05 15:19:02.000000000 +0530 +++ binutils-2.20/opcodes/v850-dis.c 2010-05-17 19:40:25.571631855 +0530 @@ -33,40 +33,150 @@ static const char *const v850_reg_names[ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp" }; +static const char *const v850_vreg_names[] = +{ "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", + "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", + "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23", + "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31" }; + static const char *const v850_sreg_names[] = -{ "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7", - "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15", - "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23", - "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31", - "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23", - "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31" }; +{ "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid", "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0", + "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau", "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u", + "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l", "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l", + "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u", "fewr", "dbwr", "bsel" }; static const char *const v850_cc_names[] = { "v", "c/l", "z", "nh", "s/n", "t", "lt", "le", "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt" }; -static int -disassemble (bfd_vma memaddr, - struct disassemble_info * info, - unsigned long insn) +static const char *const v850_float_cc_names[] = +{ "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt", + "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt" }; + + + +static void +print_value(int flags, bfd_vma memaddr, struct disassemble_info *info, long value) { - struct v850_opcode * op = (struct v850_opcode *) v850_opcodes; - const struct v850_operand * operand; - int match = 0; - int short_op = ((insn & 0x0600) != 0x0600); - int bytes_read; - int target_processor; + if (flags & V850_PCREL) + { + bfd_vma addr = value + memaddr; + info->print_address_func (addr, info); + } + else if(flags & V850_OPERAND_DISP) + { + if(flags & V850_OPERAND_SIGNED) + { + info->fprintf_func (info->stream, "%ld", value); + } + else + { + info->fprintf_func (info->stream, "%lu", value); + } + } + else + { + if(flags & V850_OPERAND_SIGNED) + { + info->fprintf_func (info->stream, "%ld", value); + } + else + { + info->fprintf_func (info->stream, "%lu", value); + } + } +} - /* Special case: 32 bit MOV. */ - if ((insn & 0xffe0) == 0x0620) - short_op = 1; +static long +get_operand_value (const struct v850_operand *operand, unsigned long insn, int bytes_read, bfd_vma memaddr, struct disassemble_info * info, int noerror, int *invalid) +{ + long value; + bfd_byte buffer[4]; + + if ((operand->flags & V850E_IMMEDIATE16) + || (operand->flags & V850E_IMMEDIATE16HI)) + { + int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info); + + if (status == 0) + { + value = bfd_getl16 (buffer); - bytes_read = short_op ? 2 : 4; + if (operand->flags & V850E_IMMEDIATE16HI) + value <<= 16; - /* If this is a two byte insn, then mask off the high bits. */ - if (short_op) - insn &= 0xffff; + return value; + } + + if (!noerror) + info->memory_error_func (status, memaddr + bytes_read, info); + + return 0; + } + + if (operand->flags & V850E_IMMEDIATE23) + { + int status = info->read_memory_func (memaddr + 2, buffer, 4, info); + + if (status == 0) + { + value = bfd_getl32 (buffer); + + value = (operand->extract) (value, invalid); + + return value; + } + + if (!noerror) + info->memory_error_func (status, memaddr + bytes_read, info); + + return 0; + } + + if (operand->flags & V850E_IMMEDIATE32) + { + int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info); + + if (status == 0) + { + bytes_read += 4; + value = bfd_getl32 (buffer); + + return value; + } + + if (!noerror) + info->memory_error_func (status, memaddr + bytes_read, info); + + return 0; + } + + if (operand->extract) + value = (operand->extract) (insn, invalid); + else + { + if (operand->bits == -1) + value = (insn & operand->shift); + else + value = (insn >> operand->shift) & ((1 << operand->bits) - 1); + if (operand->flags & V850_OPERAND_SIGNED) + value = ((long)(value << (sizeof(long)*8 - operand->bits)) + >> (sizeof(long)*8 - operand->bits)); + } + + return value; +} + + +static int +disassemble (bfd_vma memaddr, struct disassemble_info *info, int bytes_read, unsigned long insn) +{ + struct v850_opcode *op = (struct v850_opcode *)v850_opcodes; + const struct v850_operand *operand; + int match = 0; + int target_processor; + switch (info->mach) { case 0: @@ -79,22 +189,66 @@ disassemble (bfd_vma memaddr, break; case bfd_mach_v850e1: - target_processor = PROCESSOR_V850E1; + target_processor = PROCESSOR_V850E; + break; + + case bfd_mach_v850e2: + target_processor = PROCESSOR_V850E2; + break; + + case bfd_mach_v850e2v3: + target_processor = PROCESSOR_V850E2V3; break; } + + /* If this is a two byte insn, then mask off the high bits. */ + if (bytes_read == 2) + insn &= 0xffff; /* Find the opcode. */ while (op->name) { if ((op->mask & insn) == op->opcode - && (op->processors & target_processor)) + && (op->processors & target_processor) + && !(op->processors & PROCESSOR_OPTION_ALIAS)) { + /* code check start */ const unsigned char *opindex_ptr; unsigned int opnum; unsigned int memop; + for (opindex_ptr = op->operands, opnum = 1; + *opindex_ptr != 0; + opindex_ptr++, opnum++) + { + int invalid = 0; + long value; + + operand = &v850_operands[*opindex_ptr]; + + value = get_operand_value (operand, insn, bytes_read, memaddr, info, 1, &invalid); + + if (invalid) + goto next_opcode; + + if ((operand->flags & V850_NOT_R0) && value == 0) + goto next_opcode; + + if ((operand->flags & V850_NOT_SA) && value == 0xd) + goto next_opcode; + + if ((operand->flags & V850_NOT_IMM0) && value == 0) + goto next_opcode; + } + + /* code check end */ + match = 1; (*info->fprintf_func) (info->stream, "%s\t", op->name); +#if 0 + fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n", + insn, op->mask, op->opcode, op->name ); +#endif memop = op->memop; /* Now print the operands. @@ -109,31 +263,18 @@ disassemble (bfd_vma memaddr, insert commas into the output stream as well as when to insert disp[reg] expressions onto the output stream. */ - + for (opindex_ptr = op->operands, opnum = 1; *opindex_ptr != 0; opindex_ptr++, opnum++) { long value; int flag; - int status; - bfd_byte buffer[4]; - + char *prefix; + operand = &v850_operands[*opindex_ptr]; - - if (operand->extract) - value = (operand->extract) (insn, 0); - else - { - if (operand->bits == -1) - value = (insn & operand->shift); - else - value = (insn >> operand->shift) & ((1 << operand->bits) - 1); - - if (operand->flags & V850_OPERAND_SIGNED) - value = ((long)(value << (32 - operand->bits)) - >> (32 - operand->bits)); - } + + value = get_operand_value (operand, insn, bytes_read, memaddr, info, 0, 0); /* The first operand is always output without any special handling. @@ -151,94 +292,67 @@ disassemble (bfd_vma memaddr, Else we just need a comma. We may need to output a trailing ']' if the last operand - in an instruction is the register for a memory address. + in an instruction is the register for a memory address. The exception (and there's always an exception) is the "jmp" insn which needs square brackets around it's only register argument. */ + prefix = ""; + if (operand->flags & V850_OPERAND_BANG) + { + prefix = "!"; + } + else if (operand->flags & V850_OPERAND_PERCENT) + { + prefix = "%"; + } - if (memop && opnum == memop + 1) - info->fprintf_func (info->stream, "["); - else if (memop && opnum == memop + 2) - info->fprintf_func (info->stream, "],"); - else if (memop == 1 && opnum == 1 - && (operand->flags & V850_OPERAND_REG)) - info->fprintf_func (info->stream, "["); - else if (opnum > 1) - info->fprintf_func (info->stream, ", "); - - /* Extract the flags, ignorng ones which - do not effect disassembly output. */ - flag = operand->flags; - flag &= ~ V850_OPERAND_SIGNED; - flag &= ~ V850_OPERAND_RELAX; - flag &= - flag; - + if (opnum == 1 && opnum == memop) + info->fprintf_func (info->stream, "%s[", prefix); + else if (opnum > 1 + && (v850_operands[*(opindex_ptr - 1)].flags & V850_OPERAND_DISP) != 0 + && opnum == memop) + info->fprintf_func (info->stream, "%s[", prefix); + else if (opnum == memop) + info->fprintf_func (info->stream, ", %s[", prefix); + else if (opnum > 1) + info->fprintf_func (info->stream, ", %s", prefix); + + /* extract the flags, ignorng ones which do not effect disassembly output. */ + flag = operand->flags & (V850_OPERAND_REG + | V850_REG_EVEN + | V850_OPERAND_EP + | V850_OPERAND_VREG + | V850_OPERAND_SRG + | V850E_OPERAND_REG_LIST + | V850_OPERAND_CC + | V850_OPERAND_FLOAT_CC); + switch (flag) { - case V850_OPERAND_REG: - info->fprintf_func (info->stream, "%s", v850_reg_names[value]); - break; - case V850_OPERAND_SRG: - info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); - break; - case V850_OPERAND_CC: - info->fprintf_func (info->stream, "%s", v850_cc_names[value]); - break; - case V850_OPERAND_EP: - info->fprintf_func (info->stream, "ep"); - break; - default: - info->fprintf_func (info->stream, "%ld", value); - break; - case V850_OPERAND_DISP: - { - bfd_vma addr = value + memaddr; + case V850_OPERAND_REG: info->fprintf_func (info->stream, "%s", v850_reg_names[value]); break; + case (V850_OPERAND_REG|V850_REG_EVEN): info->fprintf_func (info->stream, "%s", v850_reg_names[value*2]); break; + case V850_OPERAND_EP: info->fprintf_func (info->stream, "ep"); break; + case V850_OPERAND_VREG: info->fprintf_func (info->stream, "%s", v850_vreg_names[value]); break; + case V850_OPERAND_SRG: info->fprintf_func (info->stream, "%s", v850_sreg_names[value]); break; - /* On the v850 the top 8 bits of an address are used by an - overlay manager. Thus it may happen that when we are - looking for a symbol to match against an address with - some of its top bits set, the search fails to turn up an - exact match. In this case we try to find an exact match - against a symbol in the lower address space, and if we - find one, we use that address. We only do this for - JARL instructions however, as we do not want to - misinterpret branch instructions. */ - if (operand->bits == 22) - { - if ( ! info->symbol_at_address_func (addr, info) - && ((addr & 0xFF000000) != 0) - && info->symbol_at_address_func (addr & 0x00FFFFFF, info)) - addr &= 0x00FFFFFF; - } - info->print_address_func (addr, info); - break; - } - - case V850E_PUSH_POP: + case V850E_OPERAND_REG_LIST: { - static int list12_regs[32] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 }; - static int list18_h_regs[32] = { 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 }; - static int list18_l_regs[32] = { 3, 2, 1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8 }; + static int list12_regs[32] = { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 }; int *regs; int i; unsigned long int mask = 0; int pc = 0; - int sr = 0; - + + switch (operand->shift) { case 0xffe00001: regs = list12_regs; break; - case 0xfff8000f: regs = list18_h_regs; break; - case 0xfff8001f: - regs = list18_l_regs; - value &= ~0x10; /* Do not include magic bit. */ - break; default: /* xgettext:c-format */ - fprintf (stderr, _("unknown operand shift: %x\n"), - operand->shift); - abort (); + fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift ); + abort(); } for (i = 0; i < 32; i++) @@ -249,24 +363,21 @@ disassemble (bfd_vma memaddr, { default: mask |= (1 << regs[ i ]); break; /* xgettext:c-format */ - case 0: - fprintf (stderr, _("unknown pop reg: %d\n"), i ); - abort (); + case 0: fprintf (stderr, _("unknown reg: %d\n"), i ); abort(); case -1: pc = 1; break; - case -2: sr = 1; break; } } } info->fprintf_func (info->stream, "{"); - - if (mask || pc || sr) + + if (mask || pc) { if (mask) { unsigned int bit; int shown_one = 0; - + for (bit = 0; bit < 32; bit++) if (mask & (1 << bit)) { @@ -277,10 +388,9 @@ disassemble (bfd_vma memaddr, info->fprintf_func (info->stream, ", "); else shown_one = 1; - - info->fprintf_func (info->stream, - v850_reg_names[first]); - + + info->fprintf_func (info->stream, v850_reg_names[first]); + for (bit++; bit < 32; bit++) if ((mask & (1 << bit)) == 0) break; @@ -288,113 +398,228 @@ disassemble (bfd_vma memaddr, last = bit; if (last > first + 1) - info->fprintf_func (info->stream, " - %s", - v850_reg_names[last - 1]); + { + info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]); + } } } - + if (pc) info->fprintf_func (info->stream, "%sPC", mask ? ", " : ""); - if (sr) - info->fprintf_func (info->stream, "%sSR", (mask || pc) ? ", " : ""); } - + info->fprintf_func (info->stream, "}"); } - break; - - case V850E_IMMEDIATE16: - status = info->read_memory_func (memaddr + bytes_read, - buffer, 2, info); - if (status == 0) - { - bytes_read += 2; - value = bfd_getl16 (buffer); - - /* If this is a DISPOSE instruction with ff - set to 0x10, then shift value up by 16. */ - if ((insn & 0x001fffc0) == 0x00130780) - value <<= 16; - - info->fprintf_func (info->stream, "0x%lx", value); - } - else - info->memory_error_func (status, memaddr + bytes_read, - info); break; + + case V850_OPERAND_CC: info->fprintf_func (info->stream, "%s", v850_cc_names[value]); break; + case V850_OPERAND_FLOAT_CC: info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]); break; - case V850E_IMMEDIATE32: - status = info->read_memory_func (memaddr + bytes_read, - buffer, 4, info); - if (status == 0) - { - bytes_read += 4; - value = bfd_getl32 (buffer); - info->fprintf_func (info->stream, "0x%lx", value); - } - else - info->memory_error_func (status, memaddr + bytes_read, - info); + default: + print_value(operand->flags, memaddr, info, value); break; - } + } - /* Handle jmp correctly. */ - if (memop == 1 && opnum == 1 - && ((operand->flags & V850_OPERAND_REG) != 0)) + if (memop && opnum == memop) (*info->fprintf_func) (info->stream, "]"); } - /* Close any square bracket we left open. */ - if (memop && opnum == memop + 2) - (*info->fprintf_func) (info->stream, "]"); - /* All done. */ break; } + next_opcode: op++; } - if (!match) - { - if (short_op) - info->fprintf_func (info->stream, ".short\t0x%04lx", insn); - else - info->fprintf_func (info->stream, ".long\t0x%08lx", insn); - } - - return bytes_read; + return match; } -int +int print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info) { - int status; - bfd_byte buffer[4]; - unsigned long insn = 0; + int status, status2, match; + bfd_byte buffer[8]; + int length = 0, code_length = 0; + unsigned long insn = 0, insn2 = 0; + int target_processor; + + switch (info->mach) + { + case 0: + default: + target_processor = PROCESSOR_V850; + break; + + case bfd_mach_v850e: + target_processor = PROCESSOR_V850E; + break; + + case bfd_mach_v850e1: + target_processor = PROCESSOR_V850E; + break; + + case bfd_mach_v850e2: + target_processor = PROCESSOR_V850E2; + break; + + case bfd_mach_v850e2v3: + target_processor = PROCESSOR_V850E2V3; + break; + } + - /* First figure out how big the opcode is. */ status = info->read_memory_func (memaddr, buffer, 2, info); - if (status == 0) + + if (status) + { + info->memory_error_func (status, memaddr, info); + return -1; + } + + insn = bfd_getl16 (buffer); + + status2 = info->read_memory_func (memaddr+2, buffer, 2 , info); + + if (!status2) { - insn = bfd_getl16 (buffer); + insn2 = bfd_getl16 (buffer); + /* fprintf(stderr, "insn2 0x%08lx\n", insn2); */ + } - if ( (insn & 0x0600) == 0x0600 - && (insn & 0xffe0) != 0x0620) + /* Special case */ + if (length == 0 + && (target_processor == PROCESSOR_V850E2 + || target_processor == PROCESSOR_V850E2V3)) + { + if ((insn & 0xffff) == 0x02e0 /* jr 32bit */ + && !status2 && (insn2 & 0x1) == 0) + { + length = 2; + code_length = 6; + } + else if ((insn & 0xffe0) == 0x02e0 /* jarl 32bit */ + && !status2 && (insn2 & 0x1) == 0) + { + length = 2; + code_length = 6; + } + else if ((insn & 0xffe0) == 0x06e0 /* jmp 32bit */ + && !status2 && (insn2 & 0x1) == 0) { - /* If this is a 4 byte insn, read 4 bytes of stuff. */ - status = info->read_memory_func (memaddr, buffer, 4, info); + length = 2; + code_length = 6; + } + } - if (status == 0) - insn = bfd_getl32 (buffer); + if (length == 0 + && target_processor == PROCESSOR_V850E2V3) + { + if (((insn & 0xffe0) == 0x0780 /* ld.b 23bit */ + && !status2 && (insn2 & 0x000f) == 0x0005) + || ((insn & 0xffe0) == 0x07a0 /* ld.bu 23bit */ + && !status2 && (insn2 & 0x000f) == 0x0005) + || ((insn & 0xffe0) == 0x0780 /* ld.h 23bit */ + && !status2 && (insn2 & 0x000f) == 0x0007) + || ((insn & 0xffe0) == 0x07a0 /* ld.hu 23bit */ + && !status2 && (insn2 & 0x000f) == 0x0007) + || ((insn & 0xffe0) == 0x0780 /* ld.w 23bit */ + && !status2 && (insn2 & 0x000f) == 0x0009)) + { + length = 4; + code_length = 6; + } + else if(((insn & 0xffe0) == 0x0780 /* st.b 23bit */ + && !status2 && (insn2 & 0x000f) == 0x000d) + || ((insn & 0xffe0) == 0x07a0 /* st.h 23bit */ + && !status2 && (insn2 & 0x000f) == 0x000d) + || ((insn & 0xffe0) == 0x0780 /* st.w 23bit */ + && !status2 && (insn2 & 0x000f) == 0x000f)) + { + length = 4; + code_length = 6; } } - if (status != 0) + if (length == 0 + && target_processor != PROCESSOR_V850) { - info->memory_error_func (status, memaddr, info); - return -1; + if ((insn & 0xffe0) == 0x0620) /* 32 bit MOV */ + { + length = 2; + code_length = 6; + } + else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16<<16 */ + && !status2 && (insn2 & 0x001f) == 0x0013) + { + length = 4; + code_length = 6; + } + else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16 */ + && !status2 && (insn2 & 0x001f) == 0x000b) + { + length = 4; + code_length = 6; + } + else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm32 */ + && !status2 && (insn2 & 0x001f) == 0x001b) + { + length = 4; + code_length = 8; + } + } + + if (length == 4 + || (length == 0 + && (insn & 0x0600) == 0x0600)) + { + /* this is a 4 byte insn */ + status = info->read_memory_func (memaddr, buffer, 4, info); + if (!status) + { + insn = bfd_getl32 (buffer); + + if (!length) + length = code_length = 4; + } + } + + if(code_length > length) + { + status = info->read_memory_func (memaddr + length, buffer, code_length - length, info); + if (status) + length = 0; + } + + if(length == 0 && !status) + length = code_length = 2; + + if (length == 2) + insn &= 0xffff; + + match = disassemble (memaddr, info, length, insn); + + if (!match) + { + int l = 0; + + status = info->read_memory_func (memaddr, buffer, code_length, info); + + while (l < code_length) + { + if (code_length - l == 2) + { + insn = bfd_getl16 (buffer + l) & 0xffff; + info->fprintf_func (info->stream, ".short\t0x%04lx", insn); + l += 2; + } + else + { + insn = bfd_getl32 (buffer + l); + info->fprintf_func (info->stream, ".long\t0x%08lx", insn); + l += 4; + } + } } - /* Make sure we tell our caller how many bytes we consumed. */ - return disassemble (memaddr, info, insn); + return code_length; } --- binutils-2.20/opcodes/v850-opc.c 2007-07-05 15:19:02.000000000 +0530 +++ binutils-2.20/opcodes/v850-opc.c 2010-06-04 11:26:18.934633752 +0530 @@ -19,24 +19,31 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include "sysdep.h" #include "opcode/v850.h" -#include +#include "bfd.h" #include "opintl.h" + /* Regular opcodes. */ #define OP(x) ((x & 0x3f) << 5) #define OP_MASK OP (0x3f) -/* Conditional branch opcodes. */ -#define BOP(x) ((0x0b << 7) | (x & 0x0f)) -#define BOP_MASK ((0x0f << 7) | 0x0f) +/* Conditional branch opcodes (Format III). */ +#define BOP(x) ((0x58 << 4) | (x & 0x0f)) +#define BOP_MASK ((0x78 << 4) | 0x0f) + +/* Conditional branch opcodes (Format VII). */ +#define BOP7(x) (0x107e0 | (x & 0xf)) +#define BOP7_MASK (0x1ffe0 | 0xf) /* One-word opcodes. */ #define one(x) ((unsigned int) (x)) /* Two-word opcodes. */ #define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16)) + /* The functions used to insert and extract complicated operands. */ @@ -50,106 +57,134 @@ static const char * out_of_range = N_ (" static const char * not_aligned = N_ ("displacement value is not aligned"); static const char * immediate_out_of_range = N_ ("immediate value is out of range"); +static const char * branch_out_of_range = N_ ("branch value out of range"); +static const char * branch_out_of_range_and_odd_offset = N_ ("branch value not in range and to odd offset"); +static const char * branch_to_odd_offset = N_ ("branch to odd offset"); + + +int +v850_msg_is_out_of_range(const char* msg) +{ + return msg == out_of_range + || msg == immediate_out_of_range + || msg == branch_out_of_range; +} static unsigned long -insert_d9 (unsigned long insn, long value, const char ** errmsg) +insert_i5div1 (unsigned long insn, long value, const char ** errmsg) { - if (value > 0xff || value < -0x100) + if (value > 30 || value < 2) { - if ((value % 2) != 0) - * errmsg = _("branch value not in range and to odd offset"); + if (value & 1) + * errmsg = _(not_valid); else - * errmsg = _("branch value out of range"); + * errmsg = _(out_of_range); } - else if ((value % 2) != 0) - * errmsg = _("branch to odd offset"); + else if (value & 1) + * errmsg = _(not_aligned); - return insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3); + value = (32 - value)/2; + + return (insn | ((value << (2+16)) & 0x3c0000)); } static unsigned long -extract_d9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_i5div1 (unsigned long insn, int * invalid) { - unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3); - - if ((insn & 0x8000) != 0) - ret -= 0x0200; + unsigned long ret = (insn & 0x003c0000) >> (16+2); + ret = 32 - (ret * 2); + if (invalid != 0) + *invalid = (ret > 30 || ret < 2) ? 1 : 0; return ret; } static unsigned long -insert_d22 (unsigned long insn, long value, const char ** errmsg) +insert_i5div2 (unsigned long insn, long value, const char ** errmsg) { - if (value > 0x1fffff || value < -0x200000) + if (value > 30 || value < 4) { - if ((value % 2) != 0) - * errmsg = _("branch value not in range and to an odd offset"); + if (value & 1) + * errmsg = _(not_valid); else - * errmsg = _("branch value out of range"); + * errmsg = _(out_of_range); } - else if ((value % 2) != 0) - * errmsg = _("branch to odd offset"); + else if (value & 1) + * errmsg = _(not_aligned); - return insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16); + value = (32 - value)/2; + + return (insn | ((value << (2+16)) & 0x3c0000)); } static unsigned long -extract_d22 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_i5div2 (unsigned long insn, int * invalid) { - signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16); + unsigned long ret = (insn & 0x003c0000) >> (16+2); + ret = 32 - (ret * 2); - return (unsigned long) ((ret << 10) >> 10); + if (invalid != 0) + *invalid = (ret > 30 || ret < 4) ? 1 : 0; + return ret; } static unsigned long -insert_d16_15 (unsigned long insn, long value, const char ** errmsg) +insert_i5div3 (unsigned long insn, long value, const char ** errmsg) { - if (value > 0x7fff || value < -0x8000) + if (value > 32 || value < 2) { - if ((value % 2) != 0) + if (value & 1) * errmsg = _(not_valid); else * errmsg = _(out_of_range); } - else if ((value % 2) != 0) + else if (value & 1) * errmsg = _(not_aligned); - return insn | ((value & 0xfffe) << 16); + value = (32 - value)/2; + + return (insn | ((value << (2+16)) & 0x3c0000)); } static unsigned long -extract_d16_15 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_i5div3 (unsigned long insn, int * invalid) { - signed long ret = (insn & 0xfffe0000); + unsigned long ret = (insn & 0x003c0000) >> (16+2); + ret = 32 - (ret * 2); - return ret >> 16; + if (invalid != 0) + *invalid = (ret > 32 || ret < 2) ? 1 : 0; + return ret; } static unsigned long -insert_d8_7 (unsigned long insn, long value, const char ** errmsg) +insert_d5_4 (unsigned long insn, long value, const char ** errmsg) { - if (value > 0xff || value < 0) + if (value > 0x1f || value < 0) { - if ((value % 2) != 0) + if (value & 1) * errmsg = _(not_valid); else * errmsg = _(out_of_range); } - else if ((value % 2) != 0) + else if (value & 1) * errmsg = _(not_aligned); value >>= 1; - return insn | (value & 0x7f); + return insn | (value & 0x0f); } static unsigned long -extract_d8_7 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_d5_4 (unsigned long insn, int * invalid) { - unsigned long ret = (insn & 0x7f); + unsigned long ret = (insn & 0x0f); + + ret <<= 1; - return ret << 1; + if (invalid != 0) + *invalid = 0; + return ret; } static unsigned long @@ -158,7 +193,7 @@ insert_d8_6 (unsigned long insn, long va if (value > 0xff || value < 0) { if ((value % 4) != 0) - *errmsg = _(not_valid); + * errmsg = _(not_valid); else * errmsg = _(out_of_range); } @@ -171,37 +206,147 @@ insert_d8_6 (unsigned long insn, long va } static unsigned long -extract_d8_6 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_d8_6 (unsigned long insn, int * invalid) { unsigned long ret = (insn & 0x7e); - return ret << 1; + ret <<= 1; + + if (invalid != 0) + *invalid = 0; + return ret; } static unsigned long -insert_d5_4 (unsigned long insn, long value, const char ** errmsg) +insert_d8_7 (unsigned long insn, long value, const char ** errmsg) { - if (value > 0x1f || value < 0) + if (value > 0xff || value < 0) { - if (value & 1) + if ((value % 2) != 0) * errmsg = _(not_valid); else - *errmsg = _(out_of_range); + * errmsg = _(out_of_range); } - else if (value & 1) + else if ((value % 2) != 0) * errmsg = _(not_aligned); value >>= 1; - return insn | (value & 0x0f); + return insn | (value & 0x7f); } static unsigned long -extract_d5_4 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_d8_7 (unsigned long insn, int * invalid) { - unsigned long ret = (insn & 0x0f); + unsigned long ret = (insn & 0x7f); + + ret <<= 1; + + if (invalid != 0) + *invalid = 0; + return ret; +} + +static unsigned long +insert_v8 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0xff || value < 0) + * errmsg = _(immediate_out_of_range); + + return insn | (value & 0x1f) | ((value & 0xe0) << (27-5)); +} + +static unsigned long +extract_v8 (unsigned long insn, int * invalid) +{ + unsigned long ret = (insn & 0x1f) | ((insn & 0x38000000) >> (27-5)); + + if (invalid != 0) + *invalid = 0; + return ret; +} + +static unsigned long +insert_d9 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0xff || value < -0x100) + { + if ((value % 2) != 0) + * errmsg = branch_out_of_range_and_odd_offset; + else + * errmsg = branch_out_of_range; + } + else if ((value % 2) != 0) + * errmsg = branch_to_odd_offset; + + return insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3); +} + +static unsigned long +extract_d9 (unsigned long insn, int * invalid) +{ + unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3); + + if ((insn & 0x8000) != 0) + ret -= 0x0200; + + if (invalid != 0) + *invalid = 0; + return ret; +} + +static unsigned long +insert_u16_loop (unsigned long insn, long value, const char ** errmsg) +{ + if (value < -0xffff || value > 0) + { + if ((value % 2) != 0) + * errmsg = branch_out_of_range_and_odd_offset; + else + * errmsg = branch_out_of_range; + } + else if ((value % 2) != 0) + * errmsg = branch_to_odd_offset; + + return insn | ((-value & 0xfffe) << 16); +} + +static unsigned long +extract_u16_loop (unsigned long insn, int * invalid) +{ + long ret = (insn >> 16) & 0xfffe; + ret = -ret; + + if (invalid != 0) + *invalid = 0; + return ret; +} + +static unsigned long +insert_d16_15 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0x7fff || value < -0x8000) + { + if ((value % 2) != 0) + * errmsg = _(not_valid); + else + * errmsg = _(out_of_range); + } + else if ((value % 2) != 0) + * errmsg = _(not_aligned); + + return insn | ((value & 0xfffe) << 16); +} + +static unsigned long +extract_d16_15 (unsigned long insn, int * invalid) +{ + signed long ret = (insn & 0xfffe0000); + ret >>= 16; - return ret << 1; + if (invalid != 0) + *invalid = 0; + return ret; } static unsigned long @@ -214,18 +359,88 @@ insert_d16_16 (unsigned long insn, signe } static unsigned long -extract_d16_16 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_d16_16 (unsigned long insn, int * invalid) { signed long ret = insn & 0xfffe0000; - ret >>= 16; - ret |= ((insn & 0x20) >> 5); + if (invalid != 0) + *invalid = 0; return ret; } static unsigned long +insert_d17_16 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0xffff || value < -0x10000) + * errmsg = _(out_of_range); + + return insn | ((value & 0xfffe) << 16) | ((value & 0x10000) >> (16 - 4)); +} + +static unsigned long +extract_d17_16 (unsigned long insn, int * invalid) +{ + signed long ret = (insn >> 16) & 0xfffe; + ret |= (insn << (16 - 4)) & 0x10000; + ret = (ret << ((sizeof ret)*8 - 17)) >> ((sizeof ret)*8 - 17); + + if (invalid != 0) + *invalid = 0; + return (unsigned long)ret; +} + +static unsigned long +insert_d22 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0x1fffff || value < -0x200000) + { + if ((value % 2) != 0) + * errmsg = branch_out_of_range_and_odd_offset; + else + * errmsg = branch_out_of_range; + } + else if ((value % 2) != 0) + * errmsg = branch_to_odd_offset; + + return insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16); +} + +static unsigned long +extract_d22 (unsigned long insn, int * invalid) +{ + signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16); + + ret = (ret << ((sizeof ret)*8 - 22)) >> ((sizeof ret)*8 - 22); + + if (invalid != 0) + *invalid = 0; + return (unsigned long) ret; +} + +static unsigned long +insert_d23 (unsigned long insn, long value, const char ** errmsg) +{ + if (value > 0x3fffff || value < -0x400000) + * errmsg = out_of_range; + + return insn | ((value & 0x7f) << 4) | ((value & 0x7fff80) << (16-7)); +} + +static unsigned long +extract_d23 (unsigned long insn, int * invalid) +{ + signed long ret = ((insn >> 4) & 0x7f) | ((insn >> (16-7)) & 0x7fffff80); + + ret = ((ret << ((sizeof ret)*8 - 23)) >> ((sizeof ret)*8 - 23)); + + if (invalid != 0) + *invalid = 0; + return (unsigned long) ret; +} + +static unsigned long insert_i9 (unsigned long insn, signed long value, const char ** errmsg) { if (value > 0xff || value < -0x100) @@ -235,15 +450,16 @@ insert_i9 (unsigned long insn, signed lo } static unsigned long -extract_i9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_i9 (unsigned long insn, int * invalid) { signed long ret = insn & 0x003c0000; ret <<= 10; ret >>= 23; - ret |= (insn & 0x1f); + if (invalid != 0) + *invalid = 0; return ret; } @@ -259,7 +475,7 @@ insert_u9 (unsigned long insn, long v, c } static unsigned long -extract_u9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_u9 (unsigned long insn, int * invalid) { unsigned long ret = insn & 0x003c0000; @@ -267,6 +483,8 @@ extract_u9 (unsigned long insn, int * in ret |= (insn & 0x1f); + if (invalid != 0) + *invalid = 0; return ret; } @@ -282,44 +500,40 @@ insert_spe (unsigned long insn, long v, } static unsigned long -extract_spe (unsigned long insn ATTRIBUTE_UNUSED, - int * invalid ATTRIBUTE_UNUSED) +extract_spe (unsigned long insn ATTRIBUTE_UNUSED, int * invalid) { + if (invalid != 0) + *invalid = 0; + return 3; } static unsigned long -insert_i5div (unsigned long insn, long v, const char ** errmsg) +insert_r4 (unsigned long insn, long v, const char ** errmsg) { unsigned long value = (unsigned long) v; - if (value > 0x1ff) + if (value >= 32) { - if (value & 1) - * errmsg = _("immediate value not in range and not even"); - else - * errmsg = _(immediate_out_of_range); + * errmsg = _("invalid register name"); } - else if (value & 1) - * errmsg = _("immediate value must be even"); - - value = 32 - value; - - return insn | ((value & 0x1e) << 17); + + return insn | ((value & 0x10) << (23-4)) | ((value & 0x0f) << (17)); } static unsigned long -extract_i5div (unsigned long insn, int * invalid ATTRIBUTE_UNUSED) +extract_r4 (unsigned long insn, int * invalid) { - unsigned long ret = insn & 0x3c0000; - - ret >>= 17; - - ret = 32 - ret; - + unsigned long ret; + ret = (insn >> 17) & 0xf; + ret |= (insn >> (23-4)) & 0x10; + + if (invalid != 0) + *invalid = 0; return ret; } + /* Warning: code in gas/config/tc-v850.c examines the contents of this array. If you change any of the values here, be sure to look for side effects in @@ -327,158 +541,285 @@ extract_i5div (unsigned long insn, int * const struct v850_operand v850_operands[] = { #define UNUSED 0 - { 0, 0, NULL, NULL, 0 }, + { 0, 0, NULL, NULL, 0, BFD_RELOC_NONE }, -/* The R1 field in a format 1, 6, 7, or 9 insn. */ +/* The R1 field in a format 1, 6, 7, 9, C insn. */ #define R1 (UNUSED + 1) - { 5, 0, NULL, NULL, V850_OPERAND_REG }, + { 5, 0, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE }, /* As above, but register 0 is not allowed. */ #define R1_NOTR0 (R1 + 1) - { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, + { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE }, -/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */ -#define R2 (R1_NOTR0 + 1) - { 5, 11, NULL, NULL, V850_OPERAND_REG }, +/* Even register is allowed. */ +#define R1_EVEN (R1_NOTR0 + 1) + { 4, 1, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE }, + +/* Bang(bit reverse) */ +#define R1_BANG (R1_EVEN + 1) + { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_OPERAND_BANG, BFD_RELOC_NONE }, + +/* Percent(modulo) */ +#define R1_PERCENT (R1_BANG + 1) + { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_OPERAND_PERCENT, BFD_RELOC_NONE }, + +/* The R2 field in a format 1, 2, 4, 5, 6, 7, 9, C insn. */ +#define R2 (R1_PERCENT + 1) + { 5, 11, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE }, /* As above, but register 0 is not allowed. */ #define R2_NOTR0 (R2 + 1) - { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, + { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE }, -/* The imm5 field in a format 2 insn. */ -#define I5 (R2_NOTR0 + 1) - { 5, 0, NULL, NULL, V850_OPERAND_SIGNED }, - -/* The unsigned imm5 field in a format 2 insn. */ -#define I5U (I5 + 1) - { 5, 0, NULL, NULL, 0 }, - -/* The imm16 field in a format 6 insn. */ -#define I16 (I5U + 1) - { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, - -/* The signed disp7 field in a format 4 insn. */ -#define D7 (I16 + 1) - { 7, 0, NULL, NULL, 0}, - -/* The disp16 field in a format 6 insn. */ -#define D16_15 (D7 + 1) - { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED }, +/* Even register is allowed. */ +#define R2_EVEN (R2_NOTR0 + 1) + { 4, 12, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE }, + +/* Reg2 in dispose instruction. */ +#define R2_DISPOSE (R2_EVEN + 1) + { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE }, + +/* The R3 field in a format 11, 12, C insn. */ +#define R3 (R2_DISPOSE + 1) + { 5, 27, NULL, NULL, V850_OPERAND_REG, BFD_RELOC_NONE }, -/* The 3 bit immediate field in format 8 insn. */ -#define B3 (D16_15 + 1) - { 3, 11, NULL, NULL, 0 }, +/* As above, but register 0 is not allowed. */ +#define R3_NOTR0 (R3 + 1) + { 5, 27, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0, BFD_RELOC_NONE }, -/* The 4 bit condition code in a setf instruction */ -#define CCCC (B3 + 1) - { 4, 0, NULL, NULL, V850_OPERAND_CC }, +/* As above, but odd number registers are not allowed. */ +#define R3_EVEN (R3_NOTR0 + 1) + { 4, 28, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE }, -/* The unsigned DISP8 field in a format 4 insn. */ -#define D8_7 (CCCC + 1) - { 7, 0, insert_d8_7, extract_d8_7, 0 }, - -/* The unsigned DISP8 field in a format 4 insn. */ -#define D8_6 (D8_7 + 1) - { 6, 1, insert_d8_6, extract_d8_6, 0 }, +/* As above, but register 0 is not allowed. */ +#define R3_EVEN_NOTR0 (R3_EVEN + 1) + { 4, 28, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN | V850_NOT_R0, BFD_RELOC_NONE }, -/* System register operands. */ -#define SR1 (D8_6 + 1) - { 5, 0, NULL, NULL, V850_OPERAND_SRG }, +/* Forth register in FPU Instruction. */ +#define R4 (R3_EVEN_NOTR0 + 1) + { 5, 0, insert_r4, extract_r4, V850_OPERAND_REG, BFD_RELOC_NONE }, + +/* As above, but odd number registers are not allowed. */ +#define R4_EVEN (R4 + 1) + { 4, 17, NULL, NULL, V850_OPERAND_REG | V850_REG_EVEN, BFD_RELOC_NONE }, + +/* Stack pointer in prepare instruction. */ +#define SP (R4_EVEN + 1) + { 2, 0, insert_spe, extract_spe, V850_OPERAND_REG, BFD_RELOC_NONE }, /* EP Register. */ -#define EP (SR1 + 1) - { 0, 0, NULL, NULL, V850_OPERAND_EP }, +#define EP (SP + 1) + { 0, 0, NULL, NULL, V850_OPERAND_EP, BFD_RELOC_NONE }, -/* The imm16 field (unsigned) in a format 6 insn. */ -#define I16U (EP + 1) - { 16, 16, NULL, NULL, 0}, +/* A list of registers in a prepare/dispose instruction. */ +#define LIST12 (EP + 1) + { -1, 0xffe00001, NULL, NULL, V850E_OPERAND_REG_LIST, BFD_RELOC_NONE }, + +/* System register operands. */ +#define SR1 (LIST12 + 1) + { 5, 0, NULL, NULL, V850_OPERAND_SRG, BFD_RELOC_NONE }, /* The R2 field as a system register. */ -#define SR2 (I16U + 1) - { 5, 11, NULL, NULL, V850_OPERAND_SRG }, +#define SR2 (SR1 + 1) + { 5, 11, NULL, NULL, V850_OPERAND_SRG, BFD_RELOC_NONE }, -/* The disp16 field in a format 8 insn. */ -#define D16 (SR2 + 1) - { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, - -/* The DISP9 field in a format 3 insn, relaxable. */ -#define D9_RELAX (D16 + 1) - { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP }, +/* FPU CC bit position. */ +#define FFF (SR2 + 1) + { 3, 17, NULL, NULL, 0, BFD_RELOC_NONE }, -/* The DISP22 field in a format 4 insn, relaxable. - This _must_ follow D9_RELAX; the assembler assumes that the longer - version immediately follows the shorter version for relaxing. */ -#define D22 (D9_RELAX + 1) - { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP }, +/* The 4 bit condition code in a setf instruction */ +#define CCCC (FFF + 1) + { 4, 0, NULL, NULL, V850_OPERAND_CC, BFD_RELOC_NONE }, -/* The signed disp4 field in a format 4 insn. */ -#define D4 (D22 + 1) - { 4, 0, NULL, NULL, 0}, - -/* The unsigned disp5 field in a format 4 insn. */ -#define D5_4 (D4 + 1) - { 4, 0, insert_d5_4, extract_d5_4, 0 }, - -/* The disp16 field in an format 7 unsigned byte load insn. */ -#define D16_16 (D5_4 + 1) - { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 }, - -/* Third register in conditional moves. */ -#define R3 (D16_16 + 1) - { 5, 27, NULL, NULL, V850_OPERAND_REG }, +/* Condition code in adf,sdf. */ +#define CCCC_NOTSA (CCCC + 1) + { 4, 17, NULL, NULL, V850_OPERAND_CC|V850_NOT_SA, BFD_RELOC_NONE }, /* Condition code in conditional moves. */ -#define MOVCC (R3 + 1) - { 4, 17, NULL, NULL, V850_OPERAND_CC }, +#define MOVCC (CCCC_NOTSA + 1) + { 4, 17, NULL, NULL, V850_OPERAND_CC, BFD_RELOC_NONE }, + +/* Condition code in FPU. */ +#define FLOAT_CCCC (MOVCC + 1) + { 4, 27, NULL, NULL, V850_OPERAND_FLOAT_CC, BFD_RELOC_NONE }, + +/* The R1 field in a format C insn. */ +#define VR1 (FLOAT_CCCC + 1) + { 5, 0, NULL, NULL, V850_OPERAND_VREG, BFD_RELOC_NONE }, + +/* The R2 field in a format C insn. */ +#define VR2 (VR1 + 1) + { 5, 11, NULL, NULL, V850_OPERAND_VREG, BFD_RELOC_NONE }, + +/* The VR3 field in a format C insn. */ +#define VR3 (VR2 + 1) + { 5, 27, NULL, NULL, V850_OPERAND_VREG, BFD_RELOC_NONE }, + +/* The 1 bit immediate field in format C insn. */ +#define VI1 (VR3 + 1) + { 1, 3, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 1 bit immediate field in format C insn. */ +#define VC1 (VI1 + 1) + { 1, 0, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 2 bit immediate field in format C insn. */ +#define DI2 (VC1 + 1) + { 2, 17, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 2 bit immediate field in format C insn. */ +#define VI2 (DI2 + 1) + { 2, 0, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 2 bit immediate field in format C - DUP insn. */ +#define VI2DUP (VI2 + 1) + { 2, 2, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 3 bit immediate field in format 8 insn. */ +#define B3 (VI2DUP + 1) + { 3, 11, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 3 bit immediate field in format C insn. */ +#define DI3 (B3 + 1) + { 3, 17, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 3 bit immediate field in format C insn. */ +#define I3U (DI3 + 1) + { 3, 0, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 4 bit immediate field in format C insn. */ +#define I4U (I3U + 1) + { 4, 0, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The 4 bit immediate field in fetrap. */ +#define I4U_NOTIMM0 (I4U + 1) + { 4, 11, NULL, NULL, V850_NOT_IMM0, BFD_RELOC_NONE }, + +/* The unsigned disp4 field in a sld.bu. */ +#define D4U (I4U_NOTIMM0 + 1) + { 4, 0, NULL, NULL, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_4_4_OFFSET }, + +/* The imm5 field in a format 2 insn. */ +#define I5 (D4U + 1) + { 5, 0, NULL, NULL, V850_OPERAND_SIGNED, BFD_RELOC_NONE }, + +/* The imm5 field in a format 11 insn. */ +#define I5DIV1 (I5 + 1) + { 5, 0, insert_i5div1, extract_i5div1, 0, BFD_RELOC_NONE }, + +#define I5DIV2 (I5DIV1 + 1) + { 5, 0, insert_i5div2, extract_i5div2, 0, BFD_RELOC_NONE }, + +#define I5DIV3 (I5DIV2 + 1) + { 5, 0, insert_i5div3, extract_i5div3, 0, BFD_RELOC_NONE }, + +/* The unsigned imm5 field in a format 2 insn. */ +#define I5U (I5DIV3 + 1) + { 5, 0, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The imm5 field in a prepare/dispose instruction. */ +#define IMM5 (I5U + 1) + { 5, 1, NULL, NULL, 0, BFD_RELOC_NONE }, + +/* The unsigned disp5 field in a sld.hu. */ +#define D5_4U (IMM5 + 1) + { 5, 0, insert_d5_4, extract_d5_4, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_4_5_OFFSET }, + +/* The IMM6 field in a callt instruction. */ +#define IMM6 (D5_4U + 1) + { 6, 0, NULL, NULL, 0, BFD_RELOC_V850_CALLT_6_7_OFFSET }, -/* The imm9 field in a multiply word. */ -#define I9 (MOVCC + 1) - { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED }, +/* The signed disp7 field in a format 4 insn. */ +#define D7U (IMM6 + 1) + { 7, 0, NULL, NULL, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_7_7_OFFSET }, -/* The unsigned imm9 field in a multiply word. */ +/* The unsigned DISP8 field in a format 4 insn. */ +#define D8_7U (D7U + 1) + { 8, 0, insert_d8_7, extract_d8_7, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_7_8_OFFSET }, + +/* The unsigned DISP8 field in a format 4 insn. */ +#define D8_6U (D8_7U + 1) + { 8, 0, insert_d8_6, extract_d8_6, V850_OPERAND_DISP, BFD_RELOC_V850_TDA_6_8_OFFSET }, + +/* The unsigned DISP8 field in a format 4 insn. */ +#define V8 (D8_6U + 1) + { 8, 0, insert_v8, extract_v8, 0, BFD_RELOC_NONE }, + +/* The imm9 field in a multiply word. */ +#define I9 (V8 + 1) + { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED, BFD_RELOC_NONE }, + +/* The unsigned imm9 field in a multiply word. */ #define U9 (I9 + 1) - { 9, 0, insert_u9, extract_u9, 0 }, + { 9, 0, insert_u9, extract_u9, 0, BFD_RELOC_NONE }, -/* A list of registers in a prepare/dispose instruction. */ -#define LIST12 (U9 + 1) - { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP }, +/* The DISP9 field in a format 3 insn. */ +#define D9 (U9 + 1) + { 9, 0, insert_d9, extract_d9, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_9_PCREL }, + +/* The DISP9 field in a format 3 insn, relaxable. */ +#define D9_RELAX (D9 + 1) + { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_9_PCREL }, + +/* The imm16 field in a format 6 insn. */ +#define I16 (D9_RELAX + 1) + { 16, 16, NULL, NULL, V850_OPERAND_SIGNED, BFD_RELOC_16 }, -/* The IMM6 field in a call instruction. */ -#define I6 (LIST12 + 1) - { 6, 0, NULL, NULL, 0 }, +/* The 16 bit immediate following a 32 bit instruction. */ +#define IMM16 (I16 + 1) + { 16, 32, NULL, NULL, V850E_IMMEDIATE16, BFD_RELOC_16 }, /* The 16 bit immediate following a 32 bit instruction. */ -#define IMM16 (I6 + 1) - { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 }, +#define IMM16LO (IMM16 + 1) + { 16, 32, NULL, NULL, V850E_IMMEDIATE16, BFD_RELOC_LO16 }, + +/* The hi 16 bit immediate following a 32 bit instruction. */ +#define IMM16HI (IMM16LO + 1) + { 16, 16, NULL, NULL, V850E_IMMEDIATE16HI, BFD_RELOC_HI16 }, + +/* The unsigned imm16 in a format 6 insn. */ +#define I16U (IMM16HI + 1) + { 16, 16, NULL, NULL, 0, BFD_RELOC_16 }, + +/* The disp16 field in a format 8 insn. */ +#define D16 (I16U + 1) + { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_16 }, + +/* The disp16 field in an format 7 unsigned byte load insn. */ +#define D16_16 (D16 + 1) + { 16, 0, insert_d16_16, extract_d16_16, V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_16_SPLIT_OFFSET }, + +/* The disp16 field in a format 6 insn. */ +#define D16_15 (D16_16 + 1) + { 16, 0, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED | V850_OPERAND_DISP , BFD_RELOC_V850_16_S1 }, + +/* The unsigned DISP16 field in a format 7 insn. */ +#define D16_LOOP (D16_15 + 1) + { 16, 0, insert_u16_loop, extract_u16_loop, V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_16_PCREL }, + +/* The DISP17 field in a format 7 insn. */ +#define D17_16 (D16_LOOP + 1) + { 17, 0, insert_d17_16, extract_d17_16, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_17_PCREL }, + +/* The DISP22 field in a format 4 insn, relaxable. + This _must_ follow D9_RELAX; the assembler assumes that the longer + version immediately follows the shorter version for relaxing. */ +#define D22 (D17_16 + 1) + { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_22_PCREL }, + +#define D23 (D22 + 1) + { 23, 0, insert_d23, extract_d23, V850E_IMMEDIATE23 | V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_23 }, /* The 32 bit immediate following a 32 bit instruction. */ -#define IMM32 (IMM16 + 1) - { 0, 0, NULL, NULL, V850E_IMMEDIATE32 }, +#define IMM32 (D23 + 1) + { 32, 32, NULL, NULL, V850E_IMMEDIATE32, BFD_RELOC_32 }, + +#define D32_31 (IMM32 + 1) + { 32, 32, NULL, NULL, V850E_IMMEDIATE32 | V850_OPERAND_SIGNED | V850_OPERAND_DISP, BFD_RELOC_V850_32_ABS }, + +#define D32_31_PCREL (D32_31 + 1) + { 32, 32, NULL, NULL, V850E_IMMEDIATE32 | V850_OPERAND_SIGNED | V850_OPERAND_DISP | V850_PCREL, BFD_RELOC_V850_32_PCREL }, -/* The imm5 field in a push/pop instruction. */ -#define IMM5 (IMM32 + 1) - { 5, 1, NULL, NULL, 0 }, - -/* Reg2 in dispose instruction. */ -#define R2DISPOSE (IMM5 + 1) - { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, - -/* Stack pointer in prepare instruction. */ -#define SP (R2DISPOSE + 1) - { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG }, - -/* The IMM5 field in a divide N step instruction. */ -#define I5DIV (SP + 1) - { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED }, - - /* The list of registers in a PUSHMH/POPMH instruction. */ -#define LIST18_H (I5DIV + 1) - { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP }, - - /* The list of registers in a PUSHML/POPML instruction. */ -#define LIST18_L (LIST18_H + 1) - /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c. */ - { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP }, }; @@ -497,6 +838,8 @@ const struct v850_operand v850_operands[ /* 3 operand instruction (Format VI). */ #define IF6U {I16U, R1, R2} +/* Conditional branch instruction format (Format VII). */ +#define IF7 {D17_16} /* The opcode table. @@ -531,198 +874,715 @@ const struct v850_operand v850_operands[ const struct v850_opcode v850_opcodes[] = { -{ "breakpoint", 0xffff, 0xffff, {UNUSED}, 0, PROCESSOR_ALL }, -{ "dbtrap", one (0xf840), one (0xffff), {UNUSED}, 0, PROCESSOR_V850E1 }, - -{ "jmp", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL }, - -/* Load/store instructions. */ -{ "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E1 }, -{ "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E }, - -{ "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E1 }, -{ "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E }, - -{ "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E1 }, -{ "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E }, -{ "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850 }, - -{ "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E1 }, -{ "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E }, -{ "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850 }, -{ "sld.w", one (0x0500), one (0x0781), {D8_6, EP, R2}, 1, PROCESSOR_ALL }, -{ "sst.b", one (0x0380), one (0x0780), {R2, D7, EP}, 2, PROCESSOR_ALL }, -{ "sst.h", one (0x0480), one (0x0780), {R2, D8_7, EP}, 2, PROCESSOR_ALL }, -{ "sst.w", one (0x0501), one (0x0781), {R2, D8_6, EP}, 2, PROCESSOR_ALL }, - -{ "prepare", two (0x0780, 0x0003), two (0xffc0, 0x001f), {LIST12, IMM5, SP}, 0, PROCESSOR_NOT_V850 }, -{ "prepare", two (0x0780, 0x000b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 }, -{ "prepare", two (0x0780, 0x0013), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 }, -{ "prepare", two (0x0780, 0x001b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM32}, 0, PROCESSOR_NOT_V850 }, -{ "prepare", two (0x0780, 0x0001), two (0xffc0, 0x001f), {LIST12, IMM5}, 0, PROCESSOR_NOT_V850 }, -{ "dispose", one (0x0640), one (0xffc0), {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 }, -{ "dispose", two (0x0640, 0x0000), two (0xffc0, 0x001f), {IMM5, LIST12}, 0, PROCESSOR_NOT_V850 }, - -{ "ld.b", two (0x0700, 0x0000), two (0x07e0, 0x0000), {D16, R1, R2}, 1, PROCESSOR_ALL }, -{ "ld.h", two (0x0720, 0x0000), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL }, -{ "ld.w", two (0x0720, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL }, -{ "ld.bu", two (0x0780, 0x0001), two (0x07c0, 0x0001), {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 }, -{ "ld.hu", two (0x07e0, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 }, -{ "st.b", two (0x0740, 0x0000), two (0x07e0, 0x0000), {R2, D16, R1}, 2, PROCESSOR_ALL }, -{ "st.h", two (0x0760, 0x0000), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL }, -{ "st.w", two (0x0760, 0x0001), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL }, - -/* Byte swap/extend instructions. */ -{ "zxb", one (0x0080), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, -{ "zxh", one (0x00c0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, -{ "sxb", one (0x00a0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, -{ "sxh", one (0x00e0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, -{ "bsh", two (0x07e0, 0x0342), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "bsw", two (0x07e0, 0x0340), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "hsw", two (0x07e0, 0x0344), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, - -/* Jump table instructions. */ -{ "switch", one (0x0040), one (0xffe0), {R1}, 1, PROCESSOR_NOT_V850 }, -{ "callt", one (0x0200), one (0xffc0), {I6}, 0, PROCESSOR_NOT_V850 }, -{ "ctret", two (0x07e0, 0x0144), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 }, - -/* Arithmetic operation instructions. */ -{ "setf", two (0x07e0, 0x0000), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_ALL }, -{ "cmov", two (0x07e0, 0x0320), two (0x07e0, 0x07e1), {MOVCC, R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "cmov", two (0x07e0, 0x0300), two (0x07e0, 0x07e1), {MOVCC, I5, R2, R3}, 0, PROCESSOR_NOT_V850 }, - -{ "mul", two (0x07e0, 0x0220), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "mul", two (0x07e0, 0x0240), two (0x07e0, 0x07c3), {I9, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "mulu", two (0x07e0, 0x0222), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "mulu", two (0x07e0, 0x0242), two (0x07e0, 0x07c3), {U9, R2, R3}, 0, PROCESSOR_NOT_V850 }, - -{ "div", two (0x07e0, 0x02c0), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "divu", two (0x07e0, 0x02c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "divhu", two (0x07e0, 0x0282), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "divh", two (0x07e0, 0x0280), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, -{ "divh", OP (0x02), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, - -{ "nop", one (0x00), one (0xffff), {0}, 0, PROCESSOR_ALL }, -{ "mov", OP (0x10), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "mov", one (0x0620), one (0xffe0), {IMM32, R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, -{ "mov", OP (0x00), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "movea", OP (0x31), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "movhi", OP (0x32), OP_MASK, {I16U, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, +/* standard instructions */ { "add", OP (0x0e), OP_MASK, IF1, 0, PROCESSOR_ALL }, { "add", OP (0x12), OP_MASK, IF2, 0, PROCESSOR_ALL }, + { "addi", OP (0x30), OP_MASK, IF6, 0, PROCESSOR_ALL }, -{ "sub", OP (0x0d), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "subr", OP (0x0c), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "mulh", OP (0x17), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "mulh", OP (0x07), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "mulhi", OP (0x37), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "cmp", OP (0x0f), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "cmp", OP (0x13), OP_MASK, IF2, 0, PROCESSOR_ALL }, -/* Saturated operation instructions. */ -{ "satadd", OP (0x11), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "satadd", OP (0x06), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "satsub", OP (0x05), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "satsubi", OP (0x33), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, -{ "satsubr", OP (0x04), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, +{ "adf", two (0x07e0, 0x03a0), two (0x07e0, 0x07e1), {CCCC_NOTSA, R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, -/* Logical operation instructions. */ -{ "tst", OP (0x0b), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "or", OP (0x08), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "ori", OP (0x34), OP_MASK, IF6U, 0, PROCESSOR_ALL }, { "and", OP (0x0a), OP_MASK, IF1, 0, PROCESSOR_ALL }, + { "andi", OP (0x36), OP_MASK, IF6U, 0, PROCESSOR_ALL }, -{ "xor", OP (0x09), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "xori", OP (0x35), OP_MASK, IF6U, 0, PROCESSOR_ALL }, -{ "not", OP (0x01), OP_MASK, IF1, 0, PROCESSOR_ALL }, -{ "sar", OP (0x15), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, -{ "sar", two (0x07e0, 0x00a0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, -{ "shl", OP (0x16), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, -{ "shl", two (0x07e0, 0x00c0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, -{ "shr", OP (0x14), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, -{ "shr", two (0x07e0, 0x0080), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, -{ "sasf", two (0x07e0, 0x0200), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_NOT_V850 }, -/* Branch instructions. */ - /* Signed integer. */ -{ "bgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL }, + /* signed integer */ { "bge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "blt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bge", BOP7 (0xe), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bgt", BOP7 (0xf), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "ble", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Unsigned integer. */ +{ "ble", BOP7 (0x7), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "blt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "blt", BOP7 (0x6), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + /* unsigned integer */ { "bh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "bnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bh", BOP7 (0xb), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "bl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bl", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bnh", BOP7 (0x3), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "bnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Common. */ +{ "bnl", BOP7 (0x9), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + /* common */ { "be", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "be", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "bne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Others. */ -{ "bv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "bnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "bn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "bp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bne", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + /* others */ { "bc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bc", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bf", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bf", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bn", BOP7 (0x4), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "bnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "bz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bnc", BOP7 (0x9), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bnv", BOP7 (0x8), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "bnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bnz", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bp", BOP7 (0xc), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "br", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL }, { "bsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bsa", BOP7 (0xd), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bt", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bt", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bv", BOP7 (0x0), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, +{ "bz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "bz", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + + /* signed integer */ +{ "bge17", BOP7 (0xe), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bgt17", BOP7 (0xf), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "ble17", BOP7 (0x7), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "blt17", BOP7 (0x6), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, + /* unsigned integer */ +{ "bh17", BOP7 (0xb), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bl17", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bnh17", BOP7 (0x3), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bnl17", BOP7 (0x9), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, + /* common */ +{ "be17", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bne17", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, + /* others */ +{ "bc17", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bf17", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bn17", BOP7 (0x4), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bnc17", BOP7 (0x9), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bnv17", BOP7 (0x8), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bnz17", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bp17", BOP7 (0xc), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, + /* br17 is not exists */ +{ "bsa17", BOP7 (0xd), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bt17", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bv17", BOP7 (0x0), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "bz17", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, + + +{ "bsh", two (0x07e0, 0x0342), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "bsw", two (0x07e0, 0x0340), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "callt", one (0x0200), one (0xffc0), {IMM6}, 0, PROCESSOR_NOT_V850 }, + +{ "caxi", two (0x07e0, 0x00ee), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2_ALL }, + +{ "clr1", two (0x87c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 3, PROCESSOR_ALL }, +{ "clr1", two (0x07e0, 0x00e4), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, + +{ "cmov", two (0x07e0, 0x0320), two (0x07e0, 0x07e1), {MOVCC, R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, +{ "cmov", two (0x07e0, 0x0300), two (0x07e0, 0x07e1), {MOVCC, I5, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "cmp", OP (0x0f), OP_MASK, IF1, 0, PROCESSOR_ALL }, +{ "cmp", OP (0x13), OP_MASK, IF2, 0, PROCESSOR_ALL }, + +{ "ctret", two (0x07e0, 0x0144), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 }, + +{ "dbret", two (0x07e0, 0x0146), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 }, + +{ "dbtrap", one (0xf840), one (0xffff), {0}, 0, PROCESSOR_NOT_V850 }, + +{ "di", two (0x07e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, + +{ "dispose", two (0x0640, 0x0000), two (0xffc0, 0x0000), {IMM5, LIST12, R2_DISPOSE},3, PROCESSOR_NOT_V850 }, +{ "dispose", two (0x0640, 0x0000), two (0xffc0, 0x001f), {IMM5, LIST12}, 0, PROCESSOR_NOT_V850 }, + +{ "div", two (0x07e0, 0x02c0), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "divh", two (0x07e0, 0x0280), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, +{ "divh", OP (0x02), OP_MASK, {R1_NOTR0, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "divhn", two (0x07e0, 0x0280), two (0x07e0, 0x07c3), {I5DIV1, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, + +{ "divhu", two (0x07e0, 0x0282), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "divhun", two (0x07e0, 0x0282), two (0x07e0, 0x07c3), {I5DIV1, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, +{ "divn", two (0x07e0, 0x02c0), two (0x07e0, 0x07c3), {I5DIV2, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, + +{ "divq", two (0x07e0, 0x02fc), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "divqu", two (0x07e0, 0x02fe), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "divu", two (0x07e0, 0x02c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "divun", two (0x07e0, 0x02c2), two (0x07e0, 0x07c3), {I5DIV2, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, + +{ "ei", two (0x87e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, -/* Branch macros. +{ "eiret", two (0x07e0, 0x0148), two (0xffff, 0xffff), {0}, 0, PROCESSOR_V850E2_ALL }, + +{ "feret", two (0x07e0, 0x014a), two (0xffff, 0xffff), {0}, 0, PROCESSOR_V850E2_ALL }, + +{ "fetrap", one (0x0040), one (0x87ff), {I4U_NOTIMM0}, 0, PROCESSOR_V850E2_ALL }, + +{ "halt", two (0x07e0, 0x0120), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, - We use the short form in the opcode/mask fields. The assembler - will twiddle bits as necessary if the long form is needed. */ +{ "hsh", two (0x07e0, 0x0346), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2_ALL }, - /* Signed integer. */ +{ "hsw", two (0x07e0, 0x0344), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "jarl", two (0xc7e0, 0x160), two (0xffe0, 0x07ff), {R1, R3}, 1, PROCESSOR_V850E2V3 }, +{ "jarl", two (0x0780, 0x0000), two (0x07c0, 0x0001), {D22, R2_NOTR0}, 0, PROCESSOR_ALL}, +{ "jarl", one (0x02e0), one (0xffe0), {D32_31_PCREL, R1_NOTR0}, 0, PROCESSOR_V850E2_ALL }, +/* gas local alias of mov imm22(not defined in spec) */ +{ "jarl22", two (0x0780, 0x0000), two (0x07c0, 0x0001), {D22, R2_NOTR0}, 0, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS}, +/* gas local alias of mov imm32(not defined in spec) */ +{ "jarl32", one (0x02e0), one (0xffe0), {D32_31_PCREL, R1_NOTR0}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, +{ "jarlw", one (0x02e0), one (0xffe0), {D32_31_PCREL, R1_NOTR0}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +/* v850e2-v3: place before jmp32 for disassembler */ +{ "loop", two (0x06e0, 0x0001), two (0xffe0, 0x0001), {R1, D16_LOOP}, 0, PROCESSOR_V850E2V3 }, + +{ "jmp", one (0x06e0), one (0xffe0), {D32_31, R1}, 2, PROCESSOR_V850E2_ALL }, +{ "jmp", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL }, +/* gas local alias of jmp disp22(not defined in spec) */ +{ "jmp22", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS }, +/* gas local alias of jmp disp32(not defined in spec) */ +{ "jmp32", one (0x06e0), one (0xffe0), {D32_31, R1}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, +{ "jmpw", one (0x06e0), one (0xffe0), {D32_31, R1}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "jr", two (0x0780, 0x0000), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL }, +{ "jr", one (0x02e0), one (0xffff), {D32_31_PCREL}, 0, PROCESSOR_V850E2_ALL }, +/* gas local alias of mov imm22(not defined in spec) */ +{ "jr22", two (0x0780, 0x0000), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL | PROCESSOR_OPTION_ALIAS }, +/* gas local alias of mov imm32(not defined in spec) */ +{ "jr32", one (0x02e0), one (0xffff), {D32_31_PCREL}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +/* alias of bcond(same as CA850) */ { "jgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jgt", BOP7 (0xf), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jge", BOP7 (0xe), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jlt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jlt", BOP7 (0x6), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jle", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Unsigned integer. */ +{ "jle", BOP7 (0x7), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + /* unsigned integer */ { "jh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jh", BOP7 (0xb), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jnh", BOP7 (0x3), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jl", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Common. */ +{ "jnl", BOP7 (0x9), BOP7_MASK, IF3, 0, PROCESSOR_V850E2V3 }, + /* common */ { "je", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "je", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, - /* Others. */ +{ "jne", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, + /* others */ { "jv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jv", BOP7 (0x0), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jnv", BOP7 (0x8), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jn", BOP7 (0x4), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jp", BOP7 (0xc), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jc", BOP7 (0x1), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jnc", BOP7 (0x9), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jz", BOP7 (0x2), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "jsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL }, +{ "jnz", BOP7 (0xa), BOP7_MASK, IF7, 0, PROCESSOR_V850E2V3 }, { "jbr", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL }, -{ "jr", one (0x0780), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL }, -{ "jarl", one (0x0780), two (0x07c0, 0x0001), {D22, R2}, 0, PROCESSOR_ALL }, + +{ "ldacc", two (0x07e0, 0x0bc4), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION }, -/* Bit manipulation instructions. */ -{ "set1", two (0x07c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, -{ "set1", two (0x07e0, 0x00e0), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, -{ "not1", two (0x47c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, +{ "ld.b", two (0x0700, 0x0000), two (0x07e0, 0x0000), {D16, R1, R2}, 2, PROCESSOR_ALL }, +{ "ld.b", two (0x0780, 0x0005), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL }, +{ "ld.b23", two (0x0780, 0x0005), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "ld.bu", two (0x0780, 0x0001), two (0x07c0, 0x0001), {D16_16, R1, R2_NOTR0}, 2, PROCESSOR_NOT_V850 }, +{ "ld.bu", two (0x07a0, 0x0005), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL }, +{ "ld.bu23", two (0x07a0, 0x0005), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "ld.h", two (0x0720, 0x0000), two (0x07e0, 0x0001), {D16_15, R1, R2}, 2, PROCESSOR_ALL }, +{ "ld.h", two (0x0780, 0x0007), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL }, +{ "ld.h23", two (0x0780, 0x0007), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "ld.hu", two (0x07e0, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2_NOTR0}, 2, PROCESSOR_NOT_V850 }, +{ "ld.hu", two (0x07a0, 0x0007), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL }, +{ "ld.hu23", two (0x07a0, 0x0007), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "ld.w", two (0x0720, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2}, 2, PROCESSOR_ALL }, +{ "ld.w", two (0x0780, 0x0009), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL }, +{ "ld.w23", two (0x0780, 0x0009), two (0x07e0, 0x000f), {D23, R1, R3}, 2, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "ldsr", two (0x07e0, 0x0020), two (0x07e0, 0xffff), {R1, SR2}, 0, PROCESSOR_ALL }, + +{ "macacc", two (0x07e0, 0x0bc0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION }, + +{ "mac", two (0x07e0, 0x03c0), two (0x07e0, 0x0fe1), {R1, R2, R3_EVEN, R4_EVEN}, 0, PROCESSOR_V850E2_ALL }, + +{ "macu", two (0x07e0, 0x03e0), two (0x07e0, 0x0fe1), {R1, R2, R3_EVEN, R4_EVEN}, 0, PROCESSOR_V850E2_ALL }, + +{ "macuacc", two (0x07e0, 0x0bc2), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION }, + +{ "mov", OP (0x00), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, +{ "mov", OP (0x10), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, +{ "mov", one (0x0620), one (0xffe0), {IMM32, R1}, 0, PROCESSOR_NOT_V850 }, +/* gas local alias of mov imm32(not defined in spec) */ +{ "movl", one (0x0620), one (0xffe0), {IMM32, R1}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_ALIAS }, + +{ "movea", OP (0x31), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "movhi", OP (0x32), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "mul", two (0x07e0, 0x0220), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, +{ "mul", two (0x07e0, 0x0240), two (0x07e0, 0x07c3), {I9, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "mulh", OP (0x17), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, +{ "mulh", OP (0x07), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "mulhi", OP (0x37), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "mulu", two (0x07e0, 0x0222), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, +{ "mulu", two (0x07e0, 0x0242), two (0x07e0, 0x07c3), {U9, R2, R3}, 0, PROCESSOR_NOT_V850 }, + +{ "nop", one (0x00), one (0xffff), {0}, 0, PROCESSOR_ALL }, + +{ "not", OP (0x01), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "not1", two (0x47c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 3, PROCESSOR_ALL }, { "not1", two (0x07e0, 0x00e2), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, -{ "clr1", two (0x87c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, -{ "clr1", two (0x07e0, 0x00e4), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, -{ "tst1", two (0xc7c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, -{ "tst1", two (0x07e0, 0x00e6), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, -/* Special instructions. */ -{ "di", two (0x07e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, -{ "ei", two (0x87e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, -{ "halt", two (0x07e0, 0x0120), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, +{ "or", OP (0x08), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "ori", OP (0x34), OP_MASK, IF6U, 0, PROCESSOR_ALL }, + +{ "prepare", two (0x0780, 0x0003), two (0xffc0, 0x001f), {LIST12, IMM5, SP}, 0, PROCESSOR_NOT_V850 }, +{ "prepare", two (0x0780, 0x000b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16LO},0, PROCESSOR_NOT_V850 }, +{ "prepare", two (0x0780, 0x0013), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16HI},0, PROCESSOR_NOT_V850 }, +{ "prepare", two (0x0780, 0x001b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM32}, 0, PROCESSOR_NOT_V850 }, +{ "prepare", two (0x0780, 0x0001), two (0xffc0, 0x001f), {LIST12, IMM5}, 0, PROCESSOR_NOT_V850 }, + { "reti", two (0x07e0, 0x0140), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, -{ "trap", two (0x07e0, 0x0100), two (0xffe0, 0xffff), {I5U}, 0, PROCESSOR_ALL }, -{ "ldsr", two (0x07e0, 0x0020), two (0x07e0, 0xffff), {R1, SR2}, 0, PROCESSOR_ALL }, + +{ "sar", two (0x07e0, 0x00a2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, +{ "sar", OP (0x15), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, +{ "sar", two (0x07e0, 0x00a0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, + +{ "sasf", two (0x07e0, 0x0200), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_NOT_V850 }, + +{ "satadd", two (0x07e0, 0x03ba), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, +{ "satadd", OP (0x11), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, +{ "satadd", OP (0x06), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "satsub", two (0x07e0, 0x039a), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, +{ "satsub", OP (0x05), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "satsubi", OP (0x33), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "satsubr", OP (0x04), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, + +{ "sbf", two (0x07e0, 0x0380), two (0x07e0, 0x07e1), {CCCC_NOTSA, R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "sch0l", two (0x07e0, 0x0364), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "sch0r", two (0x07e0, 0x0360), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "sch1l", two (0x07e0, 0x0366), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "sch1r", two (0x07e0, 0x0362), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2_ALL }, + +{ "sdivhn", two (0x07e0, 0x0180), two (0x07e0, 0x07c3), {I5DIV3, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, +{ "sdivhun", two (0x07e0, 0x0182), two (0x07e0, 0x07c3), {I5DIV3, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, +{ "sdivn", two (0x07e0, 0x01c0), two (0x07e0, 0x07c3), {I5DIV3, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, +{ "sdivun", two (0x07e0, 0x01c2), two (0x07e0, 0x07c3), {I5DIV3, R1, R2, R3}, 0, PROCESSOR_NOT_V850 | PROCESSOR_OPTION_EXTENSION }, + +{ "set1", two (0x07c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 3, PROCESSOR_ALL }, +{ "set1", two (0x07e0, 0x00e0), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, + +{ "setf", two (0x07e0, 0x0000), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_ALL }, + +{ "shl", two (0x07e0, 0x00c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, +{ "shl", OP (0x16), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, +{ "shl", two (0x07e0, 0x00c0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, + +{ "shr", two (0x07e0, 0x0082), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2_ALL }, +{ "shr", OP (0x14), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, +{ "shr", two (0x07e0, 0x0080), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, + +{ "sld.b", one (0x0300), one (0x0780), {D7U, EP, R2}, 2, PROCESSOR_ALL }, + +{ "sld.bu", one (0x0060), one (0x07f0), {D4U, EP, R2_NOTR0}, 2, PROCESSOR_NOT_V850 }, + +{ "sld.h", one (0x0400), one (0x0780), {D8_7U,EP, R2}, 2, PROCESSOR_ALL }, + +{ "sld.hu", one (0x0070), one (0x07f0), {D5_4U,EP, R2_NOTR0}, 2, PROCESSOR_NOT_V850 }, + +{ "sld.w", one (0x0500), one (0x0781), {D8_6U,EP, R2}, 2, PROCESSOR_ALL }, + +{ "sst.b", one (0x0380), one (0x0780), {R2, D7U, EP}, 3, PROCESSOR_ALL }, + +{ "sst.h", one (0x0480), one (0x0780), {R2, D8_7U,EP}, 3, PROCESSOR_ALL }, + +{ "sst.w", one (0x0501), one (0x0781), {R2, D8_6U,EP}, 3, PROCESSOR_ALL }, + +{ "stacch", two (0x07e0, 0x0bca), two (0x07ff, 0xffff), {R2}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION }, +{ "staccl", two (0x07e0, 0x0bc8), two (0x07ff, 0xffff), {R2}, 0, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_EXTENSION }, + +{ "st.b", two (0x0740, 0x0000), two (0x07e0, 0x0000), {R2, D16, R1}, 3, PROCESSOR_ALL }, +{ "st.b", two (0x0780, 0x000d), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL }, +{ "st.b23", two (0x0780, 0x000d), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "st.h", two (0x0760, 0x0000), two (0x07e0, 0x0001), {R2, D16_15, R1}, 3, PROCESSOR_ALL }, +{ "st.h", two (0x07a0, 0x000d), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL }, +{ "st.h23", two (0x07a0, 0x000d), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + +{ "st.w", two (0x0760, 0x0001), two (0x07e0, 0x0001), {R2, D16_15, R1}, 3, PROCESSOR_ALL }, +{ "st.w", two (0x0780, 0x000f), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL }, +{ "st.w23", two (0x0780, 0x000f), two (0x07e0, 0x000f), {R3, D23, R1}, 3, PROCESSOR_V850E2_ALL | PROCESSOR_OPTION_ALIAS }, + { "stsr", two (0x07e0, 0x0040), two (0x07e0, 0xffff), {SR1, R2}, 0, PROCESSOR_ALL }, -{ "dbret", two (0x07e0, 0x0146), two (0xffff, 0xffff), {UNUSED}, 0, PROCESSOR_V850E1 }, -{ 0, 0, 0, {0}, 0, 0 }, +{ "sub", OP (0x0d), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "subr", OP (0x0c), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "switch", one (0x0040), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, + +{ "sxb", one (0x00a0), one (0xffe0), {R1}, 0, PROCESSOR_NOT_V850 }, + +{ "sxh", one (0x00e0), one (0xffe0), {R1}, 0, PROCESSOR_NOT_V850 }, + +{ "trap", two (0x07e0, 0x0100), two (0xffe0, 0xffff), {I5U}, 0, PROCESSOR_ALL }, + +{ "tst", OP (0x0b), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "tst1", two (0xc7c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 3, PROCESSOR_ALL }, +{ "tst1", two (0x07e0, 0x00e6), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, + +{ "xor", OP (0x09), OP_MASK, IF1, 0, PROCESSOR_ALL }, + +{ "xori", OP (0x35), OP_MASK, IF6U, 0, PROCESSOR_ALL }, + +{ "zxb", one (0x0080), one (0xffe0), {R1}, 0, PROCESSOR_NOT_V850 }, + +{ "zxh", one (0x00c0), one (0xffe0), {R1}, 0, PROCESSOR_NOT_V850 }, + +/* floating point operation */ +{ "absf.d", two (0x07e0, 0x0458), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "absf.s", two (0x07e0, 0x0448), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "addf.d", two (0x07e0, 0x0470), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "addf.s", two (0x07e0, 0x0460), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.dl", two (0x07e2, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.dul", two (0x07f2, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.duw", two (0x07f2, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.dw", two (0x07e2, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.sl", two (0x07e2, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.sul", two (0x07f2, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.suw", two (0x07f2, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.sw", two (0x07e2, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "ceilf.sw", two (0x07e2, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cmovf.d", two (0x07e0, 0x0410), two (0x0fe1, 0x0ff1), {FFF, R1_EVEN, R2_EVEN, R3_EVEN_NOTR0}, 0, PROCESSOR_V850E2V3 }, +/* default value for FFF is 0(not defined in spec) */ +{ "cmovf.d", two (0x07e0, 0x0410), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN_NOTR0}, 0, PROCESSOR_V850E2V3 }, +{ "cmovf.s", two (0x07e0, 0x0400), two (0x07e0, 0x07f1), {FFF, R1, R2, R3_NOTR0}, 0, PROCESSOR_V850E2V3 }, +/* default value for FFF is 0(not defined in spec) */ +{ "cmovf.s", two (0x07e0, 0x0400), two (0x07e0, 0x07ff), {R1, R2, R3_NOTR0}, 0, PROCESSOR_V850E2V3 }, +{ "cmpf.d", two (0x07e0, 0x0430), two (0x0fe1, 0x87f1), {FLOAT_CCCC, R1_EVEN, R2_EVEN, FFF}, 0, PROCESSOR_V850E2V3 }, +{ "cmpf.d", two (0x07e0, 0x0430), two (0x0fe1, 0x87ff), {FLOAT_CCCC, R1_EVEN, R2_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cmpf.s", two (0x07e0, 0x0420), two (0x07e0, 0x87f1), {FLOAT_CCCC, R1, R2, FFF}, 0, PROCESSOR_V850E2V3 }, +{ "cmpf.s", two (0x07e0, 0x0420), two (0x07e0, 0x87ff), {FLOAT_CCCC, R1, R2}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.dl", two (0x07e4, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.ds", two (0x07e3, 0x0452), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.dul", two (0x07f4, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.duw", two (0x07f4, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.dw", two (0x07e4, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.ld", two (0x07e1, 0x0452), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.ls", two (0x07e1, 0x0442), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.sd", two (0x07e2, 0x0452), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.sl", two (0x07e4, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.sul", two (0x07f4, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.suw", two (0x07f4, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.sw", two (0x07e4, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.uld", two (0x07f1, 0x0452), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.uls", two (0x07f1, 0x0442), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.uwd", two (0x07f0, 0x0452), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.uws", two (0x07f0, 0x0442), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.wd", two (0x07e0, 0x0452), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "cvtf.ws", two (0x07e0, 0x0442), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "divf.d", two (0x07e0, 0x047e), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "divf.s", two (0x07e0, 0x046e), two (0x07e0, 0x07ff), {R1_NOTR0, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.dl", two (0x07e3, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.dul", two (0x07f3, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.duw", two (0x07f3, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.dw", two (0x07e3, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.sl", two (0x07e3, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.sul", two (0x07f3, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.suw", two (0x07f3, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "floorf.sw", two (0x07e3, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "maddf.s", two (0x07e0, 0x0500), two (0x07e0, 0x0761), {R1, R2, R3, R4}, 0, PROCESSOR_V850E2V3 }, +{ "maxf.d", two (0x07e0, 0x0478), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "maxf.s", two (0x07e0, 0x0468), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "minf.d", two (0x07e0, 0x047a), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "minf.s", two (0x07e0, 0x046a), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "msubf.s", two (0x07e0, 0x0520), two (0x07e0, 0x0761), {R1, R2, R3, R4}, 0, PROCESSOR_V850E2V3 }, +{ "mulf.d", two (0x07e0, 0x0474), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "mulf.s", two (0x07e0, 0x0464), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "negf.d", two (0x07e1, 0x0458), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "negf.s", two (0x07e1, 0x0448), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "nmaddf.s", two (0x07e0, 0x0540), two (0x07e0, 0x0761), {R1, R2, R3, R4}, 0, PROCESSOR_V850E2V3 }, +{ "nmsubf.s", two (0x07e0, 0x0560), two (0x07e0, 0x0761), {R1, R2, R3, R4}, 0, PROCESSOR_V850E2V3 }, +{ "recipf.d", two (0x07e1, 0x045e), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "recipf.s", two (0x07e1, 0x044e), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, + +{ "roundf.dl", two (0x07e0, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.dul", two (0x07f0, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.duw", two (0x07f0, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.dw", two (0x07e0, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.sl", two (0x07e0, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.sul", two (0x07f0, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.suw", two (0x07f0, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, +{ "roundf.sw", two (0x07e0, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_EXTENSION }, + +{ "rsqrtf.d", two (0x07e2, 0x045e), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "rsqrtf.s", two (0x07e2, 0x044e), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "sqrtf.d", two (0x07e0, 0x045e), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "sqrtf.s", two (0x07e0, 0x044e), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "subf.d", two (0x07e0, 0x0472), two (0x0fe1, 0x0fff), {R1_EVEN, R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "subf.s", two (0x07e0, 0x0462), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "trfsr", two (0x07e0, 0x0400), two (0xffff, 0xfff1), {FFF}, 0, PROCESSOR_V850E2V3 }, +{ "trfsr", two (0x07e0, 0x0400), two (0xffff, 0xffff), {0}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.dl", two (0x07e1, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.dul", two (0x07f1, 0x0454), two (0x0fff, 0x0fff), {R2_EVEN, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.duw", two (0x07f1, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.dw", two (0x07e1, 0x0450), two (0x0fff, 0x07ff), {R2_EVEN, R3}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.sl", two (0x07e1, 0x0444), two (0x07ff, 0x0fff), {R2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.sul", two (0x07f1, 0x0444), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.suw", two (0x07f1, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "trncf.sw", two (0x07e1, 0x0440), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_V850E2V3 }, + + /* special instruction (from gdb) mov 1, r0 */ +{ "breakpoint", one (0x0001), one (0xffff), {UNUSED}, 0, PROCESSOR_ALL }, + + /* v850e2-v3 */ +{ "synce", one (0x001d), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 }, +{ "syncm", one (0x001e), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 }, +{ "syncp", one (0x001f), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 }, +{ "syscall", two (0xd7e0, 0x0160), two (0xffe0, 0xc7ff), {V8}, 0, PROCESSOR_V850E2V3 }, + /* alias of syncp */ +{ "sync", one (0x001f), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 | PROCESSOR_OPTION_ALIAS }, +{ "rmtrap", one (0xf040), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 }, + + +{ "rie", one (0x0040), one (0xffff), {0}, 0, PROCESSOR_V850E2V3 }, +{ "rie", two (0x07f0, 0x0000), two (0x07f0, 0xffff), {0}, 0, PROCESSOR_V850E2V3 }, + +{ "ptld.b", two (0x07e0, 0x0348), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.b", two (0x07e0, 0x034e), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.b", two (0x0fe0, 0x034e), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.bu", two (0x07e0, 0x034c), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.bu", two (0x07e0, 0x0352), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.bu", two (0x0fe0, 0x0352), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.h", two (0x07e0, 0x0354), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.h", two (0x07e0, 0x035a), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.h", two (0x0fe0, 0x035a), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.hu", two (0x07e0, 0x0358), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.hu", two (0x07e0, 0x035e), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.hu", two (0x0fe0, 0x035e), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.w", two (0x07e0, 0x0368), two (0x07e0, 0x07ff), {R1, R2, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.w", two (0x07e0, 0x036e), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptld.w", two (0x0fe0, 0x036e), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, R3}, 1, PROCESSOR_V850E2V3 }, +{ "ptst.b", two (0x07e0, 0x034a), two (0x07e0, 0x07ff), {R3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.b", two (0x07e0, 0x0350), two (0x0fe0, 0x07ff), {R3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.b", two (0x0fe0, 0x0350), two (0x0fe0, 0x07ff), {R3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.h", two (0x07e0, 0x0356), two (0x07e0, 0x07ff), {R3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.h", two (0x07e0, 0x035c), two (0x0fe0, 0x07ff), {R3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.h", two (0x0fe0, 0x035c), two (0x0fe0, 0x07ff), {R3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.w", two (0x07e0, 0x036a), two (0x07e0, 0x07ff), {R3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.w", two (0x07e0, 0x0370), two (0x0fe0, 0x07ff), {R3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptst.w", two (0x0fe0, 0x0370), two (0x0fe0, 0x07ff), {R3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, + + +/* DSP operation */ +{ "vadd.h", two (0x07e0, 0x0600), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vadd.w", two (0x07e0, 0x0680), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsub.h", two (0x07e0, 0x0602), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsub.w", two (0x07e0, 0x0682), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vaddsat.h", two (0x07e0, 0x0604), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vaddsat.w", two (0x07e0, 0x0684), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsubsat.h", two (0x07e0, 0x0606), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsubsat.w", two (0x07e0, 0x0686), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vadds.h", two (0x07e0, 0x0608), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vadds.w", two (0x07e0, 0x0688), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsubs.h", two (0x07e0, 0x060a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsubs.w", two (0x07e0, 0x068a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmul.h", two (0x07e0, 0x060c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmul.w", two (0x07e0, 0x068c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmult.h", two (0x07e0, 0x060e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmult.w", two (0x07e0, 0x068e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmulrn.h", two (0x07e0, 0x0610), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmulrn.w", two (0x07e0, 0x0690), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpeq.h", two (0x07e0, 0x0612), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpeq.w", two (0x07e0, 0x0692), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpls.h", two (0x07e0, 0x0614), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpls.w", two (0x07e0, 0x0694), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmple.h", two (0x07e0, 0x0616), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmple.w", two (0x07e0, 0x0696), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpne.h", two (0x07e0, 0x0618), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpne.w", two (0x07e0, 0x0698), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpgt.h", two (0x07e0, 0x061a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpgt.w", two (0x07e0, 0x069a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpge.h", two (0x07e0, 0x061c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vcmpge.w", two (0x07e0, 0x069c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vselgt.h", two (0x07e0, 0x061e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vselgt.w", two (0x07e0, 0x069e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsells.h", two (0x07e0, 0x0620), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsells.w", two (0x07e0, 0x06a0), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vabs.h", two (0x07e0, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vabs.w", two (0x07e0, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vneg.h", two (0x07e1, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vneg.w", two (0x07e1, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmaxmum.h", two (0x07e2, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmaxmum.w", two (0x07e2, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vminmum.h", two (0x07e3, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vminmum.w", two (0x07e3, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "maxelm", two (0x07e0, 0x065a), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "minelm", two (0x07e0, 0x065c), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmad.h", two (0x07e0, 0x0628), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmad.w", two (0x07e0, 0x06a8), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsb.h", two (0x07e0, 0x062a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsb.w", two (0x07e0, 0x06aa), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadsat.h", two (0x07e0, 0x062c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadsat.w", two (0x07e0, 0x06ac), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbsat.h", two (0x07e0, 0x062e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbsat.w", two (0x07e0, 0x06ae), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadrn.h", two (0x07e0, 0x0630), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadrn.w", two (0x07e0, 0x06b0), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbrn.h", two (0x07e0, 0x0632), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbrn.w", two (0x07e0, 0x06b2), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmads.h", two (0x07e0, 0x0638), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmads.w", two (0x07e0, 0x06b8), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbs.h", two (0x07e0, 0x063a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbs.w", two (0x07e0, 0x06ba), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadrnim.h", two (0x07e0, 0x0634), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadrnim.w", two (0x07e0, 0x06b4), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbrnre.h", two (0x07e0, 0x0636), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbrnre.w", two (0x07e0, 0x06b6), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadsim.h", two (0x07e0, 0x063c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmadsim.w", two (0x07e0, 0x06bc), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbsre.h", two (0x07e0, 0x063e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsbsre.w", two (0x07e0, 0x06be), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumrn.h", two (0x07e0, 0x0640), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumrn.w", two (0x07e0, 0x06c0), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumad.h", two (0x07e0, 0x0642), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumad.w", two (0x07e0, 0x06c2), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadre.h", two (0x07e0, 0x0648), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadre.w", two (0x07e0, 0x06c8), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadim.h", two (0x07e0, 0x0646), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadim.w", two (0x07e0, 0x06c6), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrn.h", two (0x07e0, 0x0644), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrn.w", two (0x07e0, 0x06c4), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrnbq1.h", two (0x07e0, 0x064a), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrnbq2.h", two (0x07e0, 0x064c), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrnbq2d.h", two (0x07e0, 0x064e), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmsumadrnbq.w", two (0x07e0, 0x06ca), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vuconv.bh", two (0x07e0, 0x0670), two (0x07e0, 0x07f1), {DI3, VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "viconv.hw", two (0x07e0, 0x0660), two (0x07e0, 0x07f9), {DI2, VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vfconv.hw", two (0x07e0, 0x0668), two (0x07e0, 0x07f9), {DI2, VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vusatpk.hb", two (0x07e0, 0x0622), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsatpk.wh", two (0x07e0, 0x0624), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vrnpk.wh", two (0x07e0, 0x0626), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vusatpk.hh", two (0x07e6, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "sat.h", two (0x07e4, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "sat.w", two (0x07e4, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "rn.h", two (0x07e5, 0x065e), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "rn.w", two (0x07e5, 0x06de), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, + +/* VECTOR operation */ +{ "vand", two (0x07e0, 0x07c8), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vandn", two (0x07e0, 0x07ca), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vor", two (0x07e0, 0x07cc), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vxor", two (0x07e0, 0x07ce), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vnot", two (0x07e6, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar.h", two (0x07e0, 0x0780), two (0x07f0, 0x07ff), {I4U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar.h", two (0x07e0, 0x0794), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar.w", two (0x07e0, 0x0782), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar.w", two (0x07e0, 0x0796), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar", two (0x07e0, 0x0784), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vsar", two (0x07e0, 0x0798), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr.h", two (0x07e0, 0x0786), two (0x07f0, 0x07ff), {I4U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr.h", two (0x07e0, 0x079a), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr.w", two (0x07e0, 0x0788), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr.w", two (0x07e0, 0x079c), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr", two (0x07e0, 0x078a), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshr", two (0x07e0, 0x079e), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl.h", two (0x07e0, 0x078c), two (0x07f0, 0x07ff), {I4U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl.h", two (0x07e0, 0x07a0), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl.w", two (0x07e0, 0x078e), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl.w", two (0x07e0, 0x07a2), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl", two (0x07e0, 0x0790), two (0x07e0, 0x07ff), {I5U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshl", two (0x07e0, 0x07a4), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vrotater.b", two (0x07e0, 0x0792), two (0x07f8, 0x07ff), {I3U, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vmerge.h", two (0x07e0, 0x07a8), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vshufl.h", two (0x07e0, 0x07a6), two (0x07e0, 0x07ff), {R1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vconcat.h", two (0x07e0, 0x07b0), two (0x07e0, 0x07f9), {DI2, VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvuw.h", two (0x07e0, 0x07d0), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvlw.h", two (0x07e0, 0x07d2), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvuh.h", two (0x07e0, 0x07d4), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvlh.h", two (0x07e0, 0x07d6), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvu.w", two (0x07e0, 0x07d8), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvl.w", two (0x07e0, 0x07da), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvw.h", two (0x07e0, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlvh.h", two (0x07e1, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vitlv.w", two (0x07e2, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vpicku.h", two (0x07e0, 0x07dc), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vpickl.h", two (0x07e0, 0x07de), two (0x07e0, 0x07ff), {VR1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vpick.h", two (0x07e3, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mvgv.h", two (0x07fc, 0x07ac), two (0x07fc, 0x07ff), {VI2, R2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mvgv.w", two (0x07fa, 0x07ac), two (0x07fe, 0x07ac), {VC1, R2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mvgv.dw", two (0x07e7, 0x07ac), two (0x0fff, 0x07ff), {R2_EVEN, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "dupgv.h", two (0x07e2, 0x07aa), two (0x07f7, 0x07ff), {VI1, R2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "dupgv.w", two (0x07e3, 0x07aa), two (0x07ff, 0x07ff), {R2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mvvg.h", two (0x07f0, 0x07ac), two (0x07fc, 0x07ff), {VI2, VR2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "mvvg.w", two (0x07ea, 0x07ac), two (0x07fe, 0x07ff), {VC1, VR2, R3}, 0, PROCESSOR_V850E2V3 }, +{ "mvvg.dw", two (0x07e4, 0x07ac), two (0x07ff, 0x0fff), {VR2, R3_EVEN}, 0, PROCESSOR_V850E2V3 }, +{ "dup.h", two (0x07e0, 0x07aa), two (0x07f3, 0x07ff), {VI2DUP, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "dup.w", two (0x07e1, 0x07aa), two (0x07f7, 0x07ff), {VI1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mv.h", two (0x07f4, 0x07ac), two (0x07fc, 0x07ff), {VI2, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mv.w", two (0x07f8, 0x07ac), two (0x07fe, 0x07ff), {VC1, VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "mv", two (0x07e5, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, + +{ "ptldv.b", two (0x07e0, 0x07f8), two (0x07e0, 0x07ff), {R1, R2, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.b", two (0x07e0, 0x07fa), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.b", two (0x0fe0, 0x07fa), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.h", two (0x07e0, 0x07f0), two (0x07e0, 0x07ff), {R1, R2, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.h", two (0x07e0, 0x07f2), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.h", two (0x0fe0, 0x07f2), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.w", two (0x07e0, 0x07e8), two (0x07e0, 0x07ff), {R1, R2, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.w", two (0x07e0, 0x07ea), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.w", two (0x0fe0, 0x07ea), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.dw", two (0x07e0, 0x07e0), two (0x07e0, 0x07ff), {R1, R2, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.dw", two (0x07e0, 0x07e2), two (0x0fe0, 0x07ff), {R1_BANG, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptldv.dw", two (0x0fe0, 0x07e2), two (0x0fe0, 0x07ff), {R1_PERCENT, R2_EVEN, VR3}, 1, PROCESSOR_V850E2V3 }, +{ "ptstv.dw", two (0x07e0, 0x07e4), two (0x07e0, 0x07ff), {VR3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.dw", two (0x07e0, 0x07e6), two (0x0fe0, 0x07ff), {VR3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.dw", two (0x0fe0, 0x07e6), two (0x0fe0, 0x07ff), {VR3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, + +{ "ptstv.b", two (0x07e0, 0x07fc), two (0x07e0, 0x07ff), {VR3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.b", two (0x07e0, 0x07fe), two (0x0fe0, 0x07ff), {VR3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.b", two (0x0fe0, 0x07fe), two (0x0fe0, 0x07ff), {VR3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.h", two (0x07e0, 0x07f4), two (0x07e0, 0x07ff), {VR3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.h", two (0x07e0, 0x07f6), two (0x0fe0, 0x07ff), {VR3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.h", two (0x0fe0, 0x07f6), two (0x0fe0, 0x07ff), {VR3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.w", two (0x07e0, 0x07ec), two (0x07e0, 0x07ff), {VR3, R1, R2}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.w", two (0x07e0, 0x07ee), two (0x0fe0, 0x07ff), {VR3, R1_BANG, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, +{ "ptstv.w", two (0x0fe0, 0x07ee), two (0x0fe0, 0x07ff), {VR3, R1_PERCENT, R2_EVEN}, 2, PROCESSOR_V850E2V3 }, + +{ "vregshr.h", two (0x07e8, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, +{ "vregshl.h", two (0x07e9, 0x07ac), two (0x07ff, 0x07ff), {VR2, VR3}, 0, PROCESSOR_V850E2V3 }, + +{ 0, 0, 0, {0}, 0, 0 }, } ; const int v850_num_opcodes =