mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 07:22:24 +00:00
Implemented BitfieldInsert and BitfieldU/SExtract
This commit is contained in:
parent
515fb1241b
commit
e54351eefb
@ -350,9 +350,9 @@ void EmitBitwiseAnd64(EmitContext& ctx, const Operands& dest, const Operands& op
|
|||||||
void EmitBitwiseOr32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
void EmitBitwiseOr32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||||
void EmitBitwiseOr64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
void EmitBitwiseOr64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||||
void EmitBitwiseXor32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
void EmitBitwiseXor32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||||
void EmitBitFieldInsert(EmitContext& ctx);
|
void EmitBitFieldInsert(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& insert, const Operands& offset, const Operands& count);
|
||||||
void EmitBitFieldSExtract(EmitContext& ctx);
|
void EmitBitFieldSExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count);
|
||||||
void EmitBitFieldUExtract(EmitContext& ctx);
|
void EmitBitFieldUExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count);
|
||||||
void EmitBitReverse32(EmitContext& ctx);
|
void EmitBitReverse32(EmitContext& ctx);
|
||||||
void EmitBitCount32(EmitContext& ctx);
|
void EmitBitCount32(EmitContext& ctx);
|
||||||
void EmitBitCount64(EmitContext& ctx);
|
void EmitBitCount64(EmitContext& ctx);
|
||||||
|
@ -300,16 +300,70 @@ void EmitBitwiseXor32(EmitContext& ctx, const Operands& dest, const Operands& op
|
|||||||
MovGP(ctx, dest[0], tmp);
|
MovGP(ctx, dest[0], tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitBitFieldInsert(EmitContext& ctx) {
|
void EmitBitFieldInsert(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& insert, const Operands& offset, const Operands& count) {
|
||||||
throw NotImplementedException("BitFieldInsert");
|
bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]);
|
||||||
|
OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0];
|
||||||
|
Reg mask = ctx.TempGPReg().cvt32();
|
||||||
|
Reg tmp2 = ctx.TempGPReg().cvt32();
|
||||||
|
MovGP(ctx, tmp, base[0]);
|
||||||
|
MovGP(ctx, cl, count[0]);
|
||||||
|
MovGP(ctx, tmp2, insert[0]);
|
||||||
|
ctx.Code().mov(mask, 1);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().sub(mask, 1);
|
||||||
|
MovGP(ctx, cl, offset[0]);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().shl(tmp2, cl);
|
||||||
|
ctx.Code().and_(tmp2, mask);
|
||||||
|
ctx.Code().not_(mask);
|
||||||
|
ctx.Code().and_(tmp.Op(), mask);
|
||||||
|
ctx.Code().or_(tmp.Op(), tmp2);
|
||||||
|
MovGP(ctx, dest[0], tmp);
|
||||||
|
if (rcx_saved) {
|
||||||
|
EmitRestoreRegTemp(ctx, rcx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitBitFieldSExtract(EmitContext& ctx) {
|
void EmitBitFieldSExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count) {
|
||||||
throw NotImplementedException("BitFieldSExtract");
|
bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]);
|
||||||
|
OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0];
|
||||||
|
Reg mask = ctx.TempGPReg().cvt32();
|
||||||
|
MovGP(ctx, tmp, base[0]);
|
||||||
|
MovGP(ctx, cl, count[0]);
|
||||||
|
ctx.Code().mov(mask, 1);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().sub(mask, 1);
|
||||||
|
MovGP(ctx, cl, offset[0]);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().and_(tmp.Op(), mask);
|
||||||
|
ctx.Code().shr(tmp.Op(), cl);
|
||||||
|
ctx.Code().mov(ecx, 0x20);
|
||||||
|
ctx.Code().sub(ecx, count[0].Op());
|
||||||
|
ctx.Code().shl(tmp.Op(), cl);
|
||||||
|
ctx.Code().sar(tmp.Op(), cl);
|
||||||
|
MovGP(ctx, dest[0], tmp);
|
||||||
|
if (rcx_saved) {
|
||||||
|
EmitRestoreRegTemp(ctx, rcx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitBitFieldUExtract(EmitContext& ctx) {
|
void EmitBitFieldUExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count) {
|
||||||
throw NotImplementedException("BitFieldUExtract");
|
bool rcx_saved = EmitSaveRegTemp(ctx, rcx, dest[0]);
|
||||||
|
OperandHolder tmp = IsReg(dest[0], rcx) ? ctx.TempGPReg().cvt32() : dest[0];
|
||||||
|
Reg mask = ctx.TempGPReg().cvt32();
|
||||||
|
MovGP(ctx, tmp, base[0]);
|
||||||
|
MovGP(ctx, cl, count[0]);
|
||||||
|
ctx.Code().mov(mask, 1);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().sub(mask, 1);
|
||||||
|
MovGP(ctx, cl, offset[0]);
|
||||||
|
ctx.Code().shl(mask, cl);
|
||||||
|
ctx.Code().and_(tmp.Op(), mask);
|
||||||
|
ctx.Code().shr(tmp.Op(), cl);
|
||||||
|
MovGP(ctx, dest[0], tmp);
|
||||||
|
if (rcx_saved) {
|
||||||
|
EmitRestoreRegTemp(ctx, rcx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitBitReverse32(EmitContext& ctx) {
|
void EmitBitReverse32(EmitContext& ctx) {
|
||||||
|
Loading…
Reference in New Issue
Block a user