diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-20 10:33:36 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-22 11:45:12 +0000 |
commit | be59a35641616a4cf23c4a13fa0632624b021c1b (patch) | |
tree | 9da183258bdf9cc413f7562079d25ace6955467f /chromium/v8/src/compiler/arm64 | |
parent | d702e4b6a64574e97fc7df8fe3238cde70242080 (diff) | |
download | qtwebengine-chromium-be59a35641616a4cf23c4a13fa0632624b021c1b.tar.gz |
BASELINE: Update Chromium to 62.0.3202.101
Change-Id: I2d5eca8117600df6d331f6166ab24d943d9814ac
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/v8/src/compiler/arm64')
4 files changed, 104 insertions, 156 deletions
diff --git a/chromium/v8/src/compiler/arm64/code-generator-arm64.cc b/chromium/v8/src/compiler/arm64/code-generator-arm64.cc index b36aab4aa09..53a4f11131d 100644 --- a/chromium/v8/src/compiler/arm64/code-generator-arm64.cc +++ b/chromium/v8/src/compiler/arm64/code-generator-arm64.cc @@ -5,13 +5,13 @@ #include "src/compiler/code-generator.h" #include "src/arm64/assembler-arm64-inl.h" -#include "src/arm64/frames-arm64.h" #include "src/arm64/macro-assembler-arm64-inl.h" #include "src/compilation-info.h" #include "src/compiler/code-generator-impl.h" #include "src/compiler/gap-resolver.h" #include "src/compiler/node-matchers.h" #include "src/compiler/osr.h" +#include "src/frame-constants.h" #include "src/heap/heap-inl.h" namespace v8 { @@ -670,7 +670,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( internal::Assembler::BlockCodeTargetSharingScope scope; if (info()->IsWasm()) scope.Open(tasm()); - EnsureSpaceForLazyDeopt(); if (instr->InputAt(0)->IsImmediate()) { __ Call(i.InputCode(0), RelocInfo::CODE_TARGET); } else { @@ -727,7 +726,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArchCallJSFunction: { - EnsureSpaceForLazyDeopt(); Register func = i.InputRegister(0); if (FLAG_debug_code) { // Check the function's context matches the context argument. @@ -737,7 +735,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ cmp(cp, temp); __ Assert(eq, kWrongFunctionContext); } - __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); + __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeOffset)); + __ Add(x10, x10, Operand(Code::kHeaderSize - kHeapObjectTag)); __ Call(x10); RecordCallPosition(instr); // TODO(titzer): this is ugly. JSSP should be a caller-save register @@ -755,25 +754,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( frame_access_state()->ClearSPDelta(); break; } - case kArchTailCallJSFunctionFromJSFunction: { - Register func = i.InputRegister(0); - if (FLAG_debug_code) { - // Check the function's context matches the context argument. - UseScratchRegisterScope scope(tasm()); - Register temp = scope.AcquireX(); - __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); - __ cmp(cp, temp); - __ Assert(eq, kWrongFunctionContext); - } - AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, - i.TempRegister(0), i.TempRegister(1), - i.TempRegister(2)); - __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); - __ Jump(x10); - frame_access_state()->ClearSPDelta(); - frame_access_state()->SetFrameAccessToDefault(); - break; - } case kArchPrepareCallCFunction: // We don't need kArchPrepareCallCFunction on arm64 as the instruction // selector has already performed a Claim to reserve space on the stack. @@ -783,6 +763,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( // via the stack pointer. UNREACHABLE(); break; + case kArchSaveCallerRegisters: { + // kReturnRegister0 should have been saved before entering the stub. + __ PushCallerSaved(kSaveFPRegs, kReturnRegister0); + break; + } + case kArchRestoreCallerRegisters: { + // Don't overwrite the returned value. + __ PopCallerSaved(kSaveFPRegs, kReturnRegister0); + break; + } case kArchPrepareTailCall: AssemblePrepareTailCall(); break; @@ -808,6 +798,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchLookupSwitch: AssembleArchLookupSwitch(instr); break; + case kArchDebugAbort: + DCHECK(i.InputRegister(0).is(x1)); + if (!frame_access_state()->has_frame()) { + // We don't actually want to generate a pile of code for this, so just + // claim there is a stack frame, without generating one. + FrameScope scope(tasm(), StackFrame::NONE); + __ Call(isolate()->builtins()->builtin_handle(Builtins::kAbortJS), + RelocInfo::CODE_TARGET); + } else { + __ Call(isolate()->builtins()->builtin_handle(Builtins::kAbortJS), + RelocInfo::CODE_TARGET); + } + __ Debug("kArchDebugAbort", 0, BREAK); + break; case kArchDebugBreak: __ Debug("kArchDebugBreak", 0, BREAK); break; @@ -2072,6 +2076,27 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_BINOP_CASE(kArm64S128Or, Orr, 16B); SIMD_BINOP_CASE(kArm64S128Xor, Eor, 16B); SIMD_UNOP_CASE(kArm64S128Not, Mvn, 16B); + case kArm64S128Dup: { + VRegister dst = i.OutputSimd128Register(), + src = i.InputSimd128Register(0); + int lanes = i.InputInt32(1); + int index = i.InputInt32(2); + switch (lanes) { + case 4: + __ Dup(dst.V4S(), src.V4S(), index); + break; + case 8: + __ Dup(dst.V8H(), src.V8H(), index); + break; + case 16: + __ Dup(dst.V16B(), src.V16B(), index); + break; + default: + UNREACHABLE(); + break; + } + break; + } case kArm64S128Select: { VRegister dst = i.OutputSimd128Register().V16B(); DCHECK(dst.is(i.InputSimd128Register(0).V16B())); @@ -2360,24 +2385,6 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { __ EndBlockPools(); } -CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( - int deoptimization_id, SourcePosition pos) { - DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id); - DeoptimizeReason deoptimization_reason = - GetDeoptimizationReason(deoptimization_id); - Deoptimizer::BailoutType bailout_type = - deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT - : Deoptimizer::EAGER; - Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( - __ isolate(), deoptimization_id, bailout_type); - if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; - if (info()->is_source_positions_enabled()) { - __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id); - } - __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); - return kSuccess; -} - void CodeGenerator::FinishFrame(Frame* frame) { frame->AlignFrame(16); CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); @@ -2420,14 +2427,12 @@ void CodeGenerator::AssembleConstructFrame() { // Link the frame if (descriptor->IsJSFunctionCall()) { DCHECK(!descriptor->UseNativeStack()); - __ Prologue(this->info()->GeneratePreagedPrologue()); + __ Prologue(); } else { __ Push(lr, fp); __ Mov(fp, __ StackPointer()); } - if (!info()->GeneratePreagedPrologue()) { - unwinding_info_writer_.MarkFrameConstructed(__ pc_offset()); - } + unwinding_info_writer_.MarkFrameConstructed(__ pc_offset()); // Create OSR entry if applicable if (info()->is_osr()) { @@ -2675,7 +2680,11 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, VRegister src = g.ToDoubleRegister(source); if (destination->IsFPRegister()) { VRegister dst = g.ToDoubleRegister(destination); - __ Fmov(dst, src); + if (destination->IsSimd128Register()) { + __ Mov(dst.Q(), src.Q()); + } else { + __ Mov(dst, src); + } } else { DCHECK(destination->IsFPStackSlot()); MemOperand dst = g.ToMemOperand(destination, tasm()); @@ -2758,18 +2767,24 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, VRegister src = g.ToDoubleRegister(source); if (destination->IsFPRegister()) { VRegister dst = g.ToDoubleRegister(destination); - __ Fmov(temp, src); - __ Fmov(src, dst); - __ Fmov(dst, temp); + if (source->IsSimd128Register()) { + __ Mov(temp.Q(), src.Q()); + __ Mov(src.Q(), dst.Q()); + __ Mov(dst.Q(), temp.Q()); + } else { + __ Mov(temp, src); + __ Mov(src, dst); + __ Mov(dst, temp); + } } else { DCHECK(destination->IsFPStackSlot()); MemOperand dst = g.ToMemOperand(destination, tasm()); if (source->IsSimd128Register()) { - __ Fmov(temp.Q(), src.Q()); + __ Mov(temp.Q(), src.Q()); __ Ldr(src.Q(), dst); __ Str(temp.Q(), dst); } else { - __ Fmov(temp, src); + __ Mov(temp, src); __ Ldr(src, dst); __ Str(temp, dst); } @@ -2787,29 +2802,6 @@ void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { } -void CodeGenerator::EnsureSpaceForLazyDeopt() { - if (!info()->ShouldEnsureSpaceForLazyDeopt()) { - return; - } - - int space_needed = Deoptimizer::patch_size(); - // Ensure that we have enough space after the previous lazy-bailout - // instruction for patching the code here. - intptr_t current_pc = tasm()->pc_offset(); - - if (current_pc < (last_lazy_deopt_pc_ + space_needed)) { - intptr_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; - DCHECK((padding_size % kInstructionSize) == 0); - InstructionAccurateScope instruction_accurate( - tasm(), padding_size / kInstructionSize); - - while (padding_size > 0) { - __ nop(); - padding_size -= kInstructionSize; - } - } -} - #undef __ } // namespace compiler diff --git a/chromium/v8/src/compiler/arm64/instruction-codes-arm64.h b/chromium/v8/src/compiler/arm64/instruction-codes-arm64.h index 65c8729bdb7..6354dfc4db7 100644 --- a/chromium/v8/src/compiler/arm64/instruction-codes-arm64.h +++ b/chromium/v8/src/compiler/arm64/instruction-codes-arm64.h @@ -260,6 +260,7 @@ namespace compiler { V(Arm64I8x16GtU) \ V(Arm64I8x16GeU) \ V(Arm64S128Zero) \ + V(Arm64S128Dup) \ V(Arm64S128And) \ V(Arm64S128Or) \ V(Arm64S128Xor) \ diff --git a/chromium/v8/src/compiler/arm64/instruction-scheduler-arm64.cc b/chromium/v8/src/compiler/arm64/instruction-scheduler-arm64.cc index 994e157e17f..0294c828da1 100644 --- a/chromium/v8/src/compiler/arm64/instruction-scheduler-arm64.cc +++ b/chromium/v8/src/compiler/arm64/instruction-scheduler-arm64.cc @@ -93,7 +93,6 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64Float64Sub: case kArm64Float64Mul: case kArm64Float64Div: - case kArm64Float64Mod: case kArm64Float64Max: case kArm64Float64Min: case kArm64Float64Abs: @@ -236,6 +235,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64I8x16GtU: case kArm64I8x16GeU: case kArm64S128Zero: + case kArm64S128Dup: case kArm64S128And: case kArm64S128Or: case kArm64S128Xor: @@ -294,6 +294,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64Ldr: return kIsLoadOperation; + case kArm64Float64Mod: // This opcode will call a C Function which can + // alter CSP. TODO(arm64): Remove once JSSP is gone. case kArm64ClaimCSP: case kArm64ClaimJSSP: case kArm64PokeCSP: diff --git a/chromium/v8/src/compiler/arm64/instruction-selector-arm64.cc b/chromium/v8/src/compiler/arm64/instruction-selector-arm64.cc index f0e306a43c8..8b4e81cf5fd 100644 --- a/chromium/v8/src/compiler/arm64/instruction-selector-arm64.cc +++ b/chromium/v8/src/compiler/arm64/instruction-selector-arm64.cc @@ -549,6 +549,11 @@ void InstructionSelector::VisitStackSlot(Node* node) { sequence()->AddImmediate(Constant(slot)), 0, nullptr); } +void InstructionSelector::VisitDebugAbort(Node* node) { + Arm64OperandGenerator g(this); + Emit(kArchDebugAbort, g.NoOutput(), g.UseFixed(node->InputAt(0), x1)); +} + void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode, ImmediateMode immediate_mode, MachineRepresentation rep, Node* output = nullptr) { @@ -3031,43 +3036,10 @@ void InstructionSelector::VisitS128Select(Node* node) { g.UseRegister(node->InputAt(2))); } -// Tries to match 8x16 byte shuffle to equivalent 32x4 word shuffle. If -// successful, writes the 32x4 shuffle indices. -bool TryMatch32x4Shuffle(const uint8_t* shuffle, uint8_t* shuffle32x4) { - for (int i = 0; i < 4; i++) { - if (shuffle[i * 4] % 4 != 0) return false; - for (int j = 1; j < 4; j++) { - if (shuffle[i * 4 + j] - shuffle[i * 4 + j - 1] != 1) return false; - } - shuffle32x4[i] = shuffle[i * 4] / 4; - } - return true; -} - -// Tries to match byte shuffle to concatenate (vext) operation. If successful, -// writes the vext immediate value. -bool TryMatchConcat(const uint8_t* shuffle, uint8_t mask, uint8_t* vext) { - uint8_t start = shuffle[0]; - int i = 1; - for (; i < 16 - start; i++) { - if ((shuffle[i] & mask) != ((shuffle[i - 1] + 1) & mask)) return false; - } - uint8_t wrap = 16; - for (; i < 16; i++, wrap++) { - if ((shuffle[i] & mask) != (wrap & mask)) return false; - } - *vext = start; - return true; -} - namespace { -static const int kShuffleLanes = 16; -static const int kMaxLaneIndex = 15; -static const int kMaxShuffleIndex = 31; - struct ShuffleEntry { - uint8_t shuffle[kShuffleLanes]; + uint8_t shuffle[kSimd128Size]; ArchOpcode opcode; }; @@ -3126,12 +3098,12 @@ bool TryMatchArchShuffle(const uint8_t* shuffle, const ShuffleEntry* table, for (size_t i = 0; i < num_entries; i++) { const ShuffleEntry& entry = table[i]; int j = 0; - for (; j < kShuffleLanes; j++) { + for (; j < kSimd128Size; j++) { if ((entry.shuffle[j] & mask) != (shuffle[j] & mask)) { break; } } - if (j == kShuffleLanes) { + if (j == kSimd128Size) { *opcode = entry.opcode; return true; } @@ -3139,47 +3111,6 @@ bool TryMatchArchShuffle(const uint8_t* shuffle, const ShuffleEntry* table, return false; } -// Canonicalize shuffles to make pattern matching simpler. Returns a mask that -// will ignore the high bit of indices in some cases. -uint8_t CanonicalizeShuffle(InstructionSelector* selector, Node* node) { - const uint8_t* shuffle = OpParameter<uint8_t*>(node); - uint8_t mask = kMaxShuffleIndex; - // If shuffle is unary, set 'mask' to ignore the high bit of the indices. - // Replace any unused source with the other. - if (selector->GetVirtualRegister(node->InputAt(0)) == - selector->GetVirtualRegister(node->InputAt(1))) { - // unary, src0 == src1. - mask = kMaxLaneIndex; - } else { - bool src0_is_used = false; - bool src1_is_used = false; - for (int i = 0; i < 16; i++) { - if (shuffle[i] < 16) { - src0_is_used = true; - } else { - src1_is_used = true; - } - } - if (src0_is_used && !src1_is_used) { - node->ReplaceInput(1, node->InputAt(0)); - mask = kMaxLaneIndex; - } else if (src1_is_used && !src0_is_used) { - node->ReplaceInput(0, node->InputAt(1)); - mask = kMaxLaneIndex; - } - } - return mask; -} - -int32_t Pack4Lanes(const uint8_t* shuffle, uint8_t mask) { - int32_t result = 0; - for (int i = 3; i >= 0; i--) { - result <<= 8; - result |= shuffle[i] & mask; - } - return result; -} - void ArrangeShuffleTable(Arm64OperandGenerator* g, Node* input0, Node* input1, InstructionOperand* src0, InstructionOperand* src1) { if (input0 == input1) { @@ -3196,7 +3127,7 @@ void ArrangeShuffleTable(Arm64OperandGenerator* g, Node* input0, Node* input1, void InstructionSelector::VisitS8x16Shuffle(Node* node) { const uint8_t* shuffle = OpParameter<uint8_t*>(node); - uint8_t mask = CanonicalizeShuffle(this, node); + uint8_t mask = CanonicalizeShuffle(node); uint8_t shuffle32x4[4]; Arm64OperandGenerator g(this); ArchOpcode opcode; @@ -3213,10 +3144,32 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) { g.UseRegister(input1), g.UseImmediate(bias)); return; } + int index = 0; if (TryMatch32x4Shuffle(shuffle, shuffle32x4)) { - Emit(kArm64S32x4Shuffle, g.DefineAsRegister(node), - g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), - g.UseImmediate(Pack4Lanes(shuffle32x4, mask))); + if (TryMatchDup<4>(shuffle, &index)) { + InstructionOperand src = index < 4 ? g.UseRegister(node->InputAt(0)) + : g.UseRegister(node->InputAt(1)); + Emit(kArm64S128Dup, g.DefineAsRegister(node), src, g.UseImmediate(4), + g.UseImmediate(index % 4)); + } else { + Emit(kArm64S32x4Shuffle, g.DefineAsRegister(node), + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), + g.UseImmediate(Pack4Lanes(shuffle32x4, mask))); + } + return; + } + if (TryMatchDup<8>(shuffle, &index)) { + InstructionOperand src = index < 8 ? g.UseRegister(node->InputAt(0)) + : g.UseRegister(node->InputAt(1)); + Emit(kArm64S128Dup, g.DefineAsRegister(node), src, g.UseImmediate(8), + g.UseImmediate(index % 8)); + return; + } + if (TryMatchDup<16>(shuffle, &index)) { + InstructionOperand src = index < 16 ? g.UseRegister(node->InputAt(0)) + : g.UseRegister(node->InputAt(1)); + Emit(kArm64S128Dup, g.DefineAsRegister(node), src, g.UseImmediate(16), + g.UseImmediate(index % 16)); return; } // Code generator uses vtbl, arrange sources to form a valid lookup table. |