15d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 25ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without 35ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met: 55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions of source code must retain the above copyright 75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// notice, this list of conditions and the following disclaimer. 85ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions in binary form must reproduce the above 95ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// copyright notice, this list of conditions and the following 105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// disclaimer in the documentation and/or other materials provided 115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// with the distribution. 125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// contributors may be used to endorse or promote products derived 145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// from this software without specific prior written permission. 155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 2868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#include <assert.h> 2968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#include <stdio.h> 3068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org#include <stdarg.h> 3168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 32b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#include "v8.h" 339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 36b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org#include "disasm.h" 371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#include "lazy-instance.h" 38b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 39b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgnamespace disasm { 40b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 41e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgenum OperandType { 42e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UNSET_OP_ORDER = 0, 43e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Operand size decides between 16, 32 and 64 bit operands. 44e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org REG_OPER_OP_ORDER = 1, // Register destination, operand source. 45e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OPER_REG_OP_ORDER = 2, // Operand destination, register source. 46e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Fixed 8-bit operands. 47e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org BYTE_SIZE_OPERAND_FLAG = 4, 48e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org BYTE_REG_OPER_OP_ORDER = REG_OPER_OP_ORDER | BYTE_SIZE_OPERAND_FLAG, 49e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org BYTE_OPER_REG_OP_ORDER = OPER_REG_OP_ORDER | BYTE_SIZE_OPERAND_FLAG 5068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 5168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 52e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 5368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org//------------------------------------------------------------------ 5468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Tables 5568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org//------------------------------------------------------------------ 5668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstruct ByteMnemonic { 5768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int b; // -1 terminates, otherwise must be in range (0..255) 58e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandType op_order_; 5968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem; 6068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 6168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 6268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 637c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic two_operands_instr[] = { 64e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x00, BYTE_OPER_REG_OP_ORDER, "add" }, 65e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x01, OPER_REG_OP_ORDER, "add" }, 66e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x02, BYTE_REG_OPER_OP_ORDER, "add" }, 67e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x03, REG_OPER_OP_ORDER, "add" }, 68e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x08, BYTE_OPER_REG_OP_ORDER, "or" }, 69e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x09, OPER_REG_OP_ORDER, "or" }, 70e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x0A, BYTE_REG_OPER_OP_ORDER, "or" }, 71e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x0B, REG_OPER_OP_ORDER, "or" }, 72e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x10, BYTE_OPER_REG_OP_ORDER, "adc" }, 73e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x11, OPER_REG_OP_ORDER, "adc" }, 74e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x12, BYTE_REG_OPER_OP_ORDER, "adc" }, 75e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x13, REG_OPER_OP_ORDER, "adc" }, 76e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x18, BYTE_OPER_REG_OP_ORDER, "sbb" }, 77e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x19, OPER_REG_OP_ORDER, "sbb" }, 78e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x1A, BYTE_REG_OPER_OP_ORDER, "sbb" }, 79e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x1B, REG_OPER_OP_ORDER, "sbb" }, 80e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x20, BYTE_OPER_REG_OP_ORDER, "and" }, 81e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x21, OPER_REG_OP_ORDER, "and" }, 82e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x22, BYTE_REG_OPER_OP_ORDER, "and" }, 83e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x23, REG_OPER_OP_ORDER, "and" }, 84e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x28, BYTE_OPER_REG_OP_ORDER, "sub" }, 85e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x29, OPER_REG_OP_ORDER, "sub" }, 86e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x2A, BYTE_REG_OPER_OP_ORDER, "sub" }, 87e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x2B, REG_OPER_OP_ORDER, "sub" }, 88e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x30, BYTE_OPER_REG_OP_ORDER, "xor" }, 89e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x31, OPER_REG_OP_ORDER, "xor" }, 90e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x32, BYTE_REG_OPER_OP_ORDER, "xor" }, 91e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x33, REG_OPER_OP_ORDER, "xor" }, 92e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x38, BYTE_OPER_REG_OP_ORDER, "cmp" }, 93e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x39, OPER_REG_OP_ORDER, "cmp" }, 94e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x3A, BYTE_REG_OPER_OP_ORDER, "cmp" }, 95e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x3B, REG_OPER_OP_ORDER, "cmp" }, 96528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org { 0x63, REG_OPER_OP_ORDER, "movsxl" }, 97e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x84, BYTE_REG_OPER_OP_ORDER, "test" }, 98e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x85, REG_OPER_OP_ORDER, "test" }, 99e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x86, BYTE_REG_OPER_OP_ORDER, "xchg" }, 100e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x87, REG_OPER_OP_ORDER, "xchg" }, 101e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x88, BYTE_OPER_REG_OP_ORDER, "mov" }, 102e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x89, OPER_REG_OP_ORDER, "mov" }, 103e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x8A, BYTE_REG_OPER_OP_ORDER, "mov" }, 104e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x8B, REG_OPER_OP_ORDER, "mov" }, 105b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org { 0x8D, REG_OPER_OP_ORDER, "lea" }, 10668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { -1, UNSET_OP_ORDER, "" } 10768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 10868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 10968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1107c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic zero_operands_instr[] = { 11168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xC3, UNSET_OP_ORDER, "ret" }, 11268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xC9, UNSET_OP_ORDER, "leave" }, 11368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xF4, UNSET_OP_ORDER, "hlt" }, 11464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org { 0xFC, UNSET_OP_ORDER, "cld" }, 11568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xCC, UNSET_OP_ORDER, "int3" }, 11668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x60, UNSET_OP_ORDER, "pushad" }, 11768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x61, UNSET_OP_ORDER, "popad" }, 11868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x9C, UNSET_OP_ORDER, "pushfd" }, 11968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x9D, UNSET_OP_ORDER, "popfd" }, 12068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x9E, UNSET_OP_ORDER, "sahf" }, 12168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x99, UNSET_OP_ORDER, "cdq" }, 12268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x9B, UNSET_OP_ORDER, "fwait" }, 123b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 0xA4, UNSET_OP_ORDER, "movs" }, 124b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 0xA5, UNSET_OP_ORDER, "movs" }, 125b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 0xA6, UNSET_OP_ORDER, "cmps" }, 126b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org { 0xA7, UNSET_OP_ORDER, "cmps" }, 12768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { -1, UNSET_OP_ORDER, "" } 12868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 12968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 13068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1317c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic call_jump_instr[] = { 13268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xE8, UNSET_OP_ORDER, "call" }, 13368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0xE9, UNSET_OP_ORDER, "jmp" }, 13468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { -1, UNSET_OP_ORDER, "" } 13568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 13668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 13768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1387c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic short_immediate_instr[] = { 13968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x05, UNSET_OP_ORDER, "add" }, 14068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x0D, UNSET_OP_ORDER, "or" }, 14168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x15, UNSET_OP_ORDER, "adc" }, 142e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org { 0x1D, UNSET_OP_ORDER, "sbb" }, 14368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x25, UNSET_OP_ORDER, "and" }, 14468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x2D, UNSET_OP_ORDER, "sub" }, 14568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x35, UNSET_OP_ORDER, "xor" }, 14668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 0x3D, UNSET_OP_ORDER, "cmp" }, 14768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { -1, UNSET_OP_ORDER, "" } 14868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 14968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 15068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1517c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const char* const conditional_code_suffix[] = { 152b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org "o", "no", "c", "nc", "z", "nz", "na", "a", 15368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "s", "ns", "pe", "po", "l", "ge", "le", "g" 15468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 15568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 15668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 15768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgenum InstructionType { 15868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NO_INSTR, 15968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org ZERO_OPERANDS_INSTR, 16068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org TWO_OPERANDS_INSTR, 16168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org JUMP_CONDITIONAL_SHORT_INSTR, 16268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org REGISTER_INSTR, 16368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org PUSHPOP_INSTR, // Has implicit 64-bit operand size. 16468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org MOVE_REG_INSTR, 16568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CALL_JUMP_INSTR, 16668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org SHORT_IMMEDIATE_INSTR 16768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 16868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 16968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 170b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgenum Prefixes { 171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ESCAPE_PREFIX = 0x0F, 172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org OPERAND_SIZE_OVERRIDE_PREFIX = 0x66, 173b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67, 174b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org REPNE_PREFIX = 0xF2, 175b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org REP_PREFIX = 0xF3, 176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org REPEQ_PREFIX = REP_PREFIX 177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 178b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 179b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 18068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstruct InstructionDesc { 18168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem; 18268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionType type; 183e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandType op_order_; 184e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool byte_size_operation; // Fixed 8-bit operation. 18568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 18668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 18768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 18868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgclass InstructionTable { 18968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org public: 19068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionTable(); 19168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const InstructionDesc& Get(byte x) const { 19268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return instructions_[x]; 19368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 19468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 19568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org private: 19668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionDesc instructions_[256]; 19768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void Clear(); 19868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void Init(); 1997c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org void CopyTable(const ByteMnemonic bm[], InstructionType type); 200e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org void SetTableRange(InstructionType type, byte start, byte end, bool byte_size, 20168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem); 20268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void AddJumpConditionalShort(); 20368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 20468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 20568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 20668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgInstructionTable::InstructionTable() { 20768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org Clear(); 20868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org Init(); 20968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 21068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 21168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 21268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgvoid InstructionTable::Clear() { 21368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (int i = 0; i < 256; i++) { 214e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org instructions_[i].mnem = "(bad)"; 21568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org instructions_[i].type = NO_INSTR; 21668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org instructions_[i].op_order_ = UNSET_OP_ORDER; 217e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org instructions_[i].byte_size_operation = false; 21868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 21968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 22068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 22168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 22268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgvoid InstructionTable::Init() { 22368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); 22468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); 22568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CopyTable(call_jump_instr, CALL_JUMP_INSTR); 22668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); 22768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AddJumpConditionalShort(); 228e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, false, "push"); 229e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, false, "pop"); 230e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, false, "mov"); 23168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 23268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 23368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 2347c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgvoid InstructionTable::CopyTable(const ByteMnemonic bm[], 2357c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org InstructionType type) { 23668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (int i = 0; bm[i].b >= 0; i++) { 23768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionDesc* id = &instructions_[bm[i].b]; 23868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->mnem = bm[i].mnem; 239e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandType op_order = bm[i].op_order_; 240e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org id->op_order_ = 241e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org static_cast<OperandType>(op_order & ~BYTE_SIZE_OPERAND_FLAG); 2423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered 24368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->type = type; 244e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0); 24568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 24668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 24768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 24868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 249e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid InstructionTable::SetTableRange(InstructionType type, 250e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte start, 251e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte end, 252e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool byte_size, 253e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const char* mnem) { 25468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (byte b = start; b <= end; b++) { 25568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionDesc* id = &instructions_[b]; 2563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered 25768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->mnem = mnem; 25868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->type = type; 259e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org id->byte_size_operation = byte_size; 26068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 26168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 26268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 26368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 26468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgvoid InstructionTable::AddJumpConditionalShort() { 26568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (byte b = 0x70; b <= 0x7F; b++) { 26668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org InstructionDesc* id = &instructions_[b]; 2673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered 26868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->mnem = NULL; // Computed depending on condition code. 26968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org id->type = JUMP_CONDITIONAL_SHORT_INSTR; 27068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 27168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 27268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 27368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 2741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic v8::internal::LazyInstance<InstructionTable>::type instruction_table = 2751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org LAZY_INSTANCE_INITIALIZER; 27668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 277ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 278b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.orgstatic InstructionDesc cmov_instructions[16] = { 279b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 280b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 281b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 282b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovnc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 283b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 284b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovnz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 285b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovna", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 286b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmova", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 287b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovs", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 288b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovns", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 289b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovpe", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 290b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovpo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 291b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovl", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 292b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovge", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 293b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}, 294b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org {"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false} 295b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org}; 29668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 297e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 298e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org//------------------------------------------------------------------------------ 299e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// DisassemblerX64 implementation. 300e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 30168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgenum UnimplementedOpcodeAction { 30268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org CONTINUE_ON_UNIMPLEMENTED_OPCODE, 30368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org ABORT_ON_UNIMPLEMENTED_OPCODE 30468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 30568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 306e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 307e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// A new DisassemblerX64 object is created to disassemble each instruction. 308e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// The object can only disassemble a single instruction. 30968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgclass DisassemblerX64 { 31068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org public: 31168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org DisassemblerX64(const NameConverter& converter, 31268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedOpcodeAction unimplemented_action = 31368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org ABORT_ON_UNIMPLEMENTED_OPCODE) 31468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org : converter_(converter), 31568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_pos_(0), 31668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org abort_on_unimplemented_( 31768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE), 31868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org rex_(0), 319e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org operand_size_(0), 320e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org group_1_prefix_(0), 3217d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org byte_size_operand_(false), 3227d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org instruction_table_(instruction_table.Pointer()) { 32368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_[0] = '\0'; 32468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 32568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 32668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org virtual ~DisassemblerX64() { 32768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 32868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 32968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Writes one disassembled instruction into 'buffer' (0-terminated). 33068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Returns the length of the disassembled machine instruction in bytes. 33168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); 33268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 33368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org private: 334e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org enum OperandSize { 335e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org OPERAND_BYTE_SIZE = 0, 336e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org OPERAND_WORD_SIZE = 1, 337e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org OPERAND_DOUBLEWORD_SIZE = 2, 338e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org OPERAND_QUADWORD_SIZE = 3 339e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org }; 34068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 34168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const NameConverter& converter_; 34268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org v8::internal::EmbeddedVector<char, 128> tmp_buffer_; 34368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org unsigned int tmp_buffer_pos_; 34468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool abort_on_unimplemented_; 34568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Prefixes parsed 34668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte rex_; 347e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte operand_size_; // 0x66 or (if no group 3 prefix is present) 0x0. 348e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0. 349e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Byte size operand override. 350e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool byte_size_operand_; 3517d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org const InstructionTable* const instruction_table_; 35268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 35368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void setRex(byte rex) { 35468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org ASSERT_EQ(0x40, rex & 0xF0); 35568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org rex_ = rex; 35668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 35768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 35868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool rex() { return rex_ != 0; } 35968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 36068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool rex_b() { return (rex_ & 0x01) != 0; } 36168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 36268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Actual number of base register given the low bits and the rex.b state. 36368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int base_reg(int low_bits) { return low_bits | ((rex_ & 0x01) << 3); } 36468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 36568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool rex_x() { return (rex_ & 0x02) != 0; } 36668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 36768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool rex_r() { return (rex_ & 0x04) != 0; } 36868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 36968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool rex_w() { return (rex_ & 0x08) != 0; } 37068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 371e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandSize operand_size() { 372e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org if (byte_size_operand_) return OPERAND_BYTE_SIZE; 373e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org if (rex_w()) return OPERAND_QUADWORD_SIZE; 374e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org if (operand_size_ != 0) return OPERAND_WORD_SIZE; 375e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org return OPERAND_DOUBLEWORD_SIZE; 37668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 37768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 37868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org char operand_size_code() { 379e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "bwlq"[operand_size()]; 38068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 38168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 38268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* NameOfCPURegister(int reg) const { 38368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return converter_.NameOfCPURegister(reg); 38468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 38568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 38668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* NameOfByteCPURegister(int reg) const { 38768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return converter_.NameOfByteCPURegister(reg); 38868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 38968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 39068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* NameOfXMMRegister(int reg) const { 39168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return converter_.NameOfXMMRegister(reg); 39268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 39368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 39468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* NameOfAddress(byte* addr) const { 39568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return converter_.NameOfAddress(addr); 39668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 39768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 39868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Disassembler helper functions. 39968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void get_modrm(byte data, 40068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* mod, 40168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* regop, 40268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* rm) { 40368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org *mod = (data >> 6) & 3; 40468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org *regop = ((data & 0x38) >> 3) | (rex_r() ? 8 : 0); 40568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org *rm = (data & 7) | (rex_b() ? 8 : 0); 40668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 40768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 40868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void get_sib(byte data, 40968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* scale, 41068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* index, 41168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int* base) { 41268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org *scale = (data >> 6) & 3; 41368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org *index = ((data >> 3) & 7) | (rex_x() ? 8 : 0); 414e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org *base = (data & 7) | (rex_b() ? 8 : 0); 41568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 41668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 41768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; 41868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 41968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int PrintRightOperandHelper(byte* modrmp, 42068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org RegisterNameMapping register_name); 42168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int PrintRightOperand(byte* modrmp); 42268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int PrintRightByteOperand(byte* modrmp); 4233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int PrintRightXMMOperand(byte* modrmp); 42468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int PrintOperands(const char* mnem, 425e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandType op_order, 42668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* data); 427e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int PrintImmediate(byte* data, OperandSize size); 42868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int PrintImmediateOp(byte* data); 429e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const char* TwoByteMnemonic(byte opcode); 430e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int TwoByteOpcodeInstruction(byte* data); 4313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int F6F7Instruction(byte* data); 432e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int ShiftInstruction(byte* data); 43368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int JumpShort(byte* data); 43468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int JumpConditional(byte* data); 43568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int JumpConditionalShort(byte* data); 43668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int SetCC(byte* data); 43768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int FPUInstruction(byte* data); 4383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); 4393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); 44068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void AppendToBuffer(const char* format, ...); 44168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 44268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org void UnimplementedInstruction() { 44368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (abort_on_unimplemented_) { 444e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org CHECK(false); 44568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 44668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("'Unimplemented Instruction'"); 44768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 44868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 44968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 45068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 45168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 45268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgvoid DisassemblerX64::AppendToBuffer(const char* format, ...) { 45368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_; 45468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org va_list args; 45568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org va_start(args, format); 45668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int result = v8::internal::OS::VSNPrintF(buf, format, args); 45768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org va_end(args); 45868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_pos_ += result; 45968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 46068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 46168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 46268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::PrintRightOperandHelper( 46368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* modrmp, 464badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org RegisterNameMapping direct_register_name) { 46568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 46668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*modrmp, &mod, ®op, &rm); 467badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org RegisterNameMapping register_name = (mod == 3) ? direct_register_name : 468badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org &DisassemblerX64::NameOfCPURegister; 46968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (mod) { 47068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0: 47168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if ((rm & 7) == 5) { 47268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); 47368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("[0x%x]", disp); 47468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 5; 47568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else if ((rm & 7) == 4) { 47668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Codes for SIB byte. 47768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte sib = *(modrmp + 1); 47868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int scale, index, base; 47968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_sib(sib, &scale, &index, &base); 48068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { 48168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // index == rsp means no index. Only use sib byte with no index for 48268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // rsp and r12 base. 48332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s]", NameOfCPURegister(base)); 48468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 48568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else if (base == 5) { 48668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // base == rbp means no base register (when mod == 0). 48768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); 48868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("[%s*%d+0x%x]", 48932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(index), 49068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1 << scale, disp); 49168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 6; 49268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else if (index != 4 && base != 5) { 49368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // [base+index*scale] 49468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("[%s+%s*%d]", 49532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(base), 49632d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(index), 49768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1 << scale); 49868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 49968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 50068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 50168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 1; 50268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 50368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 50432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s]", NameOfCPURegister(rm)); 50568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 1; 50668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 50768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 50868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 1: // fall through 50968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 2: 51068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if ((rm & 7) == 4) { 51168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte sib = *(modrmp + 1); 51268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int scale, index, base; 51368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_sib(sib, &scale, &index, &base); 51468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) 51568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org : *reinterpret_cast<char*>(modrmp + 2); 51668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { 51768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (-disp > 0) { 51832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp); 51968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 52032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp); 52168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 52268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 52368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (-disp > 0) { 52468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("[%s+%s*%d-0x%x]", 52532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(base), 52632d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(index), 52768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1 << scale, 52868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org -disp); 52968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 53068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("[%s+%s*%d+0x%x]", 53132d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(base), 53232d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org NameOfCPURegister(index), 53368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1 << scale, 53468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org disp); 53568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 53668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 53768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return mod == 2 ? 6 : 3; 53868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 53968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // No sib. 54068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) 54168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org : *reinterpret_cast<char*>(modrmp + 1); 54268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (-disp > 0) { 54332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp); 54468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 54532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp); 54668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 54768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return (mod == 2) ? 5 : 2; 54868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 54968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 55068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 3: 55168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s", (this->*register_name)(rm)); 55268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 1; 55368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 55468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 55568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 1; 55668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 55768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UNREACHABLE(); 55868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 55968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 56068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 561e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgint DisassemblerX64::PrintImmediate(byte* data, OperandSize size) { 562e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int64_t value; 563e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int count; 564e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org switch (size) { 565e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_BYTE_SIZE: 566e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *data; 567e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count = 1; 568e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 569e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_WORD_SIZE: 570e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<int16_t*>(data); 571e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count = 2; 572e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 573e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_DOUBLEWORD_SIZE: 574e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<uint32_t*>(data); 575e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count = 4; 576e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 577e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_QUADWORD_SIZE: 578e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<int32_t*>(data); 579e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count = 4; 580e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 581e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org default: 582e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UNREACHABLE(); 583e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = 0; // Initialize variables on all paths to satisfy the compiler. 584e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count = 0; 585e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 586b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org AppendToBuffer("%" V8_PTR_PREFIX "x", value); 587e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return count; 588e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org} 589e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 590e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 59168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::PrintRightOperand(byte* modrmp) { 59268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return PrintRightOperandHelper(modrmp, 59368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org &DisassemblerX64::NameOfCPURegister); 59468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 59568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 59668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 59768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::PrintRightByteOperand(byte* modrmp) { 59868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return PrintRightOperandHelper(modrmp, 59968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org &DisassemblerX64::NameOfByteCPURegister); 600b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 601b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 602b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 6033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerX64::PrintRightXMMOperand(byte* modrmp) { 6043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return PrintRightOperandHelper(modrmp, 6053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org &DisassemblerX64::NameOfXMMRegister); 6063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 6073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 6083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 60968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used including the current *data. 61068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'. 61168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::PrintOperands(const char* mnem, 612e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org OperandType op_order, 61368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* data) { 61468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte modrm = *data; 61568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 61668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(modrm, &mod, ®op, &rm); 61768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int advance = 0; 618e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const char* register_name = 619e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte_size_operand_ ? NameOfByteCPURegister(regop) 620e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org : NameOfCPURegister(regop); 62168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (op_order) { 62268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case REG_OPER_OP_ORDER: { 62368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s%c %s,", 62468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem, 62568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 626e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org register_name); 627e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org advance = byte_size_operand_ ? PrintRightByteOperand(data) 628e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org : PrintRightOperand(data); 62968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 63068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 63168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case OPER_REG_OP_ORDER: { 63268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s%c ", mnem, operand_size_code()); 633e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org advance = byte_size_operand_ ? PrintRightByteOperand(data) 634e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org : PrintRightOperand(data); 635e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer(",%s", register_name); 63668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 63768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 63868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 63968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UNREACHABLE(); 64068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 64168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 64268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return advance; 643b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 644b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 645b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 64668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used by machine instruction, including *data byte. 64768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Writes immediate instructions to 'tmp_buffer_'. 64868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::PrintImmediateOp(byte* data) { 649e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bool byte_size_immediate = (*data & 0x02) != 0; 65068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte modrm = *(data + 1); 65168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 65268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(modrm, &mod, ®op, &rm); 65368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = "Imm???"; 65468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (regop) { 65568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0: 65668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "add"; 65768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 65868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 1: 65968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "or"; 66068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 66168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 2: 66268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "adc"; 66368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 664a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 3: 665a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org mnem = "sbb"; 666a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org break; 66768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 4: 66868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "and"; 66968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 67068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 5: 67168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "sub"; 67268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 67368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 6: 67468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "xor"; 67568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 67668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 7: 67768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "cmp"; 67868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 67968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 68068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 68168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 682e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("%s%c ", mnem, operand_size_code()); 68368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int count = PrintRightOperand(data + 1); 684e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer(",0x"); 685e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org OperandSize immediate_size = 686e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org byte_size_immediate ? OPERAND_BYTE_SIZE : operand_size(); 687e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org count += PrintImmediate(data + 1 + count, immediate_size); 688e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return 1 + count; 68968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 69068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 69168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 69268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 6933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerX64::F6F7Instruction(byte* data) { 6943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT(*data == 0xF7 || *data == 0xF6); 69568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte modrm = *(data + 1); 69668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 69768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(modrm, &mod, ®op, &rm); 69868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (mod == 3 && regop != 0) { 69968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = NULL; 70068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (regop) { 70168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 2: 70268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "not"; 70368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 70468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 3: 70568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "neg"; 70668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 70768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 4: 70868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "mul"; 70968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 710d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org case 5: 711d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org mnem = "imul"; 712d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org break; 71368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 7: 71468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "idiv"; 71568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 71668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 71768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 71868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 71968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s%c %s", 72068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem, 72168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 72268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfCPURegister(rm)); 72368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 72468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else if (regop == 0) { 72568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("test%c ", operand_size_code()); 7263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int count = PrintRightOperand(data + 1); // Use name of 64-bit register. 7273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org AppendToBuffer(",0x"); 7283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org count += PrintImmediate(data + 1 + count, operand_size()); 7293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return 1 + count; 73068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 73168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 73268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 73368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 73468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 73568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 73668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 737e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgint DisassemblerX64::ShiftInstruction(byte* data) { 738e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte op = *data & (~1); 739e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (op != 0xD0 && op != 0xD2 && op != 0xC0) { 740e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UnimplementedInstruction(); 741e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return 1; 742e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 74368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte modrm = *(data + 1); 74468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 74568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(modrm, &mod, ®op, &rm); 746e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org regop &= 0x7; // The REX.R bit does not affect the operation. 74768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int imm8 = -1; 74868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int num_bytes = 2; 749e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (mod != 3) { 75068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 751e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return num_bytes; 752e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 753e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const char* mnem = NULL; 754e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org switch (regop) { 755e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0: 756e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "rol"; 757e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 758e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 1: 759e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "ror"; 760e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 761e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 2: 762e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "rcl"; 763e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 764e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 3: 765e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "rcr"; 766e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 767e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 4: 768e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "shl"; 769e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 770e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 5: 771e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "shr"; 772e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 773e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 7: 774e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem = "sar"; 775e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 776e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org default: 777e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UnimplementedInstruction(); 778e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return num_bytes; 779e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 7803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_NE(NULL, mnem); 781e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (op == 0xD0) { 782e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org imm8 = 1; 783e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if (op == 0xC0) { 784e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org imm8 = *(data + 2); 785e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org num_bytes = 3; 786e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 787e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("%s%c %s,", 788e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org mnem, 789e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org operand_size_code(), 790e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte_size_operand_ ? NameOfByteCPURegister(rm) 791e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org : NameOfCPURegister(rm)); 792e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (op == 0xD2) { 793e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("cl"); 794e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else { 795e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("%d", imm8); 79668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 79768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return num_bytes; 79868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 79968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 80068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 80168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 80268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::JumpShort(byte* data) { 8033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0xEB, *data); 80468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte b = *(data + 1); 80568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* dest = data + static_cast<int8_t>(b) + 2; 80668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("jmp %s", NameOfAddress(dest)); 80768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 80868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 80968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 81068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 81168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 81268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::JumpConditional(byte* data) { 8133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0x0F, *data); 81468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte cond = *(data + 1) & 0x0F; 81568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* dest = data + *reinterpret_cast<int32_t*>(data + 2) + 6; 81668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = conditional_code_suffix[cond]; 81768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("j%s %s", mnem, NameOfAddress(dest)); 81868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 6; // includes 0x0F 81968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 82068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 82168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 82268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 82368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::JumpConditionalShort(byte* data) { 82468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte cond = *data & 0x0F; 82568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte b = *(data + 1); 82668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* dest = data + static_cast<int8_t>(b) + 2; 82768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = conditional_code_suffix[cond]; 82868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("j%s %s", mnem, NameOfAddress(dest)); 82968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 83068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 83168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 83268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 83368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 83468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::SetCC(byte* data) { 8353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0x0F, *data); 83668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte cond = *(data + 1) & 0x0F; 83768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = conditional_code_suffix[cond]; 83868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("set%s%c ", mnem, operand_size_code()); 83968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org PrintRightByteOperand(data + 2); 84068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 3; // includes 0x0F 84168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 84268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 84368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 84468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns number of bytes used, including *data. 84568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::FPUInstruction(byte* data) { 8463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte escape_opcode = *data; 8473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0xD8, escape_opcode & 0xF8); 8483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte modrm_byte = *(data+1); 8493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte >= 0xC0) { 8513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return RegisterFPUInstruction(escape_opcode, modrm_byte); 8523811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 8533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); 8543811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 8563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerX64::MemoryFPUInstruction(int escape_opcode, 8583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int modrm_byte, 8593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte* modrm_start) { 8603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org const char* mnem = "?"; 8613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte. 8623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (escape_opcode) { 8633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD9: switch (regop) { 8643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fld_s"; break; 8653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fstp_s"; break; 8663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 7: mnem = "fstcw"; break; 8673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 86868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 8693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDB: switch (regop) { 8723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fild_s"; break; 8733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 1: mnem = "fisttp_s"; break; 8743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 2: mnem = "fist_s"; break; 8753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fistp_s"; break; 8763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDD: switch (regop) { 8813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fld_d"; break; 8823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fstp_d"; break; 8833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDF: switch (regop) { 8883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 5: mnem = "fild_d"; break; 8893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 7: mnem = "fistp_d"; break; 8903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org AppendToBuffer("%s ", mnem); 8973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int count = PrintRightOperand(modrm_start); 8983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return count + 1; 8993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 9003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerX64::RegisterFPUInstruction(int escape_opcode, 9023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte modrm_byte) { 9033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org bool has_register = false; // Is the FPU register encoded in modrm_byte? 9043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org const char* mnem = "?"; 9053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (escape_opcode) { 9073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD8: 9083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org UnimplementedInstruction(); 9093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD9: 9123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 9134a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case 0xC0: 9144a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org mnem = "fld"; 9154a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org has_register = true; 9164a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 9173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: 9183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fxch"; 9193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 92068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 92168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 9223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte) { 9233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE0: mnem = "fchs"; break; 9243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE1: mnem = "fabs"; break; 92564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xE3: mnem = "fninit"; break; 9263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE4: mnem = "ftst"; break; 9273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fld1"; break; 9284a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case 0xEB: mnem = "fldpi"; break; 929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case 0xED: mnem = "fldln2"; break; 9303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xEE: mnem = "fldz"; break; 93164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xF0: mnem = "f2xm1"; break; 932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case 0xF1: mnem = "fyl2x"; break; 93364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xF2: mnem = "fptan"; break; 9343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF5: mnem = "fprem1"; break; 9353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF7: mnem = "fincstp"; break; 9363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fprem"; break; 93764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xFD: mnem = "fscale"; break; 9383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xFE: mnem = "fsin"; break; 9393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xFF: mnem = "fcos"; break; 9403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 9413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 94268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 9433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDA: 9463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xE9) { 9473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucompp"; 9483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 94968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 9503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9523811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDB: 9543811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if ((modrm_byte & 0xF8) == 0xE8) { 9553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucomi"; 9563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 9573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else if (modrm_byte == 0xE2) { 9583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fclex"; 9593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 96068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 9613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDC: 9653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 9663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 9673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "fadd"; break; 9683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fsub"; break; 9693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: mnem = "fmul"; break; 9703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fdiv"; break; 9713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 9723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDD: 9763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 9773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 9783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "ffree"; break; 9793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD8: mnem = "fstp"; break; 9803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 9813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDE: 9853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xD9) { 9863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fcompp"; 9873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 9883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 9893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 9903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "faddp"; break; 9913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fsubp"; break; 9923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: mnem = "fmulp"; break; 9933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fdivp"; break; 9943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 9953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 9973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 9983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 9993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDF: 10003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xE0) { 10013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fnstsw_ax"; 10023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else if ((modrm_byte & 0xF8) == 0xE8) { 10033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucomip"; 10043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 10053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 10063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 10073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 10083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 10093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 10103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 10113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (has_register) { 10123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7); 10133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 101468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s", mnem); 101568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 101668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return 2; 101768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 101868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1019e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 10203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1021e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// Handle all two-byte opcodes, which start with 0x0F. 1022e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix. 1023e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A. 1024e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgint DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { 1025e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte opcode = *(data + 1); 1026e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte* current = data + 2; 1027e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // At return, "current" points to the start of the next instruction. 1028e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const char* mnemonic = TwoByteMnemonic(opcode); 10295c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (operand_size_ == 0x66) { 10305c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 0x66 0x0F prefix. 10315c838251403b0be9a882540f1922577abba4c872ager@chromium.org int mod, regop, rm; 1032ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (opcode == 0x3A) { 1033ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org byte third_byte = *current; 1034ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org current = data + 3; 1035ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (third_byte == 0x17) { 1036ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 1037ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org AppendToBuffer("extractps "); // reg/m32, xmm, imm8 1038ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org current += PrintRightOperand(current); 1039b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); 1040ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org current += 1; 1041160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (third_byte == 0x0b) { 1042160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org get_modrm(*current, &mod, ®op, &rm); 1043160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // roundsd xmm, xmm/m64, imm8 1044b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop)); 1045b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org current += PrintRightXMMOperand(current); 1046b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%d", (*current) & 3); 1047160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += 1; 1048357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } else { 1049357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org UnimplementedInstruction(); 1050357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } 1051ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 1052ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 105364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (opcode == 0x1f) { 105464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org current++; 105564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (rm == 4) { // SIB byte present. 105664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org current++; 105764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 105864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (mod == 1) { // Byte displacement. 105964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org current += 1; 106064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (mod == 2) { // 32-bit displacement. 106164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org current += 4; 106264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } // else no immediate displacement. 106364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); 106464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (opcode == 0x28) { 1065b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("movapd %s,", NameOfXMMRegister(regop)); 1066160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1067160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (opcode == 0x29) { 1068160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org AppendToBuffer("movapd "); 1069160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1070b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1071160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (opcode == 0x6E) { 1072ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org AppendToBuffer("mov%c %s,", 1073ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org rex_w() ? 'q' : 'd', 1074ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org NameOfXMMRegister(regop)); 1075ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org current += PrintRightOperand(current); 10760ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (opcode == 0x6F) { 10770ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org AppendToBuffer("movdqa %s,", 10780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org NameOfXMMRegister(regop)); 1079badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org current += PrintRightXMMOperand(current); 1080ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else if (opcode == 0x7E) { 1081e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org AppendToBuffer("mov%c ", 1082e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org rex_w() ? 'q' : 'd'); 1083e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org current += PrintRightOperand(current); 1084b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 10850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (opcode == 0x7F) { 10860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org AppendToBuffer("movdqa "); 1087badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org current += PrintRightXMMOperand(current); 1088b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1089160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (opcode == 0xD6) { 1090160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org AppendToBuffer("movq "); 1091160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1092b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1093ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org } else if (opcode == 0x50) { 1094ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); 1095ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org current += PrintRightXMMOperand(current); 1096ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 1097ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org const char* mnemonic = "?"; 1098ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org if (opcode == 0x54) { 10995d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org mnemonic = "andpd"; 11005d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else if (opcode == 0x56) { 11015d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org mnemonic = "orpd"; 11025d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else if (opcode == 0x57) { 1103ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mnemonic = "xorpd"; 1104ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else if (opcode == 0x2E) { 1105ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org mnemonic = "ucomisd"; 110640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } else if (opcode == 0x2F) { 110740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org mnemonic = "comisd"; 1108ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 1109ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org UnimplementedInstruction(); 1110ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 1111ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); 1112ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org current += PrintRightXMMOperand(current); 1113ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 11145c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 11155c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (group_1_prefix_ == 0xF2) { 11165c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Beginning of instructions with prefix 0xF2. 11175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11185c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (opcode == 0x11 || opcode == 0x10) { 11195c838251403b0be9a882540f1922577abba4c872ager@chromium.org // MOVSD: Move scalar double-precision fp to/from/between XMM registers. 11205c838251403b0be9a882540f1922577abba4c872ager@chromium.org AppendToBuffer("movsd "); 11215c838251403b0be9a882540f1922577abba4c872ager@chromium.org int mod, regop, rm; 11225c838251403b0be9a882540f1922577abba4c872ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 11235c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (opcode == 0x11) { 1124badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org current += PrintRightXMMOperand(current); 11255c838251403b0be9a882540f1922577abba4c872ager@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 11265c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 11275c838251403b0be9a882540f1922577abba4c872ager@chromium.org AppendToBuffer("%s,", NameOfXMMRegister(regop)); 1128badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org current += PrintRightXMMOperand(current); 11295c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 11305c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (opcode == 0x2A) { 11315c838251403b0be9a882540f1922577abba4c872ager@chromium.org // CVTSI2SD: integer to XMM double conversion. 11325c838251403b0be9a882540f1922577abba4c872ager@chromium.org int mod, regop, rm; 11335c838251403b0be9a882540f1922577abba4c872ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 113440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org AppendToBuffer("%sd %s,", mnemonic, NameOfXMMRegister(regop)); 11355c838251403b0be9a882540f1922577abba4c872ager@chromium.org current += PrintRightOperand(current); 11364a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (opcode == 0x2C) { 11374a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // CVTTSD2SI: 11384a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Convert with truncation scalar double-precision FP to integer. 11394a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int mod, regop, rm; 11404a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org get_modrm(*current, &mod, ®op, &rm); 11414a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AppendToBuffer("cvttsd2si%c %s,", 11424a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org operand_size_code(), NameOfCPURegister(regop)); 11434a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org current += PrintRightXMMOperand(current); 11444a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } else if (opcode == 0x2D) { 11454a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // CVTSD2SI: Convert scalar double-precision FP to integer. 11464a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org int mod, regop, rm; 11474a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org get_modrm(*current, &mod, ®op, &rm); 11484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AppendToBuffer("cvtsd2si%c %s,", 11494a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org operand_size_code(), NameOfCPURegister(regop)); 11504a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org current += PrintRightXMMOperand(current); 11514111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) { 11525c838251403b0be9a882540f1922577abba4c872ager@chromium.org // XMM arithmetic. Mnemonic was retrieved at the start of this function. 11535c838251403b0be9a882540f1922577abba4c872ager@chromium.org int mod, regop, rm; 11545c838251403b0be9a882540f1922577abba4c872ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 11555c838251403b0be9a882540f1922577abba4c872ager@chromium.org AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); 11565c838251403b0be9a882540f1922577abba4c872ager@chromium.org current += PrintRightXMMOperand(current); 11571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } else if (opcode == 0xC2) { 11581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Intel manual 2A, Table 3-18. 11591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int mod, regop, rm; 11601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org get_modrm(*current, &mod, ®op, &rm); 11611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org const char* const pseudo_op[] = { 11621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpeqsd", 11631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpltsd", 11641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmplesd", 11651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpunordsd", 11661e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpneqsd", 11671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpnltsd", 11681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpnlesd", 11691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org "cmpordsd" 11701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org }; 11711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org AppendToBuffer("%s %s,%s", 11721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org pseudo_op[current[1]], 11731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org NameOfXMMRegister(regop), 11741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org NameOfXMMRegister(rm)); 11751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org current += 2; 11765c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 11775c838251403b0be9a882540f1922577abba4c872ager@chromium.org UnimplementedInstruction(); 11785c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 1179357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } else if (group_1_prefix_ == 0xF3) { 1180357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org // Instructions with prefix 0xF3. 118140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org if (opcode == 0x11 || opcode == 0x10) { 118240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // MOVSS: Move scalar double-precision fp to/from/between XMM registers. 118340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org AppendToBuffer("movss "); 118440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org int mod, regop, rm; 118540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org get_modrm(*current, &mod, ®op, &rm); 118640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org if (opcode == 0x11) { 118740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org current += PrintRightOperand(current); 118840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 118940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } else { 119040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org AppendToBuffer("%s,", NameOfXMMRegister(regop)); 119140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org current += PrintRightOperand(current); 119240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } 119340b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } else if (opcode == 0x2A) { 119440b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // CVTSI2SS: integer to XMM single conversion. 119540b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org int mod, regop, rm; 119640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org get_modrm(*current, &mod, ®op, &rm); 119740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org AppendToBuffer("%ss %s,", mnemonic, NameOfXMMRegister(regop)); 119840b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org current += PrintRightOperand(current); 119940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org } else if (opcode == 0x2C) { 12004a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // CVTTSS2SI: 12014a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Convert with truncation scalar single-precision FP to dword integer. 12020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int mod, regop, rm; 12030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org get_modrm(*current, &mod, ®op, &rm); 12040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org AppendToBuffer("cvttss2si%c %s,", 12050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org operand_size_code(), NameOfCPURegister(regop)); 12060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org current += PrintRightXMMOperand(current); 1207357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } else if (opcode == 0x5A) { 12084a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // CVTSS2SD: 12094a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Convert scalar single-precision FP to scalar double-precision FP. 1210357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org int mod, regop, rm; 1211357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org get_modrm(*current, &mod, ®op, &rm); 1212357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); 1213357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org current += PrintRightXMMOperand(current); 1214160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else if (opcode == 0x7E) { 1215160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int mod, regop, rm; 1216160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org get_modrm(*current, &mod, ®op, &rm); 1217b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); 1218160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1219357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } else { 1220357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org UnimplementedInstruction(); 1221357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org } 12225c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else if (opcode == 0x1F) { 1223e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // NOP 1224e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int mod, regop, rm; 1225e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org get_modrm(*current, &mod, ®op, &rm); 1226e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current++; 122764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (rm == 4) { // SIB byte present. 1228e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current++; 1229e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1230e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (mod == 1) { // Byte displacement. 1231e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current += 1; 1232e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if (mod == 2) { // 32-bit displacement. 1233e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current += 4; 1234e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } // else no immediate displacement. 1235e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("nop"); 1236160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 12378e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } else if (opcode == 0x28) { 1238160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // movaps xmm, xmm/m128 1239160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int mod, regop, rm; 1240160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org get_modrm(*current, &mod, ®op, &rm); 1241b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("movaps %s,", NameOfXMMRegister(regop)); 1242160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1243160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 12448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } else if (opcode == 0x29) { 1245160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org // movaps xmm/m128, xmm 1246160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org int mod, regop, rm; 1247160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org get_modrm(*current, &mod, ®op, &rm); 12488e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org AppendToBuffer("movaps "); 1249160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1250b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1251160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 1252ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org } else if (opcode == 0xA2) { 1253ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org // CPUID 1254e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("%s", mnemonic); 1255e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1256b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org } else if ((opcode & 0xF0) == 0x40) { 1257b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org // CMOVcc: conditional move. 1258b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org int condition = opcode & 0x0F; 1259b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org const InstructionDesc& idesc = cmov_instructions[condition]; 1260b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org byte_size_operand_ = idesc.byte_size_operation; 1261b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org current += PrintOperands(idesc.mnem, idesc.op_order_, current); 1262b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 1263af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } else if (opcode >= 0x53 && opcode <= 0x5F) { 1264af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org const char* const pseudo_op[] = { 1265af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "rcpps", 1266af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "andps", 1267af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "andnps", 1268af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "orps", 1269af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "xorps", 1270af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "addps", 1271af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "mulps", 1272af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "cvtps2pd", 1273af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "cvtdq2ps", 1274af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "subps", 1275af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "minps", 1276af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "divps", 1277af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org "maxps", 1278af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org }; 1279ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org int mod, regop, rm; 1280ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org get_modrm(*current, &mod, ®op, &rm); 1281af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org AppendToBuffer("%s %s,", 1282af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org pseudo_op[opcode - 0x53], 1283af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org NameOfXMMRegister(regop)); 1284ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org current += PrintRightXMMOperand(current); 1285ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org 1286af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } else if (opcode == 0xC6) { 1287af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // shufps xmm, xmm/m128, imm8 1288057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org int mod, regop, rm; 1289057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org get_modrm(*current, &mod, ®op, &rm); 1290af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org AppendToBuffer("shufps %s, ", NameOfXMMRegister(regop)); 1291160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org current += PrintRightXMMOperand(current); 1292af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org AppendToBuffer(", %d", (*current) & 3); 1293af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org current += 1; 1294160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 12954121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org } else if (opcode == 0x50) { 12964121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org // movmskps reg, xmm 12974121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org int mod, regop, rm; 12984121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org get_modrm(*current, &mod, ®op, &rm); 1299b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("movmskps %s,", NameOfCPURegister(regop)); 13004121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org current += PrintRightXMMOperand(current); 13014121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org 1302e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if ((opcode & 0xF0) == 0x80) { 1303e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Jcc: Conditional jump (branch). 1304e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current = data + JumpConditional(data); 1305e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1306e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 || 1307e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org opcode == 0xB7 || opcode == 0xAF) { 1308e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Size-extending moves, IMUL. 1309e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current); 1310e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1311e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if ((opcode & 0xF0) == 0x90) { 1312e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // SETcc: Set byte on condition. Needs pointer to beginning of instruction. 1313e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current = data + SetCC(data); 1314e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1315e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) { 1316e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // SHLD, SHRD (double-precision shift), BTS (bit set). 1317e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer("%s ", mnemonic); 1318e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int mod, regop, rm; 1319e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org get_modrm(*current, &mod, ®op, &rm); 1320e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org current += PrintRightOperand(current); 1321e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (opcode == 0xAB) { 1322e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1323e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else { 1324e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org AppendToBuffer(",%s,cl", NameOfCPURegister(regop)); 1325e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1326e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else { 1327e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UnimplementedInstruction(); 1328e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1329c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return static_cast<int>(current - data); 1330e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org} 1331e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1332e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1333e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// Mnemonics for two-byte opcode instructions starting with 0x0F. 1334e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// The argument is the second byte of the two-byte opcode. 133568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// Returns NULL if the instruction is not handled here. 1336e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgconst char* DisassemblerX64::TwoByteMnemonic(byte opcode) { 1337e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org switch (opcode) { 133868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x1F: 133968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "nop"; 134040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org case 0x2A: // F2/F3 prefix. 134140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org return "cvtsi2s"; 13424111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org case 0x51: // F2 prefix. 13434111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org return "sqrtsd"; 1344e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0x58: // F2 prefix. 1345e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "addsd"; 1346e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0x59: // F2 prefix. 1347e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "mulsd"; 13483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case 0x5A: // F2 prefix. 13493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return "cvtsd2ss"; 1350e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0x5C: // F2 prefix. 1351e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "subsd"; 1352e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0x5E: // F2 prefix. 1353e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "divsd"; 135468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xA2: 135568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "cpuid"; 135668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xA5: 135768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "shld"; 135868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xAB: 135968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "bts"; 1360e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xAD: 1361e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "shrd"; 1362e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xAF: 1363e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "imul"; 1364e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xB6: 1365e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "movzxb"; 1366e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xB7: 1367e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "movzxw"; 1368e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xBE: 1369e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "movsxb"; 1370e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xBF: 1371e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org return "movsxw"; 137268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 137368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return NULL; 137468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 137568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 137668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1377e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 1378e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// Disassembles the instruction at instr, and writes it into out_buffer. 137968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, 138068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* instr) { 138168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_pos_ = 0; // starting to write as position 0 138268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* data = instr; 138368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool processed = true; // Will be set to false if the current instruction 138468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // is not in 'instructions' table. 138568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte current; 138668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 138768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Scan for prefixes. 138868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org while (true) { 138968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org current = *data; 1390b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix. 1391e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org operand_size_ = current; 1392e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else if ((current & 0xF0) == 0x40) { // REX prefix. 139368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org setRex(current); 139468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (rex_w()) AppendToBuffer("REX.W "); 1395b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3). 1396e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org group_1_prefix_ = current; 1397e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } else { // Not a prefix - an opcode. 139868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 139968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 1400e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data++; 140168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 140268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 14037d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org const InstructionDesc& idesc = instruction_table_->Get(current); 1404e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte_size_operand_ = idesc.byte_size_operation; 140568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (idesc.type) { 140668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case ZERO_OPERANDS_INSTR: 1407b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (current >= 0xA4 && current <= 0xA7) { 1408b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // String move or compare operations. 1409b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (group_1_prefix_ == REP_PREFIX) { 1410b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // REP. 1411b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org AppendToBuffer("rep "); 1412b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1413b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (rex_w()) AppendToBuffer("REX.W "); 1414b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); 1415b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 1416b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org AppendToBuffer("%s", idesc.mnem, operand_size_code()); 1417b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 141868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 141968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 142068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 142168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case TWO_OPERANDS_INSTR: 142268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 142368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += PrintOperands(idesc.mnem, idesc.op_order_, data); 142468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 142568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 142668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case JUMP_CONDITIONAL_SHORT_INSTR: 142768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += JumpConditionalShort(data); 142868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 142968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 143068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case REGISTER_INSTR: 143168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s%c %s", 143268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org idesc.mnem, 143368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 143468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfCPURegister(base_reg(current & 0x07))); 143568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 143668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 143768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case PUSHPOP_INSTR: 143868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s %s", 143968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org idesc.mnem, 144068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfCPURegister(base_reg(current & 0x07))); 144168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 144268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 144368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case MOVE_REG_INSTR: { 144468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* addr = NULL; 144568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (operand_size()) { 1446e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_WORD_SIZE: 144768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1)); 144868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 3; 144968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 1450e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_DOUBLEWORD_SIZE: 145168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); 145268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 5; 145368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 1454e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_QUADWORD_SIZE: 145568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1)); 145668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 9; 145768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 145868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 145968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UNREACHABLE(); 146068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 146168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("mov%c %s,%s", 146268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 146368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfCPURegister(base_reg(current & 0x07)), 146468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfAddress(addr)); 146568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 146668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 146768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 146868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case CALL_JUMP_INSTR: { 146968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5; 147068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr)); 147168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 5; 147268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 147368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 147468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 147568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case SHORT_IMMEDIATE_INSTR: { 147668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* addr = 147768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); 1478b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr)); 147968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 5; 148068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 148168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 148268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 148368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case NO_INSTR: 148468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org processed = false; 148568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 148668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 148768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 148868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UNIMPLEMENTED(); // This type is not implemented. 148968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 149068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 149168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // The first byte didn't match any of the simple opcodes, so we 149268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // need to do special processing on it. 149368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (!processed) { 149468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (*data) { 149568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xC2: 149668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1)); 149768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 3; 149868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 149968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 150068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x69: // fall through 150168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x6B: { 150268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 150368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*(data + 1), &mod, ®op, &rm); 150468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int32_t imm = *data == 0x6B ? *(data + 2) 150568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org : *reinterpret_cast<int32_t*>(data + 2); 1506cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org AppendToBuffer("imul%c %s,%s,0x%x", 1507cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org operand_size_code(), 1508cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org NameOfCPURegister(regop), 150968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameOfCPURegister(rm), imm); 151068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 2 + (*data == 0x6B ? 1 : 4); 151168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 1512e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 151368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 151468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x81: // fall through 151568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x83: // 0x81 with sign extension bit set 151668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += PrintImmediateOp(data); 151768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 151868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1519e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0x0F: 1520e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += TwoByteOpcodeInstruction(data); 152168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 152268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 152368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x8F: { 152468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 152568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 152668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*data, &mod, ®op, &rm); 152768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (regop == 0) { 152868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("pop "); 152968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += PrintRightOperand(data); 153068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 153168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 153268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 153368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 153468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xFF: { 153568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 153668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 153768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*data, &mod, ®op, &rm); 153868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org const char* mnem = NULL; 153968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org switch (regop) { 154068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0: 154168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "inc"; 154268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 154368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 1: 154468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "dec"; 154568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 154668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 2: 154768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "call"; 154868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 154968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 4: 155068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "jmp"; 155168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 155268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 6: 155368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "push"; 155468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 155568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 155668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem = "???"; 155768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 155868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer(((regop <= 1) ? "%s%c " : "%s "), 155968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org mnem, 156068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code()); 156168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += PrintRightOperand(data); 156268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 156368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 156468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 156568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xC7: // imm32, fall through 156668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xC6: // imm8 156768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 156868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool is_byte = *data == 0xC6; 156968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 1570badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (is_byte) { 1571badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("movb "); 1572badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 1573badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int32_t imm = *data; 1574badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",0x%x", imm); 1575badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data++; 1576badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1577badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("mov%c ", operand_size_code()); 1578badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 1579e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (operand_size() == OPERAND_WORD_SIZE) { 1580e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int16_t imm = *reinterpret_cast<int16_t*>(data); 1581e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org AppendToBuffer(",0x%x", imm); 1582e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org data += 2; 1583e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1584e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org int32_t imm = *reinterpret_cast<int32_t*>(data); 1585e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org AppendToBuffer(",0x%x", imm); 1586e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org data += 4; 1587e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1588badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 158968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 159068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 159168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 159268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x80: { 159368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 159468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("cmpb "); 1595badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 159668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int32_t imm = *data; 159768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer(",0x%x", imm); 159868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 159968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 160068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 160168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 160268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x88: // 8bit, fall through 160368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x89: // 32bit 160468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org { 160568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org bool is_byte = *data == 0x88; 160668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 160768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 160868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*data, &mod, ®op, &rm); 1609badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (is_byte) { 1610badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("movb "); 1611badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 1612badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",%s", NameOfByteCPURegister(regop)); 1613badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1614badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("mov%c ", operand_size_code()); 1615badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 1616badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1617badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 161868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 161968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 162068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 162168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x90: 162268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x91: 162368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x92: 162468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x93: 162568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x94: 162668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x95: 162768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x96: 162868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x97: { 16293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int reg = (*data & 0x7) | (rex_b() ? 8 : 0); 163068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (reg == 0) { 163168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("nop"); // Common name for xchg rax,rax. 163268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 1633b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("xchg%c rax,%s", 163468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 1635e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org NameOfCPURegister(reg)); 163668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 16373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org data++; 163868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 16393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 1640a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB0: 1641a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB1: 1642a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB2: 1643a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB3: 1644a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB4: 1645a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB5: 1646a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB6: 1647a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB7: 1648a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB8: 1649a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xB9: 1650a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBA: 1651a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBB: 1652a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBC: 1653a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBD: 1654a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBE: 1655a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org case 0xBF: { 1656a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org // mov reg8,imm8 or mov reg32,imm32 1657a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org byte opcode = *data; 1658a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org data++; 1659a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org bool is_32bit = (opcode >= 0xB8); 1660a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); 1661a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org if (is_32bit) { 1662b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("mov%c %s,", 1663a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org operand_size_code(), 1664a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org NameOfCPURegister(reg)); 1665e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE); 1666a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } else { 1667b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("movb %s,", 1668a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org NameOfByteCPURegister(reg)); 1669e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org data += PrintImmediate(data, OPERAND_BYTE_SIZE); 1670a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } 1671a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org break; 1672a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } 167368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xFE: { 167468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data++; 167568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int mod, regop, rm; 167668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org get_modrm(*data, &mod, ®op, &rm); 16774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (regop == 1) { 16784a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AppendToBuffer("decb "); 1679badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 168068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 168168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 168268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 168368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 1684a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } 168568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x68: 168668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1)); 168768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 5; 168868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 168968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 169068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0x6A: 169168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); 169268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 2; 169368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 169468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 16950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org case 0xA1: // Fall through. 16960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org case 0xA3: 16970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org switch (operand_size()) { 1698e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_DOUBLEWORD_SIZE: { 16990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const char* memory_location = NameOfAddress( 17000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org reinterpret_cast<byte*>( 17010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org *reinterpret_cast<int32_t*>(data + 1))); 1702b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org if (*data == 0xA1) { // Opcode 0xA1 17030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AppendToBuffer("movzxlq rax,(%s)", memory_location); 1704b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org } else { // Opcode 0xA3 17050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AppendToBuffer("movzxlq (%s),rax", memory_location); 17060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 17070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org data += 5; 17080b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org break; 17090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 1710e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_QUADWORD_SIZE: { 17110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // New x64 instruction mov rax,(imm_64). 17120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const char* memory_location = NameOfAddress( 17130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org *reinterpret_cast<byte**>(data + 1)); 1714b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org if (*data == 0xA1) { // Opcode 0xA1 17150b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AppendToBuffer("movq rax,(%s)", memory_location); 1716b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org } else { // Opcode 0xA3 17170b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org AppendToBuffer("movq (%s),rax", memory_location); 17180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 17190b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org data += 9; 17200b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org break; 17210b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 17220b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org default: 17230b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org UnimplementedInstruction(); 17240b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org data += 2; 17250b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 17260b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org break; 17270b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 172868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xA8: 172968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1)); 173068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += 2; 173168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 173268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1733e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xA9: { 1734e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org int64_t value = 0; 1735e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org switch (operand_size()) { 1736e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_WORD_SIZE: 1737e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<uint16_t*>(data + 1); 1738e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += 3; 1739e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 1740e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_DOUBLEWORD_SIZE: 1741e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<uint32_t*>(data + 1); 1742e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += 5; 1743e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 1744e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org case OPERAND_QUADWORD_SIZE: 1745e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value = *reinterpret_cast<int32_t*>(data + 1); 1746e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += 5; 1747e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 1748e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org default: 1749e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org UNREACHABLE(); 1750e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 17510e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org AppendToBuffer("test%c rax,0x%" V8_PTR_PREFIX "x", 175268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org operand_size_code(), 1753e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org value); 175468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 1755e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 175668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xD1: // fall through 175768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xD3: // fall through 175868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xC1: 1759e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += ShiftInstruction(data); 1760e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org break; 1761e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xD0: // fall through 1762e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xD2: // fall through 1763e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org case 0xC0: 1764e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org byte_size_operand_ = true; 1765e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += ShiftInstruction(data); 176668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 176768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 176868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xD9: // fall through 176968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDA: // fall through 177068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDB: // fall through 177168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDC: // fall through 177268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDD: // fall through 177368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDE: // fall through 177468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xDF: 177568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += FPUInstruction(data); 177668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 177768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 177868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xEB: 177968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org data += JumpShort(data); 178068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 178168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 17823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF6: 17833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte_size_operand_ = true; // fall through 178468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org case 0xF7: 17853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org data += F6F7Instruction(data); 178668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org break; 178768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 17884121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org case 0x3C: 1789b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org AppendToBuffer("cmp al,0x%x", *reinterpret_cast<int8_t*>(data + 1)); 17904121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org data +=2; 17914121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org break; 17924121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org 179368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org default: 179468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UnimplementedInstruction(); 1795e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org data += 1; 179668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 179768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } // !processed 179868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 179968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (tmp_buffer_pos_ < sizeof tmp_buffer_) { 180068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_[tmp_buffer_pos_] = '\0'; 180168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 180268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1803c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int instr_len = static_cast<int>(data - instr); 180468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org ASSERT(instr_len > 0); // Ensure progress. 180568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 180668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org int outp = 0; 180768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // Instruction bytes. 180868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (byte* bp = instr; bp < data; bp++) { 180968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org outp += v8::internal::OS::SNPrintF(out_buffer + outp, "%02x", *bp); 181068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 181168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (int i = 6 - instr_len; i >= 0; i--) { 181268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org outp += v8::internal::OS::SNPrintF(out_buffer + outp, " "); 181368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 181468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 181568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org outp += v8::internal::OS::SNPrintF(out_buffer + outp, " %s", 181668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org tmp_buffer_.start()); 181768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return instr_len; 181868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 181968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 1820e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 182168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org//------------------------------------------------------------------------------ 182268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 182368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 182468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstatic const char* cpu_regs[16] = { 182568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", 182668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 182768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 182868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 182968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 183068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstatic const char* byte_cpu_regs[16] = { 183168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", 183268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l" 183368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 183468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 183568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 183668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgstatic const char* xmm_regs[16] = { 183768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 183868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" 183968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org}; 184068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 184168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 184268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst char* NameConverter::NameOfAddress(byte* addr) const { 1843ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); 1844ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return tmp_buffer_.start(); 184568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org} 184668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 184768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 184868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst char* NameConverter::NameOfConstant(byte* addr) const { 184968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return NameOfAddress(addr); 1850b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1851b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1852b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1853b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.orgconst char* NameConverter::NameOfCPURegister(int reg) const { 185468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (0 <= reg && reg < 16) 185568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return cpu_regs[reg]; 185668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "noreg"; 1857b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1858b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1859b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 186068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst char* NameConverter::NameOfByteCPURegister(int reg) const { 186168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (0 <= reg && reg < 16) 186268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return byte_cpu_regs[reg]; 186368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "noreg"; 1864b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1865b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1866b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 186768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst char* NameConverter::NameOfXMMRegister(int reg) const { 186868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (0 <= reg && reg < 16) 186968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return xmm_regs[reg]; 187068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return "noxmmreg"; 1871b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1872b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 187368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 187468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgconst char* NameConverter::NameInCode(byte* addr) const { 187568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org // X64 does not embed debug strings at the moment. 187668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org UNREACHABLE(); 187768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return ""; 1878b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1879b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1880e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 188168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org//------------------------------------------------------------------------------ 188268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 188368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgDisassembler::Disassembler(const NameConverter& converter) 188468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org : converter_(converter) { } 188568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 188668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgDisassembler::~Disassembler() { } 188768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 188868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 188968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 189068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* instruction) { 189168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org DisassemblerX64 d(converter_, CONTINUE_ON_UNIMPLEMENTED_OPCODE); 189268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return d.InstructionDecode(buffer, instruction); 1893b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1894b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 189568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 189668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org// The X64 assembler does not use constant pools. 189768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgint Disassembler::ConstantPoolSizeAt(byte* instruction) { 189868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org return -1; 1899b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1900b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 190168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 190268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgvoid Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 190368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org NameConverter converter; 190468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org Disassembler d(converter); 190568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (byte* pc = begin; pc < end;) { 190668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org v8::internal::EmbeddedVector<char, 128> buffer; 190768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org buffer[0] = '\0'; 190868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org byte* prev_pc = pc; 190968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org pc += d.InstructionDecode(buffer, pc); 191068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org fprintf(f, "%p", prev_pc); 191168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org fprintf(f, " "); 191268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org 191368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org for (byte* bp = prev_pc; bp < pc; bp++) { 191468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org fprintf(f, "%02x", *bp); 191568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 1916c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) { 191768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org fprintf(f, " "); 191868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 191968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org fprintf(f, " %s\n", buffer.start()); 192068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 1921b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} 1922b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org 1923b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org} // namespace disasm 19249dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 19259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 1926