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

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

Issue 166793002: Fixed and improved code for integral division. Fixed and extended tests. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: A64 fixes and cleanup Created 6 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 1145
1146 __ addq(reg2, Immediate(1 << 30)); 1146 __ addq(reg2, Immediate(1 << 30));
1147 __ sar(reg2, Immediate(shift)); 1147 __ sar(reg2, Immediate(shift));
1148 } 1148 }
1149 } 1149 }
1150 1150
1151 1151
1152 void LCodeGen::DoDivI(LDivI* instr) { 1152 void LCodeGen::DoDivI(LDivI* instr) {
1153 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) { 1153 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1154 Register dividend = ToRegister(instr->left()); 1154 Register dividend = ToRegister(instr->left());
1155 int32_t divisor = 1155 HDiv* hdiv = instr->hydrogen();
1156 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 1156 int32_t divisor = hdiv->right()->GetInteger32Constant();
1157 int32_t test_value = 0; 1157 Register result = ToRegister(instr->result());
1158 int32_t power = 0; 1158 ASSERT(!result.is(dividend));
1159 1159
1160 if (divisor > 0) { 1160 // Check for (0 / -x) that will produce negative zero.
1161 test_value = divisor - 1; 1161 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1162 power = WhichPowerOf2(divisor); 1162 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1163 } else { 1163 __ testl(dividend, dividend);
1164 // Check for (0 / -x) that will produce negative zero. 1164 DeoptimizeIf(zero, instr->environment());
1165 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1166 __ testl(dividend, dividend);
1167 DeoptimizeIf(zero, instr->environment());
1168 }
1169 // Check for (kMinInt / -1).
1170 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1171 __ cmpl(dividend, Immediate(kMinInt));
1172 DeoptimizeIf(zero, instr->environment());
1173 }
1174 test_value = - divisor - 1;
1175 power = WhichPowerOf2(-divisor);
1176 } 1165 }
1177 1166 // Check for (kMinInt / -1).
1178 if (test_value != 0) { 1167 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1179 if (instr->hydrogen()->CheckFlag( 1168 hdiv->CheckFlag(HValue::kCanOverflow)) {
1180 HInstruction::kAllUsesTruncatingToInt32)) { 1169 __ cmpl(dividend, Immediate(kMinInt));
1181 Label done, negative; 1170 DeoptimizeIf(zero, instr->environment());
1182 __ cmpl(dividend, Immediate(0));
1183 __ j(less, &negative, Label::kNear);
1184 __ sarl(dividend, Immediate(power));
1185 if (divisor < 0) __ negl(dividend);
1186 __ jmp(&done, Label::kNear);
1187
1188 __ bind(&negative);
1189 __ negl(dividend);
1190 __ sarl(dividend, Immediate(power));
1191 if (divisor > 0) __ negl(dividend);
1192 __ bind(&done);
1193 return; // Don't fall through to "__ neg" below.
1194 } else {
1195 // Deoptimize if remainder is not 0.
1196 __ testl(dividend, Immediate(test_value));
1197 DeoptimizeIf(not_zero, instr->environment());
1198 __ sarl(dividend, Immediate(power));
1199 }
1200 } 1171 }
1201 1172 // Deoptimize if remainder will not be 0.
1202 if (divisor < 0) __ negl(dividend); 1173 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1203 1174 __ testl(dividend, Immediate(Abs(divisor) - 1));
1175 DeoptimizeIf(not_zero, instr->environment());
1176 }
1177 __ Move(result, dividend);
1178 int32_t shift = WhichPowerOf2(Abs(divisor));
1179 if (shift > 0) {
1180 // The arithmetic shift is always OK, the 'if' is an optimization only.
1181 if (shift > 1) __ sarl(result, Immediate(31));
1182 __ shrl(result, Immediate(32 - shift));
1183 __ addl(result, dividend);
1184 __ sarl(result, Immediate(shift));
1185 }
1186 if (divisor < 0) __ negl(result);
1204 return; 1187 return;
1205 } 1188 }
1206 1189
1207 LOperand* right = instr->right(); 1190 LOperand* right = instr->right();
1208 ASSERT(ToRegister(instr->result()).is(rax)); 1191 ASSERT(ToRegister(instr->result()).is(rax));
1209 ASSERT(ToRegister(instr->left()).is(rax)); 1192 ASSERT(ToRegister(instr->left()).is(rax));
1210 ASSERT(!ToRegister(instr->right()).is(rax)); 1193 ASSERT(!ToRegister(instr->right()).is(rax));
1211 ASSERT(!ToRegister(instr->right()).is(rdx)); 1194 ASSERT(!ToRegister(instr->right()).is(rdx));
1212 1195
1213 Register left_reg = rax; 1196 Register left_reg = rax;
(...skipping 4367 matching lines...) Expand 10 before | Expand all | Expand 10 after
5581 FixedArray::kHeaderSize - kPointerSize)); 5564 FixedArray::kHeaderSize - kPointerSize));
5582 __ bind(&done); 5565 __ bind(&done);
5583 } 5566 }
5584 5567
5585 5568
5586 #undef __ 5569 #undef __
5587 5570
5588 } } // namespace v8::internal 5571 } } // namespace v8::internal
5589 5572
5590 #endif // V8_TARGET_ARCH_X64 5573 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698