mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-21 00:31:50 +00:00
Fix floating-point single precision load/store (VEX's jm-ppc-test -f)
This commit is contained in:
parent
c071cd14f6
commit
635ee55a5d
@ -237,19 +237,11 @@ DEFINE_REG(31);
|
||||
#endif
|
||||
|
||||
#ifndef do_load_single
|
||||
#define do_load_single(REG, EA) do { \
|
||||
any_register *x = (any_register *)&FD; \
|
||||
x->i = vm_read_memory_4(EA); \
|
||||
REG = (double)x->f; \
|
||||
} while (0)
|
||||
#define do_load_single(REG, EA) REG##_dw = fp_load_single_convert(vm_read_memory_4(EA))
|
||||
#endif
|
||||
|
||||
#ifndef do_store_single
|
||||
#define do_store_single(REG, EA) do { \
|
||||
any_register *x = (any_register *)&FD; \
|
||||
x->f = (float)REG; \
|
||||
vm_write_memory_4(EA, x->i); \
|
||||
} while (0)
|
||||
#define do_store_single(REG, EA) vm_write_memory_4(EA, fp_store_single_convert(REG##_dw))
|
||||
#endif
|
||||
|
||||
#ifndef do_load_double
|
||||
|
@ -616,24 +616,21 @@ void powerpc_cpu::execute_fp_loadstore(uint32 opcode)
|
||||
const uint32 a = RA::get(this, opcode);
|
||||
const uint32 b = RB::get(this, opcode);
|
||||
const uint32 ea = a + b;
|
||||
uint64 v;
|
||||
|
||||
if (LD) {
|
||||
if (DB)
|
||||
operand_fp_dw_RD::set(this, opcode, vm_read_memory_8(ea));
|
||||
else {
|
||||
any_register x;
|
||||
x.i = vm_read_memory_4(ea);
|
||||
operand_fp_RD::set(this, opcode, (double)x.f);
|
||||
}
|
||||
v = vm_read_memory_8(ea);
|
||||
else
|
||||
v = fp_load_single_convert(vm_read_memory_4(ea));
|
||||
operand_fp_dw_RD::set(this, opcode, v);
|
||||
}
|
||||
else {
|
||||
v = operand_fp_dw_RS::get(this, opcode);
|
||||
if (DB)
|
||||
vm_write_memory_8(ea, operand_fp_dw_RS::get(this, opcode));
|
||||
else {
|
||||
any_register x;
|
||||
x.f = (float)operand_fp_RS::get(this, opcode);
|
||||
vm_write_memory_4(ea, x.i);
|
||||
}
|
||||
vm_write_memory_8(ea, v);
|
||||
else
|
||||
vm_write_memory_4(ea, fp_store_single_convert(v));
|
||||
}
|
||||
|
||||
if (UP)
|
||||
|
@ -191,6 +191,39 @@ DEFINE_HELPER(do_execute_divide, (uint32 RA, uint32 RB))
|
||||
RETURN(RD);
|
||||
}
|
||||
|
||||
/**
|
||||
* FP load/store
|
||||
**/
|
||||
|
||||
// C.6 Floating-Point Load Instructions
|
||||
static inline uint64 fp_load_single_convert(uint32 v)
|
||||
{
|
||||
// XXX we currently use the native floating-point capabilities
|
||||
any_register x;
|
||||
x.i = v;
|
||||
x.d = (double)x.f;
|
||||
return x.j;
|
||||
}
|
||||
|
||||
// C.7 Floating-Point Store Instructions
|
||||
static inline uint32 fp_store_single_convert(uint64 v)
|
||||
{
|
||||
int exp = (v >> 52) & 0x7ff;
|
||||
if (exp < 874 || exp > 896) {
|
||||
// No denormalization required (or "undefined" behaviour)
|
||||
// WORD[0 - 1] = frS[0 - 1]
|
||||
// WORD[2 - 31] = frS[5 - 34]
|
||||
return (uint32)(((v >> 32) & 0xc0000000) | ((v >> 29) & 0x3fffffff));
|
||||
}
|
||||
|
||||
// Handle denormalization (874 <= frS[1 - 11] <= 896
|
||||
// XXX we currently use the native floating-point capabilities
|
||||
any_register x;
|
||||
x.j = v;
|
||||
x.f = (float)x.d;
|
||||
return x.i;
|
||||
}
|
||||
|
||||
/**
|
||||
* FP classification
|
||||
**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user