1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include <assert.h> 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include <stdarg.h> 74b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <stdio.h> 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 10864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/disasm.h" 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace disasm { 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum OperandOrder { 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNSET_OP_ORDER = 0, 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org REG_OPER_OP_ORDER, 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OPER_REG_OP_ORDER 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------ 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Tables 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------ 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct ByteMnemonic { 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int b; // -1 terminates, otherwise must be in range (0..255) 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem; 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OperandOrder op_order_; 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic two_operands_instr[] = { 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x01, "add", OPER_REG_OP_ORDER}, 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x03, "add", REG_OPER_OP_ORDER}, 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x09, "or", OPER_REG_OP_ORDER}, 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x0B, "or", REG_OPER_OP_ORDER}, 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x1B, "sbb", REG_OPER_OP_ORDER}, 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x21, "and", OPER_REG_OP_ORDER}, 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x23, "and", REG_OPER_OP_ORDER}, 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x29, "sub", OPER_REG_OP_ORDER}, 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x2A, "subb", REG_OPER_OP_ORDER}, 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x2B, "sub", REG_OPER_OP_ORDER}, 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x31, "xor", OPER_REG_OP_ORDER}, 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x33, "xor", REG_OPER_OP_ORDER}, 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x38, "cmpb", OPER_REG_OP_ORDER}, 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x3A, "cmpb", REG_OPER_OP_ORDER}, 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x3B, "cmp", REG_OPER_OP_ORDER}, 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x84, "test_b", REG_OPER_OP_ORDER}, 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x85, "test", REG_OPER_OP_ORDER}, 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x87, "xchg", REG_OPER_OP_ORDER}, 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x8A, "mov_b", REG_OPER_OP_ORDER}, 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x8B, "mov", REG_OPER_OP_ORDER}, 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x8D, "lea", REG_OPER_OP_ORDER}, 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {-1, "", UNSET_OP_ORDER} 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic zero_operands_instr[] = { 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xC3, "ret", UNSET_OP_ORDER}, 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xC9, "leave", UNSET_OP_ORDER}, 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x90, "nop", UNSET_OP_ORDER}, 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xF4, "hlt", UNSET_OP_ORDER}, 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xCC, "int3", UNSET_OP_ORDER}, 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x60, "pushad", UNSET_OP_ORDER}, 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x61, "popad", UNSET_OP_ORDER}, 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x9C, "pushfd", UNSET_OP_ORDER}, 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x9D, "popfd", UNSET_OP_ORDER}, 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x9E, "sahf", UNSET_OP_ORDER}, 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x99, "cdq", UNSET_OP_ORDER}, 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x9B, "fwait", UNSET_OP_ORDER}, 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xFC, "cld", UNSET_OP_ORDER}, 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xAB, "stos", UNSET_OP_ORDER}, 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {-1, "", UNSET_OP_ORDER} 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic call_jump_instr[] = { 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xE8, "call", UNSET_OP_ORDER}, 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0xE9, "jmp", UNSET_OP_ORDER}, 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {-1, "", UNSET_OP_ORDER} 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic short_immediate_instr[] = { 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x05, "add", UNSET_OP_ORDER}, 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x0D, "or", UNSET_OP_ORDER}, 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x15, "adc", UNSET_OP_ORDER}, 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x25, "and", UNSET_OP_ORDER}, 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x2D, "sub", UNSET_OP_ORDER}, 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x35, "xor", UNSET_OP_ORDER}, 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x3D, "cmp", UNSET_OP_ORDER}, 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {-1, "", UNSET_OP_ORDER} 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generally we don't want to generate these because they are subject to partial 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// register stalls. They are included for completeness and because the cmp 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// variant is used by the RecordWrite stub. Because it does not update the 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// register it is not subject to partial register stalls. 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic ByteMnemonic byte_immediate_instr[] = { 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x0c, "or", UNSET_OP_ORDER}, 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x24, "and", UNSET_OP_ORDER}, 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x34, "xor", UNSET_OP_ORDER}, 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {0x3c, "cmp", UNSET_OP_ORDER}, 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org {-1, "", UNSET_OP_ORDER} 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const jump_conditional_mnem[] = { 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*0*/ "jo", "jno", "jc", "jnc", 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*4*/ "jz", "jnz", "jna", "ja", 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*8*/ "js", "jns", "jpe", "jpo", 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*12*/ "jl", "jnl", "jng", "jg" 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const set_conditional_mnem[] = { 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*0*/ "seto", "setno", "setc", "setnc", 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*4*/ "setz", "setnz", "setna", "seta", 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*8*/ "sets", "setns", "setpe", "setpo", 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*12*/ "setl", "setnl", "setng", "setg" 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const conditional_move_mnem[] = { 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum InstructionType { 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NO_INSTR, 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZERO_OPERANDS_INSTR, 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TWO_OPERANDS_INSTR, 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JUMP_CONDITIONAL_SHORT_INSTR, 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org REGISTER_INSTR, 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MOVE_REG_INSTR, 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CALL_JUMP_INSTR, 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SHORT_IMMEDIATE_INSTR, 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org BYTE_IMMEDIATE_INSTR 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct InstructionDesc { 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem; 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionType type; 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OperandOrder op_order_; 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass InstructionTable { 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionTable(); 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const InstructionDesc& Get(byte x) const { return instructions_[x]; } 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static InstructionTable* get_instance() { 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static InstructionTable table; 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return &table; 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionDesc instructions_[256]; 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Clear(); 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void Init(); 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void CopyTable(const ByteMnemonic bm[], InstructionType type); 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void SetTableRange(InstructionType type, 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte start, 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte end, 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem); 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AddJumpConditionalShort(); 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgInstructionTable::InstructionTable() { 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Clear(); 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Init(); 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::Clear() { 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < 256; i++) { 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instructions_[i].mnem = ""; 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instructions_[i].type = NO_INSTR; 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instructions_[i].op_order_ = UNSET_OP_ORDER; 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::Init() { 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CopyTable(call_jump_instr, CALL_JUMP_INSTR); 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR); 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AddJumpConditionalShort(); 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::CopyTable(const ByteMnemonic bm[], 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionType type) { 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; bm[i].b >= 0; i++) { 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionDesc* id = &instructions_[bm[i].b]; 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->mnem = bm[i].mnem; 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->op_order_ = bm[i].op_order_; 214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NO_INSTR, id->type); // Information not already entered. 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->type = type; 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::SetTableRange(InstructionType type, 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte start, 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte end, 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem) { 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (byte b = start; b <= end; b++) { 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionDesc* id = &instructions_[b]; 226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NO_INSTR, id->type); // Information not already entered. 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->mnem = mnem; 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->type = type; 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::AddJumpConditionalShort() { 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (byte b = 0x70; b <= 0x7F; b++) { 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionDesc* id = &instructions_[b]; 236e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NO_INSTR, id->type); // Information not already entered. 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->mnem = jump_conditional_mnem[b & 0x0F]; 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org id->type = JUMP_CONDITIONAL_SHORT_INSTR; 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The X87 disassembler implementation. 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass DisassemblerX87 { 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DisassemblerX87(const NameConverter& converter, 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool abort_on_unimplemented = true) 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : converter_(converter), 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instruction_table_(InstructionTable::get_instance()), 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org tmp_buffer_pos_(0), 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org abort_on_unimplemented_(abort_on_unimplemented) { 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org tmp_buffer_[0] = '\0'; 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual ~DisassemblerX87() {} 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Writes one disassembled instruction into 'buffer' (0-terminated). 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Returns the length of the disassembled machine instruction in bytes. 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const NameConverter& converter_; 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstructionTable* instruction_table_; 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org v8::internal::EmbeddedVector<char, 128> tmp_buffer_; 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unsigned int tmp_buffer_pos_; 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool abort_on_unimplemented_; 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum { 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org eax = 0, 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ecx = 1, 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org edx = 2, 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ebx = 3, 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org esp = 4, 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ebp = 5, 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org esi = 6, 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org edi = 7 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum ShiftOpcodeExtension { 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kROL = 0, 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kROR = 1, 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kRCL = 2, 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kRCR = 3, 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kSHL = 4, 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org KSHR = 5, 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kSAR = 7 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* NameOfCPURegister(int reg) const { 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return converter_.NameOfCPURegister(reg); 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* NameOfByteCPURegister(int reg) const { 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return converter_.NameOfByteCPURegister(reg); 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* NameOfXMMRegister(int reg) const { 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return converter_.NameOfXMMRegister(reg); 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* NameOfAddress(byte* addr) const { 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return converter_.NameOfAddress(addr); 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Disassembler helper functions. 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static void get_modrm(byte data, int* mod, int* regop, int* rm) { 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *mod = (data >> 6) & 3; 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *regop = (data & 0x38) >> 3; 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *rm = data & 7; 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static void get_sib(byte data, int* scale, int* index, int* base) { 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *scale = (data >> 6) & 3; 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *index = (data >> 3) & 7; 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *base = data & 7; 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org typedef const char* (DisassemblerX87::*RegisterNameMapping)(int reg) const; 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintRightOperand(byte* modrmp); 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintRightByteOperand(byte* modrmp); 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintRightXMMOperand(byte* modrmp); 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int PrintImmediateOp(byte* data); 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int F7Instruction(byte* data); 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int D1D3C1Instruction(byte* data); 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int JumpShort(byte* data); 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int JumpConditional(byte* data, const char* comment); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int JumpConditionalShort(byte* data, const char* comment); 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int SetCC(byte* data); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int CMov(byte* data); 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int FPUInstruction(byte* data); 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void AppendToBuffer(const char* format, ...); 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void UnimplementedInstruction() { 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (abort_on_unimplemented_) { 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNIMPLEMENTED(); 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("'Unimplemented Instruction'"); 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid DisassemblerX87::AppendToBuffer(const char* format, ...) { 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_; 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org va_list args; 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org va_start(args, format); 36070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org int result = v8::internal::VSNPrintF(buf, format, args); 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org va_end(args); 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org tmp_buffer_pos_ += result; 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightOperandHelper( 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* modrmp, 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterNameMapping direct_register_name) { 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*modrmp, &mod, ®op, &rm); 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterNameMapping register_name = (mod == 3) ? direct_register_name : 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &DisassemblerX87::NameOfCPURegister; 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (mod) { 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0: 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (rm == ebp) { 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1); 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[0x%x]", disp); 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 5; 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (rm == esp) { 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte sib = *(modrmp + 1); 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int scale, index, base; 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_sib(sib, &scale, &index, &base); 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index == esp && base == esp && scale == 0 /*times_1*/) { 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s]", (this->*register_name)(rm)); 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2; 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (base == ebp) { 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s*%d%s0x%x]", 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(index), 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << scale, 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? "-" : "+", 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? -disp : disp); 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 6; 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (index != esp && base != ebp) { 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [base+index*scale] 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s+%s*%d]", 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(base), 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(index), 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << scale); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2; 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1; 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s]", (this->*register_name)(rm)); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1; 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 1: // fall through 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 2: 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (rm == esp) { 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte sib = *(modrmp + 1); 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int scale, index, base; 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_sib(sib, &scale, &index, &base); 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int disp = mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : *reinterpret_cast<int8_t*>(modrmp + 2); 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) { 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s%s0x%x]", 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(rm), 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? "-" : "+", 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? -disp : disp); 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s+%s*%d%s0x%x]", 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(base), 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(index), 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << scale, 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? "-" : "+", 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? -disp : disp); 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return mod == 2 ? 6 : 3; 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No sib. 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int disp = mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : *reinterpret_cast<int8_t*>(modrmp + 1); 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("[%s%s0x%x]", 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (this->*register_name)(rm), 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? "-" : "+", 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org disp < 0 ? -disp : disp); 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return mod == 2 ? 5 : 2; 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 3: 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s", (this->*register_name)(rm)); 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1; 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1; 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightOperand(byte* modrmp) { 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return PrintRightOperandHelper(modrmp, &DisassemblerX87::NameOfCPURegister); 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightByteOperand(byte* modrmp) { 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return PrintRightOperandHelper(modrmp, 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &DisassemblerX87::NameOfByteCPURegister); 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightXMMOperand(byte* modrmp) { 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return PrintRightOperandHelper(modrmp, 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &DisassemblerX87::NameOfXMMRegister); 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used including the current *data. 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'. 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintOperands(const char* mnem, 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OperandOrder op_order, 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* data) { 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte modrm = *data; 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(modrm, &mod, ®op, &rm); 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int advance = 0; 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op_order) { 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case REG_OPER_OP_ORDER: { 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop)); 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org advance = PrintRightOperand(data); 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case OPER_REG_OP_ORDER: { 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org advance = PrintRightOperand(data); 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return advance; 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used by machine instruction, including *data byte. 500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Writes immediate instructions to 'tmp_buffer_'. 501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintImmediateOp(byte* data) { 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool sign_extension_bit = (*data & 0x02) != 0; 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte modrm = *(data+1); 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(modrm, &mod, ®op, &rm); 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = "Imm???"; 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (regop) { 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0: mnem = "add"; break; 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 1: mnem = "or"; break; 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 2: mnem = "adc"; break; 511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 4: mnem = "and"; break; 512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 5: mnem = "sub"; break; 513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 6: mnem = "xor"; break; 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 7: mnem = "cmp"; break; 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int count = PrintRightOperand(data+1); 519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (sign_extension_bit) { 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", *(data + 1 + count)); 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1 + count + 1 /*int8*/; 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 1 + count + 4 /*int32_t*/; 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::F7Instruction(byte* data) { 531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0xF7, *data); 5325c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org byte modrm = *++data; 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(modrm, &mod, ®op, &rm); 5355c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org const char* mnem = NULL; 5365c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org switch (regop) { 5375c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 0: 5385c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "test"; 5395c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5405c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 2: 5415c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "not"; 5425c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5435c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 3: 5445c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "neg"; 5455c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5465c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 4: 5475c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "mul"; 5485c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5495c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 5: 5505c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "imul"; 5515c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5525c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 6: 5535c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "div"; 5545c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5555c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 7: 5565c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "idiv"; 5575c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5585c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org default: 5595c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org UnimplementedInstruction(); 5605c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } 5615c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer("%s ", mnem); 5625c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org int count = PrintRightOperand(data); 5635c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org if (regop == 0) { 5645c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count)); 5655c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org count += 4; 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5675c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org return 1 + count; 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::D1D3C1Instruction(byte* data) { 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte op = *data; 573e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op == 0xD1 || op == 0xD3 || op == 0xC1); 5745c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org byte modrm = *++data; 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(modrm, &mod, ®op, &rm); 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int imm8 = -1; 5785c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org const char* mnem = NULL; 5795c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org switch (regop) { 5805c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kROL: 5815c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "rol"; 5825c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5835c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kROR: 5845c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "ror"; 5855c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5865c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kRCL: 5875c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "rcl"; 5885c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5895c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kRCR: 5905c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "rcr"; 5915c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5925c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kSHL: 5935c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "shl"; 5945c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5955c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case KSHR: 5965c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "shr"; 5975c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 5985c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case kSAR: 5995c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org mnem = "sar"; 6005c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org break; 6015c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org default: 6025c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org UnimplementedInstruction(); 6035c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } 6045c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer("%s ", mnem); 6055c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org int count = PrintRightOperand(data); 6065c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org if (op == 0xD1) { 6075c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org imm8 = 1; 6085c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } else if (op == 0xC1) { 6099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org imm8 = *(data + 1); 6105c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org count++; 6115c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } else if (op == 0xD3) { 6125c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org // Shift/rotate by cl. 6135c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } 6145c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org if (imm8 >= 0) { 6155c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer(",%d", imm8); 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 6175c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer(",cl"); 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6195c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org return 1 + count; 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpShort(byte* data) { 625e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0xEB, *data); 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte b = *(data+1); 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* dest = data + static_cast<int8_t>(b) + 2; 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("jmp %s", NameOfAddress(dest)); 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2; 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpConditional(byte* data, const char* comment) { 635e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0x0F, *data); 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte cond = *(data+1) & 0x0F; 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = jump_conditional_mnem[cond]; 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (comment != NULL) { 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(", %s", comment); 642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 6; // includes 0x0F 644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpConditionalShort(byte* data, const char* comment) { 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte cond = *data & 0x0F; 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte b = *(data+1); 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* dest = data + static_cast<int8_t>(b) + 2; 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = jump_conditional_mnem[cond]; 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (comment != NULL) { 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(", %s", comment); 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2; 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::SetCC(byte* data) { 663e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0x0F, *data); 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte cond = *(data+1) & 0x0F; 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = set_conditional_mnem[cond]; 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrintRightByteOperand(data+2); 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 3; // Includes 0x0F. 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::CMov(byte* data) { 674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0x0F, *data); 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte cond = *(data + 1) & 0x0F; 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = conditional_move_mnem[cond]; 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2 + op_size; // includes 0x0F 679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data. 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::FPUInstruction(byte* data) { 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte escape_opcode = *data; 685e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0xD8, escape_opcode & 0xF8); 686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte modrm_byte = *(data+1); 687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (modrm_byte >= 0xC0) { 689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return RegisterFPUInstruction(escape_opcode, modrm_byte); 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::MemoryFPUInstruction(int escape_opcode, 696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int modrm_byte, 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* modrm_start) { 698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = "?"; 699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte. 700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (escape_opcode) { 701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD9: switch (regop) { 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0: mnem = "fld_s"; break; 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 2: mnem = "fst_s"; break; 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 3: mnem = "fstp_s"; break; 70506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 5: 70606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org mnem = "fldcw"; 70706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 70806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 7: 70906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org mnem = "fnstcw"; 71006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDB: switch (regop) { 716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0: mnem = "fild_s"; break; 717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 1: mnem = "fisttp_s"; break; 718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 2: mnem = "fist_s"; break; 719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 3: mnem = "fistp_s"; break; 720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 72406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 0xDC: 72506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org switch (regop) { 72606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 0: 72706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org mnem = "fadd_d"; 72806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 72906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org default: 73006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org UnimplementedInstruction(); 73106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 73206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 73306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDD: switch (regop) { 735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0: mnem = "fld_d"; break; 736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 1: mnem = "fisttp_d"; break; 737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 2: mnem = "fst_d"; break; 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 3: mnem = "fstp_d"; break; 73906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 4: 74006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org mnem = "frstor"; 74106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 74206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case 6: 74306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org mnem = "fnsave"; 74406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDF: switch (regop) { 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 5: mnem = "fild_d"; break; 751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 7: mnem = "fistp_d"; break; 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int count = PrintRightOperand(modrm_start); 760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return count + 1; 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::RegisterFPUInstruction(int escape_opcode, 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte modrm_byte) { 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool has_register = false; // Is the FPU register encoded in modrm_byte? 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = "?"; 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (escape_opcode) { 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD8: 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte & 0xF8) { 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC0: mnem = "fadd_i"; break; 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE0: mnem = "fsub_i"; break; 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC8: mnem = "fmul_i"; break; 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF0: mnem = "fdiv_i"; break; 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD9: 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte & 0xF8) { 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC0: 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fld"; 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC8: 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fxch"; 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte) { 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE0: mnem = "fchs"; break; 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE1: mnem = "fabs"; break; 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE4: mnem = "ftst"; break; 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE8: mnem = "fld1"; break; 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xEB: mnem = "fldpi"; break; 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xED: mnem = "fldln2"; break; 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xEE: mnem = "fldz"; break; 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF0: mnem = "f2xm1"; break; 800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF1: mnem = "fyl2x"; break; 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF4: mnem = "fxtract"; break; 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF5: mnem = "fprem1"; break; 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF7: mnem = "fincstp"; break; 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF8: mnem = "fprem"; break; 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFC: mnem = "frndint"; break; 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFD: mnem = "fscale"; break; 807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFE: mnem = "fsin"; break; 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFF: mnem = "fcos"; break; 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDA: 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (modrm_byte == 0xE9) { 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fucompp"; 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDB: 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((modrm_byte & 0xF8) == 0xE8) { 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fucomi"; 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (modrm_byte == 0xE2) { 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fclex"; 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (modrm_byte == 0xE3) { 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fninit"; 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDC: 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte & 0xF8) { 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC0: mnem = "fadd"; break; 839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE8: mnem = "fsub"; break; 840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC8: mnem = "fmul"; break; 841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF8: mnem = "fdiv"; break; 842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDD: 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte & 0xF8) { 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC0: mnem = "ffree"; break; 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD0: mnem = "fst"; break; 851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD8: mnem = "fstp"; break; 852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDE: 857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (modrm_byte == 0xD9) { 858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fcompp"; 859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (modrm_byte & 0xF8) { 862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC0: mnem = "faddp"; break; 863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xE8: mnem = "fsubp"; break; 864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC8: mnem = "fmulp"; break; 865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF8: mnem = "fdivp"; break; 866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDF: 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (modrm_byte == 0xE0) { 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fnstsw_ax"; 874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if ((modrm_byte & 0xF8) == 0xE8) { 875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mnem = "fucomip"; 876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org has_register = true; 877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (has_register) { 884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7); 885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s", mnem); 887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return 2; 889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Mnemonics for instructions 0xF0 byte. 893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns NULL if the instruction is not handled here. 894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* F0Mnem(byte f0byte) { 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (f0byte) { 896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x18: return "prefetch"; 897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xA2: return "cpuid"; 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xBE: return "movsx_b"; 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xBF: return "movsx_w"; 900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xB6: return "movzx_b"; 901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xB7: return "movzx_w"; 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xAF: return "imul"; 903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xA5: return "shld"; 904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xAD: return "shrd"; 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xAC: return "shrd"; // 3-operand version. 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xAB: return "bts"; 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xBD: return "bsr"; 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: return NULL; 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Disassembled instruction '*instr' and writes it into 'out_buffer'. 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer, 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* instr) { 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org tmp_buffer_pos_ = 0; // starting to write as position 0 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* data = instr; 918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for hints. 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* branch_hint = NULL; 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We use these two prefixes only with branch prediction 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*data == 0x3E /*ds*/) { 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org branch_hint = "predicted taken"; 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x2E /*cs*/) { 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org branch_hint = "predicted not taken"; 926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool processed = true; // Will be set to false if the current instruction 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is not in 'instructions' table. 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const InstructionDesc& idesc = instruction_table_->Get(*data); 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (idesc.type) { 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ZERO_OPERANDS_INSTR: 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(idesc.mnem); 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case TWO_OPERANDS_INSTR: 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintOperands(idesc.mnem, idesc.op_order_, data); 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case JUMP_CONDITIONAL_SHORT_INSTR: 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += JumpConditionalShort(data, branch_hint); 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case REGISTER_INSTR: 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case MOVE_REG_INSTR: { 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("mov %s,%s", 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(*data & 0x07), 955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfAddress(addr)); 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CALL_JUMP_INSTR: { 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5; 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr)); 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case SHORT_IMMEDIATE_INSTR: { 968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); 969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr)); 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case BYTE_IMMEDIATE_INSTR: { 975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]); 976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NO_INSTR: 981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org processed = false; 982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNIMPLEMENTED(); // This type is not implemented. 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org //---------------------------- 988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!processed) { 989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (*data) { 990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC2: 991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); 992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9955c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 0x6B: { 9965c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data++; 9975c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data += PrintOperands("imul", REG_OPER_OP_ORDER, data); 9985c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer(",%d", *data); 9995c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data++; 10005c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org } break; 10015c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org 10025c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org case 0x69: { 10035c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data++; 10045c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data += PrintOperands("imul", REG_OPER_OP_ORDER, data); 10055c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org AppendToBuffer(",%d", *reinterpret_cast<int32_t*>(data)); 10065c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org data += 4; 1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF6: 1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { data++; 1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (regop == eax) { 1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("test_b "); 1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightByteOperand(data); 1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t imm = *data; 1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", imm); 1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x81: // fall through 1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x83: // 0x81 with sign extension bit set 1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintImmediateOp(data); 1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x0F: 1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { byte f0byte = data[1]; 1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* f0mnem = F0Mnem(f0byte); 1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (f0byte == 0x18) { 1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* suffix[] = {"nta", "1", "2", "3"}; 1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s%s ", f0mnem, suffix[regop & 0x03]); 1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x1F && data[2] == 0) { 1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 3 byte nop. 1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) { 1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 4 byte nop. 1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 4; 1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 && 1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data[4] == 0) { 1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 5 byte nop. 1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 && 1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data[4] == 0 && data[5] == 0 && data[6] == 0) { 1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 7 byte nop. 1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 7; 1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 && 1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data[4] == 0 && data[5] == 0 && data[6] == 0 && 1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data[7] == 0) { 1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 8 byte nop. 1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 8; 1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0xA2 || f0byte == 0x31) { 1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s", f0mnem); 1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x28) { 1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movaps %s,%s", 1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte >= 0x53 && f0byte <= 0x5F) { 1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* const pseudo_op[] = { 1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "rcpps", 1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "andps", 1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "andnps", 1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "orps", 1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "xorps", 1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "addps", 1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "mulps", 1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cvtps2pd", 1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cvtdq2ps", 1082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "subps", 1083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "minps", 1084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "divps", 1085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "maxps", 1086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 1087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", 1092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org pseudo_op[f0byte - 0x53], 1093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop)); 1094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0x50) { 1096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movmskps %s,%s", 1100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(regop), 1101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte== 0xC6) { 1104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // shufps xmm, xmm/m128, imm8 1105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("shufps %s,%s,%d", 1110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm), 1111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if ((f0byte & 0xF0) == 0x80) { 1115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += JumpConditional(data, branch_hint); 1116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || 1117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org f0byte == 0xB7 || f0byte == 0xAF) { 1118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); 1120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if ((f0byte & 0xF0) == 0x90) { 1121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += SetCC(data); 1122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if ((f0byte & 0xF0) == 0x40) { 1123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += CMov(data); 1124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) { 1125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // shrd, shld, bts 1126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", f0mnem); 1128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (f0byte == 0xAB) { 1132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s,cl", NameOfCPURegister(regop)); 1135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (f0byte == 0xBD) { 1137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", f0mnem, NameOfCPURegister(regop)); 1141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x8F: 1149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { data++; 1150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (regop == eax) { 1153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pop "); 1154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFF: 1160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { data++; 1161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = NULL; 1164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (regop) { 1165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case esi: mnem = "push"; break; 1166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case eax: mnem = "inc"; break; 1167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ecx: mnem = "dec"; break; 1168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case edx: mnem = "call"; break; 1169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case esp: mnem = "jmp"; break; 1170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: mnem = "???"; 1171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 1173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC7: // imm32, fall through 1178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC6: // imm8 1179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { bool is_byte = *data == 0xC6; 1180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_byte) { 1182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", "mov_b"); 1183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightByteOperand(data); 1184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t imm = *data; 1185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", imm); 1186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", "mov"); 1189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t imm = *reinterpret_cast<int32_t*>(data); 1191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", imm); 1192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 4; 1193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x80: 1198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { data++; 1199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = NULL; 1202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (regop) { 1203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 5: mnem = "subb"; break; 1204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 7: mnem = "cmpb"; break; 1205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: UnimplementedInstruction(); 1206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", mnem); 1208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightByteOperand(data); 1209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t imm = *data; 1210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", imm); 1211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x88: // 8bit, fall through 1216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x89: // 32bit 1217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { bool is_byte = *data == 0x88; 1218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_byte) { 1222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", "mov_b"); 1223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightByteOperand(data); 1224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfByteCPURegister(regop)); 1225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", "mov"); 1227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x66: // prefix 1234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (*data == 0x66) data++; 1235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*data == 0xf && data[1] == 0x1f) { 1236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 0x66 prefix 1237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x90) { 1238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 0x66 prefix 1239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x8B) { 1240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); 1242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x89) { 1243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("mov_w "); 1247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xC7) { 1250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s ", "mov_w"); 1252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int imm = *reinterpret_cast<int16_t*>(data); 1254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",0x%x", imm); 1255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x0F) { 1257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*data == 0x38) { 1259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*data == 0x17) { 1261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("ptest %s,%s", 1265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x2A) { 1269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // movntdqa 1270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movntdqa %s,", NameOfXMMRegister(regop)); 1274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x3A) { 1279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*data == 0x0B) { 1281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("roundsd %s,%s,%d", 1286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm), 1288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x16) { 1291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pextrd %s,%s,%d", 1296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(regop), 1297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm), 1298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x17) { 1301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("extractps %s,%s,%d", 1306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(rm), 1307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x22) { 1311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pinsrd %s,%s,%d", 1316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(rm), 1318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x2E || *data == 0x2F) { 1324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = (*data == 0x2E) ? "ucomisd" : "comisd"; 1325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (mod == 0x3) { 1329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,%s", mnem, 1330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x50) { 1338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movmskpd %s,%s", 1342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfCPURegister(regop), 1343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x54) { 1346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("andpd %s,%s", 1350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x56) { 1354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("orpd %s,%s", 1358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x57) { 1362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("xorpd %s,%s", 1366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x6E) { 1370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movd %s,", NameOfXMMRegister(regop)); 1374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x6F) { 1376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movdqa %s,", NameOfXMMRegister(regop)); 1380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x70) { 1382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pshufd %s,%s,%d", 1387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm), 1389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x76) { 1392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pcmpeqd %s,%s", 1396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x90) { 1400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("nop"); // 2 byte nop. 1402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xF3) { 1403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("psllq %s,%s", 1407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x73) { 1411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(regop == esi || regop == edx); 1416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,%d", 1417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (regop == esi) ? "psllq" : "psrlq", 1418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm), 1419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int>(imm8)); 1420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xD3) { 1422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("psrlq %s,%s", 1426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x7F) { 1430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movdqa "); 1431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0x7E) { 1437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movd "); 1441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xDB) { 1444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pand %s,%s", 1448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xE7) { 1452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (mod == 3) { 1456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movntdq "); 1457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xEF) { 1463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("pxor %s,%s", 1467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*data == 0xEB) { 1471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("por %s,%s", 1475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data++; 1478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xFE: 1487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { data++; 1488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (regop == ecx) { 1491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("dec_b "); 1492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x68: 1500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data+1)); 1501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 1502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x6A: 1505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); 1506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xA8: 1510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); 1511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xA9: 1515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); 1516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 5; 1517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD1: // fall through 1520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD3: // fall through 1521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xC1: 1522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += D1D3C1Instruction(data); 1523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD8: // fall through 1526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xD9: // fall through 1527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDA: // fall through 1528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDB: // fall through 1529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDC: // fall through 1530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDD: // fall through 1531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDE: // fall through 1532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xDF: 1533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += FPUInstruction(data); 1534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xEB: 1537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += JumpShort(data); 1538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF2: 1541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*(data+1) == 0x0F) { 1542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte b2 = *(data+2); 1543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (b2 == 0x11) { 1544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movsd "); 1545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x10) { 1551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movsd %s,", NameOfXMMRegister(regop)); 1555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x5A) { 1557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("cvtsd2ss %s,", NameOfXMMRegister(regop)); 1561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* mnem = "?"; 1564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (b2) { 1565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x2A: mnem = "cvtsi2sd"; break; 1566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x2C: mnem = "cvttsd2si"; break; 1567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x2D: mnem = "cvtsd2si"; break; 1568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x51: mnem = "sqrtsd"; break; 1569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x58: mnem = "addsd"; break; 1570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x59: mnem = "mulsd"; break; 1571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x5C: mnem = "subsd"; break; 1572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0x5E: mnem = "divsd"; break; 1573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (b2 == 0x2A) { 1578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightOperand(data); 1580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x2C || b2 == 0x2D) { 1581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop)); 1582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0xC2) { 1584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Intel manual 2A, Table 3-18. 1585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const char* const pseudo_op[] = { 1586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpeqsd", 1587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpltsd", 1588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmplesd", 1589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpunordsd", 1590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpneqsd", 1591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpnltsd", 1592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpnlesd", 1593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "cmpordsd" 1594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 1595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,%s", 1596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org pseudo_op[data[1]], 1597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(regop), 1598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameOfXMMRegister(rm)); 1599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF3: 1611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*(data+1) == 0x0F) { 1612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte b2 = *(data+2); 1613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (b2 == 0x11) { 1614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movss "); 1615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x10) { 1621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movss %s,", NameOfXMMRegister(regop)); 1625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x2C) { 1627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop)); 1631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x5A) { 1633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); 1637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x6F) { 1639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop)); 1643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (b2 == 0x7F) { 1645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("movdqu "); 1646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 3; 1647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int mod, regop, rm; 1648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org get_modrm(*data, &mod, ®op, &rm); 1649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += PrintRightXMMOperand(data); 1650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*(data+1) == 0xA5) { 1655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("rep_movs"); 1657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (*(data+1) == 0xAB) { 1658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += 2; 1659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AppendToBuffer("rep_stos"); 1660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 0xF7: 1666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data += F7Instruction(data); 1667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UnimplementedInstruction(); 1671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (tmp_buffer_pos_ < sizeof tmp_buffer_) { 1675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org tmp_buffer_[tmp_buffer_pos_] = '\0'; 1676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int instr_len = data - instr; 1679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr_len == 0) { 1680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org printf("%02x", *data); 1681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1682e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr_len > 0); // Ensure progress. 1683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int outp = 0; 1685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Instruction bytes. 1686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (byte* bp = instr; bp < data; bp++) { 168770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org outp += v8::internal::SNPrintF(out_buffer + outp, "%02x", *bp); 1688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 6 - instr_len; i >= 0; i--) { 169070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org outp += v8::internal::SNPrintF(out_buffer + outp, " "); 1691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 169370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org outp += v8::internal::SNPrintF(out_buffer + outp, " %s", tmp_buffer_.start()); 1694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return instr_len; 1695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} // NOLINT (function is too long) 1696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------------------ 1699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* cpu_regs[8] = { 1702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" 1703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* byte_cpu_regs[8] = { 1707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" 1708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* xmm_regs[8] = { 1712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" 1713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 1714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfAddress(byte* addr) const { 171770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org v8::internal::SNPrintF(tmp_buffer_, "%p", addr); 1718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return tmp_buffer_.start(); 1719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfConstant(byte* addr) const { 1723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return NameOfAddress(addr); 1724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfCPURegister(int reg) const { 1728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (0 <= reg && reg < 8) return cpu_regs[reg]; 1729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return "noreg"; 1730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfByteCPURegister(int reg) const { 1734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (0 <= reg && reg < 8) return byte_cpu_regs[reg]; 1735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return "noreg"; 1736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfXMMRegister(int reg) const { 1740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (0 <= reg && reg < 8) return xmm_regs[reg]; 1741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return "noxmmreg"; 1742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameInCode(byte* addr) const { 1746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // X87 does not embed debug strings at the moment. 1747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ""; 1749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------------------ 1753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgDisassembler::Disassembler(const NameConverter& converter) 1755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : converter_(converter) {} 1756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgDisassembler::~Disassembler() {} 1759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* instruction) { 1763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DisassemblerX87 d(converter_, false /*do not crash if unimplemented*/); 1764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return d.InstructionDecode(buffer, instruction); 1765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The IA-32 assembler does not currently use constant pools. 1769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 1770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org/*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NameConverter converter; 1774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Disassembler d(converter); 1775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (byte* pc = begin; pc < end;) { 1776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org v8::internal::EmbeddedVector<char, 128> buffer; 1777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org buffer[0] = '\0'; 1778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org byte* prev_pc = pc; 1779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org pc += d.InstructionDecode(buffer, pc); 1780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org fprintf(f, "%p", prev_pc); 1781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org fprintf(f, " "); 1782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (byte* bp = prev_pc; bp < pc; bp++) { 1784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org fprintf(f, "%02x", *bp); 1785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 1787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org fprintf(f, " "); 1788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org fprintf(f, " %s\n", buffer.start()); 1790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} // namespace disasm 1795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 1797