summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/rsp/vsub.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/rsp/vsub.h')
-rw-r--r--src/devices/cpu/rsp/vsub.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/devices/cpu/rsp/vsub.h b/src/devices/cpu/rsp/vsub.h
new file mode 100644
index 00000000000..c3df93627c8
--- /dev/null
+++ b/src/devices/cpu/rsp/vsub.h
@@ -0,0 +1,17 @@
+// license:BSD-3-Clause
+// copyright-holders:Tyler J. Stachecki,Ryan Holtz
+
+inline rsp_vec_t vec_vsub(rsp_vec_t vs, rsp_vec_t vt, rsp_vec_t carry, rsp_vec_t *acc_lo)
+{
+ // acc_lo uses saturated arithmetic.
+ rsp_vec_t unsat_diff = _mm_sub_epi16(vt, carry);
+ rsp_vec_t sat_diff = _mm_subs_epi16(vt, carry);
+
+ *acc_lo = _mm_sub_epi16(vs, unsat_diff);
+ rsp_vec_t vd = _mm_subs_epi16(vs, sat_diff);
+
+ // VD is the signed diff of the two sources and the carry. Since we
+ // have to saturate the diff of all three, we have to be clever.
+ rsp_vec_t overflow = _mm_cmpgt_epi16(sat_diff, unsat_diff);
+ return _mm_adds_epi16(vd, overflow);
+}