[arm][arm64] Implement {kSpeculationFence} operator.

R=tebbi@chromium.org

Change-Id: Iae9a3774eb7913388350ce3cd0a96d6a6cca25e8
Reviewed-on: https://chromium-review.googlesource.com/885845
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50926}
This commit is contained in:
Michael Starzinger 2018-01-26 11:25:41 +01:00 committed by Commit Bot
parent c9941af275
commit b47427740d
13 changed files with 51 additions and 14 deletions

View File

@ -461,14 +461,12 @@ void MacroAssembler::Csneg(const Register& rd,
csneg(rd, rn, rm, cond);
}
void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) {
void TurboAssembler::Dmb(BarrierDomain domain, BarrierType type) {
DCHECK(allow_macro_instructions());
dmb(domain, type);
}
void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) {
void TurboAssembler::Dsb(BarrierDomain domain, BarrierType type) {
DCHECK(allow_macro_instructions());
dsb(domain, type);
}
@ -737,8 +735,7 @@ void MacroAssembler::Hlt(int code) {
hlt(code);
}
void MacroAssembler::Isb() {
void TurboAssembler::Isb() {
DCHECK(allow_macro_instructions());
isb();
}

View File

@ -550,6 +550,10 @@ class TurboAssembler : public Assembler {
void Cbnz(const Register& rt, Label* label);
void Cbz(const Register& rt, Label* label);
inline void Dmb(BarrierDomain domain, BarrierType type);
inline void Dsb(BarrierDomain domain, BarrierType type);
inline void Isb();
bool AllowThisStubCall(CodeStub* stub);
void CallStubDelayed(CodeStub* stub);
void CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
@ -1302,8 +1306,6 @@ class MacroAssembler : public TurboAssembler {
Condition cond);
inline void Csneg(const Register& rd, const Register& rn, const Register& rm,
Condition cond);
inline void Dmb(BarrierDomain domain, BarrierType type);
inline void Dsb(BarrierDomain domain, BarrierType type);
inline void Extr(const Register& rd, const Register& rn, const Register& rm,
unsigned lsb);
inline void Fcsel(const VRegister& fd, const VRegister& fn,
@ -1346,7 +1348,6 @@ class MacroAssembler : public TurboAssembler {
const VRegister& fm, const VRegister& fa);
inline void Hint(SystemHint code);
inline void Hlt(int code);
inline void Isb();
inline void Ldnp(const CPURegister& rt, const CPURegister& rt2,
const MemOperand& src);
inline void Movk(const Register& rd, uint64_t imm, int shift = -1);

View File

@ -1629,6 +1629,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
case kArmDsbIsb: {
__ dsb(SY);
__ isb(SY);
break;
}
case kArmF32x4Splat: {
int src_code = i.InputFloatRegister(0).code();
__ vdup(Neon32, i.OutputSimd128Register(),

View File

@ -125,6 +125,7 @@ namespace compiler {
V(ArmPush) \
V(ArmPoke) \
V(ArmPeek) \
V(ArmDsbIsb) \
V(ArmF32x4Splat) \
V(ArmF32x4ExtractLane) \
V(ArmF32x4ReplaceLane) \

View File

@ -274,6 +274,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmStr:
case kArmPush:
case kArmPoke:
case kArmDsbIsb:
return kHasSideEffect;
#define CASE(Name) case k##Name:

View File

@ -1121,7 +1121,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitSpeculationFence(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitSpeculationFence(Node* node) {
ArmOperandGenerator g(this);
Emit(kArmDsbIsb, g.NoOutput());
}
void InstructionSelector::VisitInt32Add(Node* node) {
ArmOperandGenerator g(this);
@ -2654,7 +2657,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
// static
MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::Flags flags;
MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kSpeculationFence;
if (CpuFeatures::IsSupported(SUDIV)) {
// The sdiv and udiv instructions correctly return 0 if the divisor is 0,
// but the fall-back implementation does not.

View File

@ -1546,6 +1546,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArm64StrQ:
__ Str(i.InputSimd128Register(0), i.MemoryOperand(1));
break;
case kArm64DsbIsb:
__ Dsb(FullSystem, BarrierAll);
__ Isb();
break;
case kAtomicLoadInt8:
ASSEMBLE_ATOMIC_LOAD_INTEGER(Ldarb);
__ Sxtb(i.OutputRegister(0), i.OutputRegister(0));

View File

@ -157,6 +157,7 @@ namespace compiler {
V(Arm64StrW) \
V(Arm64Ldr) \
V(Arm64Str) \
V(Arm64DsbIsb) \
V(Arm64F32x4Splat) \
V(Arm64F32x4ExtractLane) \
V(Arm64F32x4ReplaceLane) \

View File

@ -308,6 +308,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64Strh:
case kArm64StrW:
case kArm64Str:
case kArm64DsbIsb:
return kHasSideEffect;
#define CASE(Name) case k##Name:

View File

@ -1258,7 +1258,10 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord64Popcnt(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitSpeculationFence(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitSpeculationFence(Node* node) {
Arm64OperandGenerator g(this);
Emit(kArm64DsbIsb, g.NoOutput());
}
void InstructionSelector::VisitInt32Add(Node* node) {
Arm64OperandGenerator g(this);
@ -3168,7 +3171,8 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe |
MachineOperatorBuilder::kWord32ReverseBits |
MachineOperatorBuilder::kWord64ReverseBits;
MachineOperatorBuilder::kWord64ReverseBits |
MachineOperatorBuilder::kSpeculationFence;
}
// static

View File

@ -46,7 +46,7 @@ class SimulatorBase {
Args... args) {
// Convert all arguments to intptr_t. Fails if any argument is not integral
// or pointer.
std::array<intptr_t, sizeof...(args)> args_arr{ConvertArg(args)...};
std::array<intptr_t, sizeof...(args)> args_arr{{ConvertArg(args)...}};
intptr_t ret = (sim->*call)(entry, args_arr.size(), args_arr.data());
return ConvertReturn<Return>(ret);
}

View File

@ -3257,6 +3257,15 @@ TEST_F(InstructionSelectorTest, Float64Neg) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
}
TEST_F(InstructionSelectorTest, SpeculationFence) {
StreamBuilder m(this, MachineType::Int32());
m.SpeculationFence();
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArmDsbIsb, s[0]->arch_opcode());
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -4417,6 +4417,15 @@ TEST_F(InstructionSelectorTest, CompareFloat64HighGreaterThanOrEqualZero64) {
EXPECT_EQ(63, s.ToInt32(s[1]->InputAt(1)));
}
TEST_F(InstructionSelectorTest, SpeculationFence) {
StreamBuilder m(this, MachineType::Int32());
m.SpeculationFence();
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArm64DsbIsb, s[0]->arch_opcode());
}
} // namespace compiler
} // namespace internal
} // namespace v8