Index: src/sh4/disasm-sh4.cc |
diff --git a/src/sh4/disasm-sh4.cc b/src/sh4/disasm-sh4.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ddc52bf959456b17e16b75f8c156f2c81536184c |
--- /dev/null |
+++ b/src/sh4/disasm-sh4.cc |
@@ -0,0 +1,838 @@ |
+// Copyright 2011-2012 the V8 project authors. All rights reserved. |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+#include "v8.h" |
+ |
+#if defined(V8_TARGET_ARCH_SH4) |
+ |
+#include "constants-sh4.h" |
+#include "disasm.h" |
+#include "macro-assembler.h" |
+#include "platform.h" |
+ |
+// Due to GPL licencing of the opcodes-disasm-sh4.c file, if you enable the |
+// part of code surrounded by USE_KERNEL_DISASM, the the whole project became |
+// GPL. |
+ |
+//------------------------------------------------------------------------------ |
+ |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+ |
+//------------------------------------------------------------------------------ |
+ |
+#ifdef USE_KERNEL_DISASM |
+# define V8_IN_TYPE_DECLS 1 |
+# include "opcodes-disasm-sh4.c" |
+# undef V8_IN_TYPE_DECLS |
+#endif /* USE_KERNEL_DISASM */ |
+ |
+// Decoder decodes and disassembles instructions into an output buffer. |
+// It uses the converter to convert register names and call destinations into |
+// more informative description. |
+class Decoder { |
+ public: |
+ explicit Decoder(Vector<char> out_buffer) |
+ : out_buffer_(out_buffer), |
+ out_buffer_pos_(0), |
+ last_pool_offset_(0), |
+ last_pool_size_(0) { |
+ out_buffer_[out_buffer_pos_] = '\0'; |
+ } |
+ |
+ ~Decoder() {} |
+ |
+ // Writes one disassembled instruction into 'buffer' (0-terminated). |
+ // Returns the length of the disassembled machine instruction in bytes. |
+ int InstructionDecode(byte* instruction); |
+ |
+#ifndef USE_KERNEL_DISASM |
+ // All Decode... function are decoding the set of instructions |
+ // from the tables defined in thhe architecture manual. |
+ // From Architecture Manual ADCS 7182230G SH-4 CPU Core Architecture |
+ // Revision: 30 April 2003 |
+ // Section 7.3, p. 149: Instruciton set summary |
+ |
+ // Decode instructions from Table 39, p.150 |
+ int DecodeTable39(Instruction* instr); |
+#endif /* !USE_KERNEL_DISASM */ |
+ |
+ |
+ // Returns the offset from the current PC (before the instruction) |
+ // and size of the reference if a PC relative dereference was decoded. |
+ int LastPoolSize(); |
+ int LastPoolReference(); |
+ |
+ private: |
+ // Print a formated stream. |
+ void Format(const char *format, ...); |
+ |
+#if USE_KERNEL_DISASM |
+ // This method is implemented in opcodes-disasm-sh4.c |
+ void print_sh_insn(uint32_t memaddr, uint16_t insn); |
+#endif /* USE_KERNEL_DISASM */ |
+ |
+ Vector<char> out_buffer_; |
+ int out_buffer_pos_; |
+ int last_pool_offset_; |
+ int last_pool_size_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Decoder); |
+}; |
+ |
+#if USE_KERNEL_DISASM |
+# define printk Format |
+# define __get_user(val, ptr) \ |
+ do { last_pool_offset_ = (u32)(ptr) - memaddr;\ |
+ last_pool_size_ = sizeof(*(ptr)); \ |
+ ((val) = *(ptr)); } while (0) |
+# define u16 uint16_t |
+# define u32 uint32_t |
+# include "opcodes-disasm-sh4.c" |
+# undef u16 |
+# undef u32 |
+# undef __get_user |
+# undef printk |
+#endif /* USE_KERNEL_DISASM */ |
+ |
+ |
+void Decoder::Format(const char *format, ...) { |
+ va_list args; |
+ va_start(args, format); |
+ out_buffer_pos_ += OS::VSNPrintF(out_buffer_ + out_buffer_pos_, format, args); |
+ va_end(args); |
+} |
+ |
+ |
+int Decoder::InstructionDecode(byte* instr_ptr) { |
+ uint16_t bits = *reinterpret_cast<const uint16_t *>(instr_ptr); |
+ // Print raw instruction bytes. |
+ out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
+ "%02x %02x ", |
+ (bits & 0xff), ((bits>>8) & 0xff)); |
+ |
+#ifdef USE_KERNEL_DISASM |
+ uint32_t pc = (uint32_t)(instr_ptr); |
+ print_sh_insn(pc, bits); |
+#else |
+ Instruction* instr = Instruction::At(instr_ptr); |
+ DecodeTable39(instr); |
+#endif /* USE_KERNEL_DISASM */ |
+ |
+ return Instruction::kInstrSize; |
+} |
+ |
+ |
+#ifndef USE_KERNEL_DISASM |
+ |
+#define FMT_T39_1 1 |
+#define FMT_T39_1_FMT "\t%s\t#%d,%s" |
+#define FMT_T39_1_i8(instr) (instr->SBits(7, 0)) |
+#define FMT_T39_1_n(instr) (instr->Bits(11, 8)) |
+#define FMT_T39_1_OPC(instr) (instr->Bits(15, 12)) |
+#define FMT_T39_1_STR "mov" |
+ |
+#define FMT_T39_2 2 |
+#define FMT_T39_2_FMT "\t%s\t@(%u,pc),%s" |
+#define FMT_T39_2_d8(instr) (instr->Bits(7, 0)) |
+#define FMT_T39_2_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_2_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_2_STR "mov.w" |
+ |
+#define FMT_T39_3 3 |
+#define FMT_T39_3_FMT FMT_T39_2_FMT |
+#define FMT_T39_3_d8(instr) FMT_T39_2_d8(instr) |
+#define FMT_T39_3_n(instr) FMT_T39_2_n(instr) |
+#define FMT_T39_3_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_3_STR "mov.l" |
+ |
+#define FMT_T39_4 4 |
+#define FMT_T39_4_FMT "\t%s\t%s,%s" |
+#define FMT_T39_4_m(instr) (instr->Bits(7, 4)) |
+#define FMT_T39_4_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_4_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_4_OPC2(instr) (instr->Bits(3, 0)) |
+#define FMT_T39_4_STR "mov" |
+ |
+#define FMT_T39_5 5 |
+#define FMT_T39_5_FMT "\t%s\t%s,@%s" |
+#define FMT_T39_5_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_5_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_5_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_5_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_5_STR "mov.b" |
+ |
+#define FMT_T39_6 6 |
+#define FMT_T39_6_FMT FMT_T39_5_FMT |
+#define FMT_T39_6_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_6_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_6_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_6_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_6_STR "mov.w" |
+ |
+#define FMT_T39_7 7 |
+#define FMT_T39_7_FMT FMT_T39_5_FMT |
+#define FMT_T39_7_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_7_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_7_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_7_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_7_STR "mov.l" |
+ |
+#define FMT_T39_8 8 |
+#define FMT_T39_8_FMT "\t%s\t@%s,%s" |
+#define FMT_T39_8_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_8_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_8_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_8_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_8_STR "mov.b" |
+ |
+#define FMT_T39_9 9 |
+#define FMT_T39_9_FMT FMT_T39_8_FMT |
+#define FMT_T39_9_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_9_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_9_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_9_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_9_STR "mov.w" |
+ |
+#define FMT_T39_10 10 |
+#define FMT_T39_10_FMT FMT_T39_8_FMT |
+#define FMT_T39_10_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_10_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_10_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_10_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_10_STR "mov.l" |
+ |
+#define FMT_T39_11 11 |
+#define FMT_T39_11_FMT "\t%s\t%s,@-%s" |
+#define FMT_T39_11_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_11_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_11_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_11_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_11_STR "mov.b" |
+ |
+#define FMT_T39_12 12 |
+#define FMT_T39_12_FMT FMT_T39_11_FMT |
+#define FMT_T39_12_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_12_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_12_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_12_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_12_STR "mov.w" |
+ |
+#define FMT_T39_13 13 |
+#define FMT_T39_13_FMT FMT_T39_11_FMT |
+#define FMT_T39_13_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_13_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_13_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_13_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_13_STR "mov.l" |
+ |
+#define FMT_T39_14 14 |
+#define FMT_T39_14_FMT "\t%s\t@%s+,%s" |
+#define FMT_T39_14_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_14_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_14_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_14_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_14_STR "mov.b" |
+ |
+#define FMT_T39_15 15 |
+#define FMT_T39_15_FMT FMT_T39_14_FMT |
+#define FMT_T39_15_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_15_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_15_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_15_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_15_STR "mov.w" |
+ |
+#define FMT_T39_16 16 |
+#define FMT_T39_16_FMT FMT_T39_14_FMT |
+#define FMT_T39_16_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_16_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_16_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_16_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_16_STR "mov.l" |
+ |
+#define FMT_T39_17 17 |
+#define FMT_T39_17_FMT "\t%s\tr0,@(%u,%s)" |
+#define FMT_T39_17_d(instr) (instr->Bits(3, 0)) |
+#define FMT_T39_17_n(instr) (instr->Bits(7, 4)) |
+#define FMT_T39_17_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_17_OPC3(instr) (instr->Bits(11, 8)) |
+#define FMT_T39_17_STR "mov.b" |
+ |
+#define FMT_T39_18 18 |
+#define FMT_T39_18_FMT FMT_T39_17_FMT |
+#define FMT_T39_18_d(instr) FMT_T39_17_d(instr) |
+#define FMT_T39_18_n(instr) FMT_T39_17_n(instr) |
+#define FMT_T39_18_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_18_OPC3(instr) FMT_T39_17_OPC3(instr) |
+#define FMT_T39_18_STR "mov.w" |
+ |
+#define FMT_T39_19 19 |
+#define FMT_T39_19_FMT "\t%s\t%s,@(%u,%s)" |
+#define FMT_T39_19_d(instr) FMT_T39_17_d(instr) |
+#define FMT_T39_19_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_19_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_19_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_19_STR "mov.l" |
+ |
+#define FMT_T39_20 20 |
+#define FMT_T39_20_FMT "\t%s\t@(%u,%s),r0" |
+#define FMT_T39_20_d(instr) FMT_T39_17_d(instr) |
+#define FMT_T39_20_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_20_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_20_OPC3(instr) FMT_T39_17_OPC3(instr) |
+#define FMT_T39_20_STR "mov.b" |
+ |
+#define FMT_T39_21 21 |
+#define FMT_T39_21_FMT FMT_T39_20_FMT |
+#define FMT_T39_21_d(instr) FMT_T39_17_d(instr) |
+#define FMT_T39_21_m(instr) FMT_T39_20_m(instr) |
+#define FMT_T39_21_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_21_OPC3(instr) FMT_T39_17_OPC3(instr) |
+#define FMT_T39_21_STR "mov.w" |
+ |
+#define FMT_T39_22 22 |
+#define FMT_T39_22_FMT "\t%s\t@(%u,%s),%s" |
+#define FMT_T39_22_d(instr) FMT_T39_17_d(instr) |
+#define FMT_T39_22_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_22_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_22_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_22_STR "mov.l" |
+ |
+#define FMT_T39_23 23 |
+#define FMT_T39_23_FMT "\t%s\t%s,@(r0,%s)" |
+#define FMT_T39_23_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_23_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_23_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_23_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_23_STR "mov.b" |
+ |
+#define FMT_T39_24 24 |
+#define FMT_T39_24_FMT FMT_T39_23_FMT |
+#define FMT_T39_24_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_24_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_24_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_24_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_24_STR "mov.w" |
+ |
+#define FMT_T39_25 25 |
+#define FMT_T39_25_FMT FMT_T39_23_FMT |
+#define FMT_T39_25_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_25_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_25_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_25_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_25_STR "mov.l" |
+ |
+ |
+#define FMT_T39_26 26 |
+#define FMT_T39_26_FMT "\t%s\t@(r0,%s),%s" |
+#define FMT_T39_26_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_26_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_26_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_26_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_26_STR "mov.b" |
+ |
+#define FMT_T39_27 27 |
+#define FMT_T39_27_FMT FMT_T39_26_FMT |
+#define FMT_T39_27_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_27_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_27_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_27_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_27_STR "mov.w" |
+ |
+#define FMT_T39_28 28 |
+#define FMT_T39_28_FMT FMT_T39_23_FMT |
+#define FMT_T39_28_m(instr) FMT_T39_4_m(instr) |
+#define FMT_T39_28_n(instr) FMT_T39_1_n(instr) |
+#define FMT_T39_28_OPC(instr) FMT_T39_1_OPC(instr) |
+#define FMT_T39_28_OPC2(instr) FMT_T39_4_OPC2(instr) |
+#define FMT_T39_28_STR "mov.l" |
+ |
+ |
+enum OPC { |
+ FMT_T39_1_OPC_MOV = 0xe, |
+ FMT_T39_2_OPC_MOV_W = 0x9, |
+ FMT_T39_3_OPC_MOV_L = 0xd, |
+ FMT_T39_4_OPC_MOV = 0x6, |
+ FMT_T39_5_OPC_MOV_B = 0x2, |
+ FMT_T39_17_OPC_MOV_B = 0x8, |
+ FMT_T39_19_OPC_MOV_L = 0x1, |
+ FMT_T39_22_OPC_MOV_L = 0x5, |
+ FMT_T39_23_OPC_MOV_B = 0x0 |
+}; |
+ |
+enum OPC2 { |
+ FMT_T39_4_OPC2_MOV = 0x3, |
+ FMT_T39_5_OPC2_MOV_B = 0x0, |
+ FMT_T39_6_OPC2_MOV_W = 0x1, |
+ FMT_T39_7_OPC2_MOV_L = 0x2, |
+ FMT_T39_8_OPC2_MOV_B = 0x0, |
+ FMT_T39_9_OPC2_MOV_W = 0x1, |
+ FMT_T39_10_OPC2_MOV_L = 0x2, |
+ FMT_T39_11_OPC2_MOV_B = 0x4, |
+ FMT_T39_12_OPC2_MOV_W = 0x5, |
+ FMT_T39_13_OPC2_MOV_L = 0x6, |
+ FMT_T39_14_OPC2_MOV_B = 0x4, |
+ FMT_T39_15_OPC2_MOV_W = 0x5, |
+ FMT_T39_16_OPC2_MOV_L = 0x6, |
+ FMT_T39_23_OPC2_MOV_B = 0x4, |
+ FMT_T39_24_OPC2_MOV_W = 0x5, |
+ FMT_T39_25_OPC2_MOV_L = 0x6, |
+ FMT_T39_26_OPC2_MOV_B = 0xc, |
+ FMT_T39_27_OPC2_MOV_W = 0xd, |
+ FMT_T39_28_OPC2_MOV_L = 0xe |
+}; |
+ |
+enum OPC3 { |
+ FMT_T39_17_OPC3_MOV_B = 0x0, |
+ FMT_T39_18_OPC3_MOV_W = 0x1, |
+ FMT_T39_20_OPC3_MOV_B = 0x4, |
+ FMT_T39_21_OPC3_MOV_W = 0x5 |
+}; |
+ |
+int Decoder::DecodeTable39(Instruction *instr) { |
+ switch (FMT_T39_1_OPC(instr)) { |
+#ifdef FMT_T39_1 |
+ case FMT_T39_1_OPC_MOV: |
+ Format(FMT_T39_1_FMT, FMT_T39_1_STR, |
+ FMT_T39_1_i8(instr), |
+ Registers::Name(FMT_T39_1_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_2 |
+ case FMT_T39_2_OPC_MOV_W: |
+ Format(FMT_T39_2_FMT, FMT_T39_2_STR, |
+ FMT_T39_2_d8(instr), |
+ Registers::Name(FMT_T39_2_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_3 |
+ case FMT_T39_3_OPC_MOV_L: |
+ Format(FMT_T39_3_FMT, FMT_T39_3_STR, |
+ FMT_T39_3_d8(instr), |
+ Registers::Name(FMT_T39_3_n(instr))); |
+ break; |
+#endif |
+ case FMT_T39_4_OPC_MOV: |
+ switch (FMT_T39_4_OPC2(instr)) { |
+#ifdef FMT_T39_4 |
+ case FMT_T39_4_OPC2_MOV: |
+ Format(FMT_T39_4_FMT, FMT_T39_4_STR, |
+ Registers::Name(FMT_T39_4_m(instr)), |
+ Registers::Name(FMT_T39_4_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_8 |
+ case FMT_T39_8_OPC2_MOV_B: |
+ Format(FMT_T39_8_FMT, FMT_T39_8_STR, |
+ Registers::Name(FMT_T39_8_m(instr)), |
+ Registers::Name(FMT_T39_8_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_9 |
+ case FMT_T39_9_OPC2_MOV_W: |
+ Format(FMT_T39_9_FMT, FMT_T39_9_STR, |
+ Registers::Name(FMT_T39_9_m(instr)), |
+ Registers::Name(FMT_T39_9_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_10 |
+ case FMT_T39_10_OPC2_MOV_L: |
+ Format(FMT_T39_10_FMT, FMT_T39_10_STR, |
+ Registers::Name(FMT_T39_10_m(instr)), |
+ Registers::Name(FMT_T39_10_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_14 |
+ case FMT_T39_14_OPC2_MOV_B: |
+ Format(FMT_T39_14_FMT, FMT_T39_14_STR, |
+ Registers::Name(FMT_T39_14_m(instr)), |
+ Registers::Name(FMT_T39_14_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_15 |
+ case FMT_T39_15_OPC2_MOV_W: |
+ Format(FMT_T39_15_FMT, FMT_T39_15_STR, |
+ Registers::Name(FMT_T39_15_m(instr)), |
+ Registers::Name(FMT_T39_15_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_16 |
+ case FMT_T39_16_OPC2_MOV_L: |
+ Format(FMT_T39_16_FMT, FMT_T39_16_STR, |
+ Registers::Name(FMT_T39_16_m(instr)), |
+ Registers::Name(FMT_T39_16_n(instr))); |
+ break; |
+#endif |
+ default: |
+ return 0; |
+ } |
+ break; |
+ case FMT_T39_5_OPC_MOV_B: |
+ switch (FMT_T39_5_OPC2(instr)) { |
+#ifdef FMT_T39_5 |
+ case FMT_T39_5_OPC2_MOV_B: |
+ Format(FMT_T39_5_FMT, FMT_T39_5_STR, |
+ Registers::Name(FMT_T39_5_m(instr)), |
+ Registers::Name(FMT_T39_5_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_6 |
+ case FMT_T39_6_OPC2_MOV_W: |
+ Format(FMT_T39_6_FMT, FMT_T39_6_STR, |
+ Registers::Name(FMT_T39_6_m(instr)), |
+ Registers::Name(FMT_T39_6_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_7 |
+ case FMT_T39_7_OPC2_MOV_L: |
+ Format(FMT_T39_7_FMT, FMT_T39_7_STR, |
+ Registers::Name(FMT_T39_7_m(instr)), |
+ Registers::Name(FMT_T39_7_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_11 |
+ case FMT_T39_11_OPC2_MOV_B: |
+ Format(FMT_T39_11_FMT, FMT_T39_11_STR, |
+ Registers::Name(FMT_T39_11_m(instr)), |
+ Registers::Name(FMT_T39_11_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_12 |
+ case FMT_T39_12_OPC2_MOV_W: |
+ Format(FMT_T39_12_FMT, FMT_T39_12_STR, |
+ Registers::Name(FMT_T39_12_m(instr)), |
+ Registers::Name(FMT_T39_12_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_13 |
+ case FMT_T39_13_OPC2_MOV_L: |
+ Format(FMT_T39_13_FMT, FMT_T39_13_STR, |
+ Registers::Name(FMT_T39_13_m(instr)), |
+ Registers::Name(FMT_T39_13_n(instr))); |
+ break; |
+#endif |
+ default: |
+ return 0; |
+ } |
+ break; |
+ case FMT_T39_17_OPC_MOV_B: |
+ switch (FMT_T39_17_OPC3(instr)) { |
+#ifdef FMT_T39_17 |
+ case FMT_T39_17_OPC3_MOV_B: |
+ Format(FMT_T39_17_FMT, FMT_T39_17_STR, |
+ FMT_T39_17_d(instr), |
+ Registers::Name(FMT_T39_17_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_18 |
+ case FMT_T39_18_OPC3_MOV_W: |
+ Format(FMT_T39_18_FMT, FMT_T39_18_STR, |
+ FMT_T39_18_d(instr), |
+ Registers::Name(FMT_T39_18_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_20 |
+ case FMT_T39_20_OPC3_MOV_B: |
+ Format(FMT_T39_20_FMT, FMT_T39_20_STR, |
+ FMT_T39_20_d(instr), |
+ Registers::Name(FMT_T39_20_m(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_21 |
+ case FMT_T39_21_OPC3_MOV_W: |
+ Format(FMT_T39_21_FMT, FMT_T39_21_STR, |
+ FMT_T39_21_d(instr), |
+ Registers::Name(FMT_T39_21_m(instr))); |
+ break; |
+#endif |
+ default: |
+ return 0; |
+ } |
+ break; |
+#ifdef FMT_T39_19 |
+ case FMT_T39_19_OPC_MOV_L: |
+ Format(FMT_T39_19_FMT, FMT_T39_19_STR, |
+ Registers::Name(FMT_T39_19_m(instr)), |
+ FMT_T39_19_d(instr), |
+ Registers::Name(FMT_T39_19_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_22 |
+ case FMT_T39_22_OPC_MOV_L: |
+ Format(FMT_T39_22_FMT, FMT_T39_22_STR, |
+ FMT_T39_22_d(instr), |
+ Registers::Name(FMT_T39_22_m(instr)), |
+ Registers::Name(FMT_T39_22_n(instr))); |
+ break; |
+#endif |
+ case FMT_T39_23_OPC_MOV_B: |
+ switch (FMT_T39_23_OPC2(instr)) { |
+#ifdef FMT_T39_23 |
+ case FMT_T39_23_OPC2_MOV_B: |
+ Format(FMT_T39_23_FMT, FMT_T39_23_STR, |
+ Registers::Name(FMT_T39_23_m(instr)), |
+ Registers::Name(FMT_T39_23_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_24 |
+ case FMT_T39_24_OPC2_MOV_W: |
+ Format(FMT_T39_24_FMT, FMT_T39_24_STR, |
+ Registers::Name(FMT_T39_24_m(instr)), |
+ Registers::Name(FMT_T39_24_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_25 |
+ case FMT_T39_25_OPC2_MOV_L: |
+ Format(FMT_T39_25_FMT, FMT_T39_25_STR, |
+ Registers::Name(FMT_T39_25_m(instr)), |
+ Registers::Name(FMT_T39_25_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_26 |
+ case FMT_T39_26_OPC2_MOV_B: |
+ Format(FMT_T39_26_FMT, FMT_T39_26_STR, |
+ Registers::Name(FMT_T39_26_m(instr)), |
+ Registers::Name(FMT_T39_26_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_27 |
+ case FMT_T39_27_OPC2_MOV_W: |
+ Format(FMT_T39_27_FMT, FMT_T39_27_STR, |
+ Registers::Name(FMT_T39_27_m(instr)), |
+ Registers::Name(FMT_T39_27_n(instr))); |
+ break; |
+#endif |
+#ifdef FMT_T39_28 |
+ case FMT_T39_28_OPC2_MOV_L: |
+ Format(FMT_T39_28_FMT, FMT_T39_28_STR, |
+ Registers::Name(FMT_T39_28_m(instr)), |
+ Registers::Name(FMT_T39_28_n(instr))); |
+ break; |
+#endif |
+ default: |
+ return 0; |
+ } |
+ default: |
+ return 0; |
+ } |
+ return 1; |
+} |
+ |
+#endif /* !USE_KERNEL_DISASM */ |
+ |
+ |
+int Decoder::LastPoolReference() { |
+ return last_pool_offset_; |
+} |
+ |
+int Decoder::LastPoolSize() { |
+ return last_pool_size_; |
+} |
+ |
+} } // namespace v8::internal |
+ |
+ |
+//------------------------------------------------------------------------------ |
+ |
+ |
+namespace disasm { |
+ |
+const char* NameConverter::NameOfAddress(byte* addr) const { |
+ v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); |
+ return tmp_buffer_.start(); |
+} |
+ |
+ |
+const char* NameConverter::NameOfConstant(byte* addr) const { |
+ return NameOfAddress(addr); |
+} |
+ |
+ |
+const char* NameConverter::NameOfCPURegister(int reg) const { |
+ return v8::internal::Registers::Name(reg); |
+} |
+ |
+ |
+const char* NameConverter::NameOfByteCPURegister(int reg) const { |
+ UNREACHABLE(); // ARM does not have the concept of a byte register |
+ return "nobytereg"; |
+} |
+ |
+ |
+const char* NameConverter::NameOfXMMRegister(int reg) const { |
+ UNREACHABLE(); // ARM does not have any XMM registers |
+ return "noxmmreg"; |
+} |
+ |
+ |
+const char* NameConverter::NameInCode(byte* addr) const { |
+ // The default name converter is called for unknown code. So we will not try |
+ // to access any memory. |
+ return ""; |
+} |
+ |
+ |
+//------------------------------------------------------------------------------ |
+ |
+Disassembler::Disassembler(const NameConverter& converter) |
+ : converter_(converter) {} |
+ |
+ |
+Disassembler::~Disassembler() {} |
+ |
+ |
+int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, |
+ byte* instruction) { |
+ return 0; |
+} |
+ |
+ |
+ |
+void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { |
+ UNIMPLEMENTED(); |
+} |
+ |
+int Disassembler::ConstantPoolSizeAt(byte* instruction) { |
+ return 0; |
+} |
+ |
+#if 0 |
+class DisassemblerSH4: public DisassemblerInterface { |
+ public: |
+ explicit DisassemblerSH4() : start_pc_(0) { |
+ memset(pools_locs_, 9, sizeof(pools_locs_)); |
+ } |
+ |
+ virtual ~DisassemblerSH4() {} |
+ |
+ virtual int InstructionDecode(v8::internal::Vector<char> buffer, |
+ byte* instruction); |
+ |
+ virtual int ConstantPoolSizeAt(byte* instruction); |
+ |
+ private: |
+ // Management of pool references. |
+ void SetPoolAt(int offset, int size); |
+ void ClearPoolAt(int offset, int size); |
+ int HasPoolAt(int offset, int size); |
+ |
+ uint32_t start_pc_; |
+ static const int pools_locs_count_ = 1024; |
+ uint32_t pools_locs_[pools_locs_count_/sizeof(uint32_t)]; |
+}; |
+ |
+ |
+int DisassemblerSH4::InstructionDecode(v8::internal::Vector<char> buffer, |
+ byte* instruction) { |
+ if (start_pc_ == 0) |
+ start_pc_ = (uint32_t)instruction; |
+ v8::internal::Decoder d(buffer); |
+ int n = d.InstructionDecode(instruction); |
+ int offset = d.LastPoolReference(); |
+ int size = d.LastPoolSize(); |
+ if (offset > 0) |
+ SetPoolAt((uint32_t)instruction - start_pc_ + offset, size); |
+ return n; |
+} |
+ |
+ |
+int DisassemblerSH4::ConstantPoolSizeAt(byte* instruction) { |
+ // Constant pool size is a multiple of 4 from caller point of view, |
+ // we make this a post condition. |
+ // Though SH4 does not support misaligned pools, hence we |
+ // proceed by steps of 2. |
+ int size = 0; |
+ if (start_pc_ == 0) |
+ return -1; |
+ for (int offset = (uint32_t)instruction - start_pc_; |
+ HasPoolAt(offset, 2); |
+ offset += 2) { |
+ size += 2; |
+ ClearPoolAt(offset, 2); |
+ } |
+ ASSERT(size % 4 == 0); |
+ return size/4 - 1; |
+} |
+ |
+ |
+void DisassemblerSH4::SetPoolAt(int offset, int size) { |
+ ASSERT(size >= 1 && size <= 4); |
+ ASSERT(offset/4 == (offset+size-1)/4); |
+ int elt = (offset % pools_locs_count_)/(sizeof(*pools_locs_)*8); |
+ int pos = (offset % pools_locs_count_)%(sizeof(*pools_locs_)*8); |
+ uint32_t mask = ((uint32_t)1<<size)-1; |
+ pools_locs_[elt] |= (mask<<pos); |
+} |
+ |
+ |
+void DisassemblerSH4::ClearPoolAt(int offset, int size) { |
+ ASSERT(size >= 1 && size <= 4); |
+ ASSERT(offset/4 == (offset+size-1)/4); |
+ int elt = (offset % pools_locs_count_)/(sizeof(*pools_locs_)*8); |
+ int pos = (offset % pools_locs_count_)%(sizeof(*pools_locs_)*8); |
+ uint32_t mask = ((uint32_t)1<<size)-1; |
+ pools_locs_[elt] &= ~(mask<<pos); |
+} |
+ |
+ |
+int DisassemblerSH4::HasPoolAt(int offset, int size) { |
+ ASSERT(size >= 1 && size <= 4); |
+ ASSERT(offset/4 == (offset+size-1)/4); |
+ int elt = (offset % pools_locs_count_)/(sizeof(*pools_locs_)*8); |
+ int pos = (offset % pools_locs_count_)%(sizeof(*pools_locs_)*8); |
+ uint32_t mask = ((uint32_t)1<<size)-1; |
+ return (pools_locs_[elt] & (mask<<pos)) == (mask<<pos); |
+} |
+ |
+ |
+void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { |
+ NameConverter converter; |
+ DisassemblerInterface *d = DisassemblerFactory::NewDisassembler(converter); |
+ for (byte* pc = begin; pc < end;) { |
+ v8::internal::EmbeddedVector<char, 128> buffer; |
+ buffer[0] = '\0'; |
+ byte* prev_pc = pc; |
+ pc += d->InstructionDecode(buffer, pc); |
+ v8::internal::OS::FPrint(f, "%p %02x %02x %s\n", |
+ prev_pc, *reinterpret_cast<const uint8_t*>(prev_pc), |
+ *reinterpret_cast<const uint8_t*>(prev_pc+1), buffer.start()); |
+ } |
+ delete d; |
+} |
+ |
+ |
+/*static*/ DisassemblerInterface * |
+DisassemblerFactory::NewDisassembler(const NameConverter& converter) { |
+ return new DisassemblerSH4(); |
+} |
+ |
+#endif |
+} // namespace disasm |
+ |
+#endif // V8_TARGET_ARCH_SH4 |