mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[a64] Implement OPCODE_VECTOR_ADD
There is quite literally an instruction for each and every one of these cases. Passes unit tests
This commit is contained in:
parent
584c34cbd6
commit
35e8a809b1
|
|
@ -408,7 +408,59 @@ EMITTER_OPCODE_TABLE(OPCODE_VECTOR_COMPARE_UGE, VECTOR_COMPARE_UGE_V128);
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
struct VECTOR_ADD
|
struct VECTOR_ADD
|
||||||
: Sequence<VECTOR_ADD, I<OPCODE_VECTOR_ADD, V128Op, V128Op, V128Op>> {
|
: Sequence<VECTOR_ADD, I<OPCODE_VECTOR_ADD, V128Op, V128Op, V128Op>> {
|
||||||
static void Emit(A64Emitter& e, const EmitArgType& i) {}
|
static void Emit(A64Emitter& e, const EmitArgType& i) {
|
||||||
|
EmitCommutativeBinaryVOp(
|
||||||
|
e, i, [&i](A64Emitter& e, const QReg& dest, QReg src1, QReg src2) {
|
||||||
|
const TypeName part_type =
|
||||||
|
static_cast<TypeName>(i.instr->flags & 0xFF);
|
||||||
|
const uint32_t arithmetic_flags = i.instr->flags >> 8;
|
||||||
|
bool is_unsigned = !!(arithmetic_flags & ARITHMETIC_UNSIGNED);
|
||||||
|
bool saturate = !!(arithmetic_flags & ARITHMETIC_SATURATE);
|
||||||
|
switch (part_type) {
|
||||||
|
case INT8_TYPE:
|
||||||
|
if (saturate) {
|
||||||
|
if (is_unsigned) {
|
||||||
|
e.UQADD(dest.B16(), src1.B16(), src2.B16());
|
||||||
|
} else {
|
||||||
|
e.SQADD(dest.B16(), src1.B16(), src2.B16());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.ADD(dest.B16(), src1.B16(), src2.B16());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INT16_TYPE:
|
||||||
|
if (saturate) {
|
||||||
|
if (is_unsigned) {
|
||||||
|
e.UQADD(dest.H8(), src1.H8(), src2.H8());
|
||||||
|
} else {
|
||||||
|
e.SQADD(dest.H8(), src1.H8(), src2.H8());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.ADD(dest.H8(), src1.H8(), src2.H8());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INT32_TYPE:
|
||||||
|
if (saturate) {
|
||||||
|
if (is_unsigned) {
|
||||||
|
e.UQADD(dest.S4(), src1.S4(), src2.S4());
|
||||||
|
} else {
|
||||||
|
e.SQADD(dest.S4(), src1.S4(), src2.S4());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e.ADD(dest.S4(), src1.S4(), src2.S4());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FLOAT32_TYPE:
|
||||||
|
assert_false(is_unsigned);
|
||||||
|
assert_false(saturate);
|
||||||
|
e.FADD(dest.S4(), src1.S4(), src2.S4());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert_unhandled_case(part_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
EMITTER_OPCODE_TABLE(OPCODE_VECTOR_ADD, VECTOR_ADD);
|
EMITTER_OPCODE_TABLE(OPCODE_VECTOR_ADD, VECTOR_ADD);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue