Index: src/compiler/s390/code-generator-s390.cc |
diff --git a/src/compiler/s390/code-generator-s390.cc b/src/compiler/s390/code-generator-s390.cc |
index c5b8527b4cc16b2b203848a5f28bacbcf786153c..7669d2953db3e95ebb654c2c33e4cf3193027fb7 100644 |
--- a/src/compiler/s390/code-generator-s390.cc |
+++ b/src/compiler/s390/code-generator-s390.cc |
@@ -92,7 +92,7 @@ class S390OperandConverter final : public InstructionOperandConverter { |
return SlotToMemOperand(AllocatedOperand::cast(op)->index()); |
} |
- MemOperand SlotToMemOperand(int slot) { |
+ MemOperand SlotToMemOperand(int slot) const { |
FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
} |
@@ -580,6 +580,31 @@ void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
frame_access_state()->SetFrameAccessToSP(); |
} |
+void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3) { |
+ DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); |
+ Label done; |
+ |
+ // Check if current frame is an arguments adaptor frame. |
+ __ LoadP(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ __ CmpSmiLiteral(scratch1, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
+ __ bne(&done); |
+ |
+ // Load arguments count from current arguments adaptor frame (note, it |
+ // does not include receiver). |
+ Register caller_args_count_reg = scratch1; |
+ __ LoadP(caller_args_count_reg, |
+ MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ SmiUntag(caller_args_count_reg); |
+ |
+ ParameterCount callee_args_count(args_reg); |
+ __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, |
+ scratch3); |
+ __ bind(&done); |
+} |
+ |
// Assembles an instruction after register allocation, producing machine code. |
void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
S390OperandConverter i(this, instr); |
@@ -600,9 +625,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
frame_access_state()->ClearSPDelta(); |
break; |
} |
+ case kArchTailCallCodeObjectFromJSFunction: |
case kArchTailCallCodeObject: { |
int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
AssembleDeconstructActivationRecord(stack_param_delta); |
+ if (opcode == kArchTailCallCodeObjectFromJSFunction) { |
+ AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, |
+ i.TempRegister(0), i.TempRegister(1), |
+ i.TempRegister(2)); |
+ } |
if (HasRegisterInput(instr, 0)) { |
__ AddP(ip, i.InputRegister(0), |
Operand(Code::kHeaderSize - kHeapObjectTag)); |
@@ -633,6 +664,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
frame_access_state()->ClearSPDelta(); |
break; |
} |
+ case kArchTailCallJSFunctionFromJSFunction: |
case kArchTailCallJSFunction: { |
Register func = i.InputRegister(0); |
if (FLAG_debug_code) { |
@@ -644,6 +676,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
} |
int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
AssembleDeconstructActivationRecord(stack_param_delta); |
+ if (opcode == kArchTailCallJSFunctionFromJSFunction) { |
+ AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, |
+ i.TempRegister(0), i.TempRegister(1), |
+ i.TempRegister(2)); |
+ } |
__ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
__ Jump(ip); |
frame_access_state()->ClearSPDelta(); |
@@ -806,7 +843,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
ASSEMBLE_BINOP(srlg, srlg); |
break; |
#endif |
- case kS390_ShiftRightAlg32: |
+ case kS390_ShiftRightArith32: |
if (HasRegisterInput(instr, 1)) { |
if (i.OutputRegister().is(i.InputRegister(1))) { |
__ LoadRR(kScratchReg, i.InputRegister(1)); |
@@ -820,10 +857,45 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
} |
break; |
#if V8_TARGET_ARCH_S390X |
- case kS390_ShiftRightAlg64: |
+ case kS390_ShiftRightArith64: |
ASSEMBLE_BINOP(srag, srag); |
break; |
#endif |
+#if !V8_TARGET_ARCH_S390X |
+ case kS390_ShiftLeftPair: |
+ if (instr->InputAt(2)->IsImmediate()) { |
+ __ ShiftLeftPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), |
+ i.InputInt32(2)); |
+ } else { |
+ __ ShiftLeftPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), kScratchReg, |
+ i.InputRegister(2)); |
+ } |
+ break; |
+ case kS390_ShiftRightPair: |
+ if (instr->InputAt(2)->IsImmediate()) { |
+ __ ShiftRightPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), |
+ i.InputInt32(2)); |
+ } else { |
+ __ ShiftRightPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), kScratchReg, |
+ i.InputRegister(2)); |
+ } |
+ break; |
+ case kS390_ShiftRightArithPair: |
+ if (instr->InputAt(2)->IsImmediate()) { |
+ __ ShiftRightArithPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), |
+ i.InputInt32(2)); |
+ } else { |
+ __ ShiftRightArithPair(i.OutputRegister(0), i.OutputRegister(1), |
+ i.InputRegister(0), i.InputRegister(1), |
+ kScratchReg, i.InputRegister(2)); |
+ } |
+ break; |
+#endif |
case kS390_RotRight32: |
if (HasRegisterInput(instr, 1)) { |
__ LoadComplementRR(kScratchReg, i.InputRegister(1)); |
@@ -858,7 +930,14 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ risbg(i.OutputRegister(), i.OutputRegister(), Operand(startBit), |
Operand(endBit), Operand::Zero(), true); |
} else { |
- UNIMPLEMENTED(); |
+ int shiftAmount = i.InputInt32(1); |
+ int clearBitLeft = 63 - i.InputInt32(2); |
+ int clearBitRight = i.InputInt32(3); |
+ __ rll(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount)); |
+ __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBitLeft)); |
+ __ srlg(i.OutputRegister(), i.OutputRegister(), |
+ Operand((clearBitLeft + clearBitRight))); |
+ __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBitRight)); |
} |
break; |
#if V8_TARGET_ARCH_S390X |
@@ -873,7 +952,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ risbg(i.OutputRegister(), i.InputRegister(0), Operand(startBit), |
Operand(endBit), Operand(shiftAmount), true); |
} else { |
- UNIMPLEMENTED(); |
+ int shiftAmount = i.InputInt32(1); |
+ int clearBit = 63 - i.InputInt32(2); |
+ __ rllg(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount)); |
+ __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
+ __ srlg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
} |
break; |
case kS390_RotLeftAndClearRight64: |
@@ -884,7 +967,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ risbg(i.OutputRegister(), i.InputRegister(0), Operand(startBit), |
Operand(endBit), Operand(shiftAmount), true); |
} else { |
- UNIMPLEMENTED(); |
+ int shiftAmount = i.InputInt32(1); |
+ int clearBit = i.InputInt32(2); |
+ __ rllg(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount)); |
+ __ srlg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
+ __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
} |
break; |
#endif |
@@ -1652,17 +1739,21 @@ void CodeGenerator::AssembleDeoptimizerCall( |
void CodeGenerator::AssemblePrologue() { |
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
- if (descriptor->IsCFunctionCall()) { |
- __ Push(r14, fp); |
- __ LoadRR(fp, sp); |
- } else if (descriptor->IsJSFunctionCall()) { |
- __ Prologue(this->info()->GeneratePreagedPrologue(), ip); |
- } else if (frame()->needs_frame()) { |
- if (!ABI_CALL_VIA_IP && info()->output_code_kind() == Code::WASM_FUNCTION) { |
- // TODO(mbrandy): Restrict only to the wasm wrapper case. |
- __ StubPrologue(); |
+ if (frame()->needs_frame()) { |
+ if (descriptor->IsCFunctionCall()) { |
+ __ Push(r14, fp); |
+ __ LoadRR(fp, sp); |
+ } else if (descriptor->IsJSFunctionCall()) { |
+ __ Prologue(this->info()->GeneratePreagedPrologue(), ip); |
} else { |
- __ StubPrologue(ip); |
+ StackFrame::Type type = info()->GetOutputStackFrameType(); |
+ if (!ABI_CALL_VIA_IP && |
+ info()->output_code_kind() == Code::WASM_FUNCTION) { |
+ // TODO(mbrandy): Restrict only to the wasm wrapper case. |
+ __ StubPrologue(type); |
+ } else { |
+ __ StubPrologue(type, ip); |
+ } |
} |
} else { |
frame()->SetElidedFrameSizeInSlots(0); |