[RV64_DYNAREC] Extended simple wrapper for more int types (#2160)

This commit is contained in:
xctan 2024-12-17 15:23:51 +08:00 committed by GitHub
parent 485959195e
commit f65c22d329
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1679 additions and 346 deletions

View File

@ -842,24 +842,25 @@ def main(root: str, files: Iterable[Filename], ver: str):
# H could be allowed maybe?
allowed_simply: Dict[str, str] = {"ARM64": "v", "RV64": "v"}
allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWuIUlLp"}
allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWIUlLp"}
allowed_fpr : Dict[str, str] = {"ARM64": "fd", "RV64": "fd"}
allowed_sextw : Dict[str, str] = {"ARM64": "", "RV64": "cwiu"}
# Detect functions which return in an x87 register
retx87_wraps: Dict[ClausesStr, List[FunctionType]] = {}
return_x87: str = "D"
# Sanity checks
forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EcwiDVOSNHPAxXYb"}
forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EDVOSNHPAxXYb"}
assert(all(k in allowed_simply for k in forbidden_simple))
assert(all(k in allowed_regs for k in forbidden_simple))
assert(all(k in allowed_fpr for k in forbidden_simple))
for k1 in forbidden_simple:
assert(len(allowed_simply[k1]) + len(allowed_regs[k1]) + len(allowed_fpr[k1]) + len(forbidden_simple[k1]) == len(allowed_conv.values))
assert(len(allowed_simply[k1]) + len(allowed_regs[k1]) + len(allowed_fpr[k1]) + len(allowed_sextw[k1]) + len(forbidden_simple[k1]) == len(allowed_conv.values))
assert(all(c not in allowed_regs[k1] for c in allowed_simply[k1]))
assert(all(c not in allowed_simply[k1] + allowed_regs[k1] for c in allowed_fpr[k1]))
assert(all(c not in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] for c in forbidden_simple[k1]))
assert(all(c in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] + forbidden_simple[k1] for c in allowed_conv.values))
assert(all(c in allowed_simply[k1] + allowed_regs[k1] + allowed_fpr[k1] + allowed_sextw[k1] + forbidden_simple[k1] for c in allowed_conv.values))
assert(all(c in allowed_conv.values for c in return_x87))
assert(all(c in forbidden_simple[k] for c in depends_on_ld for k in forbidden_simple))
@ -872,6 +873,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
for k in forbidden_simple:
regs_count: int = 0
fpr_count : int = 0
sextw_mask: int = 0
if v.get_convention() is not allowed_conv:
continue
@ -884,6 +886,9 @@ def main(root: str, files: Iterable[Filename], ver: str):
fpr_count = fpr_count + 1
elif c in allowed_simply[k]:
continue
elif c in allowed_sextw[k]:
sextw_mask |= 1 << regs_count
regs_count += 1
else:
break
else:
@ -891,6 +896,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
if (regs_count <= 6) and (fpr_count <= 8):
# All checks passed!
ret_val = 1 + fpr_count
ret_val |= sextw_mask << 4
if v[0] in allowed_fpr[k]:
ret_val = -ret_val
ret[k] = ret_val

View File

@ -436,7 +436,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
if (isRetX87Wrapper(*(wrapper_t*)(addr)))
// return value will be on the stack, so the stack depth needs to be updated
x87_purgecache(dyn, ninst, 0, x3, x1, x4);
if (tmp < 0 || tmp > 1)
if (tmp < 0 || (tmp & 15) > 1)
tmp = 0; // TODO: removed when FP is in place
if ((box64_log < 2 && !cycle_log) && tmp) {
// GETIP(ip+3+8+8); // read the 0xCC
@ -932,7 +932,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
tmp = isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall + 2));
} else
tmp = 0;
if (tmp < 0 || tmp > 1)
if (tmp < 0 || (tmp & 15) > 1)
tmp = 0; // TODO: removed when FP is in place
if (dyn->insts[ninst].natcall && isRetX87Wrapper(*(wrapper_t*)(dyn->insts[ninst].natcall + 2)))
// return value will be on the stack, so the stack depth needs to be updated

View File

@ -844,6 +844,13 @@ void call_n(dynarec_rv64_t* dyn, int ninst, void* fnc, int w)
{
MAYUSE(fnc);
fpu_pushcache(dyn, ninst, x3, 1);
// check if additional sextw needed
int sextw_mask = ((w > 0 ? w : -w) >> 4) & 0b111111;
for (int i = 0; i < 6; i++) {
if (sextw_mask & (1 << i)) {
SEXT_W(A0+i, A0+i);
}
}
// native call
TABLE64(x3, (uintptr_t)fnc);
JALR(xRA, x3);

File diff suppressed because it is too large Load Diff