mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[A64/Sequences] Fix MUL_ADD_V128 temp handling
- Always use temporaries to avoid source/dest aliasing - Replace FMLA with FMUL+FADD for clearer ordering
This commit is contained in:
@@ -1734,30 +1734,35 @@ struct MUL_ADD_V128
|
||||
I<OPCODE_MUL_ADD, V128Op, V128Op, V128Op, V128Op>> {
|
||||
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||
const QReg dest = i.dest.reg();
|
||||
if (i.src3.is_constant) {
|
||||
e.LoadConstantV(dest.toQ(), i.src3.constant());
|
||||
} else {
|
||||
// If i.dest != i.src3, move the addition-term into dest for FMLA
|
||||
if (i.dest != i.src3) {
|
||||
e.MOV(dest.B16(), i.src3.reg().B16());
|
||||
}
|
||||
}
|
||||
|
||||
QReg src2 = Q2;
|
||||
if (i.src2.is_constant) {
|
||||
e.LoadConstantV(src2.toQ(), i.src2.constant());
|
||||
} else {
|
||||
src2 = i.src2.reg();
|
||||
}
|
||||
// Always use temporary registers to avoid conflicts
|
||||
QReg temp1 = Q0;
|
||||
QReg temp2 = Q1;
|
||||
QReg temp3 = Q2;
|
||||
|
||||
QReg src1 = Q1;
|
||||
if (i.src1.is_constant) {
|
||||
e.LoadConstantV(src1.toQ(), i.src1.constant());
|
||||
e.LoadConstantV(temp1, i.src1.constant());
|
||||
} else {
|
||||
src1 = i.src1.reg();
|
||||
e.MOV(temp1.B16(), i.src1.reg().B16());
|
||||
}
|
||||
|
||||
e.FMLA(dest.S4(), src1.S4(), src2.S4());
|
||||
if (i.src2.is_constant) {
|
||||
e.LoadConstantV(temp2, i.src2.constant());
|
||||
} else {
|
||||
e.MOV(temp2.B16(), i.src2.reg().B16());
|
||||
}
|
||||
|
||||
if (i.src3.is_constant) {
|
||||
e.LoadConstantV(temp3, i.src3.constant());
|
||||
} else {
|
||||
e.MOV(temp3.B16(), i.src3.reg().B16());
|
||||
}
|
||||
|
||||
// First multiply: dest = temp1 * temp2
|
||||
e.FMUL(dest.S4(), temp1.S4(), temp2.S4());
|
||||
|
||||
// Then add: dest = dest + temp3
|
||||
e.FADD(dest.S4(), dest.S4(), temp3.S4());
|
||||
}
|
||||
};
|
||||
EMITTER_OPCODE_TABLE(OPCODE_MUL_ADD, MUL_ADD_F32, MUL_ADD_F64, MUL_ADD_V128);
|
||||
|
||||
Reference in New Issue
Block a user