diff options
-rw-r--r-- | MAINTAINERS | 8 | ||||
-rw-r--r-- | disas/nanomips.c | 148 | ||||
-rw-r--r-- | target/mips/cpu-defs.c.inc | 4 | ||||
-rw-r--r-- | target/mips/cpu.c | 6 | ||||
-rw-r--r-- | target/mips/tcg/octeon.decode | 2 | ||||
-rw-r--r-- | target/mips/tcg/translate.c | 14 |
6 files changed, 84 insertions, 98 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 28cc70c25f..caba73ec41 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -237,16 +237,10 @@ R: Jiaxun Yang <jiaxun.yang@flygoat.com> R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Odd Fixes F: target/mips/ -F: disas/mips.c +F: disas/*mips.c F: docs/system/cpu-models-mips.rst.inc F: tests/tcg/mips/ -MIPS TCG CPUs (nanoMIPS ISA) -M: Stefan Pejic <stefan.pejic@syrmia.com> -S: Maintained -F: disas/nanomips.* -F: target/mips/tcg/*nanomips* - NiosII TCG CPUs M: Chris Wulff <crwulff@gmail.com> M: Marek Vasut <marex@denx.de> diff --git a/disas/nanomips.c b/disas/nanomips.c index 9647f1a8e3..a0253598dd 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -30,10 +30,6 @@ #include "qemu/osdep.h" #include "disas/dis-asm.h" -#include <string.h> -#include <stdio.h> -#include <stdarg.h> - typedef int64_t int64; typedef uint64_t uint64; typedef uint32_t uint32; @@ -95,7 +91,7 @@ typedef struct Pool { #define IMGASSERTONCE(test) -static char *img_format(const char *format, ...) +static char * G_GNUC_PRINTF(1, 2) img_format(const char *format, ...) { char *buffer; va_list args; @@ -3252,7 +3248,8 @@ static char *CACHE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); + return img_format("CACHE 0x%" PRIx64 ", %" PRId64 "(%s)", + op_value, s_value, rs); } @@ -3274,7 +3271,8 @@ static char *CACHEE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); + return img_format("CACHEE 0x%" PRIx64 ", %" PRId64 "(%s)", + op_value, s_value, rs); } @@ -5173,7 +5171,7 @@ static char *DADDIU_48_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); - return img_format("DADDIU %s, %s", rt, s_value); + return img_format("DADDIU %s, %" PRId64, rt, s_value); } @@ -11859,7 +11857,7 @@ static char *PREF_S9_(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("PREF 0x%" PRIx64 ", %s(%s)", + return img_format("PREF 0x%" PRIx64 ", %" PRId64 "(%s)", hint_value, s_value, rs); } @@ -11905,7 +11903,8 @@ static char *PREFE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); + return img_format("PREFE 0x%" PRIx64 ", %" PRId64 "(%s)", + hint_value, s_value, rs); } @@ -12079,7 +12078,7 @@ static char *REPL_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); - return img_format("REPL.PH %s, %s", rt, s_value); + return img_format("REPL.PH %s, %" PRId64, rt, s_value); } @@ -12232,7 +12231,8 @@ static char *RESTOREF(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value); + return img_format("RESTOREF 0x%" PRIx64 ", 0x%" PRIx64, + u_value, count_value); } @@ -12613,7 +12613,7 @@ static char *SB_S9_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SB %s, %s(%s)", rt, s_value, rs); + return img_format("SB %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12659,7 +12659,7 @@ static char *SBE(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SBE %s, %s(%s)", rt, s_value, rs); + return img_format("SBE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12706,7 +12706,7 @@ static char *SC(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SC %s, %s(%s)", rt, s_value, rs); + return img_format("SC %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12729,7 +12729,7 @@ static char *SCD(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SCD %s, %s(%s)", rt, s_value, rs); + return img_format("SCD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12776,7 +12776,7 @@ static char *SCE(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SCE %s, %s(%s)", rt, s_value, rs); + return img_format("SCE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12868,7 +12868,7 @@ static char *SD_S9_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SD %s, %s(%s)", rt, s_value, rs); + return img_format("SD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12973,7 +12973,7 @@ static char *SDC1_S9_(uint64 instruction, Dis_info *info) const char *ft = FPR(ft_value, info); const char *rs = GPR(rs_value, info); - return img_format("SDC1 %s, %s(%s)", ft, s_value, rs); + return img_format("SDC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -13066,7 +13066,8 @@ static char *SDC2(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("SDC2 CP%" PRIu64 ", %s(%s)", cs_value, s_value, rs); + return img_format("SDC2 CP%" PRIu64 ", %" PRId64 "(%s)", + cs_value, s_value, rs); } @@ -13091,7 +13092,8 @@ static char *SDM(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); - return img_format("SDM %s, %s(%s), 0x%" PRIx64, rt, s_value, rs, count3); + return img_format("SDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -21905,24 +21907,36 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -static int nanomips_dis(char **buf, - Dis_info *info, - unsigned short one, - unsigned short two, - unsigned short three) +static bool nanomips_dis(const uint16_t *data, char **buf, Dis_info *info) { - uint16 bits[3] = {one, two, three}; - TABLE_ENTRY_TYPE type; - int size = Disassemble(bits, buf, &type, MAJOR, 2, info); - return size; + + /* Handle runtime errors. */ + if (unlikely(sigsetjmp(info->buf, 0) != 0)) { + return false; + } + return Disassemble(data, buf, &type, MAJOR, ARRAY_SIZE(MAJOR), info) >= 0; +} + +static bool read_u16(uint16_t *ret, bfd_vma memaddr, + struct disassemble_info *info) +{ + int status = (*info->read_memory_func)(memaddr, (bfd_byte *)ret, 2, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr, info); + return false; + } + + if ((info->endian == BFD_ENDIAN_BIG) != HOST_BIG_ENDIAN) { + bswap16s(ret); + } + return true; } int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) { - int status; - bfd_byte buffer[2]; - uint16_t insn1 = 0, insn2 = 0, insn3 = 0; + int length; + uint16_t words[3] = { }; g_autofree char *buf = NULL; info->bytes_per_chunk = 2; @@ -21939,70 +21953,38 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) disassm_info.fprintf_func = info->fprintf_func; disassm_info.stream = info->stream; - status = (*info->read_memory_func)(memaddr, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr, info); + if (!read_u16(&words[0], memaddr, info)) { return -1; } - - if (info->endian == BFD_ENDIAN_BIG) { - insn1 = bfd_getb16(buffer); - } else { - insn1 = bfd_getl16(buffer); - } - (*info->fprintf_func)(info->stream, "%04x ", insn1); + length = 2; /* Handle 32-bit opcodes. */ - if ((insn1 & 0x1000) == 0) { - status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 2, info); + if ((words[0] & 0x1000) == 0) { + if (!read_u16(&words[1], memaddr + 2, info)) { return -1; } + length = 4; - if (info->endian == BFD_ENDIAN_BIG) { - insn2 = bfd_getb16(buffer); - } else { - insn2 = bfd_getl16(buffer); + /* Handle 48-bit opcodes. */ + if ((words[0] >> 10) == 0x18) { + if (!read_u16(&words[1], memaddr + 4, info)) { + return -1; + } + length = 6; } - (*info->fprintf_func)(info->stream, "%04x ", insn2); - } else { - (*info->fprintf_func)(info->stream, " "); } - /* Handle 48-bit opcodes. */ - if ((insn1 >> 10) == 0x18) { - status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 4, info); - return -1; - } - if (info->endian == BFD_ENDIAN_BIG) { - insn3 = bfd_getb16(buffer); + for (int i = 0; i < ARRAY_SIZE(words); i++) { + if (i * 2 < length) { + (*info->fprintf_func)(info->stream, "%04x ", words[i]); } else { - insn3 = bfd_getl16(buffer); + (*info->fprintf_func)(info->stream, " "); } - (*info->fprintf_func)(info->stream, "%04x ", insn3); - } else { - (*info->fprintf_func)(info->stream, " "); } - /* Handle runtime errors. */ - if (sigsetjmp(disassm_info.buf, 0) != 0) { - info->insn_type = dis_noninsn; - return insn3 ? 6 : insn2 ? 4 : 2; + if (nanomips_dis(words, &buf, &disassm_info)) { + (*info->fprintf_func) (info->stream, "%s", buf); } - int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3); - - /* FIXME: Should probably use a hash table on the major opcode here. */ - - (*info->fprintf_func) (info->stream, "%s", buf); - if (length > 0) { - return length / 8; - } - - info->insn_type = dis_noninsn; - - return insn3 ? 6 : insn2 ? 4 : 2; + return length; } diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index 7f53c94ec8..480e60aeec 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -934,7 +934,7 @@ const mips_def_t mips_defs[] = (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) , + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) | (3U << CP0C4_MMUSizeExt), @@ -946,7 +946,7 @@ const mips_def_t mips_defs[] = .CP0_Status_rw_bitmask = 0x12F8FFFF, .SEGBITS = 42, .PABITS = 49, - .insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP, + .insn_flags = CPU_MIPS64R2 | INSN_OCTEON, .mmu_type = MMU_TYPE_R4000, }, diff --git a/target/mips/cpu.c b/target/mips/cpu.c index e997c1b9cb..7a565466cb 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -302,6 +302,12 @@ static void mips_cpu_reset(DeviceState *dev) env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ? 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); + if (env->insn_flags & INSN_LOONGSON2F) { + /* Loongson-2F has those bits hardcoded to 1 */ + env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) | + (1 << CP0St_UX); + } + /* * Vectored interrupts not implemented, timer on int 7, * no performance counters. diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode index 8929ad088e..0c787cb498 100644 --- a/target/mips/tcg/octeon.decode +++ b/target/mips/tcg/octeon.decode @@ -12,7 +12,7 @@ # BBIT132 111110 ..... ..... ................ %bbit_p 28:1 16:5 -BBIT 11 set:1 . 10 rs:5 ..... offset:16 p=%bbit_p +BBIT 11 set:1 . 10 rs:5 ..... offset:s16 p=%bbit_p # Arithmetic # BADDU rd, rs, rt diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 2f2d707a12..624e6b7786 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx) */ void check_cp1_64bitmode(DisasContext *ctx) { - if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { + if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { gen_reserved_instruction(ctx); } } @@ -12173,12 +12173,16 @@ enum { #include "nanomips_translate.c.inc" /* MIPSDSP functions. */ -static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, - int rd, int base, int offset) + +/* Indexed load is not for DSP only */ +static void gen_mips_lx(DisasContext *ctx, uint32_t opc, + int rd, int base, int offset) { TCGv t0; - check_dsp(ctx); + if (!(ctx->insn_flags & INSN_OCTEON)) { + check_dsp(ctx); + } t0 = tcg_temp_new(); if (base == 0) { @@ -14523,7 +14527,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_LBUX: case OPC_LHX: case OPC_LWX: - gen_mipsdsp_ld(ctx, op2, rd, rs, rt); + gen_mips_lx(ctx, op2, rd, rs, rt); break; default: /* Invalid */ MIPS_INVAL("MASK LX"); |