Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Unified Diff: src/arm/simulator-arm.cc

Issue 2711863002: Implement remaining Boolean SIMD operations on ARM. (Closed)
Patch Set: All Boolean vector tests. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/arm/simulator-arm.cc
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 3a3a90225bf0af1fa7ba72f454fca9fd8487eb42..a4659de3c689aa419ee989e625b3066b0dea838f 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -900,6 +900,18 @@ void Simulator::set_d_register(int dreg, const uint32_t* value) {
}
template <typename T>
+void Simulator::get_d_register(int dreg, T* value) {
+ DCHECK((dreg >= 0) && (dreg < num_d_registers));
+ memcpy(value, vfp_registers_ + dreg * 2, kDoubleSize);
+}
+
+template <typename T>
+void Simulator::set_d_register(int dreg, const T* value) {
+ DCHECK((dreg >= 0) && (dreg < num_d_registers));
+ memcpy(vfp_registers_ + dreg * 2, value, kDoubleSize);
+}
+
+template <typename T>
void Simulator::get_q_register(int qreg, T* value) {
DCHECK((qreg >= 0) && (qreg < num_q_registers));
memcpy(value, vfp_registers_ + qreg * 4, kSimd128Size);
@@ -911,7 +923,6 @@ void Simulator::set_q_register(int qreg, const T* value) {
memcpy(vfp_registers_ + qreg * 4, value, kSimd128Size);
}
-
// Raw access to the PC register.
void Simulator::set_pc(int32_t value) {
pc_modified_ = true;
@@ -4343,6 +4354,63 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
}
break;
}
+ case 0xa: {
+ // vpmin/vpmax.s<size> Dd, Dm, Dn.
+ NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
+ bool min = instr->Bit(4) != 0;
+ switch (size) {
+ case Neon8: {
+ int8_t dst[8], src1[8], src2[8];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ for (int i = 0; i < 4; i++) {
+ if (min) {
martyn.capewell 2017/02/28 15:45:24 How about a templated minmax helper? template <typ
bbudge 2017/02/28 17:39:35 That does look nicer. Done.
+ dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 4] = std::min(src2[i * 2], src2[i * 2 + 1]);
+ } else {
+ dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 4] = std::max(src2[i * 2], src2[i * 2 + 1]);
+ }
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ case Neon16: {
+ int16_t dst[4], src1[4], src2[4];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ for (int i = 0; i < 2; i++) {
+ if (min) {
+ dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 2] = std::min(src2[i * 2], src2[i * 2 + 1]);
+ } else {
+ dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 2] = std::max(src2[i * 2], src2[i * 2 + 1]);
+ }
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ case Neon32: {
+ int32_t dst[2], src1[2], src2[2];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ if (min) {
+ dst[0] = std::min(src1[0], src1[1]);
+ dst[1] = std::min(src2[0], src2[1]);
+ } else {
+ dst[0] = std::max(src1[0], src1[1]);
+ dst[1] = std::max(src2[0], src2[1]);
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ }
case 0xd: {
if (instr->Bit(4) == 0) {
float src1[4], src2[4];
@@ -4812,6 +4880,63 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
}
break;
}
+ case 0xa: {
+ // vpmin/vpmax.u<size> Dd, Dm, Dn.
+ NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
+ bool min = instr->Bit(4) != 0;
+ switch (size) {
+ case Neon8: {
+ uint8_t dst[8], src1[8], src2[8];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ for (int i = 0; i < 4; i++) {
+ if (min) {
+ dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 4] = std::min(src2[i * 2], src2[i * 2 + 1]);
+ } else {
+ dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 4] = std::max(src2[i * 2], src2[i * 2 + 1]);
+ }
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ case Neon16: {
+ uint16_t dst[4], src1[4], src2[4];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ for (int i = 0; i < 2; i++) {
+ if (min) {
+ dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 2] = std::min(src2[i * 2], src2[i * 2 + 1]);
+ } else {
+ dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
+ dst[i + 2] = std::max(src2[i * 2], src2[i * 2 + 1]);
+ }
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ case Neon32: {
+ uint32_t dst[2], src1[2], src2[2];
+ get_d_register(Vn, src1);
+ get_d_register(Vm, src2);
+ if (min) {
+ dst[0] = std::min(src1[0], src1[1]);
+ dst[1] = std::min(src2[0], src2[1]);
+ } else {
+ dst[0] = std::max(src1[0], src1[1]);
+ dst[1] = std::max(src2[0], src2[1]);
+ }
+ set_d_register(Vd, dst);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ }
case 0xd: {
if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) {
// vmul.f32 Qd, Qn, Qm

Powered by Google App Engine
This is Rietveld 408576698