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

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

Issue 14061012: Enables API tests on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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/flow_graph_compiler_mips.cc ('k') | runtime/vm/stub_code_mips.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 return NULL; 852 return NULL;
853 } 853 }
854 854
855 855
856 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 856 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
857 UNIMPLEMENTED(); 857 UNIMPLEMENTED();
858 } 858 }
859 859
860 860
861 CompileType LoadIndexedInstr::ComputeType() const { 861 CompileType LoadIndexedInstr::ComputeType() const {
862 UNIMPLEMENTED(); 862 switch (class_id_) {
863 return CompileType::Dynamic(); 863 case kArrayCid:
864 case kImmutableArrayCid:
865 return CompileType::Dynamic();
866
867 case kTypedDataFloat32ArrayCid:
868 case kTypedDataFloat64ArrayCid:
869 return CompileType::FromCid(kDoubleCid);
870 case kTypedDataFloat32x4ArrayCid:
871 return CompileType::FromCid(kFloat32x4Cid);
872
873 case kTypedDataInt8ArrayCid:
874 case kTypedDataUint8ArrayCid:
875 case kTypedDataUint8ClampedArrayCid:
876 case kExternalTypedDataUint8ArrayCid:
877 case kExternalTypedDataUint8ClampedArrayCid:
878 case kTypedDataInt16ArrayCid:
879 case kTypedDataUint16ArrayCid:
880 case kOneByteStringCid:
881 case kTwoByteStringCid:
882 return CompileType::FromCid(kSmiCid);
883
884 case kTypedDataInt32ArrayCid:
885 case kTypedDataUint32ArrayCid:
886 // Result can be Smi or Mint when boxed.
887 // Instruction can deoptimize if we optimistically assumed that the result
888 // fits into Smi.
889 return CanDeoptimize() ? CompileType::FromCid(kSmiCid)
890 : CompileType::Int();
891
892 default:
893 UNIMPLEMENTED();
894 return CompileType::Dynamic();
895 }
864 } 896 }
865 897
866 898
867 Representation LoadIndexedInstr::representation() const { 899 Representation LoadIndexedInstr::representation() const {
868 UNIMPLEMENTED(); 900 switch (class_id_) {
869 return kTagged; 901 case kArrayCid:
902 case kImmutableArrayCid:
903 case kTypedDataInt8ArrayCid:
904 case kTypedDataUint8ArrayCid:
905 case kTypedDataUint8ClampedArrayCid:
906 case kExternalTypedDataUint8ArrayCid:
907 case kExternalTypedDataUint8ClampedArrayCid:
908 case kTypedDataInt16ArrayCid:
909 case kTypedDataUint16ArrayCid:
910 case kOneByteStringCid:
911 case kTwoByteStringCid:
912 return kTagged;
913 case kTypedDataInt32ArrayCid:
914 case kTypedDataUint32ArrayCid:
915 // Instruction can deoptimize if we optimistically assumed that the result
916 // fits into Smi.
917 return CanDeoptimize() ? kTagged : kUnboxedMint;
918 case kTypedDataFloat32ArrayCid:
919 case kTypedDataFloat64ArrayCid:
920 return kUnboxedDouble;
921 case kTypedDataFloat32x4ArrayCid:
922 return kUnboxedFloat32x4;
923 default:
924 UNIMPLEMENTED();
925 return kTagged;
926 }
870 } 927 }
871 928
872 929
873 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 930 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
874 UNIMPLEMENTED(); 931 const intptr_t kNumInputs = 2;
875 return NULL; 932 const intptr_t kNumTemps = 0;
933 LocationSummary* locs =
934 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
935 locs->set_in(0, Location::RequiresRegister());
936 // The smi index is either untagged (element size == 1), or it is left smi
937 // tagged (for all element sizes > 1).
938 // TODO(regis): Revisit and see if the index can be immediate.
939 locs->set_in(1, Location::WritableRegister());
940 if (representation() == kUnboxedDouble) {
941 locs->set_out(Location::RequiresFpuRegister());
942 } else {
943 locs->set_out(Location::RequiresRegister());
944 }
945 return locs;
876 } 946 }
877 947
878 948
879 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 949 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
880 UNIMPLEMENTED(); 950 Register array = locs()->in(0).reg();
951 Location index = locs()->in(1);
952
953 Address element_address(kNoRegister, 0);
954 if (IsExternal()) {
955 UNIMPLEMENTED();
956 } else {
957 ASSERT(this->array()->definition()->representation() == kTagged);
958 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
959 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
960 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
961 // index is expected to be untagged before accessing.
962 ASSERT(kSmiTagShift == 1);
963 switch (index_scale()) {
964 case 1: {
965 __ SmiUntag(index.reg());
966 break;
967 }
968 case 2: {
969 break;
970 }
971 case 4: {
972 __ sll(index.reg(), index.reg(), 1);
973 break;
974 }
975 case 8: {
976 __ sll(index.reg(), index.reg(), 2);
977 break;
978 }
979 case 16: {
980 __ sll(index.reg(), index.reg(), 3);
981 break;
982 }
983 default:
984 UNREACHABLE();
985 }
986 __ AddImmediate(index.reg(),
987 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
988 element_address = Address(array, index.reg());
989 }
990
991 if ((representation() == kUnboxedDouble) ||
992 (representation() == kUnboxedMint) ||
993 (representation() == kUnboxedFloat32x4)) {
994 UNIMPLEMENTED();
995 }
996
997 Register result = locs()->out().reg();
998 if ((index_scale() == 1) && index.IsRegister()) {
999 __ SmiUntag(index.reg());
1000 }
1001 switch (class_id()) {
1002 case kTypedDataInt8ArrayCid:
1003 ASSERT(index_scale() == 1);
1004 __ lb(result, element_address);
1005 __ SmiTag(result);
1006 break;
1007 case kTypedDataUint8ArrayCid:
1008 case kTypedDataUint8ClampedArrayCid:
1009 case kExternalTypedDataUint8ArrayCid:
1010 case kExternalTypedDataUint8ClampedArrayCid:
1011 case kOneByteStringCid:
1012 ASSERT(index_scale() == 1);
1013 __ lbu(result, element_address);
1014 __ SmiTag(result);
1015 break;
1016 case kTypedDataInt16ArrayCid:
1017 __ lh(result, element_address);
1018 __ SmiTag(result);
1019 break;
1020 case kTypedDataUint16ArrayCid:
1021 case kTwoByteStringCid:
1022 __ lhu(result, element_address);
1023 __ SmiTag(result);
1024 break;
1025 case kTypedDataInt32ArrayCid: {
1026 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
1027 __ lw(result, element_address);
1028 // Verify that the signed value in 'result' can fit inside a Smi.
1029 __ BranchLess(result, 0xC0000000, deopt);
1030 __ SmiTag(result);
1031 }
1032 break;
1033 case kTypedDataUint32ArrayCid: {
1034 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
1035 __ lw(result, element_address);
1036 // Verify that the unsigned value in 'result' can fit inside a Smi.
1037 __ LoadImmediate(TMP1, 0xC0000000);
1038 __ and_(CMPRES, result, TMP1);
1039 __ bne(CMPRES, ZR, deopt);
1040 __ SmiTag(result);
1041 }
1042 break;
1043 default:
1044 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1045 __ lw(result, element_address);
1046 break;
1047 }
881 } 1048 }
882 1049
883 1050
884 Representation StoreIndexedInstr::RequiredInputRepresentation( 1051 Representation StoreIndexedInstr::RequiredInputRepresentation(
885 intptr_t idx) const { 1052 intptr_t idx) const {
886 UNIMPLEMENTED(); 1053 UNIMPLEMENTED();
887 return kTagged; 1054 return kTagged;
888 } 1055 }
889 1056
890 1057
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 } 2194 }
2028 2195
2029 2196
2030 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2197 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2031 __ TraceSimMsg("BranchInstr"); 2198 __ TraceSimMsg("BranchInstr");
2032 comparison()->EmitBranchCode(compiler, this); 2199 comparison()->EmitBranchCode(compiler, this);
2033 } 2200 }
2034 2201
2035 2202
2036 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 2203 LocationSummary* CheckClassInstr::MakeLocationSummary() const {
2037 UNIMPLEMENTED(); 2204 const intptr_t kNumInputs = 1;
2038 return NULL; 2205 const intptr_t kNumTemps = 0;
2206 LocationSummary* summary =
2207 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2208 summary->set_in(0, Location::RequiresRegister());
2209 if (!null_check()) {
2210 summary->AddTemp(Location::RequiresRegister());
2211 }
2212 return summary;
2039 } 2213 }
2040 2214
2041 2215
2042 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2216 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2043 UNIMPLEMENTED(); 2217 if (null_check()) {
2218 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2219 kDeoptCheckClass);
2220 __ BranchEqual(locs()->in(0).reg(),
2221 reinterpret_cast<intptr_t>(Object::null()), deopt);
2222 return;
2223 }
2224
2225 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
2226 (unary_checks().NumberOfChecks() > 1));
2227 Register value = locs()->in(0).reg();
2228 Register temp = locs()->temp(0).reg();
2229 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2230 kDeoptCheckClass);
2231 Label is_ok;
2232 intptr_t cix = 0;
2233 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) {
2234 __ andi(CMPRES, value, Immediate(kSmiTagMask));
2235 __ beq(CMPRES, ZR, &is_ok);
2236 cix++; // Skip first check.
2237 } else {
2238 __ andi(CMPRES, value, Immediate(kSmiTagMask));
2239 __ beq(CMPRES, ZR, deopt);
2240 }
2241 __ LoadClassId(temp, value);
2242 const intptr_t num_checks = unary_checks().NumberOfChecks();
2243 for (intptr_t i = cix; i < num_checks; i++) {
2244 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid);
2245 __ LoadImmediate(TMP1, unary_checks().GetReceiverClassIdAt(i));
2246 __ subu(CMPRES, temp, TMP1);
2247 if (i == (num_checks - 1)) {
2248 __ bne(CMPRES, ZR, deopt);
2249 } else {
2250 __ beq(CMPRES, ZR, &is_ok);
2251 }
2252 }
2253 __ Bind(&is_ok);
2044 } 2254 }
2045 2255
2046 2256
2047 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { 2257 LocationSummary* CheckSmiInstr::MakeLocationSummary() const {
2048 const intptr_t kNumInputs = 1; 2258 const intptr_t kNumInputs = 1;
2049 const intptr_t kNumTemps = 0; 2259 const intptr_t kNumTemps = 0;
2050 LocationSummary* summary = 2260 LocationSummary* summary =
2051 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2261 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2052 summary->set_in(0, Location::RequiresRegister()); 2262 summary->set_in(0, Location::RequiresRegister());
2053 return summary; 2263 return summary;
2054 } 2264 }
2055 2265
2056 2266
2057 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2267 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2058 __ TraceSimMsg("CheckSmiInstr"); 2268 __ TraceSimMsg("CheckSmiInstr");
2059 Register value = locs()->in(0).reg(); 2269 Register value = locs()->in(0).reg();
2060 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2270 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2061 kDeoptCheckSmi); 2271 kDeoptCheckSmi);
2062 __ andi(TMP1, value, Immediate(kSmiTagMask)); 2272 __ andi(TMP1, value, Immediate(kSmiTagMask));
2063 __ bne(TMP1, ZR, deopt); 2273 __ bne(TMP1, ZR, deopt);
2064 } 2274 }
2065 2275
2066 2276
2067 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 2277 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
2068 UNIMPLEMENTED(); 2278 const intptr_t kNumInputs = 2;
2069 return NULL; 2279 const intptr_t kNumTemps = 0;
2280 LocationSummary* locs =
2281 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2282 locs->set_in(0, Location::RegisterOrSmiConstant(length()));
2283 locs->set_in(1, Location::RegisterOrSmiConstant(index()));
2284 return locs;
2070 } 2285 }
2071 2286
2072 2287
2073 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2288 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2074 UNIMPLEMENTED(); 2289 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2290 kDeoptCheckArrayBound);
2291 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) {
2292 // Unconditionally deoptimize for constant bounds checks because they
2293 // only occur only when index is out-of-bounds.
2294 __ b(deopt);
2295 return;
2296 }
2297
2298 if (locs()->in(1).IsConstant()) {
2299 Register length = locs()->in(0).reg();
2300 const Object& constant = locs()->in(1).constant();
2301 ASSERT(constant.IsSmi());
2302 __ BranchLessEqual(length, reinterpret_cast<int32_t>(constant.raw()),
2303 deopt);
2304 } else if (locs()->in(0).IsConstant()) {
2305 ASSERT(locs()->in(0).constant().IsSmi());
2306 const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
2307 Register index = locs()->in(1).reg();
2308 __ BranchGreaterEqual(index, reinterpret_cast<int32_t>(smi_const.raw()),
2309 deopt);
2310 } else {
2311 Register length = locs()->in(0).reg();
2312 Register index = locs()->in(1).reg();
2313 __ BranchGreaterEqual(index, length, deopt);
2314 }
2075 } 2315 }
2076 2316
2077 2317
2078 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { 2318 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const {
2079 UNIMPLEMENTED(); 2319 UNIMPLEMENTED();
2080 return NULL; 2320 return NULL;
2081 } 2321 }
2082 2322
2083 2323
2084 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2324 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
2452 &label, 2692 &label,
2453 PcDescriptors::kOther, 2693 PcDescriptors::kOther,
2454 locs()); 2694 locs());
2455 __ Drop(2); // Discard type arguments and receiver. 2695 __ Drop(2); // Discard type arguments and receiver.
2456 } 2696 }
2457 2697
2458 } // namespace dart 2698 } // namespace dart
2459 2699
2460 #endif // defined TARGET_ARCH_MIPS 2700 #endif // defined TARGET_ARCH_MIPS
2461 2701
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698