提交 3ad86e97 编写于 作者: Z Zihao Yu

Merge branch 'fix-rv64-muldiv' into 'rv64'

Fix rv64 muldiv

See merge request projectn/nemu!8
......@@ -30,6 +30,7 @@ make_EHelper(priv);
make_EHelper(mul);
make_EHelper(mulh);
make_EHelper(mulhsu);
make_EHelper(mulhu);
make_EHelper(div);
make_EHelper(divu);
......@@ -45,4 +46,4 @@ make_EHelper(remw);
make_EHelper(divuw);
make_EHelper(remuw);
make_EHelper(sraw);
make_EHelper(srlw);
\ No newline at end of file
make_EHelper(srlw);
......@@ -44,7 +44,7 @@ static OpcodeEntry op2_table [8] = {
};
static OpcodeEntry muldiv_table [8] = {
EX(mul), EX(mulh), EMPTY, EX(mulhu), EX(div), EX(divu), EX(rem), EX(remu)
EX(mul), EX(mulh), EX(mulhsu), EX(mulhu), EX(div), EX(divu), EX(rem), EX(remu)
};
static make_EHelper(op) {
......
......@@ -18,32 +18,77 @@ make_EHelper(mulhu) {
rtl_mul_hi(&s0, &id_src->val, &id_src2->val);
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(mulh);
print_asm_template3(mulhu);
}
make_EHelper(mulhsu) {
// Algorithm:
// We want to obtain ans = mulhsu(a, b).
// Consider mulhu(a, b).
// If a >= 0, then ans = mulhu(a, b);
// If a = -x < 0, then a = 2^64 - x in two's complement
// Then
// mulhu(a, b) = mulhu(2^64 -x , b) = ((2^64 - x)b) >> 64
// = ((2^64b) >> 64) + ((-xb) >> 64)
// = b + mulhsu(a, b) = b + ans
// Therefore, ans = mulhu(a, b) - b
//
// In the end, ans = (a < 0 ? mulhu(a, b) - b : mulhu(a, b))
// = mulhu(a, b) - (a < 0 ? b : 0)
rtl_sari(&s0, &id_src->val, 63);
rtl_and(&s0, &id_src2->val, &s0); // s0 = (id_src->val < 0 ? id_src2->val : 0)
rtl_mul_hi(&s1, &id_src->val, &id_src2->val);
rtl_sub(&s0, &s1, &s0);
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(mulhsu);
}
make_EHelper(div) {
rtl_idiv_q(&s0, &id_src->val, &id_src2->val);
if (id_src2->val == 0) {
rtl_li(&s0, -1);
} else if (id_src->val == 0x8000000000000000LL && id_src2->val == -1) {
rtl_mv(&s0, &id_src->val);
} else {
rtl_idiv_q(&s0, &id_src->val, &id_src2->val);
}
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(div);
}
make_EHelper(divu) {
rtl_div_q(&s0, &id_src->val, &id_src2->val);
if (id_src2->val == 0) {
rtl_li(&s0, -1);
} else {
rtl_div_q(&s0, &id_src->val, &id_src2->val);
}
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(divu);
}
make_EHelper(rem) {
rtl_idiv_r(&s0, &id_src->val, &id_src2->val);
if (id_src2->val == 0) {
rtl_mv(&s0, &id_src->val);
} else if (id_src->val == 0x8000000000000000LL && id_src2->val == -1) {
rtl_li(&s0, 0);
} else {
rtl_idiv_r(&s0, &id_src->val, &id_src2->val);
}
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(rem);
}
make_EHelper(remu) {
rtl_div_r(&s0, &id_src->val, &id_src2->val);
if (id_src2->val == 0) {
rtl_mv(&s0, &id_src->val);
} else {
rtl_div_r(&s0, &id_src->val, &id_src2->val);
}
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(remu);
......@@ -60,7 +105,13 @@ make_EHelper(mulw) {
make_EHelper(divw) {
rtl_sext(&s0, &id_src->val, 4);
rtl_sext(&s1, &id_src2->val, 4);
rtl_idiv_q(&s0, &s0, &s1);
if (s1 == 0) {
rtl_li(&s0, -1);
} else if (s0 == 0x80000000 && s1 == -1) {
//rtl_mv(&s0, &s0);
} else {
rtl_idiv_q(&s0, &s0, &s1);
}
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -70,7 +121,13 @@ make_EHelper(divw) {
make_EHelper(remw) {
rtl_sext(&s0, &id_src->val, 4);
rtl_sext(&s1, &id_src2->val, 4);
rtl_idiv_r(&s0, &s0, &s1);
if (s1 == 0) {
//rtl_mv(&s0, &s0);
} else if (s0 == 0x80000000 && s1 == -1) {
rtl_li(&s0, 0);
} else {
rtl_idiv_r(&s0, &s0, &s1);
}
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -80,7 +137,11 @@ make_EHelper(remw) {
make_EHelper(divuw) {
rtl_andi(&s0, &id_src->val, 0xffffffffu);
rtl_andi(&s1, &id_src2->val, 0xffffffffu);
rtl_div_q(&s0, &s0, &s1);
if (s1 == 0) {
rtl_li(&s0, -1);
} else {
rtl_div_q(&s0, &s0, &s1);
}
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -90,7 +151,11 @@ make_EHelper(divuw) {
make_EHelper(remuw) {
rtl_andi(&s0, &id_src->val, 0xffffffffu);
rtl_andi(&s1, &id_src2->val, 0xffffffffu);
rtl_div_r(&s0, &s0, &s1);
if (s1 == 0) {
//rtl_mv(&s0, &s0);
} else {
rtl_div_r(&s0, &s0, &s1);
}
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册