Commit 2b8f5545 authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC/s390: [builtins] Introduce a proper BUILTIN frame type.

Port f47b9e98

Original commit message:

    This adds a new BUILTIN frame type, which supports variable number of
    arguments for builtins implemented in hand-written native code (we will
    extend this mechanism to TurboFan builtins at some point). Convert the
    Math.max and Math.min builtins to construct a BUILTIN frame if required.

    This does not yet work for C++ builtins, but that'll be the next step.

R=jgruber@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com

BUG=v8:4815
LOG=N

Review-Url: https://codereview.chromium.org/2087433003
Cr-Commit-Position: refs/heads/master@{#37157}
parent d8147eb9
...@@ -38,6 +38,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { ...@@ -38,6 +38,7 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
// Insert extra arguments. // Insert extra arguments.
const int num_extra_args = 2; const int num_extra_args = 2;
__ Push(r4, r6); __ Push(r4, r6);
// JumpToExternalReference expects r3 to contain the number of arguments // JumpToExternalReference expects r3 to contain the number of arguments
// including the receiver and the extra arguments. // including the receiver and the extra arguments.
__ addi(r3, r3, Operand(num_extra_args + 1)); __ addi(r3, r3, Operand(num_extra_args + 1));
...@@ -122,6 +123,8 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { ...@@ -122,6 +123,8 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r3 : number of arguments // -- r3 : number of arguments
// -- r4 : function
// -- cp : context
// -- lr : return address // -- lr : return address
// -- sp[(argc - n) * 8] : arg[n] (zero-based) // -- sp[(argc - n) * 8] : arg[n] (zero-based)
// -- sp[(argc + 1) * 8] : receiver // -- sp[(argc + 1) * 8] : receiver
...@@ -133,57 +136,69 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { ...@@ -133,57 +136,69 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1; DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1;
// Load the accumulator with the default return value (either -Infinity or // Load the accumulator with the default return value (either -Infinity or
// +Infinity), with the tagged value in r4 and the double value in d1. // +Infinity), with the tagged value in r8 and the double value in d1.
__ LoadRoot(r4, root_index); __ LoadRoot(r8, root_index);
__ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset)); __ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
// Setup state for loop // Setup state for loop
// r5: address of arg[0] + kPointerSize // r5: address of arg[0] + kPointerSize
// r6: number of slots to drop at exit (arguments + receiver) // r6: number of slots to drop at exit (arguments + receiver)
__ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2)); __ addi(r7, r3, Operand(1));
__ add(r5, sp, r5);
__ addi(r6, r3, Operand(1));
Label done_loop, loop; Label done_loop, loop;
__ bind(&loop); __ bind(&loop);
{ {
// Check if all parameters done. // Check if all parameters done.
__ cmpl(r5, sp); __ subi(r3, r3, Operand(1));
__ ble(&done_loop); __ cmpi(r3, Operand::Zero());
__ blt(&done_loop);
// Load the next parameter tagged value into r3. // Load the next parameter tagged value into r5.
__ LoadPU(r3, MemOperand(r5, -kPointerSize)); __ ShiftLeftImm(r5, r3, Operand(kPointerSizeLog2));
__ LoadPX(r5, MemOperand(sp, r5));
// Load the double value of the parameter into d2, maybe converting the // Load the double value of the parameter into d2, maybe converting the
// parameter to a number first using the ToNumber builtin if necessary. // parameter to a number first using the ToNumber builtin if necessary.
Label convert, convert_smi, convert_number, done_convert; Label convert, convert_smi, convert_number, done_convert;
__ bind(&convert); __ bind(&convert);
__ JumpIfSmi(r3, &convert_smi); __ JumpIfSmi(r5, &convert_smi);
__ LoadP(r7, FieldMemOperand(r3, HeapObject::kMapOffset)); __ LoadP(r6, FieldMemOperand(r5, HeapObject::kMapOffset));
__ JumpIfRoot(r7, Heap::kHeapNumberMapRootIndex, &convert_number); __ JumpIfRoot(r6, Heap::kHeapNumberMapRootIndex, &convert_number);
{ {
// Parameter is not a Number, use the ToNumber builtin to convert it. // Parameter is not a Number, use the ToNumber builtin to convert it.
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::MANUAL);
__ SmiTag(r6); __ PushStandardFrame(r4);
__ Push(r4, r5, r6); __ SmiTag(r3);
__ SmiTag(r7);
__ Push(r3, r7, r8);
__ mr(r3, r5);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Pop(r4, r5, r6); __ mr(r5, r3);
__ SmiUntag(r6); __ Pop(r3, r7, r8);
{ {
// Restore the double accumulator value (d1). // Restore the double accumulator value (d1).
Label done_restore; Label done_restore;
__ SmiToDouble(d1, r4); __ SmiToDouble(d1, r8);
__ JumpIfSmi(r4, &done_restore); __ JumpIfSmi(r8, &done_restore);
__ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset)); __ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
__ bind(&done_restore); __ bind(&done_restore);
} }
__ SmiUntag(r7);
__ SmiUntag(r3);
// TODO(Jaideep): Add macro furtion for PopStandardFrame
if (FLAG_enable_embedded_constant_pool) {
__ Pop(r0, fp, kConstantPoolRegister, cp, r4);
} else {
__ Pop(r0, fp, cp, r4);
}
__ mtlr(r0);
} }
__ b(&convert); __ b(&convert);
__ bind(&convert_number); __ bind(&convert_number);
__ lfd(d2, FieldMemOperand(r3, HeapNumber::kValueOffset)); __ lfd(d2, FieldMemOperand(r5, HeapNumber::kValueOffset));
__ b(&done_convert); __ b(&done_convert);
__ bind(&convert_smi); __ bind(&convert_smi);
__ SmiToDouble(d2, r3); __ SmiToDouble(d2, r5);
__ bind(&done_convert); __ bind(&done_convert);
// Perform the actual comparison with the accumulator value on the left hand // Perform the actual comparison with the accumulator value on the left hand
...@@ -195,26 +210,26 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { ...@@ -195,26 +210,26 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ b(CommuteCondition(cond_done), &compare_swap); __ b(CommuteCondition(cond_done), &compare_swap);
// Left and right hand side are equal, check for -0 vs. +0. // Left and right hand side are equal, check for -0 vs. +0.
__ TestDoubleIsMinusZero(reg, r7, r8); __ TestDoubleIsMinusZero(reg, r9, r0);
__ bne(&loop); __ bne(&loop);
// Update accumulator. Result is on the right hand side. // Update accumulator. Result is on the right hand side.
__ bind(&compare_swap); __ bind(&compare_swap);
__ fmr(d1, d2); __ fmr(d1, d2);
__ mr(r4, r3); __ mr(r8, r5);
__ b(&loop); __ b(&loop);
// At least one side is NaN, which means that the result will be NaN too. // At least one side is NaN, which means that the result will be NaN too.
// We still need to visit the rest of the arguments. // We still need to visit the rest of the arguments.
__ bind(&compare_nan); __ bind(&compare_nan);
__ LoadRoot(r4, Heap::kNanValueRootIndex); __ LoadRoot(r8, Heap::kNanValueRootIndex);
__ lfd(d1, FieldMemOperand(r4, HeapNumber::kValueOffset)); __ lfd(d1, FieldMemOperand(r8, HeapNumber::kValueOffset));
__ b(&loop); __ b(&loop);
} }
__ bind(&done_loop); __ bind(&done_loop);
__ mr(r3, r4); __ mr(r3, r8);
__ Drop(r6); __ Drop(r7);
__ Ret(); __ Ret();
} }
......
...@@ -115,6 +115,8 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) { ...@@ -115,6 +115,8 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r2 : number of arguments // -- r2 : number of arguments
// -- r3 : function
// -- cp : context
// -- lr : return address // -- lr : return address
// -- sp[(argc - n) * 8] : arg[n] (zero-based) // -- sp[(argc - n) * 8] : arg[n] (zero-based)
// -- sp[(argc + 1) * 8] : receiver // -- sp[(argc + 1) * 8] : receiver
...@@ -126,58 +128,64 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { ...@@ -126,58 +128,64 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1; DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1;
// Load the accumulator with the default return value (either -Infinity or // Load the accumulator with the default return value (either -Infinity or
// +Infinity), with the tagged value in r3 and the double value in d1. // +Infinity), with the tagged value in r7 and the double value in d1.
__ LoadRoot(r3, root_index); __ LoadRoot(r7, root_index);
__ LoadDouble(d1, FieldMemOperand(r3, HeapNumber::kValueOffset)); __ LoadDouble(d1, FieldMemOperand(r7, HeapNumber::kValueOffset));
// Setup state for loop // Setup state for loop
// r4: address of arg[0] + kPointerSize // r4: address of arg[0] + kPointerSize
// r5: number of slots to drop at exit (arguments + receiver) // r5: number of slots to drop at exit (arguments + receiver)
__ ShiftLeftP(r4, r2, Operand(kPointerSizeLog2)); __ AddP(r6, r2, Operand(1));
__ AddP(r4, sp, r4);
__ AddP(r5, r2, Operand(1));
Label done_loop, loop; Label done_loop, loop;
__ bind(&loop); __ bind(&loop);
{ {
// Check if all parameters done. // Check if all parameters done.
__ CmpLogicalP(r4, sp); __ SubP(r2, Operand(1));
__ ble(&done_loop); __ blt(&done_loop);
// Load the next parameter tagged value into r2. // Load the next parameter tagged value into r2.
__ lay(r4, MemOperand(r4, -kPointerSize)); __ ShiftLeftP(r1, r2, Operand(kPointerSizeLog2));
__ LoadP(r2, MemOperand(r4)); __ LoadP(r4, MemOperand(sp, r1));
// Load the double value of the parameter into d2, maybe converting the // Load the double value of the parameter into d2, maybe converting the
// parameter to a number first using the ToNumber builtin if necessary. // parameter to a number first using the ToNumber builtin if necessary.
Label convert, convert_smi, convert_number, done_convert; Label convert, convert_smi, convert_number, done_convert;
__ bind(&convert); __ bind(&convert);
__ JumpIfSmi(r2, &convert_smi); __ JumpIfSmi(r4, &convert_smi);
__ LoadP(r6, FieldMemOperand(r2, HeapObject::kMapOffset)); __ LoadP(r5, FieldMemOperand(r4, HeapObject::kMapOffset));
__ JumpIfRoot(r6, Heap::kHeapNumberMapRootIndex, &convert_number); __ JumpIfRoot(r5, Heap::kHeapNumberMapRootIndex, &convert_number);
{ {
// Parameter is not a Number, use the ToNumber builtin to convert it. // Parameter is not a Number, use the ToNumber builtin to convert it.
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); DCHECK(!FLAG_enable_embedded_constant_pool);
__ SmiTag(r5); FrameScope scope(masm, StackFrame::MANUAL);
__ Push(r3, r4, r5); __ Push(r14, fp, cp, r3);
__ la(fp, MemOperand(sp, 2 * kPointerSize));
__ SmiTag(r2);
__ SmiTag(r6);
__ Push(r2, r6, r7);
__ LoadRR(r2, r4);
__ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
__ Pop(r3, r4, r5); __ LoadRR(r4, r2);
__ SmiUntag(r5); __ Pop(r2, r6, r7);
{ {
// Restore the double accumulator value (d1). // Restore the double accumulator value (d1).
Label done_restore; Label done_restore;
__ SmiToDouble(d1, r3); __ SmiToDouble(d1, r7);
__ JumpIfSmi(r3, &done_restore); __ JumpIfSmi(r7, &done_restore);
__ LoadDouble(d1, FieldMemOperand(r3, HeapNumber::kValueOffset)); __ LoadDouble(d1, FieldMemOperand(r7, HeapNumber::kValueOffset));
__ bind(&done_restore); __ bind(&done_restore);
} }
__ SmiUntag(r6);
__ SmiUntag(r2);
__ Pop(r14, fp, cp, r3);
} }
__ b(&convert); __ b(&convert);
__ bind(&convert_number); __ bind(&convert_number);
__ LoadDouble(d2, FieldMemOperand(r2, HeapNumber::kValueOffset)); __ LoadDouble(d2, FieldMemOperand(r4, HeapNumber::kValueOffset));
__ b(&done_convert); __ b(&done_convert);
__ bind(&convert_smi); __ bind(&convert_smi);
__ SmiToDouble(d2, r2); __ SmiToDouble(d2, r4);
__ bind(&done_convert); __ bind(&done_convert);
// Perform the actual comparison with the accumulator value on the left hand // Perform the actual comparison with the accumulator value on the left hand
...@@ -189,26 +197,26 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { ...@@ -189,26 +197,26 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ b(CommuteCondition(cond_done), &compare_swap); __ b(CommuteCondition(cond_done), &compare_swap);
// Left and right hand side are equal, check for -0 vs. +0. // Left and right hand side are equal, check for -0 vs. +0.
__ TestDoubleIsMinusZero(reg, r6, r7); __ TestDoubleIsMinusZero(reg, r1, r0);
__ bne(&loop); __ bne(&loop);
// Update accumulator. Result is on the right hand side. // Update accumulator. Result is on the right hand side.
__ bind(&compare_swap); __ bind(&compare_swap);
__ ldr(d1, d2); __ ldr(d1, d2);
__ LoadRR(r3, r2); __ LoadRR(r7, r4);
__ b(&loop); __ b(&loop);
// At least one side is NaN, which means that the result will be NaN too. // At least one side is NaN, which means that the result will be NaN too.
// We still need to visit the rest of the arguments. // We still need to visit the rest of the arguments.
__ bind(&compare_nan); __ bind(&compare_nan);
__ LoadRoot(r3, Heap::kNanValueRootIndex); __ LoadRoot(r7, Heap::kNanValueRootIndex);
__ LoadDouble(d1, FieldMemOperand(r3, HeapNumber::kValueOffset)); __ LoadDouble(d1, FieldMemOperand(r7, HeapNumber::kValueOffset));
__ b(&loop); __ b(&loop);
} }
__ bind(&done_loop); __ bind(&done_loop);
__ LoadRR(r2, r3); __ LoadRR(r2, r7);
__ Drop(r5); __ Drop(r6);
__ Ret(); __ Ret();
} }
......
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