1fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <assert.h> 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdio.h> 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdarg.h> 317276f14ca716596e0a0d17539516370c1f453847kasper.lund 327276f14ca716596e0a0d17539516370c1f453847kasper.lund#include "v8.h" 339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "disasm.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace disasm { 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum OperandOrder { 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNSET_OP_ORDER = 0, 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen REG_OPER_OP_ORDER, 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OPER_REG_OP_ORDER 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//------------------------------------------------------------------ 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Tables 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//------------------------------------------------------------------ 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct ByteMnemonic { 5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int b; // -1 terminates, otherwise must be in range (0..255) 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem; 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OperandOrder op_order_; 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 577c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic two_operands_instr[] = { 58c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {0x01, "add", OPER_REG_OP_ORDER}, 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x03, "add", REG_OPER_OP_ORDER}, 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x09, "or", OPER_REG_OP_ORDER}, 6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x0B, "or", REG_OPER_OP_ORDER}, 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x1B, "sbb", REG_OPER_OP_ORDER}, 63b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x21, "and", OPER_REG_OP_ORDER}, 64b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x23, "and", REG_OPER_OP_ORDER}, 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x29, "sub", OPER_REG_OP_ORDER}, 660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org {0x2A, "subb", REG_OPER_OP_ORDER}, 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x2B, "sub", REG_OPER_OP_ORDER}, 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x31, "xor", OPER_REG_OP_ORDER}, 6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x33, "xor", REG_OPER_OP_ORDER}, 70b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x38, "cmpb", OPER_REG_OP_ORDER}, 71b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x3A, "cmpb", REG_OPER_OP_ORDER}, 72b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x3B, "cmp", REG_OPER_OP_ORDER}, 73b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x84, "test_b", REG_OPER_OP_ORDER}, 74b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x85, "test", REG_OPER_OP_ORDER}, 757be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org {0x87, "xchg", REG_OPER_OP_ORDER}, 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x8A, "mov_b", REG_OPER_OP_ORDER}, 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x8B, "mov", REG_OPER_OP_ORDER}, 78b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org {0x8D, "lea", REG_OPER_OP_ORDER}, 7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {-1, "", UNSET_OP_ORDER} 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 837c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic zero_operands_instr[] = { 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xC3, "ret", UNSET_OP_ORDER}, 8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xC9, "leave", UNSET_OP_ORDER}, 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x90, "nop", UNSET_OP_ORDER}, 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xF4, "hlt", UNSET_OP_ORDER}, 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xCC, "int3", UNSET_OP_ORDER}, 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x60, "pushad", UNSET_OP_ORDER}, 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x61, "popad", UNSET_OP_ORDER}, 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x9C, "pushfd", UNSET_OP_ORDER}, 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x9D, "popfd", UNSET_OP_ORDER}, 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x9E, "sahf", UNSET_OP_ORDER}, 9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x99, "cdq", UNSET_OP_ORDER}, 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x9B, "fwait", UNSET_OP_ORDER}, 96ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org {0xFC, "cld", UNSET_OP_ORDER}, 979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com {0xAB, "stos", UNSET_OP_ORDER}, 9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {-1, "", UNSET_OP_ORDER} 9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1027c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic call_jump_instr[] = { 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xE8, "call", UNSET_OP_ORDER}, 10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0xE9, "jmp", UNSET_OP_ORDER}, 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {-1, "", UNSET_OP_ORDER} 10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1097c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const ByteMnemonic short_immediate_instr[] = { 11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x05, "add", UNSET_OP_ORDER}, 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x0D, "or", UNSET_OP_ORDER}, 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x15, "adc", UNSET_OP_ORDER}, 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x25, "and", UNSET_OP_ORDER}, 11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x2D, "sub", UNSET_OP_ORDER}, 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x35, "xor", UNSET_OP_ORDER}, 11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {0x3D, "cmp", UNSET_OP_ORDER}, 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen {-1, "", UNSET_OP_ORDER} 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Generally we don't want to generate these because they are subject to partial 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// register stalls. They are included for completeness and because the cmp 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// variant is used by the RecordWrite stub. Because it does not update the 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// register it is not subject to partial register stalls. 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic ByteMnemonic byte_immediate_instr[] = { 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {0x0c, "or", UNSET_OP_ORDER}, 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {0x24, "and", UNSET_OP_ORDER}, 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {0x34, "xor", UNSET_OP_ORDER}, 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {0x3c, "cmp", UNSET_OP_ORDER}, 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com {-1, "", UNSET_OP_ORDER} 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1347c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const char* const jump_conditional_mnem[] = { 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen /*0*/ "jo", "jno", "jc", "jnc", 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen /*4*/ "jz", "jnz", "jna", "ja", 13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen /*8*/ "js", "jns", "jpe", "jpo", 13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen /*12*/ "jl", "jnl", "jng", "jg" 13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1427c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const char* const set_conditional_mnem[] = { 1437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org /*0*/ "seto", "setno", "setc", "setnc", 1447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org /*4*/ "setz", "setnz", "setna", "seta", 1457be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org /*8*/ "sets", "setns", "setpe", "setpo", 1467be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org /*12*/ "setl", "setnl", "setng", "setg" 1477be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org}; 1487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1497be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 1507c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgstatic const char* const conditional_move_mnem[] = { 1519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", 1529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", 1539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", 1549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" 1559d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}; 1569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 1579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum InstructionType { 15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NO_INSTR, 16043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ZERO_OPERANDS_INSTR, 16143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TWO_OPERANDS_INSTR, 16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JUMP_CONDITIONAL_SHORT_INSTR, 16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen REGISTER_INSTR, 16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MOVE_REG_INSTR, 16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CALL_JUMP_INSTR, 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SHORT_IMMEDIATE_INSTR, 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com BYTE_IMMEDIATE_INSTR 16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstruct InstructionDesc { 17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem; 17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionType type; 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OperandOrder op_order_; 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass InstructionTable { 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionTable(); 18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const InstructionDesc& Get(byte x) const { return instructions_[x]; } 182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static InstructionTable* get_instance() { 183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static InstructionTable table; 184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return &table; 185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionDesc instructions_[256]; 18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Clear(); 19043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Init(); 1917c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org void CopyTable(const ByteMnemonic bm[], InstructionType type); 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetTableRange(InstructionType type, 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte start, 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte end, 19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem); 19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void AddJumpConditionalShort(); 19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenInstructionTable::InstructionTable() { 20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Clear(); 20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Init(); 20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid InstructionTable::Clear() { 20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < 256; i++) { 20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen instructions_[i].mnem = ""; 20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen instructions_[i].type = NO_INSTR; 21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen instructions_[i].op_order_ = UNSET_OP_ORDER; 21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid InstructionTable::Init() { 21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); 21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); 21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CopyTable(call_jump_instr, CALL_JUMP_INSTR); 21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR); 22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AddJumpConditionalShort(); 22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); 2267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. 22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); 22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2317c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgvoid InstructionTable::CopyTable(const ByteMnemonic bm[], 2327c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org InstructionType type) { 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; bm[i].b >= 0; i++) { 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionDesc* id = &instructions_[bm[i].b]; 23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->mnem = bm[i].mnem; 23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->op_order_ = bm[i].op_order_; 2373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. 23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->type = type; 23943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid InstructionTable::SetTableRange(InstructionType type, 24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte start, 24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte end, 24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem) { 24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (byte b = start; b <= end; b++) { 24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionDesc* id = &instructions_[b]; 2493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->mnem = mnem; 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->type = type; 25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid InstructionTable::AddJumpConditionalShort() { 25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (byte b = 0x70; b <= 0x7F; b++) { 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen InstructionDesc* id = &instructions_[b]; 2593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(NO_INSTR, id->type); // Information not already entered. 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->mnem = jump_conditional_mnem[b & 0x0F]; 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen id->type = JUMP_CONDITIONAL_SHORT_INSTR; 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The IA32 disassembler implementation. 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass DisassemblerIA32 { 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DisassemblerIA32(const NameConverter& converter, 27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool abort_on_unimplemented = true) 27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : converter_(converter), 272394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com instruction_table_(InstructionTable::get_instance()), 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tmp_buffer_pos_(0), 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen abort_on_unimplemented_(abort_on_unimplemented) { 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tmp_buffer_[0] = '\0'; 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~DisassemblerIA32() {} 27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Writes one disassembled instruction into 'buffer' (0-terminated). 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the length of the disassembled machine instruction in bytes. 282b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction); 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const NameConverter& converter_; 286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com InstructionTable* instruction_table_; 287b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org v8::internal::EmbeddedVector<char, 128> tmp_buffer_; 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen unsigned int tmp_buffer_pos_; 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool abort_on_unimplemented_; 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen enum { 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen eax = 0, 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ecx = 1, 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen edx = 2, 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ebx = 3, 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen esp = 4, 29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ebp = 5, 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen esi = 6, 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen edi = 7 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 303c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org enum ShiftOpcodeExtension { 304c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kROL = 0, 305c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kROR = 1, 306c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kRCL = 2, 307c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kRCR = 3, 308c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kSHL = 4, 309c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org KSHR = 5, 310c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org kSAR = 7 311c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org }; 312c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 313c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* NameOfCPURegister(int reg) const { 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return converter_.NameOfCPURegister(reg); 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3197be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org const char* NameOfByteCPURegister(int reg) const { 3207be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org return converter_.NameOfByteCPURegister(reg); 3217be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 3227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 3237be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* NameOfXMMRegister(int reg) const { 32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return converter_.NameOfXMMRegister(reg); 32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* NameOfAddress(byte* addr) const { 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return converter_.NameOfAddress(addr); 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Disassembler helper functions. 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void get_modrm(byte data, int* mod, int* regop, int* rm) { 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *mod = (data >> 6) & 3; 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *regop = (data & 0x38) >> 3; 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *rm = data & 7; 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void get_sib(byte data, int* scale, int* index, int* base) { 34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *scale = (data >> 6) & 3; 34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *index = (data >> 3) & 7; 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *base = data & 7; 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org typedef const char* (DisassemblerIA32::*RegisterNameMapping)(int reg) const; 34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3507be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name); 35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int PrintRightOperand(byte* modrmp); 3527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org int PrintRightByteOperand(byte* modrmp); 353badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int PrintRightXMMOperand(byte* modrmp); 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int PrintOperands(const char* mnem, OperandOrder op_order, byte* data); 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int PrintImmediateOp(byte* data); 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int F7Instruction(byte* data); 35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int D1D3C1Instruction(byte* data); 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int JumpShort(byte* data); 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int JumpConditional(byte* data, const char* comment); 36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int JumpConditionalShort(byte* data, const char* comment); 3617be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org int SetCC(byte* data); 3629d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int CMov(byte* data); 36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int FPUInstruction(byte* data); 3643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start); 3653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int RegisterFPUInstruction(int escape_opcode, byte modrm_byte); 36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void AppendToBuffer(const char* format, ...); 36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void UnimplementedInstruction() { 37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (abort_on_unimplemented_) { 37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNIMPLEMENTED(); 37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("'Unimplemented Instruction'"); 37443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid DisassemblerIA32::AppendToBuffer(const char* format, ...) { 380b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_; 38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 383b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int result = v8::internal::OS::VSNPrintF(buf, format, args); 38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tmp_buffer_pos_ += result; 38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgint DisassemblerIA32::PrintRightOperandHelper( 3897be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org byte* modrmp, 390badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org RegisterNameMapping direct_register_name) { 39143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*modrmp, &mod, ®op, &rm); 393badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org RegisterNameMapping register_name = (mod == 3) ? direct_register_name : 394badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org &DisassemblerIA32::NameOfCPURegister; 39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (mod) { 39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0: 39743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (rm == ebp) { 39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1); 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("[0x%x]", disp); 40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 5; 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (rm == esp) { 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte sib = *(modrmp + 1); 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int scale, index, base; 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_sib(sib, &scale, &index, &base); 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (index == esp && base == esp && scale == 0 /*times_1*/) { 4067be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("[%s]", (this->*register_name)(rm)); 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (base == ebp) { 40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); 41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("[%s*%d+0x%x]", 4117be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org (this->*register_name)(index), 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1 << scale, 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen disp); 41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 6; 41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (index != esp && base != ebp) { 41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // [base+index*scale] 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("[%s+%s*%d]", 4187be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org (this->*register_name)(base), 4197be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org (this->*register_name)(index), 42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1 << scale); 42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1; 42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 4277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("[%s]", (this->*register_name)(rm)); 42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1; 42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 1: // fall through 43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 2: 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (rm == esp) { 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte sib = *(modrmp + 1); 43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int scale, index, base; 43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_sib(sib, &scale, &index, &base); 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int disp = 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2) : *(modrmp + 2); 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) { 4407be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp); 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("[%s+%s*%d+0x%x]", 4437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org (this->*register_name)(base), 4447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org (this->*register_name)(index), 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1 << scale, 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen disp); 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mod == 2 ? 6 : 3; 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // No sib. 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int disp = 45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1) : *(modrmp + 1); 4537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp); 45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mod == 2 ? 5 : 2; 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 3: 4587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("%s", (this->*register_name)(rm)); 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1; 46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1; 46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgint DisassemblerIA32::PrintRightOperand(byte* modrmp) { 4697be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister); 4707be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 4717be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 4727be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 4737be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgint DisassemblerIA32::PrintRightByteOperand(byte* modrmp) { 4747be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org return PrintRightOperandHelper(modrmp, 4757be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org &DisassemblerIA32::NameOfByteCPURegister); 4767be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 4777be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 4787be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 479badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgint DisassemblerIA32::PrintRightXMMOperand(byte* modrmp) { 480badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org return PrintRightOperandHelper(modrmp, 481badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org &DisassemblerIA32::NameOfXMMRegister); 482badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 483badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 484badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used including the current *data. 48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'. 48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::PrintOperands(const char* mnem, 48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OperandOrder op_order, 48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* data) { 49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte modrm = *data; 49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(modrm, &mod, ®op, &rm); 49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int advance = 0; 49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (op_order) { 49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case REG_OPER_OP_ORDER: { 49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop)); 49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen advance = PrintRightOperand(data); 49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 49943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case OPER_REG_OP_ORDER: { 50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s ", mnem); 50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen advance = PrintRightOperand(data); 50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",%s", NameOfCPURegister(regop)); 50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 50643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 50743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 50943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 51043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return advance; 51143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 51243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used by machine instruction, including *data byte. 51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Writes immediate instructions to 'tmp_buffer_'. 51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::PrintImmediateOp(byte* data) { 51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool sign_extension_bit = (*data & 0x02) != 0; 51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte modrm = *(data+1); 51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(modrm, &mod, ®op, &rm); 52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = "Imm???"; 52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (regop) { 52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0: mnem = "add"; break; 52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 1: mnem = "or"; break; 52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 2: mnem = "adc"; break; 52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 4: mnem = "and"; break; 52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 5: mnem = "sub"; break; 52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 6: mnem = "xor"; break; 52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 7: mnem = "cmp"; break; 53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: UnimplementedInstruction(); 53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s ", mnem); 53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int count = PrintRightOperand(data+1); 53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (sign_extension_bit) { 53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",0x%x", *(data + 1 + count)); 53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1 + count + 1 /*int8*/; 53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count)); 53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1 + count + 4 /*int32_t*/; 54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used, including *data. 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::F7Instruction(byte* data) { 5463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0xF7, *data); 54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte modrm = *(data+1); 54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(modrm, &mod, ®op, &rm); 55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (mod == 3 && regop != 0) { 55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = NULL; 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (regop) { 55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 2: mnem = "not"; break; 55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 3: mnem = "neg"; break; 55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 4: mnem = "mul"; break; 556d2899aa30a5af82205029034f7a491d49c48fc68yangguo@chromium.org case 5: mnem = "imul"; break; 55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 7: mnem = "idiv"; break; 55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: UnimplementedInstruction(); 55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s", mnem, NameOfCPURegister(rm)); 56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (mod == 3 && regop == eax) { 56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int32_t imm = *reinterpret_cast<int32_t*>(data+2); 56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("test %s,0x%x", NameOfCPURegister(rm), imm); 56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 6; 56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (regop == eax) { 56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("test "); 56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int count = PrintRightOperand(data+1); 56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int32_t imm = *reinterpret_cast<int32_t*>(data+1+count); 57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",0x%x", imm); 57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 1+count+4 /*int32_t*/; 57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 578e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::D1D3C1Instruction(byte* data) { 58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte op = *data; 5813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); 58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte modrm = *(data+1); 58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(modrm, &mod, ®op, &rm); 58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int imm8 = -1; 58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int num_bytes = 2; 58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (mod == 3) { 58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = NULL; 589c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org switch (regop) { 590c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case kROL: mnem = "rol"; break; 591c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case kROR: mnem = "ror"; break; 592c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case kRCL: mnem = "rcl"; break; 593ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org case kRCR: mnem = "rcr"; break; 594c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case kSHL: mnem = "shl"; break; 595c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case KSHR: mnem = "shr"; break; 596c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org case kSAR: mnem = "sar"; break; 597c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org default: UnimplementedInstruction(); 598c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org } 59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (op == 0xD1) { 60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen imm8 = 1; 60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (op == 0xC1) { 60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen imm8 = *(data+2); 60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen num_bytes = 3; 60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (op == 0xD3) { 605c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // Shift/rotate by cl. 60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 6073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_NE(NULL, mnem); 60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s,", mnem, NameOfCPURegister(rm)); 60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (imm8 > 0) { 61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%d", imm8); 61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("cl"); 61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return num_bytes; 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used, including *data. 62243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::JumpShort(byte* data) { 6233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0xEB, *data); 62443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte b = *(data+1); 62543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* dest = data + static_cast<int8_t>(b) + 2; 62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("jmp %s", NameOfAddress(dest)); 62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 62943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 63143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used, including *data. 63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::JumpConditional(byte* data, const char* comment) { 6333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0x0F, *data); 63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte cond = *(data+1) & 0x0F; 63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6; 63643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = jump_conditional_mnem[cond]; 63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (comment != NULL) { 63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(", %s", comment); 64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 6; // includes 0x0F 64243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used, including *data. 64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::JumpConditionalShort(byte* data, const char* comment) { 64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte cond = *data & 0x0F; 64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte b = *(data+1); 64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* dest = data + static_cast<int8_t>(b) + 2; 65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = jump_conditional_mnem[cond]; 65143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s", mnem, NameOfAddress(dest)); 65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (comment != NULL) { 65343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(", %s", comment); 65443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns number of bytes used, including *data. 6607be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgint DisassemblerIA32::SetCC(byte* data) { 6613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0x0F, *data); 6627be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org byte cond = *(data+1) & 0x0F; 6637be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org const char* mnem = set_conditional_mnem[cond]; 6647be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer("%s ", mnem); 6657be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org PrintRightByteOperand(data+2); 6663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return 3; // Includes 0x0F. 6677be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 6687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6697be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 6707be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org// Returns number of bytes used, including *data. 6719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comint DisassemblerIA32::CMov(byte* data) { 6723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0x0F, *data); 6739d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com byte cond = *(data + 1) & 0x0F; 6749d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com const char* mnem = conditional_move_mnem[cond]; 6759d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 6769d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return 2 + op_size; // includes 0x0F 6779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com} 6789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 6799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 6809d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com// Returns number of bytes used, including *data. 68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint DisassemblerIA32::FPUInstruction(byte* data) { 6823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte escape_opcode = *data; 6833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ASSERT_EQ(0xD8, escape_opcode & 0xF8); 6843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte modrm_byte = *(data+1); 6853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 6863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte >= 0xC0) { 6873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return RegisterFPUInstruction(escape_opcode, modrm_byte); 6883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 6893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1); 6903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 6913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 6923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 6933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerIA32::MemoryFPUInstruction(int escape_opcode, 6943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int modrm_byte, 6953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte* modrm_start) { 6963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org const char* mnem = "?"; 6973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int regop = (modrm_byte >> 3) & 0x7; // reg/op field of modrm byte. 6983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (escape_opcode) { 6993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD9: switch (regop) { 7003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fld_s"; break; 7013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fstp_s"; break; 7023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 7: mnem = "fstcw"; break; 70343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: UnimplementedInstruction(); 70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 7053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDB: switch (regop) { 7083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fild_s"; break; 7093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 1: mnem = "fisttp_s"; break; 7103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 2: mnem = "fist_s"; break; 7113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fistp_s"; break; 71243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: UnimplementedInstruction(); 71343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 7143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDD: switch (regop) { 7173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0: mnem = "fld_d"; break; 718c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org case 1: mnem = "fisttp_d"; break; 719c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org case 2: mnem = "fst_d"; break; 7203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 3: mnem = "fstp_d"; break; 7213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 7223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDF: switch (regop) { 7263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 5: mnem = "fild_d"; break; 7273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 7: mnem = "fistp_d"; break; 7283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 7293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 7333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org AppendToBuffer("%s ", mnem); 7353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int count = PrintRightOperand(modrm_start); 7363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return count + 1; 7373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 7383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgint DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, 7403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org byte modrm_byte) { 7413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org bool has_register = false; // Is the FPU register encoded in modrm_byte? 7423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org const char* mnem = "?"; 7433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (escape_opcode) { 7453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD8: 7463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org UnimplementedInstruction(); 7473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD9: 7503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 7514a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org case 0xC0: 7524a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org mnem = "fld"; 7534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org has_register = true; 7544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org break; 7553811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: 7563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fxch"; 7573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 7583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: 7603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte) { 7613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE0: mnem = "fchs"; break; 7623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE1: mnem = "fabs"; break; 7633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE4: mnem = "ftst"; break; 7643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fld1"; break; 765ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case 0xEB: mnem = "fldpi"; break; 766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case 0xED: mnem = "fldln2"; break; 7673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xEE: mnem = "fldz"; break; 76864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xF0: mnem = "f2xm1"; break; 769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case 0xF1: mnem = "fyl2x"; break; 7703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF5: mnem = "fprem1"; break; 7713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF7: mnem = "fincstp"; break; 7723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fprem"; break; 77364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xFC: mnem = "frndint"; break; 77464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case 0xFD: mnem = "fscale"; break; 7753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xFE: mnem = "fsin"; break; 7763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xFF: mnem = "fcos"; break; 7773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 7783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7803811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7813811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDA: 7833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xE9) { 7843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucompp"; 7853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 7863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org UnimplementedInstruction(); 7873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 7893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDB: 7913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if ((modrm_byte & 0xF8) == 0xE8) { 7923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucomi"; 7933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 7943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else if (modrm_byte == 0xE2) { 7953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fclex"; 79664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (modrm_byte == 0xE3) { 79764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org mnem = "fninit"; 7983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 7993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org UnimplementedInstruction(); 8003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDC: 8043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 8053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 8063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "fadd"; break; 8073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fsub"; break; 8083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: mnem = "fmul"; break; 8093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fdiv"; break; 8103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8113811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8123811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDD: 8153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 8163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 8173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "ffree"; break; 8183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xD8: mnem = "fstp"; break; 8193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDE: 8243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xD9) { 8253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fcompp"; 8263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 8273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 8283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org switch (modrm_byte & 0xF8) { 8293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC0: mnem = "faddp"; break; 8303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xE8: mnem = "fsubp"; break; 8313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xC8: mnem = "fmulp"; break; 8323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xF8: mnem = "fdivp"; break; 8333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org case 0xDF: 8393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (modrm_byte == 0xE0) { 8403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fnstsw_ax"; 8413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else if ((modrm_byte & 0xF8) == 0xE8) { 8423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org mnem = "fucomip"; 8433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org has_register = true; 8443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org break; 8463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org default: UnimplementedInstruction(); 8483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 8493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 8503811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org if (has_register) { 8513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7); 8523811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } else { 8537276f14ca716596e0a0d17539516370c1f453847kasper.lund AppendToBuffer("%s", mnem); 85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 2; 85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Mnemonics for instructions 0xF0 byte. 86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns NULL if the instruction is not handled here. 86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const char* F0Mnem(byte f0byte) { 86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (f0byte) { 8631af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org case 0x18: return "prefetch"; 86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xA2: return "cpuid"; 86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x31: return "rdtsc"; 86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xBE: return "movsx_b"; 86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xBF: return "movsx_w"; 86843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xB6: return "movzx_b"; 86943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xB7: return "movzx_w"; 87043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xAF: return "imul"; 87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xA5: return "shld"; 87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xAD: return "shrd"; 8731f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org case 0xAC: return "shrd"; // 3-operand version. 87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xAB: return "bts"; 87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: return NULL; 87643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8806f10e41fef1524c70846d970268de222e41c594cager@chromium.org// Disassembled instruction '*instr' and writes it into 'out_buffer'. 881b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, 88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* instr) { 88343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tmp_buffer_pos_ = 0; // starting to write as position 0 88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* data = instr; 88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check for hints. 88643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* branch_hint = NULL; 8876f10e41fef1524c70846d970268de222e41c594cager@chromium.org // We use these two prefixes only with branch prediction 88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*data == 0x3E /*ds*/) { 88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen branch_hint = "predicted taken"; 89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 89143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (*data == 0x2E /*cs*/) { 89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen branch_hint = "predicted not taken"; 89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool processed = true; // Will be set to false if the current instruction 89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is not in 'instructions' table. 897394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com const InstructionDesc& idesc = instruction_table_->Get(*data); 89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (idesc.type) { 89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case ZERO_OPERANDS_INSTR: 90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(idesc.mnem); 90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 90443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case TWO_OPERANDS_INSTR: 90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 90643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintOperands(idesc.mnem, idesc.op_order_, data); 90743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case JUMP_CONDITIONAL_SHORT_INSTR: 91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += JumpConditionalShort(data, branch_hint); 91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case REGISTER_INSTR: 91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07)); 91543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 91643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 91743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case MOVE_REG_INSTR: { 91943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); 92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("mov %s,%s", 92143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NameOfCPURegister(*data & 0x07), 92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NameOfAddress(addr)); 92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 5; 92443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 92543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 92743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case CALL_JUMP_INSTR: { 92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5; 92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr)); 93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 5; 93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case SHORT_IMMEDIATE_INSTR: { 93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); 93643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr)); 93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 5; 93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case BYTE_IMMEDIATE_INSTR: { 942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AppendToBuffer("%s al, 0x%x", idesc.mnem, data[1]); 943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com data += 2; 944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 94743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case NO_INSTR: 94843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen processed = false; 94943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNIMPLEMENTED(); // This type is not implemented. 95343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen //---------------------------- 95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!processed) { 95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (*data) { 95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xC2: 95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1)); 95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 3; 96043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x69: // fall through 96343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x6B: 96443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { int mod, regop, rm; 96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*(data+1), &mod, ®op, &rm); 96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int32_t imm = 96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *data == 0x6B ? *(data+2) : *reinterpret_cast<int32_t*>(data+2); 96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("imul %s,%s,0x%x", 96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NameOfCPURegister(regop), 97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NameOfCPURegister(rm), 97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen imm); 97243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2 + (*data == 0x6B ? 1 : 4); 97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 97643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xF6: 9772356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org { data++; 9782356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org int mod, regop, rm; 9792356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org get_modrm(*data, &mod, ®op, &rm); 9802356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org if (regop == eax) { 9812356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org AppendToBuffer("test_b "); 982badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 9832356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org int32_t imm = *data; 9842356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org AppendToBuffer(",0x%x", imm); 9852356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org data++; 98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x81: // fall through 99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x83: // 0x81 with sign extension bit set 99443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintImmediateOp(data); 99543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x0F: 99864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org { byte f0byte = data[1]; 99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* f0mnem = F0Mnem(f0byte); 10001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (f0byte == 0x18) { 10011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org int mod, regop, rm; 10021af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org get_modrm(*data, &mod, ®op, &rm); 10031af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org const char* suffix[] = {"nta", "1", "2", "3"}; 10041af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org AppendToBuffer("%s%s ", f0mnem, suffix[regop & 0x03]); 10051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org data += PrintRightOperand(data); 100664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (f0byte == 0x1F && data[2] == 0) { 100764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 3 byte nop. 100864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 3; 100964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) { 101064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 4 byte nop. 101164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 4; 101264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 && 101364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data[4] == 0) { 101464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 5 byte nop. 101564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 5; 101664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 && 101764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data[4] == 0 && data[5] == 0 && data[6] == 0) { 101864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 7 byte nop. 101964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 7; 102064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 && 102164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data[4] == 0 && data[5] == 0 && data[6] == 0 && 102264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data[7] == 0) { 102364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 8 byte nop. 102464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 8; 10251af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } else if (f0byte == 0xA2 || f0byte == 0x31) { 102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s", f0mnem); 102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2; 1028c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org } else if (f0byte == 0x28) { 1029c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org data += 2; 1030c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org int mod, regop, rm; 1031c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 1032c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org AppendToBuffer("movaps %s,%s", 1033c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org NameOfXMMRegister(regop), 1034c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org NameOfXMMRegister(rm)); 1035c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org data++; 1036fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org } else if (f0byte == 0x57) { 1037fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org data += 2; 1038fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org int mod, regop, rm; 1039fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 1040fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org AppendToBuffer("xorps %s,%s", 1041fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org NameOfXMMRegister(regop), 1042fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org NameOfXMMRegister(rm)); 1043fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org data++; 10444121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org } else if (f0byte == 0x50) { 10454121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org data += 2; 10464121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org int mod, regop, rm; 10474121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org get_modrm(*data, &mod, ®op, &rm); 10484121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org AppendToBuffer("movmskps %s,%s", 10494121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org NameOfCPURegister(regop), 10504121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org NameOfXMMRegister(rm)); 10514121f23c2a08f8ef03858df1477b81a0450b94a0ulan@chromium.org data++; 105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if ((f0byte & 0xF0) == 0x80) { 105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += JumpConditional(data, branch_hint); 105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || 105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen f0byte == 0xB7 || f0byte == 0xAF) { 105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2; 105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); 10587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } else if ((f0byte & 0xF0) == 0x90) { 10597be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org data += SetCC(data); 10609d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if ((f0byte & 0xF0) == 0x40) { 10619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com data += CMov(data); 106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2; 106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) { 106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // shrd, shld, bts 106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s ", f0mnem); 106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 106843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintRightOperand(data); 107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (f0byte == 0xAB) { 107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",%s", NameOfCPURegister(regop)); 107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",%s,cl", NameOfCPURegister(regop)); 107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x8F: 108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { data++; 108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (regop == eax) { 108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("pop "); 108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintRightOperand(data); 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xFF: 109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { data++; 109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = NULL; 109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (regop) { 109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case esi: mnem = "push"; break; 110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case eax: mnem = "inc"; break; 11016f10e41fef1524c70846d970268de222e41c594cager@chromium.org case ecx: mnem = "dec"; break; 110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case edx: mnem = "call"; break; 110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case esp: mnem = "jmp"; break; 110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: mnem = "???"; 110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("%s ", mnem); 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintRightOperand(data); 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xC7: // imm32, fall through 111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xC6: // imm8 111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { bool is_byte = *data == 0xC6; 111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 1115badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (is_byte) { 1116badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s ", "mov_b"); 1117badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 1118badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int32_t imm = *data; 1119badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",0x%x", imm); 1120badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data++; 1121badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1122badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s ", "mov"); 1123badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 1124badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int32_t imm = *reinterpret_cast<int32_t*>(data); 1125badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",0x%x", imm); 1126badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += 4; 1127badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org case 0x80: 11327be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org { data++; 11330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int mod, regop, rm; 11340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 11350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org const char* mnem = NULL; 11360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org switch (regop) { 11370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 5: mnem = "subb"; break; 11380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 7: mnem = "cmpb"; break; 11390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org default: UnimplementedInstruction(); 11400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 11410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("%s ", mnem); 1142badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 11437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org int32_t imm = *data; 11447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org AppendToBuffer(",0x%x", imm); 11457be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org data++; 11467be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org } 11477be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org break; 11487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x88: // 8bit, fall through 115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x89: // 32bit 115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { bool is_byte = *data == 0x88; 115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 1155badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (is_byte) { 1156badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s ", "mov_b"); 1157badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightByteOperand(data); 1158badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",%s", NameOfByteCPURegister(regop)); 1159badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1160badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s ", "mov"); 1161badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 1162badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",%s", NameOfCPURegister(regop)); 1163badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x66: // prefix 116864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org while (*data == 0x66) data++; 116964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (*data == 0xf && data[1] == 0x1f) { 117064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 0x66 prefix 117164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (*data == 0x90) { 117264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 0x66 prefix 117364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (*data == 0x8B) { 117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); 117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (*data == 0x89) { 117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data++; 117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("mov_w "); 118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += PrintRightOperand(data); 118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",%s", NameOfCPURegister(regop)); 11839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (*data == 0x0F) { 11849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com data++; 1185ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (*data == 0x38) { 1186ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data++; 1187ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (*data == 0x17) { 1188ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data++; 1189ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int mod, regop, rm; 1190ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org get_modrm(*data, &mod, ®op, &rm); 1191ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org AppendToBuffer("ptest %s,%s", 1192ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org NameOfXMMRegister(regop), 1193ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org NameOfXMMRegister(rm)); 1194ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data++; 11951af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } else if (*data == 0x2A) { 11961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // movntdqa 11971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org data++; 11981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org int mod, regop, rm; 11991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org get_modrm(*data, &mod, ®op, &rm); 12001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org AppendToBuffer("movntdqa %s,", NameOfXMMRegister(regop)); 12011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org data += PrintRightOperand(data); 1202ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 1203ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org UnimplementedInstruction(); 1204ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 12055f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0x3A) { 12065f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 12074acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (*data == 0x0B) { 12084acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org data++; 12094acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org int mod, regop, rm; 12104acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org get_modrm(*data, &mod, ®op, &rm); 12114acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 12124acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org AppendToBuffer("roundsd %s,%s,%d", 12134acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org NameOfXMMRegister(regop), 12144acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org NameOfXMMRegister(rm), 12154acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org static_cast<int>(imm8)); 12164acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org data += 2; 12174acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } else if (*data == 0x16) { 12185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 12195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 12205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 12215f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 12225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("pextrd %s,%s,%d", 1223d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com NameOfCPURegister(regop), 12245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm), 12255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org static_cast<int>(imm8)); 12265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data += 2; 122764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (*data == 0x17) { 122864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data++; 122964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org int mod, regop, rm; 123064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org get_modrm(*data, &mod, ®op, &rm); 123164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 123264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("extractps %s,%s,%d", 123364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org NameOfCPURegister(regop), 123464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org NameOfXMMRegister(rm), 123564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org static_cast<int>(imm8)); 123664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data += 2; 1237d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else if (*data == 0x22) { 1238d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com data++; 1239d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com int mod, regop, rm; 1240d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com get_modrm(*data, &mod, ®op, &rm); 1241d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com int8_t imm8 = static_cast<int8_t>(data[1]); 1242d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com AppendToBuffer("pinsrd %s,%s,%d", 1243d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com NameOfXMMRegister(regop), 1244d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com NameOfCPURegister(rm), 1245d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com static_cast<int>(imm8)); 1246d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com data += 2; 12475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else { 12485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org UnimplementedInstruction(); 12495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 1250f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else if (*data == 0x2E || *data == 0x2F) { 1251f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org const char* mnem = (*data == 0x2E) ? "ucomisd" : "comisd"; 12529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com data++; 12539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int mod, regop, rm; 12549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com get_modrm(*data, &mod, ®op, &rm); 1255f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org if (mod == 0x3) { 1256f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org AppendToBuffer("%s %s,%s", mnem, 1257f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org NameOfXMMRegister(regop), 1258f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org NameOfXMMRegister(rm)); 1259f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org data++; 1260f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else { 1261f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1262f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org data += PrintRightOperand(data); 1263f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 1264f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } else if (*data == 0x50) { 1265f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org data++; 1266f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org int mod, regop, rm; 1267f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org get_modrm(*data, &mod, ®op, &rm); 1268f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org AppendToBuffer("movmskpd %s,%s", 1269f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org NameOfCPURegister(regop), 12709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com NameOfXMMRegister(rm)); 12719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com data++; 12725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0x54) { 12735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 12745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 12755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 12765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("andpd %s,%s", 12775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(regop), 12785f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm)); 12795f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 1280471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org } else if (*data == 0x56) { 1281471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data++; 1282471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org int mod, regop, rm; 1283471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org get_modrm(*data, &mod, ®op, &rm); 1284471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org AppendToBuffer("orpd %s,%s", 1285471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org NameOfXMMRegister(regop), 1286471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org NameOfXMMRegister(rm)); 1287471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org data++; 1288846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org } else if (*data == 0x57) { 1289846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org data++; 1290846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org int mod, regop, rm; 1291846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org get_modrm(*data, &mod, ®op, &rm); 1292846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org AppendToBuffer("xorpd %s,%s", 1293846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org NameOfXMMRegister(regop), 1294846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org NameOfXMMRegister(rm)); 1295846fb74ad58083497b91fc4668a56fddb36fbd2esgjesse@chromium.org data++; 1296ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else if (*data == 0x6E) { 1297ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data++; 1298ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int mod, regop, rm; 1299ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org get_modrm(*data, &mod, ®op, &rm); 1300ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org AppendToBuffer("movd %s,", NameOfXMMRegister(regop)); 1301ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data += PrintRightOperand(data); 13020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (*data == 0x6F) { 13030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data++; 13040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int mod, regop, rm; 13050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 13060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("movdqa %s,", NameOfXMMRegister(regop)); 1307badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 13085f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0x70) { 13095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 13115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 13125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 13135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("pshufd %s,%s,%d", 13145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(regop), 13155f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm), 13165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org static_cast<int>(imm8)); 13175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data += 2; 131833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org } else if (*data == 0x76) { 131933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org data++; 132033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int mod, regop, rm; 132133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org get_modrm(*data, &mod, ®op, &rm); 132233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org AppendToBuffer("pcmpeqd %s,%s", 132333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org NameOfXMMRegister(regop), 132433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org NameOfXMMRegister(rm)); 132533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org data++; 132664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else if (*data == 0x90) { 132764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org data++; 132864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org AppendToBuffer("nop"); // 2 byte nop. 1329c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (*data == 0xF3) { 1330c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 1331c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int mod, regop, rm; 1332c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org get_modrm(*data, &mod, ®op, &rm); 1333c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org AppendToBuffer("psllq %s,%s", 1334c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(regop), 1335c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(rm)); 1336c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 13375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0x73) { 13385f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 13405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 13415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int8_t imm8 = static_cast<int8_t>(data[1]); 1342c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org ASSERT(regop == esi || regop == edx); 1343c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org AppendToBuffer("%s %s,%d", 1344c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org (regop == esi) ? "psllq" : "psrlq", 13455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm), 13465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org static_cast<int>(imm8)); 13475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data += 2; 1348c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (*data == 0xD3) { 1349c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 1350c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int mod, regop, rm; 1351c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org get_modrm(*data, &mod, ®op, &rm); 1352c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org AppendToBuffer("psrlq %s,%s", 1353c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(regop), 1354c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(rm)); 1355c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 13560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (*data == 0x7F) { 13570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("movdqa "); 13580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data++; 13590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int mod, regop, rm; 13600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 1361badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 13620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 13635f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0x7E) { 13645f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 13665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 13675f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("movd "); 13685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data += PrintRightOperand(data); 13695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 13705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } else if (*data == 0xDB) { 13715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 13735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 13745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("pand %s,%s", 13755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(regop), 13765f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm)); 13775f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13781af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } else if (*data == 0xE7) { 13791af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org data++; 13801af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org int mod, regop, rm; 13811af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org get_modrm(*data, &mod, ®op, &rm); 1382badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (mod == 3) { 1383badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("movntdq "); 1384badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 1385badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 1386badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } else { 1387badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org UnimplementedInstruction(); 1388badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org } 1389ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else if (*data == 0xEF) { 13905f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 13915f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org int mod, regop, rm; 13925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org get_modrm(*data, &mod, ®op, &rm); 13935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org AppendToBuffer("pxor %s,%s", 13945f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(regop), 13955f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org NameOfXMMRegister(rm)); 13965f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org data++; 1397c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org } else if (*data == 0xEB) { 1398c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 1399c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org int mod, regop, rm; 1400c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org get_modrm(*data, &mod, ®op, &rm); 1401c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org AppendToBuffer("por %s,%s", 1402c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(regop), 1403c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org NameOfXMMRegister(rm)); 1404c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org data++; 14059d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 14069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com UnimplementedInstruction(); 14079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 140943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 141043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xFE: 141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { data++; 141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 14174a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (regop == ecx) { 14184a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org AppendToBuffer("dec_b "); 14194a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org data += PrintRightOperand(data); 142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 142543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x68: 142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data+1)); 142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 5; 142943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x6A: 143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); 143343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2; 143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xA8: 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1)); 143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 2; 143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xA9: 144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1)); 144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 5; 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xD1: // fall through 144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xD3: // fall through 144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xC1: 144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += D1D3C1Instruction(data); 145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xD9: // fall through 14537276f14ca716596e0a0d17539516370c1f453847kasper.lund case 0xDA: // fall through 145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xDB: // fall through 145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xDC: // fall through 145643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xDD: // fall through 145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xDE: // fall through 145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xDF: 145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += FPUInstruction(data); 146043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xEB: 146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += JumpShort(data); 146443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 146543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xF2: 146743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (*(data+1) == 0x0F) { 146843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte b2 = *(data+2); 146943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (b2 == 0x11) { 147043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("movsd "); 147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 3; 147243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 147343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 1474badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 147543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer(",%s", NameOfXMMRegister(regop)); 147643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else if (b2 == 0x10) { 147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 3; 147843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 147943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 148043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen AppendToBuffer("movsd %s,", NameOfXMMRegister(regop)); 1481badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 14827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x5A) { 14837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += 3; 14847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int mod, regop, rm; 14857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 14867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org AppendToBuffer("cvtsd2ss %s,", NameOfXMMRegister(regop)); 14877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += PrintRightXMMOperand(data); 148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 148943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* mnem = "?"; 149043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (b2) { 149143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x2A: mnem = "cvtsi2sd"; break; 1492f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org case 0x2C: mnem = "cvttsd2si"; break; 149346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org case 0x2D: mnem = "cvtsd2si"; break; 1494ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org case 0x51: mnem = "sqrtsd"; break; 149543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x58: mnem = "addsd"; break; 149643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x59: mnem = "mulsd"; break; 149743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x5C: mnem = "subsd"; break; 149843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0x5E: mnem = "divsd"; break; 149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 150043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += 3; 150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int mod, regop, rm; 150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen get_modrm(*data, &mod, ®op, &rm); 150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (b2 == 0x2A) { 1504badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1505badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightOperand(data); 150646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else if (b2 == 0x2C || b2 == 0x2D) { 1507badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop)); 1508badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 1509c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org } else if (b2 == 0xC2) { 1510c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // Intel manual 2A, Table 3-18. 1511c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org const char* const pseudo_op[] = { 1512c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpeqsd", 1513c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpltsd", 1514c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmplesd", 1515c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpunordsd", 1516c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpneqsd", 1517c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpnltsd", 1518c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpnlesd", 1519c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org "cmpordsd" 1520c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org }; 1521c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org AppendToBuffer("%s %s,%s", 1522c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org pseudo_op[data[1]], 1523c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org NameOfXMMRegister(regop), 1524c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org NameOfXMMRegister(rm)); 1525c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org data += 2; 152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 1527badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop)); 1528badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 153243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 153343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xF3: 15370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (*(data+1) == 0x0F) { 15387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org byte b2 = *(data+2); 15397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (b2 == 0x11) { 15407979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org AppendToBuffer("movss "); 15417979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += 3; 15427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int mod, regop, rm; 15437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 15447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += PrintRightXMMOperand(data); 15457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 15467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x10) { 15477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += 3; 15487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int mod, regop, rm; 15497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 15507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org AppendToBuffer("movss %s,", NameOfXMMRegister(regop)); 15517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org data += PrintRightXMMOperand(data); 15527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x2C) { 15530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data += 3; 1554badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org int mod, regop, rm; 1555badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org get_modrm(*data, &mod, ®op, &rm); 1556badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop)); 1557badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 15587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x5A) { 1559ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data += 3; 1560ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int mod, regop, rm; 1561ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org get_modrm(*data, &mod, ®op, &rm); 1562badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); 1563badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 15647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x6F) { 15650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data += 3; 15660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int mod, regop, rm; 15670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 15680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop)); 1569badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 15707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } else if (b2 == 0x7F) { 15710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("movdqu "); 15720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data += 3; 15730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org int mod, regop, rm; 15740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org get_modrm(*data, &mod, ®op, &rm); 1575badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org data += PrintRightXMMOperand(data); 15760c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer(",%s", NameOfXMMRegister(regop)); 15770c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else { 15780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org UnimplementedInstruction(); 15790c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 15800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else if (*(data+1) == 0xA5) { 15810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org data += 2; 15820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org AppendToBuffer("rep_movs"); 1583ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else if (*(data+1) == 0xAB) { 1584ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org data += 2; 1585ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org AppendToBuffer("rep_stos"); 158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0xF7: 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data += F7Instruction(data); 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnimplementedInstruction(); 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tmp_buffer_pos_ < sizeof tmp_buffer_) { 160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tmp_buffer_[tmp_buffer_pos_] = '\0'; 160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int instr_len = data - instr; 16050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org if (instr_len == 0) { 16060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org printf("%02x", *data); 16070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 16087276f14ca716596e0a0d17539516370c1f453847kasper.lund ASSERT(instr_len > 0); // Ensure progress. 16097276f14ca716596e0a0d17539516370c1f453847kasper.lund 16107276f14ca716596e0a0d17539516370c1f453847kasper.lund int outp = 0; 16117276f14ca716596e0a0d17539516370c1f453847kasper.lund // Instruction bytes. 16127276f14ca716596e0a0d17539516370c1f453847kasper.lund for (byte* bp = instr; bp < data; bp++) { 16137276f14ca716596e0a0d17539516370c1f453847kasper.lund outp += v8::internal::OS::SNPrintF(out_buffer + outp, 16147276f14ca716596e0a0d17539516370c1f453847kasper.lund "%02x", 16157276f14ca716596e0a0d17539516370c1f453847kasper.lund *bp); 16167276f14ca716596e0a0d17539516370c1f453847kasper.lund } 16177276f14ca716596e0a0d17539516370c1f453847kasper.lund for (int i = 6 - instr_len; i >= 0; i--) { 16187276f14ca716596e0a0d17539516370c1f453847kasper.lund outp += v8::internal::OS::SNPrintF(out_buffer + outp, 16197276f14ca716596e0a0d17539516370c1f453847kasper.lund " "); 16207276f14ca716596e0a0d17539516370c1f453847kasper.lund } 16217276f14ca716596e0a0d17539516370c1f453847kasper.lund 16227276f14ca716596e0a0d17539516370c1f453847kasper.lund outp += v8::internal::OS::SNPrintF(out_buffer + outp, 16237276f14ca716596e0a0d17539516370c1f453847kasper.lund " %s", 1624b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org tmp_buffer_.start()); 162543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return instr_len; 1626c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} // NOLINT (function is too long) 162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//------------------------------------------------------------------------------ 163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 163243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const char* cpu_regs[8] = { 16337be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" 16347be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org}; 16357be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 16367be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 16377be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgstatic const char* byte_cpu_regs[8] = { 16387be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" 163943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 164043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const char* xmm_regs[8] = { 16437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" 164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* NameConverter::NameOfAddress(byte* addr) const { 1648ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); 1649ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return tmp_buffer_.start(); 165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* NameConverter::NameOfConstant(byte* addr) const { 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NameOfAddress(addr); 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* NameConverter::NameOfCPURegister(int reg) const { 165943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (0 <= reg && reg < 8) return cpu_regs[reg]; 166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return "noreg"; 166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16647be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgconst char* NameConverter::NameOfByteCPURegister(int reg) const { 16657be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org if (0 <= reg && reg < 8) return byte_cpu_regs[reg]; 16667be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org return "noreg"; 16677be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org} 16687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 16697be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org 167043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* NameConverter::NameOfXMMRegister(int reg) const { 167143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (0 <= reg && reg < 8) return xmm_regs[reg]; 167243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return "noxmmreg"; 167343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* NameConverter::NameInCode(byte* addr) const { 167743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // IA32 does not embed debug strings at the moment. 167843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 167943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ""; 168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//------------------------------------------------------------------------------ 168443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDisassembler::Disassembler(const NameConverter& converter) 168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : converter_(converter) {} 168743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDisassembler::~Disassembler() {} 169043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 169143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1692b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 169343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* instruction) { 169443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DisassemblerIA32 d(converter_, false /*do not crash if unimplemented*/); 1695b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return d.InstructionDecode(buffer, instruction); 169643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 169743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 169843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16997276f14ca716596e0a0d17539516370c1f453847kasper.lund// The IA-32 assembler does not currently use constant pools. 17007276f14ca716596e0a0d17539516370c1f453847kasper.lundint Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 17017276f14ca716596e0a0d17539516370c1f453847kasper.lund 17027276f14ca716596e0a0d17539516370c1f453847kasper.lund 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 17043bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org NameConverter converter; 17053bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org Disassembler d(converter); 170643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (byte* pc = begin; pc < end;) { 1707b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org v8::internal::EmbeddedVector<char, 128> buffer; 170843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen buffer[0] = '\0'; 170943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* prev_pc = pc; 1710b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org pc += d.InstructionDecode(buffer, pc); 171143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fprintf(f, "%p", prev_pc); 171243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fprintf(f, " "); 171343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 171443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (byte* bp = prev_pc; bp < pc; bp++) { 171543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fprintf(f, "%02x", *bp); 171643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 171743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 6 - (pc - prev_pc); i >= 0; i--) { 171843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fprintf(f, " "); 171943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1720b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org fprintf(f, " %s\n", buffer.start()); 172143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 172243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 172343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} // namespace disasm 17269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 17279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 1728