1a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 2a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj/*---------------------------------------------------------------*/ 3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin host_amd64_defs.c ---*/ 4a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj/*---------------------------------------------------------------*/ 5a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 6a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj/* 7752f90673ebbb6b2f55fc5e46606dea371313713sewardj This file is part of Valgrind, a dynamic binary instrumentation 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj framework. 9a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2004-2017 OpenWorks LLP 11752f90673ebbb6b2f55fc5e46606dea371313713sewardj info@open-works.net 127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 13752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is free software; you can redistribute it and/or 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj modify it under the terms of the GNU General Public License as 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj published by the Free Software Foundation; either version 2 of the 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj License, or (at your option) any later version. 177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 18752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is distributed in the hope that it will be useful, but 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj General Public License for more details. 227bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj You should have received a copy of the GNU General Public License 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj along with this program; if not, write to the Free Software 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26752f90673ebbb6b2f55fc5e46606dea371313713sewardj 02110-1301, USA. 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 28752f90673ebbb6b2f55fc5e46606dea371313713sewardj The GNU General Public License is contained in the file COPYING. 29a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 30a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj Neither the names of the U.S. Department of Energy nor the 31a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj University of California nor the names of its contributors may be 32a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj used to endorse or promote products derived from this software 33a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj without prior written permission. 34a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj*/ 35a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 36a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj#include "libvex_basictypes.h" 37a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj#include "libvex.h" 38a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj#include "libvex_trc_values.h" 39a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 41cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_generic_regs.h" 42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "host_amd64_defs.h" 43c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 44c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 45c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj/* --------- Registers. --------- */ 46c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 47a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjconst RRegUniverse* getRRegUniverse_AMD64 ( void ) 48a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 49a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj /* The real-register universe is a big constant, so we just want to 50a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj initialise it once. */ 51a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj static RRegUniverse rRegUniverse_AMD64; 52a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj static Bool rRegUniverse_AMD64_initted = False; 53a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 54a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj /* Handy shorthand, nothing more */ 55a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj RRegUniverse* ru = &rRegUniverse_AMD64; 56a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 57a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj /* This isn't thread-safe. Sigh. */ 58a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj if (LIKELY(rRegUniverse_AMD64_initted)) 59a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return ru; 60a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 61a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj RRegUniverse__init(ru); 62a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 63a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj /* Add the registers. The initial segment of this array must be 64a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj those available for allocation by reg-alloc, and those that 65a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj follow are not available for allocation. */ 66a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RSI(); 67a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RDI(); 68a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R8(); 69a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R9(); 70a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R12(); 71a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R13(); 72a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R14(); 73a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R15(); 74a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RBX(); 75a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM3(); 76a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM4(); 77a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM5(); 78a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM6(); 79a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM7(); 80a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM8(); 81a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM9(); 82a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM10(); 83a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM11(); 84a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM12(); 85a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R10(); 86a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->allocable = ru->size; 87a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj /* And other regs, not available to the allocator. */ 88a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RAX(); 89a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RCX(); 90a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RDX(); 91a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RSP(); 92a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_RBP(); 93a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_R11(); 94a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM0(); 95a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj ru->regs[ru->size++] = hregAMD64_XMM1(); 96a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 97a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rRegUniverse_AMD64_initted = True; 98a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 99a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj RRegUniverse__check_is_sane(ru); 100a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return ru; 101a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 102a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 103a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 104c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardjvoid ppHRegAMD64 ( HReg reg ) 105614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj{ 106614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj Int r; 10755085f8680acc89d727e321f3b34cae1a8c4093aflorian static const HChar* ireg64_names[16] 108614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj = { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", 109614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }; 110614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj /* Be generic for all virtual regs. */ 111614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj if (hregIsVirtual(reg)) { 112614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppHReg(reg); 113614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 114614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj } 115614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj /* But specific for real regs. */ 116614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj switch (hregClass(reg)) { 117614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case HRcInt64: 118a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj r = hregEncoding(reg); 119614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vassert(r >= 0 && r < 16); 120614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("%s", ireg64_names[r]); 121614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 122614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case HRcVec128: 123a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj r = hregEncoding(reg); 124614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vassert(r >= 0 && r < 16); 125614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("%%xmm%d", r); 126614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 127614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj default: 128614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vpanic("ppHRegAMD64"); 129614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj } 130c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 131c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 132549e06463d433ee6351b72dc9107f22ce4305250sewardjstatic void ppHRegAMD64_lo32 ( HReg reg ) 133549e06463d433ee6351b72dc9107f22ce4305250sewardj{ 134549e06463d433ee6351b72dc9107f22ce4305250sewardj Int r; 13555085f8680acc89d727e321f3b34cae1a8c4093aflorian static const HChar* ireg32_names[16] 136a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj = { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", 137a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" }; 138549e06463d433ee6351b72dc9107f22ce4305250sewardj /* Be generic for all virtual regs. */ 139549e06463d433ee6351b72dc9107f22ce4305250sewardj if (hregIsVirtual(reg)) { 140549e06463d433ee6351b72dc9107f22ce4305250sewardj ppHReg(reg); 141549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf("d"); 142549e06463d433ee6351b72dc9107f22ce4305250sewardj return; 143549e06463d433ee6351b72dc9107f22ce4305250sewardj } 144549e06463d433ee6351b72dc9107f22ce4305250sewardj /* But specific for real regs. */ 145549e06463d433ee6351b72dc9107f22ce4305250sewardj switch (hregClass(reg)) { 146549e06463d433ee6351b72dc9107f22ce4305250sewardj case HRcInt64: 147a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj r = hregEncoding(reg); 148549e06463d433ee6351b72dc9107f22ce4305250sewardj vassert(r >= 0 && r < 16); 149549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf("%s", ireg32_names[r]); 150549e06463d433ee6351b72dc9107f22ce4305250sewardj return; 151549e06463d433ee6351b72dc9107f22ce4305250sewardj default: 152549e06463d433ee6351b72dc9107f22ce4305250sewardj vpanic("ppHRegAMD64_lo32: invalid regclass"); 153549e06463d433ee6351b72dc9107f22ce4305250sewardj } 154549e06463d433ee6351b72dc9107f22ce4305250sewardj} 155549e06463d433ee6351b72dc9107f22ce4305250sewardj 156c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 157f67eadf04f5150178e589060f03381300d28e540sewardj/* --------- Condition codes, Intel encoding. --------- */ 158f67eadf04f5150178e589060f03381300d28e540sewardj 15955085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showAMD64CondCode ( AMD64CondCode cond ) 160f67eadf04f5150178e589060f03381300d28e540sewardj{ 161f67eadf04f5150178e589060f03381300d28e540sewardj switch (cond) { 162f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_O: return "o"; 163f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NO: return "no"; 164f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_B: return "b"; 165f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NB: return "nb"; 166f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_Z: return "z"; 167f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NZ: return "nz"; 168f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_BE: return "be"; 169f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NBE: return "nbe"; 170f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_S: return "s"; 171f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NS: return "ns"; 172f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_P: return "p"; 173f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NP: return "np"; 174f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_L: return "l"; 175f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NL: return "nl"; 176f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_LE: return "le"; 177f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_NLE: return "nle"; 178f67eadf04f5150178e589060f03381300d28e540sewardj case Acc_ALWAYS: return "ALWAYS"; 179f67eadf04f5150178e589060f03381300d28e540sewardj default: vpanic("ppAMD64CondCode"); 180f67eadf04f5150178e589060f03381300d28e540sewardj } 181f67eadf04f5150178e589060f03381300d28e540sewardj} 182614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 183614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 184614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj/* --------- AMD64AMode: memory address expressions. --------- */ 185614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 186614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjAMD64AMode* AMD64AMode_IR ( UInt imm32, HReg reg ) { 187d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64AMode* am = LibVEX_Alloc_inline(sizeof(AMD64AMode)); 188614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->tag = Aam_IR; 189614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IR.imm = imm32; 190614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IR.reg = reg; 191614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return am; 192614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 193614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjAMD64AMode* AMD64AMode_IRRS ( UInt imm32, HReg base, HReg indEx, Int shift ) { 194d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64AMode* am = LibVEX_Alloc_inline(sizeof(AMD64AMode)); 195614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->tag = Aam_IRRS; 196614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IRRS.imm = imm32; 197614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IRRS.base = base; 198614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IRRS.index = indEx; 199614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj am->Aam.IRRS.shift = shift; 200614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vassert(shift >= 0 && shift <= 3); 201614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return am; 202614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 203614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 204614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjvoid ppAMD64AMode ( AMD64AMode* am ) { 205614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj switch (am->tag) { 206614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aam_IR: 207614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj if (am->Aam.IR.imm == 0) 208614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("("); 209614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj else 210614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("0x%x(", am->Aam.IR.imm); 211614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppHRegAMD64(am->Aam.IR.reg); 212614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf(")"); 213614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 214614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aam_IRRS: 215614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("0x%x(", am->Aam.IRRS.imm); 216614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppHRegAMD64(am->Aam.IRRS.base); 217614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf(","); 218614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppHRegAMD64(am->Aam.IRRS.index); 219614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf(",%d)", 1 << am->Aam.IRRS.shift); 220614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 221614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj default: 222614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vpanic("ppAMD64AMode"); 223614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj } 224614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 225614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 226f67eadf04f5150178e589060f03381300d28e540sewardjstatic void addRegUsage_AMD64AMode ( HRegUsage* u, AMD64AMode* am ) { 227f67eadf04f5150178e589060f03381300d28e540sewardj switch (am->tag) { 228f67eadf04f5150178e589060f03381300d28e540sewardj case Aam_IR: 229f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, am->Aam.IR.reg); 230f67eadf04f5150178e589060f03381300d28e540sewardj return; 231f67eadf04f5150178e589060f03381300d28e540sewardj case Aam_IRRS: 232f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, am->Aam.IRRS.base); 233f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, am->Aam.IRRS.index); 234f67eadf04f5150178e589060f03381300d28e540sewardj return; 235f67eadf04f5150178e589060f03381300d28e540sewardj default: 236f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("addRegUsage_AMD64AMode"); 237f67eadf04f5150178e589060f03381300d28e540sewardj } 238f67eadf04f5150178e589060f03381300d28e540sewardj} 239f67eadf04f5150178e589060f03381300d28e540sewardj 240f67eadf04f5150178e589060f03381300d28e540sewardjstatic void mapRegs_AMD64AMode ( HRegRemap* m, AMD64AMode* am ) { 241f67eadf04f5150178e589060f03381300d28e540sewardj switch (am->tag) { 242f67eadf04f5150178e589060f03381300d28e540sewardj case Aam_IR: 243f67eadf04f5150178e589060f03381300d28e540sewardj am->Aam.IR.reg = lookupHRegRemap(m, am->Aam.IR.reg); 244f67eadf04f5150178e589060f03381300d28e540sewardj return; 245f67eadf04f5150178e589060f03381300d28e540sewardj case Aam_IRRS: 246f67eadf04f5150178e589060f03381300d28e540sewardj am->Aam.IRRS.base = lookupHRegRemap(m, am->Aam.IRRS.base); 247f67eadf04f5150178e589060f03381300d28e540sewardj am->Aam.IRRS.index = lookupHRegRemap(m, am->Aam.IRRS.index); 248f67eadf04f5150178e589060f03381300d28e540sewardj return; 249f67eadf04f5150178e589060f03381300d28e540sewardj default: 250f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("mapRegs_AMD64AMode"); 251f67eadf04f5150178e589060f03381300d28e540sewardj } 252f67eadf04f5150178e589060f03381300d28e540sewardj} 253614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 254614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj/* --------- Operand, which can be reg, immediate or memory. --------- */ 255614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 256614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjAMD64RMI* AMD64RMI_Imm ( UInt imm32 ) { 257d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RMI* op = LibVEX_Alloc_inline(sizeof(AMD64RMI)); 258614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj op->tag = Armi_Imm; 259614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj op->Armi.Imm.imm32 = imm32; 260614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return op; 261614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 2628258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardjAMD64RMI* AMD64RMI_Reg ( HReg reg ) { 263d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RMI* op = LibVEX_Alloc_inline(sizeof(AMD64RMI)); 2648258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj op->tag = Armi_Reg; 2658258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj op->Armi.Reg.reg = reg; 2668258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return op; 2678258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 268614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjAMD64RMI* AMD64RMI_Mem ( AMD64AMode* am ) { 269d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RMI* op = LibVEX_Alloc_inline(sizeof(AMD64RMI)); 270614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj op->tag = Armi_Mem; 271614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj op->Armi.Mem.am = am; 272614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return op; 273614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 274614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 2759cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardjstatic void ppAMD64RMI_wrk ( AMD64RMI* op, Bool lo32 ) { 276614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj switch (op->tag) { 277614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Armi_Imm: 278614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("$0x%x", op->Armi.Imm.imm32); 279614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 2809cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Armi_Reg: 2819cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (lo32) 2829cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppHRegAMD64_lo32(op->Armi.Reg.reg); 2839cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj else 2849cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppHRegAMD64(op->Armi.Reg.reg); 285614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 286614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Armi_Mem: 287614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppAMD64AMode(op->Armi.Mem.am); 288614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 289614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj default: 290614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vpanic("ppAMD64RMI"); 291614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj } 292614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 2939cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardjvoid ppAMD64RMI ( AMD64RMI* op ) { 2949cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppAMD64RMI_wrk(op, False/*!lo32*/); 2959cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj} 2969cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardjvoid ppAMD64RMI_lo32 ( AMD64RMI* op ) { 2979cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppAMD64RMI_wrk(op, True/*lo32*/); 2989cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj} 299614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 300f67eadf04f5150178e589060f03381300d28e540sewardj/* An AMD64RMI can only be used in a "read" context (what would it mean 301f67eadf04f5150178e589060f03381300d28e540sewardj to write or modify a literal?) and so we enumerate its registers 302f67eadf04f5150178e589060f03381300d28e540sewardj accordingly. */ 303f67eadf04f5150178e589060f03381300d28e540sewardjstatic void addRegUsage_AMD64RMI ( HRegUsage* u, AMD64RMI* op ) { 304f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 305f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Imm: 306f67eadf04f5150178e589060f03381300d28e540sewardj return; 307f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Reg: 308f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, op->Armi.Reg.reg); 309f67eadf04f5150178e589060f03381300d28e540sewardj return; 310f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Mem: 311f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64AMode(u, op->Armi.Mem.am); 312f67eadf04f5150178e589060f03381300d28e540sewardj return; 313f67eadf04f5150178e589060f03381300d28e540sewardj default: 314f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("addRegUsage_AMD64RMI"); 315f67eadf04f5150178e589060f03381300d28e540sewardj } 316f67eadf04f5150178e589060f03381300d28e540sewardj} 317f67eadf04f5150178e589060f03381300d28e540sewardj 318f67eadf04f5150178e589060f03381300d28e540sewardjstatic void mapRegs_AMD64RMI ( HRegRemap* m, AMD64RMI* op ) { 319f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 320f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Imm: 321f67eadf04f5150178e589060f03381300d28e540sewardj return; 322f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Reg: 323f67eadf04f5150178e589060f03381300d28e540sewardj op->Armi.Reg.reg = lookupHRegRemap(m, op->Armi.Reg.reg); 324f67eadf04f5150178e589060f03381300d28e540sewardj return; 325f67eadf04f5150178e589060f03381300d28e540sewardj case Armi_Mem: 326f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64AMode(m, op->Armi.Mem.am); 327f67eadf04f5150178e589060f03381300d28e540sewardj return; 328f67eadf04f5150178e589060f03381300d28e540sewardj default: 329f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("mapRegs_AMD64RMI"); 330f67eadf04f5150178e589060f03381300d28e540sewardj } 331f67eadf04f5150178e589060f03381300d28e540sewardj} 332f67eadf04f5150178e589060f03381300d28e540sewardj 333f67eadf04f5150178e589060f03381300d28e540sewardj 334f67eadf04f5150178e589060f03381300d28e540sewardj/* --------- Operand, which can be reg or immediate only. --------- */ 335f67eadf04f5150178e589060f03381300d28e540sewardj 336f67eadf04f5150178e589060f03381300d28e540sewardjAMD64RI* AMD64RI_Imm ( UInt imm32 ) { 337d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RI* op = LibVEX_Alloc_inline(sizeof(AMD64RI)); 338f67eadf04f5150178e589060f03381300d28e540sewardj op->tag = Ari_Imm; 339f67eadf04f5150178e589060f03381300d28e540sewardj op->Ari.Imm.imm32 = imm32; 340f67eadf04f5150178e589060f03381300d28e540sewardj return op; 341f67eadf04f5150178e589060f03381300d28e540sewardj} 342f67eadf04f5150178e589060f03381300d28e540sewardjAMD64RI* AMD64RI_Reg ( HReg reg ) { 343d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RI* op = LibVEX_Alloc_inline(sizeof(AMD64RI)); 344f67eadf04f5150178e589060f03381300d28e540sewardj op->tag = Ari_Reg; 345f67eadf04f5150178e589060f03381300d28e540sewardj op->Ari.Reg.reg = reg; 346f67eadf04f5150178e589060f03381300d28e540sewardj return op; 347f67eadf04f5150178e589060f03381300d28e540sewardj} 348f67eadf04f5150178e589060f03381300d28e540sewardj 349f67eadf04f5150178e589060f03381300d28e540sewardjvoid ppAMD64RI ( AMD64RI* op ) { 350f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 351f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Imm: 352f67eadf04f5150178e589060f03381300d28e540sewardj vex_printf("$0x%x", op->Ari.Imm.imm32); 353f67eadf04f5150178e589060f03381300d28e540sewardj return; 354f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Reg: 355f67eadf04f5150178e589060f03381300d28e540sewardj ppHRegAMD64(op->Ari.Reg.reg); 356f67eadf04f5150178e589060f03381300d28e540sewardj return; 357f67eadf04f5150178e589060f03381300d28e540sewardj default: 358f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("ppAMD64RI"); 359f67eadf04f5150178e589060f03381300d28e540sewardj } 360f67eadf04f5150178e589060f03381300d28e540sewardj} 361f67eadf04f5150178e589060f03381300d28e540sewardj 362f67eadf04f5150178e589060f03381300d28e540sewardj/* An AMD64RI can only be used in a "read" context (what would it mean 363f67eadf04f5150178e589060f03381300d28e540sewardj to write or modify a literal?) and so we enumerate its registers 364f67eadf04f5150178e589060f03381300d28e540sewardj accordingly. */ 365f67eadf04f5150178e589060f03381300d28e540sewardjstatic void addRegUsage_AMD64RI ( HRegUsage* u, AMD64RI* op ) { 366f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 367f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Imm: 368f67eadf04f5150178e589060f03381300d28e540sewardj return; 369f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Reg: 370f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, op->Ari.Reg.reg); 371f67eadf04f5150178e589060f03381300d28e540sewardj return; 372f67eadf04f5150178e589060f03381300d28e540sewardj default: 373f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("addRegUsage_AMD64RI"); 374f67eadf04f5150178e589060f03381300d28e540sewardj } 375f67eadf04f5150178e589060f03381300d28e540sewardj} 376f67eadf04f5150178e589060f03381300d28e540sewardj 377f67eadf04f5150178e589060f03381300d28e540sewardjstatic void mapRegs_AMD64RI ( HRegRemap* m, AMD64RI* op ) { 378f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 379f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Imm: 380f67eadf04f5150178e589060f03381300d28e540sewardj return; 381f67eadf04f5150178e589060f03381300d28e540sewardj case Ari_Reg: 382f67eadf04f5150178e589060f03381300d28e540sewardj op->Ari.Reg.reg = lookupHRegRemap(m, op->Ari.Reg.reg); 383f67eadf04f5150178e589060f03381300d28e540sewardj return; 384f67eadf04f5150178e589060f03381300d28e540sewardj default: 385f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("mapRegs_AMD64RI"); 386f67eadf04f5150178e589060f03381300d28e540sewardj } 387f67eadf04f5150178e589060f03381300d28e540sewardj} 3888258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 3898258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 3908258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj/* --------- Operand, which can be reg or memory only. --------- */ 3918258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 3928258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardjAMD64RM* AMD64RM_Reg ( HReg reg ) { 393d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RM* op = LibVEX_Alloc_inline(sizeof(AMD64RM)); 3948258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj op->tag = Arm_Reg; 3958258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj op->Arm.Reg.reg = reg; 3968258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return op; 3978258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 39805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardjAMD64RM* AMD64RM_Mem ( AMD64AMode* am ) { 399d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64RM* op = LibVEX_Alloc_inline(sizeof(AMD64RM)); 40005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj op->tag = Arm_Mem; 40105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj op->Arm.Mem.am = am; 40205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return op; 40305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj} 4048258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 4058258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardjvoid ppAMD64RM ( AMD64RM* op ) { 4068258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj switch (op->tag) { 4078258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Arm_Mem: 4088258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj ppAMD64AMode(op->Arm.Mem.am); 4098258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return; 4108258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Arm_Reg: 4118258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj ppHRegAMD64(op->Arm.Reg.reg); 4128258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return; 4138258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj default: 4148258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj vpanic("ppAMD64RM"); 4158258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj } 4168258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 4178258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 418f67eadf04f5150178e589060f03381300d28e540sewardj/* Because an AMD64RM can be both a source or destination operand, we 419f67eadf04f5150178e589060f03381300d28e540sewardj have to supply a mode -- pertaining to the operand as a whole -- 420f67eadf04f5150178e589060f03381300d28e540sewardj indicating how it's being used. */ 421f67eadf04f5150178e589060f03381300d28e540sewardjstatic void addRegUsage_AMD64RM ( HRegUsage* u, AMD64RM* op, HRegMode mode ) { 422f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 423f67eadf04f5150178e589060f03381300d28e540sewardj case Arm_Mem: 424f67eadf04f5150178e589060f03381300d28e540sewardj /* Memory is read, written or modified. So we just want to 425f67eadf04f5150178e589060f03381300d28e540sewardj know the regs read by the amode. */ 426f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64AMode(u, op->Arm.Mem.am); 427f67eadf04f5150178e589060f03381300d28e540sewardj return; 428f67eadf04f5150178e589060f03381300d28e540sewardj case Arm_Reg: 429f67eadf04f5150178e589060f03381300d28e540sewardj /* reg is read, written or modified. Add it in the 430f67eadf04f5150178e589060f03381300d28e540sewardj appropriate way. */ 431f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, mode, op->Arm.Reg.reg); 432f67eadf04f5150178e589060f03381300d28e540sewardj return; 433f67eadf04f5150178e589060f03381300d28e540sewardj default: 434f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("addRegUsage_AMD64RM"); 435f67eadf04f5150178e589060f03381300d28e540sewardj } 436f67eadf04f5150178e589060f03381300d28e540sewardj} 437f67eadf04f5150178e589060f03381300d28e540sewardj 438f67eadf04f5150178e589060f03381300d28e540sewardjstatic void mapRegs_AMD64RM ( HRegRemap* m, AMD64RM* op ) 439f67eadf04f5150178e589060f03381300d28e540sewardj{ 440f67eadf04f5150178e589060f03381300d28e540sewardj switch (op->tag) { 441f67eadf04f5150178e589060f03381300d28e540sewardj case Arm_Mem: 442f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64AMode(m, op->Arm.Mem.am); 443f67eadf04f5150178e589060f03381300d28e540sewardj return; 444f67eadf04f5150178e589060f03381300d28e540sewardj case Arm_Reg: 445f67eadf04f5150178e589060f03381300d28e540sewardj op->Arm.Reg.reg = lookupHRegRemap(m, op->Arm.Reg.reg); 446f67eadf04f5150178e589060f03381300d28e540sewardj return; 447f67eadf04f5150178e589060f03381300d28e540sewardj default: 448f67eadf04f5150178e589060f03381300d28e540sewardj vpanic("mapRegs_AMD64RM"); 449f67eadf04f5150178e589060f03381300d28e540sewardj } 450f67eadf04f5150178e589060f03381300d28e540sewardj} 451f67eadf04f5150178e589060f03381300d28e540sewardj 452f67eadf04f5150178e589060f03381300d28e540sewardj 4539b96767debeeb1f78378f0e7e295fe6762c64002sewardj/* --------- Instructions. --------- */ 4549b96767debeeb1f78378f0e7e295fe6762c64002sewardj 45555085f8680acc89d727e321f3b34cae1a8c4093aflorianstatic const HChar* showAMD64ScalarSz ( Int sz ) { 4569b96767debeeb1f78378f0e7e295fe6762c64002sewardj switch (sz) { 4579b96767debeeb1f78378f0e7e295fe6762c64002sewardj case 2: return "w"; 4589b96767debeeb1f78378f0e7e295fe6762c64002sewardj case 4: return "l"; 4599b96767debeeb1f78378f0e7e295fe6762c64002sewardj case 8: return "q"; 4609b96767debeeb1f78378f0e7e295fe6762c64002sewardj default: vpanic("showAMD64ScalarSz"); 4619b96767debeeb1f78378f0e7e295fe6762c64002sewardj } 4629b96767debeeb1f78378f0e7e295fe6762c64002sewardj} 4639b96767debeeb1f78378f0e7e295fe6762c64002sewardj 46455085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showAMD64UnaryOp ( AMD64UnaryOp op ) { 465d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj switch (op) { 466d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Aun_NOT: return "not"; 467d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Aun_NEG: return "neg"; 468d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj default: vpanic("showAMD64UnaryOp"); 469d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 470d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj} 471614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 47255085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showAMD64AluOp ( AMD64AluOp op ) { 473614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj switch (op) { 474614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_MOV: return "mov"; 475614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_CMP: return "cmp"; 476614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_ADD: return "add"; 477614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_SUB: return "sub"; 478614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_ADC: return "adc"; 479614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_SBB: return "sbb"; 480614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_AND: return "and"; 481614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_OR: return "or"; 482614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Aalu_XOR: return "xor"; 4837de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Aalu_MUL: return "imul"; 484614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj default: vpanic("showAMD64AluOp"); 485614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj } 486614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 487614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 48855085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showAMD64ShiftOp ( AMD64ShiftOp op ) { 4898258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj switch (op) { 4908258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Ash_SHL: return "shl"; 4918258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Ash_SHR: return "shr"; 4928258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Ash_SAR: return "sar"; 4938258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj default: vpanic("showAMD64ShiftOp"); 4948258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj } 4958258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 4968258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj 49755085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showA87FpOp ( A87FpOp op ) { 49825a858136df4cbea0055c20aa7035d25fd40ee89sewardj switch (op) { 49925a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_SCALE: return "scale"; 50025a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_ATAN: return "atan"; 50125a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_YL2X: return "yl2x"; 5025e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_YL2XP1: return "yl2xp1"; 503f4c803b0947e7534809589cba8007851d78c7a2esewardj case Afp_PREM: return "prem"; 5044970e4e219cb92ef15de742d102c537ea33d5430sewardj case Afp_PREM1: return "prem1"; 50525a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_SQRT: return "sqrt"; 50625a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_SIN: return "sin"; 50725a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_COS: return "cos"; 5085e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_TAN: return "tan"; 50925a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_ROUND: return "round"; 51025a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Afp_2XM1: return "2xm1"; 51125a858136df4cbea0055c20aa7035d25fd40ee89sewardj default: vpanic("showA87FpOp"); 51225a858136df4cbea0055c20aa7035d25fd40ee89sewardj } 51325a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 5141001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 51555085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar* showAMD64SseOp ( AMD64SseOp op ) { 5161001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj switch (op) { 5171830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Asse_MOV: return "movups"; 5181001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_ADDF: return "add"; 5191001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_SUBF: return "sub"; 5201001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_MULF: return "mul"; 5211001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_DIVF: return "div"; 5221a01e65f9993d97095c2af463e98674a091834casewardj case Asse_MAXF: return "max"; 5231a01e65f9993d97095c2af463e98674a091834casewardj case Asse_MINF: return "min"; 5248d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPEQF: return "cmpFeq"; 5258d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPLTF: return "cmpFlt"; 5268d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPLEF: return "cmpFle"; 5278d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPUNF: return "cmpFun"; 528a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RCPF: return "rcp"; 529a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RSQRTF: return "rsqrt"; 5301830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Asse_SQRTF: return "sqrt"; 5311001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_AND: return "and"; 5321001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_OR: return "or"; 5331001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_XOR: return "xor"; 5341001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_ANDN: return "andn"; 535976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_ADD8: return "paddb"; 536976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_ADD16: return "paddw"; 537976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_ADD32: return "paddd"; 53809717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_ADD64: return "paddq"; 5395992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD8U: return "paddusb"; 5405992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD16U: return "paddusw"; 5415992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD8S: return "paddsb"; 5425992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD16S: return "paddsw"; 543976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB8: return "psubb"; 544976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB16: return "psubw"; 545976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB32: return "psubd"; 54609717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_SUB64: return "psubq"; 547976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB8U: return "psubusb"; 548976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB16U: return "psubusw"; 549976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB8S: return "psubsb"; 550976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB16S: return "psubsw"; 551adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MUL16: return "pmullw"; 552adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MULHI16U: return "pmulhuw"; 553adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MULHI16S: return "pmulhw"; 5545992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_AVG8U: return "pavgb"; 5555992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_AVG16U: return "pavgw"; 556adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MAX16S: return "pmaxw"; 557adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MAX8U: return "pmaxub"; 558adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MIN16S: return "pminw"; 559adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MIN8U: return "pminub"; 5605992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPEQ8: return "pcmpeqb"; 5615992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPEQ16: return "pcmpeqw"; 56209717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_CMPEQ32: return "pcmpeqd"; 5635992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT8S: return "pcmpgtb"; 5645992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT16S: return "pcmpgtw"; 5655992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT32S: return "pcmpgtd"; 566adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL16: return "psllw"; 567adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL32: return "pslld"; 568adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL64: return "psllq"; 569adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHR16: return "psrlw"; 570adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHR32: return "psrld"; 57109717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_SHR64: return "psrlq"; 572adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SAR16: return "psraw"; 573adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SAR32: return "psrad"; 574976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKSSD: return "packssdw"; 575976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKSSW: return "packsswb"; 576976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKUSW: return "packuswb"; 577976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHB: return "punpckhb"; 578976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHW: return "punpckhw"; 579976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHD: return "punpckhd"; 580976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHQ: return "punpckhq"; 581976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLB: return "punpcklb"; 582976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLW: return "punpcklw"; 583976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLD: return "punpckld"; 584976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLQ: return "punpcklq"; 5851001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj default: vpanic("showAMD64SseOp"); 5861001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 5871001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 588614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj 589813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardjAMD64Instr* AMD64Instr_Imm64 ( ULong imm64, HReg dst ) { 590d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 591813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->tag = Ain_Imm64; 592813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->Ain.Imm64.imm64 = imm64; 593813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->Ain.Imm64.dst = dst; 594813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return i; 595813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 596614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardjAMD64Instr* AMD64Instr_Alu64R ( AMD64AluOp op, AMD64RMI* src, HReg dst ) { 597d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 598614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj i->tag = Ain_Alu64R; 599614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj i->Ain.Alu64R.op = op; 600614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj i->Ain.Alu64R.src = src; 601614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj i->Ain.Alu64R.dst = dst; 602614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return i; 603614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj} 604f67eadf04f5150178e589060f03381300d28e540sewardjAMD64Instr* AMD64Instr_Alu64M ( AMD64AluOp op, AMD64RI* src, AMD64AMode* dst ) { 605d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 606f67eadf04f5150178e589060f03381300d28e540sewardj i->tag = Ain_Alu64M; 607f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Alu64M.op = op; 608f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Alu64M.src = src; 609f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Alu64M.dst = dst; 610f67eadf04f5150178e589060f03381300d28e540sewardj vassert(op != Aalu_MUL); 611f67eadf04f5150178e589060f03381300d28e540sewardj return i; 612f67eadf04f5150178e589060f03381300d28e540sewardj} 613501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardjAMD64Instr* AMD64Instr_Sh64 ( AMD64ShiftOp op, UInt src, HReg dst ) { 614d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6158258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->tag = Ain_Sh64; 6168258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.Sh64.op = op; 6178258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.Sh64.src = src; 6188258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.Sh64.dst = dst; 6198258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return i; 6208258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 621501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardjAMD64Instr* AMD64Instr_Test64 ( UInt imm32, HReg dst ) { 622d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 623501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj i->tag = Ain_Test64; 624501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj i->Ain.Test64.imm32 = imm32; 625501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj i->Ain.Test64.dst = dst; 62605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return i; 62705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj} 628501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardjAMD64Instr* AMD64Instr_Unary64 ( AMD64UnaryOp op, HReg dst ) { 629d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 630d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj i->tag = Ain_Unary64; 631d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj i->Ain.Unary64.op = op; 632d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj i->Ain.Unary64.dst = dst; 633d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return i; 634d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj} 6356ce1a23b27d1729da9d705abd15b2007dce8daecsewardjAMD64Instr* AMD64Instr_Lea64 ( AMD64AMode* am, HReg dst ) { 636d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6376ce1a23b27d1729da9d705abd15b2007dce8daecsewardj i->tag = Ain_Lea64; 6386ce1a23b27d1729da9d705abd15b2007dce8daecsewardj i->Ain.Lea64.am = am; 6396ce1a23b27d1729da9d705abd15b2007dce8daecsewardj i->Ain.Lea64.dst = dst; 6406ce1a23b27d1729da9d705abd15b2007dce8daecsewardj return i; 6416ce1a23b27d1729da9d705abd15b2007dce8daecsewardj} 6429cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardjAMD64Instr* AMD64Instr_Alu32R ( AMD64AluOp op, AMD64RMI* src, HReg dst ) { 643d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6449cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->tag = Ain_Alu32R; 6459cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.op = op; 6469cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.src = src; 6479cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.dst = dst; 6489cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj switch (op) { 6499cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_ADD: case Aalu_SUB: case Aalu_CMP: 6509cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_AND: case Aalu_OR: case Aalu_XOR: break; 6519cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj default: vassert(0); 6529cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } 6539cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj return i; 6549cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj} 655501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardjAMD64Instr* AMD64Instr_MulL ( Bool syned, AMD64RM* src ) { 656d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6579b96767debeeb1f78378f0e7e295fe6762c64002sewardj i->tag = Ain_MulL; 6589b96767debeeb1f78378f0e7e295fe6762c64002sewardj i->Ain.MulL.syned = syned; 6599b96767debeeb1f78378f0e7e295fe6762c64002sewardj i->Ain.MulL.src = src; 6609b96767debeeb1f78378f0e7e295fe6762c64002sewardj return i; 6619b96767debeeb1f78378f0e7e295fe6762c64002sewardj} 6627de0d3c800437fbd82c59d57d156f4823d67609fsewardjAMD64Instr* AMD64Instr_Div ( Bool syned, Int sz, AMD64RM* src ) { 663d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6647de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->tag = Ain_Div; 6657de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Div.syned = syned; 6667de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Div.sz = sz; 6677de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Div.src = src; 6687de0d3c800437fbd82c59d57d156f4823d67609fsewardj vassert(sz == 4 || sz == 8); 6697de0d3c800437fbd82c59d57d156f4823d67609fsewardj return i; 6707de0d3c800437fbd82c59d57d156f4823d67609fsewardj} 6711001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardjAMD64Instr* AMD64Instr_Push( AMD64RMI* src ) { 672d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 6731001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->tag = Ain_Push; 6741001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.Push.src = src; 6751001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return i; 6761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 677cfe046e178666280b87da998b1b52ecda03ecd89sewardjAMD64Instr* AMD64Instr_Call ( AMD64CondCode cond, Addr64 target, Int regparms, 678cfe046e178666280b87da998b1b52ecda03ecd89sewardj RetLoc rloc ) { 679d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 68005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->tag = Ain_Call; 68105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.Call.cond = cond; 68205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.Call.target = target; 68305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.Call.regparms = regparms; 684cfe046e178666280b87da998b1b52ecda03ecd89sewardj i->Ain.Call.rloc = rloc; 68505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vassert(regparms >= 0 && regparms <= 6); 68674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj vassert(is_sane_RetLoc(rloc)); 68705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return i; 68805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj} 689c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 690c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjAMD64Instr* AMD64Instr_XDirect ( Addr64 dstGA, AMD64AMode* amRIP, 691c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj AMD64CondCode cond, Bool toFastEP ) { 692d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 693c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->tag = Ain_XDirect; 694c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XDirect.dstGA = dstGA; 695c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XDirect.amRIP = amRIP; 696c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XDirect.cond = cond; 697c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XDirect.toFastEP = toFastEP; 698c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return i; 699c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 700c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjAMD64Instr* AMD64Instr_XIndir ( HReg dstGA, AMD64AMode* amRIP, 701c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj AMD64CondCode cond ) { 702d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 703c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->tag = Ain_XIndir; 704c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XIndir.dstGA = dstGA; 705c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XIndir.amRIP = amRIP; 706c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XIndir.cond = cond; 707c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return i; 708c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 709c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjAMD64Instr* AMD64Instr_XAssisted ( HReg dstGA, AMD64AMode* amRIP, 710c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj AMD64CondCode cond, IRJumpKind jk ) { 711d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 712c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->tag = Ain_XAssisted; 713c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XAssisted.dstGA = dstGA; 714c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XAssisted.amRIP = amRIP; 715c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XAssisted.cond = cond; 716c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XAssisted.jk = jk; 717f67eadf04f5150178e589060f03381300d28e540sewardj return i; 718f67eadf04f5150178e589060f03381300d28e540sewardj} 719c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 720e357c67787b7429f85a030ee5fbedf33173b5656sewardjAMD64Instr* AMD64Instr_CMov64 ( AMD64CondCode cond, HReg src, HReg dst ) { 721d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 72205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->tag = Ain_CMov64; 72305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.CMov64.cond = cond; 72405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.CMov64.src = src; 72505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.CMov64.dst = dst; 72605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vassert(cond != Acc_ALWAYS); 72705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return i; 72805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj} 729bdea5508b371d394c81b91464fa8df767010d4dasewardjAMD64Instr* AMD64Instr_CLoad ( AMD64CondCode cond, UChar szB, 730bdea5508b371d394c81b91464fa8df767010d4dasewardj AMD64AMode* addr, HReg dst ) { 731d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 732bdea5508b371d394c81b91464fa8df767010d4dasewardj i->tag = Ain_CLoad; 733bdea5508b371d394c81b91464fa8df767010d4dasewardj i->Ain.CLoad.cond = cond; 734bdea5508b371d394c81b91464fa8df767010d4dasewardj i->Ain.CLoad.szB = szB; 735bdea5508b371d394c81b91464fa8df767010d4dasewardj i->Ain.CLoad.addr = addr; 736bdea5508b371d394c81b91464fa8df767010d4dasewardj i->Ain.CLoad.dst = dst; 7376f1ec58d9806064dea0000e4b543aacded9b11easewardj vassert(cond != Acc_ALWAYS && (szB == 4 || szB == 8)); 7386f1ec58d9806064dea0000e4b543aacded9b11easewardj return i; 7396f1ec58d9806064dea0000e4b543aacded9b11easewardj} 7406f1ec58d9806064dea0000e4b543aacded9b11easewardjAMD64Instr* AMD64Instr_CStore ( AMD64CondCode cond, UChar szB, 7416f1ec58d9806064dea0000e4b543aacded9b11easewardj HReg src, AMD64AMode* addr ) { 742d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 7436f1ec58d9806064dea0000e4b543aacded9b11easewardj i->tag = Ain_CStore; 7446f1ec58d9806064dea0000e4b543aacded9b11easewardj i->Ain.CStore.cond = cond; 7456f1ec58d9806064dea0000e4b543aacded9b11easewardj i->Ain.CStore.szB = szB; 7466f1ec58d9806064dea0000e4b543aacded9b11easewardj i->Ain.CStore.src = src; 7476f1ec58d9806064dea0000e4b543aacded9b11easewardj i->Ain.CStore.addr = addr; 7486f1ec58d9806064dea0000e4b543aacded9b11easewardj vassert(cond != Acc_ALWAYS && (szB == 4 || szB == 8)); 749bdea5508b371d394c81b91464fa8df767010d4dasewardj return i; 750bdea5508b371d394c81b91464fa8df767010d4dasewardj} 751ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardjAMD64Instr* AMD64Instr_MovxLQ ( Bool syned, HReg src, HReg dst ) { 752d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 753ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj i->tag = Ain_MovxLQ; 754ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj i->Ain.MovxLQ.syned = syned; 755ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj i->Ain.MovxLQ.src = src; 756ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj i->Ain.MovxLQ.dst = dst; 757f67eadf04f5150178e589060f03381300d28e540sewardj return i; 758f67eadf04f5150178e589060f03381300d28e540sewardj} 7598258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardjAMD64Instr* AMD64Instr_LoadEX ( UChar szSmall, Bool syned, 7608258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj AMD64AMode* src, HReg dst ) { 761d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 7628258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->tag = Ain_LoadEX; 7638258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.LoadEX.szSmall = szSmall; 7648258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.LoadEX.syned = syned; 7658258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.LoadEX.src = src; 7668258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj i->Ain.LoadEX.dst = dst; 7678258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj vassert(szSmall == 1 || szSmall == 2 || szSmall == 4); 7688258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return i; 7698258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj} 770f67eadf04f5150178e589060f03381300d28e540sewardjAMD64Instr* AMD64Instr_Store ( UChar sz, HReg src, AMD64AMode* dst ) { 771d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 772f67eadf04f5150178e589060f03381300d28e540sewardj i->tag = Ain_Store; 773f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Store.sz = sz; 774f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Store.src = src; 775f67eadf04f5150178e589060f03381300d28e540sewardj i->Ain.Store.dst = dst; 776f67eadf04f5150178e589060f03381300d28e540sewardj vassert(sz == 1 || sz == 2 || sz == 4); 777f67eadf04f5150178e589060f03381300d28e540sewardj return i; 778f67eadf04f5150178e589060f03381300d28e540sewardj} 779a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardjAMD64Instr* AMD64Instr_Set64 ( AMD64CondCode cond, HReg dst ) { 780d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 781a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj i->tag = Ain_Set64; 782a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj i->Ain.Set64.cond = cond; 783a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj i->Ain.Set64.dst = dst; 784a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj return i; 785a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj} 786f53b7359a342e7d79090615169c6583a1a75fbcesewardjAMD64Instr* AMD64Instr_Bsfr64 ( Bool isFwds, HReg src, HReg dst ) { 787d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 788f53b7359a342e7d79090615169c6583a1a75fbcesewardj i->tag = Ain_Bsfr64; 789f53b7359a342e7d79090615169c6583a1a75fbcesewardj i->Ain.Bsfr64.isFwds = isFwds; 790f53b7359a342e7d79090615169c6583a1a75fbcesewardj i->Ain.Bsfr64.src = src; 791f53b7359a342e7d79090615169c6583a1a75fbcesewardj i->Ain.Bsfr64.dst = dst; 792f53b7359a342e7d79090615169c6583a1a75fbcesewardj return i; 793f53b7359a342e7d79090615169c6583a1a75fbcesewardj} 794e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjAMD64Instr* AMD64Instr_MFence ( void ) { 795d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 79625a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->tag = Ain_MFence; 79725a858136df4cbea0055c20aa7035d25fd40ee89sewardj return i; 79825a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 799e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjAMD64Instr* AMD64Instr_ACAS ( AMD64AMode* addr, UChar sz ) { 800d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 801e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->tag = Ain_ACAS; 802e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->Ain.ACAS.addr = addr; 803e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->Ain.ACAS.sz = sz; 804e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(sz == 8 || sz == 4 || sz == 2 || sz == 1); 805e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return i; 806e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj} 807e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardjAMD64Instr* AMD64Instr_DACAS ( AMD64AMode* addr, UChar sz ) { 808d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 809e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->tag = Ain_DACAS; 810e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->Ain.DACAS.addr = addr; 811e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->Ain.DACAS.sz = sz; 812e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(sz == 8 || sz == 4); 813e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return i; 814e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj} 815e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 81625a858136df4cbea0055c20aa7035d25fd40ee89sewardjAMD64Instr* AMD64Instr_A87Free ( Int nregs ) 81725a858136df4cbea0055c20aa7035d25fd40ee89sewardj{ 818d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 81925a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->tag = Ain_A87Free; 82025a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->Ain.A87Free.nregs = nregs; 82125a858136df4cbea0055c20aa7035d25fd40ee89sewardj vassert(nregs >= 1 && nregs <= 7); 82225a858136df4cbea0055c20aa7035d25fd40ee89sewardj return i; 82325a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 824d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardjAMD64Instr* AMD64Instr_A87PushPop ( AMD64AMode* addr, Bool isPush, UChar szB ) 82525a858136df4cbea0055c20aa7035d25fd40ee89sewardj{ 826d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 82725a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->tag = Ain_A87PushPop; 82825a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->Ain.A87PushPop.addr = addr; 82925a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->Ain.A87PushPop.isPush = isPush; 830d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj i->Ain.A87PushPop.szB = szB; 831d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj vassert(szB == 8 || szB == 4); 83225a858136df4cbea0055c20aa7035d25fd40ee89sewardj return i; 83325a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 83425a858136df4cbea0055c20aa7035d25fd40ee89sewardjAMD64Instr* AMD64Instr_A87FpOp ( A87FpOp op ) 83525a858136df4cbea0055c20aa7035d25fd40ee89sewardj{ 836d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 83725a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->tag = Ain_A87FpOp; 83825a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->Ain.A87FpOp.op = op; 83925a858136df4cbea0055c20aa7035d25fd40ee89sewardj return i; 84025a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 84125a858136df4cbea0055c20aa7035d25fd40ee89sewardjAMD64Instr* AMD64Instr_A87LdCW ( AMD64AMode* addr ) 84225a858136df4cbea0055c20aa7035d25fd40ee89sewardj{ 843d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 84425a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->tag = Ain_A87LdCW; 84525a858136df4cbea0055c20aa7035d25fd40ee89sewardj i->Ain.A87LdCW.addr = addr; 846d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return i; 847d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj} 848f4c803b0947e7534809589cba8007851d78c7a2esewardjAMD64Instr* AMD64Instr_A87StSW ( AMD64AMode* addr ) 849f4c803b0947e7534809589cba8007851d78c7a2esewardj{ 850d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 851f4c803b0947e7534809589cba8007851d78c7a2esewardj i->tag = Ain_A87StSW; 852f4c803b0947e7534809589cba8007851d78c7a2esewardj i->Ain.A87StSW.addr = addr; 853f4c803b0947e7534809589cba8007851d78c7a2esewardj return i; 854f4c803b0947e7534809589cba8007851d78c7a2esewardj} 8551a01e65f9993d97095c2af463e98674a091834casewardjAMD64Instr* AMD64Instr_LdMXCSR ( AMD64AMode* addr ) { 856d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 8571a01e65f9993d97095c2af463e98674a091834casewardj i->tag = Ain_LdMXCSR; 8581a01e65f9993d97095c2af463e98674a091834casewardj i->Ain.LdMXCSR.addr = addr; 8591a01e65f9993d97095c2af463e98674a091834casewardj return i; 8601a01e65f9993d97095c2af463e98674a091834casewardj} 8611830386e7b10430c0c3630123a82d8bcf0a071e7sewardjAMD64Instr* AMD64Instr_SseUComIS ( Int sz, HReg srcL, HReg srcR, HReg dst ) { 862d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 8631830386e7b10430c0c3630123a82d8bcf0a071e7sewardj i->tag = Ain_SseUComIS; 86403ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseUComIS.sz = toUChar(sz); 8651830386e7b10430c0c3630123a82d8bcf0a071e7sewardj i->Ain.SseUComIS.srcL = srcL; 8661830386e7b10430c0c3630123a82d8bcf0a071e7sewardj i->Ain.SseUComIS.srcR = srcR; 8671830386e7b10430c0c3630123a82d8bcf0a071e7sewardj i->Ain.SseUComIS.dst = dst; 8681830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vassert(sz == 4 || sz == 8); 8691830386e7b10430c0c3630123a82d8bcf0a071e7sewardj return i; 8701830386e7b10430c0c3630123a82d8bcf0a071e7sewardj} 8711a01e65f9993d97095c2af463e98674a091834casewardjAMD64Instr* AMD64Instr_SseSI2SF ( Int szS, Int szD, HReg src, HReg dst ) { 872d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 8731a01e65f9993d97095c2af463e98674a091834casewardj i->tag = Ain_SseSI2SF; 87403ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseSI2SF.szS = toUChar(szS); 87503ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseSI2SF.szD = toUChar(szD); 8761a01e65f9993d97095c2af463e98674a091834casewardj i->Ain.SseSI2SF.src = src; 8771a01e65f9993d97095c2af463e98674a091834casewardj i->Ain.SseSI2SF.dst = dst; 8781a01e65f9993d97095c2af463e98674a091834casewardj vassert(szS == 4 || szS == 8); 8791a01e65f9993d97095c2af463e98674a091834casewardj vassert(szD == 4 || szD == 8); 8801a01e65f9993d97095c2af463e98674a091834casewardj return i; 8811a01e65f9993d97095c2af463e98674a091834casewardj} 8821a01e65f9993d97095c2af463e98674a091834casewardjAMD64Instr* AMD64Instr_SseSF2SI ( Int szS, Int szD, HReg src, HReg dst ) { 883d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 8841a01e65f9993d97095c2af463e98674a091834casewardj i->tag = Ain_SseSF2SI; 88503ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseSF2SI.szS = toUChar(szS); 88603ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseSF2SI.szD = toUChar(szD); 8871a01e65f9993d97095c2af463e98674a091834casewardj i->Ain.SseSF2SI.src = src; 8881a01e65f9993d97095c2af463e98674a091834casewardj i->Ain.SseSF2SI.dst = dst; 8891a01e65f9993d97095c2af463e98674a091834casewardj vassert(szS == 4 || szS == 8); 8901a01e65f9993d97095c2af463e98674a091834casewardj vassert(szD == 4 || szD == 8); 8911a01e65f9993d97095c2af463e98674a091834casewardj return i; 8921a01e65f9993d97095c2af463e98674a091834casewardj} 8938d965316c72c2392f670dcdfa127547ec77c7e56sewardjAMD64Instr* AMD64Instr_SseSDSS ( Bool from64, HReg src, HReg dst ) 8948d965316c72c2392f670dcdfa127547ec77c7e56sewardj{ 895d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 8968d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->tag = Ain_SseSDSS; 8978d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseSDSS.from64 = from64; 8988d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseSDSS.src = src; 8998d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseSDSS.dst = dst; 9008d965316c72c2392f670dcdfa127547ec77c7e56sewardj return i; 9018d965316c72c2392f670dcdfa127547ec77c7e56sewardj} 9021830386e7b10430c0c3630123a82d8bcf0a071e7sewardjAMD64Instr* AMD64Instr_SseLdSt ( Bool isLoad, Int sz, 9031830386e7b10430c0c3630123a82d8bcf0a071e7sewardj HReg reg, AMD64AMode* addr ) { 904d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9051001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->tag = Ain_SseLdSt; 9061001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdSt.isLoad = isLoad; 90703ccf858efa285d793061359c04fdd0055cd9d31sewardj i->Ain.SseLdSt.sz = toUChar(sz); 9081001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdSt.reg = reg; 9091001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdSt.addr = addr; 9101830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vassert(sz == 4 || sz == 8 || sz == 16); 9111001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return i; 9121001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 91370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjAMD64Instr* AMD64Instr_SseCStore ( AMD64CondCode cond, 91470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj HReg src, AMD64AMode* addr ) 91570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 91670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 91770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->tag = Ain_SseCStore; 91870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCStore.cond = cond; 91970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCStore.src = src; 92070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCStore.addr = addr; 92170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(cond != Acc_ALWAYS); 92270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return i; 92370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 92470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardjAMD64Instr* AMD64Instr_SseCLoad ( AMD64CondCode cond, 92570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj AMD64AMode* addr, HReg dst ) 92670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj{ 92770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 92870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->tag = Ain_SseCLoad; 92970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCLoad.cond = cond; 93070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCLoad.addr = addr; 93170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCLoad.dst = dst; 93270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(cond != Acc_ALWAYS); 93370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return i; 93470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj} 9351001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardjAMD64Instr* AMD64Instr_SseLdzLO ( Int sz, HReg reg, AMD64AMode* addr ) 9361001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj{ 937d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9381001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->tag = Ain_SseLdzLO; 9391001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdzLO.sz = sz; 9401001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdzLO.reg = reg; 9411001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdzLO.addr = addr; 9421001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(sz == 4 || sz == 8); 9431001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return i; 9441001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 9458d965316c72c2392f670dcdfa127547ec77c7e56sewardjAMD64Instr* AMD64Instr_Sse32Fx4 ( AMD64SseOp op, HReg src, HReg dst ) { 946d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9478d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->tag = Ain_Sse32Fx4; 9488d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32Fx4.op = op; 9498d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32Fx4.src = src; 9508d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32Fx4.dst = dst; 9518d965316c72c2392f670dcdfa127547ec77c7e56sewardj vassert(op != Asse_MOV); 9528d965316c72c2392f670dcdfa127547ec77c7e56sewardj return i; 9538d965316c72c2392f670dcdfa127547ec77c7e56sewardj} 9548d965316c72c2392f670dcdfa127547ec77c7e56sewardjAMD64Instr* AMD64Instr_Sse32FLo ( AMD64SseOp op, HReg src, HReg dst ) { 955d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9568d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->tag = Ain_Sse32FLo; 9578d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32FLo.op = op; 9588d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32FLo.src = src; 9598d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32FLo.dst = dst; 9608d965316c72c2392f670dcdfa127547ec77c7e56sewardj vassert(op != Asse_MOV); 9618d965316c72c2392f670dcdfa127547ec77c7e56sewardj return i; 9628d965316c72c2392f670dcdfa127547ec77c7e56sewardj} 9634c328cf28ebd12977fbf837c44a614c5aac660f3sewardjAMD64Instr* AMD64Instr_Sse64Fx2 ( AMD64SseOp op, HReg src, HReg dst ) { 964d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9654c328cf28ebd12977fbf837c44a614c5aac660f3sewardj i->tag = Ain_Sse64Fx2; 9664c328cf28ebd12977fbf837c44a614c5aac660f3sewardj i->Ain.Sse64Fx2.op = op; 9674c328cf28ebd12977fbf837c44a614c5aac660f3sewardj i->Ain.Sse64Fx2.src = src; 9684c328cf28ebd12977fbf837c44a614c5aac660f3sewardj i->Ain.Sse64Fx2.dst = dst; 9694c328cf28ebd12977fbf837c44a614c5aac660f3sewardj vassert(op != Asse_MOV); 9704c328cf28ebd12977fbf837c44a614c5aac660f3sewardj return i; 9714c328cf28ebd12977fbf837c44a614c5aac660f3sewardj} 9721001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardjAMD64Instr* AMD64Instr_Sse64FLo ( AMD64SseOp op, HReg src, HReg dst ) { 973d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9741001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->tag = Ain_Sse64FLo; 9751001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.Sse64FLo.op = op; 9761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.Sse64FLo.src = src; 9771001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.Sse64FLo.dst = dst; 9781001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(op != Asse_MOV); 9791001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return i; 9801001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 9811001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardjAMD64Instr* AMD64Instr_SseReRg ( AMD64SseOp op, HReg re, HReg rg ) { 982d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9831001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->tag = Ain_SseReRg; 9841001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseReRg.op = op; 9851001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseReRg.src = re; 9861001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseReRg.dst = rg; 9871001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return i; 9881001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 9898d965316c72c2392f670dcdfa127547ec77c7e56sewardjAMD64Instr* AMD64Instr_SseCMov ( AMD64CondCode cond, HReg src, HReg dst ) { 990d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 9918d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->tag = Ain_SseCMov; 9928d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseCMov.cond = cond; 9938d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseCMov.src = src; 9948d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.SseCMov.dst = dst; 9958d965316c72c2392f670dcdfa127547ec77c7e56sewardj vassert(cond != Acc_ALWAYS); 9968d965316c72c2392f670dcdfa127547ec77c7e56sewardj return i; 9978d965316c72c2392f670dcdfa127547ec77c7e56sewardj} 99809717341a0c364814e35bf405e61399d0e45fa7csewardjAMD64Instr* AMD64Instr_SseShuf ( Int order, HReg src, HReg dst ) { 999d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 100009717341a0c364814e35bf405e61399d0e45fa7csewardj i->tag = Ain_SseShuf; 100109717341a0c364814e35bf405e61399d0e45fa7csewardj i->Ain.SseShuf.order = order; 100209717341a0c364814e35bf405e61399d0e45fa7csewardj i->Ain.SseShuf.src = src; 100309717341a0c364814e35bf405e61399d0e45fa7csewardj i->Ain.SseShuf.dst = dst; 100409717341a0c364814e35bf405e61399d0e45fa7csewardj vassert(order >= 0 && order <= 0xFF); 100509717341a0c364814e35bf405e61399d0e45fa7csewardj return i; 100609717341a0c364814e35bf405e61399d0e45fa7csewardj} 10073616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu AMD64Instr* AMD64Instr_AvxLdSt ( Bool isLoad, 10083616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu HReg reg, AMD64AMode* addr ) { 1009d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian//uu AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 10103616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->tag = Ain_AvxLdSt; 10113616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxLdSt.isLoad = isLoad; 10123616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxLdSt.reg = reg; 10133616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxLdSt.addr = addr; 10143616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu return i; 10153616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 10163616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu AMD64Instr* AMD64Instr_AvxReRg ( AMD64SseOp op, HReg re, HReg rg ) { 1017d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian//uu AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 10183616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->tag = Ain_AvxReRg; 10193616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxReRg.op = op; 10203616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxReRg.src = re; 10213616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu i->Ain.AvxReRg.dst = rg; 10223616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu return i; 10233616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 1024c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjAMD64Instr* AMD64Instr_EvCheck ( AMD64AMode* amCounter, 1025c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj AMD64AMode* amFailAddr ) { 1026d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 1027c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->tag = Ain_EvCheck; 1028c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.EvCheck.amCounter = amCounter; 1029c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.EvCheck.amFailAddr = amFailAddr; 1030c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return i; 1031c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 1032c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjAMD64Instr* AMD64Instr_ProfInc ( void ) { 1033d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); 1034c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->tag = Ain_ProfInc; 1035c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return i; 1036c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 1037c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1038d8c64e082224b2e688abdef9219cc76fd82b373bflorianvoid ppAMD64Instr ( const AMD64Instr* i, Bool mode64 ) 1039c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj{ 104092b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 1041c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj switch (i->tag) { 1042813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Ain_Imm64: 10431b8d58eb046ad31fbb058d65855b604886d3d177sewardj vex_printf("movabsq $0x%llx,", i->Ain.Imm64.imm64); 1044813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj ppHRegAMD64(i->Ain.Imm64.dst); 1045813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return; 1046614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj case Ain_Alu64R: 1047614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf("%sq ", showAMD64AluOp(i->Ain.Alu64R.op)); 1048614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppAMD64RMI(i->Ain.Alu64R.src); 1049614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj vex_printf(","); 1050614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj ppHRegAMD64(i->Ain.Alu64R.dst); 1051614b3fb2b4b226c487bf7f4c85c719c31527bc89sewardj return; 1052f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Alu64M: 1053f67eadf04f5150178e589060f03381300d28e540sewardj vex_printf("%sq ", showAMD64AluOp(i->Ain.Alu64M.op)); 1054f67eadf04f5150178e589060f03381300d28e540sewardj ppAMD64RI(i->Ain.Alu64M.src); 1055f67eadf04f5150178e589060f03381300d28e540sewardj vex_printf(","); 1056f67eadf04f5150178e589060f03381300d28e540sewardj ppAMD64AMode(i->Ain.Alu64M.dst); 1057f67eadf04f5150178e589060f03381300d28e540sewardj return; 10588258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Ain_Sh64: 10591b8d58eb046ad31fbb058d65855b604886d3d177sewardj vex_printf("%sq ", showAMD64ShiftOp(i->Ain.Sh64.op)); 10608258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj if (i->Ain.Sh64.src == 0) 10618258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj vex_printf("%%cl,"); 10628258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj else 106303ccf858efa285d793061359c04fdd0055cd9d31sewardj vex_printf("$%d,", (Int)i->Ain.Sh64.src); 1064501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj ppHRegAMD64(i->Ain.Sh64.dst); 10658258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return; 106605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Test64: 1067501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj vex_printf("testq $%d,", (Int)i->Ain.Test64.imm32); 1068501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj ppHRegAMD64(i->Ain.Test64.dst); 106905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1070d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_Unary64: 1071b522077275a57df04305eec3ec1ef3fab9801197sewardj vex_printf("%sq ", showAMD64UnaryOp(i->Ain.Unary64.op)); 1072501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj ppHRegAMD64(i->Ain.Unary64.dst); 1073d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 10746ce1a23b27d1729da9d705abd15b2007dce8daecsewardj case Ain_Lea64: 10756ce1a23b27d1729da9d705abd15b2007dce8daecsewardj vex_printf("leaq "); 10766ce1a23b27d1729da9d705abd15b2007dce8daecsewardj ppAMD64AMode(i->Ain.Lea64.am); 10776ce1a23b27d1729da9d705abd15b2007dce8daecsewardj vex_printf(","); 10786ce1a23b27d1729da9d705abd15b2007dce8daecsewardj ppHRegAMD64(i->Ain.Lea64.dst); 10796ce1a23b27d1729da9d705abd15b2007dce8daecsewardj return; 10809cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Ain_Alu32R: 10819cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj vex_printf("%sl ", showAMD64AluOp(i->Ain.Alu32R.op)); 10829cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppAMD64RMI_lo32(i->Ain.Alu32R.src); 10839cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj vex_printf(","); 10849cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj ppHRegAMD64_lo32(i->Ain.Alu32R.dst); 10859cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj return; 10869b96767debeeb1f78378f0e7e295fe6762c64002sewardj case Ain_MulL: 1087501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj vex_printf("%cmulq ", i->Ain.MulL.syned ? 's' : 'u'); 10889b96767debeeb1f78378f0e7e295fe6762c64002sewardj ppAMD64RM(i->Ain.MulL.src); 10899b96767debeeb1f78378f0e7e295fe6762c64002sewardj return; 10907de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Ain_Div: 10917de0d3c800437fbd82c59d57d156f4823d67609fsewardj vex_printf("%cdiv%s ", 10927de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Div.syned ? 's' : 'u', 10937de0d3c800437fbd82c59d57d156f4823d67609fsewardj showAMD64ScalarSz(i->Ain.Div.sz)); 10947de0d3c800437fbd82c59d57d156f4823d67609fsewardj ppAMD64RM(i->Ain.Div.src); 10957de0d3c800437fbd82c59d57d156f4823d67609fsewardj return; 10961001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Push: 10971001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf("pushq "); 10981001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppAMD64RMI(i->Ain.Push.src); 10991001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 110005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Call: 1101cfe046e178666280b87da998b1b52ecda03ecd89sewardj vex_printf("call%s[%d,", 110205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.Call.cond==Acc_ALWAYS 110305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj ? "" : showAMD64CondCode(i->Ain.Call.cond), 110405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj i->Ain.Call.regparms ); 1105cfe046e178666280b87da998b1b52ecda03ecd89sewardj ppRetLoc(i->Ain.Call.rloc); 1106cfe046e178666280b87da998b1b52ecda03ecd89sewardj vex_printf("] 0x%llx", i->Ain.Call.target); 110705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj break; 1108c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 1109c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XDirect: 1110c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("(xDirect) "); 1111c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("if (%%rflags.%s) { ", 1112c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj showAMD64CondCode(i->Ain.XDirect.cond)); 1113c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("movabsq $0x%llx,%%r11; ", i->Ain.XDirect.dstGA); 1114c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("movq %%r11,"); 1115c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppAMD64AMode(i->Ain.XDirect.amRIP); 1116c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; "); 1117c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("movabsq $disp_cp_chain_me_to_%sEP,%%r11; call *%%r11 }", 1118c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj i->Ain.XDirect.toFastEP ? "fast" : "slow"); 1119c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1120c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XIndir: 1121c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("(xIndir) "); 1122c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("if (%%rflags.%s) { ", 1123c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj showAMD64CondCode(i->Ain.XIndir.cond)); 11241b8d58eb046ad31fbb058d65855b604886d3d177sewardj vex_printf("movq "); 1125c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppHRegAMD64(i->Ain.XIndir.dstGA); 1126c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf(","); 1127c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppAMD64AMode(i->Ain.XIndir.amRIP); 1128c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; movabsq $disp_indir,%%r11; jmp *%%r11 }"); 1129c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1130c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XAssisted: 1131c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("(xAssisted) "); 1132c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("if (%%rflags.%s) { ", 1133c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj showAMD64CondCode(i->Ain.XAssisted.cond)); 1134c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("movq "); 1135c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppHRegAMD64(i->Ain.XAssisted.dstGA); 1136c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf(","); 1137c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppAMD64AMode(i->Ain.XAssisted.amRIP); 1138c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; movl $IRJumpKind_to_TRCVAL(%d),%%rbp", 1139c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (Int)i->Ain.XAssisted.jk); 1140c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; movabsq $disp_assisted,%%r11; jmp *%%r11 }"); 1141f67eadf04f5150178e589060f03381300d28e540sewardj return; 1142c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 114305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_CMov64: 114405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vex_printf("cmov%s ", showAMD64CondCode(i->Ain.CMov64.cond)); 1145e357c67787b7429f85a030ee5fbedf33173b5656sewardj ppHRegAMD64(i->Ain.CMov64.src); 114605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vex_printf(","); 114705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj ppHRegAMD64(i->Ain.CMov64.dst); 114805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1149bdea5508b371d394c81b91464fa8df767010d4dasewardj case Ain_CLoad: 1150bdea5508b371d394c81b91464fa8df767010d4dasewardj vex_printf("if (%%rflags.%s) { ", 1151bdea5508b371d394c81b91464fa8df767010d4dasewardj showAMD64CondCode(i->Ain.CLoad.cond)); 11526f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf("mov%c ", i->Ain.CLoad.szB == 4 ? 'l' : 'q'); 1153bdea5508b371d394c81b91464fa8df767010d4dasewardj ppAMD64AMode(i->Ain.CLoad.addr); 11546f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf(", "); 1155bdea5508b371d394c81b91464fa8df767010d4dasewardj (i->Ain.CLoad.szB == 4 ? ppHRegAMD64_lo32 : ppHRegAMD64) 1156bdea5508b371d394c81b91464fa8df767010d4dasewardj (i->Ain.CLoad.dst); 1157bdea5508b371d394c81b91464fa8df767010d4dasewardj vex_printf(" }"); 1158bdea5508b371d394c81b91464fa8df767010d4dasewardj return; 11596f1ec58d9806064dea0000e4b543aacded9b11easewardj case Ain_CStore: 11606f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf("if (%%rflags.%s) { ", 11616f1ec58d9806064dea0000e4b543aacded9b11easewardj showAMD64CondCode(i->Ain.CStore.cond)); 11626f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf("mov%c ", i->Ain.CStore.szB == 4 ? 'l' : 'q'); 11636f1ec58d9806064dea0000e4b543aacded9b11easewardj (i->Ain.CStore.szB == 4 ? ppHRegAMD64_lo32 : ppHRegAMD64) 11646f1ec58d9806064dea0000e4b543aacded9b11easewardj (i->Ain.CStore.src); 11656f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf(", "); 11666f1ec58d9806064dea0000e4b543aacded9b11easewardj ppAMD64AMode(i->Ain.CStore.addr); 11676f1ec58d9806064dea0000e4b543aacded9b11easewardj vex_printf(" }"); 11686f1ec58d9806064dea0000e4b543aacded9b11easewardj return; 11696f1ec58d9806064dea0000e4b543aacded9b11easewardj 1170ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj case Ain_MovxLQ: 1171ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj vex_printf("mov%clq ", i->Ain.MovxLQ.syned ? 's' : 'z'); 1172ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj ppHRegAMD64_lo32(i->Ain.MovxLQ.src); 1173f67eadf04f5150178e589060f03381300d28e540sewardj vex_printf(","); 1174ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj ppHRegAMD64(i->Ain.MovxLQ.dst); 1175f67eadf04f5150178e589060f03381300d28e540sewardj return; 11768258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj case Ain_LoadEX: 1177549e06463d433ee6351b72dc9107f22ce4305250sewardj if (i->Ain.LoadEX.szSmall==4 && !i->Ain.LoadEX.syned) { 1178549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf("movl "); 1179549e06463d433ee6351b72dc9107f22ce4305250sewardj ppAMD64AMode(i->Ain.LoadEX.src); 1180549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf(","); 1181549e06463d433ee6351b72dc9107f22ce4305250sewardj ppHRegAMD64_lo32(i->Ain.LoadEX.dst); 1182549e06463d433ee6351b72dc9107f22ce4305250sewardj } else { 1183549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf("mov%c%cq ", 1184549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.LoadEX.syned ? 's' : 'z', 1185549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.LoadEX.szSmall==1 1186549e06463d433ee6351b72dc9107f22ce4305250sewardj ? 'b' 1187549e06463d433ee6351b72dc9107f22ce4305250sewardj : (i->Ain.LoadEX.szSmall==2 ? 'w' : 'l')); 1188549e06463d433ee6351b72dc9107f22ce4305250sewardj ppAMD64AMode(i->Ain.LoadEX.src); 1189549e06463d433ee6351b72dc9107f22ce4305250sewardj vex_printf(","); 1190549e06463d433ee6351b72dc9107f22ce4305250sewardj ppHRegAMD64(i->Ain.LoadEX.dst); 1191549e06463d433ee6351b72dc9107f22ce4305250sewardj } 11928258a8c9f2e0ba23e79e322102fa6d0c354436f1sewardj return; 119305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Store: 119405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vex_printf("mov%c ", i->Ain.Store.sz==1 ? 'b' 119505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj : (i->Ain.Store.sz==2 ? 'w' : 'l')); 119605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj ppHRegAMD64(i->Ain.Store.src); 119705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj vex_printf(","); 119805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj ppAMD64AMode(i->Ain.Store.dst); 119905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1200a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj case Ain_Set64: 1201a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj vex_printf("setq%s ", showAMD64CondCode(i->Ain.Set64.cond)); 1202a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj ppHRegAMD64(i->Ain.Set64.dst); 1203a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj return; 1204f53b7359a342e7d79090615169c6583a1a75fbcesewardj case Ain_Bsfr64: 1205f53b7359a342e7d79090615169c6583a1a75fbcesewardj vex_printf("bs%cq ", i->Ain.Bsfr64.isFwds ? 'f' : 'r'); 1206f53b7359a342e7d79090615169c6583a1a75fbcesewardj ppHRegAMD64(i->Ain.Bsfr64.src); 1207f53b7359a342e7d79090615169c6583a1a75fbcesewardj vex_printf(","); 1208f53b7359a342e7d79090615169c6583a1a75fbcesewardj ppHRegAMD64(i->Ain.Bsfr64.dst); 1209f53b7359a342e7d79090615169c6583a1a75fbcesewardj return; 1210d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_MFence: 1211d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vex_printf("mfence" ); 1212d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 1213e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_ACAS: 1214e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vex_printf("lock cmpxchg%c ", 1215e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj i->Ain.ACAS.sz==1 ? 'b' : i->Ain.ACAS.sz==2 ? 'w' 1216e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj : i->Ain.ACAS.sz==4 ? 'l' : 'q' ); 1217e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vex_printf("{%%rax->%%rbx},"); 1218e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj ppAMD64AMode(i->Ain.ACAS.addr); 1219e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 1220e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_DACAS: 1221e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vex_printf("lock cmpxchg%db {%%rdx:%%rax->%%rcx:%%rbx},", 1222e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj (Int)(2 * i->Ain.DACAS.sz)); 1223e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj ppAMD64AMode(i->Ain.DACAS.addr); 1224e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 122525a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87Free: 1226f4c803b0947e7534809589cba8007851d78c7a2esewardj vex_printf("ffree %%st(7..%d)", 8 - i->Ain.A87Free.nregs ); 122725a858136df4cbea0055c20aa7035d25fd40ee89sewardj break; 122825a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87PushPop: 1229d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj vex_printf(i->Ain.A87PushPop.isPush ? "fld%c " : "fstp%c ", 1230d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj i->Ain.A87PushPop.szB == 4 ? 's' : 'l'); 123125a858136df4cbea0055c20aa7035d25fd40ee89sewardj ppAMD64AMode(i->Ain.A87PushPop.addr); 123225a858136df4cbea0055c20aa7035d25fd40ee89sewardj break; 123325a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87FpOp: 1234f4c803b0947e7534809589cba8007851d78c7a2esewardj vex_printf("f%s", showA87FpOp(i->Ain.A87FpOp.op)); 123525a858136df4cbea0055c20aa7035d25fd40ee89sewardj break; 123625a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87LdCW: 123725a858136df4cbea0055c20aa7035d25fd40ee89sewardj vex_printf("fldcw "); 123825a858136df4cbea0055c20aa7035d25fd40ee89sewardj ppAMD64AMode(i->Ain.A87LdCW.addr); 123925a858136df4cbea0055c20aa7035d25fd40ee89sewardj break; 1240f4c803b0947e7534809589cba8007851d78c7a2esewardj case Ain_A87StSW: 1241f4c803b0947e7534809589cba8007851d78c7a2esewardj vex_printf("fstsw "); 1242f4c803b0947e7534809589cba8007851d78c7a2esewardj ppAMD64AMode(i->Ain.A87StSW.addr); 1243f4c803b0947e7534809589cba8007851d78c7a2esewardj break; 12441a01e65f9993d97095c2af463e98674a091834casewardj case Ain_LdMXCSR: 12451a01e65f9993d97095c2af463e98674a091834casewardj vex_printf("ldmxcsr "); 12461a01e65f9993d97095c2af463e98674a091834casewardj ppAMD64AMode(i->Ain.LdMXCSR.addr); 12471a01e65f9993d97095c2af463e98674a091834casewardj break; 12481830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Ain_SseUComIS: 12491830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vex_printf("ucomis%s ", i->Ain.SseUComIS.sz==4 ? "s" : "d"); 12501830386e7b10430c0c3630123a82d8bcf0a071e7sewardj ppHRegAMD64(i->Ain.SseUComIS.srcL); 12511830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vex_printf(","); 12521830386e7b10430c0c3630123a82d8bcf0a071e7sewardj ppHRegAMD64(i->Ain.SseUComIS.srcR); 12531830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vex_printf(" ; pushfq ; popq "); 12541830386e7b10430c0c3630123a82d8bcf0a071e7sewardj ppHRegAMD64(i->Ain.SseUComIS.dst); 12551830386e7b10430c0c3630123a82d8bcf0a071e7sewardj break; 12561a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSI2SF: 12571a01e65f9993d97095c2af463e98674a091834casewardj vex_printf("cvtsi2s%s ", i->Ain.SseSI2SF.szD==4 ? "s" : "d"); 12581a01e65f9993d97095c2af463e98674a091834casewardj (i->Ain.SseSI2SF.szS==4 ? ppHRegAMD64_lo32 : ppHRegAMD64) 12591a01e65f9993d97095c2af463e98674a091834casewardj (i->Ain.SseSI2SF.src); 12601a01e65f9993d97095c2af463e98674a091834casewardj vex_printf(","); 12611a01e65f9993d97095c2af463e98674a091834casewardj ppHRegAMD64(i->Ain.SseSI2SF.dst); 12621a01e65f9993d97095c2af463e98674a091834casewardj break; 12631a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSF2SI: 12641a01e65f9993d97095c2af463e98674a091834casewardj vex_printf("cvts%s2si ", i->Ain.SseSF2SI.szS==4 ? "s" : "d"); 12651a01e65f9993d97095c2af463e98674a091834casewardj ppHRegAMD64(i->Ain.SseSF2SI.src); 12661a01e65f9993d97095c2af463e98674a091834casewardj vex_printf(","); 12671a01e65f9993d97095c2af463e98674a091834casewardj (i->Ain.SseSF2SI.szD==4 ? ppHRegAMD64_lo32 : ppHRegAMD64) 12681a01e65f9993d97095c2af463e98674a091834casewardj (i->Ain.SseSF2SI.dst); 12691a01e65f9993d97095c2af463e98674a091834casewardj break; 12708d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseSDSS: 12718d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf(i->Ain.SseSDSS.from64 ? "cvtsd2ss " : "cvtss2sd "); 12728d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.SseSDSS.src); 12738d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf(","); 12748d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.SseSDSS.dst); 12758d965316c72c2392f670dcdfa127547ec77c7e56sewardj break; 12761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdSt: 12771830386e7b10430c0c3630123a82d8bcf0a071e7sewardj switch (i->Ain.SseLdSt.sz) { 12781830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case 4: vex_printf("movss "); break; 12791830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case 8: vex_printf("movsd "); break; 12801830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case 16: vex_printf("movups "); break; 12811830386e7b10430c0c3630123a82d8bcf0a071e7sewardj default: vassert(0); 12821830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } 12831001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj if (i->Ain.SseLdSt.isLoad) { 12841001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppAMD64AMode(i->Ain.SseLdSt.addr); 12851001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf(","); 12861001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.SseLdSt.reg); 12871001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } else { 12881001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.SseLdSt.reg); 12891001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf(","); 12901001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppAMD64AMode(i->Ain.SseLdSt.addr); 12911001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 12921001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 129370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCStore: 129470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf("if (%%rflags.%s) { ", 129570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj showAMD64CondCode(i->Ain.SseCStore.cond)); 129670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf("movups "); 129770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ppHRegAMD64(i->Ain.SseCStore.src); 129870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf(", "); 129970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ppAMD64AMode(i->Ain.SseCStore.addr); 130070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf(" }"); 130170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 130270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCLoad: 130370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf("if (%%rflags.%s) { ", 130470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj showAMD64CondCode(i->Ain.SseCLoad.cond)); 130570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf("movups "); 130670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ppAMD64AMode(i->Ain.SseCLoad.addr); 130770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf(", "); 130870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ppHRegAMD64(i->Ain.SseCLoad.dst); 130970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vex_printf(" }"); 131070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 13111001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdzLO: 13121001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf("movs%s ", i->Ain.SseLdzLO.sz==4 ? "s" : "d"); 13131001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppAMD64AMode(i->Ain.SseLdzLO.addr); 13141001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf(","); 13151001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.SseLdzLO.reg); 13161001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 13178d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32Fx4: 13188d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf("%sps ", showAMD64SseOp(i->Ain.Sse32Fx4.op)); 13198d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.Sse32Fx4.src); 13208d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf(","); 13218d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.Sse32Fx4.dst); 13228d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 13238d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32FLo: 13248d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf("%sss ", showAMD64SseOp(i->Ain.Sse32FLo.op)); 13258d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.Sse32FLo.src); 13268d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf(","); 13278d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.Sse32FLo.dst); 13288d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 13294c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Ain_Sse64Fx2: 13304c328cf28ebd12977fbf837c44a614c5aac660f3sewardj vex_printf("%spd ", showAMD64SseOp(i->Ain.Sse64Fx2.op)); 13314c328cf28ebd12977fbf837c44a614c5aac660f3sewardj ppHRegAMD64(i->Ain.Sse64Fx2.src); 13324c328cf28ebd12977fbf837c44a614c5aac660f3sewardj vex_printf(","); 13334c328cf28ebd12977fbf837c44a614c5aac660f3sewardj ppHRegAMD64(i->Ain.Sse64Fx2.dst); 13344c328cf28ebd12977fbf837c44a614c5aac660f3sewardj return; 13351001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Sse64FLo: 13361001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf("%ssd ", showAMD64SseOp(i->Ain.Sse64FLo.op)); 13371001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.Sse64FLo.src); 13381001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf(","); 13391001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.Sse64FLo.dst); 13401001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 13411001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseReRg: 13421001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf("%s ", showAMD64SseOp(i->Ain.SseReRg.op)); 13431001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.SseReRg.src); 13441001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vex_printf(","); 13451001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ppHRegAMD64(i->Ain.SseReRg.dst); 13461001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 13478d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseCMov: 13488d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf("cmov%s ", showAMD64CondCode(i->Ain.SseCMov.cond)); 13498d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.SseCMov.src); 13508d965316c72c2392f670dcdfa127547ec77c7e56sewardj vex_printf(","); 13518d965316c72c2392f670dcdfa127547ec77c7e56sewardj ppHRegAMD64(i->Ain.SseCMov.dst); 13528d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 135309717341a0c364814e35bf405e61399d0e45fa7csewardj case Ain_SseShuf: 1354b173774421d015736c2316b5e6e998e7de545a5cflorian vex_printf("pshufd $0x%x,", (UInt)i->Ain.SseShuf.order); 135509717341a0c364814e35bf405e61399d0e45fa7csewardj ppHRegAMD64(i->Ain.SseShuf.src); 135609717341a0c364814e35bf405e61399d0e45fa7csewardj vex_printf(","); 135709717341a0c364814e35bf405e61399d0e45fa7csewardj ppHRegAMD64(i->Ain.SseShuf.dst); 135809717341a0c364814e35bf405e61399d0e45fa7csewardj return; 13593616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxLdSt: 13603616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu vex_printf("vmovups "); 13613616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu if (i->Ain.AvxLdSt.isLoad) { 13623616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppAMD64AMode(i->Ain.AvxLdSt.addr); 13633616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu vex_printf(","); 13643616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppHRegAMD64(i->Ain.AvxLdSt.reg); 13653616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu } else { 13663616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppHRegAMD64(i->Ain.AvxLdSt.reg); 13673616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu vex_printf(","); 13683616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppAMD64AMode(i->Ain.AvxLdSt.addr); 13693616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu } 13703616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return; 13713616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxReRg: 13723616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu vex_printf("v%s ", showAMD64SseOp(i->Ain.SseReRg.op)); 13733616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppHRegAMD64(i->Ain.AvxReRg.src); 13743616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu vex_printf(","); 13753616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ppHRegAMD64(i->Ain.AvxReRg.dst); 13763616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return; 1377c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_EvCheck: 1378c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("(evCheck) decl "); 1379c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppAMD64AMode(i->Ain.EvCheck.amCounter); 1380c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; jns nofail; jmp *"); 1381c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppAMD64AMode(i->Ain.EvCheck.amFailAddr); 1382c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("; nofail:"); 1383c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1384c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_ProfInc: 1385c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("(profInc) movabsq $NotKnownYet, %%r11; incq (%%r11)"); 1386c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1387c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj default: 1388c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj vpanic("ppAMD64Instr"); 1389c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj } 1390c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1391c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1392c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj/* --------- Helpers for register allocation. --------- */ 1393c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1394d8c64e082224b2e688abdef9219cc76fd82b373bflorianvoid getRegUsage_AMD64Instr ( HRegUsage* u, const AMD64Instr* i, Bool mode64 ) 1395c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj{ 13961001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj Bool unary; 139792b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 1398c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj initHRegUsage(u); 1399c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj switch (i->tag) { 1400813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Ain_Imm64: 1401813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj addHRegUse(u, HRmWrite, i->Ain.Imm64.dst); 1402813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return; 1403f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Alu64R: 1404f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64RMI(u, i->Ain.Alu64R.src); 1405f67eadf04f5150178e589060f03381300d28e540sewardj if (i->Ain.Alu64R.op == Aalu_MOV) { 1406f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmWrite, i->Ain.Alu64R.dst); 1407f67eadf04f5150178e589060f03381300d28e540sewardj return; 1408f67eadf04f5150178e589060f03381300d28e540sewardj } 1409f67eadf04f5150178e589060f03381300d28e540sewardj if (i->Ain.Alu64R.op == Aalu_CMP) { 1410f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, i->Ain.Alu64R.dst); 1411f67eadf04f5150178e589060f03381300d28e540sewardj return; 1412f67eadf04f5150178e589060f03381300d28e540sewardj } 1413f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmModify, i->Ain.Alu64R.dst); 1414f67eadf04f5150178e589060f03381300d28e540sewardj return; 1415f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Alu64M: 1416f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64RI(u, i->Ain.Alu64M.src); 1417f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64AMode(u, i->Ain.Alu64M.dst); 1418f67eadf04f5150178e589060f03381300d28e540sewardj return; 1419f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Sh64: 1420501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj addHRegUse(u, HRmModify, i->Ain.Sh64.dst); 1421f67eadf04f5150178e589060f03381300d28e540sewardj if (i->Ain.Sh64.src == 0) 1422f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmRead, hregAMD64_RCX()); 1423f67eadf04f5150178e589060f03381300d28e540sewardj return; 142405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Test64: 1425501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj addHRegUse(u, HRmRead, i->Ain.Test64.dst); 142605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1427d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_Unary64: 1428501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj addHRegUse(u, HRmModify, i->Ain.Unary64.dst); 1429d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 14306ce1a23b27d1729da9d705abd15b2007dce8daecsewardj case Ain_Lea64: 14316ce1a23b27d1729da9d705abd15b2007dce8daecsewardj addRegUsage_AMD64AMode(u, i->Ain.Lea64.am); 14326ce1a23b27d1729da9d705abd15b2007dce8daecsewardj addHRegUse(u, HRmWrite, i->Ain.Lea64.dst); 14336ce1a23b27d1729da9d705abd15b2007dce8daecsewardj return; 14349cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Ain_Alu32R: 14359cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj vassert(i->Ain.Alu32R.op != Aalu_MOV); 14369cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj addRegUsage_AMD64RMI(u, i->Ain.Alu32R.src); 14379cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (i->Ain.Alu32R.op == Aalu_CMP) { 14389cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj addHRegUse(u, HRmRead, i->Ain.Alu32R.dst); 14399cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj return; 14409cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } 14419cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj addHRegUse(u, HRmModify, i->Ain.Alu32R.dst); 14429cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj return; 14439b96767debeeb1f78378f0e7e295fe6762c64002sewardj case Ain_MulL: 14449b96767debeeb1f78378f0e7e295fe6762c64002sewardj addRegUsage_AMD64RM(u, i->Ain.MulL.src, HRmRead); 14459b96767debeeb1f78378f0e7e295fe6762c64002sewardj addHRegUse(u, HRmModify, hregAMD64_RAX()); 14469b96767debeeb1f78378f0e7e295fe6762c64002sewardj addHRegUse(u, HRmWrite, hregAMD64_RDX()); 14479b96767debeeb1f78378f0e7e295fe6762c64002sewardj return; 14487de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Ain_Div: 14497de0d3c800437fbd82c59d57d156f4823d67609fsewardj addRegUsage_AMD64RM(u, i->Ain.Div.src, HRmRead); 14507de0d3c800437fbd82c59d57d156f4823d67609fsewardj addHRegUse(u, HRmModify, hregAMD64_RAX()); 14517de0d3c800437fbd82c59d57d156f4823d67609fsewardj addHRegUse(u, HRmModify, hregAMD64_RDX()); 14527de0d3c800437fbd82c59d57d156f4823d67609fsewardj return; 14531001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Push: 14541001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addRegUsage_AMD64RMI(u, i->Ain.Push.src); 14551001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmModify, hregAMD64_RSP()); 14561001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 145705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Call: 145805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj /* This is a bit subtle. */ 145905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj /* First off, claim it trashes all the caller-saved regs 146005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj which fall within the register allocator's jurisdiction. 146105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj These I believe to be: rax rcx rdx rsi rdi r8 r9 r10 r11 14623616a2ec4af166a3917810e4fdbe910ed80bd278sewardj and all the xmm registers. 146305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj */ 146405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_RAX()); 146505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_RCX()); 146605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_RDX()); 146705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_RSI()); 146805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_RDI()); 146905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_R8()); 147005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_R9()); 147105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_R10()); 147205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_R11()); 14731001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM0()); 14741001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM1()); 14751001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM3()); 14761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM4()); 14771001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM5()); 14781001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM6()); 14791001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM7()); 14801001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM8()); 14811001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM9()); 14821001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM10()); 14831001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM11()); 14841001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, hregAMD64_XMM12()); 148505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj 148605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj /* Now we have to state any parameter-carrying registers 148705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj which might be read. This depends on the regparmness. */ 148805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj switch (i->Ain.Call.regparms) { 148905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 6: addHRegUse(u, HRmRead, hregAMD64_R9()); /*fallthru*/ 149005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 5: addHRegUse(u, HRmRead, hregAMD64_R8()); /*fallthru*/ 149105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 4: addHRegUse(u, HRmRead, hregAMD64_RCX()); /*fallthru*/ 149205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 3: addHRegUse(u, HRmRead, hregAMD64_RDX()); /*fallthru*/ 149305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 2: addHRegUse(u, HRmRead, hregAMD64_RSI()); /*fallthru*/ 149405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 1: addHRegUse(u, HRmRead, hregAMD64_RDI()); break; 149505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case 0: break; 149605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj default: vpanic("getRegUsage_AMD64Instr:Call:regparms"); 149705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj } 149805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj /* Finally, there is the issue that the insn trashes a 149905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj register because the literal target address has to be 150005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj loaded into a register. Fortunately, r11 is stated in the 150105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj ABI as a scratch register, and so seems a suitable victim. */ 150205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmWrite, hregAMD64_R11()); 150305b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj /* Upshot of this is that the assembler really must use r11, 150405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj and no other, as a destination temporary. */ 150505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1506c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* XDirect/XIndir/XAssisted are also a bit subtle. They 1507c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj conditionally exit the block. Hence we only need to list (1) 1508c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj the registers that they read, and (2) the registers that they 1509c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj write in the case where the block is not exited. (2) is 1510c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj empty, hence only (1) is relevant here. */ 1511c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XDirect: 1512c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Don't bother to mention the write to %r11, since it is not 1513c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj available to the allocator. */ 1514c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addRegUsage_AMD64AMode(u, i->Ain.XDirect.amRIP); 1515c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1516c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XIndir: 1517c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Ditto re %r11 */ 1518c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addHRegUse(u, HRmRead, i->Ain.XIndir.dstGA); 1519c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addRegUsage_AMD64AMode(u, i->Ain.XIndir.amRIP); 1520c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1521c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XAssisted: 1522c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Ditto re %r11 and %rbp (the baseblock ptr) */ 1523c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addHRegUse(u, HRmRead, i->Ain.XAssisted.dstGA); 1524c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addRegUsage_AMD64AMode(u, i->Ain.XAssisted.amRIP); 1525f67eadf04f5150178e589060f03381300d28e540sewardj return; 152605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_CMov64: 1527e357c67787b7429f85a030ee5fbedf33173b5656sewardj addHRegUse(u, HRmRead, i->Ain.CMov64.src); 152805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmModify, i->Ain.CMov64.dst); 152905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1530bdea5508b371d394c81b91464fa8df767010d4dasewardj case Ain_CLoad: 1531bdea5508b371d394c81b91464fa8df767010d4dasewardj addRegUsage_AMD64AMode(u, i->Ain.CLoad.addr); 1532bdea5508b371d394c81b91464fa8df767010d4dasewardj addHRegUse(u, HRmModify, i->Ain.CLoad.dst); 1533bdea5508b371d394c81b91464fa8df767010d4dasewardj return; 15346f1ec58d9806064dea0000e4b543aacded9b11easewardj case Ain_CStore: 15356f1ec58d9806064dea0000e4b543aacded9b11easewardj addRegUsage_AMD64AMode(u, i->Ain.CStore.addr); 15366f1ec58d9806064dea0000e4b543aacded9b11easewardj addHRegUse(u, HRmRead, i->Ain.CStore.src); 15376f1ec58d9806064dea0000e4b543aacded9b11easewardj return; 1538ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj case Ain_MovxLQ: 1539ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj addHRegUse(u, HRmRead, i->Ain.MovxLQ.src); 1540ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj addHRegUse(u, HRmWrite, i->Ain.MovxLQ.dst); 1541f67eadf04f5150178e589060f03381300d28e540sewardj return; 1542f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_LoadEX: 1543f67eadf04f5150178e589060f03381300d28e540sewardj addRegUsage_AMD64AMode(u, i->Ain.LoadEX.src); 1544f67eadf04f5150178e589060f03381300d28e540sewardj addHRegUse(u, HRmWrite, i->Ain.LoadEX.dst); 1545f67eadf04f5150178e589060f03381300d28e540sewardj return; 154605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Store: 154705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addHRegUse(u, HRmRead, i->Ain.Store.src); 154805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj addRegUsage_AMD64AMode(u, i->Ain.Store.dst); 154905b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1550a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj case Ain_Set64: 1551a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj addHRegUse(u, HRmWrite, i->Ain.Set64.dst); 1552a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj return; 1553f53b7359a342e7d79090615169c6583a1a75fbcesewardj case Ain_Bsfr64: 1554f53b7359a342e7d79090615169c6583a1a75fbcesewardj addHRegUse(u, HRmRead, i->Ain.Bsfr64.src); 1555f53b7359a342e7d79090615169c6583a1a75fbcesewardj addHRegUse(u, HRmWrite, i->Ain.Bsfr64.dst); 1556f53b7359a342e7d79090615169c6583a1a75fbcesewardj return; 1557d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_MFence: 1558d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 1559e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_ACAS: 1560e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addRegUsage_AMD64AMode(u, i->Ain.ACAS.addr); 1561e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmRead, hregAMD64_RBX()); 1562e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmModify, hregAMD64_RAX()); 1563e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 1564e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_DACAS: 1565e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addRegUsage_AMD64AMode(u, i->Ain.DACAS.addr); 1566e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmRead, hregAMD64_RCX()); 1567e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmRead, hregAMD64_RBX()); 1568e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmModify, hregAMD64_RDX()); 1569e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addHRegUse(u, HRmModify, hregAMD64_RAX()); 1570e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 157125a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87Free: 157225a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 157325a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87PushPop: 157425a858136df4cbea0055c20aa7035d25fd40ee89sewardj addRegUsage_AMD64AMode(u, i->Ain.A87PushPop.addr); 157525a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 157625a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87FpOp: 157725a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 157825a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87LdCW: 157925a858136df4cbea0055c20aa7035d25fd40ee89sewardj addRegUsage_AMD64AMode(u, i->Ain.A87LdCW.addr); 158025a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 1581f4c803b0947e7534809589cba8007851d78c7a2esewardj case Ain_A87StSW: 1582f4c803b0947e7534809589cba8007851d78c7a2esewardj addRegUsage_AMD64AMode(u, i->Ain.A87StSW.addr); 1583f4c803b0947e7534809589cba8007851d78c7a2esewardj return; 15841a01e65f9993d97095c2af463e98674a091834casewardj case Ain_LdMXCSR: 15851a01e65f9993d97095c2af463e98674a091834casewardj addRegUsage_AMD64AMode(u, i->Ain.LdMXCSR.addr); 15861a01e65f9993d97095c2af463e98674a091834casewardj return; 15871830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Ain_SseUComIS: 15881830386e7b10430c0c3630123a82d8bcf0a071e7sewardj addHRegUse(u, HRmRead, i->Ain.SseUComIS.srcL); 15891830386e7b10430c0c3630123a82d8bcf0a071e7sewardj addHRegUse(u, HRmRead, i->Ain.SseUComIS.srcR); 15901830386e7b10430c0c3630123a82d8bcf0a071e7sewardj addHRegUse(u, HRmWrite, i->Ain.SseUComIS.dst); 15911830386e7b10430c0c3630123a82d8bcf0a071e7sewardj return; 15921a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSI2SF: 15931a01e65f9993d97095c2af463e98674a091834casewardj addHRegUse(u, HRmRead, i->Ain.SseSI2SF.src); 15941a01e65f9993d97095c2af463e98674a091834casewardj addHRegUse(u, HRmWrite, i->Ain.SseSI2SF.dst); 15951a01e65f9993d97095c2af463e98674a091834casewardj return; 15961a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSF2SI: 15971a01e65f9993d97095c2af463e98674a091834casewardj addHRegUse(u, HRmRead, i->Ain.SseSF2SI.src); 15981a01e65f9993d97095c2af463e98674a091834casewardj addHRegUse(u, HRmWrite, i->Ain.SseSF2SI.dst); 15991a01e65f9993d97095c2af463e98674a091834casewardj return; 16008d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseSDSS: 16018d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmRead, i->Ain.SseSDSS.src); 16028d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmWrite, i->Ain.SseSDSS.dst); 16038d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 16041001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdSt: 16051001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addRegUsage_AMD64AMode(u, i->Ain.SseLdSt.addr); 16061001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, i->Ain.SseLdSt.isLoad ? HRmWrite : HRmRead, 16071001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseLdSt.reg); 16081001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 160970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCStore: 161070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addRegUsage_AMD64AMode(u, i->Ain.SseCStore.addr); 161170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addHRegUse(u, HRmRead, i->Ain.SseCStore.src); 161270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 161370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCLoad: 161470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addRegUsage_AMD64AMode(u, i->Ain.SseCLoad.addr); 161570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj addHRegUse(u, HRmModify, i->Ain.SseCLoad.dst); 161670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 16171001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdzLO: 16181001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addRegUsage_AMD64AMode(u, i->Ain.SseLdzLO.addr); 16191001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, i->Ain.SseLdzLO.reg); 16201001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 16218d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32Fx4: 16228d965316c72c2392f670dcdfa127547ec77c7e56sewardj vassert(i->Ain.Sse32Fx4.op != Asse_MOV); 162303ccf858efa285d793061359c04fdd0055cd9d31sewardj unary = toBool( i->Ain.Sse32Fx4.op == Asse_RCPF 162403ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse32Fx4.op == Asse_RSQRTF 162503ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse32Fx4.op == Asse_SQRTF ); 16268d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmRead, i->Ain.Sse32Fx4.src); 16278d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, unary ? HRmWrite : HRmModify, 16288d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32Fx4.dst); 16298d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 16308d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32FLo: 16318d965316c72c2392f670dcdfa127547ec77c7e56sewardj vassert(i->Ain.Sse32FLo.op != Asse_MOV); 163203ccf858efa285d793061359c04fdd0055cd9d31sewardj unary = toBool( i->Ain.Sse32FLo.op == Asse_RCPF 163303ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse32FLo.op == Asse_RSQRTF 163403ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse32FLo.op == Asse_SQRTF ); 16358d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmRead, i->Ain.Sse32FLo.src); 16368d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, unary ? HRmWrite : HRmModify, 16378d965316c72c2392f670dcdfa127547ec77c7e56sewardj i->Ain.Sse32FLo.dst); 16388d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 16394c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Ain_Sse64Fx2: 16404c328cf28ebd12977fbf837c44a614c5aac660f3sewardj vassert(i->Ain.Sse64Fx2.op != Asse_MOV); 1641ca673ab9a76f5697f7ce086ff564bf26f4fa28besewardj unary = toBool( i->Ain.Sse64Fx2.op == Asse_RCPF 1642ca673ab9a76f5697f7ce086ff564bf26f4fa28besewardj || i->Ain.Sse64Fx2.op == Asse_RSQRTF 1643ca673ab9a76f5697f7ce086ff564bf26f4fa28besewardj || i->Ain.Sse64Fx2.op == Asse_SQRTF ); 16444c328cf28ebd12977fbf837c44a614c5aac660f3sewardj addHRegUse(u, HRmRead, i->Ain.Sse64Fx2.src); 16454c328cf28ebd12977fbf837c44a614c5aac660f3sewardj addHRegUse(u, unary ? HRmWrite : HRmModify, 16464c328cf28ebd12977fbf837c44a614c5aac660f3sewardj i->Ain.Sse64Fx2.dst); 16474c328cf28ebd12977fbf837c44a614c5aac660f3sewardj return; 16481001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Sse64FLo: 16491001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(i->Ain.Sse64FLo.op != Asse_MOV); 165003ccf858efa285d793061359c04fdd0055cd9d31sewardj unary = toBool( i->Ain.Sse64FLo.op == Asse_RCPF 165103ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse64FLo.op == Asse_RSQRTF 165203ccf858efa285d793061359c04fdd0055cd9d31sewardj || i->Ain.Sse64FLo.op == Asse_SQRTF ); 16531001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmRead, i->Ain.Sse64FLo.src); 16541001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, unary ? HRmWrite : HRmModify, 16551001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.Sse64FLo.dst); 16561001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 16571001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseReRg: 1658ac5304450fb867b10fce90f1c1774a153dc9576asewardj if ( (i->Ain.SseReRg.op == Asse_XOR 1659ac5304450fb867b10fce90f1c1774a153dc9576asewardj || i->Ain.SseReRg.op == Asse_CMPEQ32) 166079efdc6ea93db174395af845d4e21a4a7ad600ccflorian && sameHReg(i->Ain.SseReRg.src, i->Ain.SseReRg.dst)) { 1661ac5304450fb867b10fce90f1c1774a153dc9576asewardj /* reg-alloc needs to understand 'xor r,r' and 'cmpeqd 1662ac5304450fb867b10fce90f1c1774a153dc9576asewardj r,r' as a write of a value to r, and independent of any 1663ac5304450fb867b10fce90f1c1774a153dc9576asewardj previous value in r */ 16641001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj /* (as opposed to a rite of passage :-) */ 16651001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmWrite, i->Ain.SseReRg.dst); 16661001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } else { 16671001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, HRmRead, i->Ain.SseReRg.src); 16681001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj addHRegUse(u, i->Ain.SseReRg.op == Asse_MOV 16691001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj ? HRmWrite : HRmModify, 16701001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj i->Ain.SseReRg.dst); 16711001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 16721001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 16738d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseCMov: 16748d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmRead, i->Ain.SseCMov.src); 16758d965316c72c2392f670dcdfa127547ec77c7e56sewardj addHRegUse(u, HRmModify, i->Ain.SseCMov.dst); 16768d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 167709717341a0c364814e35bf405e61399d0e45fa7csewardj case Ain_SseShuf: 167809717341a0c364814e35bf405e61399d0e45fa7csewardj addHRegUse(u, HRmRead, i->Ain.SseShuf.src); 167909717341a0c364814e35bf405e61399d0e45fa7csewardj addHRegUse(u, HRmWrite, i->Ain.SseShuf.dst); 168009717341a0c364814e35bf405e61399d0e45fa7csewardj return; 16813616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxLdSt: 16823616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu addRegUsage_AMD64AMode(u, i->Ain.AvxLdSt.addr); 16833616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu addHRegUse(u, i->Ain.AvxLdSt.isLoad ? HRmWrite : HRmRead, 16843616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu i->Ain.AvxLdSt.reg); 16853616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return; 16863616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxReRg: 16873616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu if ( (i->Ain.AvxReRg.op == Asse_XOR 16883616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu || i->Ain.AvxReRg.op == Asse_CMPEQ32) 16893616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu && i->Ain.AvxReRg.src == i->Ain.AvxReRg.dst) { 16903616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu /* See comments on the case for Ain_SseReRg. */ 16913616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu addHRegUse(u, HRmWrite, i->Ain.AvxReRg.dst); 16923616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu } else { 16933616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu addHRegUse(u, HRmRead, i->Ain.AvxReRg.src); 16943616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu addHRegUse(u, i->Ain.AvxReRg.op == Asse_MOV 16953616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu ? HRmWrite : HRmModify, 16963616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu i->Ain.AvxReRg.dst); 16973616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu } 16983616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return; 1699c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_EvCheck: 1700c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We expect both amodes only to mention %rbp, so this is in 1701c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj fact pointless, since %rbp isn't allocatable, but anyway.. */ 1702c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addRegUsage_AMD64AMode(u, i->Ain.EvCheck.amCounter); 1703c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addRegUsage_AMD64AMode(u, i->Ain.EvCheck.amFailAddr); 1704c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1705c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_ProfInc: 1706c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addHRegUse(u, HRmWrite, hregAMD64_R11()); 1707c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1708c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj default: 170992b643609c5fa432b11fc726c2706ae3f3296eb4cerion ppAMD64Instr(i, mode64); 1710c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj vpanic("getRegUsage_AMD64Instr"); 1711c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj } 1712c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1713f67eadf04f5150178e589060f03381300d28e540sewardj 1714f67eadf04f5150178e589060f03381300d28e540sewardj/* local helper */ 171525a858136df4cbea0055c20aa7035d25fd40ee89sewardjstatic inline void mapReg(HRegRemap* m, HReg* r) 1716f67eadf04f5150178e589060f03381300d28e540sewardj{ 1717f67eadf04f5150178e589060f03381300d28e540sewardj *r = lookupHRegRemap(m, *r); 1718f67eadf04f5150178e589060f03381300d28e540sewardj} 1719c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 172092b643609c5fa432b11fc726c2706ae3f3296eb4cerionvoid mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr* i, Bool mode64 ) 1721c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj{ 172292b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 1723c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj switch (i->tag) { 1724813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Ain_Imm64: 1725813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj mapReg(m, &i->Ain.Imm64.dst); 1726813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return; 1727f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Alu64R: 1728f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64RMI(m, i->Ain.Alu64R.src); 1729f67eadf04f5150178e589060f03381300d28e540sewardj mapReg(m, &i->Ain.Alu64R.dst); 1730f67eadf04f5150178e589060f03381300d28e540sewardj return; 1731f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Alu64M: 1732f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64RI(m, i->Ain.Alu64M.src); 1733f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64AMode(m, i->Ain.Alu64M.dst); 1734f67eadf04f5150178e589060f03381300d28e540sewardj return; 1735f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_Sh64: 1736501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj mapReg(m, &i->Ain.Sh64.dst); 1737f67eadf04f5150178e589060f03381300d28e540sewardj return; 173805b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Test64: 1739501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj mapReg(m, &i->Ain.Test64.dst); 174005b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1741d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_Unary64: 1742501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj mapReg(m, &i->Ain.Unary64.dst); 1743d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 17446ce1a23b27d1729da9d705abd15b2007dce8daecsewardj case Ain_Lea64: 17456ce1a23b27d1729da9d705abd15b2007dce8daecsewardj mapRegs_AMD64AMode(m, i->Ain.Lea64.am); 17466ce1a23b27d1729da9d705abd15b2007dce8daecsewardj mapReg(m, &i->Ain.Lea64.dst); 17476ce1a23b27d1729da9d705abd15b2007dce8daecsewardj return; 17489cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Ain_Alu32R: 17499cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mapRegs_AMD64RMI(m, i->Ain.Alu32R.src); 17509cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj mapReg(m, &i->Ain.Alu32R.dst); 17519cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj return; 17529b96767debeeb1f78378f0e7e295fe6762c64002sewardj case Ain_MulL: 17539b96767debeeb1f78378f0e7e295fe6762c64002sewardj mapRegs_AMD64RM(m, i->Ain.MulL.src); 17549b96767debeeb1f78378f0e7e295fe6762c64002sewardj return; 17557de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Ain_Div: 17567de0d3c800437fbd82c59d57d156f4823d67609fsewardj mapRegs_AMD64RM(m, i->Ain.Div.src); 17577de0d3c800437fbd82c59d57d156f4823d67609fsewardj return; 17581001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Push: 17591001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapRegs_AMD64RMI(m, i->Ain.Push.src); 17601001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 176105b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Call: 176205b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1763c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XDirect: 1764c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapRegs_AMD64AMode(m, i->Ain.XDirect.amRIP); 1765c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1766c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XIndir: 1767c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapReg(m, &i->Ain.XIndir.dstGA); 1768c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapRegs_AMD64AMode(m, i->Ain.XIndir.amRIP); 1769c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1770c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XAssisted: 1771c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapReg(m, &i->Ain.XAssisted.dstGA); 1772c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapRegs_AMD64AMode(m, i->Ain.XAssisted.amRIP); 1773f67eadf04f5150178e589060f03381300d28e540sewardj return; 177405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_CMov64: 1775e357c67787b7429f85a030ee5fbedf33173b5656sewardj mapReg(m, &i->Ain.CMov64.src); 177605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj mapReg(m, &i->Ain.CMov64.dst); 177705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1778bdea5508b371d394c81b91464fa8df767010d4dasewardj case Ain_CLoad: 1779bdea5508b371d394c81b91464fa8df767010d4dasewardj mapRegs_AMD64AMode(m, i->Ain.CLoad.addr); 1780bdea5508b371d394c81b91464fa8df767010d4dasewardj mapReg(m, &i->Ain.CLoad.dst); 1781bdea5508b371d394c81b91464fa8df767010d4dasewardj return; 17826f1ec58d9806064dea0000e4b543aacded9b11easewardj case Ain_CStore: 17836f1ec58d9806064dea0000e4b543aacded9b11easewardj mapRegs_AMD64AMode(m, i->Ain.CStore.addr); 17846f1ec58d9806064dea0000e4b543aacded9b11easewardj mapReg(m, &i->Ain.CStore.src); 17856f1ec58d9806064dea0000e4b543aacded9b11easewardj return; 1786ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj case Ain_MovxLQ: 1787ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj mapReg(m, &i->Ain.MovxLQ.src); 1788ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj mapReg(m, &i->Ain.MovxLQ.dst); 1789f67eadf04f5150178e589060f03381300d28e540sewardj return; 1790f67eadf04f5150178e589060f03381300d28e540sewardj case Ain_LoadEX: 1791f67eadf04f5150178e589060f03381300d28e540sewardj mapRegs_AMD64AMode(m, i->Ain.LoadEX.src); 1792f67eadf04f5150178e589060f03381300d28e540sewardj mapReg(m, &i->Ain.LoadEX.dst); 1793f67eadf04f5150178e589060f03381300d28e540sewardj return; 179405b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj case Ain_Store: 179505b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj mapReg(m, &i->Ain.Store.src); 179605b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj mapRegs_AMD64AMode(m, i->Ain.Store.dst); 179705b3b6a0474ba57b4dbd15ac26d857197cdc87fcsewardj return; 1798a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj case Ain_Set64: 1799a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj mapReg(m, &i->Ain.Set64.dst); 1800a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj return; 1801f53b7359a342e7d79090615169c6583a1a75fbcesewardj case Ain_Bsfr64: 1802f53b7359a342e7d79090615169c6583a1a75fbcesewardj mapReg(m, &i->Ain.Bsfr64.src); 1803f53b7359a342e7d79090615169c6583a1a75fbcesewardj mapReg(m, &i->Ain.Bsfr64.dst); 1804f53b7359a342e7d79090615169c6583a1a75fbcesewardj return; 1805d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_MFence: 1806d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj return; 1807e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_ACAS: 1808e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj mapRegs_AMD64AMode(m, i->Ain.ACAS.addr); 1809e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 1810e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_DACAS: 1811e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj mapRegs_AMD64AMode(m, i->Ain.DACAS.addr); 1812e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 181325a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87Free: 181425a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 181525a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87PushPop: 181625a858136df4cbea0055c20aa7035d25fd40ee89sewardj mapRegs_AMD64AMode(m, i->Ain.A87PushPop.addr); 181725a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 181825a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87FpOp: 181925a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 182025a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87LdCW: 182125a858136df4cbea0055c20aa7035d25fd40ee89sewardj mapRegs_AMD64AMode(m, i->Ain.A87LdCW.addr); 182225a858136df4cbea0055c20aa7035d25fd40ee89sewardj return; 1823f4c803b0947e7534809589cba8007851d78c7a2esewardj case Ain_A87StSW: 1824f4c803b0947e7534809589cba8007851d78c7a2esewardj mapRegs_AMD64AMode(m, i->Ain.A87StSW.addr); 1825f4c803b0947e7534809589cba8007851d78c7a2esewardj return; 18261a01e65f9993d97095c2af463e98674a091834casewardj case Ain_LdMXCSR: 18271a01e65f9993d97095c2af463e98674a091834casewardj mapRegs_AMD64AMode(m, i->Ain.LdMXCSR.addr); 18281a01e65f9993d97095c2af463e98674a091834casewardj return; 18291830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Ain_SseUComIS: 18301830386e7b10430c0c3630123a82d8bcf0a071e7sewardj mapReg(m, &i->Ain.SseUComIS.srcL); 18311830386e7b10430c0c3630123a82d8bcf0a071e7sewardj mapReg(m, &i->Ain.SseUComIS.srcR); 18321830386e7b10430c0c3630123a82d8bcf0a071e7sewardj mapReg(m, &i->Ain.SseUComIS.dst); 18331830386e7b10430c0c3630123a82d8bcf0a071e7sewardj return; 18341a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSI2SF: 18351a01e65f9993d97095c2af463e98674a091834casewardj mapReg(m, &i->Ain.SseSI2SF.src); 18361a01e65f9993d97095c2af463e98674a091834casewardj mapReg(m, &i->Ain.SseSI2SF.dst); 18371a01e65f9993d97095c2af463e98674a091834casewardj return; 18381a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSF2SI: 18391a01e65f9993d97095c2af463e98674a091834casewardj mapReg(m, &i->Ain.SseSF2SI.src); 18401a01e65f9993d97095c2af463e98674a091834casewardj mapReg(m, &i->Ain.SseSF2SI.dst); 18411a01e65f9993d97095c2af463e98674a091834casewardj return; 18428d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseSDSS: 18438d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.SseSDSS.src); 18448d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.SseSDSS.dst); 18458d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 18461001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdSt: 18471001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.SseLdSt.reg); 18481001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapRegs_AMD64AMode(m, i->Ain.SseLdSt.addr); 18491001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj break; 185070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCStore: 185170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj mapRegs_AMD64AMode(m, i->Ain.SseCStore.addr); 185270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj mapReg(m, &i->Ain.SseCStore.src); 185370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 185470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCLoad: 185570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj mapRegs_AMD64AMode(m, i->Ain.SseCLoad.addr); 185670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj mapReg(m, &i->Ain.SseCLoad.dst); 185770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj return; 18581001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdzLO: 18591001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.SseLdzLO.reg); 18601001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapRegs_AMD64AMode(m, i->Ain.SseLdzLO.addr); 18611001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj break; 18628d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32Fx4: 18638d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.Sse32Fx4.src); 18648d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.Sse32Fx4.dst); 18658d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 18668d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32FLo: 18678d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.Sse32FLo.src); 18688d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.Sse32FLo.dst); 18698d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 18704c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Ain_Sse64Fx2: 18714c328cf28ebd12977fbf837c44a614c5aac660f3sewardj mapReg(m, &i->Ain.Sse64Fx2.src); 18724c328cf28ebd12977fbf837c44a614c5aac660f3sewardj mapReg(m, &i->Ain.Sse64Fx2.dst); 18734c328cf28ebd12977fbf837c44a614c5aac660f3sewardj return; 18741001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Sse64FLo: 18751001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.Sse64FLo.src); 18761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.Sse64FLo.dst); 18771001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 18781001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseReRg: 18791001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.SseReRg.src); 18801001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj mapReg(m, &i->Ain.SseReRg.dst); 18811001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj return; 18828d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseCMov: 18838d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.SseCMov.src); 18848d965316c72c2392f670dcdfa127547ec77c7e56sewardj mapReg(m, &i->Ain.SseCMov.dst); 18858d965316c72c2392f670dcdfa127547ec77c7e56sewardj return; 188609717341a0c364814e35bf405e61399d0e45fa7csewardj case Ain_SseShuf: 188709717341a0c364814e35bf405e61399d0e45fa7csewardj mapReg(m, &i->Ain.SseShuf.src); 188809717341a0c364814e35bf405e61399d0e45fa7csewardj mapReg(m, &i->Ain.SseShuf.dst); 188909717341a0c364814e35bf405e61399d0e45fa7csewardj return; 18903616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxLdSt: 18913616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu mapReg(m, &i->Ain.AvxLdSt.reg); 18923616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu mapRegs_AMD64AMode(m, i->Ain.AvxLdSt.addr); 18933616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu break; 18943616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxReRg: 18953616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu mapReg(m, &i->Ain.AvxReRg.src); 18963616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu mapReg(m, &i->Ain.AvxReRg.dst); 18973616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return; 1898c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_EvCheck: 1899c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We expect both amodes only to mention %rbp, so this is in 1900c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj fact pointless, since %rbp isn't allocatable, but anyway.. */ 1901c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapRegs_AMD64AMode(m, i->Ain.EvCheck.amCounter); 1902c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj mapRegs_AMD64AMode(m, i->Ain.EvCheck.amFailAddr); 1903c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1904c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_ProfInc: 1905c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* hardwires r11 -- nothing to modify. */ 1906c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return; 1907c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj default: 190892b643609c5fa432b11fc726c2706ae3f3296eb4cerion ppAMD64Instr(i, mode64); 1909c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj vpanic("mapRegs_AMD64Instr"); 1910c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj } 1911c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1912c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1913c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj/* Figure out if i represents a reg-reg move, and if so assign the 1914c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj source and destination to *src and *dst. If in doubt say No. Used 1915c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj by the register allocator to do move coalescing. 1916c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj*/ 1917d8c64e082224b2e688abdef9219cc76fd82b373bflorianBool isMove_AMD64Instr ( const AMD64Instr* i, HReg* src, HReg* dst ) 1918c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj{ 1919c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj switch (i->tag) { 1920c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj case Ain_Alu64R: 1921c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj /* Moves between integer regs */ 1922c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj if (i->Ain.Alu64R.op != Aalu_MOV) 1923c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return False; 1924c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj if (i->Ain.Alu64R.src->tag != Armi_Reg) 1925c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return False; 1926c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj *src = i->Ain.Alu64R.src->Armi.Reg.reg; 1927c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj *dst = i->Ain.Alu64R.dst; 1928c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return True; 1929c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj case Ain_SseReRg: 1930c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj /* Moves between SSE regs */ 1931c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj if (i->Ain.SseReRg.op != Asse_MOV) 1932c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return False; 1933c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj *src = i->Ain.SseReRg.src; 1934c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj *dst = i->Ain.SseReRg.dst; 1935c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj return True; 19363616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxReRg: 19373616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu /* Moves between AVX regs */ 19383616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu if (i->Ain.AvxReRg.op != Asse_MOV) 19393616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return False; 19403616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu *src = i->Ain.AvxReRg.src; 19413616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu *dst = i->Ain.AvxReRg.dst; 19423616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu return True; 1943c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj default: 19441830386e7b10430c0c3630123a82d8bcf0a071e7sewardj return False; 19451830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } 1946c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj /*NOTREACHED*/ 1947c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1948c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1949c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1950c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj/* Generate amd64 spill/reload instructions under the direction of the 1951c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj register allocator. Note it's critical these don't write the 1952c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj condition codes. */ 1953c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 19542a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardjvoid genSpill_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 19552a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj HReg rreg, Int offsetB, Bool mode64 ) 1956d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj{ 1957d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj AMD64AMode* am; 1958d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vassert(offsetB >= 0); 1959d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vassert(!hregIsVirtual(rreg)); 196092b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 19612a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = *i2 = NULL; 1962d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj am = AMD64AMode_IR(offsetB, hregAMD64_RBP()); 1963d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj switch (hregClass(rreg)) { 1964d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case HRcInt64: 19652a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = AMD64Instr_Alu64M ( Aalu_MOV, AMD64RI_Reg(rreg), am ); 19662a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj return; 19671001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case HRcVec128: 19682a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = AMD64Instr_SseLdSt ( False/*store*/, 16, rreg, am ); 19692a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj return; 1970d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj default: 1971d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj ppHRegClass(hregClass(rreg)); 1972d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vpanic("genSpill_AMD64: unimplemented regclass"); 1973d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 1974c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1975c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 19762a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardjvoid genReload_AMD64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 19772a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj HReg rreg, Int offsetB, Bool mode64 ) 1978d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj{ 1979d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj AMD64AMode* am; 1980d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vassert(offsetB >= 0); 1981d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vassert(!hregIsVirtual(rreg)); 198292b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 19832a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = *i2 = NULL; 1984d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj am = AMD64AMode_IR(offsetB, hregAMD64_RBP()); 1985d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj switch (hregClass(rreg)) { 1986d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case HRcInt64: 19872a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = AMD64Instr_Alu64R ( Aalu_MOV, AMD64RMI_Mem(am), rreg ); 19882a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj return; 19891001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case HRcVec128: 19902a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj *i1 = AMD64Instr_SseLdSt ( True/*load*/, 16, rreg, am ); 19912a1ed8e417440976e0c8059715ee0c87d3e2f5ccsewardj return; 1992d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj default: 1993d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj ppHRegClass(hregClass(rreg)); 1994d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj vpanic("genReload_AMD64: unimplemented regclass"); 1995d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 1996c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 1997c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 1998ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott HughesAMD64Instr* directReload_AMD64( AMD64Instr* i, HReg vreg, Short spill_off ) 1999ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes{ 2000ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes vassert(spill_off >= 0 && spill_off < 10000); /* let's say */ 2001ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 2002ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Deal with form: src=RMI_Reg, dst=Reg where src == vreg 2003ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Convert to: src=RMI_Mem, dst=Reg 2004ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes */ 2005ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (i->tag == Ain_Alu64R 2006ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && (i->Ain.Alu64R.op == Aalu_MOV || i->Ain.Alu64R.op == Aalu_OR 2007ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes || i->Ain.Alu64R.op == Aalu_XOR) 2008ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && i->Ain.Alu64R.src->tag == Armi_Reg 2009ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && sameHReg(i->Ain.Alu64R.src->Armi.Reg.reg, vreg)) { 2010ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes vassert(! sameHReg(i->Ain.Alu64R.dst, vreg)); 2011ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return AMD64Instr_Alu64R( 2012ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes i->Ain.Alu64R.op, 2013ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes AMD64RMI_Mem( AMD64AMode_IR( spill_off, hregAMD64_RBP())), 2014ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes i->Ain.Alu64R.dst 2015ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes ); 2016ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 2017ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 2018ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* Deal with form: src=RMI_Imm, dst=Reg where dst == vreg 2019ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Convert to: src=RI_Imm, dst=Mem 2020ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes */ 2021ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (i->tag == Ain_Alu64R 2022ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && (i->Ain.Alu64R.op == Aalu_CMP) 2023ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && i->Ain.Alu64R.src->tag == Armi_Imm 2024ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && sameHReg(i->Ain.Alu64R.dst, vreg)) { 2025ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return AMD64Instr_Alu64M( 2026ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes i->Ain.Alu64R.op, 2027ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes AMD64RI_Imm( i->Ain.Alu64R.src->Armi.Imm.imm32 ), 2028ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes AMD64AMode_IR( spill_off, hregAMD64_RBP()) 2029ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes ); 2030ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 2031ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 2032ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes return NULL; 2033ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes} 2034ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 2035c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 2036813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* --------- The amd64 assembler (bleh.) --------- */ 2037813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2038813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* Produce the low three bits of an integer register number. */ 2039a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt iregEnc210 ( HReg r ) 2040813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2041813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj UInt n; 2042813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(hregClass(r) == HRcInt64); 2043813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(!hregIsVirtual(r)); 2044a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj n = hregEncoding(r); 2045813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(n <= 15); 2046a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return n & 7; 2047813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2048813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2049813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* Produce bit 3 of an integer register number. */ 2050a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt iregEnc3 ( HReg r ) 2051813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2052813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj UInt n; 2053813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(hregClass(r) == HRcInt64); 2054813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(!hregIsVirtual(r)); 2055a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj n = hregEncoding(r); 2056813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(n <= 15); 2057a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return (n >> 3) & 1; 2058813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2059813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2060dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj/* Produce a complete 4-bit integer register number. */ 2061a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt iregEnc3210 ( HReg r ) 2062dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj{ 2063dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj UInt n; 2064dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj vassert(hregClass(r) == HRcInt64); 2065dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj vassert(!hregIsVirtual(r)); 2066a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj n = hregEncoding(r); 2067dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj vassert(n <= 15); 2068a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return n; 2069dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj} 2070dc2ca89b181aa0429f7c62aed4f94cfb415ec02esewardj 2071a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj/* Produce a complete 4-bit integer register number. */ 2072a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt vregEnc3210 ( HReg r ) 20731001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj{ 20741001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj UInt n; 20751001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(hregClass(r) == HRcVec128); 20761001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(!hregIsVirtual(r)); 2077a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj n = hregEncoding(r); 20781001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(n <= 15); 2079a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return n; 20801001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj} 2081813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2082a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UChar mkModRegRM ( UInt mod, UInt reg, UInt regmem ) 2083813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2084b5e7ced3600c90faa2ebf9dbbdc0e0e6cda7bfc7sewardj vassert(mod < 4); 2085b5e7ced3600c90faa2ebf9dbbdc0e0e6cda7bfc7sewardj vassert((reg|regmem) < 8); 2086a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return (UChar)( ((mod & 3) << 6) | ((reg & 7) << 3) | (regmem & 7) ); 2087813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2088813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2089a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UChar mkSIB ( UInt shift, UInt regindex, UInt regbase ) 2090813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2091b5e7ced3600c90faa2ebf9dbbdc0e0e6cda7bfc7sewardj vassert(shift < 4); 2092b5e7ced3600c90faa2ebf9dbbdc0e0e6cda7bfc7sewardj vassert((regindex|regbase) < 8); 2093a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return (UChar)( ((shift & 3) << 6) | ((regindex & 7) << 3) | (regbase & 7) ); 2094813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2095813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2096813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardjstatic UChar* emit32 ( UChar* p, UInt w32 ) 2097813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 209803ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar((w32) & 0x000000FF); 209903ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar((w32 >> 8) & 0x000000FF); 210003ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar((w32 >> 16) & 0x000000FF); 210103ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar((w32 >> 24) & 0x000000FF); 2102813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2103813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2104813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 21051b8d58eb046ad31fbb058d65855b604886d3d177sewardjstatic UChar* emit64 ( UChar* p, ULong w64 ) 21061b8d58eb046ad31fbb058d65855b604886d3d177sewardj{ 210703ccf858efa285d793061359c04fdd0055cd9d31sewardj p = emit32(p, toUInt(w64 & 0xFFFFFFFF)); 210803ccf858efa285d793061359c04fdd0055cd9d31sewardj p = emit32(p, toUInt((w64 >> 32) & 0xFFFFFFFF)); 21091b8d58eb046ad31fbb058d65855b604886d3d177sewardj return p; 21101b8d58eb046ad31fbb058d65855b604886d3d177sewardj} 21111b8d58eb046ad31fbb058d65855b604886d3d177sewardj 2112813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* Does a sign-extend of the lowest 8 bits give 2113813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj the original number? */ 2114813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardjstatic Bool fits8bits ( UInt w32 ) 2115813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2116813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj Int i32 = (Int)w32; 2117108e03fcb0a4ef42164235b1988aa540aa1e5298florian return toBool(i32 == ((Int)(w32 << 24) >> 24)); 2118813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 21194d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj/* Can the lower 32 bits be signedly widened to produce the whole 21204d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj 64-bit value? In other words, are the top 33 bits either all 0 or 21214d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj all 1 ? */ 21224d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardjstatic Bool fitsIn32Bits ( ULong x ) 21234d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj{ 2124108e03fcb0a4ef42164235b1988aa540aa1e5298florian Long y1; 2125108e03fcb0a4ef42164235b1988aa540aa1e5298florian y1 = x << 32; 21264d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj y1 >>=/*s*/ 32; 21274d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj return toBool(x == y1); 21284d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj} 2129813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2130813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2131813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* Forming mod-reg-rm bytes and scale-index-base bytes. 2132813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2133e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj greg, 0(ereg) | ereg is not any of: RSP RBP R12 R13 2134813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj = 00 greg ereg 2135813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2136e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj greg, d8(ereg) | ereg is neither of: RSP R12 2137813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj = 01 greg ereg, d8 2138813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2139e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj greg, d32(ereg) | ereg is neither of: RSP R12 2140813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj = 10 greg ereg, d32 2141813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2142e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj greg, d8(ereg) | ereg is either: RSP R12 2143e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj = 01 greg 100, 0x24, d8 2144e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj (lowest bit of rex distinguishes R12/RSP) 2145e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj 21467de0d3c800437fbd82c59d57d156f4823d67609fsewardj greg, d32(ereg) | ereg is either: RSP R12 21477de0d3c800437fbd82c59d57d156f4823d67609fsewardj = 10 greg 100, 0x24, d32 21487de0d3c800437fbd82c59d57d156f4823d67609fsewardj (lowest bit of rex distinguishes R12/RSP) 2149813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2150813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj ----------------------------------------------- 2151813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2152813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj greg, d8(base,index,scale) 2153813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj | index != RSP 2154813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj = 01 greg 100, scale index base, d8 2155813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2156813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj greg, d32(base,index,scale) 2157813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj | index != RSP 2158813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj = 10 greg 100, scale index base, d32 2159813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj*/ 2160a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_M__wrk ( UChar* p, UInt gregEnc3210, AMD64AMode* am ) 2161813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2162a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UInt gregEnc210 = gregEnc3210 & 7; 2163813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (am->tag == Aam_IR) { 2164813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (am->Aam.IR.imm == 0 216579efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_RSP()) 216679efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_RBP()) 216779efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_R12()) 216879efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_R13()) 2169e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj ) { 2170a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(0, gregEnc210, iregEnc210(am->Aam.IR.reg)); 2171813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2172813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2173813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (fits8bits(am->Aam.IR.imm) 217479efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_RSP()) 217579efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_R12()) 2176e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj ) { 2177a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(1, gregEnc210, iregEnc210(am->Aam.IR.reg)); 217803ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(am->Aam.IR.imm & 0xFF); 2179813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2180813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 218179efdc6ea93db174395af845d4e21a4a7ad600ccflorian if (! sameHReg(am->Aam.IR.reg, hregAMD64_RSP()) 218279efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IR.reg, hregAMD64_R12()) 2183e95b04a535c72c948cf135f802fbdca5d3b23f76sewardj ) { 2184a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(2, gregEnc210, iregEnc210(am->Aam.IR.reg)); 2185813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj p = emit32(p, am->Aam.IR.imm); 2186813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2187813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 218879efdc6ea93db174395af845d4e21a4a7ad600ccflorian if ((sameHReg(am->Aam.IR.reg, hregAMD64_RSP()) 218979efdc6ea93db174395af845d4e21a4a7ad600ccflorian || sameHReg(am->Aam.IR.reg, hregAMD64_R12())) 2190813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj && fits8bits(am->Aam.IR.imm)) { 2191a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(1, gregEnc210, 4); 2192813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj *p++ = 0x24; 219303ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(am->Aam.IR.imm & 0xFF); 2194813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2195813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 219679efdc6ea93db174395af845d4e21a4a7ad600ccflorian if (/* (sameHReg(am->Aam.IR.reg, hregAMD64_RSP()) 2197a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj || wait for test case for RSP case */ 219879efdc6ea93db174395af845d4e21a4a7ad600ccflorian sameHReg(am->Aam.IR.reg, hregAMD64_R12())) { 2199a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(2, gregEnc210, 4); 22007de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0x24; 22017de0d3c800437fbd82c59d57d156f4823d67609fsewardj p = emit32(p, am->Aam.IR.imm); 22027de0d3c800437fbd82c59d57d156f4823d67609fsewardj return p; 22037de0d3c800437fbd82c59d57d156f4823d67609fsewardj } 2204813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj ppAMD64AMode(am); 2205813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vpanic("doAMode_M: can't emit amode IR"); 2206813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj /*NOTREACHED*/ 2207813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2208813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (am->tag == Aam_IRRS) { 2209813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (fits8bits(am->Aam.IRRS.imm) 221079efdc6ea93db174395af845d4e21a4a7ad600ccflorian && ! sameHReg(am->Aam.IRRS.index, hregAMD64_RSP())) { 2211a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(1, gregEnc210, 4); 2212a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkSIB(am->Aam.IRRS.shift, iregEnc210(am->Aam.IRRS.index), 2213a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj iregEnc210(am->Aam.IRRS.base)); 221403ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(am->Aam.IRRS.imm & 0xFF); 2215813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2216813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 221779efdc6ea93db174395af845d4e21a4a7ad600ccflorian if (! sameHReg(am->Aam.IRRS.index, hregAMD64_RSP())) { 2218a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(2, gregEnc210, 4); 2219a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkSIB(am->Aam.IRRS.shift, iregEnc210(am->Aam.IRRS.index), 2220a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj iregEnc210(am->Aam.IRRS.base)); 2221813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj p = emit32(p, am->Aam.IRRS.imm); 2222813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2223813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2224813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj ppAMD64AMode(am); 2225813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vpanic("doAMode_M: can't emit amode IRRS"); 2226813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj /*NOTREACHED*/ 2227813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2228813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vpanic("doAMode_M: unknown amode"); 2229813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj /*NOTREACHED*/ 2230813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2231813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2232a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_M ( UChar* p, HReg greg, AMD64AMode* am ) 2233a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2234a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_M__wrk(p, iregEnc3210(greg), am); 2235a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2236a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2237a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_M_enc ( UChar* p, UInt gregEnc3210, AMD64AMode* am ) 2238a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2239a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(gregEnc3210 < 16); 2240a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_M__wrk(p, gregEnc3210, am); 2241a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2242a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2243813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2244813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj/* Emit a mod-reg-rm byte when the rm bit denotes a reg. */ 2245a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline 2246a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_R__wrk ( UChar* p, UInt gregEnc3210, UInt eregEnc3210 ) 2247813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2248a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = mkModRegRM(3, gregEnc3210 & 7, eregEnc3210 & 7); 2249813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj return p; 2250813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2251813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2252a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_R ( UChar* p, HReg greg, HReg ereg ) 2253a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2254a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_R__wrk(p, iregEnc3210(greg), iregEnc3210(ereg)); 2255a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2256a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2257a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_R_enc_reg ( UChar* p, UInt gregEnc3210, HReg ereg ) 2258a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2259a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(gregEnc3210 < 16); 2260a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_R__wrk(p, gregEnc3210, iregEnc3210(ereg)); 2261a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2262a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2263a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_R_reg_enc ( UChar* p, HReg greg, UInt eregEnc3210 ) 2264a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2265a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(eregEnc3210 < 16); 2266a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_R__wrk(p, iregEnc3210(greg), eregEnc3210); 2267a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2268a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2269a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar* doAMode_R_enc_enc ( UChar* p, UInt gregEnc3210, UInt eregEnc3210 ) 2270a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2271a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert( (gregEnc3210|eregEnc3210) < 16); 2272a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return doAMode_R__wrk(p, gregEnc3210, eregEnc3210); 2273a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2274a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2275813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2276549e06463d433ee6351b72dc9107f22ce4305250sewardj/* Clear the W bit on a REX byte, thereby changing the operand size 2277549e06463d433ee6351b72dc9107f22ce4305250sewardj back to whatever that instruction's default operand size is. */ 2278549e06463d433ee6351b72dc9107f22ce4305250sewardjstatic inline UChar clearWBit ( UChar rex ) 2279549e06463d433ee6351b72dc9107f22ce4305250sewardj{ 2280a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rex & ~(1<<3); 2281549e06463d433ee6351b72dc9107f22ce4305250sewardj} 2282549e06463d433ee6351b72dc9107f22ce4305250sewardj 2283549e06463d433ee6351b72dc9107f22ce4305250sewardj 2284549e06463d433ee6351b72dc9107f22ce4305250sewardj/* Make up a REX byte, with W=1 (size=64), for a (greg,amode) pair. */ 2285a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UChar rexAMode_M__wrk ( UInt gregEnc3210, AMD64AMode* am ) 2286813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj{ 2287813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (am->tag == Aam_IR) { 2288813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj UChar W = 1; /* we want 64-bit mode */ 2289a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar R = (gregEnc3210 >> 3) & 1; 2290813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj UChar X = 0; /* not relevant */ 2291a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar B = iregEnc3(am->Aam.IR.reg); 2292a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return 0x40 + ((W << 3) | (R << 2) | (X << 1) | (B << 0)); 2293813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2294813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (am->tag == Aam_IRRS) { 2295813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj UChar W = 1; /* we want 64-bit mode */ 2296a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar R = (gregEnc3210 >> 3) & 1; 2297a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar X = iregEnc3(am->Aam.IRRS.index); 2298a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar B = iregEnc3(am->Aam.IRRS.base); 2299a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return 0x40 + ((W << 3) | (R << 2) | (X << 1) | (B << 0)); 2300813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2301813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj vassert(0); 230203ccf858efa285d793061359c04fdd0055cd9d31sewardj return 0; /*NOTREACHED*/ 2303813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj} 2304813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2305a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_M ( HReg greg, AMD64AMode* am ) 2306a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2307a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_M__wrk(iregEnc3210(greg), am); 2308a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2309a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2310a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_M_enc ( UInt gregEnc3210, AMD64AMode* am ) 2311a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2312a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(gregEnc3210 < 16); 2313a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_M__wrk(gregEnc3210, am); 2314a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2315a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2316a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2317549e06463d433ee6351b72dc9107f22ce4305250sewardj/* Make up a REX byte, with W=1 (size=64), for a (greg,ereg) pair. */ 2318a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UChar rexAMode_R__wrk ( UInt gregEnc3210, UInt eregEnc3210 ) 2319549e06463d433ee6351b72dc9107f22ce4305250sewardj{ 2320549e06463d433ee6351b72dc9107f22ce4305250sewardj UChar W = 1; /* we want 64-bit mode */ 2321a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar R = (gregEnc3210 >> 3) & 1; 2322549e06463d433ee6351b72dc9107f22ce4305250sewardj UChar X = 0; /* not relevant */ 2323a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj UChar B = (eregEnc3210 >> 3) & 1; 2324a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return 0x40 + ((W << 3) | (R << 2) | (X << 1) | (B << 0)); 2325a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2326a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2327a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_R ( HReg greg, HReg ereg ) 2328a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2329a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_R__wrk(iregEnc3210(greg), iregEnc3210(ereg)); 2330a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2331a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2332a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_R_enc_reg ( UInt gregEnc3210, HReg ereg ) 2333a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2334a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(gregEnc3210 < 16); 2335a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_R__wrk(gregEnc3210, iregEnc3210(ereg)); 2336a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2337a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2338a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_R_reg_enc ( HReg greg, UInt eregEnc3210 ) 2339a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2340a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert(eregEnc3210 < 16); 2341a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_R__wrk(iregEnc3210(greg), eregEnc3210); 2342a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj} 2343a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj 2344a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjstatic UChar rexAMode_R_enc_enc ( UInt gregEnc3210, UInt eregEnc3210 ) 2345a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{ 2346a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vassert((gregEnc3210|eregEnc3210) < 16); 2347a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj return rexAMode_R__wrk(gregEnc3210, eregEnc3210); 2348549e06463d433ee6351b72dc9107f22ce4305250sewardj} 2349549e06463d433ee6351b72dc9107f22ce4305250sewardj 2350813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 23513616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* May 2012: this VEX prefix stuff is currently unused, but has 23523616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu verified correct (I reckon). Certainly it has been known to 23533616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu produce correct VEX prefixes during testing. */ 23543616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu 23553616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* Assemble a 2 or 3 byte VEX prefix from parts. rexR, rexX, rexB and 23563616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu notVvvvv need to be not-ed before packing. mmmmm, rexW, L and pp go 23573616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu in verbatim. There's no range checking on the bits. */ 23583616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu static UInt packVexPrefix ( UInt rexR, UInt rexX, UInt rexB, 23593616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UInt mmmmm, UInt rexW, UInt notVvvv, 23603616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UInt L, UInt pp ) 23613616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu { 23623616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar byte0 = 0; 23633616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar byte1 = 0; 23643616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar byte2 = 0; 23653616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu if (rexX == 0 && rexB == 0 && mmmmm == 1 && rexW == 0) { 23663616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* 2 byte encoding is possible. */ 23673616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu byte0 = 0xC5; 23683616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu byte1 = ((rexR ^ 1) << 7) | ((notVvvv ^ 0xF) << 3) 23693616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu | (L << 2) | pp; 23703616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } else { 23713616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* 3 byte encoding is needed. */ 23723616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu byte0 = 0xC4; 23733616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu byte1 = ((rexR ^ 1) << 7) | ((rexX ^ 1) << 6) 23743616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu | ((rexB ^ 1) << 5) | mmmmm; 23753616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu byte2 = (rexW << 7) | ((notVvvv ^ 0xF) << 3) | (L << 2) | pp; 23763616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 23773616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu return (((UInt)byte2) << 16) | (((UInt)byte1) << 8) | ((UInt)byte0); 23783616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 23793616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu 23803616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* Make up a VEX prefix for a (greg,amode) pair. First byte in bits 23813616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu 7:0 of result, second in 15:8, third (for a 3 byte prefix) in 23823616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu 23:16. Has m-mmmm set to indicate a prefix of 0F, pp set to 23833616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu indicate no SIMD prefix, W=0 (ignore), L=1 (size=256), and 23843616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu vvvv=1111 (unused 3rd reg). */ 23853616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu static UInt vexAMode_M ( HReg greg, AMD64AMode* am ) 23863616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu { 23873616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar L = 1; /* size = 256 */ 23883616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar pp = 0; /* no SIMD prefix */ 23893616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar mmmmm = 1; /* 0F */ 23903616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar notVvvv = 0; /* unused */ 23913616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar rexW = 0; 23923616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar rexR = 0; 23933616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar rexX = 0; 23943616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu UChar rexB = 0; 23953616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu /* Same logic as in rexAMode_M. */ 23963616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu if (am->tag == Aam_IR) { 2397a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj//uu rexR = iregEnc3(greg); 23983616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu rexX = 0; /* not relevant */ 2399a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj//uu rexB = iregEnc3(am->Aam.IR.reg); 24003616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 24013616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu else if (am->tag == Aam_IRRS) { 2402a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj//uu rexR = iregEnc3(greg); 2403a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj//uu rexX = iregEnc3(am->Aam.IRRS.index); 2404a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj//uu rexB = iregEnc3(am->Aam.IRRS.base); 24053616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } else { 24063616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu vassert(0); 24073616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 24083616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu return packVexPrefix( rexR, rexX, rexB, mmmmm, rexW, notVvvv, L, pp ); 24093616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 24103616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu 24113616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu static UChar* emitVexPrefix ( UChar* p, UInt vex ) 24123616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu { 24133616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu switch (vex & 0xFF) { 24143616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu case 0xC5: 24153616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu *p++ = 0xC5; 24163616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu *p++ = (vex >> 8) & 0xFF; 24173616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu vassert(0 == (vex >> 16)); 24183616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu break; 24193616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu case 0xC4: 24203616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu *p++ = 0xC4; 24213616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu *p++ = (vex >> 8) & 0xFF; 24223616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu *p++ = (vex >> 16) & 0xFF; 24233616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu vassert(0 == (vex >> 24)); 24243616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu break; 24253616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu default: 24263616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu vassert(0); 24273616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 24283616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu return p; 24293616a2ec4af166a3917810e4fdbe910ed80bd278sewardj//uu } 2430c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj 2431c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj 243225a858136df4cbea0055c20aa7035d25fd40ee89sewardj/* Emit ffree %st(N) */ 243325a858136df4cbea0055c20aa7035d25fd40ee89sewardjstatic UChar* do_ffree_st ( UChar* p, Int n ) 243425a858136df4cbea0055c20aa7035d25fd40ee89sewardj{ 243525a858136df4cbea0055c20aa7035d25fd40ee89sewardj vassert(n >= 0 && n <= 7); 243625a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = 0xDD; 243725a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = toUChar(0xC0 + n); 243825a858136df4cbea0055c20aa7035d25fd40ee89sewardj return p; 243925a858136df4cbea0055c20aa7035d25fd40ee89sewardj} 244025a858136df4cbea0055c20aa7035d25fd40ee89sewardj 2441c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj/* Emit an instruction into buf and return the number of bytes used. 2442c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj Note that buf is not the insn's final place, and therefore it is 2443c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj imperative to emit position-independent code. If the emitted 2444c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj instruction was a profiler inc, set *is_profInc to True, else 2445c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj leave it unchanged. */ 2446c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 2447c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjInt emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc, 2448d8c64e082224b2e688abdef9219cc76fd82b373bflorian UChar* buf, Int nbuf, const AMD64Instr* i, 24499b76916dcc1628e133d57db001563429c6e3a590sewardj Bool mode64, VexEndness endness_host, 24508462d113e3efeacceb304222dada8d85f748295aflorian const void* disp_cp_chain_me_to_slowEP, 24518462d113e3efeacceb304222dada8d85f748295aflorian const void* disp_cp_chain_me_to_fastEP, 24528462d113e3efeacceb304222dada8d85f748295aflorian const void* disp_cp_xindir, 24538462d113e3efeacceb304222dada8d85f748295aflorian const void* disp_cp_xassisted ) 2454c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj{ 2455c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj UInt /*irno,*/ opc, opc_rr, subopc_imm, opc_imma, opc_cl, opc_imm, subopc; 24561001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj UInt xtra; 2457a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj UInt reg; 24581001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj UChar rex; 2459c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj UChar* p = &buf[0]; 2460549e06463d433ee6351b72dc9107f22ce4305250sewardj UChar* ptmp; 246125a858136df4cbea0055c20aa7035d25fd40ee89sewardj Int j; 246270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(nbuf >= 64); 246392b643609c5fa432b11fc726c2706ae3f3296eb4cerion vassert(mode64 == True); 2464549e06463d433ee6351b72dc9107f22ce4305250sewardj 246592b643609c5fa432b11fc726c2706ae3f3296eb4cerion /* vex_printf("asm "); ppAMD64Instr(i, mode64); vex_printf("\n"); */ 2466c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 2467c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj switch (i->tag) { 2468c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 24691b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ain_Imm64: 24707cf5bd04544e5288102d0b911a8910533d0a2161sewardj if (i->Ain.Imm64.imm64 <= 0xFFFFFULL) { 24717cf5bd04544e5288102d0b911a8910533d0a2161sewardj /* Use the short form (load into 32 bit reg, + default 24727cf5bd04544e5288102d0b911a8910533d0a2161sewardj widening rule) for constants under 1 million. We could 24737cf5bd04544e5288102d0b911a8910533d0a2161sewardj use this form for the range 0 to 0x7FFFFFFF inclusive, but 24747cf5bd04544e5288102d0b911a8910533d0a2161sewardj limit it to a smaller range for verifiability purposes. */ 2475a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj if (1 & iregEnc3(i->Ain.Imm64.dst)) 24767cf5bd04544e5288102d0b911a8910533d0a2161sewardj *p++ = 0x41; 2477a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = 0xB8 + iregEnc210(i->Ain.Imm64.dst); 24787cf5bd04544e5288102d0b911a8910533d0a2161sewardj p = emit32(p, (UInt)i->Ain.Imm64.imm64); 24797cf5bd04544e5288102d0b911a8910533d0a2161sewardj } else { 2480a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x48 + (1 & iregEnc3(i->Ain.Imm64.dst))); 2481a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0xB8 + iregEnc210(i->Ain.Imm64.dst)); 24827cf5bd04544e5288102d0b911a8910533d0a2161sewardj p = emit64(p, i->Ain.Imm64.imm64); 24837cf5bd04544e5288102d0b911a8910533d0a2161sewardj } 24841b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 24851b8d58eb046ad31fbb058d65855b604886d3d177sewardj 2486813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Ain_Alu64R: 2487813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj /* Deal specially with MOV */ 2488813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj if (i->Ain.Alu64R.op == Aalu_MOV) { 2489813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj switch (i->Ain.Alu64R.src->tag) { 2490813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Armi_Imm: 24917cf5bd04544e5288102d0b911a8910533d0a2161sewardj if (0 == (i->Ain.Alu64R.src->Armi.Imm.imm32 & ~0xFFFFF)) { 249295e154cd4155e22c25e4ed0554d42773cb0e0650sewardj /* Actually we could use this form for constants in 249395e154cd4155e22c25e4ed0554d42773cb0e0650sewardj the range 0 through 0x7FFFFFFF inclusive, but 249495e154cd4155e22c25e4ed0554d42773cb0e0650sewardj limit it to a small range for verifiability 249595e154cd4155e22c25e4ed0554d42773cb0e0650sewardj purposes. */ 249695e154cd4155e22c25e4ed0554d42773cb0e0650sewardj /* Generate "movl $imm32, 32-bit-register" and let 249795e154cd4155e22c25e4ed0554d42773cb0e0650sewardj the default zero-extend rule cause the upper half 249895e154cd4155e22c25e4ed0554d42773cb0e0650sewardj of the dst to be zeroed out too. This saves 1 249995e154cd4155e22c25e4ed0554d42773cb0e0650sewardj and sometimes 2 bytes compared to the more 250095e154cd4155e22c25e4ed0554d42773cb0e0650sewardj obvious encoding in the 'else' branch. */ 2501a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj if (1 & iregEnc3(i->Ain.Alu64R.dst)) 250295e154cd4155e22c25e4ed0554d42773cb0e0650sewardj *p++ = 0x41; 2503a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = 0xB8 + iregEnc210(i->Ain.Alu64R.dst); 250495e154cd4155e22c25e4ed0554d42773cb0e0650sewardj p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32); 250595e154cd4155e22c25e4ed0554d42773cb0e0650sewardj } else { 2506a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x48 + (1 & iregEnc3(i->Ain.Alu64R.dst))); 250795e154cd4155e22c25e4ed0554d42773cb0e0650sewardj *p++ = 0xC7; 2508a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0xC0 + iregEnc210(i->Ain.Alu64R.dst)); 250995e154cd4155e22c25e4ed0554d42773cb0e0650sewardj p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32); 251095e154cd4155e22c25e4ed0554d42773cb0e0650sewardj } 2511813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj goto done; 2512813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Armi_Reg: 25131b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = rexAMode_R( i->Ain.Alu64R.src->Armi.Reg.reg, 25141b8d58eb046ad31fbb058d65855b604886d3d177sewardj i->Ain.Alu64R.dst ); 2515813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj *p++ = 0x89; 2516813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj p = doAMode_R(p, i->Ain.Alu64R.src->Armi.Reg.reg, 2517813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->Ain.Alu64R.dst); 2518813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj goto done; 2519813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj case Armi_Mem: 2520549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = rexAMode_M(i->Ain.Alu64R.dst, 2521813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->Ain.Alu64R.src->Armi.Mem.am); 2522813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj *p++ = 0x8B; 2523813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj p = doAMode_M(p, i->Ain.Alu64R.dst, 2524813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj i->Ain.Alu64R.src->Armi.Mem.am); 2525813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj goto done; 2526813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj default: 2527813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj goto bad; 2528813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2529813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj } 2530d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj /* MUL */ 2531d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj if (i->Ain.Alu64R.op == Aalu_MUL) { 2532d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj switch (i->Ain.Alu64R.src->tag) { 25337de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Armi_Reg: 25347de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = rexAMode_R( i->Ain.Alu64R.dst, 25357de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Alu64R.src->Armi.Reg.reg); 25367de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0x0F; 25377de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0xAF; 25387de0d3c800437fbd82c59d57d156f4823d67609fsewardj p = doAMode_R(p, i->Ain.Alu64R.dst, 25397de0d3c800437fbd82c59d57d156f4823d67609fsewardj i->Ain.Alu64R.src->Armi.Reg.reg); 25407de0d3c800437fbd82c59d57d156f4823d67609fsewardj goto done; 2541d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Armi_Mem: 2542d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj *p++ = rexAMode_M(i->Ain.Alu64R.dst, 2543d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj i->Ain.Alu64R.src->Armi.Mem.am); 2544d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj *p++ = 0x0F; 2545d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj *p++ = 0xAF; 2546d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj p = doAMode_M(p, i->Ain.Alu64R.dst, 2547d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj i->Ain.Alu64R.src->Armi.Mem.am); 2548d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj goto done; 25497de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Armi_Imm: 25507de0d3c800437fbd82c59d57d156f4823d67609fsewardj if (fits8bits(i->Ain.Alu64R.src->Armi.Imm.imm32)) { 25517de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = rexAMode_R(i->Ain.Alu64R.dst, i->Ain.Alu64R.dst); 25527de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0x6B; 25537de0d3c800437fbd82c59d57d156f4823d67609fsewardj p = doAMode_R(p, i->Ain.Alu64R.dst, i->Ain.Alu64R.dst); 255403ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(0xFF & i->Ain.Alu64R.src->Armi.Imm.imm32); 25557de0d3c800437fbd82c59d57d156f4823d67609fsewardj } else { 25567de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = rexAMode_R(i->Ain.Alu64R.dst, i->Ain.Alu64R.dst); 25577de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0x69; 25587de0d3c800437fbd82c59d57d156f4823d67609fsewardj p = doAMode_R(p, i->Ain.Alu64R.dst, i->Ain.Alu64R.dst); 25597de0d3c800437fbd82c59d57d156f4823d67609fsewardj p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32); 25607de0d3c800437fbd82c59d57d156f4823d67609fsewardj } 25617de0d3c800437fbd82c59d57d156f4823d67609fsewardj goto done; 2562d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj default: 2563d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj goto bad; 2564d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 2565d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 2566549e06463d433ee6351b72dc9107f22ce4305250sewardj /* ADD/SUB/ADC/SBB/AND/OR/XOR/CMP */ 2567549e06463d433ee6351b72dc9107f22ce4305250sewardj opc = opc_rr = subopc_imm = opc_imma = 0; 2568549e06463d433ee6351b72dc9107f22ce4305250sewardj switch (i->Ain.Alu64R.op) { 2569549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_ADC: opc = 0x13; opc_rr = 0x11; 2570549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 2; opc_imma = 0x15; break; 2571549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_ADD: opc = 0x03; opc_rr = 0x01; 2572549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 0; opc_imma = 0x05; break; 2573549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_SUB: opc = 0x2B; opc_rr = 0x29; 2574549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 5; opc_imma = 0x2D; break; 2575549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_SBB: opc = 0x1B; opc_rr = 0x19; 2576549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 3; opc_imma = 0x1D; break; 2577549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_AND: opc = 0x23; opc_rr = 0x21; 2578549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 4; opc_imma = 0x25; break; 2579549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_XOR: opc = 0x33; opc_rr = 0x31; 2580549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 6; opc_imma = 0x35; break; 2581549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_OR: opc = 0x0B; opc_rr = 0x09; 2582549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 1; opc_imma = 0x0D; break; 2583549e06463d433ee6351b72dc9107f22ce4305250sewardj case Aalu_CMP: opc = 0x3B; opc_rr = 0x39; 2584549e06463d433ee6351b72dc9107f22ce4305250sewardj subopc_imm = 7; opc_imma = 0x3D; break; 2585549e06463d433ee6351b72dc9107f22ce4305250sewardj default: goto bad; 2586549e06463d433ee6351b72dc9107f22ce4305250sewardj } 2587549e06463d433ee6351b72dc9107f22ce4305250sewardj switch (i->Ain.Alu64R.src->tag) { 2588549e06463d433ee6351b72dc9107f22ce4305250sewardj case Armi_Imm: 258979efdc6ea93db174395af845d4e21a4a7ad600ccflorian if (sameHReg(i->Ain.Alu64R.dst, hregAMD64_RAX()) 2590549e06463d433ee6351b72dc9107f22ce4305250sewardj && !fits8bits(i->Ain.Alu64R.src->Armi.Imm.imm32)) { 25911830386e7b10430c0c3630123a82d8bcf0a071e7sewardj goto bad; /* FIXME: awaiting test case */ 259203ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(opc_imma); 2593549e06463d433ee6351b72dc9107f22ce4305250sewardj p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32); 2594549e06463d433ee6351b72dc9107f22ce4305250sewardj } else 2595549e06463d433ee6351b72dc9107f22ce4305250sewardj if (fits8bits(i->Ain.Alu64R.src->Armi.Imm.imm32)) { 2596a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg( 0, i->Ain.Alu64R.dst ); 2597549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0x83; 2598a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc_imm, i->Ain.Alu64R.dst); 259903ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(0xFF & i->Ain.Alu64R.src->Armi.Imm.imm32); 2600549e06463d433ee6351b72dc9107f22ce4305250sewardj } else { 2601a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg( 0, i->Ain.Alu64R.dst); 2602549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0x81; 2603a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc_imm, i->Ain.Alu64R.dst); 2604549e06463d433ee6351b72dc9107f22ce4305250sewardj p = emit32(p, i->Ain.Alu64R.src->Armi.Imm.imm32); 2605549e06463d433ee6351b72dc9107f22ce4305250sewardj } 2606549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 2607549e06463d433ee6351b72dc9107f22ce4305250sewardj case Armi_Reg: 2608549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = rexAMode_R( i->Ain.Alu64R.src->Armi.Reg.reg, 2609549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.Alu64R.dst); 261003ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(opc_rr); 2611549e06463d433ee6351b72dc9107f22ce4305250sewardj p = doAMode_R(p, i->Ain.Alu64R.src->Armi.Reg.reg, 2612549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.Alu64R.dst); 2613549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 2614549e06463d433ee6351b72dc9107f22ce4305250sewardj case Armi_Mem: 261531191074d1de762d8fbed3590ec08f2894ab1d8bsewardj *p++ = rexAMode_M( i->Ain.Alu64R.dst, 261631191074d1de762d8fbed3590ec08f2894ab1d8bsewardj i->Ain.Alu64R.src->Armi.Mem.am); 261703ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(opc); 2618549e06463d433ee6351b72dc9107f22ce4305250sewardj p = doAMode_M(p, i->Ain.Alu64R.dst, 2619549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.Alu64R.src->Armi.Mem.am); 2620549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 2621549e06463d433ee6351b72dc9107f22ce4305250sewardj default: 2622549e06463d433ee6351b72dc9107f22ce4305250sewardj goto bad; 2623549e06463d433ee6351b72dc9107f22ce4305250sewardj } 2624813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj break; 2625813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj 2626549e06463d433ee6351b72dc9107f22ce4305250sewardj case Ain_Alu64M: 2627549e06463d433ee6351b72dc9107f22ce4305250sewardj /* Deal specially with MOV */ 2628549e06463d433ee6351b72dc9107f22ce4305250sewardj if (i->Ain.Alu64M.op == Aalu_MOV) { 2629549e06463d433ee6351b72dc9107f22ce4305250sewardj switch (i->Ain.Alu64M.src->tag) { 2630549e06463d433ee6351b72dc9107f22ce4305250sewardj case Ari_Reg: 2631549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = rexAMode_M(i->Ain.Alu64M.src->Ari.Reg.reg, 2632549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.Alu64M.dst); 2633549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0x89; 2634549e06463d433ee6351b72dc9107f22ce4305250sewardj p = doAMode_M(p, i->Ain.Alu64M.src->Ari.Reg.reg, 2635549e06463d433ee6351b72dc9107f22ce4305250sewardj i->Ain.Alu64M.dst); 2636549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 2637549e06463d433ee6351b72dc9107f22ce4305250sewardj case Ari_Imm: 2638a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_M_enc(0, i->Ain.Alu64M.dst); 2639549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0xC7; 2640a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 0, i->Ain.Alu64M.dst); 2641549e06463d433ee6351b72dc9107f22ce4305250sewardj p = emit32(p, i->Ain.Alu64M.src->Ari.Imm.imm32); 2642549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 2643549e06463d433ee6351b72dc9107f22ce4305250sewardj default: 2644549e06463d433ee6351b72dc9107f22ce4305250sewardj goto bad; 2645549e06463d433ee6351b72dc9107f22ce4305250sewardj } 2646549e06463d433ee6351b72dc9107f22ce4305250sewardj } 2647ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* ADD/SUB/ADC/SBB/AND/OR/XOR/CMP. MUL is not 2648ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes allowed here. (This is derived from the x86 version of same). */ 2649ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes opc = subopc_imm = opc_imma = 0; 2650ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes switch (i->Ain.Alu64M.op) { 2651ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case Aalu_CMP: opc = 0x39; subopc_imm = 7; break; 2652ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes default: goto bad; 2653ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 2654ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes switch (i->Ain.Alu64M.src->tag) { 2655ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes /* 2656ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case Xri_Reg: 2657ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = toUChar(opc); 2658ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes p = doAMode_M(p, i->Xin.Alu32M.src->Xri.Reg.reg, 2659ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes i->Xin.Alu32M.dst); 2660ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes goto done; 2661ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes */ 2662ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes case Ari_Imm: 2663ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (fits8bits(i->Ain.Alu64M.src->Ari.Imm.imm32)) { 2664ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = rexAMode_M_enc(subopc_imm, i->Ain.Alu64M.dst); 2665ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = 0x83; 2666ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes p = doAMode_M_enc(p, subopc_imm, i->Ain.Alu64M.dst); 2667ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = toUChar(0xFF & i->Ain.Alu64M.src->Ari.Imm.imm32); 2668ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes goto done; 2669ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } else { 2670ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = rexAMode_M_enc(subopc_imm, i->Ain.Alu64M.dst); 2671ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes *p++ = 0x81; 2672ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes p = doAMode_M_enc(p, subopc_imm, i->Ain.Alu64M.dst); 2673ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes p = emit32(p, i->Ain.Alu64M.src->Ari.Imm.imm32); 2674ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes goto done; 2675ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 2676ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes default: 2677ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes goto bad; 2678ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes } 2679ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes 2680549e06463d433ee6351b72dc9107f22ce4305250sewardj break; 2681549e06463d433ee6351b72dc9107f22ce4305250sewardj 26821b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ain_Sh64: 26831b8d58eb046ad31fbb058d65855b604886d3d177sewardj opc_cl = opc_imm = subopc = 0; 26841b8d58eb046ad31fbb058d65855b604886d3d177sewardj switch (i->Ain.Sh64.op) { 26851b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ash_SHR: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 5; break; 26861b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ash_SAR: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 7; break; 26871b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ash_SHL: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 4; break; 26881b8d58eb046ad31fbb058d65855b604886d3d177sewardj default: goto bad; 26891b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 26901b8d58eb046ad31fbb058d65855b604886d3d177sewardj if (i->Ain.Sh64.src == 0) { 2691a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Sh64.dst); 269203ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(opc_cl); 2693a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc, i->Ain.Sh64.dst); 2694501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 26951b8d58eb046ad31fbb058d65855b604886d3d177sewardj } else { 2696a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Sh64.dst); 269703ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(opc_imm); 2698a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc, i->Ain.Sh64.dst); 2699501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = (UChar)(i->Ain.Sh64.src); 2700501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 27011b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 27021b8d58eb046ad31fbb058d65855b604886d3d177sewardj break; 27031b8d58eb046ad31fbb058d65855b604886d3d177sewardj 27041b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ain_Test64: 2705501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj /* testq sign-extend($imm32), %reg */ 2706a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Test64.dst); 2707501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = 0xF7; 2708a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, 0, i->Ain.Test64.dst); 2709501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj p = emit32(p, i->Ain.Test64.imm32); 2710501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 27111b8d58eb046ad31fbb058d65855b604886d3d177sewardj 2712d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_Unary64: 2713d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj if (i->Ain.Unary64.op == Aun_NOT) { 2714a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Unary64.dst); 2715501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = 0xF7; 2716a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, 2, i->Ain.Unary64.dst); 2717501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 2718d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj } 2719b522077275a57df04305eec3ec1ef3fab9801197sewardj if (i->Ain.Unary64.op == Aun_NEG) { 2720a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Unary64.dst); 2721501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = 0xF7; 2722a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, 3, i->Ain.Unary64.dst); 2723501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 2724b522077275a57df04305eec3ec1ef3fab9801197sewardj } 2725d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj break; 27269b96767debeeb1f78378f0e7e295fe6762c64002sewardj 27276ce1a23b27d1729da9d705abd15b2007dce8daecsewardj case Ain_Lea64: 27286ce1a23b27d1729da9d705abd15b2007dce8daecsewardj *p++ = rexAMode_M(i->Ain.Lea64.dst, i->Ain.Lea64.am); 27296ce1a23b27d1729da9d705abd15b2007dce8daecsewardj *p++ = 0x8D; 27306ce1a23b27d1729da9d705abd15b2007dce8daecsewardj p = doAMode_M(p, i->Ain.Lea64.dst, i->Ain.Lea64.am); 27316ce1a23b27d1729da9d705abd15b2007dce8daecsewardj goto done; 27326ce1a23b27d1729da9d705abd15b2007dce8daecsewardj 27339cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Ain_Alu32R: 27349cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj /* ADD/SUB/AND/OR/XOR/CMP */ 27359cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj opc = opc_rr = subopc_imm = opc_imma = 0; 27369cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj switch (i->Ain.Alu32R.op) { 27379cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_ADD: opc = 0x03; opc_rr = 0x01; 27389cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 0; opc_imma = 0x05; break; 27399cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_SUB: opc = 0x2B; opc_rr = 0x29; 27409cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 5; opc_imma = 0x2D; break; 27419cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_AND: opc = 0x23; opc_rr = 0x21; 27429cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 4; opc_imma = 0x25; break; 27439cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_XOR: opc = 0x33; opc_rr = 0x31; 27449cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 6; opc_imma = 0x35; break; 27459cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_OR: opc = 0x0B; opc_rr = 0x09; 27469cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 1; opc_imma = 0x0D; break; 27479cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Aalu_CMP: opc = 0x3B; opc_rr = 0x39; 27489cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj subopc_imm = 7; opc_imma = 0x3D; break; 27499cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj default: goto bad; 27509cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } 27519cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj switch (i->Ain.Alu32R.src->tag) { 27529cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Armi_Imm: 275379efdc6ea93db174395af845d4e21a4a7ad600ccflorian if (sameHReg(i->Ain.Alu32R.dst, hregAMD64_RAX()) 27549cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj && !fits8bits(i->Ain.Alu32R.src->Armi.Imm.imm32)) { 27559cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj goto bad; /* FIXME: awaiting test case */ 27569cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = toUChar(opc_imma); 27579cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj p = emit32(p, i->Ain.Alu32R.src->Armi.Imm.imm32); 27589cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } else 27599cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (fits8bits(i->Ain.Alu32R.src->Armi.Imm.imm32)) { 2760a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = clearWBit( rexAMode_R_enc_reg( 0, i->Ain.Alu32R.dst ) ); 27619cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (rex != 0x40) *p++ = rex; 27629cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = 0x83; 2763a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc_imm, i->Ain.Alu32R.dst); 27649cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = toUChar(0xFF & i->Ain.Alu32R.src->Armi.Imm.imm32); 27659cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } else { 2766a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = clearWBit( rexAMode_R_enc_reg( 0, i->Ain.Alu32R.dst) ); 27679cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (rex != 0x40) *p++ = rex; 27689cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = 0x81; 2769a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc_imm, i->Ain.Alu32R.dst); 27709cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj p = emit32(p, i->Ain.Alu32R.src->Armi.Imm.imm32); 27719cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } 27729cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj goto done; 27739cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Armi_Reg: 27749cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj rex = clearWBit( 27759cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj rexAMode_R( i->Ain.Alu32R.src->Armi.Reg.reg, 27769cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.dst) ); 27779cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (rex != 0x40) *p++ = rex; 27789cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = toUChar(opc_rr); 27799cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj p = doAMode_R(p, i->Ain.Alu32R.src->Armi.Reg.reg, 27809cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.dst); 27819cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj goto done; 27829cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj case Armi_Mem: 27839cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj rex = clearWBit( 27849cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj rexAMode_M( i->Ain.Alu32R.dst, 27859cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.src->Armi.Mem.am) ); 27869cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj if (rex != 0x40) *p++ = rex; 27879cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj *p++ = toUChar(opc); 27889cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj p = doAMode_M(p, i->Ain.Alu32R.dst, 27899cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj i->Ain.Alu32R.src->Armi.Mem.am); 27909cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj goto done; 27919cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj default: 27929cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj goto bad; 27939cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj } 27949cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj break; 27959cc2bbf8496403cf998aec6152c086cd66b8bcdfsewardj 27969b96767debeeb1f78378f0e7e295fe6762c64002sewardj case Ain_MulL: 27979b96767debeeb1f78378f0e7e295fe6762c64002sewardj subopc = i->Ain.MulL.syned ? 5 : 4; 2798501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj switch (i->Ain.MulL.src->tag) { 2799501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj case Arm_Mem: 2800a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_M_enc(0, i->Ain.MulL.src->Arm.Mem.am); 2801501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = 0xF7; 2802a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, subopc, i->Ain.MulL.src->Arm.Mem.am); 2803501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 2804501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj case Arm_Reg: 2805a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.MulL.src->Arm.Reg.reg); 2806501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj *p++ = 0xF7; 2807a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc, i->Ain.MulL.src->Arm.Reg.reg); 2808501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto done; 2809501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj default: 2810501a339ba08d28f30eb96d17b3f5bbe996ca6a4dsewardj goto bad; 28119b96767debeeb1f78378f0e7e295fe6762c64002sewardj } 28129b96767debeeb1f78378f0e7e295fe6762c64002sewardj break; 28139b96767debeeb1f78378f0e7e295fe6762c64002sewardj 28147de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Ain_Div: 28157de0d3c800437fbd82c59d57d156f4823d67609fsewardj subopc = i->Ain.Div.syned ? 7 : 6; 28167de0d3c800437fbd82c59d57d156f4823d67609fsewardj if (i->Ain.Div.sz == 4) { 28177de0d3c800437fbd82c59d57d156f4823d67609fsewardj switch (i->Ain.Div.src->tag) { 28187de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Arm_Mem: 2819a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj goto bad; 2820a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj /*FIXME*/ 28217de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0xF7; 2822a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, subopc, i->Ain.Div.src->Arm.Mem.am); 28237de0d3c800437fbd82c59d57d156f4823d67609fsewardj goto done; 28247de0d3c800437fbd82c59d57d156f4823d67609fsewardj case Arm_Reg: 28257de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = clearWBit( 2826a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_reg(0, i->Ain.Div.src->Arm.Reg.reg)); 28277de0d3c800437fbd82c59d57d156f4823d67609fsewardj *p++ = 0xF7; 2828a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc, i->Ain.Div.src->Arm.Reg.reg); 28297de0d3c800437fbd82c59d57d156f4823d67609fsewardj goto done; 28307de0d3c800437fbd82c59d57d156f4823d67609fsewardj default: 28317de0d3c800437fbd82c59d57d156f4823d67609fsewardj goto bad; 28327de0d3c800437fbd82c59d57d156f4823d67609fsewardj } 28337de0d3c800437fbd82c59d57d156f4823d67609fsewardj } 2834a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj if (i->Ain.Div.sz == 8) { 2835a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj switch (i->Ain.Div.src->tag) { 2836a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj case Arm_Mem: 2837a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_M_enc(0, i->Ain.Div.src->Arm.Mem.am); 2838a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj *p++ = 0xF7; 2839a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, subopc, i->Ain.Div.src->Arm.Mem.am); 2840a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj goto done; 2841a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj case Arm_Reg: 2842a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = rexAMode_R_enc_reg(0, i->Ain.Div.src->Arm.Reg.reg); 2843a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj *p++ = 0xF7; 2844a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg(p, subopc, i->Ain.Div.src->Arm.Reg.reg); 2845a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj goto done; 2846a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj default: 2847a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj goto bad; 2848a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj } 2849a6b93d109a1d3b18e1ffaf3c1721216e79aaadc7sewardj } 28507de0d3c800437fbd82c59d57d156f4823d67609fsewardj break; 28517de0d3c800437fbd82c59d57d156f4823d67609fsewardj 28521001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Push: 28531001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj switch (i->Ain.Push.src->tag) { 28541001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Armi_Mem: 28551001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = clearWBit( 2856a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(0, i->Ain.Push.src->Armi.Mem.am)); 28571001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0xFF; 2858a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 6, i->Ain.Push.src->Armi.Mem.am); 28591001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto done; 28601a01e65f9993d97095c2af463e98674a091834casewardj case Armi_Imm: 28611a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x68; 28621a01e65f9993d97095c2af463e98674a091834casewardj p = emit32(p, i->Ain.Push.src->Armi.Imm.imm32); 28631a01e65f9993d97095c2af463e98674a091834casewardj goto done; 28641a01e65f9993d97095c2af463e98674a091834casewardj case Armi_Reg: 2865a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x40 + (1 & iregEnc3(i->Ain.Push.src->Armi.Reg.reg))); 2866a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x50 + iregEnc210(i->Ain.Push.src->Armi.Reg.reg)); 28671a01e65f9993d97095c2af463e98674a091834casewardj goto done; 28681001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj default: 28691001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto bad; 28701001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 28711b8d58eb046ad31fbb058d65855b604886d3d177sewardj 28724d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj case Ain_Call: { 2873bdea5508b371d394c81b91464fa8df767010d4dasewardj /* As per detailed comment for Ain_Call in getRegUsage_AMD64Instr 2874bdea5508b371d394c81b91464fa8df767010d4dasewardj above, %r11 is used as an address temporary. */ 2875bdea5508b371d394c81b91464fa8df767010d4dasewardj /* If we don't need to do any fixup actions in the case that the 2876bdea5508b371d394c81b91464fa8df767010d4dasewardj call doesn't happen, just do the simple thing and emit 2877bdea5508b371d394c81b91464fa8df767010d4dasewardj straight-line code. This is usually the case. */ 2878bdea5508b371d394c81b91464fa8df767010d4dasewardj if (i->Ain.Call.cond == Acc_ALWAYS/*call always happens*/ 2879bdea5508b371d394c81b91464fa8df767010d4dasewardj || i->Ain.Call.rloc.pri == RLPri_None/*no fixup action*/) { 2880bdea5508b371d394c81b91464fa8df767010d4dasewardj /* jump over the following two insns if the condition does 2881bdea5508b371d394c81b91464fa8df767010d4dasewardj not hold */ 2882bdea5508b371d394c81b91464fa8df767010d4dasewardj Bool shortImm = fitsIn32Bits(i->Ain.Call.target); 2883bdea5508b371d394c81b91464fa8df767010d4dasewardj if (i->Ain.Call.cond != Acc_ALWAYS) { 2884bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.Call.cond ^ 1))); 2885bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = shortImm ? 10 : 13; 2886bdea5508b371d394c81b91464fa8df767010d4dasewardj /* 10 or 13 bytes in the next two insns */ 2887bdea5508b371d394c81b91464fa8df767010d4dasewardj } 2888bdea5508b371d394c81b91464fa8df767010d4dasewardj if (shortImm) { 2889bdea5508b371d394c81b91464fa8df767010d4dasewardj /* 7 bytes: movl sign-extend(imm32), %r11 */ 2890bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x49; 2891bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xC7; 2892bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xC3; 2893bdea5508b371d394c81b91464fa8df767010d4dasewardj p = emit32(p, (UInt)i->Ain.Call.target); 2894bdea5508b371d394c81b91464fa8df767010d4dasewardj } else { 2895bdea5508b371d394c81b91464fa8df767010d4dasewardj /* 10 bytes: movabsq $target, %r11 */ 2896bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x49; 2897bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xBB; 2898bdea5508b371d394c81b91464fa8df767010d4dasewardj p = emit64(p, i->Ain.Call.target); 2899bdea5508b371d394c81b91464fa8df767010d4dasewardj } 2900bdea5508b371d394c81b91464fa8df767010d4dasewardj /* 3 bytes: call *%r11 */ 2901bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x41; 2902bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xFF; 2903bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xD3; 29044d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj } else { 2905bdea5508b371d394c81b91464fa8df767010d4dasewardj Int delta; 2906bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Complex case. We have to generate an if-then-else diamond. */ 2907bdea5508b371d394c81b91464fa8df767010d4dasewardj // before: 2908bdea5508b371d394c81b91464fa8df767010d4dasewardj // j{!cond} else: 2909bdea5508b371d394c81b91464fa8df767010d4dasewardj // movabsq $target, %r11 2910bdea5508b371d394c81b91464fa8df767010d4dasewardj // call* %r11 2911bdea5508b371d394c81b91464fa8df767010d4dasewardj // preElse: 2912bdea5508b371d394c81b91464fa8df767010d4dasewardj // jmp after: 2913bdea5508b371d394c81b91464fa8df767010d4dasewardj // else: 2914bdea5508b371d394c81b91464fa8df767010d4dasewardj // movabsq $0x5555555555555555, %rax // possibly 2915bdea5508b371d394c81b91464fa8df767010d4dasewardj // movq %rax, %rdx // possibly 2916bdea5508b371d394c81b91464fa8df767010d4dasewardj // after: 2917bdea5508b371d394c81b91464fa8df767010d4dasewardj 2918bdea5508b371d394c81b91464fa8df767010d4dasewardj // before: 2919bdea5508b371d394c81b91464fa8df767010d4dasewardj UChar* pBefore = p; 2920bdea5508b371d394c81b91464fa8df767010d4dasewardj 2921bdea5508b371d394c81b91464fa8df767010d4dasewardj // j{!cond} else: 2922bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.Call.cond ^ 1))); 2923bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 2924bdea5508b371d394c81b91464fa8df767010d4dasewardj 2925bdea5508b371d394c81b91464fa8df767010d4dasewardj // movabsq $target, %r11 29264d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj *p++ = 0x49; 29274d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj *p++ = 0xBB; 29284d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj p = emit64(p, i->Ain.Call.target); 2929bdea5508b371d394c81b91464fa8df767010d4dasewardj 2930bdea5508b371d394c81b91464fa8df767010d4dasewardj // call* %r11 2931bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x41; 2932bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xFF; 2933bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xD3; 2934bdea5508b371d394c81b91464fa8df767010d4dasewardj 2935bdea5508b371d394c81b91464fa8df767010d4dasewardj // preElse: 2936bdea5508b371d394c81b91464fa8df767010d4dasewardj UChar* pPreElse = p; 2937bdea5508b371d394c81b91464fa8df767010d4dasewardj 2938bdea5508b371d394c81b91464fa8df767010d4dasewardj // jmp after: 2939bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0xEB; 2940bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 2941bdea5508b371d394c81b91464fa8df767010d4dasewardj 2942bdea5508b371d394c81b91464fa8df767010d4dasewardj // else: 2943bdea5508b371d394c81b91464fa8df767010d4dasewardj UChar* pElse = p; 2944bdea5508b371d394c81b91464fa8df767010d4dasewardj 2945bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Do the 'else' actions */ 2946bdea5508b371d394c81b91464fa8df767010d4dasewardj switch (i->Ain.Call.rloc.pri) { 2947bdea5508b371d394c81b91464fa8df767010d4dasewardj case RLPri_Int: 2948bdea5508b371d394c81b91464fa8df767010d4dasewardj // movabsq $0x5555555555555555, %rax 2949bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x48; *p++ = 0xB8; p = emit64(p, 0x5555555555555555ULL); 2950bdea5508b371d394c81b91464fa8df767010d4dasewardj break; 2951bdea5508b371d394c81b91464fa8df767010d4dasewardj case RLPri_2Int: 295270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj goto bad; //ATC 2953bdea5508b371d394c81b91464fa8df767010d4dasewardj // movabsq $0x5555555555555555, %rax 2954bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x48; *p++ = 0xB8; p = emit64(p, 0x5555555555555555ULL); 2955bdea5508b371d394c81b91464fa8df767010d4dasewardj // movq %rax, %rdx 2956bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x48; *p++ = 0x89; *p++ = 0xC2; 295770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 295870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case RLPri_V128SpRel: 295970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj if (i->Ain.Call.rloc.spOff == 0) { 296070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // We could accept any |spOff| here, but that's more 296170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // hassle and the only value we're ever going to get 296270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // is zero (I believe.) Hence take the easy path :) 296370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // We need a scag register -- r11 can be it. 296470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // movabsq $0x5555555555555555, %r11 296570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x49; *p++ = 0xBB; 296670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj p = emit64(p, 0x5555555555555555ULL); 296770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // movq %r11, 0(%rsp) 296870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x4C; *p++ = 0x89; *p++ = 0x1C; *p++ = 0x24; 296970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj // movq %r11, 8(%rsp) 297070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x4C; *p++ = 0x89; *p++ = 0x5C; *p++ = 0x24; 297170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x08; 297270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj break; 297370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 297470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj goto bad; //ATC for all other spOff values 297570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case RLPri_V256SpRel: 297670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj goto bad; //ATC 2977bdea5508b371d394c81b91464fa8df767010d4dasewardj case RLPri_None: case RLPri_INVALID: default: 297870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(0); // should never get here 2979bdea5508b371d394c81b91464fa8df767010d4dasewardj } 2980bdea5508b371d394c81b91464fa8df767010d4dasewardj 2981bdea5508b371d394c81b91464fa8df767010d4dasewardj // after: 2982bdea5508b371d394c81b91464fa8df767010d4dasewardj UChar* pAfter = p; 2983bdea5508b371d394c81b91464fa8df767010d4dasewardj 2984bdea5508b371d394c81b91464fa8df767010d4dasewardj // Fix up the branch offsets. The +2s in the offset 2985bdea5508b371d394c81b91464fa8df767010d4dasewardj // calculations are there because x86 requires conditional 2986bdea5508b371d394c81b91464fa8df767010d4dasewardj // branches to have their offset stated relative to the 2987bdea5508b371d394c81b91464fa8df767010d4dasewardj // instruction immediately following the branch insn. And in 2988bdea5508b371d394c81b91464fa8df767010d4dasewardj // both cases the branch insns are 2 bytes long. 2989bdea5508b371d394c81b91464fa8df767010d4dasewardj 2990bdea5508b371d394c81b91464fa8df767010d4dasewardj // First, the "j{!cond} else:" at pBefore. 2991bdea5508b371d394c81b91464fa8df767010d4dasewardj delta = (Int)(Long)(pElse - (pBefore + 2)); 2992bdea5508b371d394c81b91464fa8df767010d4dasewardj vassert(delta >= 0 && delta < 100/*arbitrary*/); 2993bdea5508b371d394c81b91464fa8df767010d4dasewardj *(pBefore+1) = (UChar)delta; 2994bdea5508b371d394c81b91464fa8df767010d4dasewardj 2995bdea5508b371d394c81b91464fa8df767010d4dasewardj // And secondly, the "jmp after:" at pPreElse. 2996bdea5508b371d394c81b91464fa8df767010d4dasewardj delta = (Int)(Long)(pAfter - (pPreElse + 2)); 2997bdea5508b371d394c81b91464fa8df767010d4dasewardj vassert(delta >= 0 && delta < 100/*arbitrary*/); 2998bdea5508b371d394c81b91464fa8df767010d4dasewardj *(pPreElse+1) = (UChar)delta; 29991b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 30001b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 30014d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj } 3002549e06463d433ee6351b72dc9107f22ce4305250sewardj 3003c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XDirect: { 3004c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* NB: what goes on here has to be very closely coordinated with the 3005c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj chainXDirect_AMD64 and unchainXDirect_AMD64 below. */ 3006c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We're generating chain-me requests here, so we need to be 3007c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj sure this is actually allowed -- no-redir translations can't 3008c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj use chain-me's. Hence: */ 3009c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(disp_cp_chain_me_to_slowEP != NULL); 3010c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(disp_cp_chain_me_to_fastEP != NULL); 3011c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3012c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj HReg r11 = hregAMD64_R11(); 3013010ac5400c3294a8c0991fac7b382578e5b91b1csewardj 3014549e06463d433ee6351b72dc9107f22ce4305250sewardj /* Use ptmp for backpatching conditional jumps. */ 3015549e06463d433ee6351b72dc9107f22ce4305250sewardj ptmp = NULL; 3016549e06463d433ee6351b72dc9107f22ce4305250sewardj 3017549e06463d433ee6351b72dc9107f22ce4305250sewardj /* First off, if this is conditional, create a conditional 3018549e06463d433ee6351b72dc9107f22ce4305250sewardj jump over the rest of it. */ 3019c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XDirect.cond != Acc_ALWAYS) { 3020549e06463d433ee6351b72dc9107f22ce4305250sewardj /* jmp fwds if !condition */ 3021c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.XDirect.cond ^ 1))); 3022549e06463d433ee6351b72dc9107f22ce4305250sewardj ptmp = p; /* fill in this bit later */ 3023549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 3024549e06463d433ee6351b72dc9107f22ce4305250sewardj } 3025549e06463d433ee6351b72dc9107f22ce4305250sewardj 3026c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Update the guest RIP. */ 30273e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj if (fitsIn32Bits(i->Ain.XDirect.dstGA)) { 30283e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* use a shorter encoding */ 30293e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* movl sign-extend(dstGA), %r11 */ 30303e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0x49; 30313e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xC7; 30323e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xC3; 30333e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj p = emit32(p, (UInt)i->Ain.XDirect.dstGA); 30343e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj } else { 30353e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* movabsq $dstGA, %r11 */ 30363e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0x49; 30373e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xBB; 30383e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj p = emit64(p, i->Ain.XDirect.dstGA); 30393e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj } 30403e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj 3041c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movq %r11, amRIP */ 3042c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = rexAMode_M(r11, i->Ain.XDirect.amRIP); 3043c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x89; 3044c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p = doAMode_M(p, r11, i->Ain.XDirect.amRIP); 3045c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3046c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* --- FIRST PATCHABLE BYTE follows --- */ 3047c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're calling 3048c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj to) backs up the return address, so as to find the address of 3049c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj the first patchable byte. So: don't change the length of the 3050c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj two instructions below. */ 3051c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movabsq $disp_cp_chain_me_to_{slow,fast}EP,%r11; */ 3052c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x49; 3053c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xBB; 30548462d113e3efeacceb304222dada8d85f748295aflorian const void* disp_cp_chain_me 3055c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj = i->Ain.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP 3056c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj : disp_cp_chain_me_to_slowEP; 305793a09742b0de3d61718882c2d999f64be402564dflorian p = emit64(p, (Addr)disp_cp_chain_me); 3058c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* call *%r11 */ 3059c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x41; 3060c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xFF; 3061c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xD3; 3062c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* --- END of PATCHABLE BYTES --- */ 3063c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3064c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Fix up the conditional jump, if there was one. */ 3065c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XDirect.cond != Acc_ALWAYS) { 3066c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Int delta = p - ptmp; 3067c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(delta > 0 && delta < 40); 3068c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *ptmp = toUChar(delta-1); 3069549e06463d433ee6351b72dc9107f22ce4305250sewardj } 3070c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj goto done; 3071c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3072549e06463d433ee6351b72dc9107f22ce4305250sewardj 3073c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XIndir: { 3074c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We're generating transfers that could lead indirectly to a 3075c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj chain-me, so we need to be sure this is actually allowed -- 3076c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj no-redir translations are not allowed to reach normal 3077c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj translations without going through the scheduler. That means 3078c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj no XDirects or XIndirs out from no-redir translations. 3079c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Hence: */ 3080c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(disp_cp_xindir != NULL); 3081c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3082c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Use ptmp for backpatching conditional jumps. */ 3083c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ptmp = NULL; 3084c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3085c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* First off, if this is conditional, create a conditional 3086c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jump over the rest of it. */ 3087c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XIndir.cond != Acc_ALWAYS) { 3088c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* jmp fwds if !condition */ 3089c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.XIndir.cond ^ 1))); 3090c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ptmp = p; /* fill in this bit later */ 3091c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 3092549e06463d433ee6351b72dc9107f22ce4305250sewardj } 3093549e06463d433ee6351b72dc9107f22ce4305250sewardj 3094c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movq dstGA(a reg), amRIP -- copied from Alu64M MOV case */ 3095c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = rexAMode_M(i->Ain.XIndir.dstGA, i->Ain.XIndir.amRIP); 3096c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x89; 3097c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p = doAMode_M(p, i->Ain.XIndir.dstGA, i->Ain.XIndir.amRIP); 30983e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj 30993e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* get $disp_cp_xindir into %r11 */ 310093a09742b0de3d61718882c2d999f64be402564dflorian if (fitsIn32Bits((Addr)disp_cp_xindir)) { 31013e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* use a shorter encoding */ 31023e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* movl sign-extend(disp_cp_xindir), %r11 */ 31033e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0x49; 31043e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xC7; 31053e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xC3; 310693a09742b0de3d61718882c2d999f64be402564dflorian p = emit32(p, (UInt)(Addr)disp_cp_xindir); 31073e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj } else { 31083e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj /* movabsq $disp_cp_xindir, %r11 */ 31093e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0x49; 31103e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj *p++ = 0xBB; 311193a09742b0de3d61718882c2d999f64be402564dflorian p = emit64(p, (Addr)disp_cp_xindir); 31123e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj } 31133e8ba60decf63c6c349ccfe509733c81aee8c6b8sewardj 3114c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* jmp *%r11 */ 3115c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x41; 3116c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xFF; 3117c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xE3; 31180528bb5bd879eed0e8fa7e2bc9bc8debea00bf5fsewardj 3119c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Fix up the conditional jump, if there was one. */ 3120c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XIndir.cond != Acc_ALWAYS) { 3121c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Int delta = p - ptmp; 3122c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(delta > 0 && delta < 40); 3123c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *ptmp = toUChar(delta-1); 3124c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3125c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj goto done; 3126c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3127c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3128c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_XAssisted: { 3129c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Use ptmp for backpatching conditional jumps. */ 3130c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ptmp = NULL; 3131c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3132c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* First off, if this is conditional, create a conditional 3133c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jump over the rest of it. */ 3134c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XAssisted.cond != Acc_ALWAYS) { 3135c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* jmp fwds if !condition */ 3136c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.XAssisted.cond ^ 1))); 3137c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ptmp = p; /* fill in this bit later */ 3138c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 31394d77a9c73b332df0f5c7c36c2d8d72c7f22b735dsewardj } 3140c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3141c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movq dstGA(a reg), amRIP -- copied from Alu64M MOV case */ 3142c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = rexAMode_M(i->Ain.XAssisted.dstGA, i->Ain.XAssisted.amRIP); 3143c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x89; 3144c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p = doAMode_M(p, i->Ain.XAssisted.dstGA, i->Ain.XAssisted.amRIP); 3145c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movl $magic_number, %ebp. Since these numbers are all small positive 3146c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj integers, we can get away with "movl $N, %ebp" rather than 3147c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj the longer "movq $N, %rbp". */ 3148c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj UInt trcval = 0; 3149c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj switch (i->Ain.XAssisted.jk) { 3150c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_ClientReq: trcval = VEX_TRC_JMP_CLIENTREQ; break; 3151c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break; 3152c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Sys_int32: trcval = VEX_TRC_JMP_SYS_INT32; break; 31533e5d82d003f0746010e22c7cfc4a25b34c9641f1sewardj case Ijk_Sys_int210: trcval = VEX_TRC_JMP_SYS_INT210; break; 3154c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Yield: trcval = VEX_TRC_JMP_YIELD; break; 3155c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_EmWarn: trcval = VEX_TRC_JMP_EMWARN; break; 3156c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_MapFail: trcval = VEX_TRC_JMP_MAPFAIL; break; 3157c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_NoDecode: trcval = VEX_TRC_JMP_NODECODE; break; 315805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break; 3159c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break; 3160c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break; 3161c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break; 3162c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Boring: trcval = VEX_TRC_JMP_BORING; break; 3163c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We don't expect to see the following being assisted. */ 3164c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Ret: 3165c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ijk_Call: 3166c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* fallthrough */ 3167c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj default: 3168c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ppIRJumpKind(i->Ain.XAssisted.jk); 3169c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vpanic("emit_AMD64Instr.Ain_XAssisted: unexpected jump kind"); 3170c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3171c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(trcval != 0); 3172c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xBD; 3173c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p = emit32(p, trcval); 3174c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* movabsq $disp_assisted, %r11 */ 3175c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x49; 3176c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xBB; 317793a09742b0de3d61718882c2d999f64be402564dflorian p = emit64(p, (Addr)disp_cp_xassisted); 3178c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* jmp *%r11 */ 3179c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x41; 31800528bb5bd879eed0e8fa7e2bc9bc8debea00bf5fsewardj *p++ = 0xFF; 3181c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xE3; 3182549e06463d433ee6351b72dc9107f22ce4305250sewardj 3183549e06463d433ee6351b72dc9107f22ce4305250sewardj /* Fix up the conditional jump, if there was one. */ 3184c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (i->Ain.XAssisted.cond != Acc_ALWAYS) { 3185549e06463d433ee6351b72dc9107f22ce4305250sewardj Int delta = p - ptmp; 3186c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(delta > 0 && delta < 40); 318703ccf858efa285d793061359c04fdd0055cd9d31sewardj *ptmp = toUChar(delta-1); 3188549e06463d433ee6351b72dc9107f22ce4305250sewardj } 3189549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 3190010ac5400c3294a8c0991fac7b382578e5b91b1csewardj } 3191549e06463d433ee6351b72dc9107f22ce4305250sewardj 31921b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ain_CMov64: 31931b8d58eb046ad31fbb058d65855b604886d3d177sewardj vassert(i->Ain.CMov64.cond != Acc_ALWAYS); 3194e357c67787b7429f85a030ee5fbedf33173b5656sewardj *p++ = rexAMode_R(i->Ain.CMov64.dst, i->Ain.CMov64.src); 3195e357c67787b7429f85a030ee5fbedf33173b5656sewardj *p++ = 0x0F; 3196e357c67787b7429f85a030ee5fbedf33173b5656sewardj *p++ = toUChar(0x40 + (0xF & i->Ain.CMov64.cond)); 3197e357c67787b7429f85a030ee5fbedf33173b5656sewardj p = doAMode_R(p, i->Ain.CMov64.dst, i->Ain.CMov64.src); 3198e357c67787b7429f85a030ee5fbedf33173b5656sewardj goto done; 3199549e06463d433ee6351b72dc9107f22ce4305250sewardj 3200bdea5508b371d394c81b91464fa8df767010d4dasewardj case Ain_CLoad: { 3201bdea5508b371d394c81b91464fa8df767010d4dasewardj vassert(i->Ain.CLoad.cond != Acc_ALWAYS); 3202bdea5508b371d394c81b91464fa8df767010d4dasewardj 3203bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Only 32- or 64-bit variants are allowed. */ 3204bdea5508b371d394c81b91464fa8df767010d4dasewardj vassert(i->Ain.CLoad.szB == 4 || i->Ain.CLoad.szB == 8); 3205bdea5508b371d394c81b91464fa8df767010d4dasewardj 3206bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Use ptmp for backpatching conditional jumps. */ 3207bdea5508b371d394c81b91464fa8df767010d4dasewardj ptmp = NULL; 3208bdea5508b371d394c81b91464fa8df767010d4dasewardj 3209bdea5508b371d394c81b91464fa8df767010d4dasewardj /* jmp fwds if !condition */ 3210bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.CLoad.cond ^ 1))); 3211bdea5508b371d394c81b91464fa8df767010d4dasewardj ptmp = p; /* fill in this bit later */ 3212bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 3213bdea5508b371d394c81b91464fa8df767010d4dasewardj 3214bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Now the load. Either a normal 64 bit load or a normal 32 bit 3215bdea5508b371d394c81b91464fa8df767010d4dasewardj load, which, by the default zero-extension rule, zeroes out 3216bdea5508b371d394c81b91464fa8df767010d4dasewardj the upper half of the destination, as required. */ 3217bdea5508b371d394c81b91464fa8df767010d4dasewardj rex = rexAMode_M(i->Ain.CLoad.dst, i->Ain.CLoad.addr); 3218bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = i->Ain.CLoad.szB == 4 ? clearWBit(rex) : rex; 3219bdea5508b371d394c81b91464fa8df767010d4dasewardj *p++ = 0x8B; 3220bdea5508b371d394c81b91464fa8df767010d4dasewardj p = doAMode_M(p, i->Ain.CLoad.dst, i->Ain.CLoad.addr); 3221bdea5508b371d394c81b91464fa8df767010d4dasewardj 3222bdea5508b371d394c81b91464fa8df767010d4dasewardj /* Fix up the conditional branch */ 3223bdea5508b371d394c81b91464fa8df767010d4dasewardj Int delta = p - ptmp; 3224bdea5508b371d394c81b91464fa8df767010d4dasewardj vassert(delta > 0 && delta < 40); 3225bdea5508b371d394c81b91464fa8df767010d4dasewardj *ptmp = toUChar(delta-1); 3226bdea5508b371d394c81b91464fa8df767010d4dasewardj goto done; 3227bdea5508b371d394c81b91464fa8df767010d4dasewardj } 3228bdea5508b371d394c81b91464fa8df767010d4dasewardj 32296f1ec58d9806064dea0000e4b543aacded9b11easewardj case Ain_CStore: { 323070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* AFAICS this is identical to Ain_CLoad except that the opcode 32316f1ec58d9806064dea0000e4b543aacded9b11easewardj is 0x89 instead of 0x8B. */ 32326f1ec58d9806064dea0000e4b543aacded9b11easewardj vassert(i->Ain.CStore.cond != Acc_ALWAYS); 32336f1ec58d9806064dea0000e4b543aacded9b11easewardj 32346f1ec58d9806064dea0000e4b543aacded9b11easewardj /* Only 32- or 64-bit variants are allowed. */ 32356f1ec58d9806064dea0000e4b543aacded9b11easewardj vassert(i->Ain.CStore.szB == 4 || i->Ain.CStore.szB == 8); 32366f1ec58d9806064dea0000e4b543aacded9b11easewardj 32376f1ec58d9806064dea0000e4b543aacded9b11easewardj /* Use ptmp for backpatching conditional jumps. */ 32386f1ec58d9806064dea0000e4b543aacded9b11easewardj ptmp = NULL; 32396f1ec58d9806064dea0000e4b543aacded9b11easewardj 32406f1ec58d9806064dea0000e4b543aacded9b11easewardj /* jmp fwds if !condition */ 32416f1ec58d9806064dea0000e4b543aacded9b11easewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.CStore.cond ^ 1))); 32426f1ec58d9806064dea0000e4b543aacded9b11easewardj ptmp = p; /* fill in this bit later */ 32436f1ec58d9806064dea0000e4b543aacded9b11easewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 32446f1ec58d9806064dea0000e4b543aacded9b11easewardj 32456f1ec58d9806064dea0000e4b543aacded9b11easewardj /* Now the store. */ 32466f1ec58d9806064dea0000e4b543aacded9b11easewardj rex = rexAMode_M(i->Ain.CStore.src, i->Ain.CStore.addr); 32476f1ec58d9806064dea0000e4b543aacded9b11easewardj *p++ = i->Ain.CStore.szB == 4 ? clearWBit(rex) : rex; 32486f1ec58d9806064dea0000e4b543aacded9b11easewardj *p++ = 0x89; 32496f1ec58d9806064dea0000e4b543aacded9b11easewardj p = doAMode_M(p, i->Ain.CStore.src, i->Ain.CStore.addr); 32506f1ec58d9806064dea0000e4b543aacded9b11easewardj 32516f1ec58d9806064dea0000e4b543aacded9b11easewardj /* Fix up the conditional branch */ 32526f1ec58d9806064dea0000e4b543aacded9b11easewardj Int delta = p - ptmp; 32536f1ec58d9806064dea0000e4b543aacded9b11easewardj vassert(delta > 0 && delta < 40); 32546f1ec58d9806064dea0000e4b543aacded9b11easewardj *ptmp = toUChar(delta-1); 32556f1ec58d9806064dea0000e4b543aacded9b11easewardj goto done; 32566f1ec58d9806064dea0000e4b543aacded9b11easewardj } 32576f1ec58d9806064dea0000e4b543aacded9b11easewardj 3258ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj case Ain_MovxLQ: 3259ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* No, _don't_ ask me why the sense of the args has to be 3260ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj different in the S vs Z case. I don't know. */ 3261ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj if (i->Ain.MovxLQ.syned) { 3262ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* Need REX.W = 1 here, but rexAMode_R does that for us. */ 3263ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj *p++ = rexAMode_R(i->Ain.MovxLQ.dst, i->Ain.MovxLQ.src); 3264ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj *p++ = 0x63; 3265ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj p = doAMode_R(p, i->Ain.MovxLQ.dst, i->Ain.MovxLQ.src); 3266ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj } else { 3267ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* Produce a 32-bit reg-reg move, since the implicit 3268ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj zero-extend does what we want. */ 3269ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj *p++ = clearWBit ( 3270ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj rexAMode_R(i->Ain.MovxLQ.src, i->Ain.MovxLQ.dst)); 3271ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj *p++ = 0x89; 3272ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj p = doAMode_R(p, i->Ain.MovxLQ.src, i->Ain.MovxLQ.dst); 3273ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj } 3274549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 3275549e06463d433ee6351b72dc9107f22ce4305250sewardj 3276549e06463d433ee6351b72dc9107f22ce4305250sewardj case Ain_LoadEX: 32771b8d58eb046ad31fbb058d65855b604886d3d177sewardj if (i->Ain.LoadEX.szSmall == 1 && !i->Ain.LoadEX.syned) { 32781b8d58eb046ad31fbb058d65855b604886d3d177sewardj /* movzbq */ 32791b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = rexAMode_M(i->Ain.LoadEX.dst, i->Ain.LoadEX.src); 32801b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0x0F; 32811b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0xB6; 32821b8d58eb046ad31fbb058d65855b604886d3d177sewardj p = doAMode_M(p, i->Ain.LoadEX.dst, i->Ain.LoadEX.src); 32831b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 32841b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 32851b8d58eb046ad31fbb058d65855b604886d3d177sewardj if (i->Ain.LoadEX.szSmall == 2 && !i->Ain.LoadEX.syned) { 32861b8d58eb046ad31fbb058d65855b604886d3d177sewardj /* movzwq */ 32871b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = rexAMode_M(i->Ain.LoadEX.dst, i->Ain.LoadEX.src); 32881b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0x0F; 32891b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0xB7; 32901b8d58eb046ad31fbb058d65855b604886d3d177sewardj p = doAMode_M(p, i->Ain.LoadEX.dst, i->Ain.LoadEX.src); 32911b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 32921b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 3293549e06463d433ee6351b72dc9107f22ce4305250sewardj if (i->Ain.LoadEX.szSmall == 4 && !i->Ain.LoadEX.syned) { 3294549e06463d433ee6351b72dc9107f22ce4305250sewardj /* movzlq */ 32951b8d58eb046ad31fbb058d65855b604886d3d177sewardj /* This isn't really an existing AMD64 instruction per se. 3296549e06463d433ee6351b72dc9107f22ce4305250sewardj Rather, we have to do a 32-bit load. Because a 32-bit 3297549e06463d433ee6351b72dc9107f22ce4305250sewardj write implicitly clears the upper 32 bits of the target 3298549e06463d433ee6351b72dc9107f22ce4305250sewardj register, we get what we want. */ 3299549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = clearWBit( 3300549e06463d433ee6351b72dc9107f22ce4305250sewardj rexAMode_M(i->Ain.LoadEX.dst, i->Ain.LoadEX.src)); 3301549e06463d433ee6351b72dc9107f22ce4305250sewardj *p++ = 0x8B; 3302549e06463d433ee6351b72dc9107f22ce4305250sewardj p = doAMode_M(p, i->Ain.LoadEX.dst, i->Ain.LoadEX.src); 3303549e06463d433ee6351b72dc9107f22ce4305250sewardj goto done; 3304549e06463d433ee6351b72dc9107f22ce4305250sewardj } 3305549e06463d433ee6351b72dc9107f22ce4305250sewardj break; 3306549e06463d433ee6351b72dc9107f22ce4305250sewardj 3307a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj case Ain_Set64: 3308a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj /* Make the destination register be 1 or 0, depending on whether 3309a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj the relevant condition holds. Complication: the top 56 bits 3310a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj of the destination should be forced to zero, but doing 'xorq 3311a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj %r,%r' kills the flag(s) we are about to read. Sigh. So 3312a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj start off my moving $0 into the dest. */ 3313a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj reg = iregEnc3210(i->Ain.Set64.dst); 3314a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj vassert(reg < 16); 3315a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj 3316a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj /* movq $0, %dst */ 3317a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = toUChar(reg >= 8 ? 0x49 : 0x48); 3318a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = 0xC7; 3319a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = toUChar(0xC0 + (reg & 7)); 3320a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj p = emit32(p, 0); 3321a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj 3322a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj /* setb lo8(%dst) */ 3323a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj /* note, 8-bit register rex trickyness. Be careful here. */ 3324a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = toUChar(reg >= 8 ? 0x41 : 0x40); 3325a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = 0x0F; 3326a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = toUChar(0x90 + (0x0F & i->Ain.Set64.cond)); 3327a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj *p++ = toUChar(0xC0 + (reg & 7)); 3328a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj goto done; 3329a5bd0aff6eda3e7c312f51ae6bc742ea62b5d404sewardj 3330f53b7359a342e7d79090615169c6583a1a75fbcesewardj case Ain_Bsfr64: 3331f53b7359a342e7d79090615169c6583a1a75fbcesewardj *p++ = rexAMode_R(i->Ain.Bsfr64.dst, i->Ain.Bsfr64.src); 3332f53b7359a342e7d79090615169c6583a1a75fbcesewardj *p++ = 0x0F; 3333f53b7359a342e7d79090615169c6583a1a75fbcesewardj if (i->Ain.Bsfr64.isFwds) { 3334f53b7359a342e7d79090615169c6583a1a75fbcesewardj *p++ = 0xBC; 3335f53b7359a342e7d79090615169c6583a1a75fbcesewardj } else { 3336f53b7359a342e7d79090615169c6583a1a75fbcesewardj *p++ = 0xBD; 3337f53b7359a342e7d79090615169c6583a1a75fbcesewardj } 3338f53b7359a342e7d79090615169c6583a1a75fbcesewardj p = doAMode_R(p, i->Ain.Bsfr64.dst, i->Ain.Bsfr64.src); 3339f53b7359a342e7d79090615169c6583a1a75fbcesewardj goto done; 3340d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj 3341d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj case Ain_MFence: 3342d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj /* mfence */ 3343d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj *p++ = 0x0F; *p++ = 0xAE; *p++ = 0xF0; 3344d0a12df66280288ed336f61b4b9a0c769b2ecef8sewardj goto done; 33451b8d58eb046ad31fbb058d65855b604886d3d177sewardj 3346e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_ACAS: 3347e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* lock */ 3348e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = 0xF0; 3349e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (i->Ain.ACAS.sz == 2) *p++ = 0x66; 3350e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* cmpxchg{b,w,l,q} %rbx,mem. Expected-value in %rax, new value 3351e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj in %rbx. The new-value register is hardwired to be %rbx 3352e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj since dealing with byte integer registers is too much hassle, 3353e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj so we force the register operand to %rbx (could equally be 3354e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj %rcx or %rdx). */ 3355e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj rex = rexAMode_M( hregAMD64_RBX(), i->Ain.ACAS.addr ); 3356e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (i->Ain.ACAS.sz != 8) 3357e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj rex = clearWBit(rex); 3358e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 3359e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = rex; /* this can emit 0x40, which is pointless. oh well. */ 3360e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = 0x0F; 3361e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (i->Ain.ACAS.sz == 1) *p++ = 0xB0; else *p++ = 0xB1; 3362e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj p = doAMode_M(p, hregAMD64_RBX(), i->Ain.ACAS.addr); 3363e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj goto done; 3364e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 3365e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ain_DACAS: 3366e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* lock */ 3367e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = 0xF0; 3368e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* cmpxchg{8,16}b m{64,128}. Expected-value in %rdx:%rax, new 3369e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj value in %rcx:%rbx. All 4 regs are hardwired in the ISA, so 3370e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aren't encoded in the insn. */ 3371a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = rexAMode_M_enc(1, i->Ain.ACAS.addr ); 3372e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (i->Ain.ACAS.sz != 8) 3373e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj rex = clearWBit(rex); 3374e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = rex; 3375e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = 0x0F; 3376e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj *p++ = 0xC7; 3377a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 1, i->Ain.DACAS.addr); 3378e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj goto done; 3379e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 338025a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87Free: 338125a858136df4cbea0055c20aa7035d25fd40ee89sewardj vassert(i->Ain.A87Free.nregs > 0 && i->Ain.A87Free.nregs <= 7); 338225a858136df4cbea0055c20aa7035d25fd40ee89sewardj for (j = 0; j < i->Ain.A87Free.nregs; j++) { 338325a858136df4cbea0055c20aa7035d25fd40ee89sewardj p = do_ffree_st(p, 7-j); 338425a858136df4cbea0055c20aa7035d25fd40ee89sewardj } 338525a858136df4cbea0055c20aa7035d25fd40ee89sewardj goto done; 338625a858136df4cbea0055c20aa7035d25fd40ee89sewardj 338725a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87PushPop: 3388d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj vassert(i->Ain.A87PushPop.szB == 8 || i->Ain.A87PushPop.szB == 4); 338925a858136df4cbea0055c20aa7035d25fd40ee89sewardj if (i->Ain.A87PushPop.isPush) { 3390d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj /* Load from memory into %st(0): flds/fldl amode */ 339125a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = clearWBit( 3392a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(0, i->Ain.A87PushPop.addr) ); 3393d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj *p++ = i->Ain.A87PushPop.szB == 4 ? 0xD9 : 0xDD; 3394a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 0/*subopcode*/, i->Ain.A87PushPop.addr); 339525a858136df4cbea0055c20aa7035d25fd40ee89sewardj } else { 3396d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj /* Dump %st(0) to memory: fstps/fstpl amode */ 339725a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = clearWBit( 3398a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(3, i->Ain.A87PushPop.addr) ); 3399d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj *p++ = i->Ain.A87PushPop.szB == 4 ? 0xD9 : 0xDD; 3400a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 3/*subopcode*/, i->Ain.A87PushPop.addr); 340125a858136df4cbea0055c20aa7035d25fd40ee89sewardj goto done; 340225a858136df4cbea0055c20aa7035d25fd40ee89sewardj } 340325a858136df4cbea0055c20aa7035d25fd40ee89sewardj goto done; 340425a858136df4cbea0055c20aa7035d25fd40ee89sewardj 340525a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87FpOp: 340625a858136df4cbea0055c20aa7035d25fd40ee89sewardj switch (i->Ain.A87FpOp.op) { 34075e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_SQRT: *p++ = 0xD9; *p++ = 0xFA; break; 34085e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_SIN: *p++ = 0xD9; *p++ = 0xFE; break; 34095e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_COS: *p++ = 0xD9; *p++ = 0xFF; break; 34105e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_ROUND: *p++ = 0xD9; *p++ = 0xFC; break; 34115e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_2XM1: *p++ = 0xD9; *p++ = 0xF0; break; 34125e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_SCALE: *p++ = 0xD9; *p++ = 0xFD; break; 34135e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_ATAN: *p++ = 0xD9; *p++ = 0xF3; break; 34145e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_YL2X: *p++ = 0xD9; *p++ = 0xF1; break; 34155e205372f0023f11eb756ee38de40a065b0681c1sewardj case Afp_YL2XP1: *p++ = 0xD9; *p++ = 0xF9; break; 3416f4c803b0947e7534809589cba8007851d78c7a2esewardj case Afp_PREM: *p++ = 0xD9; *p++ = 0xF8; break; 34174970e4e219cb92ef15de742d102c537ea33d5430sewardj case Afp_PREM1: *p++ = 0xD9; *p++ = 0xF5; break; 3418e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj case Afp_TAN: 3419e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj /* fptan pushes 1.0 on the FP stack, except when the 3420e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj argument is out of range. Hence we have to do the 3421e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj instruction, then inspect C2 to see if there is an out 3422e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj of range condition. If there is, we skip the fincstp 3423e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj that is used by the in-range case to get rid of this 3424e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj extra 1.0 value. */ 3425e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0xD9; *p++ = 0xF2; // fptan 3426e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0x50; // pushq %rax 3427e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0xDF; *p++ = 0xE0; // fnstsw %ax 3428e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0x66; *p++ = 0xA9; 3429e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0x00; *p++ = 0x04; // testw $0x400,%ax 3430e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0x75; *p++ = 0x02; // jnz after_fincstp 3431e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0xD9; *p++ = 0xF7; // fincstp 3432e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj *p++ = 0x58; // after_fincstp: popq %rax 3433e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj break; 3434e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj default: 3435e9c51c9287ce703a0740e610d5bdd2ea8429fb6dsewardj goto bad; 343625a858136df4cbea0055c20aa7035d25fd40ee89sewardj } 343725a858136df4cbea0055c20aa7035d25fd40ee89sewardj goto done; 343825a858136df4cbea0055c20aa7035d25fd40ee89sewardj 343925a858136df4cbea0055c20aa7035d25fd40ee89sewardj case Ain_A87LdCW: 344025a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = clearWBit( 3441a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(5, i->Ain.A87LdCW.addr) ); 344225a858136df4cbea0055c20aa7035d25fd40ee89sewardj *p++ = 0xD9; 3443a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 5/*subopcode*/, i->Ain.A87LdCW.addr); 344425a858136df4cbea0055c20aa7035d25fd40ee89sewardj goto done; 344525a858136df4cbea0055c20aa7035d25fd40ee89sewardj 3446f4c803b0947e7534809589cba8007851d78c7a2esewardj case Ain_A87StSW: 3447f4c803b0947e7534809589cba8007851d78c7a2esewardj *p++ = clearWBit( 3448a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(7, i->Ain.A87StSW.addr) ); 3449f4c803b0947e7534809589cba8007851d78c7a2esewardj *p++ = 0xDD; 3450a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 7/*subopcode*/, i->Ain.A87StSW.addr); 3451f4c803b0947e7534809589cba8007851d78c7a2esewardj goto done; 3452f4c803b0947e7534809589cba8007851d78c7a2esewardj 34531b8d58eb046ad31fbb058d65855b604886d3d177sewardj case Ain_Store: 34541b8d58eb046ad31fbb058d65855b604886d3d177sewardj if (i->Ain.Store.sz == 2) { 34551b8d58eb046ad31fbb058d65855b604886d3d177sewardj /* This just goes to show the crazyness of the instruction 34561b8d58eb046ad31fbb058d65855b604886d3d177sewardj set encoding. We have to insert two prefix bytes, but be 34571b8d58eb046ad31fbb058d65855b604886d3d177sewardj careful to avoid a conflict in what the size should be, by 34581b8d58eb046ad31fbb058d65855b604886d3d177sewardj ensuring that REX.W = 0. */ 34591b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0x66; /* override to 16-bits */ 34601b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = clearWBit( rexAMode_M( i->Ain.Store.src, i->Ain.Store.dst) ); 34611b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0x89; 34621b8d58eb046ad31fbb058d65855b604886d3d177sewardj p = doAMode_M(p, i->Ain.Store.src, i->Ain.Store.dst); 34631b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 34641b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 34651b8d58eb046ad31fbb058d65855b604886d3d177sewardj if (i->Ain.Store.sz == 4) { 34661b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = clearWBit( rexAMode_M( i->Ain.Store.src, i->Ain.Store.dst) ); 34671b8d58eb046ad31fbb058d65855b604886d3d177sewardj *p++ = 0x89; 34681b8d58eb046ad31fbb058d65855b604886d3d177sewardj p = doAMode_M(p, i->Ain.Store.src, i->Ain.Store.dst); 34691b8d58eb046ad31fbb058d65855b604886d3d177sewardj goto done; 34701b8d58eb046ad31fbb058d65855b604886d3d177sewardj } 3471e1698951a3a6431c2421f1eb42f3d246226917basewardj if (i->Ain.Store.sz == 1) { 3472a890367704a21066b655cf8a1136e1846b326f52sewardj /* This is one place where it would be wrong to skip emitting 3473a890367704a21066b655cf8a1136e1846b326f52sewardj a rex byte of 0x40, since the mere presence of rex changes 3474a890367704a21066b655cf8a1136e1846b326f52sewardj the meaning of the byte register access. Be careful. */ 3475e1698951a3a6431c2421f1eb42f3d246226917basewardj *p++ = clearWBit( rexAMode_M( i->Ain.Store.src, i->Ain.Store.dst) ); 3476e1698951a3a6431c2421f1eb42f3d246226917basewardj *p++ = 0x88; 3477e1698951a3a6431c2421f1eb42f3d246226917basewardj p = doAMode_M(p, i->Ain.Store.src, i->Ain.Store.dst); 3478e1698951a3a6431c2421f1eb42f3d246226917basewardj goto done; 3479e1698951a3a6431c2421f1eb42f3d246226917basewardj } 34801b8d58eb046ad31fbb058d65855b604886d3d177sewardj break; 34811b8d58eb046ad31fbb058d65855b604886d3d177sewardj 34821a01e65f9993d97095c2af463e98674a091834casewardj case Ain_LdMXCSR: 3483a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = clearWBit(rexAMode_M_enc(0, i->Ain.LdMXCSR.addr)); 34841a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x0F; 34851a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0xAE; 3486a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 2/*subopcode*/, i->Ain.LdMXCSR.addr); 34871a01e65f9993d97095c2af463e98674a091834casewardj goto done; 34881a01e65f9993d97095c2af463e98674a091834casewardj 34891830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Ain_SseUComIS: 34901830386e7b10430c0c3630123a82d8bcf0a071e7sewardj /* ucomi[sd] %srcL, %srcR ; pushfq ; popq %dst */ 34911830386e7b10430c0c3630123a82d8bcf0a071e7sewardj /* ucomi[sd] %srcL, %srcR */ 34921830386e7b10430c0c3630123a82d8bcf0a071e7sewardj if (i->Ain.SseUComIS.sz == 8) { 34931830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0x66; 34941830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } else { 34951830386e7b10430c0c3630123a82d8bcf0a071e7sewardj goto bad; 34961830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vassert(i->Ain.SseUComIS.sz == 4); 34971830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } 34981830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = clearWBit ( 3499a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.SseUComIS.srcL), 3500a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseUComIS.srcR) )); 35011830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0x0F; 35021830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0x2E; 3503a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.SseUComIS.srcL), 3504a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseUComIS.srcR) ); 35051830386e7b10430c0c3630123a82d8bcf0a071e7sewardj /* pushfq */ 35061830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0x9C; 35071830386e7b10430c0c3630123a82d8bcf0a071e7sewardj /* popq %dst */ 3508a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x40 + (1 & iregEnc3(i->Ain.SseUComIS.dst))); 3509a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj *p++ = toUChar(0x58 + iregEnc210(i->Ain.SseUComIS.dst)); 35101830386e7b10430c0c3630123a82d8bcf0a071e7sewardj goto done; 35111830386e7b10430c0c3630123a82d8bcf0a071e7sewardj 35121a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSI2SF: 35131a01e65f9993d97095c2af463e98674a091834casewardj /* cvssi2s[sd] %src, %dst */ 3514a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = rexAMode_R_enc_reg( vregEnc3210(i->Ain.SseSI2SF.dst), 3515a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseSI2SF.src ); 351603ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseSI2SF.szD==4 ? 0xF3 : 0xF2); 351703ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseSI2SF.szS==4 ? clearWBit(rex) : rex); 35181a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x0F; 35191a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x2A; 3520a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_reg( p, vregEnc3210(i->Ain.SseSI2SF.dst), 3521a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseSI2SF.src ); 35221a01e65f9993d97095c2af463e98674a091834casewardj goto done; 35231a01e65f9993d97095c2af463e98674a091834casewardj 35241a01e65f9993d97095c2af463e98674a091834casewardj case Ain_SseSF2SI: 35251a01e65f9993d97095c2af463e98674a091834casewardj /* cvss[sd]2si %src, %dst */ 3526a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = rexAMode_R_reg_enc( i->Ain.SseSF2SI.dst, 3527a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseSF2SI.src) ); 352803ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseSF2SI.szS==4 ? 0xF3 : 0xF2); 352903ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseSF2SI.szD==4 ? clearWBit(rex) : rex); 35301a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x0F; 35311a01e65f9993d97095c2af463e98674a091834casewardj *p++ = 0x2D; 3532a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_reg_enc( p, i->Ain.SseSF2SI.dst, 3533a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseSF2SI.src) ); 35341a01e65f9993d97095c2af463e98674a091834casewardj goto done; 35351a01e65f9993d97095c2af463e98674a091834casewardj 35368d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseSDSS: 35378d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* cvtsd2ss/cvtss2sd %src, %dst */ 353803ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseSDSS.from64 ? 0xF2 : 0xF3); 35398d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = clearWBit( 3540a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.SseSDSS.dst), 3541a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseSDSS.src) )); 35428d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x0F; 35438d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x5A; 3544a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc( p, vregEnc3210(i->Ain.SseSDSS.dst), 3545a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseSDSS.src) ); 35468d965316c72c2392f670dcdfa127547ec77c7e56sewardj goto done; 35478d965316c72c2392f670dcdfa127547ec77c7e56sewardj 35481001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdSt: 35491830386e7b10430c0c3630123a82d8bcf0a071e7sewardj if (i->Ain.SseLdSt.sz == 8) { 35501830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0xF2; 35511830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } else 35521830386e7b10430c0c3630123a82d8bcf0a071e7sewardj if (i->Ain.SseLdSt.sz == 4) { 35531830386e7b10430c0c3630123a82d8bcf0a071e7sewardj *p++ = 0xF3; 35541830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } else 35551830386e7b10430c0c3630123a82d8bcf0a071e7sewardj if (i->Ain.SseLdSt.sz != 16) { 35561830386e7b10430c0c3630123a82d8bcf0a071e7sewardj vassert(0); 35571830386e7b10430c0c3630123a82d8bcf0a071e7sewardj } 35581001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = clearWBit( 3559a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(vregEnc3210(i->Ain.SseLdSt.reg), 3560a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseLdSt.addr)); 35611001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0x0F; 356203ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseLdSt.isLoad ? 0x10 : 0x11); 3563a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, vregEnc3210(i->Ain.SseLdSt.reg), 3564a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseLdSt.addr); 35651001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto done; 35661001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 356770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCStore: { 356870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(i->Ain.SseCStore.cond != Acc_ALWAYS); 356970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 357070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Use ptmp for backpatching conditional jumps. */ 357170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ptmp = NULL; 357270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 357370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* jmp fwds if !condition */ 357470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.SseCStore.cond ^ 1))); 357570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ptmp = p; /* fill in this bit later */ 357670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 357770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 357870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Now the store. */ 357970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = clearWBit( 358070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj rexAMode_M_enc(vregEnc3210(i->Ain.SseCStore.src), 358170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCStore.addr)); 358270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x0F; 358370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = toUChar(0x11); 358470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj p = doAMode_M_enc(p, vregEnc3210(i->Ain.SseCStore.src), 358570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCStore.addr); 358670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 358770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Fix up the conditional branch */ 358870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj Int delta = p - ptmp; 358970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(delta > 0 && delta < 40); 359070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *ptmp = toUChar(delta-1); 359170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj goto done; 359270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 359370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 359470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Ain_SseCLoad: { 359570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(i->Ain.SseCLoad.cond != Acc_ALWAYS); 359670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 359770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Use ptmp for backpatching conditional jumps. */ 359870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ptmp = NULL; 359970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 360070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* jmp fwds if !condition */ 360170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = toUChar(0x70 + (0xF & (i->Ain.SseCLoad.cond ^ 1))); 360270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj ptmp = p; /* fill in this bit later */ 360370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0; /* # of bytes to jump over; don't know how many yet. */ 360470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 360570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Now the load. */ 360670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = clearWBit( 360770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj rexAMode_M_enc(vregEnc3210(i->Ain.SseCLoad.dst), 360870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCLoad.addr)); 360970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = 0x0F; 361070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *p++ = toUChar(0x10); 361170dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj p = doAMode_M_enc(p, vregEnc3210(i->Ain.SseCLoad.dst), 361270dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj i->Ain.SseCLoad.addr); 361370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 361470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj /* Fix up the conditional branch */ 361570dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj Int delta = p - ptmp; 361670dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(delta > 0 && delta < 40); 361770dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj *ptmp = toUChar(delta-1); 361870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj goto done; 361970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj } 362070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj 36211001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseLdzLO: 36221001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj vassert(i->Ain.SseLdzLO.sz == 4 || i->Ain.SseLdzLO.sz == 8); 36231001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj /* movs[sd] amode, %xmm-dst */ 362403ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(i->Ain.SseLdzLO.sz==4 ? 0xF3 : 0xF2); 36251001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = clearWBit( 3626a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_M_enc(vregEnc3210(i->Ain.SseLdzLO.reg), 3627a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseLdzLO.addr)); 36281001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0x0F; 36291001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0x10; 3630a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, vregEnc3210(i->Ain.SseLdzLO.reg), 3631a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj i->Ain.SseLdzLO.addr); 36321001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto done; 36331001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 36348d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32Fx4: 36358d965316c72c2392f670dcdfa127547ec77c7e56sewardj xtra = 0; 36368d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = clearWBit( 3637a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.Sse32Fx4.dst), 3638a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse32Fx4.src) )); 36398d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x0F; 36408d965316c72c2392f670dcdfa127547ec77c7e56sewardj switch (i->Ain.Sse32Fx4.op) { 3641432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_ADDF: *p++ = 0x58; break; 3642432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_DIVF: *p++ = 0x5E; break; 3643432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_MAXF: *p++ = 0x5F; break; 3644432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_MINF: *p++ = 0x5D; break; 3645432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_MULF: *p++ = 0x59; break; 3646a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RCPF: *p++ = 0x53; break; 3647a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RSQRTF: *p++ = 0x52; break; 3648a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_SQRTF: *p++ = 0x51; break; 3649432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_SUBF: *p++ = 0x5C; break; 36508d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; 3651432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; 3652432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; 3653b928263af5cbbf25ae6da4be3ab5b7f3ee3bb79bsewardj case Asse_CMPUNF: *p++ = 0xC2; xtra = 0x103; break; 36548d965316c72c2392f670dcdfa127547ec77c7e56sewardj default: goto bad; 36558d965316c72c2392f670dcdfa127547ec77c7e56sewardj } 3656a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.Sse32Fx4.dst), 3657a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse32Fx4.src) ); 36588d965316c72c2392f670dcdfa127547ec77c7e56sewardj if (xtra & 0x100) 365903ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(xtra & 0xFF); 36608d965316c72c2392f670dcdfa127547ec77c7e56sewardj goto done; 36618d965316c72c2392f670dcdfa127547ec77c7e56sewardj 36624c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Ain_Sse64Fx2: 36634c328cf28ebd12977fbf837c44a614c5aac660f3sewardj xtra = 0; 36644c328cf28ebd12977fbf837c44a614c5aac660f3sewardj *p++ = 0x66; 36654c328cf28ebd12977fbf837c44a614c5aac660f3sewardj *p++ = clearWBit( 3666a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.Sse64Fx2.dst), 3667a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse64Fx2.src) )); 36684c328cf28ebd12977fbf837c44a614c5aac660f3sewardj *p++ = 0x0F; 36694c328cf28ebd12977fbf837c44a614c5aac660f3sewardj switch (i->Ain.Sse64Fx2.op) { 36704c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Asse_ADDF: *p++ = 0x58; break; 36715992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_DIVF: *p++ = 0x5E; break; 36725992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_MAXF: *p++ = 0x5F; break; 36735992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_MINF: *p++ = 0x5D; break; 36744c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Asse_MULF: *p++ = 0x59; break; 3675976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SQRTF: *p++ = 0x51; break; 36764c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Asse_SUBF: *p++ = 0x5C; break; 3677976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; 3678976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; 3679976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; 3680b928263af5cbbf25ae6da4be3ab5b7f3ee3bb79bsewardj case Asse_CMPUNF: *p++ = 0xC2; xtra = 0x103; break; 36814c328cf28ebd12977fbf837c44a614c5aac660f3sewardj default: goto bad; 36824c328cf28ebd12977fbf837c44a614c5aac660f3sewardj } 3683a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.Sse64Fx2.dst), 3684a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse64Fx2.src) ); 36854c328cf28ebd12977fbf837c44a614c5aac660f3sewardj if (xtra & 0x100) 3686ca673ab9a76f5697f7ce086ff564bf26f4fa28besewardj *p++ = toUChar(xtra & 0xFF); 36874c328cf28ebd12977fbf837c44a614c5aac660f3sewardj goto done; 36888d965316c72c2392f670dcdfa127547ec77c7e56sewardj 36898d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_Sse32FLo: 36908d965316c72c2392f670dcdfa127547ec77c7e56sewardj xtra = 0; 36918d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0xF3; 36928d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = clearWBit( 3693a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.Sse32FLo.dst), 3694a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse32FLo.src) )); 36958d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x0F; 36968d965316c72c2392f670dcdfa127547ec77c7e56sewardj switch (i->Ain.Sse32FLo.op) { 36978d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_ADDF: *p++ = 0x58; break; 3698c49ce233511cddeaf1fed6931e9a5d8a0cbcf279sewardj case Asse_DIVF: *p++ = 0x5E; break; 369937d52574c28a12a0e1930f1a703db573a4aa3e44sewardj case Asse_MAXF: *p++ = 0x5F; break; 370037d52574c28a12a0e1930f1a703db573a4aa3e44sewardj case Asse_MINF: *p++ = 0x5D; break; 37018d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_MULF: *p++ = 0x59; break; 3702a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RCPF: *p++ = 0x53; break; 3703a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_RSQRTF: *p++ = 0x52; break; 3704a7ba8c47f30998a518cda7e38b4082a9e5c6892esewardj case Asse_SQRTF: *p++ = 0x51; break; 37058d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_SUBF: *p++ = 0x5C; break; 3706432f8b63f5f06d0b86daf3b360a722aaf2f3344fsewardj case Asse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; 37073aba9eb1a223f2cbb21500ec8854f745c9eb11absewardj case Asse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; 37084c328cf28ebd12977fbf837c44a614c5aac660f3sewardj case Asse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; 3709b928263af5cbbf25ae6da4be3ab5b7f3ee3bb79bsewardj case Asse_CMPUNF: *p++ = 0xC2; xtra = 0x103; break; 37108d965316c72c2392f670dcdfa127547ec77c7e56sewardj default: goto bad; 37118d965316c72c2392f670dcdfa127547ec77c7e56sewardj } 3712a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.Sse32FLo.dst), 3713a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse32FLo.src) ); 37148d965316c72c2392f670dcdfa127547ec77c7e56sewardj if (xtra & 0x100) 371503ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(xtra & 0xFF); 37168d965316c72c2392f670dcdfa127547ec77c7e56sewardj goto done; 37171001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 37181001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_Sse64FLo: 37191001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj xtra = 0; 37201001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0xF2; 37211001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = clearWBit( 3722a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.Sse64FLo.dst), 3723a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse64FLo.src) )); 37241001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj *p++ = 0x0F; 37251001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj switch (i->Ain.Sse64FLo.op) { 37261001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_ADDF: *p++ = 0x58; break; 37271001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_DIVF: *p++ = 0x5E; break; 37281a01e65f9993d97095c2af463e98674a091834casewardj case Asse_MAXF: *p++ = 0x5F; break; 3729c49ce233511cddeaf1fed6931e9a5d8a0cbcf279sewardj case Asse_MINF: *p++ = 0x5D; break; 37301001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_MULF: *p++ = 0x59; break; 37311830386e7b10430c0c3630123a82d8bcf0a071e7sewardj case Asse_SQRTF: *p++ = 0x51; break; 37321001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_SUBF: *p++ = 0x5C; break; 3733137015d7434c75ff70954d347bd61432efba3532sewardj case Asse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break; 37348d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break; 3735137015d7434c75ff70954d347bd61432efba3532sewardj case Asse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break; 3736b928263af5cbbf25ae6da4be3ab5b7f3ee3bb79bsewardj case Asse_CMPUNF: *p++ = 0xC2; xtra = 0x103; break; 37371001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj default: goto bad; 37381001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 3739a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.Sse64FLo.dst), 3740a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.Sse64FLo.src) ); 37411001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj if (xtra & 0x100) 374203ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(xtra & 0xFF); 37431001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto done; 37441001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 37451001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Ain_SseReRg: 37461001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj# define XX(_n) *p++ = (_n) 37471001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 37481001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj rex = clearWBit( 3749a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.SseReRg.dst), 3750a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseReRg.src) )); 37511001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 37521001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj switch (i->Ain.SseReRg.op) { 37531001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj case Asse_MOV: /*movups*/ XX(rex); XX(0x0F); XX(0x10); break; 37548d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Asse_OR: XX(rex); XX(0x0F); XX(0x56); break; 37559da16977406ea569541209807c7dcf8cb936a8dcsewardj case Asse_XOR: XX(rex); XX(0x0F); XX(0x57); break; 37561a01e65f9993d97095c2af463e98674a091834casewardj case Asse_AND: XX(rex); XX(0x0F); XX(0x54); break; 3757137015d7434c75ff70954d347bd61432efba3532sewardj case Asse_ANDN: XX(rex); XX(0x0F); XX(0x55); break; 3758976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKSSD: XX(0x66); XX(rex); XX(0x0F); XX(0x6B); break; 3759976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKSSW: XX(0x66); XX(rex); XX(0x0F); XX(0x63); break; 3760976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_PACKUSW: XX(0x66); XX(rex); XX(0x0F); XX(0x67); break; 3761976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_ADD8: XX(0x66); XX(rex); XX(0x0F); XX(0xFC); break; 37625992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_ADD16: XX(0x66); XX(rex); XX(0x0F); XX(0xFD); break; 3763976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_ADD32: XX(0x66); XX(rex); XX(0x0F); XX(0xFE); break; 376409717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_ADD64: XX(0x66); XX(rex); XX(0x0F); XX(0xD4); break; 37655992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD8S: XX(0x66); XX(rex); XX(0x0F); XX(0xEC); break; 37665992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD16S: XX(0x66); XX(rex); XX(0x0F); XX(0xED); break; 37675992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD8U: XX(0x66); XX(rex); XX(0x0F); XX(0xDC); break; 37685992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_QADD16U: XX(0x66); XX(rex); XX(0x0F); XX(0xDD); break; 37695992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_AVG8U: XX(0x66); XX(rex); XX(0x0F); XX(0xE0); break; 37705992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_AVG16U: XX(0x66); XX(rex); XX(0x0F); XX(0xE3); break; 37715992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPEQ8: XX(0x66); XX(rex); XX(0x0F); XX(0x74); break; 37725992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPEQ16: XX(0x66); XX(rex); XX(0x0F); XX(0x75); break; 377309717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_CMPEQ32: XX(0x66); XX(rex); XX(0x0F); XX(0x76); break; 37745992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT8S: XX(0x66); XX(rex); XX(0x0F); XX(0x64); break; 37755992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT16S: XX(0x66); XX(rex); XX(0x0F); XX(0x65); break; 37765992bd07a3237cae1c22f6c93c43730e6447350csewardj case Asse_CMPGT32S: XX(0x66); XX(rex); XX(0x0F); XX(0x66); break; 3777adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MAX16S: XX(0x66); XX(rex); XX(0x0F); XX(0xEE); break; 3778adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MAX8U: XX(0x66); XX(rex); XX(0x0F); XX(0xDE); break; 3779adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MIN16S: XX(0x66); XX(rex); XX(0x0F); XX(0xEA); break; 3780adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MIN8U: XX(0x66); XX(rex); XX(0x0F); XX(0xDA); break; 3781adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MULHI16U: XX(0x66); XX(rex); XX(0x0F); XX(0xE4); break; 3782adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MULHI16S: XX(0x66); XX(rex); XX(0x0F); XX(0xE5); break; 3783adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_MUL16: XX(0x66); XX(rex); XX(0x0F); XX(0xD5); break; 3784adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL16: XX(0x66); XX(rex); XX(0x0F); XX(0xF1); break; 3785adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL32: XX(0x66); XX(rex); XX(0x0F); XX(0xF2); break; 3786adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHL64: XX(0x66); XX(rex); XX(0x0F); XX(0xF3); break; 3787adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SAR16: XX(0x66); XX(rex); XX(0x0F); XX(0xE1); break; 3788adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SAR32: XX(0x66); XX(rex); XX(0x0F); XX(0xE2); break; 3789adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHR16: XX(0x66); XX(rex); XX(0x0F); XX(0xD1); break; 3790adffcef004712e8afc6a7d87b30ef90e4685df40sewardj case Asse_SHR32: XX(0x66); XX(rex); XX(0x0F); XX(0xD2); break; 379109717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_SHR64: XX(0x66); XX(rex); XX(0x0F); XX(0xD3); break; 3792976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB8: XX(0x66); XX(rex); XX(0x0F); XX(0xF8); break; 3793976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB16: XX(0x66); XX(rex); XX(0x0F); XX(0xF9); break; 3794976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_SUB32: XX(0x66); XX(rex); XX(0x0F); XX(0xFA); break; 379509717341a0c364814e35bf405e61399d0e45fa7csewardj case Asse_SUB64: XX(0x66); XX(rex); XX(0x0F); XX(0xFB); break; 3796976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB8S: XX(0x66); XX(rex); XX(0x0F); XX(0xE8); break; 3797976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB16S: XX(0x66); XX(rex); XX(0x0F); XX(0xE9); break; 3798976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB8U: XX(0x66); XX(rex); XX(0x0F); XX(0xD8); break; 3799976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_QSUB16U: XX(0x66); XX(rex); XX(0x0F); XX(0xD9); break; 3800976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHB: XX(0x66); XX(rex); XX(0x0F); XX(0x68); break; 3801976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHW: XX(0x66); XX(rex); XX(0x0F); XX(0x69); break; 3802976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHD: XX(0x66); XX(rex); XX(0x0F); XX(0x6A); break; 3803976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKHQ: XX(0x66); XX(rex); XX(0x0F); XX(0x6D); break; 3804976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLB: XX(0x66); XX(rex); XX(0x0F); XX(0x60); break; 3805976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLW: XX(0x66); XX(rex); XX(0x0F); XX(0x61); break; 3806976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLD: XX(0x66); XX(rex); XX(0x0F); XX(0x62); break; 3807976285992e00e9b3656f08d0e08e62e65ec6a29fsewardj case Asse_UNPCKLQ: XX(0x66); XX(rex); XX(0x0F); XX(0x6C); break; 38081001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj default: goto bad; 38091001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj } 3810a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.SseReRg.dst), 3811a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseReRg.src) ); 38121001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj# undef XX 38131001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj goto done; 38141001dc4dbf8f684e2afeaaea169e37a7ddeb5934sewardj 38158d965316c72c2392f670dcdfa127547ec77c7e56sewardj case Ain_SseCMov: 38168d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* jmp fwds if !condition */ 381703ccf858efa285d793061359c04fdd0055cd9d31sewardj *p++ = toUChar(0x70 + (i->Ain.SseCMov.cond ^ 1)); 38188d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0; /* # of bytes in the next bit, which we don't know yet */ 38198d965316c72c2392f670dcdfa127547ec77c7e56sewardj ptmp = p; 38208d965316c72c2392f670dcdfa127547ec77c7e56sewardj 38218d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* movaps %src, %dst */ 38228d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = clearWBit( 3823a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.SseCMov.dst), 3824a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseCMov.src) )); 38258d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x0F; 38268d965316c72c2392f670dcdfa127547ec77c7e56sewardj *p++ = 0x28; 3827a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.SseCMov.dst), 3828a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseCMov.src) ); 38298d965316c72c2392f670dcdfa127547ec77c7e56sewardj 38308d965316c72c2392f670dcdfa127547ec77c7e56sewardj /* Fill in the jump offset. */ 383103ccf858efa285d793061359c04fdd0055cd9d31sewardj *(ptmp-1) = toUChar(p - ptmp); 38328d965316c72c2392f670dcdfa127547ec77c7e56sewardj goto done; 38338d965316c72c2392f670dcdfa127547ec77c7e56sewardj 383409717341a0c364814e35bf405e61399d0e45fa7csewardj case Ain_SseShuf: 383509717341a0c364814e35bf405e61399d0e45fa7csewardj *p++ = 0x66; 383609717341a0c364814e35bf405e61399d0e45fa7csewardj *p++ = clearWBit( 3837a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rexAMode_R_enc_enc( vregEnc3210(i->Ain.SseShuf.dst), 3838a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseShuf.src) )); 383909717341a0c364814e35bf405e61399d0e45fa7csewardj *p++ = 0x0F; 384009717341a0c364814e35bf405e61399d0e45fa7csewardj *p++ = 0x70; 3841a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_R_enc_enc(p, vregEnc3210(i->Ain.SseShuf.dst), 3842a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj vregEnc3210(i->Ain.SseShuf.src) ); 384309717341a0c364814e35bf405e61399d0e45fa7csewardj *p++ = (UChar)(i->Ain.SseShuf.order); 384409717341a0c364814e35bf405e61399d0e45fa7csewardj goto done; 384509717341a0c364814e35bf405e61399d0e45fa7csewardj 38463616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu case Ain_AvxLdSt: { 38473616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu UInt vex = vexAMode_M( dvreg2ireg(i->Ain.AvxLdSt.reg), 38483616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu i->Ain.AvxLdSt.addr ); 38493616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu p = emitVexPrefix(p, vex); 38503616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu *p++ = toUChar(i->Ain.AvxLdSt.isLoad ? 0x10 : 0x11); 38513616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu p = doAMode_M(p, dvreg2ireg(i->Ain.AvxLdSt.reg), i->Ain.AvxLdSt.addr); 38523616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu goto done; 38533616a2ec4af166a3917810e4fdbe910ed80bd278sewardj //uu } 3854c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj 3855c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_EvCheck: { 3856c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We generate: 3857c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (3 bytes) decl 8(%rbp) 8 == offsetof(host_EvC_COUNTER) 3858c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (2 bytes) jns nofail expected taken 3859c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (3 bytes) jmp* 0(%rbp) 0 == offsetof(host_EvC_FAILADDR) 3860c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj nofail: 3861c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 3862c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* This is heavily asserted re instruction lengths. It needs to 3863c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj be. If we get given unexpected forms of .amCounter or 3864c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj .amFailAddr -- basically, anything that's not of the form 3865c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj uimm7(%rbp) -- they are likely to fail. */ 3866c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Note also that after the decl we must be very careful not to 3867c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj read the carry flag, else we get a partial flags stall. 3868c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj js/jns avoids that, though. */ 3869c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj UChar* p0 = p; 3870c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* --- decl 8(%rbp) --- */ 3871c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Need to compute the REX byte for the decl in order to prove 3872c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj that we don't need it, since this is a 32-bit inc and all 3873a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj registers involved in the amode are < r8. "1" because 3874c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj there's no register in this encoding; instead the register 3875c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj field is used as a sub opcode. The encoding for "decl r/m32" 3876a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj is FF /1, hence the "1". */ 3877a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = clearWBit(rexAMode_M_enc(1, i->Ain.EvCheck.amCounter)); 3878c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (rex != 0x40) goto bad; /* We don't expect to need the REX byte. */ 3879c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xFF; 3880a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 1, i->Ain.EvCheck.amCounter); 3881c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p - p0 == 3); 3882c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* --- jns nofail --- */ 3883c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x79; 3884c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x03; /* need to check this 0x03 after the next insn */ 3885c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p - p0 == 5); 3886c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* --- jmp* 0(%rbp) --- */ 3887c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Once again, verify we don't need REX. The encoding is FF /4. 3888c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj We don't need REX.W since by default FF /4 in 64-bit mode 3889c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj implies a 64 bit load. */ 3890a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj rex = clearWBit(rexAMode_M_enc(4, i->Ain.EvCheck.amFailAddr)); 3891c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (rex != 0x40) goto bad; 3892c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0xFF; 3893a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj p = doAMode_M_enc(p, 4, i->Ain.EvCheck.amFailAddr); 3894c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p - p0 == 8); /* also ensures that 0x03 offset above is ok */ 3895c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* And crosscheck .. */ 38967ce2cc883c5b36586babec833838951ecf9f2a76florian vassert(evCheckSzB_AMD64() == 8); 3897c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj goto done; 3898c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3899c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3900c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ain_ProfInc: { 3901c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* We generate movabsq $0, %r11 3902c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj incq (%r11) 3903c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj in the expectation that a later call to LibVEX_patchProfCtr 3904c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj will be used to fill in the immediate field once the right 3905c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj value is known. 3906c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 BB 00 00 00 00 00 00 00 00 3907c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 FF 03 3908c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 3909c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x49; *p++ = 0xBB; 3910c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; 3911c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; 3912c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *p++ = 0x49; *p++ = 0xFF; *p++ = 0x03; 3913c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Tell the caller .. */ 3914c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(!(*is_profInc)); 3915c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj *is_profInc = True; 3916c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj goto done; 3917c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 3918c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3919c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj default: 3920c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj goto bad; 3921c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj } 3922c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 3923c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj bad: 392492b643609c5fa432b11fc726c2706ae3f3296eb4cerion ppAMD64Instr(i, mode64); 3925c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj vpanic("emit_AMD64Instr"); 3926c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj /*NOTREACHED*/ 3927c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj 3928813ce9e974ad75c2f69f570e6dbc087b5b3b1706sewardj done: 392970dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj vassert(p - &buf[0] <= 64); 3930c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj return p - &buf[0]; 3931c33671d7b0e21edb1d1015e4cbccbc6ca139e6d8sewardj} 3932a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj 3933c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3934c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* How big is an event check? See case for Ain_EvCheck in 3935c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj emit_AMD64Instr just above. That crosschecks what this returns, so 3936c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj we can tell if we're inconsistent. */ 39377ce2cc883c5b36586babec833838951ecf9f2a76florianInt evCheckSzB_AMD64 (void) 3938c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{ 3939c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return 8; 3940c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 3941c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3942c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3943c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* NB: what goes on here has to be very closely coordinated with the 3944c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj emitInstr case for XDirect, above. */ 39459b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange chainXDirect_AMD64 ( VexEndness endness_host, 39469b76916dcc1628e133d57db001563429c6e3a590sewardj void* place_to_chain, 39477d6f81de12e6d8deb3e119ab318f361d97a10a65florian const void* disp_cp_chain_me_EXPECTED, 39487d6f81de12e6d8deb3e119ab318f361d97a10a65florian const void* place_to_jump_to ) 3949c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{ 39509b76916dcc1628e133d57db001563429c6e3a590sewardj vassert(endness_host == VexEndnessLE); 39519b76916dcc1628e133d57db001563429c6e3a590sewardj 3952c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* What we're expecting to see is: 3953c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj movabsq $disp_cp_chain_me_EXPECTED, %r11 3954c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj call *%r11 3955c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 3956c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 BB <8 bytes value == disp_cp_chain_me_EXPECTED> 3957c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 41 FF D3 3958c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 3959c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj UChar* p = (UChar*)place_to_chain; 3960c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[0] == 0x49); 3961c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[1] == 0xBB); 396248729060949c3c8e2cfdd9aae20df000dac279c0sewardj vassert(read_misaligned_ULong_LE(&p[2]) == (Addr)disp_cp_chain_me_EXPECTED); 3963c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[10] == 0x41); 3964c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[11] == 0xFF); 3965c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[12] == 0xD3); 3966c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* And what we want to change it to is either: 3967c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (general case): 3968c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj movabsq $place_to_jump_to, %r11 3969c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jmpq *%r11 3970c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 3971c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 BB <8 bytes value == place_to_jump_to> 3972c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 41 FF E3 3973c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj So it's the same length (convenient, huh) and we don't 3974c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj need to change all the bits. 3975c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ---OR--- 3976c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj in the case where the displacement falls within 32 bits 3977c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jmpq disp32 where disp32 is relative to the next insn 3978c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ud2; ud2; ud2; ud2 3979c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 3980c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj E9 <4 bytes == disp32> 3981c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 0F 0B 0F 0B 0F 0B 0F 0B 3982c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3983c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj In both cases the replacement has the same length as the original. 3984c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj To remain sane & verifiable, 3985c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (1) limit the displacement for the short form to 3986c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (say) +/- one billion, so as to avoid wraparound 3987c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj off-by-ones 3988c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (2) even if the short form is applicable, once every (say) 3989c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 1024 times use the long form anyway, so as to maintain 3990c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj verifiability 3991c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 3992c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* This is the delta we need to put into a JMP d32 insn. It's 3993c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj relative to the start of the next insn, hence the -5. */ 39947d6f81de12e6d8deb3e119ab318f361d97a10a65florian Long delta = (Long)((const UChar *)place_to_jump_to - (const UChar*)p) - 5; 3995c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Bool shortOK = delta >= -1000*1000*1000 && delta < 1000*1000*1000; 3996c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 3997c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj static UInt shortCTR = 0; /* DO NOT MAKE NON-STATIC */ 3998c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (shortOK) { 3999c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj shortCTR++; // thread safety bleh 4000c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (0 == (shortCTR & 0x3FF)) { 4001c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj shortOK = False; 4002c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (0) 4003c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("QQQ chainXDirect_AMD64: shortCTR = %u, " 4004c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj "using long jmp\n", shortCTR); 4005c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 4006c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 4007c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4008c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* And make the modifications. */ 4009c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (shortOK) { 4010c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[0] = 0xE9; 401148729060949c3c8e2cfdd9aae20df000dac279c0sewardj write_misaligned_UInt_LE(&p[1], (UInt)(Int)delta); 4012c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[5] = 0x0F; p[6] = 0x0B; 4013c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[7] = 0x0F; p[8] = 0x0B; 4014c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[9] = 0x0F; p[10] = 0x0B; 4015c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[11] = 0x0F; p[12] = 0x0B; 4016c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* sanity check on the delta -- top 32 are all 0 or all 1 */ 4017c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj delta >>= 32; 4018c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(delta == 0LL || delta == -1LL); 4019c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } else { 4020c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Minimal modifications from the starting sequence. */ 402148729060949c3c8e2cfdd9aae20df000dac279c0sewardj write_misaligned_ULong_LE(&p[2], (ULong)(Addr)place_to_jump_to); 4022c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[12] = 0xE3; 4023c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 40245ea257be80e49474f724426939d4c398c8bfab1bflorian VexInvalRange vir = { (HWord)place_to_chain, 13 }; 4025c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return vir; 4026c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 4027c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4028c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4029c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* NB: what goes on here has to be very closely coordinated with the 4030c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj emitInstr case for XDirect, above. */ 40319b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host, 40329b76916dcc1628e133d57db001563429c6e3a590sewardj void* place_to_unchain, 40337d6f81de12e6d8deb3e119ab318f361d97a10a65florian const void* place_to_jump_to_EXPECTED, 40347d6f81de12e6d8deb3e119ab318f361d97a10a65florian const void* disp_cp_chain_me ) 4035c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{ 40369b76916dcc1628e133d57db001563429c6e3a590sewardj vassert(endness_host == VexEndnessLE); 40379b76916dcc1628e133d57db001563429c6e3a590sewardj 4038c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* What we're expecting to see is either: 4039c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj (general case) 4040c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj movabsq $place_to_jump_to_EXPECTED, %r11 4041c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jmpq *%r11 4042c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 4043c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 BB <8 bytes value == place_to_jump_to_EXPECTED> 4044c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 41 FF E3 4045c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ---OR--- 4046c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj in the case where the displacement falls within 32 bits 4047c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj jmpq d32 4048c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj ud2; ud2; ud2; ud2 4049c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 4050c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj E9 <4 bytes == disp32> 4051c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 0F 0B 0F 0B 0F 0B 0F 0B 4052c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 4053c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj UChar* p = (UChar*)place_to_unchain; 4054c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Bool valid = False; 4055c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (p[0] == 0x49 && p[1] == 0xBB 405648729060949c3c8e2cfdd9aae20df000dac279c0sewardj && read_misaligned_ULong_LE(&p[2]) 405748729060949c3c8e2cfdd9aae20df000dac279c0sewardj == (ULong)(Addr)place_to_jump_to_EXPECTED 4058c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj && p[10] == 0x41 && p[11] == 0xFF && p[12] == 0xE3) { 4059c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* it's the long form */ 4060c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj valid = True; 4061c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 4062c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj else 4063c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (p[0] == 0xE9 4064c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj && p[5] == 0x0F && p[6] == 0x0B 4065c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj && p[7] == 0x0F && p[8] == 0x0B 4066c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj && p[9] == 0x0F && p[10] == 0x0B 4067c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj && p[11] == 0x0F && p[12] == 0x0B) { 4068c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* It's the short form. Check the offset is right. */ 406948729060949c3c8e2cfdd9aae20df000dac279c0sewardj Int s32 = (Int)read_misaligned_UInt_LE(&p[1]); 4070c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Long s64 = (Long)s32; 40717d6f81de12e6d8deb3e119ab318f361d97a10a65florian if ((UChar*)p + 5 + s64 == place_to_jump_to_EXPECTED) { 4072c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj valid = True; 4073c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (0) 4074c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vex_printf("QQQ unchainXDirect_AMD64: found short form\n"); 4075c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 4076c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 4077c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(valid); 4078c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* And what we want to change it to is: 4079c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj movabsq $disp_cp_chain_me, %r11 4080c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj call *%r11 4081c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj viz 4082c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 49 BB <8 bytes value == disp_cp_chain_me> 4083c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 41 FF D3 4084c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj So it's the same length (convenient, huh). 4085c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj */ 4086c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[0] = 0x49; 4087c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[1] = 0xBB; 408848729060949c3c8e2cfdd9aae20df000dac279c0sewardj write_misaligned_ULong_LE(&p[2], (ULong)(Addr)disp_cp_chain_me); 4089c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[10] = 0x41; 4090c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[11] = 0xFF; 4091c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[12] = 0xD3; 40925ea257be80e49474f724426939d4c398c8bfab1bflorian VexInvalRange vir = { (HWord)place_to_unchain, 13 }; 4093c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return vir; 4094c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 4095c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4096c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4097c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* Patch the counter address into a profile inc point, as previously 4098c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj created by the Ain_ProfInc case for emit_AMD64Instr. */ 40999b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange patchProfInc_AMD64 ( VexEndness endness_host, 41009b76916dcc1628e133d57db001563429c6e3a590sewardj void* place_to_patch, 41017d6f81de12e6d8deb3e119ab318f361d97a10a65florian const ULong* location_of_counter ) 4102c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{ 41039b76916dcc1628e133d57db001563429c6e3a590sewardj vassert(endness_host == VexEndnessLE); 4104c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(sizeof(ULong*) == 8); 4105c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj UChar* p = (UChar*)place_to_patch; 4106c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[0] == 0x49); 4107c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[1] == 0xBB); 4108c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[2] == 0x00); 4109c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[3] == 0x00); 4110c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[4] == 0x00); 4111c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[5] == 0x00); 4112c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[6] == 0x00); 4113c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[7] == 0x00); 4114c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[8] == 0x00); 4115c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[9] == 0x00); 4116c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[10] == 0x49); 4117c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[11] == 0xFF); 4118c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj vassert(p[12] == 0x03); 411993a09742b0de3d61718882c2d999f64be402564dflorian ULong imm64 = (ULong)(Addr)location_of_counter; 4120c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[2] = imm64 & 0xFF; imm64 >>= 8; 4121c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[3] = imm64 & 0xFF; imm64 >>= 8; 4122c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[4] = imm64 & 0xFF; imm64 >>= 8; 4123c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[5] = imm64 & 0xFF; imm64 >>= 8; 4124c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[6] = imm64 & 0xFF; imm64 >>= 8; 4125c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[7] = imm64 & 0xFF; imm64 >>= 8; 4126c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[8] = imm64 & 0xFF; imm64 >>= 8; 4127c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj p[9] = imm64 & 0xFF; imm64 >>= 8; 41285ea257be80e49474f724426939d4c398c8bfab1bflorian VexInvalRange vir = { (HWord)place_to_patch, 13 }; 4129c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return vir; 4130c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 4131c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4132c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 4133a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj/*---------------------------------------------------------------*/ 4134cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end host_amd64_defs.c ---*/ 4135a3e9830f0ab418d41a9c8484216b563d438cf2dcsewardj/*---------------------------------------------------------------*/ 4136