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

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

Issue 15769010: Improve code for integral modulus calculation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. Created 7 years, 6 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/ia32/lithium-ia32.cc ('k') | src/mips/lithium-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 } 1125 }
1126 } 1126 }
1127 1127
1128 1128
1129 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1129 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1130 // Nothing to do. 1130 // Nothing to do.
1131 } 1131 }
1132 1132
1133 1133
1134 void LCodeGen::DoModI(LModI* instr) { 1134 void LCodeGen::DoModI(LModI* instr) {
1135 Register scratch = scratch0(); 1135 HMod* hmod = instr->hydrogen();
1136 const Register left = ToRegister(instr->left()); 1136 HValue* left = hmod->left();
1137 const Register result = ToRegister(instr->result()); 1137 HValue* right = hmod->right();
1138 if (hmod->HasPowerOf2Divisor()) {
1139 const Register scratch = scratch0();
1140 const Register left_reg = ToRegister(instr->left());
1141 ASSERT(!left_reg.is(scratch));
1142 const Register result_reg = ToRegister(instr->result());
1138 1143
1139 Label done; 1144 // Note: The code below even works when right contains kMinInt.
1145 int32_t divisor = Abs(right->GetInteger32Constant());
1140 1146
1141 if (instr->hydrogen()->HasPowerOf2Divisor()) { 1147 __ mov(scratch, left_reg);
1142 Register scratch = scratch0();
1143 ASSERT(!left.is(scratch));
1144 __ mov(scratch, left);
1145 int32_t p2constant = HConstant::cast(
1146 instr->hydrogen()->right())->Integer32Value();
1147 ASSERT(p2constant != 0);
1148 // Result always takes the sign of the dividend (left).
1149 p2constant = abs(p2constant);
1150 1148
1151 Label positive_dividend; 1149 Label left_is_not_negative, done;
1152 __ Branch(USE_DELAY_SLOT, &positive_dividend, ge, left, Operand(zero_reg)); 1150 if (left->CanBeNegative()) {
1153 __ subu(result, zero_reg, left); 1151 __ Branch(USE_DELAY_SLOT, &left_is_not_negative,
1154 __ And(result, result, p2constant - 1); 1152 ge, left_reg, Operand(zero_reg));
1155 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1153 __ subu(result_reg, zero_reg, left_reg);
1156 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 1154 __ And(result_reg, result_reg, divisor - 1);
1157 } 1155 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1158 __ Branch(USE_DELAY_SLOT, &done); 1156 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1159 __ subu(result, zero_reg, result); 1157 }
1160 __ bind(&positive_dividend); 1158 __ Branch(USE_DELAY_SLOT, &done);
1161 __ And(result, scratch, p2constant - 1); 1159 __ subu(result_reg, zero_reg, result_reg);
1162 } else {
1163 // div runs in the background while we check for special cases.
1164 Register right = EmitLoadRegister(instr->right(), scratch);
1165 __ div(left, right);
1166
1167 // Check for x % 0.
1168 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
1169 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg));
1170 } 1160 }
1171 1161
1172 // Check for (kMinInt % -1). 1162 __ bind(&left_is_not_negative);
1173 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1163 __ And(result_reg, scratch, divisor - 1);
1164 __ bind(&done);
1165
1166 } else {
1167 // TODO(svenpanne) Add right->has_fixed_right_arg() case.
1168
1169 const Register scratch = scratch0();
1170 const Register left_reg = ToRegister(instr->left());
1171 const Register result_reg = ToRegister(instr->result());
1172
1173 // div runs in the background while we check for special cases.
1174 Register right_reg = EmitLoadRegister(instr->right(), scratch);
1175 __ div(left_reg, right_reg);
1176
1177 Label done;
1178 // Check for x % 0, we have to deopt in this case because we can't return a
1179 // NaN.
1180 if (right->CanBeZero()) {
1181 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg));
1182 }
1183
1184 // Check for kMinInt % -1, we have to deopt if we care about -0, because we
1185 // can't return that.
1186 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
1174 Label left_not_min_int; 1187 Label left_not_min_int;
1175 __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); 1188 __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt));
1176 DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); 1189 // TODO(svenpanne) Don't deopt when we don't care about -0.
1190 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1));
1177 __ bind(&left_not_min_int); 1191 __ bind(&left_not_min_int);
1178 } 1192 }
1179 1193
1180 __ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg)); 1194 // TODO(svenpanne) Only emit the test/deopt if we have to.
1181 __ mfhi(result); 1195 __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg));
1196 __ mfhi(result_reg);
1182 1197
1183 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1198 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1184 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 1199 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
1185 } 1200 }
1201 __ bind(&done);
1186 } 1202 }
1187 __ bind(&done);
1188 } 1203 }
1189 1204
1190 1205
1191 void LCodeGen::DoDivI(LDivI* instr) { 1206 void LCodeGen::DoDivI(LDivI* instr) {
1192 const Register left = ToRegister(instr->left()); 1207 const Register left = ToRegister(instr->left());
1193 const Register right = ToRegister(instr->right()); 1208 const Register right = ToRegister(instr->right());
1194 const Register result = ToRegister(instr->result()); 1209 const Register result = ToRegister(instr->result());
1195 1210
1196 // On MIPS div is asynchronous - it will run in the background while we 1211 // On MIPS div is asynchronous - it will run in the background while we
1197 // check for special cases. 1212 // check for special cases.
(...skipping 4478 matching lines...) Expand 10 before | Expand all | Expand 10 after
5676 __ Subu(scratch, result, scratch); 5691 __ Subu(scratch, result, scratch);
5677 __ lw(result, FieldMemOperand(scratch, 5692 __ lw(result, FieldMemOperand(scratch,
5678 FixedArray::kHeaderSize - kPointerSize)); 5693 FixedArray::kHeaderSize - kPointerSize));
5679 __ bind(&done); 5694 __ bind(&done);
5680 } 5695 }
5681 5696
5682 5697
5683 #undef __ 5698 #undef __
5684 5699
5685 } } // namespace v8::internal 5700 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/mips/lithium-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698