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

Unified Diff: runtime/vm/simulator_arm64.cc

Issue 269343010: Adds single-precision and SIMD load/store to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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/simulator_arm64.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_arm64.cc
===================================================================
--- runtime/vm/simulator_arm64.cc (revision 35932)
+++ runtime/vm/simulator_arm64.cc (working copy)
@@ -616,7 +616,7 @@
}
-int64_t Simulator::get_vregisterd(VRegister reg) {
+int64_t Simulator::get_vregisterd(VRegister reg) const {
ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
return vregisters_[reg].lo;
}
@@ -629,6 +629,20 @@
}
+void Simulator::get_vregister(VRegister reg, simd_value_t* value) const {
+ ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
+ value->lo = vregisters_[reg].lo;
+ value->hi = vregisters_[reg].hi;
+}
+
+
+void Simulator::set_vregister(VRegister reg, const simd_value_t& value) {
+ ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
+ vregisters_[reg].lo = value.lo;
+ vregisters_[reg].hi = value.hi;
+}
+
+
// Raw access to the PC register.
void Simulator::set_pc(int64_t value) {
pc_modified_ = true;
@@ -1409,7 +1423,9 @@
const Register rt = instr->RtField();
const VRegister vt = instr->VtField();
const int64_t rn_val = get_register(rn, R31IsSP);
- const uint32_t size = instr->SzField();
+ const uint32_t size =
+ (instr->Bit(26) == 1) ? ((instr->Bit(23) << 2) | instr->SzField())
+ : instr->SzField();
uword address = 0;
uword wb_address = 0;
bool wb = false;
@@ -1458,16 +1474,51 @@
}
// Do access.
- if (instr->Bits(22, 2) == 0) {
- if (instr->Bit(26) == 1) {
- // Format(instr, "vstrd 'vt, 'memop");
- if (size != 3) {
- UnimplementedInstruction(instr);
- return;
+ if (instr->Bit(26) == 1) {
+ if (instr->Bit(22) == 0) {
+ // Format(instr, "fstr'fsz 'vt, 'memop");
+ const int64_t vt_val = get_vregisterd(vt);
+ switch (size) {
+ case 2:
+ WriteW(address, vt_val & kWRegMask, instr);
+ break;
+ case 3:
+ WriteX(address, vt_val, instr);
+ break;
+ case 4: {
+ simd_value_t val;
+ get_vregister(vt, &val);
+ WriteX(address, val.lo, instr);
+ WriteX(address + kWordSize, val.hi, instr);
+ break;
+ }
+ default:
+ UnimplementedInstruction(instr);
+ return;
}
- const int64_t vt_val = get_vregisterd(vt);
- WriteX(address, vt_val, instr);
} else {
+ // Format(instr, "fldr'fsz 'vt, 'memop");
+ switch (size) {
+ case 2:
+ set_vregisterd(vt, static_cast<int64_t>(ReadWU(address, instr)));
+ break;
+ case 3:
+ set_vregisterd(vt, ReadX(address, instr));
+ break;
+ case 4: {
+ simd_value_t val;
+ val.lo = ReadX(address, instr);
+ val.hi = ReadX(address + kWordSize, instr);
+ set_vregister(vt, val);
+ break;
+ }
+ default:
+ UnimplementedInstruction(instr);
+ return;
+ }
+ }
+ } else {
+ if (instr->Bits(22, 2) == 0) {
// Format(instr, "str'sz 'rt, 'memop");
const int32_t rt_val32 = get_wregister(rt, R31IsZR);
switch (size) {
@@ -1495,16 +1546,6 @@
UNREACHABLE();
break;
}
- }
- } else {
- if (instr->Bit(26) == 1) {
- // Format(instr, "ldrd 'vt, 'memop");
- if ((size != 3) || (instr->Bit(23) != 0)) {
- UnimplementedInstruction(instr);
- return;
- }
- const int64_t val = ReadX(address, instr);
- set_vregisterd(vt, val);
} else {
// Format(instr, "ldr'sz 'rt, 'memop");
// Undefined case.
@@ -2085,12 +2126,21 @@
void Simulator::DecodeFPOneSource(Instr* instr) {
- const int opc = instr->Bits(15, 2);
+ const int opc = instr->Bits(15, 6);
const VRegister vd = instr->VdField();
const VRegister vn = instr->VnField();
const int64_t vn_val = get_vregisterd(vn);
+ const int32_t vn_val32 = vn_val & kWRegMask;
const double vn_dbl = bit_cast<double, int64_t>(vn_val);
+ const float vn_flt = bit_cast<float, int32_t>(vn_val32);
+ if ((opc != 5) && (instr->Bit(22) != 1)) {
+ // Source is interpreted as single-precision only if we're doing a
+ // conversion from single -> double.
+ UnimplementedInstruction(instr);
+ return;
+ }
+
int64_t res_val = 0;
switch (opc) {
case 0:
@@ -2109,8 +2159,19 @@
// Format("fsqrtd 'vd, 'vn");
res_val = bit_cast<int64_t, double>(sqrt(vn_dbl));
break;
+ case 4: {
+ // Format(instr, "fcvtsd 'vd, 'vn");
+ const uint32_t val =
+ bit_cast<uint32_t, float>(static_cast<float>(vn_dbl));
+ res_val = static_cast<int64_t>(val);
+ break;
+ }
+ case 5:
+ // Format(instr, "fcvtds 'vd, 'vn");
+ res_val = bit_cast<int64_t, double>(static_cast<double>(vn_flt));
+ break;
default:
- UNREACHABLE();
+ UnimplementedInstruction(instr);
break;
}
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698