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

Unified Diff: runtime/vm/simulator_arm.cc

Issue 19773017: Adds ARM SIMD instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
« no previous file with comments | « runtime/vm/disassembler_arm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_arm.cc
===================================================================
--- runtime/vm/simulator_arm.cc (revision 25244)
+++ runtime/vm/simulator_arm.cc (working copy)
@@ -2900,6 +2900,40 @@
}
+static float arm_recip_estimate(float a) {
+ // From the ARM Architecture Reference Manual A2-85.
+ if (isinf(a) || (abs(a) >= exp2f(126))) return 0.0;
+ else if (a == 0.0) return INFINITY;
+ else if (isnan(a)) return a;
+
+ uint32_t a_bits = bit_cast<uint32_t, float>(a);
+ // scaled = '0011 1111 1110' : a<22:0> : Zeros(29)
+ uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) |
+ ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29);
+ // result_exp = 253 - UInt(a<30:23>)
+ int32_t result_exp = 253 - ((a_bits >> 23) & 0xff);
+ ASSERT((result_exp >= 1) && (result_exp <= 252));
+
+ double scaled_d = bit_cast<double, uint64_t>(scaled);
+ ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0));
+
+ // a in units of 1/512 rounded down.
+ int32_t q = static_cast<int32_t>(scaled_d * 512.0);
+ // reciprocal r.
+ double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
+ // r in units of 1/256 rounded to nearest.
+ int32_t s = static_cast<int32_t>(256.0 * r + 0.5);
+ double estimate = static_cast<double>(s) / 256.0;
+ ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0)));
+
+ // result = sign : result_exp<7:0> : estimate<51:29>
+ int32_t result_bits =
+ (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) |
+ ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
+ return bit_cast<float, int32_t>(result_bits);
+}
+
+
void Simulator::DecodeSIMDDataProcessing(Instr* instr) {
ASSERT(instr->ConditionField() == kSpecialCondition);
@@ -3038,6 +3072,33 @@
s8d.data_[i].u = s8n.data_[i].u | s8m.data_[i].u;
}
}
+ } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) &&
+ (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) {
+ // Format(instr, "vminqs 'qd, 'qn, 'qm");
+ for (int i = 0; i < 4; i++) {
+ s8d.data_[i].f =
+ s8n.data_[i].f <= s8m.data_[i].f ? s8n.data_[i].f : s8m.data_[i].f;
+ }
+ } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) &&
+ (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
+ // Format(instr, "vmaxqs 'qd, 'qn, 'qm");
+ for (int i = 0; i < 4; i++) {
+ s8d.data_[i].f =
+ s8n.data_[i].f >= s8m.data_[i].f ? s8n.data_[i].f : s8m.data_[i].f;
+ }
+ } else if ((instr->Bits(7, 5) == 10) && (instr->Bit(4) == 0) &&
+ (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
+ (instr->Bits(16, 4) == 11)) {
+ // Format(instr, "vrecpeq 'qd, 'qm");
+ for (int i = 0; i < 4; i++) {
+ s8d.data_[i].f = arm_recip_estimate(s8m.data_[i].f);
+ }
+ } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 1) &&
+ (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) {
+ // Format(instr, "vrecpsq 'qd, 'qn, 'qm");
+ for (int i = 0; i < 4; i++) {
+ s8d.data_[i].f = 2.0 - (s8n.data_[i].f * s8m.data_[i].f);
+ }
} else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) &&
(instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) &&
(instr->Bit(7) == 0)) {
« no previous file with comments | « runtime/vm/disassembler_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698