summaryrefslogtreecommitdiff
path: root/chromium/v8/src/compiler/arm64
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-20 10:33:36 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-22 11:45:12 +0000
commitbe59a35641616a4cf23c4a13fa0632624b021c1b (patch)
tree9da183258bdf9cc413f7562079d25ace6955467f /chromium/v8/src/compiler/arm64
parentd702e4b6a64574e97fc7df8fe3238cde70242080 (diff)
downloadqtwebengine-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')
-rw-r--r--chromium/v8/src/compiler/arm64/code-generator-arm64.cc140
-rw-r--r--chromium/v8/src/compiler/arm64/instruction-codes-arm64.h1
-rw-r--r--chromium/v8/src/compiler/arm64/instruction-scheduler-arm64.cc4
-rw-r--r--chromium/v8/src/compiler/arm64/instruction-selector-arm64.cc115
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.