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")
|
||||
|
||||
// Data Processing - FP and SIMD - Conversion between floating point and fixed point
|
||||
//INST(SCVTF_float_fix, "SCVTF (scalar, fixed-point)", "z0011110yy000010ppppppnnnnnddddd")
|
||||
//INST(UCVTF_float_fix, "UCVTF (scalar, fixed-point)", "z0011110yy000011ppppppnnnnnddddd")
|
||||
INST(SCVTF_float_fix, "SCVTF (scalar, fixed-point)", "z0011110yy000010ppppppnnnnnddddd")
|
||||
INST(UCVTF_float_fix, "UCVTF (scalar, fixed-point)", "z0011110yy000011ppppppnnnnnddddd")
|
||||
INST(FCVTZS_float_fix, "FCVTZS (scalar, fixed-point)", "z0011110yy011000ppppppnnnnnddddd")
|
||||
INST(FCVTZU_float_fix, "FCVTZU (scalar, fixed-point)", "z0011110yy011001ppppppnnnnnddddd")
|
||||
|
||||
|
|
|
@ -10,6 +10,62 @@
|
|||
|
||||
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) {
|
||||
const size_t intsize = sf ? 64 : 32;
|
||||
const auto fltsize = FPGetDataSize(type);
|
||||
|
|
Loading…
Reference in a new issue