mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-07-21 10:24:33 +00:00
target-tricore: Add instructions of RR opcode format, that have 0xf as the first opcode
Add instructions of RR opcode format, that have 0xf as the first opcode. Add helper functions: * clo/z/s: Counts leading ones/zeros/signs. * clo/z/s_h: Count leading ones/zeros/signs in two haflwords. * sh/_h: Shifts one/two word/hwords. * sha/_h: Shifts one/two word/hwords arithmeticly. Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
d5de7839d7
commit
0b79a78169
|
@ -64,6 +64,18 @@ DEF_HELPER_FLAGS_2(min_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
DEF_HELPER_FLAGS_2(min_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
DEF_HELPER_FLAGS_2(min_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
DEF_HELPER_FLAGS_2(min_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
DEF_HELPER_FLAGS_2(min_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
DEF_HELPER_FLAGS_2(min_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
DEF_HELPER_FLAGS_2(min_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
|
/* count leading ... */
|
||||||
|
DEF_HELPER_FLAGS_1(clo, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_1(clo_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_1(clz_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_1(cls, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_1(cls_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||||
|
/* sh */
|
||||||
|
DEF_HELPER_FLAGS_2(sh, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
|
DEF_HELPER_FLAGS_2(sh_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||||
|
DEF_HELPER_3(sha, i32, env, i32, i32)
|
||||||
|
DEF_HELPER_2(sha_h, i32, i32, i32)
|
||||||
/* CSA */
|
/* CSA */
|
||||||
DEF_HELPER_2(call, void, env, i32)
|
DEF_HELPER_2(call, void, env, i32)
|
||||||
DEF_HELPER_1(ret, void, env)
|
DEF_HELPER_1(ret, void, env)
|
||||||
|
|
|
@ -873,6 +873,166 @@ EXTREMA_H_B(min, <)
|
||||||
|
|
||||||
#undef EXTREMA_H_B
|
#undef EXTREMA_H_B
|
||||||
|
|
||||||
|
uint32_t helper_clo(target_ulong r1)
|
||||||
|
{
|
||||||
|
return clo32(r1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_clo_h(target_ulong r1)
|
||||||
|
{
|
||||||
|
uint32_t ret_hw0 = extract32(r1, 0, 16);
|
||||||
|
uint32_t ret_hw1 = extract32(r1, 16, 16);
|
||||||
|
|
||||||
|
ret_hw0 = clo32(ret_hw0 << 16);
|
||||||
|
ret_hw1 = clo32(ret_hw1 << 16);
|
||||||
|
|
||||||
|
if (ret_hw0 > 16) {
|
||||||
|
ret_hw0 = 16;
|
||||||
|
}
|
||||||
|
if (ret_hw1 > 16) {
|
||||||
|
ret_hw1 = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_hw0 | (ret_hw1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_clz(target_ulong r1)
|
||||||
|
{
|
||||||
|
return clz32(r1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_clz_h(target_ulong r1)
|
||||||
|
{
|
||||||
|
uint32_t ret_hw0 = extract32(r1, 0, 16);
|
||||||
|
uint32_t ret_hw1 = extract32(r1, 16, 16);
|
||||||
|
|
||||||
|
ret_hw0 = clz32(ret_hw0 << 16);
|
||||||
|
ret_hw1 = clz32(ret_hw1 << 16);
|
||||||
|
|
||||||
|
if (ret_hw0 > 16) {
|
||||||
|
ret_hw0 = 16;
|
||||||
|
}
|
||||||
|
if (ret_hw1 > 16) {
|
||||||
|
ret_hw1 = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_hw0 | (ret_hw1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_cls(target_ulong r1)
|
||||||
|
{
|
||||||
|
return clrsb32(r1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_cls_h(target_ulong r1)
|
||||||
|
{
|
||||||
|
uint32_t ret_hw0 = extract32(r1, 0, 16);
|
||||||
|
uint32_t ret_hw1 = extract32(r1, 16, 16);
|
||||||
|
|
||||||
|
ret_hw0 = clrsb32(ret_hw0 << 16);
|
||||||
|
ret_hw1 = clrsb32(ret_hw1 << 16);
|
||||||
|
|
||||||
|
if (ret_hw0 > 15) {
|
||||||
|
ret_hw0 = 15;
|
||||||
|
}
|
||||||
|
if (ret_hw1 > 15) {
|
||||||
|
ret_hw1 = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_hw0 | (ret_hw1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_sh(target_ulong r1, target_ulong r2)
|
||||||
|
{
|
||||||
|
int32_t shift_count = sextract32(r2, 0, 6);
|
||||||
|
|
||||||
|
if (shift_count == -32) {
|
||||||
|
return 0;
|
||||||
|
} else if (shift_count < 0) {
|
||||||
|
return r1 >> -shift_count;
|
||||||
|
} else {
|
||||||
|
return r1 << shift_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
|
||||||
|
{
|
||||||
|
int32_t ret_hw0, ret_hw1;
|
||||||
|
int32_t shift_count;
|
||||||
|
|
||||||
|
shift_count = sextract32(r2, 0, 5);
|
||||||
|
|
||||||
|
if (shift_count == -16) {
|
||||||
|
return 0;
|
||||||
|
} else if (shift_count < 0) {
|
||||||
|
ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
|
||||||
|
ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
|
||||||
|
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
|
||||||
|
} else {
|
||||||
|
ret_hw0 = extract32(r1, 0, 16) << shift_count;
|
||||||
|
ret_hw1 = extract32(r1, 16, 16) << shift_count;
|
||||||
|
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
|
||||||
|
{
|
||||||
|
int32_t shift_count;
|
||||||
|
int64_t result, t1;
|
||||||
|
uint32_t ret;
|
||||||
|
|
||||||
|
shift_count = sextract32(r2, 0, 6);
|
||||||
|
t1 = sextract32(r1, 0, 32);
|
||||||
|
|
||||||
|
if (shift_count == 0) {
|
||||||
|
env->PSW_USB_C = env->PSW_USB_V = 0;
|
||||||
|
ret = r1;
|
||||||
|
} else if (shift_count == -32) {
|
||||||
|
env->PSW_USB_C = r1;
|
||||||
|
env->PSW_USB_V = 0;
|
||||||
|
ret = t1 >> 31;
|
||||||
|
} else if (shift_count > 0) {
|
||||||
|
result = t1 << shift_count;
|
||||||
|
/* calc carry */
|
||||||
|
env->PSW_USB_C = ((result & 0xffffffff00000000) != 0);
|
||||||
|
/* calc v */
|
||||||
|
env->PSW_USB_V = (((result > 0x7fffffffLL) ||
|
||||||
|
(result < -0x80000000LL)) << 31);
|
||||||
|
/* calc sv */
|
||||||
|
env->PSW_USB_SV |= env->PSW_USB_V;
|
||||||
|
ret = (uint32_t)result;
|
||||||
|
} else {
|
||||||
|
env->PSW_USB_V = 0;
|
||||||
|
env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
|
||||||
|
ret = t1 >> -shift_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->PSW_USB_AV = ret ^ ret * 2u;
|
||||||
|
env->PSW_USB_SAV |= env->PSW_USB_AV;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
|
||||||
|
{
|
||||||
|
int32_t shift_count;
|
||||||
|
int32_t ret_hw0, ret_hw1;
|
||||||
|
|
||||||
|
shift_count = sextract32(r2, 0, 5);
|
||||||
|
|
||||||
|
if (shift_count == 0) {
|
||||||
|
return r1;
|
||||||
|
} else if (shift_count < 0) {
|
||||||
|
ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
|
||||||
|
ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
|
||||||
|
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
|
||||||
|
} else {
|
||||||
|
ret_hw0 = sextract32(r1, 0, 16) << shift_count;
|
||||||
|
ret_hw1 = sextract32(r1, 16, 16) << shift_count;
|
||||||
|
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* context save area (CSA) related helpers */
|
/* context save area (CSA) related helpers */
|
||||||
|
|
||||||
static int cdc_increment(target_ulong *psw)
|
static int cdc_increment(target_ulong *psw)
|
||||||
|
|
|
@ -4196,6 +4196,81 @@ static void decode_rr_accumulator(CPUTriCoreState *env, DisasContext *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void decode_rr_logical_shift(CPUTriCoreState *env, DisasContext *ctx)
|
||||||
|
{
|
||||||
|
uint32_t op2;
|
||||||
|
int r3, r2, r1;
|
||||||
|
TCGv temp;
|
||||||
|
|
||||||
|
r3 = MASK_OP_RR_D(ctx->opcode);
|
||||||
|
r2 = MASK_OP_RR_S2(ctx->opcode);
|
||||||
|
r1 = MASK_OP_RR_S1(ctx->opcode);
|
||||||
|
|
||||||
|
temp = tcg_temp_new();
|
||||||
|
op2 = MASK_OP_RR_OP2(ctx->opcode);
|
||||||
|
|
||||||
|
switch (op2) {
|
||||||
|
case OPC2_32_RR_AND:
|
||||||
|
tcg_gen_and_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_ANDN:
|
||||||
|
tcg_gen_andc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLO:
|
||||||
|
gen_helper_clo(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLO_H:
|
||||||
|
gen_helper_clo_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLS:
|
||||||
|
gen_helper_cls(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLS_H:
|
||||||
|
gen_helper_cls_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLZ:
|
||||||
|
gen_helper_clz(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_CLZ_H:
|
||||||
|
gen_helper_clz_h(cpu_gpr_d[r3], cpu_gpr_d[r1]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_NAND:
|
||||||
|
tcg_gen_nand_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_NOR:
|
||||||
|
tcg_gen_nor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_OR:
|
||||||
|
tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_ORN:
|
||||||
|
tcg_gen_orc_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_SH:
|
||||||
|
gen_helper_sh(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_SH_H:
|
||||||
|
gen_helper_sh_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_SHA:
|
||||||
|
gen_helper_sha(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_SHA_H:
|
||||||
|
gen_helper_sha_h(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_SHAS:
|
||||||
|
gen_shas(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_XNOR:
|
||||||
|
tcg_gen_eqv_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
case OPC2_32_RR_XOR:
|
||||||
|
tcg_gen_xor_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
}
|
||||||
|
|
||||||
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||||
{
|
{
|
||||||
int op1;
|
int op1;
|
||||||
|
@ -4431,6 +4506,9 @@ static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
|
||||||
case OPCM_32_RR_ACCUMULATOR:
|
case OPCM_32_RR_ACCUMULATOR:
|
||||||
decode_rr_accumulator(env, ctx);
|
decode_rr_accumulator(env, ctx);
|
||||||
break;
|
break;
|
||||||
|
case OPCM_32_RR_LOGICAL_SHIFT:
|
||||||
|
decode_rr_logical_shift(env, ctx);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue