| Index: runtime/vm/simulator_arm64.cc
|
| ===================================================================
|
| --- runtime/vm/simulator_arm64.cc (revision 36461)
|
| +++ runtime/vm/simulator_arm64.cc (working copy)
|
| @@ -93,7 +93,9 @@
|
| Simulator* sim_;
|
|
|
| bool GetValue(char* desc, int64_t* value);
|
| + bool GetSValue(char* desc, int32_t* value);
|
| bool GetDValue(char* desc, int64_t* value);
|
| + bool GetQValue(char* desc, simd_value_t* value);
|
| // TODO(zra): Breakpoints.
|
| };
|
|
|
| @@ -185,10 +187,30 @@
|
| }
|
|
|
|
|
| +bool SimulatorDebugger::GetSValue(char* desc, int32_t* value) {
|
| + VRegister vreg = LookupVRegisterByName(desc);
|
| + if (vreg != kNoVRegister) {
|
| + *value = sim_->get_vregisters(vreg, 0);
|
| + return true;
|
| + }
|
| + if (desc[0] == '*') {
|
| + int64_t addr;
|
| + if (GetValue(desc + 1, &addr)) {
|
| + if (Simulator::IsIllegalAddress(addr)) {
|
| + return false;
|
| + }
|
| + *value = *(reinterpret_cast<int32_t*>(addr));
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| bool SimulatorDebugger::GetDValue(char* desc, int64_t* value) {
|
| VRegister vreg = LookupVRegisterByName(desc);
|
| if (vreg != kNoVRegister) {
|
| - *value = sim_->get_vregisterd(vreg);
|
| + *value = sim_->get_vregisterd(vreg, 0);
|
| return true;
|
| }
|
| if (desc[0] == '*') {
|
| @@ -205,6 +227,26 @@
|
| }
|
|
|
|
|
| +bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) {
|
| + VRegister vreg = LookupVRegisterByName(desc);
|
| + if (vreg != kNoVRegister) {
|
| + sim_->get_vregister(vreg, value);
|
| + return true;
|
| + }
|
| + if (desc[0] == '*') {
|
| + int64_t addr;
|
| + if (GetValue(desc + 1, &addr)) {
|
| + if (Simulator::IsIllegalAddress(addr)) {
|
| + return false;
|
| + }
|
| + *value = *(reinterpret_cast<simd_value_t*>(addr));
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| void SimulatorDebugger::Debug() {
|
| intptr_t last_pc = -1;
|
| bool done = false;
|
| @@ -259,7 +301,9 @@
|
| "gdb -- transfer control to gdb\n"
|
| "h/help -- print this help string\n"
|
| "p/print <reg or value or *addr> -- print integer value\n"
|
| - "pd/printdouble <dreg or *addr> -- print double value\n"
|
| + "pf/printfloat <vreg or *addr> --print float value\n"
|
| + "pd/printdouble <vreg or *addr> -- print double value\n"
|
| + "pq/printquad <vreg or *addr> -- print vector register\n"
|
| "po/printobject <*reg or *addr> -- print object\n"
|
| "si/stepi -- single step an instruction\n"
|
| "q/quit -- Quit the debugger and exit the program\n");
|
| @@ -284,6 +328,20 @@
|
| } else {
|
| OS::Print("print <reg or value or *addr>\n");
|
| }
|
| + } else if ((strcmp(cmd, "pf") == 0) ||
|
| + (strcmp(cmd, "printfloat") == 0)) {
|
| + if (args == 2) {
|
| + int32_t value;
|
| + if (GetSValue(arg1, &value)) {
|
| + float svalue = bit_cast<float, int32_t>(value);
|
| + OS::Print("%s: %d 0x%x %.8g\n",
|
| + arg1, value, value, svalue);
|
| + } else {
|
| + OS::Print("%s unrecognized\n", arg1);
|
| + }
|
| + } else {
|
| + OS::Print("printfloat <vreg or *addr>\n");
|
| + }
|
| } else if ((strcmp(cmd, "pd") == 0) ||
|
| (strcmp(cmd, "printdouble") == 0)) {
|
| if (args == 2) {
|
| @@ -296,8 +354,37 @@
|
| OS::Print("%s unrecognized\n", arg1);
|
| }
|
| } else {
|
| - OS::Print("printdouble <dreg or *addr>\n");
|
| + OS::Print("printdouble <vreg or *addr>\n");
|
| }
|
| + } else if ((strcmp(cmd, "pq") == 0) ||
|
| + (strcmp(cmd, "printquad") == 0)) {
|
| + if (args == 2) {
|
| + simd_value_t quad_value;
|
| + if (GetQValue(arg1, &quad_value)) {
|
| + const int64_t d0 = quad_value.bits.i64[0];
|
| + const int64_t d1 = quad_value.bits.i64[1];
|
| + const double dval0 = bit_cast<double, int64_t>(d0);
|
| + const double dval1 = bit_cast<double, int64_t>(d1);
|
| + const int32_t s0 = quad_value.bits.i32[0];
|
| + const int32_t s1 = quad_value.bits.i32[1];
|
| + const int32_t s2 = quad_value.bits.i32[2];
|
| + const int32_t s3 = quad_value.bits.i32[3];
|
| + const float sval0 = bit_cast<float, int32_t>(s0);
|
| + const float sval1 = bit_cast<float, int32_t>(s1);
|
| + const float sval2 = bit_cast<float, int32_t>(s2);
|
| + const float sval3 = bit_cast<float, int32_t>(s3);
|
| + OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n", arg1, d0, d0, dval0);
|
| + OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n", arg1, d1, d1, dval1);
|
| + OS::Print("%s: %d 0x%x %.8g\n", arg1, s0, s0, sval0);
|
| + OS::Print("%s: %d 0x%x %.8g\n", arg1, s1, s1, sval1);
|
| + OS::Print("%s: %d 0x%x %.8g\n", arg1, s2, s2, sval2);
|
| + OS::Print("%s: %d 0x%x %.8g\n", arg1, s3, s3, sval3);
|
| + } else {
|
| + OS::Print("%s unrecognized\n", arg1);
|
| + }
|
| + } else {
|
| + OS::Print("printquad <vreg or *addr>\n");
|
| + }
|
| } else if ((strcmp(cmd, "po") == 0) ||
|
| (strcmp(cmd, "printobject") == 0)) {
|
| if (args == 2) {
|
| @@ -471,8 +558,8 @@
|
| v_flag_ = false;
|
|
|
| for (int i = 0; i < kNumberOfVRegisters; i++) {
|
| - vregisters_[i].lo = 0;
|
| - vregisters_[i].hi = 0;
|
| + vregisters_[i].bits.i64[0] = 0;
|
| + vregisters_[i].bits.i64[1] = 0;
|
| }
|
|
|
| // The sp is initialized to point to the bottom (high address) of the
|
| @@ -616,30 +703,45 @@
|
| }
|
|
|
|
|
| -int64_t Simulator::get_vregisterd(VRegister reg) const {
|
| +int32_t Simulator::get_vregisters(VRegister reg, int idx) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| - return vregisters_[reg].lo;
|
| + ASSERT((idx >= 0) && (idx <= 3));
|
| + return vregisters_[reg].bits.i32[idx];
|
| }
|
|
|
|
|
| -void Simulator::set_vregisterd(VRegister reg, int64_t value) {
|
| +void Simulator::set_vregisters(VRegister reg, int idx, int32_t value) {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| - vregisters_[reg].lo = value;
|
| - vregisters_[reg].hi = 0;
|
| + ASSERT((idx >= 0) && (idx <= 3));
|
| + vregisters_[reg].bits.i32[idx] = value;
|
| }
|
|
|
|
|
| +int64_t Simulator::get_vregisterd(VRegister reg, int idx) const {
|
| + ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return vregisters_[reg].bits.i64[idx];
|
| +}
|
| +
|
| +
|
| +void Simulator::set_vregisterd(VRegister reg, int idx, int64_t value) {
|
| + ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + vregisters_[reg].bits.i64[idx] = value;
|
| +}
|
| +
|
| +
|
| 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;
|
| + value->bits.i64[0] = vregisters_[reg].bits.i64[0];
|
| + value->bits.i64[1] = vregisters_[reg].bits.i64[1];
|
| }
|
|
|
|
|
| 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;
|
| + vregisters_[reg].bits.i64[0] = value.bits.i64[0];
|
| + vregisters_[reg].bits.i64[1] = value.bits.i64[1];
|
| }
|
|
|
|
|
| @@ -1217,16 +1319,17 @@
|
| (redirection->argument_count() <= 8));
|
| SimulatorLeafFloatRuntimeCall target =
|
| reinterpret_cast<SimulatorLeafFloatRuntimeCall>(external);
|
| - const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0));
|
| - const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1));
|
| - const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2));
|
| - const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3));
|
| - const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4));
|
| - const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5));
|
| - const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6));
|
| - const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7));
|
| + const double d0 = bit_cast<double, int64_t>(get_vregisterd(V0, 0));
|
| + const double d1 = bit_cast<double, int64_t>(get_vregisterd(V1, 0));
|
| + const double d2 = bit_cast<double, int64_t>(get_vregisterd(V2, 0));
|
| + const double d3 = bit_cast<double, int64_t>(get_vregisterd(V3, 0));
|
| + const double d4 = bit_cast<double, int64_t>(get_vregisterd(V4, 0));
|
| + const double d5 = bit_cast<double, int64_t>(get_vregisterd(V5, 0));
|
| + const double d6 = bit_cast<double, int64_t>(get_vregisterd(V6, 0));
|
| + const double d7 = bit_cast<double, int64_t>(get_vregisterd(V7, 0));
|
| const double res = target(d0, d1, d2, d3, d4, d5, d6, d7);
|
| - set_vregisterd(V0, bit_cast<int64_t, double>(res));
|
| + set_vregisterd(V0, 0, bit_cast<int64_t, double>(res));
|
| + set_vregisterd(V0, 1, 0);
|
| } else if (redirection->call_kind() == kBootstrapNativeCall) {
|
| NativeArguments* arguments;
|
| arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
|
| @@ -1477,7 +1580,7 @@
|
| if (instr->Bit(26) == 1) {
|
| if (instr->Bit(22) == 0) {
|
| // Format(instr, "fstr'fsz 'vt, 'memop");
|
| - const int64_t vt_val = get_vregisterd(vt);
|
| + const int64_t vt_val = get_vregisterd(vt, 0);
|
| switch (size) {
|
| case 2:
|
| WriteW(address, vt_val & kWRegMask, instr);
|
| @@ -1488,8 +1591,8 @@
|
| case 4: {
|
| simd_value_t val;
|
| get_vregister(vt, &val);
|
| - WriteX(address, val.lo, instr);
|
| - WriteX(address + kWordSize, val.hi, instr);
|
| + WriteX(address, val.bits.i64[0], instr);
|
| + WriteX(address + kWordSize, val.bits.i64[1], instr);
|
| break;
|
| }
|
| default:
|
| @@ -1500,15 +1603,17 @@
|
| // Format(instr, "fldr'fsz 'vt, 'memop");
|
| switch (size) {
|
| case 2:
|
| - set_vregisterd(vt, static_cast<int64_t>(ReadWU(address, instr)));
|
| + set_vregisterd(vt, 0, static_cast<int64_t>(ReadWU(address, instr)));
|
| + set_vregisterd(vt, 1, 0);
|
| break;
|
| case 3:
|
| - set_vregisterd(vt, ReadX(address, instr));
|
| + set_vregisterd(vt, 0, ReadX(address, instr));
|
| + set_vregisterd(vt, 1, 0);
|
| break;
|
| case 4: {
|
| simd_value_t val;
|
| - val.lo = ReadX(address, instr);
|
| - val.hi = ReadX(address + kWordSize, instr);
|
| + val.bits.i64[0] = ReadX(address, instr);
|
| + val.bits.i64[1] = ReadX(address + kWordSize, instr);
|
| set_vregister(vt, val);
|
| break;
|
| }
|
| @@ -2067,8 +2172,145 @@
|
| }
|
|
|
|
|
| +void Simulator::DecodeSIMDCopy(Instr* instr) {
|
| + const int32_t Q = instr->Bit(30);
|
| + const int32_t op = instr->Bit(29);
|
| + const int32_t imm4 = instr->Bits(11, 4);
|
| + const int32_t imm5 = instr->Bits(16, 5);
|
| +
|
| + int32_t idx4 = -1;
|
| + int32_t idx5 = -1;
|
| + int32_t element_bytes;
|
| + if (imm5 & 0x1) {
|
| + idx4 = imm4;
|
| + idx5 = imm5 >> 1;
|
| + element_bytes = 1;
|
| + } else if (imm5 & 0x2) {
|
| + idx4 = imm4 >> 1;
|
| + idx5 = imm5 >> 2;
|
| + element_bytes = 2;
|
| + } else if (imm5 & 0x4) {
|
| + idx4 = imm4 >> 2;
|
| + idx5 = imm5 >> 3;
|
| + element_bytes = 4;
|
| + } else if (imm5 & 0x8) {
|
| + idx4 = imm4 >> 3;
|
| + idx5 = imm5 >> 4;
|
| + element_bytes = 8;
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + return;
|
| + }
|
| + ASSERT((idx4 != -1) && (idx5 != -1));
|
| +
|
| + const VRegister vd = instr->VdField();
|
| + const VRegister vn = instr->VnField();
|
| + if ((Q == 1) && (op == 0) && (imm4 == 0)) {
|
| + // Format(instr, "vdup'csz 'vd, 'vn'idx5");
|
| + if (element_bytes == 4) {
|
| + for (int i = 0; i < 4; i++) {
|
| + set_vregisters(vd, i, get_vregisters(vn, idx5));
|
| + }
|
| + } else if (element_bytes == 8) {
|
| + for (int i = 0; i < 2; i++) {
|
| + set_vregisterd(vd, i, get_vregisterd(vn, idx5));
|
| + }
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + return;
|
| + }
|
| + } else if ((Q == 1) && (op == 1)) {
|
| + // Format(instr, "vins'csz 'vd'idx5, 'vn'idx4");
|
| + if (element_bytes == 4) {
|
| + set_vregisters(vd, idx5, get_vregisters(vn, idx4));
|
| + } else if (element_bytes == 8) {
|
| + set_vregisterd(vd, idx5, get_vregisterd(vn, idx4));
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + }
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + }
|
| +}
|
| +
|
| +
|
| +void Simulator::DecodeSIMDThreeSame(Instr* instr) {
|
| + const int Q = instr->Bit(30);
|
| + const int U = instr->Bit(29);
|
| + const int opcode = instr->Bits(11, 5);
|
| +
|
| + if (Q == 0) {
|
| + UnimplementedInstruction(instr);
|
| + return;
|
| + }
|
| +
|
| + const VRegister vd = instr->VdField();
|
| + const VRegister vn = instr->VnField();
|
| + const VRegister vm = instr->VmField();
|
| + if (instr->Bit(22) == 0) {
|
| + // f32 case.
|
| + for (int idx = 0; idx < 4; idx++) {
|
| + const float vn_val = bit_cast<float, int32_t>(get_vregisters(vn, idx));
|
| + const float vm_val = bit_cast<float, int32_t>(get_vregisters(vm, idx));
|
| + float res = 0.0;
|
| + if ((U == 0) && (opcode == 0x1a)) {
|
| + if (instr->Bit(23) == 0) {
|
| + // Format(instr, "vadd'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val + vm_val;
|
| + } else {
|
| + // Format(instr, "vsub'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val - vm_val;
|
| + }
|
| + } else if ((U == 1) && (opcode == 0x1b)) {
|
| + // Format(instr, "vmul'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val * vm_val;
|
| + } else if ((U == 1) && (opcode == 0x1f)) {
|
| + // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val / vm_val;
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + return;
|
| + }
|
| + set_vregisters(vd, idx, bit_cast<int32_t, float>(res));
|
| + }
|
| + } else {
|
| + // f64 case.
|
| + for (int idx = 0; idx < 2; idx++) {
|
| + const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, idx));
|
| + const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, idx));
|
| + double res = 0.0;
|
| + if ((U == 0) && (opcode == 0x1a)) {
|
| + if (instr->Bit(23) == 0) {
|
| + // Format(instr, "vadd'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val + vm_val;
|
| + } else {
|
| + // Format(instr, "vsub'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val - vm_val;
|
| + }
|
| + } else if ((U == 1) && (opcode == 0x1b)) {
|
| + // Format(instr, "vmul'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val * vm_val;
|
| + } else if ((U == 1) && (opcode == 0x1f)) {
|
| + // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm");
|
| + res = vn_val / vm_val;
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + return;
|
| + }
|
| + set_vregisterd(vd, idx, bit_cast<int64_t, double>(res));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| void Simulator::DecodeDPSimd1(Instr* instr) {
|
| - UnimplementedInstruction(instr);
|
| + if (instr->IsSIMDCopyOp()) {
|
| + DecodeSIMDCopy(instr);
|
| + } else if (instr->IsSIMDThreeSameOp()) {
|
| + DecodeSIMDThreeSame(instr);
|
| + } else {
|
| + UnimplementedInstruction(instr);
|
| + }
|
| }
|
|
|
|
|
| @@ -2083,7 +2325,8 @@
|
| // Format(instr, "fmovd 'vd, #'immd");
|
| const VRegister vd = instr->VdField();
|
| const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
|
| - set_vregisterd(vd, immd);
|
| + set_vregisterd(vd, 0, immd);
|
| + set_vregisterd(vd, 1, 0);
|
| } else {
|
| // Single.
|
| UnimplementedInstruction(instr);
|
| @@ -2106,18 +2349,20 @@
|
| // Format(instr, "scvtfd 'vd, 'vn");
|
| const int64_t rn_val = get_register(rn, instr->RnMode());
|
| const double vn_dbl = static_cast<double>(rn_val);
|
| - set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl));
|
| + set_vregisterd(vd, 0, bit_cast<int64_t, double>(vn_dbl));
|
| + set_vregisterd(vd, 1, 0);
|
| } else if (instr->Bits(16, 5) == 6) {
|
| // Format(instr, "fmovrd 'rd, 'vn");
|
| - const int64_t vn_val = get_vregisterd(vn);
|
| + const int64_t vn_val = get_vregisterd(vn, 0);
|
| set_register(rd, vn_val, R31IsZR);
|
| } else if (instr->Bits(16, 5) == 7) {
|
| // Format(instr, "fmovdr 'vd, 'rn");
|
| const int64_t rn_val = get_register(rn, R31IsZR);
|
| - set_vregisterd(vd, rn_val);
|
| + set_vregisterd(vd, 0, rn_val);
|
| + set_vregisterd(vd, 1, 0);
|
| } else if (instr->Bits(16, 5) == 24) {
|
| // Format(instr, "fcvtzds 'rd, 'vn");
|
| - const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
|
| + const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
|
| set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode());
|
| } else {
|
| UnimplementedInstruction(instr);
|
| @@ -2129,7 +2374,7 @@
|
| 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 int64_t vn_val = get_vregisterd(vn, 0);
|
| 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);
|
| @@ -2145,7 +2390,7 @@
|
| switch (opc) {
|
| case 0:
|
| // Format("fmovdd 'vd, 'vn");
|
| - res_val = get_vregisterd(vn);
|
| + res_val = get_vregisterd(vn, 0);
|
| break;
|
| case 1:
|
| // Format("fabsd 'vd, 'vn");
|
| @@ -2175,7 +2420,8 @@
|
| break;
|
| }
|
|
|
| - set_vregisterd(vd, res_val);
|
| + set_vregisterd(vd, 0, res_val);
|
| + set_vregisterd(vd, 1, 0);
|
| }
|
|
|
|
|
| @@ -2187,8 +2433,8 @@
|
| const VRegister vd = instr->VdField();
|
| const VRegister vn = instr->VnField();
|
| const VRegister vm = instr->VmField();
|
| - const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
|
| - const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm));
|
| + const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
|
| + const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
|
| const int opc = instr->Bits(12, 4);
|
| double result;
|
|
|
| @@ -2214,19 +2460,20 @@
|
| return;
|
| }
|
|
|
| - set_vregisterd(vd, bit_cast<int64_t, double>(result));
|
| + set_vregisterd(vd, 0, bit_cast<int64_t, double>(result));
|
| + set_vregisterd(vd, 1, 0);
|
| }
|
|
|
|
|
| void Simulator::DecodeFPCompare(Instr* instr) {
|
| const VRegister vn = instr->VnField();
|
| const VRegister vm = instr->VmField();
|
| - const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
|
| + const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, 0));
|
| double vm_val;
|
|
|
| if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
|
| // Format(instr, "fcmpd 'vn, 'vm");
|
| - vm_val = bit_cast<double, int64_t>(get_vregisterd(vm));
|
| + vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, 0));
|
| } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
|
| if (instr->VmField() == V0) {
|
| // Format(instr, "fcmpd 'vn, #0.0");
|
| @@ -2366,10 +2613,14 @@
|
|
|
| // Setup parameters.
|
| if (fp_args) {
|
| - set_vregisterd(V0, parameter0);
|
| - set_vregisterd(V1, parameter1);
|
| - set_vregisterd(V2, parameter2);
|
| - set_vregisterd(V3, parameter3);
|
| + set_vregisterd(V0, 0, parameter0);
|
| + set_vregisterd(V0, 1, 0);
|
| + set_vregisterd(V1, 0, parameter1);
|
| + set_vregisterd(V1, 1, 0);
|
| + set_vregisterd(V2, 0, parameter2);
|
| + set_vregisterd(V2, 1, 0);
|
| + set_vregisterd(V3, 0, parameter3);
|
| + set_vregisterd(V3, 1, 0);
|
| } else {
|
| set_register(R0, parameter0);
|
| set_register(R1, parameter1);
|
| @@ -2408,8 +2659,9 @@
|
| int64_t preserved_dvals[kAbiPreservedFpuRegCount];
|
| for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
| const VRegister r = static_cast<VRegister>(i);
|
| - preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r);
|
| - set_vregisterd(r, callee_saved_value);
|
| + preserved_dvals[i - kAbiFirstPreservedFpuReg] = get_vregisterd(r, 0);
|
| + set_vregisterd(r, 0, callee_saved_value);
|
| + set_vregisterd(r, 1, 0);
|
| }
|
|
|
| // Start the simulation.
|
| @@ -2425,15 +2677,16 @@
|
|
|
| for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
|
| const VRegister r = static_cast<VRegister>(i);
|
| - ASSERT(callee_saved_value == get_vregisterd(r));
|
| - set_vregisterd(r, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
|
| + ASSERT(callee_saved_value == get_vregisterd(r, 0));
|
| + set_vregisterd(r, 0, preserved_dvals[i - kAbiFirstPreservedFpuReg]);
|
| + set_vregisterd(r, 1, 0);
|
| }
|
|
|
| // Restore the SP register and return R0.
|
| set_register(R31, sp_before_call, R31IsSP);
|
| int64_t return_value;
|
| if (fp_return) {
|
| - return_value = get_vregisterd(V0);
|
| + return_value = get_vregisterd(V0, 0);
|
| } else {
|
| return_value = get_register(R0);
|
| }
|
|
|