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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6529050: ARM: Remove crankshaft dependency on the generic binary operation stub... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 10 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 | « src/arm/lithium-codegen-arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 // Nothing to do. 980 // Nothing to do.
981 } 981 }
982 982
983 983
984 void LCodeGen::DoModI(LModI* instr) { 984 void LCodeGen::DoModI(LModI* instr) {
985 class DeferredModI: public LDeferredCode { 985 class DeferredModI: public LDeferredCode {
986 public: 986 public:
987 DeferredModI(LCodeGen* codegen, LModI* instr) 987 DeferredModI(LCodeGen* codegen, LModI* instr)
988 : LDeferredCode(codegen), instr_(instr) { } 988 : LDeferredCode(codegen), instr_(instr) { }
989 virtual void Generate() { 989 virtual void Generate() {
990 codegen()->DoDeferredGenericBinaryStub(instr_, Token::MOD); 990 codegen()->DoDeferredBinaryOpStub(instr_, Token::MOD);
991 } 991 }
992 private: 992 private:
993 LModI* instr_; 993 LModI* instr_;
994 }; 994 };
995 // These registers hold untagged 32 bit values. 995 // These registers hold untagged 32 bit values.
996 Register left = ToRegister(instr->InputAt(0)); 996 Register left = ToRegister(instr->InputAt(0));
997 Register right = ToRegister(instr->InputAt(1)); 997 Register right = ToRegister(instr->InputAt(1));
998 Register result = ToRegister(instr->result()); 998 Register result = ToRegister(instr->result());
999 Register scratch = scratch0(); 999 Register scratch = scratch0();
1000 1000
1001 Label deoptimize, done; 1001 Label deoptimize, done;
1002 // Check for x % 0. 1002 // Check for x % 0.
1003 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1003 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1004 __ tst(right, Operand(right)); 1004 __ tst(right, Operand(right));
1005 __ b(eq, &deoptimize); 1005 __ b(eq, &deoptimize);
1006 } 1006 }
1007 1007
1008 // Check for (0 % -x) that will produce negative zero. 1008 // Check for (0 % -x) that will produce negative zero.
1009 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1009 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1010 Label ok; 1010 Label ok;
1011 __ tst(left, Operand(left)); 1011 __ tst(left, Operand(left));
1012 __ b(ne, &ok); 1012 __ b(ne, &ok);
1013 __ tst(right, Operand(right)); 1013 __ tst(right, Operand(right));
1014 __ b(pl, &ok); 1014 __ b(pl, &ok);
1015 __ b(al, &deoptimize); 1015 __ b(al, &deoptimize);
1016 __ bind(&ok); 1016 __ bind(&ok);
1017 } 1017 }
1018 1018
1019 // Try a few common cases before using the generic stub. 1019 // Try a few common cases before using the stub.
1020 Label call_stub; 1020 Label call_stub;
1021 const int kUnfolds = 3; 1021 const int kUnfolds = 3;
1022 // Skip if either side is negative. 1022 // Skip if either side is negative.
1023 __ cmp(left, Operand(0)); 1023 __ cmp(left, Operand(0));
1024 __ cmp(right, Operand(0), NegateCondition(mi)); 1024 __ cmp(right, Operand(0), NegateCondition(mi));
1025 __ b(mi, &call_stub); 1025 __ b(mi, &call_stub);
1026 // If the right hand side is smaller than the (nonnegative) 1026 // If the right hand side is smaller than the (nonnegative)
1027 // left hand side, it is the result. Else try a few subtractions 1027 // left hand side, it is the result. Else try a few subtractions
1028 // of the left hand side. 1028 // of the left hand side.
1029 __ mov(scratch, left); 1029 __ mov(scratch, left);
1030 for (int i = 0; i < kUnfolds; i++) { 1030 for (int i = 0; i < kUnfolds; i++) {
1031 // Check if the left hand side is less or equal than the 1031 // Check if the left hand side is less or equal than the
1032 // the right hand side. 1032 // the right hand side.
1033 __ cmp(scratch, right); 1033 __ cmp(scratch, right);
1034 __ mov(result, scratch, LeaveCC, lt); 1034 __ mov(result, scratch, LeaveCC, lt);
1035 __ b(lt, &done); 1035 __ b(lt, &done);
1036 // If not, reduce the left hand side by the right hand 1036 // If not, reduce the left hand side by the right hand
1037 // side and check again. 1037 // side and check again.
1038 if (i < kUnfolds - 1) __ sub(scratch, scratch, right); 1038 if (i < kUnfolds - 1) __ sub(scratch, scratch, right);
1039 } 1039 }
1040 1040
1041 // Check for power of two on the right hand side. 1041 // Check for power of two on the right hand side.
1042 __ JumpIfNotPowerOfTwoOrZero(right, scratch, &call_stub); 1042 __ JumpIfNotPowerOfTwoOrZero(right, scratch, &call_stub);
1043 // Perform modulo operation (scratch contains right - 1). 1043 // Perform modulo operation (scratch contains right - 1).
1044 __ and_(result, scratch, Operand(left)); 1044 __ and_(result, scratch, Operand(left));
1045 1045
1046 __ bind(&call_stub); 1046 __ bind(&call_stub);
1047 // Call the generic stub. The numbers in r0 and r1 have 1047 // Call the stub. The numbers in r0 and r1 have
1048 // to be tagged to Smis. If that is not possible, deoptimize. 1048 // to be tagged to Smis. If that is not possible, deoptimize.
1049 DeferredModI* deferred = new DeferredModI(this, instr); 1049 DeferredModI* deferred = new DeferredModI(this, instr);
1050 __ TrySmiTag(left, &deoptimize, scratch); 1050 __ TrySmiTag(left, &deoptimize, scratch);
1051 __ TrySmiTag(right, &deoptimize, scratch); 1051 __ TrySmiTag(right, &deoptimize, scratch);
1052 1052
1053 __ b(al, deferred->entry()); 1053 __ b(al, deferred->entry());
1054 __ bind(deferred->exit()); 1054 __ bind(deferred->exit());
1055 1055
1056 // If the result in r0 is a Smi, untag it, else deoptimize. 1056 // If the result in r0 is a Smi, untag it, else deoptimize.
1057 __ JumpIfNotSmi(result, &deoptimize); 1057 __ JumpIfNotSmi(result, &deoptimize);
1058 __ SmiUntag(result); 1058 __ SmiUntag(result);
1059 1059
1060 __ b(al, &done); 1060 __ b(al, &done);
1061 __ bind(&deoptimize); 1061 __ bind(&deoptimize);
1062 DeoptimizeIf(al, instr->environment()); 1062 DeoptimizeIf(al, instr->environment());
1063 __ bind(&done); 1063 __ bind(&done);
1064 } 1064 }
1065 1065
1066 1066
1067 void LCodeGen::DoDivI(LDivI* instr) { 1067 void LCodeGen::DoDivI(LDivI* instr) {
1068 class DeferredDivI: public LDeferredCode { 1068 class DeferredDivI: public LDeferredCode {
1069 public: 1069 public:
1070 DeferredDivI(LCodeGen* codegen, LDivI* instr) 1070 DeferredDivI(LCodeGen* codegen, LDivI* instr)
1071 : LDeferredCode(codegen), instr_(instr) { } 1071 : LDeferredCode(codegen), instr_(instr) { }
1072 virtual void Generate() { 1072 virtual void Generate() {
1073 codegen()->DoDeferredGenericBinaryStub(instr_, Token::DIV); 1073 codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV);
1074 } 1074 }
1075 private: 1075 private:
1076 LDivI* instr_; 1076 LDivI* instr_;
1077 }; 1077 };
1078 1078
1079 const Register left = ToRegister(instr->InputAt(0)); 1079 const Register left = ToRegister(instr->InputAt(0));
1080 const Register right = ToRegister(instr->InputAt(1)); 1080 const Register right = ToRegister(instr->InputAt(1));
1081 const Register scratch = scratch0(); 1081 const Register scratch = scratch0();
1082 const Register result = ToRegister(instr->result()); 1082 const Register result = ToRegister(instr->result());
1083 1083
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 __ cmp(right, Operand(2)); 1116 __ cmp(right, Operand(2));
1117 __ tst(left, Operand(1), eq); 1117 __ tst(left, Operand(1), eq);
1118 __ mov(result, Operand(left, ASR, 1), LeaveCC, eq); 1118 __ mov(result, Operand(left, ASR, 1), LeaveCC, eq);
1119 __ b(eq, &done); 1119 __ b(eq, &done);
1120 1120
1121 __ cmp(right, Operand(4)); 1121 __ cmp(right, Operand(4));
1122 __ tst(left, Operand(3), eq); 1122 __ tst(left, Operand(3), eq);
1123 __ mov(result, Operand(left, ASR, 2), LeaveCC, eq); 1123 __ mov(result, Operand(left, ASR, 2), LeaveCC, eq);
1124 __ b(eq, &done); 1124 __ b(eq, &done);
1125 1125
1126 // Call the generic stub. The numbers in r0 and r1 have 1126 // Call the stub. The numbers in r0 and r1 have
1127 // to be tagged to Smis. If that is not possible, deoptimize. 1127 // to be tagged to Smis. If that is not possible, deoptimize.
1128 DeferredDivI* deferred = new DeferredDivI(this, instr); 1128 DeferredDivI* deferred = new DeferredDivI(this, instr);
1129 1129
1130 __ TrySmiTag(left, &deoptimize, scratch); 1130 __ TrySmiTag(left, &deoptimize, scratch);
1131 __ TrySmiTag(right, &deoptimize, scratch); 1131 __ TrySmiTag(right, &deoptimize, scratch);
1132 1132
1133 __ b(al, deferred->entry()); 1133 __ b(al, deferred->entry());
1134 __ bind(deferred->exit()); 1134 __ bind(deferred->exit());
1135 1135
1136 // If the result in r0 is a Smi, untag it, else deoptimize. 1136 // If the result in r0 is a Smi, untag it, else deoptimize.
1137 __ JumpIfNotSmi(result, &deoptimize); 1137 __ JumpIfNotSmi(result, &deoptimize);
1138 __ SmiUntag(result); 1138 __ SmiUntag(result);
1139 __ b(&done); 1139 __ b(&done);
1140 1140
1141 __ bind(&deoptimize); 1141 __ bind(&deoptimize);
1142 DeoptimizeIf(al, instr->environment()); 1142 DeoptimizeIf(al, instr->environment());
1143 __ bind(&done); 1143 __ bind(&done);
1144 } 1144 }
1145 1145
1146 1146
1147 template<int T> 1147 template<int T>
1148 void LCodeGen::DoDeferredGenericBinaryStub(LTemplateInstruction<1, 2, T>* instr, 1148 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
1149 Token::Value op) { 1149 Token::Value op) {
1150 Register left = ToRegister(instr->InputAt(0)); 1150 Register left = ToRegister(instr->InputAt(0));
1151 Register right = ToRegister(instr->InputAt(1)); 1151 Register right = ToRegister(instr->InputAt(1));
1152 1152
1153 __ PushSafepointRegistersAndDoubles(); 1153 __ PushSafepointRegistersAndDoubles();
1154 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); 1154 // Move left to r1 and right to r0 for the stub call.
1155 if (left.is(r1)) {
1156 __ Move(r0, right);
1157 } else if (left.is(r0) && right.is(r1)) {
1158 __ Swap(r0, r1, r2);
1159 } else if (left.is(r0)) {
1160 ASSERT(!right.is(r1));
1161 __ mov(r1, r0);
1162 __ mov(r0, right);
1163 } else {
1164 ASSERT(!left.is(r0) && !right.is(r0));
1165 __ mov(r0, right);
1166 __ mov(r1, left);
1167 }
1168 TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT);
1155 __ CallStub(&stub); 1169 __ CallStub(&stub);
1156 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1170 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1157 0, 1171 0,
1158 Safepoint::kNoDeoptimizationIndex); 1172 Safepoint::kNoDeoptimizationIndex);
1159 // Overwrite the stored value of r0 with the result of the stub. 1173 // Overwrite the stored value of r0 with the result of the stub.
1160 __ StoreToSafepointRegistersAndDoublesSlot(r0); 1174 __ StoreToSafepointRegistersAndDoublesSlot(r0);
1161 __ PopSafepointRegistersAndDoubles(); 1175 __ PopSafepointRegistersAndDoubles();
1162 } 1176 }
1163 1177
1164 1178
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 break; 1438 break;
1425 } 1439 }
1426 } 1440 }
1427 1441
1428 1442
1429 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1443 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1430 ASSERT(ToRegister(instr->InputAt(0)).is(r1)); 1444 ASSERT(ToRegister(instr->InputAt(0)).is(r1));
1431 ASSERT(ToRegister(instr->InputAt(1)).is(r0)); 1445 ASSERT(ToRegister(instr->InputAt(1)).is(r0));
1432 ASSERT(ToRegister(instr->result()).is(r0)); 1446 ASSERT(ToRegister(instr->result()).is(r0));
1433 1447
1434 // TODO(regis): Implement TypeRecordingBinaryOpStub and replace current 1448 TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
1435 // GenericBinaryOpStub:
1436 // TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE);
1437 GenericBinaryOpStub stub(instr->op(), NO_OVERWRITE, r1, r0);
1438 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1449 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1439 } 1450 }
1440 1451
1441 1452
1442 int LCodeGen::GetNextEmittedBlock(int block) { 1453 int LCodeGen::GetNextEmittedBlock(int block) {
1443 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1454 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
1444 LLabel* label = chunk_->GetLabel(i); 1455 LLabel* label = chunk_->GetLabel(i);
1445 if (!label->HasReplacement()) return i; 1456 if (!label->HasReplacement()) return i;
1446 } 1457 }
1447 return -1; 1458 return -1;
(...skipping 2508 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 ASSERT(!environment->HasBeenRegistered()); 3967 ASSERT(!environment->HasBeenRegistered());
3957 RegisterEnvironmentForDeoptimization(environment); 3968 RegisterEnvironmentForDeoptimization(environment);
3958 ASSERT(osr_pc_offset_ == -1); 3969 ASSERT(osr_pc_offset_ == -1);
3959 osr_pc_offset_ = masm()->pc_offset(); 3970 osr_pc_offset_ = masm()->pc_offset();
3960 } 3971 }
3961 3972
3962 3973
3963 #undef __ 3974 #undef __
3964 3975
3965 } } // namespace v8::internal 3976 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698