From cea9476cf01bd29c15349ce000822e8cebb96ac3 Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Tue, 30 Jun 2009 13:38:40 +0000 Subject: [PATCH] More changes to make the simulator run code that is for the ARM5 snapshot. Review URL: http://codereview.chromium.org/150100 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2307 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/constants-arm.h | 31 +++++++++++++++++++++++++++++++ src/arm/disasm-arm.cc | 21 +++++++++++++++++++-- src/arm/macro-assembler-arm.cc | 8 ++++---- src/arm/simulator-arm.cc | 38 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index d5f967f..f0311df 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -36,6 +36,19 @@ # define USE_ARM_EABI 1 #endif +// This means that interwork-compatible jump instructions are generated. We +// want to generate them on the simulator too so it makes snapshots that can +// be used on real hardware. +#if defined(__THUMB_INTERWORK__) || !defined(__arm__) +# define USE_THUMB_INTERWORK 1 +#endif + +// Simulator should support ARM5 instructions. +#if !defined(__arm__) +# define __ARM_ARCH_5__ 1 +# define __ARM_ARCH_5T__ 1 +#endif + namespace assembler { namespace arm { @@ -97,6 +110,24 @@ enum Opcode { }; +// Some special instructions encoded as a TEQ with S=0 (bit 20). +enum Opcode9Bits { + BX = 1, + BXJ = 2, + BLX = 3, + BKPT = 7 +}; + + +// Some special instructions encoded as a CMN with S=0 (bit 20). +enum Opcode11Bits { + CLZ = 1 +}; + + +// S + + // Shifter types for Data-processing operands as defined in section A5.1.2. enum Shift { no_shift = -1, diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc index 908c45a..588732b 100644 --- a/src/arm/disasm-arm.cc +++ b/src/arm/disasm-arm.cc @@ -593,7 +593,17 @@ void Decoder::DecodeType01(Instr* instr) { if (instr->HasS()) { Format(instr, "teq'cond 'rn, 'shift_op"); } else { - Unknown(instr); // not used by V8 + switch (instr->Bits(7, 4)) { + case BX: + Format(instr, "bx'cond 'rm"); + break; + case BLX: + Format(instr, "blx'cond 'rm"); + break; + default: + Unknown(instr); // not used by V8 + break; + } } break; } @@ -609,7 +619,14 @@ void Decoder::DecodeType01(Instr* instr) { if (instr->HasS()) { Format(instr, "cmn'cond 'rn, 'shift_op"); } else { - Unknown(instr); // not used by V8 + switch (instr->Bits(7, 4)) { + case CLZ: + Format(instr, "clz'cond 'rd, 'rm"); + break; + default: + Unknown(instr); // not used by V8 + break; + } } break; } diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 897b5a7..3d6b8cb 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -46,14 +46,14 @@ MacroAssembler::MacroAssembler(void* buffer, int size) // We always generate arm code, never thumb code, even if V8 is compiled to // thumb, so we require inter-working support -#if defined(__thumb__) && !defined(__THUMB_INTERWORK__) +#if defined(__thumb__) && !defined(USE_THUMB_INTERWORK) #error "flag -mthumb-interwork missing" #endif // We do not support thumb inter-working with an arm architecture not supporting // the blx instruction (below v5t) -#if defined(__THUMB_INTERWORK__) +#if defined(USE_THUMB_INTERWORK) #if !defined(__ARM_ARCH_5T__) && \ !defined(__ARM_ARCH_5TE__) && \ !defined(__ARM_ARCH_7A__) && \ @@ -65,12 +65,12 @@ MacroAssembler::MacroAssembler(void* buffer, int size) // Using blx may yield better code, so use it when required or when available -#if defined(__THUMB_INTERWORK__) || defined(__ARM_ARCH_5__) +#if defined(USE_THUMB_INTERWORK) || defined(__ARM_ARCH_5__) #define USE_BLX 1 #endif // Using bx does not yield better code, so use it only when required -#if defined(__THUMB_INTERWORK__) +#if defined(USE_THUMB_INTERWORK) #define USE_BX 1 #endif diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index e31e058..53dbec9 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -1360,7 +1360,21 @@ void Simulator::DecodeType01(Instr* instr) { SetNZFlags(alu_out); SetCFlag(shifter_carry_out); } else { - UNIMPLEMENTED(); + ASSERT(type == 0); + int rm = instr->RmField(); + switch (instr->Bits(7, 4)) { + case BX: + set_pc(get_register(rm)); + break; + case BLX: { + uint32_t old_pc = get_pc(); + set_pc(get_register(rm)); + set_register(lr, old_pc + Instr::kInstrSize); + break; + } + default: + UNIMPLEMENTED(); + } } break; } @@ -1384,7 +1398,27 @@ void Simulator::DecodeType01(Instr* instr) { Format(instr, "cmn'cond 'rn, 'shift_rm"); Format(instr, "cmn'cond 'rn, 'imm"); } else { - UNIMPLEMENTED(); + ASSERT(type == 0); + int rm = instr->RmField(); + int rd = instr->RdField(); + switch (instr->Bits(7, 4)) { + case CLZ: { + uint32_t bits = get_register(rm); + int leading_zeros = 0; + if (bits == 0) { + leading_zeros = 32; + } else { + while ((bits & 0x80000000u) == 0) { + bits <<= 1; + leading_zeros++; + } + } + set_register(rd, leading_zeros); + break; + } + default: + UNIMPLEMENTED(); + } } break; } -- 2.7.4