A64: Implement SCVTF, UCVTF (scalar, fixed-point)
This commit is contained in:
parent
8051f60db0
commit
027b0ef725
2 changed files with 58 additions and 2 deletions
|
@ -878,8 +878,8 @@ INST(SHA512SU0, "SHA512SU0", "11001
|
||||||
INST(SM4E, "SM4E", "1100111011000000100001nnnnnddddd")
|
INST(SM4E, "SM4E", "1100111011000000100001nnnnnddddd")
|
||||||
|
|
||||||
// Data Processing - FP and SIMD - Conversion between floating point and fixed point
|
// Data Processing - FP and SIMD - Conversion between floating point and fixed point
|
||||||
//INST(SCVTF_float_fix, "SCVTF (scalar, fixed-point)", "z0011110yy000010ppppppnnnnnddddd")
|
INST(SCVTF_float_fix, "SCVTF (scalar, fixed-point)", "z0011110yy000010ppppppnnnnnddddd")
|
||||||
//INST(UCVTF_float_fix, "UCVTF (scalar, fixed-point)", "z0011110yy000011ppppppnnnnnddddd")
|
INST(UCVTF_float_fix, "UCVTF (scalar, fixed-point)", "z0011110yy000011ppppppnnnnnddddd")
|
||||||
INST(FCVTZS_float_fix, "FCVTZS (scalar, fixed-point)", "z0011110yy011000ppppppnnnnnddddd")
|
INST(FCVTZS_float_fix, "FCVTZS (scalar, fixed-point)", "z0011110yy011000ppppppnnnnnddddd")
|
||||||
INST(FCVTZU_float_fix, "FCVTZU (scalar, fixed-point)", "z0011110yy011001ppppppnnnnnddddd")
|
INST(FCVTZU_float_fix, "FCVTZU (scalar, fixed-point)", "z0011110yy011001ppppppnnnnnddddd")
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,62 @@
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SCVTF_float_fix(bool sf, Imm<2> type, Imm<6> scale, Reg Rn, Vec Vd) {
|
||||||
|
const size_t intsize = sf ? 64 : 32;
|
||||||
|
const auto fltsize = FPGetDataSize(type);
|
||||||
|
if (!fltsize || *fltsize == 16) {
|
||||||
|
return UnallocatedEncoding();
|
||||||
|
}
|
||||||
|
if (!sf && !scale.Bit<5>()) {
|
||||||
|
return UnallocatedEncoding();
|
||||||
|
}
|
||||||
|
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
||||||
|
const FP::RoundingMode rounding_mode = ir.current_location->FPCR().RMode();
|
||||||
|
|
||||||
|
const IR::U32U64 intval = X(intsize, Rn);
|
||||||
|
const IR::U32U64 fltval = [&]() -> IR::U32U64 {
|
||||||
|
switch (*fltsize) {
|
||||||
|
case 32:
|
||||||
|
return ir.FPSignedFixedToSingle(intval, fracbits, rounding_mode);
|
||||||
|
case 64:
|
||||||
|
return ir.FPSignedFixedToDouble(intval, fracbits, rounding_mode);
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}();
|
||||||
|
|
||||||
|
V_scalar(*fltsize, Vd, fltval);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::UCVTF_float_fix(bool sf, Imm<2> type, Imm<6> scale, Reg Rn, Vec Vd) {
|
||||||
|
const size_t intsize = sf ? 64 : 32;
|
||||||
|
const auto fltsize = FPGetDataSize(type);
|
||||||
|
if (!fltsize || *fltsize == 16) {
|
||||||
|
return UnallocatedEncoding();
|
||||||
|
}
|
||||||
|
if (!sf && !scale.Bit<5>()) {
|
||||||
|
return UnallocatedEncoding();
|
||||||
|
}
|
||||||
|
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
||||||
|
const FP::RoundingMode rounding_mode = ir.current_location->FPCR().RMode();
|
||||||
|
|
||||||
|
const IR::U32U64 intval = X(intsize, Rn);
|
||||||
|
const IR::U32U64 fltval = [&]() -> IR::U32U64 {
|
||||||
|
switch (*fltsize) {
|
||||||
|
case 32:
|
||||||
|
return ir.FPUnsignedFixedToSingle(intval, fracbits, rounding_mode);
|
||||||
|
case 64:
|
||||||
|
return ir.FPUnsignedFixedToDouble(intval, fracbits, rounding_mode);
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}();
|
||||||
|
|
||||||
|
V_scalar(*fltsize, Vd, fltval);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::FCVTZS_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec Vn, Reg Rd) {
|
bool TranslatorVisitor::FCVTZS_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec Vn, Reg Rd) {
|
||||||
const size_t intsize = sf ? 64 : 32;
|
const size_t intsize = sf ? 64 : 32;
|
||||||
const auto fltsize = FPGetDataSize(type);
|
const auto fltsize = FPGetDataSize(type);
|
||||||
|
|
Loading…
Reference in a new issue