| 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);
|
|
|