提交 acde727d 编写于 作者: Z Zihao Yu

x86,exec,lazycc: pass eflagstest

* need refactor
上级 b1c27541
......@@ -101,7 +101,7 @@ static inline make_EHelper(adc) {
rtl_add(s, s1, ddest, s0);
#ifdef LAZY_CC
rtl_set_lazycc(s, s1, dsrc1, ddest, LAZYCC_ADC, id_dest->width);
rtl_set_lazycc(s, s1, s0, dsrc1, LAZYCC_ADC, id_dest->width);
#else
rtl_update_ZFSF(s, s1, id_dest->width);
rtl_is_add_overflow(s, s2, s1, ddest, dsrc1, id_dest->width);
......@@ -128,7 +128,7 @@ static inline make_EHelper(sbb) {
rtl_sub(s, s1, ddest, s0);
#ifdef LAZY_CC
rtl_set_lazycc(s, s1, ddest, s0, LAZYCC_SBB, id_dest->width);
rtl_set_lazycc(s, s1, ddest, dsrc1, LAZYCC_SBB, id_dest->width);
#else
rtl_update_ZFSF(s, s1, id_dest->width);
rtl_is_sub_overflow(s, s2, s1, ddest, dsrc1, id_dest->width);
......
......@@ -11,36 +11,49 @@ static inline make_rtl(set_lazycc, const rtlreg_t *dest, const rtlreg_t *src1, c
cpu.cc_width = width;
}
#define UNARY 0x100 // compare with cpu.cc_dest and rz
static const int cc2relop [] = {
[CC_O] = -1, [CC_NO] = -1,
[CC_O] = 0, [CC_NO] = 0,
[CC_B] = RELOP_LTU, [CC_NB] = RELOP_GEU,
[CC_E] = RELOP_EQ, [CC_NE] = RELOP_NE,
[CC_E] = UNARY | RELOP_EQ, [CC_NE] = UNARY | RELOP_NE,
[CC_BE] = RELOP_LEU, [CC_NBE] = RELOP_GTU,
[CC_S] = -1, [CC_NS] = -1,
[CC_P] = -1, [CC_NP] = -1,
[CC_S] = UNARY | RELOP_LT, [CC_NS] = UNARY | RELOP_GE,
[CC_P] = 0, [CC_NP] = 0,
[CC_L] = RELOP_LT, [CC_NL] = RELOP_GE,
[CC_LE] = RELOP_LE, [CC_NLE] = RELOP_GT,
};
static inline make_rtl(lazy_jcc, uint32_t cc) {
// common condition codes which only depend on cpu.cc_dest
switch (cc) {
case CC_E: rtl_jrelop(s, RELOP_EQ, &cpu.cc_dest, rz, s->jmp_pc); return;
case CC_NE: rtl_jrelop(s, RELOP_NE, &cpu.cc_dest, rz, s->jmp_pc); return;
case CC_S: rtl_jrelop(s, RELOP_LT, &cpu.cc_dest, rz, s->jmp_pc); return;
case CC_NS: rtl_jrelop(s, RELOP_GE, &cpu.cc_dest, rz, s->jmp_pc); return;
if (cc2relop[cc] & UNARY) {
uint32_t relop = cc2relop[cc] ^ UNARY;
rtlreg_t *p = &cpu.cc_dest;
if (cpu.cc_width != 4) {
rtl_shli(s, s2, &cpu.cc_dest, 32 - cpu.cc_width * 8);
p = s2;
}
rtl_jrelop(s, relop, p, rz, s->jmp_pc);
return;
}
switch (cpu.cc_op) {
case LAZYCC_DEC:
if (cc2relop[cc] != -1) {
if (cc2relop[cc] != 0) {
rtl_jrelop(s, cc2relop[cc], &cpu.cc_dest, rz, s->jmp_pc);
return;
}
break;
case LAZYCC_SBB: // FIXME: should consider CF
if (cc == CC_B) {
rtl_sub(s, s0, &cpu.cc_src1, &cpu.cc_dest);
rtl_is_add_carry(s, s0, s0, &cpu.cc_src2);
rtl_is_sub_carry(s, s1, &cpu.cc_src1, &cpu.cc_dest);
rtl_or(s, s0, s0, s1);
rtl_jrelop(s, RELOP_NE, s0, rz, s->jmp_pc);
return;
}
break;
case LAZYCC_SUB:
if (cc2relop[cc] != -1) {
if (cc2relop[cc] != 0) {
//Log("cc = %d, src1 = 0x%x, src2 = 0x%x", cc, cpu.cc_src1, cpu.cc_src2);
rtl_sub(s, t0, &cpu.cc_src1, &cpu.cc_dest);
rtl_jrelop(s, cc2relop[cc], &cpu.cc_src1, t0, s->jmp_pc);
......@@ -60,11 +73,97 @@ static inline make_rtl(lazy_jcc, uint32_t cc) {
}
static inline make_rtl(lazy_setcc, rtlreg_t *dest, uint32_t cc) {
if (cc2relop[cc] & UNARY) {
uint32_t relop = cc2relop[cc] ^ UNARY;
rtlreg_t *p = &cpu.cc_dest;
if (cpu.cc_width != 4) {
rtl_shli(s, dest, &cpu.cc_dest, 32 - cpu.cc_width * 8);
p = dest;
}
rtl_setrelop(s, relop, dest, p, rz);
return;
}
switch (cpu.cc_op) {
case LAZYCC_ADD:
if (cc2relop[cc] != 0) {
rtlreg_t *p = &cpu.cc_dest;
if (cpu.cc_width != 4) {
rtl_andi(s, dest, &cpu.cc_dest, 0xffffffffu >> ((4 - cpu.cc_width) * 8));
p = dest;
}
rtl_setrelop(s, cc2relop[cc], dest, p, &cpu.cc_src1);
return;
}
if (cc == CC_O) {
rtl_sub(s, dest, &cpu.cc_dest, &cpu.cc_src1);
rtl_is_add_overflow(s, dest, &cpu.cc_dest, &cpu.cc_src1, dest, cpu.cc_width);
return;
}
break;
case LAZYCC_SUB:
if (cc2relop[cc] != -1) {
rtl_sub(s, t0, &cpu.cc_src1, &cpu.cc_dest);
rtl_setrelop(s, cc2relop[cc], dest, &cpu.cc_src1, t0);
if (cc2relop[cc] != 0) {
rtl_sub(s, dest, &cpu.cc_src1, &cpu.cc_dest);
rtl_setrelop(s, cc2relop[cc], dest, &cpu.cc_src1, dest);
return;
}
if (cc == CC_O) {
rtl_sub(s, dest, &cpu.cc_src1, &cpu.cc_dest);
rtl_is_sub_overflow(s, dest, &cpu.cc_dest, &cpu.cc_src1, dest, cpu.cc_width);
return;
}
break;
case LAZYCC_NEG:
if (cc == CC_B) {
rtl_setrelopi(s, RELOP_NE, dest, &cpu.cc_dest, 0);
return;
}
if (cc == CC_O) {
rtl_setrelopi(s, RELOP_EQ, dest, &cpu.cc_dest, -(0x1u << (cpu.cc_width * 8 - 1)));
return;
}
break;
case LAZYCC_INC:
if (cc == CC_O) {
rtl_setrelopi(s, RELOP_EQ, dest, &cpu.cc_dest, 0x1u << (cpu.cc_width * 8 - 1));
return;
}
break;
case LAZYCC_DEC:
if (cc == CC_O) {
rtl_addi(s, dest, &cpu.cc_dest, 1);
rtl_setrelopi(s, RELOP_EQ, dest, dest, 0x1u << (cpu.cc_width * 8 - 1));
return;
}
break;
case LAZYCC_ADC:
if (cc == CC_B) {
rtlreg_t *p = &cpu.cc_dest;
if (cpu.cc_width != 4) {
rtl_andi(s, dest, &cpu.cc_dest, 0xffffffffu >> ((4 - cpu.cc_width) * 8));
p = dest;
}
rtl_is_add_carry(s, t0, &cpu.cc_src1, &cpu.cc_src2);
rtl_is_add_carry(s, dest, p, &cpu.cc_src1);
rtl_or(s, dest, t0, dest);
return;
}
if (cc == CC_O) {
rtl_sub(s, dest, &cpu.cc_dest, &cpu.cc_src1);
rtl_is_add_overflow(s, dest, &cpu.cc_dest, dest, &cpu.cc_src2, cpu.cc_width);
return;
}
break;
case LAZYCC_SBB:
if (cc == CC_B) {
rtl_sub(s, s0, &cpu.cc_src1, &cpu.cc_dest);
rtl_is_add_carry(s, s0, s0, &cpu.cc_src2);
rtl_is_sub_carry(s, s1, &cpu.cc_src1, &cpu.cc_dest);
rtl_or(s, dest, s0, s1);
return;
}
if (cc == CC_O) {
rtl_is_sub_overflow(s, dest, &cpu.cc_dest, &cpu.cc_src1, &cpu.cc_src2, cpu.cc_width);
return;
}
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册