Reviewers: ulan, Benedikt Meurer,
Description:
ARM: Optimize truncating division and fix sim
Optimize code generated for DivI Lithium instruction when handling division
where the result is int32. Also, fix the ARM simulator to give the correct
answer for kMinInt / -1.
TEST=Division tests added to test-assembler-arm.cc
BUG=
Please review this at https://codereview.chromium.org/102623003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+76, -2 lines):
M src/arm/lithium-codegen-arm.cc
M src/arm/simulator-arm.cc
M test/cctest/test-assembler-arm.cc
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
8f1c9c090dfbdf6e1de38ed34c1f028a2efbe8b0..6bd5ebf23b1e320f818fb3cddd06f85d1fd67a41
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1413,7 +1413,11 @@ void LCodeGen::DoDivI(LDivI* instr) {
}
// Check for (kMinInt / -1).
- if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow) &&
+ (!CpuFeatures::IsSupported(SUDIV) ||
+ !instr->hydrogen()->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ // We don't need to check for overflow when truncating with sdiv
+ // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
Label left_not_min_int;
__ cmp(left, Operand(kMinInt));
__ b(ne, &left_not_min_int);
Index: src/arm/simulator-arm.cc
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index
461d032b99f56171bb41eec2997de9f34fddb7d5..131a1bbdd8e2858dcc7378c6d56bc58bd9f5027d
100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -2733,7 +2733,11 @@ void Simulator::DecodeType3(Instruction* instr) {
int32_t rs_val = get_register(rs);
int32_t ret_val = 0;
ASSERT(rs_val != 0);
- ret_val = rm_val/rs_val;
+ if ((rm_val == kMinInt) && (rs_val == -1)) {
+ ret_val = kMinInt;
+ } else {
+ ret_val = rm_val / rs_val;
+ }
set_register(rn, ret_val);
return;
}
Index: test/cctest/test-assembler-arm.cc
diff --git a/test/cctest/test-assembler-arm.cc
b/test/cctest/test-assembler-arm.cc
index
69ea6f4742601f035472c046cb909906dcbde307..b21dc34dc4afcebb0a9d3293e1ea2f50bbee8b4b
100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -1439,6 +1439,72 @@ TEST(17) {
}
+#define TEST_SDIV(expected_, dividend_, divisor_) \
+ t.dividend = dividend_; \
+ t.divisor = divisor_; \
+ t.result = 0; \
+ dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \
+ CHECK_EQ(expected_, t.result);
+
+
+TEST(18) {
+ // Test the sdiv.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ uint32_t dividend;
+ uint32_t divisor;
+ uint32_t result;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ if (CpuFeatures::IsSupported(SUDIV)) {
+ CpuFeatureScope scope(&assm, SUDIV);
+
+ __ mov(r3, Operand(r0));
+
+ __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
+ __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+
+ __ sdiv(r2, r0, r1);
+ __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+
+ __ bx(lr);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = isolate->heap()->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Code>())->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef DEBUG
+ Code::cast(code)->Print();
+#endif
+ F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
+ Object* dummy;
+ TEST_SDIV(1073741824, kMinInt, -2);
+ TEST_SDIV(kMinInt, kMinInt, -1);
+ TEST_SDIV(5, 10, 2);
+ TEST_SDIV(3, 10, 3);
+ TEST_SDIV(-5, 10, -2);
+ TEST_SDIV(-3, 10, -3);
+ TEST_SDIV(-5, -10, 2);
+ TEST_SDIV(-3, -10, 3);
+ TEST_SDIV(5, -10, -2);
+ TEST_SDIV(3, -10, -3);
+ USE(dummy);
+ }
+}
+
+
+#undef TEST_SDIV
+
+
TEST(code_relative_offset) {
// Test extracting the offset of a label from the beginning of the code
// in a register.
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.