From a86e897924e47d03e4d1453ed416a200306ac453 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Mon, 15 Oct 2012 15:42:09 +0000 Subject: [PATCH] Simulate and disasm NOP on ARM R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/11116011 Patch from JF Bastien . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12737 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/assembler-arm.cc | 10 +++++++--- src/arm/constants-arm.h | 3 +++ src/arm/disasm-arm.cc | 2 ++ src/arm/simulator-arm.cc | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index 86bed1caac..ccf7208a8f 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -2440,15 +2440,19 @@ void Assembler::vsqrt(const DwVfpRegister dst, // Pseudo instructions. void Assembler::nop(int type) { - // This is mov rx, rx. - ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. + // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes + // some of the CPU's pipeline and has to issue. Older ARM chips simply used + // MOV Rx, Rx as NOP and it performs better even in newer CPUs. + // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode + // a type. + ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop. emit(al | 13*B21 | type*B12 | type); } bool Assembler::IsNop(Instr instr, int type) { + ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop. // Check for mov rx, rx where x = type. - ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. return instr == (al | 13*B21 | type*B12 | type); } diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index a6b584394f..4fa49e3d3c 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -687,6 +687,9 @@ 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 a stop instruction. inline bool IsStop() const { return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode); diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc index 7c5f63edc9..3c94a46e62 100644 --- a/src/arm/disasm-arm.cc +++ b/src/arm/disasm-arm.cc @@ -830,6 +830,8 @@ void Decoder::DecodeType01(Instruction* instr) { } else { Unknown(instr); // not used by V8 } + } else if ((type == 1) && instr->IsNopType1()) { + Format(instr, "nop'cond"); } else { switch (instr->OpcodeField()) { case AND: { diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index a75046a195..5b8ba2adae 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -2183,6 +2183,8 @@ void Simulator::DecodeType01(Instruction* instr) { PrintF("%08x\n", instr->InstructionBits()); UNIMPLEMENTED(); } + } else if ((type == 1) && instr->IsNopType1()) { + // NOP. } else { int rd = instr->RdValue(); int rn = instr->RnValue();