mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-28 01:08:24 +00:00
hotfix: 64-bit shift fixups
This commit is contained in:
parent
9dcf40e261
commit
4d12de8149
|
@ -348,7 +348,8 @@ Id EmitSLessThanEqual(EmitContext& ctx, Id lhs, Id rhs);
|
|||
Id EmitULessThanEqual(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitSGreaterThan(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitINotEqual32(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitINotEqual64(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitSGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs);
|
||||
Id EmitLogicalOr(EmitContext& ctx, Id a, Id b);
|
||||
|
|
|
@ -324,7 +324,11 @@ Id EmitUGreaterThan(EmitContext& ctx, Id lhs, Id rhs) {
|
|||
return ctx.OpUGreaterThan(ctx.U1[1], lhs, rhs);
|
||||
}
|
||||
|
||||
Id EmitINotEqual(EmitContext& ctx, Id lhs, Id rhs) {
|
||||
Id EmitINotEqual32(EmitContext& ctx, Id lhs, Id rhs) {
|
||||
return ctx.OpINotEqual(ctx.U1[1], lhs, rhs);
|
||||
}
|
||||
|
||||
Id EmitINotEqual64(EmitContext& ctx, Id lhs, Id rhs) {
|
||||
return ctx.OpINotEqual(ctx.U1[1], lhs, rhs);
|
||||
}
|
||||
|
||||
|
|
|
@ -1257,28 +1257,7 @@ void Translator::V_CVT_PK_U8_F32(const GcnInst& inst) {
|
|||
void Translator::V_LSHL_B64(const GcnInst& inst) {
|
||||
const IR::U64 src0{GetSrc64(inst.src[0])};
|
||||
const IR::U64 src1{GetSrc64(inst.src[1])};
|
||||
const IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
if (src0.IsImmediate()) {
|
||||
if (src0.U64() == -1) {
|
||||
// If src0 is a fixed -1, the result will always be -1.
|
||||
ir.SetVectorReg(dst_reg, ir.Imm32(0xFFFFFFFF));
|
||||
ir.SetVectorReg(dst_reg + 1, ir.Imm32(0xFFFFFFFF));
|
||||
return;
|
||||
}
|
||||
if (src1.IsImmediate()) {
|
||||
// If both src0 and src1 are immediates, we can calculate the result now.
|
||||
// Note that according to the manual, only bits 4:0 are used from src1.
|
||||
const u64 result = src0.U64() << (src1.U64() & 0x1F);
|
||||
ir.SetVectorReg(dst_reg, ir.Imm32(static_cast<u32>(result)));
|
||||
ir.SetVectorReg(dst_reg + 1, ir.Imm32(static_cast<u32>(result >> 32)));
|
||||
return;
|
||||
}
|
||||
|
||||
const IR::U64 result = ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F))));
|
||||
SetDst64(inst.dst[0], result);
|
||||
return;
|
||||
}
|
||||
UNREACHABLE_MSG("Unimplemented V_LSHL_B64 arguments");
|
||||
SetDst64(inst.dst[0], ir.ShiftLeftLogical(src0, ir.BitwiseAnd(src1, ir.Imm64(u64(0x3F)))));
|
||||
}
|
||||
|
||||
void Translator::V_MUL_F64(const GcnInst& inst) {
|
||||
|
|
|
@ -1461,8 +1461,18 @@ U1 IREmitter::IGreaterThan(const U32& lhs, const U32& rhs, bool is_signed) {
|
|||
return Inst<U1>(is_signed ? Opcode::SGreaterThan : Opcode::UGreaterThan, lhs, rhs);
|
||||
}
|
||||
|
||||
U1 IREmitter::INotEqual(const U32& lhs, const U32& rhs) {
|
||||
return Inst<U1>(Opcode::INotEqual, lhs, rhs);
|
||||
U1 IREmitter::INotEqual(const U32U64& lhs, const U32U64& rhs) {
|
||||
if (lhs.Type() != rhs.Type()) {
|
||||
UNREACHABLE_MSG("Mismatching types {} and {}", lhs.Type(), rhs.Type());
|
||||
}
|
||||
switch (lhs.Type()) {
|
||||
case Type::U32:
|
||||
return Inst<U1>(Opcode::INotEqual32, lhs, rhs);
|
||||
case Type::U64:
|
||||
return Inst<U1>(Opcode::INotEqual64, lhs, rhs);
|
||||
default:
|
||||
ThrowInvalidType(lhs.Type());
|
||||
}
|
||||
}
|
||||
|
||||
U1 IREmitter::IGreaterThanEqual(const U32& lhs, const U32& rhs, bool is_signed) {
|
||||
|
|
|
@ -258,7 +258,7 @@ public:
|
|||
[[nodiscard]] U1 IEqual(const U32U64& lhs, const U32U64& rhs);
|
||||
[[nodiscard]] U1 ILessThanEqual(const U32& lhs, const U32& rhs, bool is_signed);
|
||||
[[nodiscard]] U1 IGreaterThan(const U32& lhs, const U32& rhs, bool is_signed);
|
||||
[[nodiscard]] U1 INotEqual(const U32& lhs, const U32& rhs);
|
||||
[[nodiscard]] U1 INotEqual(const U32U64& lhs, const U32U64& rhs);
|
||||
[[nodiscard]] U1 IGreaterThanEqual(const U32& lhs, const U32& rhs, bool is_signed);
|
||||
|
||||
[[nodiscard]] U1 LogicalOr(const U1& a, const U1& b);
|
||||
|
|
|
@ -321,7 +321,8 @@ OPCODE(SLessThanEqual, U1, U32,
|
|||
OPCODE(ULessThanEqual, U1, U32, U32, )
|
||||
OPCODE(SGreaterThan, U1, U32, U32, )
|
||||
OPCODE(UGreaterThan, U1, U32, U32, )
|
||||
OPCODE(INotEqual, U1, U32, U32, )
|
||||
OPCODE(INotEqual32, U1, U32, U32, )
|
||||
OPCODE(INotEqual64, U1, U64, U64, )
|
||||
OPCODE(SGreaterThanEqual, U1, U32, U32, )
|
||||
OPCODE(UGreaterThanEqual, U1, U32, U32, )
|
||||
|
||||
|
|
|
@ -403,9 +403,12 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
|
|||
case IR::Opcode::IEqual64:
|
||||
FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a == b; });
|
||||
return;
|
||||
case IR::Opcode::INotEqual:
|
||||
case IR::Opcode::INotEqual32:
|
||||
FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a != b; });
|
||||
return;
|
||||
case IR::Opcode::INotEqual64:
|
||||
FoldWhenAllImmediates(inst, [](u64 a, u64 b) { return a != b; });
|
||||
return;
|
||||
case IR::Opcode::BitwiseAnd32:
|
||||
FoldWhenAllImmediates(inst, [](u32 a, u32 b) { return a & b; });
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue