[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:
parent
c9941af275
commit
b47427740d
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -125,6 +125,7 @@ namespace compiler {
|
||||
V(ArmPush) \
|
||||
V(ArmPoke) \
|
||||
V(ArmPeek) \
|
||||
V(ArmDsbIsb) \
|
||||
V(ArmF32x4Splat) \
|
||||
V(ArmF32x4ExtractLane) \
|
||||
V(ArmF32x4ReplaceLane) \
|
||||
|
@ -274,6 +274,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kArmStr:
|
||||
case kArmPush:
|
||||
case kArmPoke:
|
||||
case kArmDsbIsb:
|
||||
return kHasSideEffect;
|
||||
|
||||
#define CASE(Name) case k##Name:
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -157,6 +157,7 @@ namespace compiler {
|
||||
V(Arm64StrW) \
|
||||
V(Arm64Ldr) \
|
||||
V(Arm64Str) \
|
||||
V(Arm64DsbIsb) \
|
||||
V(Arm64F32x4Splat) \
|
||||
V(Arm64F32x4ExtractLane) \
|
||||
V(Arm64F32x4ReplaceLane) \
|
||||
|
@ -308,6 +308,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kArm64Strh:
|
||||
case kArm64StrW:
|
||||
case kArm64Str:
|
||||
case kArm64DsbIsb:
|
||||
return kHasSideEffect;
|
||||
|
||||
#define CASE(Name) case k##Name:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user