mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 03:24:49 +00:00
Implemented BitfieldInsert and BitfieldU/SExtract
This commit is contained in:
parent
515fb1241b
commit
e54351eefb
2 changed files with 63 additions and 9 deletions
|
@ -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 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 EmitBitFieldInsert(EmitContext& ctx);
|
||||
void EmitBitFieldSExtract(EmitContext& ctx);
|
||||
void EmitBitFieldUExtract(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, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count);
|
||||
void EmitBitFieldUExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count);
|
||||
void EmitBitReverse32(EmitContext& ctx);
|
||||
void EmitBitCount32(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);
|
||||
}
|
||||
|
||||
void EmitBitFieldInsert(EmitContext& ctx) {
|
||||
throw NotImplementedException("BitFieldInsert");
|
||||
void EmitBitFieldInsert(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& insert, const Operands& offset, const Operands& count) {
|
||||
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) {
|
||||
throw NotImplementedException("BitFieldSExtract");
|
||||
void EmitBitFieldSExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count) {
|
||||
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) {
|
||||
throw NotImplementedException("BitFieldUExtract");
|
||||
void EmitBitFieldUExtract(EmitContext& ctx, const Operands& dest, const Operands& base, const Operands& offset, const Operands& count) {
|
||||
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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue