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

Side by Side Diff: runtime/vm/simulator_arm64.cc

Issue 262333007: Adds arm64 double arithmetic instructions. (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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <math.h> // for isnan. 5 #include <math.h> // for isnan.
6 #include <setjmp.h> 6 #include <setjmp.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #if defined(TARGET_ARCH_ARM64) 10 #if defined(TARGET_ARCH_ARM64)
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 end = start + (length * Instr::kInstrSize); 352 end = start + (length * Instr::kInstrSize);
353 } 353 }
354 } 354 }
355 Disassembler::Disassemble(start, end); 355 Disassembler::Disassemble(start, end);
356 } else if (strcmp(cmd, "flags") == 0) { 356 } else if (strcmp(cmd, "flags") == 0) {
357 OS::Print("APSR: "); 357 OS::Print("APSR: ");
358 OS::Print("N flag: %d; ", sim_->n_flag_); 358 OS::Print("N flag: %d; ", sim_->n_flag_);
359 OS::Print("Z flag: %d; ", sim_->z_flag_); 359 OS::Print("Z flag: %d; ", sim_->z_flag_);
360 OS::Print("C flag: %d; ", sim_->c_flag_); 360 OS::Print("C flag: %d; ", sim_->c_flag_);
361 OS::Print("V flag: %d\n", sim_->v_flag_); 361 OS::Print("V flag: %d\n", sim_->v_flag_);
362 OS::Print("FPSCR: ");
363 OS::Print("N flag: %d; ", sim_->fp_n_flag_);
364 OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
365 OS::Print("C flag: %d; ", sim_->fp_c_flag_);
366 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
367 } else if (strcmp(cmd, "gdb") == 0) { 362 } else if (strcmp(cmd, "gdb") == 0) {
368 OS::Print("relinquishing control to gdb\n"); 363 OS::Print("relinquishing control to gdb\n");
369 OS::DebugBreak(); 364 OS::DebugBreak();
370 OS::Print("regaining control from gdb\n"); 365 OS::Print("regaining control from gdb\n");
371 } else { 366 } else {
372 OS::Print("Unknown command: %s\n", cmd); 367 OS::Print("Unknown command: %s\n", cmd);
373 } 368 }
374 } 369 }
375 delete[] line; 370 delete[] line;
376 } 371 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 } 467 }
473 n_flag_ = false; 468 n_flag_ = false;
474 z_flag_ = false; 469 z_flag_ = false;
475 c_flag_ = false; 470 c_flag_ = false;
476 v_flag_ = false; 471 v_flag_ = false;
477 472
478 for (int i = 0; i < kNumberOfVRegisters; i++) { 473 for (int i = 0; i < kNumberOfVRegisters; i++) {
479 vregisters_[i].lo = 0; 474 vregisters_[i].lo = 0;
480 vregisters_[i].hi = 0; 475 vregisters_[i].hi = 0;
481 } 476 }
482 fp_n_flag_ = false;
483 fp_z_flag_ = false;
484 fp_c_flag_ = false;
485 fp_v_flag_ = false;
486 477
487 // The sp is initialized to point to the bottom (high address) of the 478 // The sp is initialized to point to the bottom (high address) of the
488 // allocated stack area. 479 // allocated stack area.
489 registers_[R31] = StackTop(); 480 registers_[R31] = StackTop();
490 // The lr and pc are initialized to a known bad value that will cause an 481 // The lr and pc are initialized to a known bad value that will cause an
491 // access violation if the simulator ever tries to execute it. 482 // access violation if the simulator ever tries to execute it.
492 registers_[LR] = kBadLR; 483 registers_[LR] = kBadLR;
493 pc_ = kBadLR; 484 pc_ = kBadLR;
494 } 485 }
495 486
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val); 1951 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val);
1961 const int64_t alu_out = static_cast<int64_t>(res >> 64); 1952 const int64_t alu_out = static_cast<int64_t>(res >> 64);
1962 set_register(rd, alu_out, R31IsZR); 1953 set_register(rd, alu_out, R31IsZR);
1963 } else { 1954 } else {
1964 UnimplementedInstruction(instr); 1955 UnimplementedInstruction(instr);
1965 } 1956 }
1966 } 1957 }
1967 1958
1968 1959
1969 void Simulator::DecodeConditionalSelect(Instr* instr) { 1960 void Simulator::DecodeConditionalSelect(Instr* instr) {
1961 const Register rd = instr->RdField();
1962 const Register rn = instr->RnField();
1963 const Register rm = instr->RmField();
1964 const int64_t rm_val64 = get_register(rm, R31IsZR);
1965 const int32_t rm_val32 = get_wregister(rm, R31IsZR);
1966 const int64_t rn_val64 = get_register(rn, instr->RnMode());
1967 const int32_t rn_val32 = get_wregister(rn, instr->RnMode());
1968 int64_t result64 = 0;
1969 int32_t result32 = 0;
1970
1970 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { 1971 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) {
1971 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); 1972 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm");
1972 const Register rd = instr->RdField(); 1973 result64 = rm_val64;
1973 const Register rn = instr->RnField(); 1974 result32 = rm_val32;
1974 const Register rm = instr->RmField(); 1975 if (ConditionallyExecute(instr)) {
1975 if (instr->SFField() == 1) { 1976 result64 = rn_val64;
1976 int64_t res = 0; 1977 result32 = rn_val32;
1977 if (ConditionallyExecute(instr)) {
1978 res = get_register(rn, instr->RnMode());
1979 } else {
1980 res = get_register(rm, R31IsZR);
1981 }
1982 set_register(rd, res, instr->RdMode());
1983 } else {
1984 int32_t res = 0;
1985 if (ConditionallyExecute(instr)) {
1986 res = get_wregister(rn, instr->RnMode());
1987 } else {
1988 res = get_wregister(rm, R31IsZR);
1989 }
1990 set_wregister(rd, res, instr->RdMode());
1991 } 1978 }
1992 1979 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) {
1980 // Format(instr, "csinc'sf'cond 'rd, 'rn, 'rm");
1981 result64 = rm_val64 + 1;
1982 result32 = rm_val32 + 1;
1983 if (ConditionallyExecute(instr)) {
1984 result64 = rn_val64;
1985 result32 = rn_val32;
1986 }
1993 } else { 1987 } else {
1994 UnimplementedInstruction(instr); 1988 UnimplementedInstruction(instr);
1989 return;
1990 }
1991
1992 if (instr->SFField() == 1) {
1993 set_register(rd, result64, instr->RdMode());
1994 } else {
1995 set_wregister(rd, result32, instr->RdMode());
1995 } 1996 }
1996 } 1997 }
1997 1998
1998 1999
1999 void Simulator::DecodeDPRegister(Instr* instr) { 2000 void Simulator::DecodeDPRegister(Instr* instr) {
2000 if (instr->IsAddSubShiftExtOp()) { 2001 if (instr->IsAddSubShiftExtOp()) {
2001 DecodeAddSubShiftExt(instr); 2002 DecodeAddSubShiftExt(instr);
2002 } else if (instr->IsLogicalShiftOp()) { 2003 } else if (instr->IsLogicalShiftOp()) {
2003 DecodeLogicalShift(instr); 2004 DecodeLogicalShift(instr);
2004 } else if (instr->IsMiscDP2SourceOp()) { 2005 } else if (instr->IsMiscDP2SourceOp()) {
(...skipping 26 matching lines...) Expand all
2031 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); 2032 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
2032 set_vregisterd(vd, immd); 2033 set_vregisterd(vd, immd);
2033 } else { 2034 } else {
2034 // Single. 2035 // Single.
2035 UnimplementedInstruction(instr); 2036 UnimplementedInstruction(instr);
2036 } 2037 }
2037 } 2038 }
2038 2039
2039 2040
2040 void Simulator::DecodeFPIntCvt(Instr* instr) { 2041 void Simulator::DecodeFPIntCvt(Instr* instr) {
2042 const VRegister vd = instr->VdField();
2043 const VRegister vn = instr->VnField();
2044 const Register rd = instr->RdField();
2045 const Register rn = instr->RnField();
2046
2041 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || 2047 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
2042 (instr->Bits(22, 2) != 1)) { 2048 (instr->Bits(22, 2) != 1)) {
2043 UnimplementedInstruction(instr); 2049 UnimplementedInstruction(instr);
2044 return; 2050 return;
2045 } 2051 }
2046 if (instr->Bits(16, 3) == 6) { 2052 if (instr->Bits(16, 5) == 2) {
2053 // Format(instr, "scvtfd 'vd, 'vn");
2054 const int64_t rn_val = get_register(rn, instr->RnMode());
2055 const double vn_dbl = static_cast<double>(rn_val);
2056 set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl));
2057 } else if (instr->Bits(16, 5) == 6) {
2047 // Format(instr, "fmovrd 'rd, 'vn"); 2058 // Format(instr, "fmovrd 'rd, 'vn");
2048 const VRegister vn = instr->VnField();
2049 const Register rd = instr->RdField();
2050 const int64_t vn_val = get_vregisterd(vn); 2059 const int64_t vn_val = get_vregisterd(vn);
2051 set_register(rd, vn_val, R31IsZR); 2060 set_register(rd, vn_val, R31IsZR);
2052 } else if (instr->Bits(16, 3) == 7) { 2061 } else if (instr->Bits(16, 5) == 7) {
2053 // Format(instr, "fmovdr 'vd, 'rn"); 2062 // Format(instr, "fmovdr 'vd, 'rn");
2054 const VRegister vd = instr->VdField();
2055 const Register rn = instr->RnField();
2056 const int64_t rn_val = get_register(rn, R31IsZR); 2063 const int64_t rn_val = get_register(rn, R31IsZR);
2057 set_vregisterd(vd, rn_val); 2064 set_vregisterd(vd, rn_val);
2065 } else if (instr->Bits(16, 5) == 24) {
2066 // Format(instr, "fcvtzds 'rd, 'vn");
2067 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
2068 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode());
2058 } else { 2069 } else {
2059 UnimplementedInstruction(instr); 2070 UnimplementedInstruction(instr);
2060 } 2071 }
2061 } 2072 }
2062 2073
2063 2074
2064 void Simulator::DecodeFPOneSource(Instr* instr) { 2075 void Simulator::DecodeFPOneSource(Instr* instr) {
2065 const int opc = instr->Bits(15, 2); 2076 const int opc = instr->Bits(15, 2);
2066 const VRegister vd = instr->VdField(); 2077 const VRegister vd = instr->VdField();
2067 const VRegister vn = instr->VnField(); 2078 const VRegister vn = instr->VnField();
2068 switch (opc) { 2079 switch (opc) {
2069 case 0: 2080 case 0:
2070 // Format("fmovdd 'vd, 'vn"); 2081 // Format("fmovdd 'vd, 'vn");
2071 set_vregisterd(vd, get_vregisterd(vn)); 2082 set_vregisterd(vd, get_vregisterd(vn));
2072 break; 2083 break;
2073 default: 2084 default:
2074 UnimplementedInstruction(instr); 2085 UnimplementedInstruction(instr);
2075 break; 2086 break;
2076 } 2087 }
2077 } 2088 }
2078 2089
2079 2090
2091 void Simulator::DecodeFPTwoSource(Instr* instr) {
2092 if (instr->Bits(22, 2) != 1) {
2093 UnimplementedInstruction(instr);
2094 return;
2095 }
2096 const VRegister vd = instr->VdField();
2097 const VRegister vn = instr->VnField();
2098 const VRegister vm = instr->VmField();
2099 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
2100 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm));
2101 const int opc = instr->Bits(12, 4);
2102 double result;
2103
2104 switch (opc) {
2105 case 0:
2106 // Format(instr, "fmuld 'vd, 'vn, 'vm");
2107 result = vn_val * vm_val;
2108 break;
2109 case 1:
2110 // Format(instr, "fdivd 'vd, 'vn, 'vm");
2111 result = vn_val / vm_val;
2112 break;
2113 case 2:
2114 // Format(instr, "faddd 'vd, 'vn, 'vm");
2115 result = vn_val + vm_val;
2116 break;
2117 case 3:
2118 // Format(instr, "fsubd 'vd, 'vn, 'vm");
2119 result = vn_val - vm_val;
2120 break;
2121 default:
2122 // Unknown(instr);
2123 break;
2124 }
2125
2126 set_vregisterd(vd, bit_cast<int64_t, double>(result));
2127 }
2128
2129
2130 void Simulator::DecodeFPCompare(Instr* instr) {
2131 const VRegister vn = instr->VnField();
2132 const VRegister vm = instr->VmField();
2133 const double vn_val = get_vregisterd(vn);
2134 double vm_val;
2135
2136 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
2137 // Format(instr, "fcmpd 'vn, 'vm");
2138 vm_val = get_vregisterd(vm);
2139 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
2140 if (instr->VmField() == V0) {
2141 // Format(instr, "fcmpd 'vn, #0.0");
2142 vm_val = 0.0;
2143 } else {
2144 UnimplementedInstruction(instr);
2145 return;
2146 }
2147 } else {
2148 UnimplementedInstruction(instr);
2149 return;
2150 }
2151
2152 n_flag_ = false;
2153 z_flag_ = false;
2154 c_flag_ = false;
2155 v_flag_ = false;
2156
2157 if (isnan(vn_val) || isnan(vm_val)) {
2158 c_flag_ = true;
2159 v_flag_ = true;
2160 } else if (vn_val == vm_val) {
2161 z_flag_ = true;
2162 c_flag_ = true;
2163 } else if (vn_val < vm_val) {
2164 n_flag_ = true;
2165 } else {
2166 c_flag_ = true;
2167 }
2168 }
2169
2170
2080 void Simulator::DecodeFP(Instr* instr) { 2171 void Simulator::DecodeFP(Instr* instr) {
2081 if (instr->IsFPImmOp()) { 2172 if (instr->IsFPImmOp()) {
2082 DecodeFPImm(instr); 2173 DecodeFPImm(instr);
2083 } else if (instr->IsFPIntCvtOp()) { 2174 } else if (instr->IsFPIntCvtOp()) {
2084 DecodeFPIntCvt(instr); 2175 DecodeFPIntCvt(instr);
2085 } else if (instr->IsFPOneSourceOp()) { 2176 } else if (instr->IsFPOneSourceOp()) {
2086 DecodeFPOneSource(instr); 2177 DecodeFPOneSource(instr);
2178 } else if (instr->IsFPTwoSourceOp()) {
2179 DecodeFPTwoSource(instr);
2180 } else if (instr->IsFPCompareOp()) {
2181 DecodeFPCompare(instr);
2087 } else { 2182 } else {
2088 UnimplementedInstruction(instr); 2183 UnimplementedInstruction(instr);
2089 } 2184 }
2090 } 2185 }
2091 2186
2092 2187
2093 void Simulator::DecodeDPSimd2(Instr* instr) { 2188 void Simulator::DecodeDPSimd2(Instr* instr) {
2094 if (instr->IsFPOp()) { 2189 if (instr->IsFPOp()) {
2095 DecodeFP(instr); 2190 DecodeFP(instr);
2096 } else { 2191 } else {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 2381 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
2287 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 2382 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
2288 buf->Longjmp(); 2383 buf->Longjmp();
2289 } 2384 }
2290 2385
2291 } // namespace dart 2386 } // namespace dart
2292 2387
2293 #endif // !defined(HOST_ARCH_ARM64) 2388 #endif // !defined(HOST_ARCH_ARM64)
2294 2389
2295 #endif // defined TARGET_ARCH_ARM64 2390 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« 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