LLVM DSL: add line number in get_const_vector automatically
This commit is contained in:
@@ -108,7 +108,7 @@ llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32 a, u32 b)
|
std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32 _pos, u32 _line)
|
||||||
{
|
{
|
||||||
v128 result{};
|
v128 result{};
|
||||||
|
|
||||||
@@ -131,12 +131,12 @@ std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32
|
|||||||
return {true, result};
|
return {true, result};
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("[0x%x, %u] Not a vector", a, b);
|
fmt::throw_exception("[0x%x, %u] Not a vector", _pos, _line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto v = llvm::cast<llvm::VectorType>(t); v->getScalarSizeInBits() * v->getNumElements() != 128)
|
if (auto v = llvm::cast<llvm::VectorType>(t); v->getScalarSizeInBits() * v->getNumElements() != 128)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("[0x%x, %u] Bad vector size: i%ux%u", a, b, v->getScalarSizeInBits(), v->getNumElements());
|
fmt::throw_exception("[0x%x, %u] Bad vector size: i%ux%u", _pos, _line, v->getScalarSizeInBits(), v->getNumElements());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto cv = llvm::dyn_cast<llvm::ConstantDataVector>(c);
|
const auto cv = llvm::dyn_cast<llvm::ConstantDataVector>(c);
|
||||||
@@ -151,10 +151,10 @@ std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32
|
|||||||
if (llvm::isa<llvm::ConstantExpr>(c))
|
if (llvm::isa<llvm::ConstantExpr>(c))
|
||||||
{
|
{
|
||||||
// Sorry, if we cannot evaluate it we cannot use it
|
// Sorry, if we cannot evaluate it we cannot use it
|
||||||
fmt::throw_exception("[0x%x, %u] Constant Expression!", a, b);
|
fmt::throw_exception("[0x%x, %u] Constant Expression!", _pos, _line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("[0x%x, %u] Unexpected constant type", a, b);
|
fmt::throw_exception("[0x%x, %u] Unexpected constant type", _pos, _line);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto sct = t->getScalarType();
|
const auto sct = t->getScalarType();
|
||||||
@@ -203,14 +203,14 @@ std::pair<bool, v128> cpu_translator::get_const_vector<v128>(llvm::Value* c, u32
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt::throw_exception("[0x%x, %u] Unexpected vector element type", a, b);
|
fmt::throw_exception("[0x%x, %u] Unexpected vector element type", _pos, _line);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {true, result};
|
return {true, result};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t)
|
llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t, u32 _line)
|
||||||
{
|
{
|
||||||
if (const auto ct = llvm::dyn_cast<llvm::IntegerType>(t); ct && ct->getBitWidth() == 128)
|
if (const auto ct = llvm::dyn_cast<llvm::IntegerType>(t); ct && ct->getBitWidth() == 128)
|
||||||
{
|
{
|
||||||
@@ -247,7 +247,7 @@ llvm::Constant* cpu_translator::make_const_vector<v128>(v128 v, llvm::Type* t)
|
|||||||
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const f64*>(v._bytes), 2));
|
return llvm::ConstantDataVector::get(m_context, llvm::makeArrayRef(reinterpret_cast<const f64*>(v._bytes), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::throw_exception("No supported constant type");
|
fmt::throw_exception("[line %u] No supported constant type", _line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3228,10 +3228,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename R = v128>
|
template <typename R = v128>
|
||||||
std::pair<bool, R> get_const_vector(llvm::Value*, u32 a, u32 b);
|
std::pair<bool, R> get_const_vector(llvm::Value*, u32 pos, u32 = __builtin_LINE());
|
||||||
|
|
||||||
template <typename T = v128>
|
template <typename T = v128>
|
||||||
llvm::Constant* make_const_vector(T, llvm::Type*);
|
llvm::Constant* make_const_vector(T, llvm::Type*, u32 = __builtin_LINE());
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format llvm::SizeType
|
// Format llvm::SizeType
|
||||||
|
|||||||
@@ -1006,7 +1006,7 @@ void PPUTranslator::VMADDFP(ppu_opcode_t op)
|
|||||||
auto [a, b, c] = get_vrs<f32[4]>(op.va, op.vb, op.vc);
|
auto [a, b, c] = get_vrs<f32[4]>(op.va, op.vb, op.vc);
|
||||||
|
|
||||||
// Optimization: Emit only a floating multiply if the addend is zero
|
// Optimization: Emit only a floating multiply if the addend is zero
|
||||||
if (auto [ok, data] = get_const_vector(b.value, m_addr, 2000); ok)
|
if (auto [ok, data] = get_const_vector(b.value, m_addr); ok)
|
||||||
{
|
{
|
||||||
if (data == v128::from32p(1u << 31))
|
if (data == v128::from32p(1u << 31))
|
||||||
{
|
{
|
||||||
@@ -1317,7 +1317,7 @@ void PPUTranslator::VNMSUBFP(ppu_opcode_t op)
|
|||||||
auto [a, b, c] = get_vrs<f32[4]>(op.va, op.vb, op.vc);
|
auto [a, b, c] = get_vrs<f32[4]>(op.va, op.vb, op.vc);
|
||||||
|
|
||||||
// Optimization: Emit only a floating multiply if the addend is zero
|
// Optimization: Emit only a floating multiply if the addend is zero
|
||||||
if (const auto [ok, data] = get_const_vector(b.value, m_addr, 2004); ok)
|
if (const auto [ok, data] = get_const_vector(b.value, m_addr); ok)
|
||||||
{
|
{
|
||||||
if (data == v128{})
|
if (data == v128{})
|
||||||
{
|
{
|
||||||
@@ -1515,7 +1515,7 @@ void PPUTranslator::VSEL(ppu_opcode_t op)
|
|||||||
const auto c = get_vr<u32[4]>(op.vc);
|
const auto c = get_vr<u32[4]>(op.vc);
|
||||||
|
|
||||||
// Check if the constant mask doesn't require bit granularity
|
// Check if the constant mask doesn't require bit granularity
|
||||||
if (auto [ok, mask] = get_const_vector(c.value, m_addr, 9000); ok)
|
if (auto [ok, mask] = get_const_vector(c.value, m_addr); ok)
|
||||||
{
|
{
|
||||||
bool sel_32 = true;
|
bool sel_32 = true;
|
||||||
for (u32 i = 0; i < 4; i++)
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
|||||||
@@ -7390,7 +7390,7 @@ public:
|
|||||||
const auto c = get_vr(op.rc);
|
const auto c = get_vr(op.rc);
|
||||||
|
|
||||||
// Check if the constant mask doesn't require bit granularity
|
// Check if the constant mask doesn't require bit granularity
|
||||||
if (auto [ok, mask] = get_const_vector(c.value, m_pos, 8000); ok)
|
if (auto [ok, mask] = get_const_vector(c.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
bool sel_32 = true;
|
bool sel_32 = true;
|
||||||
for (u32 i = 0; i < 4; i++)
|
for (u32 i = 0; i < 4; i++)
|
||||||
@@ -7492,7 +7492,7 @@ public:
|
|||||||
|
|
||||||
const auto c = get_vr<u8[16]>(op.rc);
|
const auto c = get_vr<u8[16]>(op.rc);
|
||||||
|
|
||||||
if (auto [ok, mask] = get_const_vector(c.value, m_pos, 57216); ok)
|
if (auto [ok, mask] = get_const_vector(c.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
// Optimization: SHUFB with constant mask
|
// Optimization: SHUFB with constant mask
|
||||||
if (((mask._u64[0] | mask._u64[1]) & 0xe0e0e0e0e0e0e0e0) == 0)
|
if (((mask._u64[0] | mask._u64[1]) & 0xe0e0e0e0e0e0e0e0) == 0)
|
||||||
@@ -7597,7 +7597,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto [ok, data] = get_const_vector(b.value, m_pos, 7000); ok)
|
if (auto [ok, data] = get_const_vector(b.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
const bool all_bytes_equiv = data == v128::from8p(data._u8[0]);
|
const bool all_bytes_equiv = data == v128::from8p(data._u8[0]);
|
||||||
if (all_bytes_equiv)
|
if (all_bytes_equiv)
|
||||||
@@ -7613,7 +7613,7 @@ public:
|
|||||||
|
|
||||||
if (auto [ok, bs] = match_expr(b, byteswap(match<u8[16]>())); ok)
|
if (auto [ok, bs] = match_expr(b, byteswap(match<u8[16]>())); ok)
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(a.value, m_pos, 7000); ok)
|
if (auto [ok, data] = get_const_vector(a.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
const bool all_bytes_equiv = data == v128::from8p(data._u8[0]);
|
const bool all_bytes_equiv = data == v128::from8p(data._u8[0]);
|
||||||
if (all_bytes_equiv)
|
if (all_bytes_equiv)
|
||||||
@@ -7858,7 +7858,7 @@ public:
|
|||||||
|
|
||||||
for (u32 i = 0; i < 2; i++)
|
for (u32 i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos, 5000); ok)
|
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos); ok)
|
||||||
{
|
{
|
||||||
safe_int_compare.set(i);
|
safe_int_compare.set(i);
|
||||||
safe_nonzero_compare.set(i);
|
safe_nonzero_compare.set(i);
|
||||||
@@ -8028,7 +8028,7 @@ public:
|
|||||||
|
|
||||||
for (u32 i = 0; i < 2; i++)
|
for (u32 i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos, 6000); ok)
|
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos); ok)
|
||||||
{
|
{
|
||||||
safe_float_compare.set(i);
|
safe_float_compare.set(i);
|
||||||
safe_int_compare.set(i);
|
safe_int_compare.set(i);
|
||||||
@@ -8093,7 +8093,7 @@ public:
|
|||||||
|
|
||||||
for (u32 i = 0; i < 2; i++)
|
for (u32 i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos, 6000); ok)
|
if (auto [ok, data] = get_const_vector(ab[i].value, m_pos); ok)
|
||||||
{
|
{
|
||||||
safe_float_compare.set(i);
|
safe_float_compare.set(i);
|
||||||
safe_int_compare.set(i);
|
safe_int_compare.set(i);
|
||||||
@@ -8151,7 +8151,7 @@ public:
|
|||||||
|
|
||||||
// Optimization: Emit only a floating multiply if the addend is zero
|
// Optimization: Emit only a floating multiply if the addend is zero
|
||||||
// This is odd since SPU code could just use the FM instruction, but it seems common enough
|
// This is odd since SPU code could just use the FM instruction, but it seems common enough
|
||||||
if (auto [ok, data] = get_const_vector(c.value, m_pos, 4000); ok)
|
if (auto [ok, data] = get_const_vector(c.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
if (is_spu_float_zero(data, -1))
|
if (is_spu_float_zero(data, -1))
|
||||||
{
|
{
|
||||||
@@ -8168,14 +8168,14 @@ public:
|
|||||||
|
|
||||||
if ([&]()
|
if ([&]()
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(a.value, m_pos, 4000); ok)
|
if (auto [ok, data] = get_const_vector(a.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
if (!is_spu_float_zero(data, +1))
|
if (!is_spu_float_zero(data, +1))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto [ok0, data0] = get_const_vector(b.value, m_pos, 4000); ok0)
|
if (auto [ok0, data0] = get_const_vector(b.value, m_pos); ok0)
|
||||||
{
|
{
|
||||||
if (is_spu_float_zero(data0, +1))
|
if (is_spu_float_zero(data0, +1))
|
||||||
{
|
{
|
||||||
@@ -8184,14 +8184,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto [ok, data] = get_const_vector(a.value, m_pos, 4000); ok)
|
if (auto [ok, data] = get_const_vector(a.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
if (!is_spu_float_zero(data, -1))
|
if (!is_spu_float_zero(data, -1))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto [ok0, data0] = get_const_vector(b.value, m_pos, 4000); ok0)
|
if (auto [ok0, data0] = get_const_vector(b.value, m_pos); ok0)
|
||||||
{
|
{
|
||||||
if (is_spu_float_zero(data0, -1))
|
if (is_spu_float_zero(data0, -1))
|
||||||
{
|
{
|
||||||
@@ -8435,7 +8435,7 @@ public:
|
|||||||
value_t<s32[4]> a = get_vr<s32[4]>(op.ra);
|
value_t<s32[4]> a = get_vr<s32[4]>(op.ra);
|
||||||
value_t<f64[4]> r;
|
value_t<f64[4]> r;
|
||||||
|
|
||||||
if (auto [ok, data] = get_const_vector(a.value, m_pos, 25971); ok)
|
if (auto [ok, data] = get_const_vector(a.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
r.value = build<f64[4]>(data._s32[0], data._s32[1], data._s32[2], data._s32[3]).eval(m_ir);
|
r.value = build<f64[4]>(data._s32[0], data._s32[1], data._s32[2], data._s32[3]).eval(m_ir);
|
||||||
}
|
}
|
||||||
@@ -8475,7 +8475,7 @@ public:
|
|||||||
value_t<s32[4]> a = get_vr<s32[4]>(op.ra);
|
value_t<s32[4]> a = get_vr<s32[4]>(op.ra);
|
||||||
value_t<f64[4]> r;
|
value_t<f64[4]> r;
|
||||||
|
|
||||||
if (auto [ok, data] = get_const_vector(a.value, m_pos, 20971); ok)
|
if (auto [ok, data] = get_const_vector(a.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
r.value = build<f64[4]>(data._u32[0], data._u32[1], data._u32[2], data._u32[3]).eval(m_ir);
|
r.value = build<f64[4]>(data._u32[0], data._u32[1], data._u32[2], data._u32[3]).eval(m_ir);
|
||||||
}
|
}
|
||||||
@@ -8528,7 +8528,7 @@ public:
|
|||||||
|
|
||||||
for (auto pair : std::initializer_list<std::pair<value_t<u32[4]>, value_t<u32[4]>>>{{a, b}, {b, a}})
|
for (auto pair : std::initializer_list<std::pair<value_t<u32[4]>, value_t<u32[4]>>>{{a, b}, {b, a}})
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(pair.first.value, m_pos, 10000); ok)
|
if (auto [ok, data] = get_const_vector(pair.first.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
data._u32[3] %= SPU_LS_SIZE;
|
data._u32[3] %= SPU_LS_SIZE;
|
||||||
|
|
||||||
@@ -8552,7 +8552,7 @@ public:
|
|||||||
|
|
||||||
for (auto pair : std::initializer_list<std::pair<value_t<u32[4]>, value_t<u32[4]>>>{{a, b}, {b, a}})
|
for (auto pair : std::initializer_list<std::pair<value_t<u32[4]>, value_t<u32[4]>>>{{a, b}, {b, a}})
|
||||||
{
|
{
|
||||||
if (auto [ok, data] = get_const_vector(pair.first.value, m_pos, 10000); ok)
|
if (auto [ok, data] = get_const_vector(pair.first.value, m_pos); ok)
|
||||||
{
|
{
|
||||||
data._u32[3] %= SPU_LS_SIZE;
|
data._u32[3] %= SPU_LS_SIZE;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user