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

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

Issue 175143002: Consistenly handle power-of-2 divisors in division-like operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 6 years, 9 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/utils.h ('k') | src/x64/lithium-x64.h » ('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 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 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 UNREACHABLE(); 976 UNREACHABLE();
977 } 977 }
978 } 978 }
979 979
980 980
981 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 981 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
982 GenerateOsrPrologue(); 982 GenerateOsrPrologue();
983 } 983 }
984 984
985 985
986 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
987 Register dividend = ToRegister(instr->dividend());
988 int32_t divisor = instr->divisor();
989 ASSERT(dividend.is(ToRegister(instr->result())));
990
991 // Theoretically, a variation of the branch-free code for integer division by
992 // a power of 2 (calculating the remainder via an additional multiplication
993 // (which gets simplified to an 'and') and subtraction) should be faster, and
994 // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to
995 // indicate that positive dividends are heavily favored, so the branching
996 // version performs better.
997 HMod* hmod = instr->hydrogen();
998 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
999 Label dividend_is_not_negative, done;
1000 if (hmod->left()->CanBeNegative()) {
1001 __ testl(dividend, dividend);
1002 __ j(not_sign, &dividend_is_not_negative, Label::kNear);
1003 // Note that this is correct even for kMinInt operands.
1004 __ negl(dividend);
1005 __ andl(dividend, Immediate(mask));
1006 __ negl(dividend);
1007 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1008 DeoptimizeIf(zero, instr->environment());
1009 }
1010 __ jmp(&done, Label::kNear);
1011 }
1012
1013 __ bind(&dividend_is_not_negative);
1014 __ andl(dividend, Immediate(mask));
1015 __ bind(&done);
1016 }
1017
1018
986 void LCodeGen::DoModI(LModI* instr) { 1019 void LCodeGen::DoModI(LModI* instr) {
1020 if (instr->hydrogen()->RightIsPowerOf2()) {
1021 return DoModByPowerOf2I(reinterpret_cast<LModByPowerOf2I*>(instr));
1022 }
987 HMod* hmod = instr->hydrogen(); 1023 HMod* hmod = instr->hydrogen();
988 HValue* left = hmod->left(); 1024 HValue* left = hmod->left();
989 HValue* right = hmod->right(); 1025 HValue* right = hmod->right();
990 if (hmod->RightIsPowerOf2()) { 1026
991 // TODO(svenpanne) We should really do the strength reduction on the 1027 Register left_reg = ToRegister(instr->left());
992 // Hydrogen level. 1028 ASSERT(left_reg.is(rax));
993 Register left_reg = ToRegister(instr->left()); 1029 Register right_reg = ToRegister(instr->right());
994 ASSERT(left_reg.is(ToRegister(instr->result()))); 1030 ASSERT(!right_reg.is(rax));
995 1031 ASSERT(!right_reg.is(rdx));
996 // Note: The code below even works when right contains kMinInt. 1032 Register result_reg = ToRegister(instr->result());
997 int32_t divisor = Abs(right->GetInteger32Constant()); 1033 ASSERT(result_reg.is(rdx));
998 1034
999 Label left_is_not_negative, done; 1035 Label done;
1000 if (left->CanBeNegative()) { 1036 // Check for x % 0, idiv would signal a divide error. We have to
1001 __ testl(left_reg, left_reg); 1037 // deopt in this case because we can't return a NaN.
1002 __ j(not_sign, &left_is_not_negative, Label::kNear); 1038 if (right->CanBeZero()) {
1003 __ negl(left_reg); 1039 __ testl(right_reg, right_reg);
1004 __ andl(left_reg, Immediate(divisor - 1)); 1040 DeoptimizeIf(zero, instr->environment());
1005 __ negl(left_reg); 1041 }
1006 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1042
1007 DeoptimizeIf(zero, instr->environment()); 1043 // Check for kMinInt % -1, idiv would signal a divide error. We
1008 } 1044 // have to deopt if we care about -0, because we can't return that.
1045 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) {
1046 Label no_overflow_possible;
1047 __ cmpl(left_reg, Immediate(kMinInt));
1048 __ j(not_zero, &no_overflow_possible, Label::kNear);
1049 __ cmpl(right_reg, Immediate(-1));
1050 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1051 DeoptimizeIf(equal, instr->environment());
1052 } else {
1053 __ j(not_equal, &no_overflow_possible, Label::kNear);
1054 __ Set(result_reg, 0);
1009 __ jmp(&done, Label::kNear); 1055 __ jmp(&done, Label::kNear);
1010 } 1056 }
1011 1057 __ bind(&no_overflow_possible);
1012 __ bind(&left_is_not_negative); 1058 }
1013 __ andl(left_reg, Immediate(divisor - 1)); 1059
1014 __ bind(&done); 1060 // Sign extend dividend in eax into edx:eax, since we are using only the low
1015 } else { 1061 // 32 bits of the values.
1016 Register left_reg = ToRegister(instr->left()); 1062 __ cdq();
1017 ASSERT(left_reg.is(rax)); 1063
1018 Register right_reg = ToRegister(instr->right()); 1064 // If we care about -0, test if the dividend is <0 and the result is 0.
1019 ASSERT(!right_reg.is(rax)); 1065 if (left->CanBeNegative() &&
1020 ASSERT(!right_reg.is(rdx)); 1066 hmod->CanBeZero() &&
1021 Register result_reg = ToRegister(instr->result()); 1067 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1022 ASSERT(result_reg.is(rdx)); 1068 Label positive_left;
1023 1069 __ testl(left_reg, left_reg);
1024 Label done; 1070 __ j(not_sign, &positive_left, Label::kNear);
1025 // Check for x % 0, idiv would signal a divide error. We have to 1071 __ idivl(right_reg);
1026 // deopt in this case because we can't return a NaN. 1072 __ testl(result_reg, result_reg);
1027 if (right->CanBeZero()) { 1073 DeoptimizeIf(zero, instr->environment());
1028 __ testl(right_reg, right_reg); 1074 __ jmp(&done, Label::kNear);
1029 DeoptimizeIf(zero, instr->environment()); 1075 __ bind(&positive_left);
1076 }
1077 __ idivl(right_reg);
1078 __ bind(&done);
1079 }
1080
1081
1082 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
1083 Register dividend = ToRegister(instr->dividend());
1084 int32_t divisor = instr->divisor();
1085 ASSERT(dividend.is(ToRegister(instr->result())));
1086
1087 // If the divisor is positive, things are easy: There can be no deopts and we
1088 // can simply do an arithmetic right shift.
1089 if (divisor == 1) return;
1090 int32_t shift = WhichPowerOf2Abs(divisor);
1091 if (divisor > 1) {
1092 __ sarl(dividend, Immediate(shift));
1093 return;
1094 }
1095
1096 // If the divisor is negative, we have to negate and handle edge cases.
1097 Label not_kmin_int, done;
1098 __ negl(dividend);
1099 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1100 DeoptimizeIf(zero, instr->environment());
1101 }
1102 if (instr->hydrogen()->left()->RangeCanInclude(kMinInt)) {
1103 // Note that we could emit branch-free code, but that would need one more
1104 // register.
1105 __ j(no_overflow, &not_kmin_int, Label::kNear);
1106 if (divisor == -1) {
1107 DeoptimizeIf(no_condition, instr->environment());
1108 } else {
1109 __ movl(dividend, Immediate(kMinInt / divisor));
1110 __ jmp(&done, Label::kNear);
1030 } 1111 }
1031 1112 }
1032 // Check for kMinInt % -1, idiv would signal a divide error. We 1113 __ bind(&not_kmin_int);
1033 // have to deopt if we care about -0, because we can't return that. 1114 __ sarl(dividend, Immediate(shift));
1034 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { 1115 __ bind(&done);
1035 Label no_overflow_possible; 1116 }
1036 __ cmpl(left_reg, Immediate(kMinInt)); 1117
1037 __ j(not_zero, &no_overflow_possible, Label::kNear); 1118
1038 __ cmpl(right_reg, Immediate(-1)); 1119 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
1039 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1120 Register dividend = ToRegister(instr->dividend());
1040 DeoptimizeIf(equal, instr->environment()); 1121 int32_t divisor = instr->divisor();
1041 } else { 1122 Register temp = ToRegister(instr->temp());
1042 __ j(not_equal, &no_overflow_possible, Label::kNear); 1123 Register result = ToRegister(instr->result());
1043 __ Set(result_reg, 0); 1124
1044 __ jmp(&done, Label::kNear); 1125 if (divisor == 0) {
1045 }
1046 __ bind(&no_overflow_possible);
1047 }
1048
1049 // Sign extend dividend in eax into edx:eax, since we are using only the low
1050 // 32 bits of the values.
1051 __ cdq();
1052
1053 // If we care about -0, test if the dividend is <0 and the result is 0.
1054 if (left->CanBeNegative() &&
1055 hmod->CanBeZero() &&
1056 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1057 Label positive_left;
1058 __ testl(left_reg, left_reg);
1059 __ j(not_sign, &positive_left, Label::kNear);
1060 __ idivl(right_reg);
1061 __ testl(result_reg, result_reg);
1062 DeoptimizeIf(zero, instr->environment());
1063 __ jmp(&done, Label::kNear);
1064 __ bind(&positive_left);
1065 }
1066 __ idivl(right_reg);
1067 __ bind(&done);
1068 }
1069 }
1070
1071
1072 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
1073 ASSERT(instr->right()->IsConstantOperand());
1074
1075 const Register dividend = ToRegister(instr->left());
1076 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
1077 const Register result = ToRegister(instr->result());
1078
1079 switch (divisor) {
1080 case 0:
1081 DeoptimizeIf(no_condition, instr->environment()); 1126 DeoptimizeIf(no_condition, instr->environment());
1082 return; 1127 return;
1083 1128 }
1084 case 1: 1129
1085 if (!result.is(dividend)) { 1130 // Find b which: 2^b < divisor_abs < 2^(b+1).
1086 __ movl(result, dividend);
1087 }
1088 return;
1089
1090 case -1:
1091 if (!result.is(dividend)) {
1092 __ movl(result, dividend);
1093 }
1094 __ negl(result);
1095 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1096 DeoptimizeIf(zero, instr->environment());
1097 }
1098 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1099 DeoptimizeIf(overflow, instr->environment());
1100 }
1101 return;
1102 }
1103
1104 uint32_t divisor_abs = abs(divisor); 1131 uint32_t divisor_abs = abs(divisor);
1105 if (IsPowerOf2(divisor_abs)) { 1132 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1106 int32_t power = WhichPowerOf2(divisor_abs); 1133 unsigned shift = 32 + b; // Precision +1bit (effectively).
1107 if (divisor < 0) { 1134 double multiplier_f =
1108 __ movsxlq(result, dividend); 1135 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
1109 __ neg(result); 1136 int64_t multiplier;
1110 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1137 if (multiplier_f - std::floor(multiplier_f) < 0.5) {
1111 DeoptimizeIf(zero, instr->environment()); 1138 multiplier = static_cast<int64_t>(std::floor(multiplier_f));
1112 }
1113 __ sar(result, Immediate(power));
1114 } else {
1115 if (!result.is(dividend)) {
1116 __ movl(result, dividend);
1117 }
1118 __ sarl(result, Immediate(power));
1119 }
1120 } else { 1139 } else {
1121 Register reg1 = ToRegister(instr->temp()); 1140 multiplier = static_cast<int64_t>(std::floor(multiplier_f)) + 1;
1122 Register reg2 = ToRegister(instr->result()); 1141 }
1123 1142 // The multiplier is a uint32.
1124 // Find b which: 2^b < divisor_abs < 2^(b+1). 1143 ASSERT(multiplier > 0 &&
1125 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 1144 multiplier < (static_cast<int64_t>(1) << 32));
1126 unsigned shift = 32 + b; // Precision +1bit (effectively). 1145 // The multiply is int64, so sign-extend to r64.
1127 double multiplier_f = 1146 __ movsxlq(temp, dividend);
1128 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 1147 if (divisor < 0 &&
1129 int64_t multiplier; 1148 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1130 if (multiplier_f - std::floor(multiplier_f) < 0.5) { 1149 __ neg(temp);
1131 multiplier = static_cast<int64_t>(std::floor(multiplier_f)); 1150 DeoptimizeIf(zero, instr->environment());
1132 } else { 1151 }
1133 multiplier = static_cast<int64_t>(std::floor(multiplier_f)) + 1; 1152 __ Set(result, multiplier);
1134 } 1153 // Result just fit in r64, because it's int32 * uint32.
1135 // The multiplier is a uint32. 1154 __ imul(result, temp);
1136 ASSERT(multiplier > 0 && 1155
1137 multiplier < (static_cast<int64_t>(1) << 32)); 1156 __ addq(result, Immediate(1 << 30));
1138 // The multiply is int64, so sign-extend to r64. 1157 __ sar(result, Immediate(shift));
1139 __ movsxlq(reg1, dividend); 1158 }
1140 if (divisor < 0 && 1159
1141 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1160
1142 __ neg(reg1); 1161 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1143 DeoptimizeIf(zero, instr->environment()); 1162 Register dividend = ToRegister(instr->dividend());
1144 } 1163 int32_t divisor = instr->divisor();
1145 __ Set(reg2, multiplier); 1164 Register result = ToRegister(instr->result());
1146 // Result just fit in r64, because it's int32 * uint32. 1165 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
1147 __ imul(reg2, reg1); 1166 ASSERT(!result.is(dividend));
1148 1167
1149 __ addq(reg2, Immediate(1 << 30)); 1168 // Check for (0 / -x) that will produce negative zero.
1150 __ sar(reg2, Immediate(shift)); 1169 HDiv* hdiv = instr->hydrogen();
1151 } 1170 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
1171 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
1172 __ testl(dividend, dividend);
1173 DeoptimizeIf(zero, instr->environment());
1174 }
1175 // Check for (kMinInt / -1).
1176 if (hdiv->CheckFlag(HValue::kCanOverflow) &&
1177 hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
1178 __ cmpl(dividend, Immediate(kMinInt));
1179 DeoptimizeIf(zero, instr->environment());
1180 }
1181 // Deoptimize if remainder will not be 0.
1182 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1183 divisor != 1 && divisor != -1) {
1184 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1185 __ testl(dividend, Immediate(mask));
1186 DeoptimizeIf(not_zero, instr->environment());
1187 }
1188 __ Move(result, dividend);
1189 int32_t shift = WhichPowerOf2Abs(divisor);
1190 if (shift > 0) {
1191 // The arithmetic shift is always OK, the 'if' is an optimization only.
1192 if (shift > 1) __ sarl(result, Immediate(31));
1193 __ shrl(result, Immediate(32 - shift));
1194 __ addl(result, dividend);
1195 __ sarl(result, Immediate(shift));
1196 }
1197 if (divisor < 0) __ negl(result);
1152 } 1198 }
1153 1199
1154 1200
1155 void LCodeGen::DoDivI(LDivI* instr) { 1201 void LCodeGen::DoDivI(LDivI* instr) {
1156 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) { 1202 Register dividend = ToRegister(instr->left());
1157 Register dividend = ToRegister(instr->left()); 1203 Register divisor = ToRegister(instr->right());
1158 HDiv* hdiv = instr->hydrogen(); 1204 Register remainder = ToRegister(instr->temp());
1159 int32_t divisor = hdiv->right()->GetInteger32Constant(); 1205 Register result = ToRegister(instr->result());
1160 Register result = ToRegister(instr->result()); 1206 ASSERT(dividend.is(rax));
1161 ASSERT(!result.is(dividend)); 1207 ASSERT(remainder.is(rdx));
1162 1208 ASSERT(result.is(rax));
1163 // Check for (0 / -x) that will produce negative zero. 1209 ASSERT(!divisor.is(rax));
1164 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 && 1210 ASSERT(!divisor.is(rdx));
1165 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1166 __ testl(dividend, dividend);
1167 DeoptimizeIf(zero, instr->environment());
1168 }
1169 // Check for (kMinInt / -1).
1170 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1171 hdiv->CheckFlag(HValue::kCanOverflow)) {
1172 __ cmpl(dividend, Immediate(kMinInt));
1173 DeoptimizeIf(zero, instr->environment());
1174 }
1175 // Deoptimize if remainder will not be 0.
1176 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1177 __ testl(dividend, Immediate(Abs(divisor) - 1));
1178 DeoptimizeIf(not_zero, instr->environment());
1179 }
1180 __ Move(result, dividend);
1181 int32_t shift = WhichPowerOf2(Abs(divisor));
1182 if (shift > 0) {
1183 // The arithmetic shift is always OK, the 'if' is an optimization only.
1184 if (shift > 1) __ sarl(result, Immediate(31));
1185 __ shrl(result, Immediate(32 - shift));
1186 __ addl(result, dividend);
1187 __ sarl(result, Immediate(shift));
1188 }
1189 if (divisor < 0) __ negl(result);
1190 return;
1191 }
1192
1193 LOperand* right = instr->right();
1194 ASSERT(ToRegister(instr->result()).is(rax));
1195 ASSERT(ToRegister(instr->left()).is(rax));
1196 ASSERT(!ToRegister(instr->right()).is(rax));
1197 ASSERT(!ToRegister(instr->right()).is(rdx));
1198
1199 Register left_reg = rax;
1200 1211
1201 // Check for x / 0. 1212 // Check for x / 0.
1202 Register right_reg = ToRegister(right); 1213 HBinaryOperation* hdiv = instr->hydrogen();
1203 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { 1214 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1204 __ testl(right_reg, right_reg); 1215 __ testl(divisor, divisor);
1205 DeoptimizeIf(zero, instr->environment()); 1216 DeoptimizeIf(zero, instr->environment());
1206 } 1217 }
1207 1218
1208 // Check for (0 / -x) that will produce negative zero. 1219 // Check for (0 / -x) that will produce negative zero.
1209 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1220 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1210 Label left_not_zero; 1221 Label dividend_not_zero;
1211 __ testl(left_reg, left_reg); 1222 __ testl(dividend, dividend);
1212 __ j(not_zero, &left_not_zero, Label::kNear); 1223 __ j(not_zero, &dividend_not_zero, Label::kNear);
1213 __ testl(right_reg, right_reg); 1224 __ testl(divisor, divisor);
1214 DeoptimizeIf(sign, instr->environment()); 1225 DeoptimizeIf(sign, instr->environment());
1215 __ bind(&left_not_zero); 1226 __ bind(&dividend_not_zero);
1216 } 1227 }
1217 1228
1218 // Check for (kMinInt / -1). 1229 // Check for (kMinInt / -1).
1219 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) { 1230 if (hdiv->CheckFlag(HValue::kCanOverflow)) {
1220 Label left_not_min_int; 1231 Label dividend_not_min_int;
1221 __ cmpl(left_reg, Immediate(kMinInt)); 1232 __ cmpl(dividend, Immediate(kMinInt));
1222 __ j(not_zero, &left_not_min_int, Label::kNear); 1233 __ j(not_zero, &dividend_not_min_int, Label::kNear);
1223 __ cmpl(right_reg, Immediate(-1)); 1234 __ cmpl(divisor, Immediate(-1));
1224 DeoptimizeIf(zero, instr->environment()); 1235 DeoptimizeIf(zero, instr->environment());
1225 __ bind(&left_not_min_int); 1236 __ bind(&dividend_not_min_int);
1226 } 1237 }
1227 1238
1228 // Sign extend to rdx. 1239 // Sign extend to rdx (= remainder).
1229 __ cdq(); 1240 __ cdq();
1230 __ idivl(right_reg); 1241 __ idivl(divisor);
1231 1242
1232 if (instr->is_flooring()) { 1243 if (instr->is_flooring()) {
1233 Label done; 1244 Label done;
1234 __ testl(rdx, rdx); 1245 __ testl(remainder, remainder);
1235 __ j(zero, &done, Label::kNear); 1246 __ j(zero, &done, Label::kNear);
1236 __ xorl(rdx, right_reg); 1247 __ xorl(remainder, divisor);
1237 __ sarl(rdx, Immediate(31)); 1248 __ sarl(remainder, Immediate(31));
1238 __ addl(rax, rdx); 1249 __ addl(result, remainder);
1239 __ bind(&done); 1250 __ bind(&done);
1240 } else if (!instr->hydrogen()->CheckFlag( 1251 } else if (!instr->hydrogen()->CheckFlag(
1241 HInstruction::kAllUsesTruncatingToInt32)) { 1252 HInstruction::kAllUsesTruncatingToInt32)) {
1242 // Deoptimize if remainder is not 0. 1253 // Deoptimize if remainder is not 0.
1243 __ testl(rdx, rdx); 1254 __ testl(remainder, remainder);
1244 DeoptimizeIf(not_zero, instr->environment()); 1255 DeoptimizeIf(not_zero, instr->environment());
1245 } 1256 }
1246 } 1257 }
1247 1258
1248 1259
1249 void LCodeGen::DoMulI(LMulI* instr) { 1260 void LCodeGen::DoMulI(LMulI* instr) {
1250 Register left = ToRegister(instr->left()); 1261 Register left = ToRegister(instr->left());
1251 LOperand* right = instr->right(); 1262 LOperand* right = instr->right();
1252 1263
1253 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1264 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
(...skipping 4333 matching lines...) Expand 10 before | Expand all | Expand 10 after
5587 FixedArray::kHeaderSize - kPointerSize)); 5598 FixedArray::kHeaderSize - kPointerSize));
5588 __ bind(&done); 5599 __ bind(&done);
5589 } 5600 }
5590 5601
5591 5602
5592 #undef __ 5603 #undef __
5593 5604
5594 } } // namespace v8::internal 5605 } } // namespace v8::internal
5595 5606
5596 #endif // V8_TARGET_ARCH_X64 5607 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/utils.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698