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

Unified Diff: runtime/vm/simulator_arm64.cc

Issue 261783005: Begins work on arm64 floating point instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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/unit_test.h » ('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 35658)
+++ runtime/vm/simulator_arm64.cc (working copy)
@@ -93,7 +93,7 @@
Simulator* sim_;
bool GetValue(char* desc, int64_t* value);
- // TODO(zra): GetVValue for doubles.
+ bool GetDValue(char* desc, int64_t* value);
// TODO(zra): Breakpoints.
};
@@ -143,6 +143,16 @@
}
+static VRegister LookupVRegisterByName(const char* name) {
+ int reg_nr = -1;
+ bool ok = SScanF(name, "v%d", &reg_nr);
+ if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfVRegisters)) {
+ return static_cast<VRegister>(reg_nr);
+ }
+ return kNoVRegister;
+}
+
+
bool SimulatorDebugger::GetValue(char* desc, int64_t* value) {
Register reg = LookupCpuRegisterByName(desc);
if (reg != kNoRegister) {
@@ -175,6 +185,26 @@
}
+bool SimulatorDebugger::GetDValue(char* desc, int64_t* value) {
+ VRegister vreg = LookupVRegisterByName(desc);
+ if (vreg != kNoVRegister) {
+ *value = sim_->get_vregisterd(vreg);
+ return true;
+ }
+ if (desc[0] == '*') {
+ int64_t addr;
+ if (GetValue(desc + 1, &addr)) {
+ if (Simulator::IsIllegalAddress(addr)) {
+ return false;
+ }
+ *value = *(reinterpret_cast<int64_t*>(addr));
+ return true;
+ }
+ }
+ return false;
+}
+
+
void SimulatorDebugger::Debug() {
intptr_t last_pc = -1;
bool done = false;
@@ -225,9 +255,11 @@
" disasm <address>\n"
" disasm <address> <number_of_instructions>\n"
" by default 10 instrs are disassembled\n"
+ "flags -- print flag values\n"
"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"
"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");
@@ -252,6 +284,20 @@
} else {
OS::Print("print <reg or value or *addr>\n");
}
+ } else if ((strcmp(cmd, "pd") == 0) ||
+ (strcmp(cmd, "printdouble") == 0)) {
+ if (args == 2) {
+ int64_t long_value;
+ if (GetDValue(arg1, &long_value)) {
+ double dvalue = bit_cast<double, int64_t>(long_value);
+ OS::Print("%s: %"Pu64" 0x%"Px64" %.8g\n",
+ arg1, long_value, long_value, dvalue);
+ } else {
+ OS::Print("%s unrecognized\n", arg1);
+ }
+ } else {
+ OS::Print("printdouble <dreg or *addr>\n");
+ }
} else if ((strcmp(cmd, "po") == 0) ||
(strcmp(cmd, "printobject") == 0)) {
if (args == 2) {
@@ -307,6 +353,17 @@
}
}
Disassembler::Disassemble(start, end);
+ } else if (strcmp(cmd, "flags") == 0) {
+ OS::Print("APSR: ");
+ OS::Print("N flag: %d; ", sim_->n_flag_);
+ OS::Print("Z flag: %d; ", sim_->z_flag_);
+ OS::Print("C flag: %d; ", sim_->c_flag_);
+ OS::Print("V flag: %d\n", sim_->v_flag_);
+ OS::Print("FPSCR: ");
+ OS::Print("N flag: %d; ", sim_->fp_n_flag_);
+ OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
+ OS::Print("C flag: %d; ", sim_->fp_c_flag_);
+ OS::Print("V flag: %d\n", sim_->fp_v_flag_);
} else if (strcmp(cmd, "gdb") == 0) {
OS::Print("relinquishing control to gdb\n");
OS::DebugBreak();
@@ -418,6 +475,15 @@
c_flag_ = false;
v_flag_ = false;
+ for (int i = 0; i < kNumberOfVRegisters; i++) {
+ vregisters_[i].lo = 0;
+ vregisters_[i].hi = 0;
+ }
+ fp_n_flag_ = false;
+ fp_z_flag_ = false;
+ fp_c_flag_ = false;
+ fp_v_flag_ = false;
+
// The sp is initialized to point to the bottom (high address) of the
// allocated stack area.
registers_[R31] = StackTop();
@@ -559,6 +625,19 @@
}
+int64_t Simulator::get_vregisterd(VRegister reg) {
+ ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
+ return vregisters_[reg].lo;
+}
+
+
+void Simulator::set_vregisterd(VRegister reg, int64_t value) {
+ ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
+ vregisters_[reg].lo = value;
+ vregisters_[reg].hi = 0;
+}
+
+
// Raw access to the PC register.
void Simulator::set_pc(int64_t value) {
pc_modified_ = true;
@@ -843,7 +922,7 @@
const int hw = instr->HWField();
const int64_t shift = hw << 4;
const int64_t shifted_imm =
- static_cast<uint64_t>(instr->Imm16Field()) << shift;
+ static_cast<int64_t>(instr->Imm16Field()) << shift;
if (instr->SFField()) {
if (instr->Bits(29, 2) == 0) {
@@ -1899,8 +1978,66 @@
}
+void Simulator::DecodeFPImm(Instr* instr) {
+ if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
+ (instr->Bits(5, 5) != 0)) {
+ UnimplementedInstruction(instr);
+ return;
+ }
+ if (instr->Bit(22) == 1) {
+ // Double.
+ // Format(instr, "fmovd 'vd, #'immd");
+ const VRegister vd = instr->VdField();
+ const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
+ set_vregisterd(vd, immd);
+ } else {
+ // Single.
+ UnimplementedInstruction(instr);
+ }
+}
+
+
+void Simulator::DecodeFPIntCvt(Instr* instr) {
+ if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
+ (instr->Bits(22, 2) != 1)) {
+ UnimplementedInstruction(instr);
+ return;
+ }
+ if (instr->Bits(16, 3) == 6) {
+ // Format(instr, "fmovrd 'rd, 'vn");
+ const VRegister vn = instr->VnField();
+ const Register rd = instr->RdField();
+ const int64_t vn_val = get_vregisterd(vn);
+ set_register(rd, vn_val, R31IsZR);
+ } else if (instr->Bits(16, 3) == 7) {
+ // Format(instr, "fmovdr 'vd, 'rn");
+ const VRegister vd = instr->VdField();
+ const Register rn = instr->RnField();
+ const int64_t rn_val = get_register(rn, R31IsZR);
+ set_vregisterd(vd, rn_val);
+ } else {
+ UnimplementedInstruction(instr);
+ }
+}
+
+
+void Simulator::DecodeFP(Instr* instr) {
+ if (instr->IsFPImmOp()) {
+ DecodeFPImm(instr);
+ } else if (instr->IsFPIntCvtOp()) {
+ DecodeFPIntCvt(instr);
+ } else {
+ UnimplementedInstruction(instr);
+ }
+}
+
+
void Simulator::DecodeDPSimd2(Instr* instr) {
- UnimplementedInstruction(instr);
+ if (instr->IsFPOp()) {
+ DecodeFP(instr);
+ } else {
+ UnimplementedInstruction(instr);
+ }
}
@@ -1977,15 +2114,24 @@
int64_t parameter0,
int64_t parameter1,
int64_t parameter2,
- int64_t parameter3) {
+ int64_t parameter3,
+ bool fp_return,
+ bool fp_args) {
// Save the SP register before the call so we can restore it.
intptr_t sp_before_call = get_register(R31, R31IsSP);
// Setup parameters.
- set_register(R0, parameter0);
- set_register(R1, parameter1);
- set_register(R2, parameter2);
- set_register(R3, parameter3);
+ if (fp_args) {
+ set_vregisterd(V0, parameter0);
+ set_vregisterd(V1, parameter1);
+ set_vregisterd(V2, parameter2);
+ set_vregisterd(V3, parameter3);
+ } else {
+ set_register(R0, parameter0);
+ set_register(R1, parameter1);
+ set_register(R2, parameter2);
+ set_register(R3, parameter3);
+ }
// Make sure the activation frames are properly aligned.
intptr_t stack_pointer = sp_before_call;
@@ -2002,67 +2148,50 @@
// the LR the simulation stops when returning to this call point.
set_register(LR, kEndSimulatingPC);
- // Remember the values of callee-saved registers.
- int64_t r19_val = get_register(R19);
- int64_t r20_val = get_register(R20);
- int64_t r21_val = get_register(R21);
- int64_t r22_val = get_register(R22);
- int64_t r23_val = get_register(R23);
- int64_t r24_val = get_register(R24);
- int64_t r25_val = get_register(R25);
- int64_t r26_val = get_register(R26);
- int64_t r27_val = get_register(R27);
- int64_t r28_val = get_register(R28);
- int64_t r29_val = get_register(R29);
-
- // Setup the callee-saved registers with a known value. To be able to check
- // that they are preserved properly across dart execution.
+ // Remember the values of callee-saved registers, and set them up with a
+ // known value so that we are able to check that they are preserved
+ // properly across Dart execution.
+ int64_t preserved_vals[kAbiPreservedCpuRegCount];
int64_t callee_saved_value = icount_;
- set_register(R19, callee_saved_value);
- set_register(R20, callee_saved_value);
- set_register(R21, callee_saved_value);
- set_register(R22, callee_saved_value);
- set_register(R23, callee_saved_value);
- set_register(R24, callee_saved_value);
- set_register(R25, callee_saved_value);
- set_register(R26, callee_saved_value);
- set_register(R27, callee_saved_value);
- set_register(R28, callee_saved_value);
- set_register(R29, callee_saved_value);
+ for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
+ const Register r = static_cast<Register>(i);
+ preserved_vals[i - kAbiFirstPreservedCpuReg] = get_register(r);
+ set_register(r, callee_saved_value);
+ }
+ // Only the bottom half of the V registers must be preserved.
+ 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);
+ }
+
// Start the simulation
Execute();
- // Check that the callee-saved registers have been preserved.
- ASSERT(callee_saved_value == get_register(R19));
- ASSERT(callee_saved_value == get_register(R20));
- ASSERT(callee_saved_value == get_register(R21));
- ASSERT(callee_saved_value == get_register(R22));
- ASSERT(callee_saved_value == get_register(R23));
- ASSERT(callee_saved_value == get_register(R24));
- ASSERT(callee_saved_value == get_register(R25));
- ASSERT(callee_saved_value == get_register(R26));
- ASSERT(callee_saved_value == get_register(R27));
- ASSERT(callee_saved_value == get_register(R28));
- ASSERT(callee_saved_value == get_register(R29));
+ // Check that the callee-saved registers have been preserved,
+ // and restore them with the original value
+ for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
+ const Register r = static_cast<Register>(i);
+ ASSERT(callee_saved_value == get_register(r));
+ set_register(r, preserved_vals[i - kAbiFirstPreservedCpuReg]);
+ }
- // Restore callee-saved registers with the original value.
- set_register(R19, r19_val);
- set_register(R20, r20_val);
- set_register(R21, r21_val);
- set_register(R22, r22_val);
- set_register(R23, r23_val);
- set_register(R24, r24_val);
- set_register(R25, r25_val);
- set_register(R26, r26_val);
- set_register(R27, r27_val);
- set_register(R28, r28_val);
- set_register(R29, r29_val);
+ 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]);
+ }
// Restore the SP register and return R0.
set_register(R31, sp_before_call, R31IsSP);
int64_t return_value;
- return_value = get_register(R0);
+ if (fp_return) {
+ return_value = get_vregisterd(V0);
+ } else {
+ return_value = get_register(R0);
+ }
return return_value;
}
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/unit_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698