Commit 3caf0f20 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[arm] Fix off-by-1 issue with stack returns

On 32-bit platforms, float64 stack returns take 2 stack slots. In the
implemention of the kArmPeek instruction we assume that provided slot
index points to the first stack slot. However, due to an off-by-1 issue
the provided slot index pointed to the second stack slot. This CL fixes
the problem and generalizes an existing test which reproduces it.

R=v8-arm-ports@googlegroups.com

Change-Id: Ibb2fd8275cf912da064e2f863c2d64d2526caaac
Reviewed-on: https://chromium-review.googlesource.com/839761Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50291}
parent a7c85f33
...@@ -1578,17 +1578,22 @@ void InstructionSelector::EmitPrepareResults(ZoneVector<PushParameter>* results, ...@@ -1578,17 +1578,22 @@ void InstructionSelector::EmitPrepareResults(ZoneVector<PushParameter>* results,
int reverse_slot = 0; int reverse_slot = 0;
for (PushParameter output : *results) { for (PushParameter output : *results) {
if (!output.location.IsCallerFrameSlot()) continue; if (!output.location.IsCallerFrameSlot()) continue;
reverse_slot += output.location.GetSizeInPointers(); ++reverse_slot;
// Skip any alignment holes in nodes. // Skip any alignment holes in nodes.
if (output.node == nullptr) continue; if (output.node != nullptr) {
DCHECK(!descriptor->IsCFunctionCall()); DCHECK(!descriptor->IsCFunctionCall());
if (output.location.GetType() == MachineType::Float32()) { if (output.location.GetType() == MachineType::Float32()) {
MarkAsFloat32(output.node); MarkAsFloat32(output.node);
} else if (output.location.GetType() == MachineType::Float64()) { } else if (output.location.GetType() == MachineType::Float64()) {
MarkAsFloat64(output.node); MarkAsFloat64(output.node);
}
InstructionOperand result = g.DefineAsRegister(output.node);
Emit(kArmPeek | MiscField::encode(reverse_slot), result);
}
if (output.location.GetType() == MachineType::Float64()) {
// Float64 require an implicit second slot.
++reverse_slot;
} }
InstructionOperand result = g.DefineAsRegister(output.node);
Emit(kArmPeek | MiscField::encode(reverse_slot), result);
} }
} }
......
...@@ -477,14 +477,13 @@ TEST(ReturnMultipleRandom) { ...@@ -477,14 +477,13 @@ TEST(ReturnMultipleRandom) {
} }
} }
TEST(ReturnLastValue) { void ReturnLastValue(MachineType type) {
v8::internal::AccountingAllocator allocator; v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME); Zone zone(&allocator, ZONE_NAME);
// Let 2 returns be on the stack. // Let 2 returns be on the stack.
const int return_count = num_registers(MachineType::Int32()) + 2; const int return_count = num_registers(type) + 2;
CallDescriptor* desc = CallDescriptor* desc = CreateMonoCallDescriptor(&zone, return_count, 0, type);
CreateMonoCallDescriptor(&zone, return_count, 0, MachineType::Int32());
HandleAndZoneScope handles; HandleAndZoneScope handles;
RawMachineAssembler m(handles.main_isolate(), RawMachineAssembler m(handles.main_isolate(),
...@@ -495,7 +494,7 @@ TEST(ReturnLastValue) { ...@@ -495,7 +494,7 @@ TEST(ReturnLastValue) {
std::unique_ptr<Node* []> returns(new Node*[return_count]); std::unique_ptr<Node* []> returns(new Node*[return_count]);
for (int i = 0; i < return_count; ++i) { for (int i = 0; i < return_count; ++i) {
returns[i] = m.Int32Constant(i); returns[i] = Constant(m, type, i);
} }
m.Return(return_count, returns.get()); m.Return(return_count, returns.get());
...@@ -511,10 +510,16 @@ TEST(ReturnLastValue) { ...@@ -511,10 +510,16 @@ TEST(ReturnLastValue) {
Node* call = mt.AddNode(mt.common()->Call(desc), 1, &code_node); Node* call = mt.AddNode(mt.common()->Call(desc), 1, &code_node);
mt.Return(mt.AddNode(mt.common()->Projection(return_count - 1), call)); mt.Return(ToInt32(
mt, type, mt.AddNode(mt.common()->Projection(return_count - 1), call)));
CHECK_EQ(expect, mt.Call()); CHECK_EQ(expect, mt.Call());
} }
TEST(ReturnLastValueInt32) { ReturnLastValue(MachineType::Int32()); }
TEST(ReturnLastValueFloat32) { ReturnLastValue(MachineType::Float32()); }
TEST(ReturnLastValueFloat64) { ReturnLastValue(MachineType::Float64()); }
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment