SPU/PPU LLVM: Improve expressions matching (#8620)

This commit is contained in:
Eladash 2020-07-24 18:53:48 +03:00 committed by GitHub
parent bb3ac62126
commit 3354c800d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 6 deletions

View file

@ -515,12 +515,14 @@ Value* PPUTranslator::Shuffle(Value* left, Value* right, std::initializer_list<u
Value* PPUTranslator::SExt(Value* value, Type* type) Value* PPUTranslator::SExt(Value* value, Type* type)
{ {
return m_ir->CreateSExt(value, type ? type : ScaleType(value->getType(), 1)); type = type ? type : ScaleType(value->getType(), 1);
return value->getType() != type ? m_ir->CreateSExt(value, type) : value;
} }
Value* PPUTranslator::ZExt(Value* value, Type* type) Value* PPUTranslator::ZExt(Value* value, Type* type)
{ {
return m_ir->CreateZExt(value, type ? type : ScaleType(value->getType(), 1)); type = type ? type : ScaleType(value->getType(), 1);
return value->getType() != type ? m_ir->CreateZExt(value, type) : value;
} }
Value* PPUTranslator::Add(std::initializer_list<Value*> args) Value* PPUTranslator::Add(std::initializer_list<Value*> args)
@ -536,7 +538,8 @@ Value* PPUTranslator::Add(std::initializer_list<Value*> args)
Value* PPUTranslator::Trunc(Value* value, Type* type) Value* PPUTranslator::Trunc(Value* value, Type* type)
{ {
return m_ir->CreateTrunc(value, type ? type : ScaleType(value->getType(), -1)); type = type ? type : ScaleType(value->getType(), -1);
return type != value->getType() ? m_ir->CreateTrunc(value, type) : value;
} }
void PPUTranslator::UseCondition(MDNode* hint, Value* cond) void PPUTranslator::UseCondition(MDNode* hint, Value* cond)
@ -4454,12 +4457,12 @@ void PPUTranslator::UNK(ppu_opcode_t op)
Value* PPUTranslator::GetGpr(u32 r, u32 num_bits) Value* PPUTranslator::GetGpr(u32 r, u32 num_bits)
{ {
return m_ir->CreateTrunc(RegLoad(m_gpr[r]), m_ir->getIntNTy(num_bits)); return Trunc(RegLoad(m_gpr[r]), m_ir->getIntNTy(num_bits));
} }
void PPUTranslator::SetGpr(u32 r, Value* value) void PPUTranslator::SetGpr(u32 r, Value* value)
{ {
RegStore(m_ir->CreateZExt(value, GetType<u64>()), m_gpr[r]); RegStore(ZExt(value, GetType<u64>()), m_gpr[r]);
} }
Value* PPUTranslator::GetFpr(u32 r, u32 bits, bool as_int) Value* PPUTranslator::GetFpr(u32 r, u32 bits, bool as_int)
@ -4476,7 +4479,7 @@ Value* PPUTranslator::GetFpr(u32 r, u32 bits, bool as_int)
} }
else else
{ {
return m_ir->CreateTrunc(m_ir->CreateBitCast(value, GetType<u64>()), m_ir->getIntNTy(bits)); return Trunc(m_ir->CreateBitCast(value, GetType<u64>()), m_ir->getIntNTy(bits));
} }
} }

View file

@ -6679,6 +6679,7 @@ public:
void SHLQBYI(spu_opcode_t op) void SHLQBYI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.i7) return set_vr(op.rt, get_vr(op.ra)); // For expressions matching
const auto a = get_vr<u8[16]>(op.ra); const auto a = get_vr<u8[16]>(op.ra);
const auto sc = build<u8[16]>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); const auto sc = build<u8[16]>(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
const auto sh = sc - (get_imm<u8[16]>(op.i7, false) & 0x1f); const auto sh = sc - (get_imm<u8[16]>(op.i7, false) & 0x1f);
@ -6878,16 +6879,19 @@ public:
void ORI(spu_opcode_t op) void ORI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra)); // For expressions matching
set_vr(op.rt, get_vr<s32[4]>(op.ra) | get_imm<s32[4]>(op.si10)); set_vr(op.rt, get_vr<s32[4]>(op.ra) | get_imm<s32[4]>(op.si10));
} }
void ORHI(spu_opcode_t op) void ORHI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s16[8]>(op.ra) | get_imm<s16[8]>(op.si10)); set_vr(op.rt, get_vr<s16[8]>(op.ra) | get_imm<s16[8]>(op.si10));
} }
void ORBI(spu_opcode_t op) void ORBI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s8[16]>(op.ra) | get_imm<s8[16]>(op.si10)); set_vr(op.rt, get_vr<s8[16]>(op.ra) | get_imm<s8[16]>(op.si10));
} }
@ -6903,41 +6907,49 @@ public:
void ANDI(spu_opcode_t op) void ANDI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s32[4]>(op.ra) & get_imm<s32[4]>(op.si10)); set_vr(op.rt, get_vr<s32[4]>(op.ra) & get_imm<s32[4]>(op.si10));
} }
void ANDHI(spu_opcode_t op) void ANDHI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s16[8]>(op.ra) & get_imm<s16[8]>(op.si10)); set_vr(op.rt, get_vr<s16[8]>(op.ra) & get_imm<s16[8]>(op.si10));
} }
void ANDBI(spu_opcode_t op) void ANDBI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s8[16]>(op.ra) & get_imm<s8[16]>(op.si10)); set_vr(op.rt, get_vr<s8[16]>(op.ra) & get_imm<s8[16]>(op.si10));
} }
void AI(spu_opcode_t op) void AI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s32[4]>(op.ra) + get_imm<s32[4]>(op.si10)); set_vr(op.rt, get_vr<s32[4]>(op.ra) + get_imm<s32[4]>(op.si10));
} }
void AHI(spu_opcode_t op) void AHI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s16[8]>(op.ra) + get_imm<s16[8]>(op.si10)); set_vr(op.rt, get_vr<s16[8]>(op.ra) + get_imm<s16[8]>(op.si10));
} }
void XORI(spu_opcode_t op) void XORI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s32[4]>(op.ra) ^ get_imm<s32[4]>(op.si10)); set_vr(op.rt, get_vr<s32[4]>(op.ra) ^ get_imm<s32[4]>(op.si10));
} }
void XORHI(spu_opcode_t op) void XORHI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s16[8]>(op.ra) ^ get_imm<s16[8]>(op.si10)); set_vr(op.rt, get_vr<s16[8]>(op.ra) ^ get_imm<s16[8]>(op.si10));
} }
void XORBI(spu_opcode_t op) void XORBI(spu_opcode_t op)
{ {
if (!m_interp_magn && !op.si10) return set_vr(op.rt, get_vr(op.ra));
set_vr(op.rt, get_vr<s8[16]>(op.ra) ^ get_imm<s8[16]>(op.si10)); set_vr(op.rt, get_vr<s8[16]>(op.ra) ^ get_imm<s8[16]>(op.si10));
} }