mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-11 05:42:58 +00:00
opcodes: Add 64-bit CountLeadingZeroes opcode
This commit is contained in:
@@ -1302,7 +1302,7 @@ void EmitX64<JST>::EmitByteReverseDual(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitCountLeadingZeros(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64<JST>::EmitCountLeadingZeros32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
if (code->DoesCpuSupport(Xbyak::util::Cpu::tLZCNT)) {
|
||||
Xbyak::Reg32 source = ctx.reg_alloc.UseGpr(args[0]).cvt32();
|
||||
@@ -1326,6 +1326,31 @@ void EmitX64<JST>::EmitCountLeadingZeros(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitCountLeadingZeros64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
if (code->DoesCpuSupport(Xbyak::util::Cpu::tLZCNT)) {
|
||||
Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]).cvt64();
|
||||
Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr().cvt64();
|
||||
|
||||
code->lzcnt(result, source);
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
} else {
|
||||
Xbyak::Reg64 source = ctx.reg_alloc.UseScratchGpr(args[0]).cvt64();
|
||||
Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr().cvt64();
|
||||
|
||||
// The result of a bsr of zero is undefined, but zf is set after it.
|
||||
code->bsr(result, source);
|
||||
code->mov(source.cvt32(), 0xFFFFFFFF);
|
||||
code->cmovz(result.cvt32(), source.cvt32());
|
||||
code->neg(result.cvt32());
|
||||
code->add(result.cvt32(), 63);
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitSignedSaturatedAdd(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp);
|
||||
|
||||
Reference in New Issue
Block a user