diff options
author | Julien Brianceau <jbriance@cisco.com> | 2015-06-17 16:39:11 +0200 |
---|---|---|
committer | Julien Brianceau <jbriance@cisco.com> | 2015-06-19 17:01:47 +0000 |
commit | 93c1b8cc6bb7feb922a1cd5d038db6b488745eaa (patch) | |
tree | 025cf1f09d51513ed6076842459d05441d084e65 /src/3rdparty | |
parent | 3df1aae3a522a99fba2a6a22ded01529f9a9c4da (diff) |
V4: add mips32 disassembler.
Add a rudimentary disassembler for mips32 instruction set.
Although few instructions might be missing, the whole set from
MacroAssemblerMIPS should be covered.
Change-Id: I9b1b9b40537b99098ca65036f671651d04fe1ab6
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/3rdparty')
-rw-r--r-- | src/3rdparty/masm/disassembler/Mips32Disassembler.cpp | 56 | ||||
-rw-r--r-- | src/3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp | 620 | ||||
-rw-r--r-- | src/3rdparty/masm/disassembler/mips32/Mips32Opcode.h | 78 | ||||
-rw-r--r-- | src/3rdparty/masm/masm-defs.pri | 1 | ||||
-rw-r--r-- | src/3rdparty/masm/masm.pri | 3 | ||||
-rw-r--r-- | src/3rdparty/masm/wtf/Platform.h | 2 |
6 files changed, 759 insertions, 1 deletions
diff --git a/src/3rdparty/masm/disassembler/Mips32Disassembler.cpp b/src/3rdparty/masm/disassembler/Mips32Disassembler.cpp new file mode 100644 index 0000000000..af0a73b2cb --- /dev/null +++ b/src/3rdparty/masm/disassembler/Mips32Disassembler.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 Cisco Systems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS, INC. ``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 CISCO SYSTEMS, INC. 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 "config.h" +#include "Disassembler.h" + +#if USE(MIPS32_DISASSEMBLER) + +#include "mips32/Mips32Opcode.h" +#include "MacroAssemblerCodeRef.h" + +namespace JSC { + +bool tryToDisassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, PrintStream& out) +{ + Mips32Opcode mipsOpcode; + + uint32_t* currentPC = reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(codePtr.executableAddress()) & ~3); + uint32_t* endPC = currentPC + (size / sizeof(uint32_t)); + + while (currentPC < endPC) { + char pcString[12]; + snprintf(pcString, sizeof(pcString), "0x%x", reinterpret_cast<unsigned>(currentPC)); + out.printf("%s%10s: %s\n", prefix, pcString, mipsOpcode.disassemble(currentPC)); + currentPC++; + } + + return true; +} + +} // namespace JSC + +#endif // USE(MIPS32_DISASSEMBLER) + diff --git a/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp b/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp new file mode 100644 index 0000000000..164217eb55 --- /dev/null +++ b/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.cpp @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2015 Cisco Systems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS, INC. ``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 CISCO SYSTEMS, INC. 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 "config.h" + +#if USE(MIPS32_DISASSEMBLER) + +#include "Mips32Opcode.h" + +#include <stdio.h> + +#define OPCODE_FMT "%s\t" +#define COP1_OPCODE_FMT "%s.%s\t" +#define FORMAT_INSTR(_format, ...) \ + snprintf(m_formatBuffer, bufferSize - 1, _format, ##__VA_ARGS__) + +const char *Mips32Opcode::registerName(uint8_t r) +{ + static const char *gpRegisters[] = { + "zero", "AT", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "kt0", "kt1", "gp", "sp", "s8", "ra" + }; + + return (r < sizeof(gpRegisters)) ? gpRegisters[r] : "invalid"; +} + +const char *Mips32Opcode::fpRegisterName(uint8_t r) +{ + static const char *fpRegisters[] = { + "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", + "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", + "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", + "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" + }; + + return (r < sizeof(fpRegisters)) ? fpRegisters[r] : "invalid"; +} + +void Mips32Opcode::formatSpecialEncodingOpcode(uint8_t op1, uint8_t op2, uint8_t dest, uint8_t shift, uint8_t function) +{ + const char *opcode; + OpcodePrintFormat format = Unknown; + switch (function) { + case 0x00: + format = RdRtSa; + opcode = "sll"; + break; + case 0x02: + format = RdRtSa; + opcode = "srl"; + break; + case 0x03: + format = RdRtSa; + opcode = "sra"; + break; + case 0x04: + format = RdRtRs; + opcode = "sllv"; + break; + case 0x06: + format = RdRtRs; + opcode = "srlv"; + break; + case 0x07: + format = RdRtRs; + opcode = "srav"; + break; + case 0x08: + format = Rs; + opcode = "jr"; + break; + case 0x09: + format = (dest != 0x1f) ? RdRs : Rs; + opcode = "jalr"; + break; + case 0x10: + format = Rd; + opcode = "mfhi"; + break; + case 0x11: + format = Rs; + opcode = "mthi"; + break; + case 0x12: + format = Rd; + opcode = "mflo"; + break; + case 0x13: + format = Rs; + opcode = "mtlo"; + break; + case 0x18: + format = RsRt; + opcode = "mult"; + break; + case 0x19: + format = RsRt; + opcode = "multu"; + break; + case 0x1a: + format = RsRt; + opcode = "div"; + break; + case 0x1b: + format = RsRt; + opcode = "divu"; + break; + case 0x20: + format = RdRsRt; + opcode = "add"; + break; + case 0x21: + if (op2) { + format = RdRsRt; + opcode = "addu"; + } else { + format = RdRs; + opcode = "move"; + } + break; + case 0x22: + format = RdRsRt; + opcode = "sub"; + break; + case 0x23: + format = RdRsRt; + opcode = "subu"; + break; + case 0x24: + format = RdRsRt; + opcode = "and"; + break; + case 0x25: + format = RdRsRt; + opcode = "or"; + break; + case 0x26: + format = RdRsRt; + opcode = "xor"; + break; + case 0x27: + format = RdRsRt; + opcode = "nor"; + break; + case 0x2a: + format = RdRsRt; + opcode = "slt"; + break; + case 0x2b: + format = RdRsRt; + opcode = "sltu"; + break; + } + + switch (format) { + case Rs: + FORMAT_INSTR(OPCODE_FMT "%s", opcode, registerName(op1)); + break; + case Rd: + FORMAT_INSTR(OPCODE_FMT "%s", opcode, registerName(dest)); + break; + case RdRs: + FORMAT_INSTR(OPCODE_FMT "%s, %s", opcode, registerName(dest), registerName(op1)); + break; + case RsRt: + FORMAT_INSTR(OPCODE_FMT "%s, %s", opcode, registerName(op1), registerName(op2)); + break; + case RdRtRs: + FORMAT_INSTR(OPCODE_FMT "%s, %s, %s", opcode, registerName(dest), registerName(op2), registerName(op1)); + break; + case RdRsRt: + FORMAT_INSTR(OPCODE_FMT "%s, %s, %s", opcode, registerName(dest), registerName(op1), registerName(op2)); + break; + case RdRtSa: + FORMAT_INSTR(OPCODE_FMT "%s, %s, %d", opcode, registerName(dest), registerName(op2), shift); + break; + default: + FORMAT_INSTR("unknown special encoding opcode 0x%x", function); + break; + } +} + +void Mips32Opcode::formatSpecial2EncodingOpcode(uint8_t op1, uint8_t op2, uint8_t dest, uint8_t function) +{ + if (function == 0x02) { + FORMAT_INSTR(OPCODE_FMT "%s, %s, %s", "mul", registerName(dest), registerName(op1), registerName(op2)); + return; + } + + FORMAT_INSTR("unknown special2 encoding opcode 0x%x", function); +} + +void Mips32Opcode::formatJumpEncodingOpcode(uint32_t iOp, uint32_t index, uint32_t* opcodePtr) +{ + if ((iOp != 0x02) && (iOp != 0x03)) { + FORMAT_INSTR("unknown jump encoding opcode 0x%x", iOp); + return; + } + + FORMAT_INSTR(OPCODE_FMT "0x%x", (iOp == 0x02) ? "j" : "jal", + (reinterpret_cast<unsigned>(opcodePtr+1) & 0xf0000000) | (index << 2)); +} + +void Mips32Opcode::formatREGIMMEncodingOpcode(uint8_t rs, uint8_t rt, int16_t imm, uint32_t* opcodePtr) +{ + const char *opcodes[] = { "bltz", "bgez", "bltzl", "bgezl" }; + if (rt < sizeof(opcodes)) + FORMAT_INSTR(OPCODE_FMT "%s, 0x%x", opcodes[rt], registerName(rs), reinterpret_cast<unsigned>(opcodePtr+1) + (imm << 2)); + else + FORMAT_INSTR("unknown REGIMM encoding opcode 0x%x", rt); +} + +void Mips32Opcode::formatImmediateEncodingOpcode(uint32_t iOp, uint8_t rs, uint8_t rt, int16_t imm, uint32_t* opcodePtr) +{ + const char *opcode; + OpcodePrintFormat format = Unknown; + switch (iOp) { + case 0x04: + if (!rs && !rt) { + format = Addr; + opcode = "b"; + } else { + format = RsRtAddr; + opcode = "beq"; + } + break; + case 0x05: + format = RsRtAddr; + opcode = "bne"; + break; + case 0x06: + format = RsRtAddr; + opcode = "blez"; + break; + case 0x07: + format = RsRtAddr; + opcode = "bgtz"; + break; + case 0x08: + format = RtRsImm; + opcode = "addi"; + break; + case 0x09: + if (rs) { + format = RtRsImm; + opcode = "addiu"; + } else { + format = RtUImm; + opcode = "li"; + } + break; + case 0x0a: + format = RtRsImm; + opcode = "slti"; + break; + case 0x0b: + format = RtRsImm; + opcode = "sltiu"; + break; + case 0x0c: + format = RtRsImm; + opcode = "andi"; + break; + case 0x0d: + format = RtRsImm; + opcode = "ori"; + break; + case 0x0e: + format = RtRsImm; + opcode = "xori"; + break; + case 0x0f: + format = RtUImm; + opcode = "lui"; + break; + case 0x20: + format = RtOffsetBase; + opcode = "lb"; + break; + case 0x21: + format = RtOffsetBase; + opcode = "lh"; + break; + case 0x22: + format = RtOffsetBase; + opcode = "lwl"; + break; + case 0x23: + format = RtOffsetBase; + opcode = "lw"; + break; + case 0x24: + format = RtOffsetBase; + opcode = "lbu"; + break; + case 0x25: + format = RtOffsetBase; + opcode = "lhu"; + break; + case 0x26: + format = RtOffsetBase; + opcode = "lwr"; + break; + case 0x28: + format = RtOffsetBase; + opcode = "sb"; + break; + case 0x29: + format = RtOffsetBase; + opcode = "sh"; + break; + case 0x2a: + format = RtOffsetBase; + opcode = "swl"; + break; + case 0x2b: + format = RtOffsetBase; + opcode = "sw"; + break; + case 0x2e: + format = RtOffsetBase; + opcode = "swr"; + break; + case 0x35: + format = FtOffsetBase; + opcode = "ldc1"; + break; + case 0x3d: + format = FtOffsetBase; + opcode = "sdc1"; + break; + } + + switch (format) { + case Addr: + FORMAT_INSTR(OPCODE_FMT "0x%x", opcode, reinterpret_cast<unsigned>(opcodePtr+1) + (imm << 2)); + break; + case RtUImm: + FORMAT_INSTR(OPCODE_FMT "%s, 0x%hx", opcode, registerName(rt), imm); + break; + case RtRsImm: + FORMAT_INSTR(OPCODE_FMT "%s, %s, %d", opcode, registerName(rt), registerName(rs), imm); + break; + case RsRtAddr: + FORMAT_INSTR(OPCODE_FMT "%s, %s, 0x%x", opcode, registerName(rs), registerName(rt), + reinterpret_cast<unsigned>(opcodePtr+1) + (imm << 2)); + break; + case RtOffsetBase: + FORMAT_INSTR(OPCODE_FMT "%s, %d(%s)", opcode, registerName(rt), imm, registerName(rs)); + break; + case FtOffsetBase: + FORMAT_INSTR(OPCODE_FMT "%s, %d(%s)", opcode, fpRegisterName(rt), imm, registerName(rs)); + break; + default: + FORMAT_INSTR("unknown immediate encoding opcode 0x%x", iOp); + break; + } +} + +void Mips32Opcode::formatCOP1Opcode(uint8_t fmt, uint8_t ft, uint8_t fs, uint8_t fd, uint8_t func) +{ + const char *opcode; + const char *suffix; + OpcodePrintFormat format = Unknown; + + if (fmt < 0x10) { + switch (fmt) { + case 0x00: + opcode = "mfc1"; + break; + case 0x04: + opcode = "mtc1"; + break; + default: + FORMAT_INSTR("unknown COP1 rs 0x%x", fmt); + return; + } + FORMAT_INSTR(OPCODE_FMT "%s, %s", opcode, registerName(ft), fpRegisterName(fs)); + return; + } + + switch (fmt) { + case 0x10: + suffix = "s"; + break; + case 0x11: + suffix = "d"; + break; + case 0x14: + suffix = "w"; + break; + case 0x15: + suffix = "l"; + break; + case 0x16: + suffix = "ps"; + break; + default: + FORMAT_INSTR("unknown COP1 fmt 0x%x", fmt); + return; + } + + switch (func) { + case 0x00: + format = FdFsFt; + opcode = "add"; + break; + case 0x01: + format = FdFsFt; + opcode = "sub"; + break; + case 0x02: + format = FdFsFt; + opcode = "mul"; + break; + case 0x03: + format = FdFsFt; + opcode = "div"; + break; + case 0x04: + format = FdFs; + opcode = "sqrt"; + break; + case 0x05: + format = FdFs; + opcode = "abs"; + break; + case 0x06: + format = FdFs; + opcode = "mov"; + break; + case 0x07: + format = FdFs; + opcode = "neg"; + break; + case 0x08: + format = FdFs; + opcode = "round.l"; + break; + case 0x09: + format = FdFs; + opcode = "trunc.l"; + break; + case 0x0a: + format = FdFs; + opcode = "ceil.l"; + break; + case 0x0b: + format = FdFs; + opcode = "floor.l"; + break; + case 0x0c: + format = FdFs; + opcode = "round.w"; + break; + case 0x0d: + format = FdFs; + opcode = "trunc.w"; + break; + case 0x0e: + format = FdFs; + opcode = "ceil.w"; + break; + case 0x0f: + format = FdFs; + opcode = "floor.w"; + break; + case 0x20: + format = FdFs; + opcode = "cvt.s"; + break; + case 0x21: + format = FdFs; + opcode = "cvt.d"; + break; + case 0x24: + format = FdFs; + opcode = "cvt.w"; + break; + case 0x25: + format = FdFs; + opcode = "cvt.l"; + break; + } + + switch (format) { + case FdFs: + FORMAT_INSTR(COP1_OPCODE_FMT "%s, %s", opcode, suffix, fpRegisterName(fd), fpRegisterName(fs)); + break; + case FdFsFt: + FORMAT_INSTR(COP1_OPCODE_FMT "%s, %s, %s", opcode, suffix, fpRegisterName(fd), fpRegisterName(fs), fpRegisterName(ft)); + break; + default: + FORMAT_INSTR("unknown COP1 opcode 0x%x", func); + break; + } +} + +void Mips32Opcode::formatCOP1FPCompareOpcode(uint8_t fmt, uint8_t ft, uint8_t fs, uint8_t cc, uint8_t cond) +{ + const char *suffix; + static const char *opcodes[] = { + "c.f", "c.un", "c.eq", "c.ueq", "c.olt", "c.ult", "c.ole", "c.ule", + "c.sf", "c.ngle", "c.seq", "c.ngl", "c.lt", "c.nge", "c.le", "c.ngt" + }; + ASSERT(cond < sizeof(opcdoes)); + + switch (fmt) { + case 0x10: + suffix = "s"; + break; + case 0x11: + suffix = "d"; + break; + case 0x16: + suffix = "ps"; + break; + default: + FORMAT_INSTR("unknown COP1 fmt 0x%x", fmt); + return; + } + + if (!cc) + FORMAT_INSTR(COP1_OPCODE_FMT "%s, %s", opcodes[cond], suffix, fpRegisterName(fs), fpRegisterName(ft)); + else + FORMAT_INSTR(COP1_OPCODE_FMT "%d, %s, %s", opcodes[cond], suffix, cc, fpRegisterName(fs), fpRegisterName(ft)); +} + +void Mips32Opcode::formatCOP1BCOpcode(uint8_t cc, uint8_t ndtf, int16_t offset, uint32_t* opcodePtr) +{ + static const char *opcodes[] = { "bc1f", "bc1t", "bc1fl", "bc1tl" }; + ASSERT(ndtf < sizeof(opcodes)); + + if (!cc) + FORMAT_INSTR(OPCODE_FMT "0x%x", opcodes[ndtf], reinterpret_cast<unsigned>(opcodePtr+1) + (offset << 2)); + else + FORMAT_INSTR(OPCODE_FMT "%d, 0x%x", opcodes[ndtf], cc, reinterpret_cast<unsigned>(opcodePtr+1) + (offset << 2)); +} + +const char* Mips32Opcode::disassemble(uint32_t* opcodePtr) +{ + uint32_t opcode = *opcodePtr; + uint32_t iOp = (opcode >> 26) & 0x3f; + + if (!opcode) + FORMAT_INSTR(OPCODE_FMT, "nop"); + else if (!iOp) { + uint8_t op1 = (opcode >> 21) & 0x1f; + uint8_t op2 = (opcode >> 16) & 0x1f; + uint8_t dst = (opcode >> 11) & 0x1f; + uint8_t shft = (opcode >> 6) & 0x1f; + uint8_t func = opcode & 0x3f; + formatSpecialEncodingOpcode(op1, op2, dst, shft, func); + } else if ((iOp == 0x02) || (iOp == 0x03)) { + uint32_t index = opcode & 0x3ffffff; + formatJumpEncodingOpcode(iOp, index, opcodePtr); + } else if (iOp == 0x11) { + uint8_t fmt = (opcode >> 21) & 0x1f; + if (fmt == 0x08) { + uint8_t cc = (opcode >> 18) & 0x07; + uint8_t ndtf = (opcode >> 16) & 0x03; + int16_t offset = opcode & 0xffff; + formatCOP1BCOpcode(cc, ndtf, offset, opcodePtr); + } else if ((opcode & 0xf0) == 0x30) { + uint8_t ft = (opcode >> 16) & 0x1f; + uint8_t fs = (opcode >> 11) & 0x1f; + uint8_t cc = (opcode >> 8) & 0x07; + uint8_t cond = opcode & 0x0f; + formatCOP1FPCompareOpcode(fmt, ft, fs, cc, cond); + } else { + uint8_t ft = (opcode >> 16) & 0x1f; + uint8_t fs = (opcode >> 11) & 0x1f; + uint8_t fd = (opcode >> 6) & 0x1f; + uint8_t func = opcode & 0x3f; + formatCOP1Opcode(fmt, ft, fs, fd, func); + } + } else if (iOp == 0x1c) { + uint8_t op1 = (opcode >> 21) & 0x1f; + uint8_t op2 = (opcode >> 16) & 0x1f; + uint8_t dst = (opcode >> 11) & 0x1f; + uint8_t func = opcode & 0x3f; + formatSpecial2EncodingOpcode(op1, op2, dst, func); + } else { + uint8_t rs = (opcode >> 21) & 0x1f; + uint8_t rt = (opcode >> 16) & 0x1f; + int16_t imm = opcode & 0xffff; + if (iOp == 0x01) + formatREGIMMEncodingOpcode(rs, rt, imm, opcodePtr); + else + formatImmediateEncodingOpcode(iOp, rs, rt, imm, opcodePtr); + } + + return m_formatBuffer; +} + +#endif // USE(MIPS32_DISASSEMBLER) diff --git a/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.h b/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.h new file mode 100644 index 0000000000..c63fb1109a --- /dev/null +++ b/src/3rdparty/masm/disassembler/mips32/Mips32Opcode.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Cisco Systems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS, INC. ``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 CISCO SYSTEMS, INC. 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. + */ + +#ifndef _MIPS32Opcode_h_ +#define _MIPS32Opcode_h_ + +#if USE(MIPS32_DISASSEMBLER) + +#include <stdint.h> +#include <wtf/Assertions.h> + +class Mips32Opcode { +public: + Mips32Opcode() {} + + const char* disassemble(uint32_t*); + +private: + enum OpcodePrintFormat { + Unknown = 0, + Rs, + Rd, + Addr, + RdRs, + RsRt, + RtUImm, + RdRtRs, + RdRsRt, + RdRtSa, + RtRsImm, + RsRtAddr, + RtOffsetBase, + FdFs, + FdFsFt, + FtOffsetBase + }; + + const char *registerName(uint8_t r); + const char *fpRegisterName(uint8_t r); + void formatSpecialEncodingOpcode(uint8_t op1, uint8_t op2, uint8_t dest, uint8_t shift, uint8_t function); + void formatSpecial2EncodingOpcode(uint8_t op1, uint8_t op2, uint8_t dest, uint8_t function); + void formatJumpEncodingOpcode(uint32_t iOp, uint32_t index, uint32_t* opcodePtr); + void formatREGIMMEncodingOpcode(uint8_t rs, uint8_t rt, int16_t imm, uint32_t* opcodePtr); + void formatImmediateEncodingOpcode(uint32_t iOp, uint8_t rs, uint8_t rt, int16_t imm, uint32_t* opcodePtr); + void formatCOP1Opcode(uint8_t fmt, uint8_t ft, uint8_t fs, uint8_t fd, uint8_t func); + void formatCOP1FPCompareOpcode(uint8_t fmt, uint8_t ft, uint8_t fs, uint8_t cc, uint8_t cond); + void formatCOP1BCOpcode(uint8_t cc, uint8_t ndtf, int16_t offset, uint32_t* opcodePtr); + + static const int bufferSize = 81; + + char m_formatBuffer[bufferSize]; +}; + +#endif + +#endif // _MIPS32Opcode_h_ diff --git a/src/3rdparty/masm/masm-defs.pri b/src/3rdparty/masm/masm-defs.pri index d0980c5312..f09a8329c9 100644 --- a/src/3rdparty/masm/masm-defs.pri +++ b/src/3rdparty/masm/masm-defs.pri @@ -26,6 +26,7 @@ INCLUDEPATH += $$PWD disassembler { if(isEqual(QT_ARCH, "i386")|isEqual(QT_ARCH, "x86_64")): DEFINES += WTF_USE_UDIS86=1 if(isEqual(QT_ARCH, "arm")): DEFINES += WTF_USE_ARMV7_DISASSEMBLER=1 + if(isEqual(QT_ARCH, "mips")): DEFINES += WTF_USE_MIPS32_DISASSEMBLER=1 } else { DEFINES += WTF_USE_UDIS86=0 } diff --git a/src/3rdparty/masm/masm.pri b/src/3rdparty/masm/masm.pri index 3497650f0c..04548fe8a3 100644 --- a/src/3rdparty/masm/masm.pri +++ b/src/3rdparty/masm/masm.pri @@ -59,6 +59,9 @@ contains(DEFINES, WTF_USE_UDIS86=1) { SOURCES += $$PWD/disassembler/ARMv7Disassembler.cpp SOURCES += $$PWD/disassembler/ARMv7/ARMv7DOpcode.cpp HEADERS += $$PWD/disassembler/ARMv7/ARMv7DOpcode.h +SOURCES += $$PWD/disassembler/Mips32Disassembler.cpp +SOURCES += $$PWD/disassembler/mips32/Mips32Opcode.cpp +HEADERS += $$PWD/disassembler/mips32/Mips32Opcode.h SOURCES += $$PWD/yarr/*.cpp HEADERS += $$PWD/yarr/*.h diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h index 3e2a51379c..f0612fe50e 100644 --- a/src/3rdparty/masm/wtf/Platform.h +++ b/src/3rdparty/masm/wtf/Platform.h @@ -735,7 +735,7 @@ #define WTF_USE_UDIS86 1 #endif -#if !defined(ENABLE_DISASSEMBLER) && (USE(UDIS86) || USE(ARMV7_DISASSEMBLER)) +#if !defined(ENABLE_DISASSEMBLER) && (USE(UDIS86) || USE(ARMV7_DISASSEMBLER) || USE(MIPS32_DISASSEMBLER)) #define ENABLE_DISASSEMBLER 1 #endif |