diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index bfa54fabaa..723dfc0ca7 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -2371,6 +2371,11 @@ void Assembler::isb(BarrierOption option) { } } +void Assembler::csdb() { + // Details available in Arm Cache Speculation Side-channels white paper, + // version 1.1, page 4. + emit(0xE320F014); +} // Coprocessor instructions. void Assembler::cdp(Coprocessor coproc, diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h index fa402ca6c0..20598a35dd 100644 --- a/src/arm/assembler-arm.h +++ b/src/arm/assembler-arm.h @@ -960,6 +960,9 @@ class Assembler : public AssemblerBase { void dsb(BarrierOption option); void isb(BarrierOption option); + // Conditional speculation barrier. + void csdb(); + // Coprocessor instructions void cdp(Coprocessor coproc, int opcode_1, diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 1c865afb09..4e52a91738 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -641,8 +641,8 @@ class Instruction { && (Bit(20) == 0) && ((Bit(7) == 0)); } - // Test for a nop instruction, which falls under type 1. - inline bool IsNopType1() const { return Bits(24, 0) == 0x0120F000; } + // Test for nop-like instructions which fall under type 1. + inline bool IsNopLikeType1() const { return Bits(24, 8) == 0x120F0; } // Test for a stop instruction. inline bool IsStop() const { diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc index 9951136561..9459a7e60d 100644 --- a/src/arm/disasm-arm.cc +++ b/src/arm/disasm-arm.cc @@ -937,8 +937,14 @@ void Decoder::DecodeType01(Instruction* instr) { } else { Unknown(instr); // not used by V8 } - } else if ((type == 1) && instr->IsNopType1()) { - Format(instr, "nop'cond"); + } else if ((type == 1) && instr->IsNopLikeType1()) { + if (instr->BitField(7, 0) == 0) { + Format(instr, "nop'cond"); + } else if (instr->BitField(7, 0) == 20) { + Format(instr, "csdb"); + } else { + Unknown(instr); // Not used in V8. + } } else { switch (instr->OpcodeField()) { case AND: { diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 30277ce2f7..6a735fcef6 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -2308,8 +2308,15 @@ void Simulator::DecodeType01(Instruction* instr) { PrintF("%08x\n", instr->InstructionBits()); UNIMPLEMENTED(); } - } else if ((type == 1) && instr->IsNopType1()) { - // NOP. + } else if ((type == 1) && instr->IsNopLikeType1()) { + if (instr->BitField(7, 0) == 0) { + // NOP. + } else if (instr->BitField(7, 0) == 20) { + // CSDB. + } else { + PrintF("%08x\n", instr->InstructionBits()); + UNIMPLEMENTED(); + } } else { int rd = instr->RdValue(); int rn = instr->RnValue(); diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc index 300309244e..52912b7591 100644 --- a/test/cctest/test-disasm-arm.cc +++ b/test/cctest/test-disasm-arm.cc @@ -1568,6 +1568,9 @@ TEST(Barrier) { COMPARE(mcr(p15, 0, r0, cr7, cr10, 4, ne), "1e070f9a mcrne (CP15DSB)"); COMPARE(mcr(p15, 0, r0, cr7, cr5, 4, mi), "4e070f95 mcrmi (CP15ISB)"); + // Conditional speculation barrier. + COMPARE(csdb(), "e320f014 csdb"); + VERIFY_RUN(); }