Big endian opcode decoding is slightly different. Signed-off-by: Max Filippov <jcmvb...@gmail.com> --- configure | 7 ++++--- hw/xtensa_sample.c | 6 +++++- target-xtensa/translate.c | 31 +++++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/configure b/configure index 41a7007..c45c2a3 100755 --- a/configure +++ b/configure @@ -1029,6 +1029,7 @@ sh4eb-softmmu \ sparc-softmmu \ sparc64-softmmu \ xtensa-softmmu \ +xtensaeb-softmmu \ " fi # the following are Linux specific @@ -3016,7 +3017,7 @@ target_arch2=`echo $target | cut -d '-' -f 1` target_bigendian="no" case "$target_arch2" in - armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus) + armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb) target_bigendian=yes ;; esac @@ -3211,7 +3212,7 @@ case "$target_arch2" in unicore32) target_phys_bits=32 ;; - xtensa) + xtensa|xtensaeb) TARGET_ARCH=xtensa gdb_xml_files="xtensa-core.xml" target_phys_bits=32 @@ -3391,7 +3392,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_SPARC_DIS=y" >> $config_target_mak echo "CONFIG_SPARC_DIS=y" >> $libdis_config_mak ;; - xtensa) + xtensa*) echo "CONFIG_XTENSA_DIS=y" >> $config_target_mak echo "CONFIG_XTENSA_DIS=y" >> $libdis_config_mak ;; diff --git a/hw/xtensa_sample.c b/hw/xtensa_sample.c index 8103675..b1da7e1 100644 --- a/hw/xtensa_sample.c +++ b/hw/xtensa_sample.c @@ -32,9 +32,13 @@ static void xtensa_init(ram_addr_t ram_size, if (kernel_filename) { uint64_t elf_entry; uint64_t elf_lowaddr; - +#ifdef TARGET_WORDS_BIGENDIAN + int success = load_elf(kernel_filename, NULL, NULL, &elf_entry, + &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); +#else int success = load_elf(kernel_filename, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0); +#endif if (success > 0) { env->pc = elf_entry; } diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index a47efb0..da3120f 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -170,12 +170,21 @@ static void disas_xtensa_insn(DisasContext *dc) } while (0) +#ifdef TARGET_WORDS_BIGENDIAN #define _OP0 (((_b0) & 0xf0) >> 4) #define _OP1 (((_b2) & 0xf0) >> 4) #define _OP2 ((_b2) & 0xf) #define RRR_R ((_b1) & 0xf) #define RRR_S (((_b1) & 0xf0) >> 4) #define RRR_T ((_b0) & 0xf) +#else +#define _OP0 (((_b0) & 0xf)) +#define _OP1 (((_b2) & 0xf)) +#define _OP2 (((_b2) & 0xf0) >> 4) +#define RRR_R (((_b1) & 0xf0) >> 4) +#define RRR_S (((_b1) & 0xf)) +#define RRR_T (((_b0) & 0xf0) >> 4) +#endif #define RRRN_R RRR_R #define RRRN_S RRR_S @@ -187,20 +196,38 @@ static void disas_xtensa_insn(DisasContext *dc) #define RRI8_IMM8 (_b2) #define RRI8_IMM8_SE ((((_b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8) +#ifdef TARGET_WORDS_BIGENDIAN #define RI16_IMM16 (((_b1) << 8) | (_b2)) +#else +#define RI16_IMM16 (((_b2) << 8) | (_b1)) +#endif +#ifdef TARGET_WORDS_BIGENDIAN #define CALL_N (((_b0) & 0xc) >> 2) #define CALL_OFFSET ((((_b0) & 0x3) << 16) | ((_b1) << 8) | (_b2)) -#define CALL_OFFSET_SE (((_b0 & 0x2) ? 0xfffc0000 : 0) | CALL_OFFSET) +#else +#define CALL_N (((_b0) & 0x30) >> 4) +#define CALL_OFFSET ((((_b0) & 0xc0) >> 6) | ((_b1) << 2) | ((_b2) << 10)) +#endif +#define CALL_OFFSET_SE \ + (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET) #define CALLX_N CALL_N +#ifdef TARGET_WORDS_BIGENDIAN #define CALLX_M ((_b0) & 0x3) +#else +#define CALLX_M (((_b0) & 0xc0) >> 6) +#endif #define CALLX_S RRR_S #define BRI12_M CALLX_M #define BRI12_S RRR_S +#ifdef TARGET_WORDS_BIGENDIAN #define BRI12_IMM12 ((((_b1) & 0xf) << 8) | (_b2)) -#define BRI12_IMM12_SE ((((_b1) & 0x8) ? 0xfffff000 : 0) | BRI12_IMM12) +#else +#define BRI12_IMM12 ((((_b1) & 0xf0) >> 4) | ((_b2) << 4)) +#endif +#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12) #define BRI8_M BRI12_M #define BRI8_R RRI8_R -- 1.7.3.4