[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/14] target-tilegx: Decode ill pseudo-instructions
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 11/14] target-tilegx: Decode ill pseudo-instructions |
Date: |
Thu, 1 Oct 2015 12:38:43 +1000 |
From: Chen Gang <address@hidden>
Notice raise and bpt, decoding the constants embedded in the
nop addil instruction in the x0 slot.
[rth: Generalize TILEGX_EXCP_OPCODE_ILL to TILEGX_EXCP_SIGNAL.
Drop validation of signal values.]
Signed-off-by: Chen Gang <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
linux-user/main.c | 14 ++++++++
target-tilegx/cpu.h | 5 ++-
target-tilegx/translate.c | 81 +++++++++++++++++++++++++++++++++++++++--------
3 files changed, 85 insertions(+), 15 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 25cf875..be3a7ad 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3436,6 +3436,17 @@ static void gen_sigill_reg(CPUTLGState *env)
queue_signal(env, info.si_signo, &info);
}
+static void do_signal(CPUTLGState *env)
+{
+ target_siginfo_t info;
+
+ info.si_signo = env->signo;
+ info.si_errno = 0;
+ info.si_code = env->sigcode;
+ info._sifields._sigfault._addr = env->pc;
+ queue_signal(env, info.si_signo, &info);
+}
+
static void set_regval(CPUTLGState *env, uint8_t reg, uint64_t val)
{
if (unlikely(reg >= TILEGX_R_COUNT)) {
@@ -3622,6 +3633,9 @@ void cpu_loop(CPUTLGState *env)
case TILEGX_EXCP_OPCODE_FETCHOR4:
do_fetch(env, trapnr, false);
break;
+ case TILEGX_EXCP_SIGNAL:
+ do_signal(env);
+ break;
case TILEGX_EXCP_REG_IDN_ACCESS:
case TILEGX_EXCP_REG_UDN_ACCESS:
gen_sigill_reg(env);
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index b9f5082..023ccd4 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -61,6 +61,7 @@ typedef enum {
TILEGX_EXCP_NONE = 0,
TILEGX_EXCP_SYSCALL = 1,
TILEGX_EXCP_SEGV = 2,
+ TILEGX_EXCP_SIGNAL = 3,
TILEGX_EXCP_OPCODE_UNKNOWN = 0x101,
TILEGX_EXCP_OPCODE_UNIMPLEMENTED = 0x102,
TILEGX_EXCP_OPCODE_CMPEXCH = 0x103,
@@ -87,10 +88,12 @@ typedef struct CPUTLGState {
uint64_t pc; /* Current pc */
#if defined(CONFIG_USER_ONLY)
+ uint64_t excaddr; /* exception address */
uint64_t atomic_srca; /* Arguments to atomic "exceptions" */
uint64_t atomic_srcb;
uint32_t atomic_dstr;
- uint64_t excaddr; /* exception address */
+ uint32_t signo; /* Signal number */
+ uint32_t sigcode; /* Signal code */
#endif
CPU_COMMON
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 3566b88..54aa71d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -23,6 +23,8 @@
#include "disas/disas.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
+#include "linux-user/syscall_defs.h"
+
#include "opcode_tilegx.h"
#include "spr_def_64.h"
@@ -429,8 +431,66 @@ static void gen_v4op(TCGv d64, TCGv a64, TCGv b64,
tcg_temp_free_i32(bh);
}
+static TileExcp gen_signal(DisasContext *dc, int signo, int sigcode,
+ const char *mnemonic)
+{
+ TCGv_i32 t0 = tcg_const_i32(signo);
+ TCGv_i32 t1 = tcg_const_i32(sigcode);
+
+ tcg_gen_st_i32(t0, cpu_env, offsetof(CPUTLGState, signo));
+ tcg_gen_st_i32(t1, cpu_env, offsetof(CPUTLGState, sigcode));
+
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(t0);
+
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
+ return TILEGX_EXCP_SIGNAL;
+}
+
+static bool parse_from_addli(uint64_t bundle, int *signo, int *sigcode)
+{
+ int imm;
+
+ if ((get_Opcode_X0(bundle) != ADDLI_OPCODE_X0)
+ || (get_Dest_X0(bundle) != TILEGX_R_ZERO)
+ || (get_SrcA_X0(bundle) != TILEGX_R_ZERO)) {
+ return false;
+ }
+
+ imm = get_Imm16_X0(bundle);
+ *signo = imm & 0x3f;
+ *sigcode = (imm >> 6) & 0xf;
+
+ /* ??? The linux kernel validates both signo and the sigcode vs the
+ known max for each signal. Don't bother here. */
+ return true;
+}
+
+static TileExcp gen_specill(DisasContext *dc, unsigned dest, unsigned srca,
+ uint64_t bundle)
+{
+ const char *mnemonic;
+ int signo;
+ int sigcode;
+
+ if (dest == 0x1c && srca == 0x25) {
+ signo = TARGET_SIGTRAP;
+ sigcode = TARGET_TRAP_BRKPT;
+ mnemonic = "bpt";
+ } else if (dest == 0x1d && srca == 0x25
+ && parse_from_addli(bundle, &signo, &sigcode)) {
+ mnemonic = "raise";
+ } else {
+ signo = TARGET_SIGILL;
+ sigcode = TARGET_ILL_ILLOPC;
+ mnemonic = "ill";
+ }
+
+ return gen_signal(dc, signo, sigcode, mnemonic);
+}
+
static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext,
- unsigned dest, unsigned srca)
+ unsigned dest, unsigned srca, uint64_t bundle)
{
TCGv tdest, tsrca;
const char *mnemonic;
@@ -458,16 +518,9 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned
opext,
mnemonic = "flushwb";
goto done0;
case OE_RR_X1(ILL):
- if (dest == 0x1c && srca == 0x25) {
- mnemonic = "bpt";
- goto done2;
- }
- /* Fall through */
+ return gen_specill(dc, dest, srca, bundle);
case OE_RR_Y1(ILL):
- mnemonic = "ill";
- done2:
- qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s", mnemonic);
- return TILEGX_EXCP_OPCODE_UNKNOWN;
+ return gen_signal(dc, TARGET_SIGILL, TARGET_ILL_ILLOPC, "ill");
case OE_RR_X1(MF):
mnemonic = "mf";
goto done0;
@@ -1909,7 +1962,7 @@ static TileExcp decode_y0(DisasContext *dc,
tilegx_bundle_bits bundle)
case RRR_1_OPCODE_Y0:
if (ext == UNARY_RRR_1_OPCODE_Y0) {
ext = get_UnaryOpcodeExtension_Y0(bundle);
- return gen_rr_opcode(dc, OE(opc, ext, Y0), dest, srca);
+ return gen_rr_opcode(dc, OE(opc, ext, Y0), dest, srca, bundle);
}
/* fallthru */
case RRR_0_OPCODE_Y0:
@@ -1955,7 +2008,7 @@ static TileExcp decode_y1(DisasContext *dc,
tilegx_bundle_bits bundle)
case RRR_1_OPCODE_Y1:
if (ext == UNARY_RRR_1_OPCODE_Y0) {
ext = get_UnaryOpcodeExtension_Y1(bundle);
- return gen_rr_opcode(dc, OE(opc, ext, Y1), dest, srca);
+ return gen_rr_opcode(dc, OE(opc, ext, Y1), dest, srca, bundle);
}
/* fallthru */
case RRR_0_OPCODE_Y1:
@@ -2057,7 +2110,7 @@ static TileExcp decode_x0(DisasContext *dc,
tilegx_bundle_bits bundle)
ext = get_RRROpcodeExtension_X0(bundle);
if (ext == UNARY_RRR_0_OPCODE_X0) {
ext = get_UnaryOpcodeExtension_X0(bundle);
- return gen_rr_opcode(dc, OE(opc, ext, X0), dest, srca);
+ return gen_rr_opcode(dc, OE(opc, ext, X0), dest, srca, bundle);
}
srcb = get_SrcB_X0(bundle);
return gen_rrr_opcode(dc, OE(opc, ext, X0), dest, srca, srcb);
@@ -2104,7 +2157,7 @@ static TileExcp decode_x1(DisasContext *dc,
tilegx_bundle_bits bundle)
switch (ext) {
case UNARY_RRR_0_OPCODE_X1:
ext = get_UnaryOpcodeExtension_X1(bundle);
- return gen_rr_opcode(dc, OE(opc, ext, X1), dest, srca);
+ return gen_rr_opcode(dc, OE(opc, ext, X1), dest, srca, bundle);
case ST1_RRR_0_OPCODE_X1:
return gen_st_opcode(dc, dest, srca, srcb, MO_UB, "st1");
case ST2_RRR_0_OPCODE_X1:
--
2.4.3
- [Qemu-devel] [PATCH 00/14] Collected tilegx patches, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 07/14] target-tilegx: Implement complex multiply instructions, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 09/14] linux-user/syscall_defs.h: Sync the latest si_code from Linux kernel, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 01/14] target-tilegx: Use V1 in simd_helper.c, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 03/14] target-tilegx: Implement v*add and v*sub instructions, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 13/14] target-tilegx: Fix a typo for mnemonic about "ld_add", Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 14/14] target-tilegx: Handle nofault prefetch instructions, Richard Henderson, 2015/10/08
- Message not available
- [Qemu-devel] [PATCH 11/14] target-tilegx: Decode ill pseudo-instructions,
Richard Henderson <=
- [Qemu-devel] [PATCH 12/14] target-tilegx: Use TILEGX_EXCP_SIGNAL instead of TILEGX_EXCP_SEGV, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 04/14] target-tilegx: Implement v1multu instruction, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 02/14] target-tilegx: Implement v*shl, v*shru, and v*shrs instructions, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 06/14] target-tilegx: Implement table index instructions, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 10/14] linux-user/tilegx: Implement tilegx signal features, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 05/14] target-tilegx: Implement crc instructions, Richard Henderson, 2015/10/08
- [Qemu-devel] [PATCH 08/14] target-tilegx: Let x1 pipe process bpt instruction only, Richard Henderson, 2015/10/08