1175 void compileArithMod()
1176 {
1177 switch (m_node->binaryUseKind()) {
1178 case Int32Use: {
1179 LValue numerator = lowInt32(m_node->child1());
1180 LValue denominator = lowInt32(m_node->child2());
1181
1182 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
1183 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
1184 LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithMod done"));
1185
1186 Vector<ValueFromBlock, 3> results;
1187
1188 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1189
1190 m_out.branch(m_out.above(adjustedDenominator, m_out.int32One), continuation, unsafeDenominator);
1191
1192 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1193
1194 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1195
1196 // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
1197 // separate case for that. But it probably doesn't matter so much.
1198 if (shouldCheckOverflow(m_node->arithMode())) {
1199 LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
1200 speculate(Overflow, noValue(), 0, cond);
1201 m_out.jump(continuation);
1202 } else {
1203 // This is the case where we convert the result to an int after we're done. So,
1204 // if the denominator is zero, then the result should be result should be zero.
1205 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
1206 // check above) and the numerator is -2^31 then the result should be -2^31.
1207
1208 LBasicBlock modByZero = FTL_NEW_BLOCK(m_out, ("ArithMod modulo by zero"));
1209 LBasicBlock notModByZero = FTL_NEW_BLOCK(m_out, ("ArithMod not modulo by zero"));
1210 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithMod -2^31/-1"));
1211
1212 m_out.branch(m_out.isZero32(denominator), modByZero, notModByZero);
1213
1214 m_out.appendTo(modByZero, notModByZero);
1215 results.append(m_out.anchor(m_out.int32Zero));
1216 m_out.jump(done);
1217
1218 m_out.appendTo(notModByZero, neg2ToThe31ByNeg1);
1219 m_out.branch(m_out.equal(numerator, neg2ToThe31), neg2ToThe31ByNeg1, continuation);
1220
1221 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
1222 results.append(m_out.anchor(m_out.int32Zero));
1223 m_out.jump(done);
1224 }
1225
1226 m_out.appendTo(continuation, done);
1227
1228 LValue remainder = m_out.rem(numerator, denominator);
1229
1230 if (shouldCheckNegativeZero(m_node->arithMode())) {
1231 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
1232 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
1233
1234 m_out.branch(
1235 m_out.lessThan(numerator, m_out.int32Zero),
1236 negativeNumerator, numeratorContinuation);
1237
1238 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1239
1240 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1241
1242 m_out.jump(numeratorContinuation);
1243
1244 m_out.appendTo(numeratorContinuation, innerLastNext);
1245 }
1246
1247 results.append(m_out.anchor(remainder));
1248 m_out.jump(done);
1249
1250 m_out.appendTo(done, lastNext);
1251
1252 setInt32(m_out.phi(m_out.int32, results));
1253 break;
1254 }
1255
1256 case NumberUse: {
1257 setDouble(
1258 m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1259 break;
1260 }
1261
1262 default:
1263 RELEASE_ASSERT_NOT_REACHED();
1264 break;
1265 }
1266 }
1267