[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 15/15] target-tricore: Add instructions of SR opc
From: |
Bastian Koppelmann |
Subject: |
[Qemu-devel] [PATCH v3 15/15] target-tricore: Add instructions of SR opcode format |
Date: |
Mon, 4 Aug 2014 18:38:52 +0100 |
Add instructions of SR opcode format.
Add micro-op generator functions for saturate.
Add helper return from exception (rfe).
Signed-off-by: Bastian Koppelmann <address@hidden>
---
v2 -> v3:
- Fix CDC.COUNT calculation in cdc_zero.
- helper_ret now uses psw_write.
- Add missing temp_free to gen_saturate.
- RSUB: replace tcg_gen_subfi_tl with tcg_gen_net_tl.
target-tricore/helper.h | 1 +
target-tricore/op_helper.c | 52 +++++++++++++++++++++
target-tricore/translate.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 163 insertions(+)
diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 3c73234..7b7d74b 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -22,3 +22,4 @@ DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
DEF_HELPER_2(bisr, void, env, i32)
+DEF_HELPER_1(rfe, void, env)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index a4a6802..d0ca92a 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -95,6 +95,21 @@ static int cdc_decrement(target_ulong *psw)
return 0;
}
+static bool cdc_zero(target_ulong *psw)
+{
+ int cdc = *psw & MASK_PSW_CDC;
+ /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
+ 7'b1111111, otherwise returns FALSE. */
+ if (cdc == 0x7f) {
+ return true;
+ }
+ /* find CDC.COUNT */
+ int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
+ int mask = (1u << (7 - lo)) - 1;
+ int count = *psw & mask;
+ return count == 0;
+}
+
static void save_context_upper(CPUTRICOREState *env, int ea,
target_ulong *new_FCX)
{
@@ -298,6 +313,43 @@ void helper_bisr(CPUTRICOREState *env, uint32_t const9)
}
}
+void helper_rfe(CPUTRICOREState *env)
+{
+ target_ulong ea;
+ target_ulong new_PCXI;
+ target_ulong new_PSW;
+ /* if (PCXI[19: 0] == 0) then trap(CSU); */
+ if ((env->PCXI & 0xfffff) == 0) {
+ /* raise csu trap */
+ }
+ /* if (PCXI.UL == 0) then trap(CTYP); */
+ if ((env->PCXI & MASK_PCXI_UL) == 0) {
+ /* raise CTYP trap */
+ }
+ /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
+ if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
+ /* raise MNG trap */
+ }
+ /* ICR.IE = PCXI.PIE; */
+ env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
+ /* ICR.CCPN = PCXI.PCPN; */
+ env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
+ ((env->PCXI & MASK_PCXI_PCPN) >> 24);
+ /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
+ ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
+ ((env->PCXI & MASK_PCXI_PCXO) << 6);
+ /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
+ A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
+ M(EA, word) = FCX;*/
+ restore_context_upper(env, ea, &new_PCXI, &new_PSW);
+ /* FCX[19: 0] = PCXI[19: 0]; */
+ env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
+ /* PCXI = new_PCXI; */
+ env->PCXI = new_PCXI;
+ /* write psw */
+ psw_write(env, new_PSW);
+}
+
static inline void QEMU_NORETURN do_raise_exception_err(CPUTRICOREState *env,
uint32_t exception,
int error_code,
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 1ff0bbf..1e251da 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -201,6 +201,29 @@ static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
gen_calc_psw_sav_i32(cpu_PSW_SAV, cpu_PSW_AV);
}
+static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
+{
+ TCGv sat_neg = tcg_const_i32(low);
+ TCGv temp = tcg_const_i32(up);
+
+ /* sat_neg = (arg < low ) ? low : arg; */
+ tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, arg, sat_neg);
+
+ /* ret = (sat_neg > up ) ? up : sat_neg; */
+ tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
+
+ tcg_temp_free(sat_neg);
+ tcg_temp_free(temp);
+}
+
+static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
+{
+ TCGv temp = tcg_const_i32(up);
+ /* sat_neg = (arg > up ) ? up : arg; */
+ tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
+ tcg_temp_free(temp);
+}
+
#define OP_COND(insn)\
static inline void gen_cond_##insn(int cond, TCGv r1, TCGv r2, TCGv r3, \
TCGv r4) \
@@ -450,6 +473,15 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t
opc, int r1,
case OPC1_16_SBR_LOOP:
gen_loop(ctx, r1, offset * 2 - 32);
break;
+/* SR-format jumps */
+ case OPC1_16_SR_JI:
+ tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
+ tcg_gen_exit_tb(0);
+ break;
+ case OPC2_16_SR_RET:
+ gen_helper_ret(cpu_env);
+ tcg_gen_exit_tb(0);
+ break;
default:
printf("Branch Error at %x\n", ctx->pc);
}
@@ -766,6 +798,66 @@ static void decode_sro_opc(DisasContext *ctx, int op1)
}
}
+static void decode_sr_system(CPUTRICOREState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ op2 = MASK_OP_SR_OP2(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_16_SR_NOP:
+ break;
+ case OPC2_16_SR_RET:
+ gen_compute_branch(ctx, op2, 0, 0, 0, 0);
+ break;
+ case OPC2_16_SR_RFE:
+ gen_helper_rfe(cpu_env);
+ tcg_gen_exit_tb(0);
+ ctx->bstate = BS_BRANCH;
+ break;
+ case OPC2_16_SR_DEBUG:
+ /* raise EXCP_DEBUG */
+ break;
+ }
+}
+
+static void decode_sr_accu(CPUTRICOREState *env, DisasContext *ctx)
+{
+ uint32_t op2;
+ uint32_t r1;
+ TCGv temp, t0, t1;
+
+ r1 = MASK_OP_SR_S1D(ctx->opcode);
+ op2 = MASK_OP_SR_OP2(ctx->opcode);
+
+ switch (op2) {
+ case OPC2_16_SR_RSUB:
+ /* overflow only if r1 = -0x80000000 */
+ temp = tcg_const_i32(-0x80000000);
+ t0 = tcg_const_i32(0);
+ t1 = tcg_const_i32(1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r1], temp, t1,
t0);
+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_PSW_SV, cpu_gpr_d[r1], temp,
+ t1, cpu_PSW_SV);
+ tcg_gen_neg_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
+ tcg_temp_free(temp);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ break;
+ case OPC2_16_SR_SAT_B:
+ gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
+ break;
+ case OPC2_16_SR_SAT_BU:
+ gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
+ break;
+ case OPC2_16_SR_SAT_H:
+ gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
+ break;
+ case OPC2_16_SR_SAT_HU:
+ gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
+ break;
+ }
+}
+
static void decode_16Bit_opc(CPUTRICOREState *env, DisasContext *ctx)
{
int op1;
@@ -952,6 +1044,24 @@ static void decode_16Bit_opc(CPUTRICOREState *env,
DisasContext *ctx)
const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
break;
+/* SR-format */
+ case OPCM_16_SR_SYSTEM:
+ decode_sr_system(env, ctx);
+ break;
+ case OPCM_16_SR_ACCU:
+ decode_sr_accu(env, ctx);
+ break;
+ case OPC1_16_SR_JI:
+ r1 = MASK_OP_SR_S1D(ctx->opcode);
+ gen_compute_branch(ctx, op1, r1, 0, 0, 0);
+ break;
+ case OPC1_16_SR_NOT:
+ if (MASK_OP_SR_OP2(ctx->opcode) == 0x0) {
+ break;
+ }
+ r1 = MASK_OP_SR_S1D(ctx->opcode);
+ tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
+ break;
}
}
--
2.0.4
- [Qemu-devel] [PATCH v3 03/15] target-tricore: Add softmmu support, (continued)
- [Qemu-devel] [PATCH v3 03/15] target-tricore: Add softmmu support, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 10/15] target-tricore: Add instructions of SB opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 09/15] target-tricore: Add instructions of SRRS and SLRO opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 08/15] target-tricore: Add instructions of SSR opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 02/15] target-tricore: Add board for systemmode, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 04/15] target-tricore: Add initialization for translation and activate target, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 13/15] target-tricore: Add instructions of SC opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 06/15] target-tricore: Add instructions of SRC opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 14/15] target-tricore: Add instructions of SLR, SSRO and SRO opcode format, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 15/15] target-tricore: Add instructions of SR opcode format,
Bastian Koppelmann <=
- [Qemu-devel] [PATCH v3 05/15] target-tricore: Add masks and opcodes for decoding, Bastian Koppelmann, 2014/08/04
- [Qemu-devel] [PATCH v3 12/15] target-tricore: Add instructions of SBR opcode format, Bastian Koppelmann, 2014/08/04