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

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) {
1970 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { 1961 const Register rd = instr->RdField();
1971 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); 1962 const Register rn = instr->RnField();
1972 const Register rd = instr->RdField(); 1963 const Register rm = instr->RmField();
1973 const Register rn = instr->RnField(); 1964 const int64_t rm_val64 = get_register(rm, R31IsZR);
1974 const Register rm = instr->RmField(); 1965 const int32_t rm_val32 = get_wregister(rm, R31IsZR);
1975 if (instr->SFField() == 1) { 1966 const int64_t rn_val64 = get_register(rn, instr->RnMode());
1976 int64_t res = 0; 1967 const int32_t rn_val32 = get_wregister(rn, instr->RnMode());
1977 if (ConditionallyExecute(instr)) { 1968 int64_t result64 = rm_val64;
1978 res = get_register(rn, instr->RnMode()); 1969 int32_t result32 = rm_val32;
regis 2014/05/06 20:01:12 I do not think this is correct for cinc, which doe
zra 2014/05/06 20:50:24 Whoops. Thanks for catching this. I totally misrea
1979 } else { 1970
1980 res = get_register(rm, R31IsZR); 1971 if (ConditionallyExecute(instr)) {
1981 } 1972 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) {
1982 set_register(rd, res, instr->RdMode()); 1973 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm");
1974 result64 = rn_val64;
1975 result32 = rn_val32;
1976 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) {
1977 // Format(instr, "inc'sf'cond 'rd, 'rn, 'rm");
1978 result64 = rn_val64 + 1;
1979 result32 = rn_val32 + 1;
1983 } else { 1980 } else {
1984 int32_t res = 0; 1981 UnimplementedInstruction(instr);
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 } 1982 }
1983 }
1992 1984
1985 if (instr->SFField() == 1) {
1986 set_register(rd, result64, instr->RdMode());
1993 } else { 1987 } else {
1994 UnimplementedInstruction(instr); 1988 set_wregister(rd, result32, instr->RdMode());
1995 } 1989 }
1996 } 1990 }
1997 1991
1998 1992
1999 void Simulator::DecodeDPRegister(Instr* instr) { 1993 void Simulator::DecodeDPRegister(Instr* instr) {
2000 if (instr->IsAddSubShiftExtOp()) { 1994 if (instr->IsAddSubShiftExtOp()) {
2001 DecodeAddSubShiftExt(instr); 1995 DecodeAddSubShiftExt(instr);
2002 } else if (instr->IsLogicalShiftOp()) { 1996 } else if (instr->IsLogicalShiftOp()) {
2003 DecodeLogicalShift(instr); 1997 DecodeLogicalShift(instr);
2004 } else if (instr->IsMiscDP2SourceOp()) { 1998 } else if (instr->IsMiscDP2SourceOp()) {
(...skipping 26 matching lines...) Expand all
2031 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); 2025 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field());
2032 set_vregisterd(vd, immd); 2026 set_vregisterd(vd, immd);
2033 } else { 2027 } else {
2034 // Single. 2028 // Single.
2035 UnimplementedInstruction(instr); 2029 UnimplementedInstruction(instr);
2036 } 2030 }
2037 } 2031 }
2038 2032
2039 2033
2040 void Simulator::DecodeFPIntCvt(Instr* instr) { 2034 void Simulator::DecodeFPIntCvt(Instr* instr) {
2035 const VRegister vd = instr->VdField();
2036 const VRegister vn = instr->VnField();
2037 const Register rd = instr->RdField();
2038 const Register rn = instr->RnField();
2039
2041 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || 2040 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
2042 (instr->Bits(22, 2) != 1)) { 2041 (instr->Bits(22, 2) != 1)) {
2043 UnimplementedInstruction(instr); 2042 UnimplementedInstruction(instr);
2044 return; 2043 return;
2045 } 2044 }
2046 if (instr->Bits(16, 3) == 6) { 2045 if (instr->Bits(16, 5) == 2) {
2046 // Format(instr, "scvtfd 'vd, 'vn");
2047 const int64_t rn_val = get_register(rn, instr->RnMode());
2048 const double vn_dbl = static_cast<double>(rn_val);
2049 set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl));
2050 } else if (instr->Bits(16, 5) == 6) {
2047 // Format(instr, "fmovrd 'rd, 'vn"); 2051 // 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); 2052 const int64_t vn_val = get_vregisterd(vn);
2051 set_register(rd, vn_val, R31IsZR); 2053 set_register(rd, vn_val, R31IsZR);
2052 } else if (instr->Bits(16, 3) == 7) { 2054 } else if (instr->Bits(16, 5) == 7) {
2053 // Format(instr, "fmovdr 'vd, 'rn"); 2055 // 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); 2056 const int64_t rn_val = get_register(rn, R31IsZR);
2057 set_vregisterd(vd, rn_val); 2057 set_vregisterd(vd, rn_val);
2058 } else if (instr->Bits(16, 5) == 24) {
2059 // Format(instr, "fcvtzds 'rd, 'vn");
2060 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
2061 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode());
2058 } else { 2062 } else {
2059 UnimplementedInstruction(instr); 2063 UnimplementedInstruction(instr);
2060 } 2064 }
2061 } 2065 }
2062 2066
2063 2067
2064 void Simulator::DecodeFPOneSource(Instr* instr) { 2068 void Simulator::DecodeFPOneSource(Instr* instr) {
2065 const int opc = instr->Bits(15, 2); 2069 const int opc = instr->Bits(15, 2);
2066 const VRegister vd = instr->VdField(); 2070 const VRegister vd = instr->VdField();
2067 const VRegister vn = instr->VnField(); 2071 const VRegister vn = instr->VnField();
2068 switch (opc) { 2072 switch (opc) {
2069 case 0: 2073 case 0:
2070 // Format("fmovdd 'vd, 'vn"); 2074 // Format("fmovdd 'vd, 'vn");
2071 set_vregisterd(vd, get_vregisterd(vn)); 2075 set_vregisterd(vd, get_vregisterd(vn));
2072 break; 2076 break;
2073 default: 2077 default:
2074 UnimplementedInstruction(instr); 2078 UnimplementedInstruction(instr);
2075 break; 2079 break;
2076 } 2080 }
2077 } 2081 }
2078 2082
2079 2083
2084 void Simulator::DecodeFPTwoSource(Instr* instr) {
2085 if (instr->Bits(22, 2) != 1) {
2086 UnimplementedInstruction(instr);
2087 return;
2088 }
2089 const VRegister vd = instr->VdField();
2090 const VRegister vn = instr->VnField();
2091 const VRegister vm = instr->VmField();
2092 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn));
2093 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm));
2094 const int opc = instr->Bits(12, 4);
2095 double result;
2096
2097 switch (opc) {
2098 case 0:
2099 // Format(instr, "fmuld 'vd, 'vn, 'vm");
2100 result = vn_val * vm_val;
2101 break;
2102 case 1:
2103 // Format(instr, "fdivd 'vd, 'vn, 'vm");
2104 result = vn_val / vm_val;
2105 break;
2106 case 2:
2107 // Format(instr, "faddd 'vd, 'vn, 'vm");
2108 result = vn_val + vm_val;
2109 break;
2110 case 3:
2111 // Format(instr, "fsubd 'vd, 'vn, 'vm");
2112 result = vn_val - vm_val;
2113 break;
2114 default:
2115 // Unknown(instr);
2116 break;
2117 }
2118
2119 set_vregisterd(vd, bit_cast<int64_t, double>(result));
2120 }
2121
2122
2123 void Simulator::DecodeFPCompare(Instr* instr) {
2124 const VRegister vn = instr->VnField();
2125 const VRegister vm = instr->VmField();
2126 const double vn_val = get_vregisterd(vn);
2127 double vm_val;
2128
2129 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) {
2130 // Format(instr, "fcmpd 'vn, 'vm");
2131 vm_val = get_vregisterd(vm);
2132 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) {
2133 if (instr->VmField() == V0) {
2134 // Format(instr, "fcmpd 'vn, #0.0");
2135 vm_val = 0.0;
2136 } else {
2137 UnimplementedInstruction(instr);
2138 return;
2139 }
2140 } else {
2141 UnimplementedInstruction(instr);
2142 return;
2143 }
2144
2145 n_flag_ = false;
2146 z_flag_ = false;
2147 c_flag_ = false;
2148 v_flag_ = false;
2149
2150 if (isnan(vn_val) || isnan(vm_val)) {
2151 c_flag_ = true;
2152 v_flag_ = true;
2153 } else if (vn_val == vm_val) {
2154 z_flag_ = true;
2155 c_flag_ = true;
2156 } else if (vn_val < vm_val) {
2157 n_flag_ = true;
2158 } else {
2159 c_flag_ = true;
2160 }
2161 }
2162
2163
2080 void Simulator::DecodeFP(Instr* instr) { 2164 void Simulator::DecodeFP(Instr* instr) {
2081 if (instr->IsFPImmOp()) { 2165 if (instr->IsFPImmOp()) {
2082 DecodeFPImm(instr); 2166 DecodeFPImm(instr);
2083 } else if (instr->IsFPIntCvtOp()) { 2167 } else if (instr->IsFPIntCvtOp()) {
2084 DecodeFPIntCvt(instr); 2168 DecodeFPIntCvt(instr);
2085 } else if (instr->IsFPOneSourceOp()) { 2169 } else if (instr->IsFPOneSourceOp()) {
2086 DecodeFPOneSource(instr); 2170 DecodeFPOneSource(instr);
2171 } else if (instr->IsFPTwoSourceOp()) {
2172 DecodeFPTwoSource(instr);
2173 } else if (instr->IsFPCompareOp()) {
2174 DecodeFPCompare(instr);
2087 } else { 2175 } else {
2088 UnimplementedInstruction(instr); 2176 UnimplementedInstruction(instr);
2089 } 2177 }
2090 } 2178 }
2091 2179
2092 2180
2093 void Simulator::DecodeDPSimd2(Instr* instr) { 2181 void Simulator::DecodeDPSimd2(Instr* instr) {
2094 if (instr->IsFPOp()) { 2182 if (instr->IsFPOp()) {
2095 DecodeFP(instr); 2183 DecodeFP(instr);
2096 } else { 2184 } else {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 2374 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
2287 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 2375 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
2288 buf->Longjmp(); 2376 buf->Longjmp();
2289 } 2377 }
2290 2378
2291 } // namespace dart 2379 } // namespace dart
2292 2380
2293 #endif // !defined(HOST_ARCH_ARM64) 2381 #endif // !defined(HOST_ARCH_ARM64)
2294 2382
2295 #endif // defined TARGET_ARCH_ARM64 2383 #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