diff options
Diffstat (limited to 'deps/v8/src/crankshaft/s390/lithium-codegen-s390.cc')
-rw-r--r-- | deps/v8/src/crankshaft/s390/lithium-codegen-s390.cc | 226 |
1 files changed, 134 insertions, 92 deletions
diff --git a/deps/v8/src/crankshaft/s390/lithium-codegen-s390.cc b/deps/v8/src/crankshaft/s390/lithium-codegen-s390.cc index c44df9550a..7bbc917bc6 100644 --- a/deps/v8/src/crankshaft/s390/lithium-codegen-s390.cc +++ b/deps/v8/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); } } @@ -1283,8 +1287,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 +1423,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); @@ -1721,35 +1741,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 +1989,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()); @@ -3012,7 +3027,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); } @@ -3258,7 +3273,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 +3406,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 +3538,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) { @@ -4287,12 +4292,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 +4891,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); } } |