diff options
Diffstat (limited to 'src/crankshaft/s390/lithium-codegen-s390.cc')
-rw-r--r-- | src/crankshaft/s390/lithium-codegen-s390.cc | 284 |
1 files changed, 165 insertions, 119 deletions
diff --git a/src/crankshaft/s390/lithium-codegen-s390.cc b/src/crankshaft/s390/lithium-codegen-s390.cc index c44df955..02c6b6f7 100644 --- a/src/crankshaft/s390/lithium-codegen-s390.cc +++ b/src/crankshaft/s390/lithium-codegen-s390.cc @@ -6,6 +6,7 @@ #include "src/crankshaft/s390/lithium-codegen-s390.h" #include "src/base/bits.h" +#include "src/builtins/builtins-constructor.h" #include "src/code-factory.h" #include "src/code-stubs.h" #include "src/crankshaft/hydrogen-osr.h" @@ -177,15 +178,18 @@ void LCodeGen::DoPrologue(LPrologue* instr) { __ CallRuntime(Runtime::kNewScriptContext); deopt_mode = Safepoint::kLazyDeopt; } else { - if (slots <= FastNewFunctionContextStub::kMaximumSlots) { - FastNewFunctionContextStub stub(isolate()); + if (slots <= + ConstructorBuiltinsAssembler::MaximumFunctionContextSlots()) { + Callable callable = CodeFactory::FastNewFunctionContext( + isolate(), info()->scope()->scope_type()); __ mov(FastNewFunctionContextDescriptor::SlotsRegister(), Operand(slots)); - __ CallStub(&stub); - // Result of FastNewFunctionContextStub is always in new space. + __ Call(callable.code(), RelocInfo::CODE_TARGET); + // Result of the FastNewFunctionContext builtin is always in new space. need_write_barrier = false; } else { __ push(r3); + __ Push(Smi::FromInt(info()->scope()->scope_type())); __ CallRuntime(Runtime::kNewFunctionContext); } } @@ -271,7 +275,8 @@ bool LCodeGen::GenerateDeferredCode() { DCHECK(!frame_is_built_); DCHECK(info()->IsStub()); frame_is_built_ = true; - __ LoadSmiLiteral(scratch0(), Smi::FromInt(StackFrame::STUB)); + __ Load(scratch0(), + Operand(StackFrame::TypeToMarker(StackFrame::STUB))); __ PushCommonFrame(scratch0()); Comment(";;; Deferred code"); } @@ -340,7 +345,7 @@ bool LCodeGen::GenerateJumpTable() { // have a function pointer to install in the stack frame that we're // building, install a special marker there instead. DCHECK(info()->IsStub()); - __ LoadSmiLiteral(ip, Smi::FromInt(StackFrame::STUB)); + __ Load(ip, Operand(StackFrame::TypeToMarker(StackFrame::STUB))); __ push(ip); DCHECK(info()->IsStub()); } @@ -1283,8 +1288,12 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { __ bge(&done, Label::kNear); // If there is no remainder then we are done. - __ lr(scratch, result); - __ msr(scratch, divisor); + if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) { + __ msrkc(scratch, result, divisor); + } else { + __ lr(scratch, result); + __ msr(scratch, divisor); + } __ Cmp32(dividend, scratch); __ beq(&done, Label::kNear); @@ -1415,36 +1424,48 @@ void LCodeGen::DoMulI(LMulI* instr) { Register right = ToRegister(right_op); if (can_overflow) { -#if V8_TARGET_ARCH_S390X - // result = left * right. - if (instr->hydrogen()->representation().IsSmi()) { - __ SmiUntag(result, left); - __ SmiUntag(scratch, right); - __ msgr(result, scratch); + if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) { + // result = left * right. + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiUntag(scratch, right); + __ MulPWithCondition(result, left, scratch); + } else { + __ msrkc(result, left, right); + __ LoadW(result, result); + } + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } else { - __ LoadRR(result, left); - __ msgr(result, right); - } - __ TestIfInt32(result, r0); - DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); - if (instr->hydrogen()->representation().IsSmi()) { - __ SmiTag(result); - } +#if V8_TARGET_ARCH_S390X + // result = left * right. + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiUntag(result, left); + __ SmiUntag(scratch, right); + __ msgr(result, scratch); + } else { + __ LoadRR(result, left); + __ msgr(result, right); + } + __ TestIfInt32(result, r0); + DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiTag(result); + } #else - // r0:scratch = scratch * right - if (instr->hydrogen()->representation().IsSmi()) { - __ SmiUntag(scratch, left); - __ mr_z(r0, right); - __ LoadRR(result, scratch); - } else { // r0:scratch = scratch * right - __ LoadRR(scratch, left); - __ mr_z(r0, right); - __ LoadRR(result, scratch); - } - __ TestIfInt32(r0, result, scratch); - DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); + if (instr->hydrogen()->representation().IsSmi()) { + __ SmiUntag(scratch, left); + __ mr_z(r0, right); + __ LoadRR(result, scratch); + } else { + // r0:scratch = scratch * right + __ LoadRR(scratch, left); + __ mr_z(r0, right); + __ LoadRR(result, scratch); + } + __ TestIfInt32(r0, result, scratch); + DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); #endif + } } else { if (instr->hydrogen()->representation().IsSmi()) { __ SmiUntag(result, left); @@ -1678,10 +1699,17 @@ void LCodeGen::DoSubI(LSubI* instr) { #endif if (right->IsConstantOperand()) { - if (!isInteger || !checkOverflow) + if (!isInteger || !checkOverflow) { __ SubP(ToRegister(result), ToRegister(left), ToOperand(right)); - else - __ Sub32(ToRegister(result), ToRegister(left), ToOperand(right)); + } else { + // -(MinInt) will overflow + if (ToInteger32(LConstantOperand::cast(right)) == kMinInt) { + __ Load(scratch0(), ToOperand(right)); + __ Sub32(ToRegister(result), ToRegister(left), scratch0()); + } else { + __ Sub32(ToRegister(result), ToRegister(left), ToOperand(right)); + } + } } else if (right->IsRegister()) { if (!isInteger) __ SubP(ToRegister(result), ToRegister(left), ToRegister(right)); @@ -1721,35 +1749,12 @@ void LCodeGen::DoSubI(LSubI* instr) { } } -void LCodeGen::DoRSubI(LRSubI* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); - LOperand* result = instr->result(); - - DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow) && - right->IsConstantOperand()); - -#if V8_TARGET_ARCH_S390X - // The overflow detection needs to be tested on the lower 32-bits. - // As a result, on 64-bit, we need to force 32-bit arithmetic operations - // to set the CC overflow bit properly. The result is then sign-extended. - bool checkOverflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); -#else - bool checkOverflow = true; -#endif - - Operand right_operand = ToOperand(right); - __ mov(r0, right_operand); - - if (!checkOverflow) { - __ SubP_ExtendSrc(ToRegister(result), r0, ToRegister(left)); - } else { - __ Sub32(ToRegister(result), r0, ToRegister(left)); - } -} - void LCodeGen::DoConstantI(LConstantI* instr) { - __ mov(ToRegister(instr->result()), Operand(instr->value())); + Register dst = ToRegister(instr->result()); + if (instr->value() == 0) + __ XorP(dst, dst); + else + __ Load(dst, Operand(instr->value())); } void LCodeGen::DoConstantS(LConstantS* instr) { @@ -1992,20 +1997,38 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { DoubleRegister left = ToDoubleRegister(instr->left()); DoubleRegister right = ToDoubleRegister(instr->right()); DoubleRegister result = ToDoubleRegister(instr->result()); - // All operations except MOD are computed in-place. - DCHECK(instr->op() == Token::MOD || left.is(result)); switch (instr->op()) { case Token::ADD: - __ adbr(result, right); + if (CpuFeatures::IsSupported(VECTOR_FACILITY)) { + __ vfa(result, left, right); + } else { + DCHECK(result.is(left)); + __ adbr(result, right); + } break; case Token::SUB: - __ sdbr(result, right); + if (CpuFeatures::IsSupported(VECTOR_FACILITY)) { + __ vfs(result, left, right); + } else { + DCHECK(result.is(left)); + __ sdbr(result, right); + } break; case Token::MUL: - __ mdbr(result, right); + if (CpuFeatures::IsSupported(VECTOR_FACILITY)) { + __ vfm(result, left, right); + } else { + DCHECK(result.is(left)); + __ mdbr(result, right); + } break; case Token::DIV: - __ ddbr(result, right); + if (CpuFeatures::IsSupported(VECTOR_FACILITY)) { + __ vfd(result, left, right); + } else { + DCHECK(result.is(left)); + __ ddbr(result, right); + } break; case Token::MOD: { __ PrepareCallCFunction(0, 2, scratch0()); @@ -2187,13 +2210,6 @@ void LCodeGen::DoBranch(LBranch* instr) { __ beq(instr->TrueLabel(chunk_)); } - if (expected & ToBooleanHint::kSimdValue) { - // SIMD value -> true. - Label not_simd; - __ CompareInstanceType(map, ip, SIMD128_VALUE_TYPE); - __ beq(instr->TrueLabel(chunk_)); - } - if (expected & ToBooleanHint::kHeapNumber) { // heap number -> false iff +0, -0, or NaN. Label not_heap_number; @@ -3012,7 +3028,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { // protector cell contains (Smi) Isolate::kProtectorValid. Otherwise // it needs to bail out. __ LoadRoot(result, Heap::kArrayProtectorRootIndex); - __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset)); + __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset)); __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kProtectorValid), r0); DeoptimizeIf(ne, instr, DeoptimizeReason::kHole); } @@ -3080,8 +3096,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { __ LoadP( result, MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset)); - __ LoadSmiLiteral(r0, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - __ CmpP(result, r0); + __ CmpP(result, + Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); // Result is the frame pointer for the frame if not adapted and for the real // frame below the adaptor frame if adapted. @@ -3258,7 +3274,7 @@ void LCodeGen::DoContext(LContext* instr) { void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { DCHECK(ToRegister(instr->context()).is(cp)); - __ Move(scratch0(), instr->hydrogen()->pairs()); + __ Move(scratch0(), instr->hydrogen()->declarations()); __ push(scratch0()); __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags())); __ push(scratch0()); @@ -3391,31 +3407,17 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { void LCodeGen::EmitMathAbs(LMathAbs* instr) { Register input = ToRegister(instr->value()); Register result = ToRegister(instr->result()); - Label done; - __ CmpP(input, Operand::Zero()); - __ Move(result, input); - __ bge(&done, Label::kNear); - __ LoadComplementRR(result, result); + __ LoadPositiveP(result, input); // Deoptimize on overflow. DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow, cr0); - __ bind(&done); } #if V8_TARGET_ARCH_S390X void LCodeGen::EmitInteger32MathAbs(LMathAbs* instr) { Register input = ToRegister(instr->value()); Register result = ToRegister(instr->result()); - Label done; - __ Cmp32(input, Operand::Zero()); - __ Move(result, input); - __ bge(&done, Label::kNear); - - // Deoptimize on overflow. - __ Cmp32(input, Operand(0x80000000)); - DeoptimizeIf(eq, instr, DeoptimizeReason::kOverflow); - - __ LoadComplementRR(result, result); - __ bind(&done); + __ LoadPositive32(result, input); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } #endif @@ -3537,9 +3539,13 @@ void LCodeGen::DoMathFround(LMathFround* instr) { } void LCodeGen::DoMathSqrt(LMathSqrt* instr) { - DoubleRegister input = ToDoubleRegister(instr->value()); DoubleRegister result = ToDoubleRegister(instr->result()); - __ sqdbr(result, input); + LOperand* input = instr->value(); + if (input->IsDoubleRegister()) { + __ Sqrt(result, ToDoubleRegister(instr->value())); + } else { + __ Sqrt(result, ToMemOperand(input)); + } } void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { @@ -3668,7 +3674,8 @@ void LCodeGen::PrepareForTailCall(const ParameterCount& actual, __ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); __ LoadP(scratch3, MemOperand(scratch2, StandardFrameConstants::kContextOffset)); - __ CmpSmiLiteral(scratch3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); + __ CmpP(scratch3, + Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); __ bne(&no_arguments_adaptor); // Drop current frame and load arguments count from arguments adaptor frame. @@ -4287,12 +4294,21 @@ void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { if (Smi::IsValid(int_key)) { __ LoadSmiLiteral(r5, Smi::FromInt(int_key)); } else { - // We should never get here at runtime because there is a smi check on - // the key before this point. - __ stop("expected smi"); + Abort(kArrayIndexConstantValueTooBig); } } else { + Label is_smi; +#if V8_TARGET_ARCH_S390X __ SmiTag(r5, ToRegister(key)); +#else + // Deopt if the key is outside Smi range. The stub expects Smi and would + // bump the elements into dictionary mode (and trigger a deopt) anyways. + __ Add32(r5, ToRegister(key), ToRegister(key)); + __ b(nooverflow, &is_smi); + __ PopSafepointRegisters(); + DeoptimizeIf(al, instr, DeoptimizeReason::kOverflow, cr0); + __ bind(&is_smi); +#endif } GrowArrayElementsStub stub(isolate(), instr->hydrogen()->kind()); @@ -4877,14 +4893,42 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); - __ TestIfSmi(ToRegister(input)); + if (input->IsRegister()) { + __ TestIfSmi(ToRegister(input)); + } else if (input->IsStackSlot()) { + MemOperand value = ToMemOperand(input); +#if !V8_TARGET_LITTLE_ENDIAN +#if V8_TARGET_ARCH_S390X + __ TestIfSmi(MemOperand(value.rb(), value.offset() + 7)); +#else + __ TestIfSmi(MemOperand(value.rb(), value.offset() + 3)); +#endif +#else + __ TestIfSmi(value); +#endif + } DeoptimizeIf(ne, instr, DeoptimizeReason::kNotASmi, cr0); } void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { LOperand* input = instr->value(); - __ TestIfSmi(ToRegister(input)); + if (input->IsRegister()) { + __ TestIfSmi(ToRegister(input)); + } else if (input->IsStackSlot()) { + MemOperand value = ToMemOperand(input); +#if !V8_TARGET_LITTLE_ENDIAN +#if V8_TARGET_ARCH_S390X + __ TestIfSmi(MemOperand(value.rb(), value.offset() + 7)); +#else + __ TestIfSmi(MemOperand(value.rb(), value.offset() + 3)); +#endif +#else + __ TestIfSmi(value); +#endif + } else { + UNIMPLEMENTED(); + } DeoptimizeIf(eq, instr, DeoptimizeReason::kSmi, cr0); } } @@ -4963,6 +5007,13 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { Register temp = ToRegister(instr->temp()); + Label deopt, done; + // If the map is not deprecated the migration attempt does not make sense. + __ LoadP(temp, FieldMemOperand(object, HeapObject::kMapOffset)); + __ LoadlW(temp, FieldMemOperand(temp, Map::kBitField3Offset)); + __ TestBitMask(temp, Map::Deprecated::kMask, r0); + __ beq(&deopt); + { PushSafepointRegistersScope scope(this); __ push(object); @@ -4973,7 +5024,13 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { __ StoreToSafepointRegisterSlot(r2, temp); } __ TestIfSmi(temp); - DeoptimizeIf(eq, instr, DeoptimizeReason::kInstanceMigrationFailed, cr0); + __ bne(&done); + + __ bind(&deopt); + // In case of "al" condition the operand is not used so just pass cr0 there. + DeoptimizeIf(al, instr, DeoptimizeReason::kInstanceMigrationFailed, cr0); + + __ bind(&done); } void LCodeGen::DoCheckMaps(LCheckMaps* instr) { @@ -5322,17 +5379,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, Label* false_label, __ CmpP(r0, Operand::Zero()); final_branch_condition = eq; -// clang-format off -#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ - } else if (String::Equals(type_name, factory->type##_string())) { \ - __ JumpIfSmi(input, false_label); \ - __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); \ - __ CompareRoot(scratch, Heap::k##Type##MapRootIndex); \ - final_branch_condition = eq; - SIMD128_TYPES(SIMD128_TYPE) -#undef SIMD128_TYPE - // clang-format on - } else { __ b(false_label); } |