microblaze: Improve addkc
* Optimize handling when carry is not updated. * Optimize handling for adds with nop semantics. * Move code from helper_addkc to the translator making helper_addkc PURE and CONST. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
parent
2accfb5fa6
commit
40cbf5b709
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
DEF_HELPER_1(raise_exception, void, i32)
|
DEF_HELPER_1(raise_exception, void, i32)
|
||||||
DEF_HELPER_0(debug, void)
|
DEF_HELPER_0(debug, void)
|
||||||
DEF_HELPER_4(addkc, i32, i32, i32, i32, i32)
|
DEF_HELPER_FLAGS_3(addkc, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32, i32, i32)
|
||||||
DEF_HELPER_4(subkc, i32, i32, i32, i32, i32)
|
DEF_HELPER_4(subkc, i32, i32, i32, i32, i32)
|
||||||
DEF_HELPER_2(cmp, i32, i32, i32)
|
DEF_HELPER_2(cmp, i32, i32, i32)
|
||||||
DEF_HELPER_2(cmpu, i32, i32, i32)
|
DEF_HELPER_2(cmpu, i32, i32, i32)
|
||||||
|
@ -128,26 +128,14 @@ uint32_t helper_cmpu(uint32_t a, uint32_t b)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t helper_addkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
|
uint32_t helper_addkc(uint32_t a, uint32_t b, uint32_t cf)
|
||||||
{
|
{
|
||||||
uint32_t d, cf = 0, ncf;
|
uint32_t d, ncf;
|
||||||
|
|
||||||
if (c)
|
|
||||||
cf = env->sregs[SR_MSR] >> 31;
|
|
||||||
assert(cf == 0 || cf == 1);
|
|
||||||
d = a + b + cf;
|
d = a + b + cf;
|
||||||
|
|
||||||
if (!k) {
|
ncf = compute_carry(a, b, cf);
|
||||||
ncf = compute_carry(a, b, cf);
|
return ncf;
|
||||||
assert(ncf == 0 || ncf == 1);
|
|
||||||
if (ncf)
|
|
||||||
env->sregs[SR_MSR] |= MSR_C | MSR_CC;
|
|
||||||
else
|
|
||||||
env->sregs[SR_MSR] &= ~(MSR_C | MSR_CC);
|
|
||||||
}
|
|
||||||
D(qemu_log("%x = %x + %x cf=%d ncf=%d k=%d c=%d\n",
|
|
||||||
d, a, b, cf, ncf, k, c));
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t helper_subkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
|
uint32_t helper_subkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
|
||||||
|
@ -193,6 +193,7 @@ static inline TCGv *dec_alu_op_b(DisasContext *dc)
|
|||||||
static void dec_add(DisasContext *dc)
|
static void dec_add(DisasContext *dc)
|
||||||
{
|
{
|
||||||
unsigned int k, c;
|
unsigned int k, c;
|
||||||
|
TCGv cf;
|
||||||
|
|
||||||
k = dc->opcode & 4;
|
k = dc->opcode & 4;
|
||||||
c = dc->opcode & 2;
|
c = dc->opcode & 2;
|
||||||
@ -201,17 +202,47 @@ static void dec_add(DisasContext *dc)
|
|||||||
dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
|
dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
|
||||||
dc->rd, dc->ra, dc->rb);
|
dc->rd, dc->ra, dc->rb);
|
||||||
|
|
||||||
if (k && !c && dc->rd)
|
/* Take care of the easy cases first. */
|
||||||
tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
if (k) {
|
||||||
else if (dc->rd)
|
/* k - keep carry, no need to update MSR. */
|
||||||
gen_helper_addkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)),
|
/* If rd == r0, it's a nop. */
|
||||||
tcg_const_tl(k), tcg_const_tl(c));
|
if (dc->rd) {
|
||||||
else {
|
tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
||||||
TCGv d = tcg_temp_new();
|
|
||||||
gen_helper_addkc(d, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
|
if (c) {
|
||||||
tcg_const_tl(k), tcg_const_tl(c));
|
/* c - Add carry into the result. */
|
||||||
tcg_temp_free(d);
|
cf = tcg_temp_new();
|
||||||
|
|
||||||
|
read_carry(dc, cf);
|
||||||
|
tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
|
||||||
|
tcg_temp_free(cf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From now on, we can assume k is zero. So we need to update MSR. */
|
||||||
|
/* Extract carry. */
|
||||||
|
cf = tcg_temp_new();
|
||||||
|
if (c) {
|
||||||
|
read_carry(dc, cf);
|
||||||
|
} else {
|
||||||
|
tcg_gen_movi_tl(cf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dc->rd) {
|
||||||
|
TCGv ncf = tcg_temp_new();
|
||||||
|
gen_helper_addkc(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf);
|
||||||
|
tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
|
||||||
|
tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->rd], cf);
|
||||||
|
write_carry(dc, ncf);
|
||||||
|
tcg_temp_free(ncf);
|
||||||
|
} else {
|
||||||
|
gen_helper_addkc(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
|
||||||
|
tcg_const_tl(cf));
|
||||||
|
write_carry(dc, cf);
|
||||||
|
}
|
||||||
|
tcg_temp_free(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dec_sub(DisasContext *dc)
|
static void dec_sub(DisasContext *dc)
|
||||||
|
Loading…
Reference in New Issue
Block a user