mirror of
https://github.com/open-goal/jak-project
synced 2026-09-03 10:21:36 -04:00
compiler: Support the majority of the remaining VU VF instructions (#258)
* compiler: Support the majority of the remaining VU VF instructions - VWAIT - VMADD variants - VMSUB variants - VSQRT - VDIV - outer product (VOPMULA + VOPMSUB) * compiler: Fix some bugs / optimize some instructions * tests/compiler: Add test coverage for new instructions * docs: Add documentation for new inline assembly functions * lint: Formatting / fix failing test * Remove my comment about ftf/fsf encoding, it's been fixed * address review feedback * correct VSQRTPS implementation
This commit is contained in:
@@ -1099,6 +1099,27 @@ void IR_AsmFNop::do_codegen(emitter::ObjectGenerator* gen,
|
||||
gen->add_instr(IGen::nop_vf(), irec);
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// AsmFWait
|
||||
///////////////////////
|
||||
|
||||
IR_AsmFWait::IR_AsmFWait() : IR_Asm(false) {}
|
||||
|
||||
std::string IR_AsmFWait::print() {
|
||||
return ".wait.vf";
|
||||
}
|
||||
|
||||
RegAllocInstr IR_AsmFWait::to_rai() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void IR_AsmFWait::do_codegen(emitter::ObjectGenerator* gen,
|
||||
const AllocationResult& allocs,
|
||||
emitter::IR_Record irec) {
|
||||
(void)allocs;
|
||||
gen->add_instr(IGen::wait_vf(), irec);
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// AsmPush
|
||||
///////////////////////
|
||||
@@ -1343,6 +1364,9 @@ std::string IR_VFMath3Asm::print() {
|
||||
case Kind::MIN:
|
||||
function = ".min.vf";
|
||||
break;
|
||||
case Kind::DIV:
|
||||
function = ".div.vf";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
@@ -1386,11 +1410,16 @@ void IR_VFMath3Asm::do_codegen(emitter::ObjectGenerator* gen,
|
||||
case Kind::MIN:
|
||||
gen->add_instr(IGen::min_vf(dst, src1, src2), irec);
|
||||
break;
|
||||
case Kind::DIV:
|
||||
gen->add_instr(IGen::div_vf(dst, src1, src2), irec);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Blend VF
|
||||
|
||||
IR_BlendVF::IR_BlendVF(bool use_color,
|
||||
const RegVal* dst,
|
||||
const RegVal* src1,
|
||||
@@ -1422,6 +1451,8 @@ void IR_BlendVF::do_codegen(emitter::ObjectGenerator* gen,
|
||||
gen->add_instr(IGen::blend_vf(dst, src1, src2, m_mask), irec);
|
||||
}
|
||||
|
||||
// ----- Splat VF
|
||||
|
||||
IR_SplatVF::IR_SplatVF(bool use_color,
|
||||
const RegVal* dst,
|
||||
const RegVal* src,
|
||||
@@ -1449,3 +1480,60 @@ void IR_SplatVF::do_codegen(emitter::ObjectGenerator* gen,
|
||||
auto src = get_reg_asm(m_src, allocs, irec, m_use_coloring);
|
||||
gen->add_instr(IGen::splat_vf(dst, src, m_element), irec);
|
||||
}
|
||||
|
||||
// ---- Swizzle VF
|
||||
|
||||
IR_SwizzleVF::IR_SwizzleVF(bool use_color,
|
||||
const RegVal* dst,
|
||||
const RegVal* src,
|
||||
const u8 controlBytes)
|
||||
: IR_Asm(use_color), m_dst(dst), m_src(src), m_controlBytes(controlBytes) {}
|
||||
|
||||
std::string IR_SwizzleVF::print() {
|
||||
return fmt::format(".swizzle.vf{} {}, {}, {}", get_color_suffix_string(), m_dst->print(),
|
||||
m_src->print(), m_controlBytes);
|
||||
}
|
||||
|
||||
RegAllocInstr IR_SwizzleVF::to_rai() {
|
||||
RegAllocInstr rai;
|
||||
if (m_use_coloring) {
|
||||
rai.write.push_back(m_dst->ireg());
|
||||
rai.read.push_back(m_src->ireg());
|
||||
}
|
||||
return rai;
|
||||
}
|
||||
|
||||
void IR_SwizzleVF::do_codegen(emitter::ObjectGenerator* gen,
|
||||
const AllocationResult& allocs,
|
||||
emitter::IR_Record irec) {
|
||||
auto dst = get_reg_asm(m_dst, allocs, irec, m_use_coloring);
|
||||
auto src = get_reg_asm(m_src, allocs, irec, m_use_coloring);
|
||||
gen->add_instr(IGen::swizzle_vf(dst, src, m_controlBytes), irec);
|
||||
}
|
||||
|
||||
// ---- Square Root VF
|
||||
|
||||
IR_SqrtVF::IR_SqrtVF(bool use_color, const RegVal* dst, const RegVal* src)
|
||||
: IR_Asm(use_color), m_dst(dst), m_src(src) {}
|
||||
|
||||
std::string IR_SqrtVF::print() {
|
||||
return fmt::format(".sqrt.vf{} {}, {}", get_color_suffix_string(), m_dst->print(),
|
||||
m_src->print());
|
||||
}
|
||||
|
||||
RegAllocInstr IR_SqrtVF::to_rai() {
|
||||
RegAllocInstr rai;
|
||||
if (m_use_coloring) {
|
||||
rai.write.push_back(m_dst->ireg());
|
||||
rai.read.push_back(m_src->ireg());
|
||||
}
|
||||
return rai;
|
||||
}
|
||||
|
||||
void IR_SqrtVF::do_codegen(emitter::ObjectGenerator* gen,
|
||||
const AllocationResult& allocs,
|
||||
emitter::IR_Record irec) {
|
||||
auto dst = get_reg_asm(m_dst, allocs, irec, m_use_coloring);
|
||||
auto src = get_reg_asm(m_src, allocs, irec, m_use_coloring);
|
||||
gen->add_instr(IGen::sqrt_vf(dst, src), irec);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user