Commit b4742774 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

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

R=tebbi@chromium.org

Change-Id: Iae9a3774eb7913388350ce3cd0a96d6a6cca25e8
Reviewed-on: https://chromium-review.googlesource.com/885845Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50926}
parent c9941af2
...@@ -461,14 +461,12 @@ void MacroAssembler::Csneg(const Register& rd, ...@@ -461,14 +461,12 @@ void MacroAssembler::Csneg(const Register& rd,
csneg(rd, rn, rm, cond); csneg(rd, rn, rm, cond);
} }
void TurboAssembler::Dmb(BarrierDomain domain, BarrierType type) {
void MacroAssembler::Dmb(BarrierDomain domain, BarrierType type) {
DCHECK(allow_macro_instructions()); DCHECK(allow_macro_instructions());
dmb(domain, type); dmb(domain, type);
} }
void TurboAssembler::Dsb(BarrierDomain domain, BarrierType type) {
void MacroAssembler::Dsb(BarrierDomain domain, BarrierType type) {
DCHECK(allow_macro_instructions()); DCHECK(allow_macro_instructions());
dsb(domain, type); dsb(domain, type);
} }
...@@ -737,8 +735,7 @@ void MacroAssembler::Hlt(int code) { ...@@ -737,8 +735,7 @@ void MacroAssembler::Hlt(int code) {
hlt(code); hlt(code);
} }
void TurboAssembler::Isb() {
void MacroAssembler::Isb() {
DCHECK(allow_macro_instructions()); DCHECK(allow_macro_instructions());
isb(); isb();
} }
......
...@@ -550,6 +550,10 @@ class TurboAssembler : public Assembler { ...@@ -550,6 +550,10 @@ class TurboAssembler : public Assembler {
void Cbnz(const Register& rt, Label* label); void Cbnz(const Register& rt, Label* label);
void Cbz(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); bool AllowThisStubCall(CodeStub* stub);
void CallStubDelayed(CodeStub* stub); void CallStubDelayed(CodeStub* stub);
void CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid, void CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
...@@ -1302,8 +1306,6 @@ class MacroAssembler : public TurboAssembler { ...@@ -1302,8 +1306,6 @@ class MacroAssembler : public TurboAssembler {
Condition cond); Condition cond);
inline void Csneg(const Register& rd, const Register& rn, const Register& rm, inline void Csneg(const Register& rd, const Register& rn, const Register& rm,
Condition cond); 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, inline void Extr(const Register& rd, const Register& rn, const Register& rm,
unsigned lsb); unsigned lsb);
inline void Fcsel(const VRegister& fd, const VRegister& fn, inline void Fcsel(const VRegister& fd, const VRegister& fn,
...@@ -1346,7 +1348,6 @@ class MacroAssembler : public TurboAssembler { ...@@ -1346,7 +1348,6 @@ class MacroAssembler : public TurboAssembler {
const VRegister& fm, const VRegister& fa); const VRegister& fm, const VRegister& fa);
inline void Hint(SystemHint code); inline void Hint(SystemHint code);
inline void Hlt(int code); inline void Hlt(int code);
inline void Isb();
inline void Ldnp(const CPURegister& rt, const CPURegister& rt2, inline void Ldnp(const CPURegister& rt, const CPURegister& rt2,
const MemOperand& src); const MemOperand& src);
inline void Movk(const Register& rd, uint64_t imm, int shift = -1); inline void Movk(const Register& rd, uint64_t imm, int shift = -1);
......
...@@ -1629,6 +1629,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1629,6 +1629,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} }
break; break;
} }
case kArmDsbIsb: {
__ dsb(SY);
__ isb(SY);
break;
}
case kArmF32x4Splat: { case kArmF32x4Splat: {
int src_code = i.InputFloatRegister(0).code(); int src_code = i.InputFloatRegister(0).code();
__ vdup(Neon32, i.OutputSimd128Register(), __ vdup(Neon32, i.OutputSimd128Register(),
......
...@@ -125,6 +125,7 @@ namespace compiler { ...@@ -125,6 +125,7 @@ namespace compiler {
V(ArmPush) \ V(ArmPush) \
V(ArmPoke) \ V(ArmPoke) \
V(ArmPeek) \ V(ArmPeek) \
V(ArmDsbIsb) \
V(ArmF32x4Splat) \ V(ArmF32x4Splat) \
V(ArmF32x4ExtractLane) \ V(ArmF32x4ExtractLane) \
V(ArmF32x4ReplaceLane) \ V(ArmF32x4ReplaceLane) \
......
...@@ -274,6 +274,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -274,6 +274,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmStr: case kArmStr:
case kArmPush: case kArmPush:
case kArmPoke: case kArmPoke:
case kArmDsbIsb:
return kHasSideEffect; return kHasSideEffect;
#define CASE(Name) case k##Name: #define CASE(Name) case k##Name:
......
...@@ -1121,7 +1121,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); } ...@@ -1121,7 +1121,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord32Popcnt(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) { void InstructionSelector::VisitInt32Add(Node* node) {
ArmOperandGenerator g(this); ArmOperandGenerator g(this);
...@@ -2654,7 +2657,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { ...@@ -2654,7 +2657,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::Flags flags; MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::kSpeculationFence;
if (CpuFeatures::IsSupported(SUDIV)) { if (CpuFeatures::IsSupported(SUDIV)) {
// The sdiv and udiv instructions correctly return 0 if the divisor is 0, // The sdiv and udiv instructions correctly return 0 if the divisor is 0,
// but the fall-back implementation does not. // but the fall-back implementation does not.
......
...@@ -1546,6 +1546,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1546,6 +1546,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArm64StrQ: case kArm64StrQ:
__ Str(i.InputSimd128Register(0), i.MemoryOperand(1)); __ Str(i.InputSimd128Register(0), i.MemoryOperand(1));
break; break;
case kArm64DsbIsb:
__ Dsb(FullSystem, BarrierAll);
__ Isb();
break;
case kAtomicLoadInt8: case kAtomicLoadInt8:
ASSEMBLE_ATOMIC_LOAD_INTEGER(Ldarb); ASSEMBLE_ATOMIC_LOAD_INTEGER(Ldarb);
__ Sxtb(i.OutputRegister(0), i.OutputRegister(0)); __ Sxtb(i.OutputRegister(0), i.OutputRegister(0));
......
...@@ -157,6 +157,7 @@ namespace compiler { ...@@ -157,6 +157,7 @@ namespace compiler {
V(Arm64StrW) \ V(Arm64StrW) \
V(Arm64Ldr) \ V(Arm64Ldr) \
V(Arm64Str) \ V(Arm64Str) \
V(Arm64DsbIsb) \
V(Arm64F32x4Splat) \ V(Arm64F32x4Splat) \
V(Arm64F32x4ExtractLane) \ V(Arm64F32x4ExtractLane) \
V(Arm64F32x4ReplaceLane) \ V(Arm64F32x4ReplaceLane) \
......
...@@ -308,6 +308,7 @@ int InstructionScheduler::GetTargetInstructionFlags( ...@@ -308,6 +308,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64Strh: case kArm64Strh:
case kArm64StrW: case kArm64StrW:
case kArm64Str: case kArm64Str:
case kArm64DsbIsb:
return kHasSideEffect; return kHasSideEffect;
#define CASE(Name) case k##Name: #define CASE(Name) case k##Name:
......
...@@ -1258,7 +1258,10 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); } ...@@ -1258,7 +1258,10 @@ void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitWord64Popcnt(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) { void InstructionSelector::VisitInt32Add(Node* node) {
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
...@@ -3168,7 +3171,8 @@ InstructionSelector::SupportedMachineOperatorFlags() { ...@@ -3168,7 +3171,8 @@ InstructionSelector::SupportedMachineOperatorFlags() {
MachineOperatorBuilder::kInt32DivIsSafe | MachineOperatorBuilder::kInt32DivIsSafe |
MachineOperatorBuilder::kUint32DivIsSafe | MachineOperatorBuilder::kUint32DivIsSafe |
MachineOperatorBuilder::kWord32ReverseBits | MachineOperatorBuilder::kWord32ReverseBits |
MachineOperatorBuilder::kWord64ReverseBits; MachineOperatorBuilder::kWord64ReverseBits |
MachineOperatorBuilder::kSpeculationFence;
} }
// static // static
......
...@@ -46,7 +46,7 @@ class SimulatorBase { ...@@ -46,7 +46,7 @@ class SimulatorBase {
Args... args) { Args... args) {
// Convert all arguments to intptr_t. Fails if any argument is not integral // Convert all arguments to intptr_t. Fails if any argument is not integral
// or pointer. // 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()); intptr_t ret = (sim->*call)(entry, args_arr.size(), args_arr.data());
return ConvertReturn<Return>(ret); return ConvertReturn<Return>(ret);
} }
......
...@@ -3257,6 +3257,15 @@ TEST_F(InstructionSelectorTest, Float64Neg) { ...@@ -3257,6 +3257,15 @@ TEST_F(InstructionSelectorTest, Float64Neg) {
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 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 compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -4417,6 +4417,15 @@ TEST_F(InstructionSelectorTest, CompareFloat64HighGreaterThanOrEqualZero64) { ...@@ -4417,6 +4417,15 @@ TEST_F(InstructionSelectorTest, CompareFloat64HighGreaterThanOrEqualZero64) {
EXPECT_EQ(63, s.ToInt32(s[1]->InputAt(1))); 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 compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment