static_inst.cc revision 10934:5af8f40d8f2c
19380SAndreas.Sandberg@ARM.com/* 29380SAndreas.Sandberg@ARM.com * Copyright (c) 2007 The Hewlett-Packard Development Company 39380SAndreas.Sandberg@ARM.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 49380SAndreas.Sandberg@ARM.com * All rights reserved. 59380SAndreas.Sandberg@ARM.com * 69380SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 79380SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 89380SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 99380SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 109380SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 119380SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 129380SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 139380SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 149380SAndreas.Sandberg@ARM.com * 159380SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 169380SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 179380SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 189380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 199380SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 209380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 219380SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 229380SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 239380SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 249380SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 259380SAndreas.Sandberg@ARM.com * 269380SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 279380SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 289380SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 299380SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 309380SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 319380SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 329380SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 339380SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 349380SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 359380SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 369380SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 379380SAndreas.Sandberg@ARM.com * 389380SAndreas.Sandberg@ARM.com * Authors: Gabe Black 399380SAndreas.Sandberg@ARM.com */ 409380SAndreas.Sandberg@ARM.com 419380SAndreas.Sandberg@ARM.com#include "arch/x86/insts/static_inst.hh" 429380SAndreas.Sandberg@ARM.com#include "arch/x86/regs/segment.hh" 439380SAndreas.Sandberg@ARM.com#include "cpu/reg_class.hh" 449380SAndreas.Sandberg@ARM.com 459380SAndreas.Sandberg@ARM.comnamespace X86ISA 469654SAndreas.Sandberg@ARM.com{ 479654SAndreas.Sandberg@ARM.com void X86StaticInst::printMnemonic(std::ostream &os, 489380SAndreas.Sandberg@ARM.com const char * mnemonic) const 499380SAndreas.Sandberg@ARM.com { 509380SAndreas.Sandberg@ARM.com ccprintf(os, " %s ", mnemonic); 519380SAndreas.Sandberg@ARM.com } 529380SAndreas.Sandberg@ARM.com 539380SAndreas.Sandberg@ARM.com void X86StaticInst::printMnemonic(std::ostream &os, 549380SAndreas.Sandberg@ARM.com const char * instMnemonic, const char * mnemonic) const 559380SAndreas.Sandberg@ARM.com { 569380SAndreas.Sandberg@ARM.com ccprintf(os, " %s : %s ", instMnemonic, mnemonic); 579380SAndreas.Sandberg@ARM.com } 589380SAndreas.Sandberg@ARM.com 599380SAndreas.Sandberg@ARM.com void X86StaticInst::printSegment(std::ostream &os, int segment) const 609380SAndreas.Sandberg@ARM.com { 619380SAndreas.Sandberg@ARM.com switch (segment) 629380SAndreas.Sandberg@ARM.com { 639380SAndreas.Sandberg@ARM.com case SEGMENT_REG_ES: 649380SAndreas.Sandberg@ARM.com ccprintf(os, "ES"); 659380SAndreas.Sandberg@ARM.com break; 669380SAndreas.Sandberg@ARM.com case SEGMENT_REG_CS: 679380SAndreas.Sandberg@ARM.com ccprintf(os, "CS"); 689380SAndreas.Sandberg@ARM.com break; 699380SAndreas.Sandberg@ARM.com case SEGMENT_REG_SS: 709380SAndreas.Sandberg@ARM.com ccprintf(os, "SS"); 719380SAndreas.Sandberg@ARM.com break; 729380SAndreas.Sandberg@ARM.com case SEGMENT_REG_DS: 739380SAndreas.Sandberg@ARM.com ccprintf(os, "DS"); 749380SAndreas.Sandberg@ARM.com break; 759380SAndreas.Sandberg@ARM.com case SEGMENT_REG_FS: 769380SAndreas.Sandberg@ARM.com ccprintf(os, "FS"); 779380SAndreas.Sandberg@ARM.com break; 789380SAndreas.Sandberg@ARM.com case SEGMENT_REG_GS: 799380SAndreas.Sandberg@ARM.com ccprintf(os, "GS"); 809380SAndreas.Sandberg@ARM.com break; 819380SAndreas.Sandberg@ARM.com case SEGMENT_REG_HS: 829380SAndreas.Sandberg@ARM.com ccprintf(os, "HS"); 839380SAndreas.Sandberg@ARM.com break; 849380SAndreas.Sandberg@ARM.com case SEGMENT_REG_TSL: 859380SAndreas.Sandberg@ARM.com ccprintf(os, "TSL"); 869380SAndreas.Sandberg@ARM.com break; 879380SAndreas.Sandberg@ARM.com case SEGMENT_REG_TSG: 889380SAndreas.Sandberg@ARM.com ccprintf(os, "TSG"); 899380SAndreas.Sandberg@ARM.com break; 909380SAndreas.Sandberg@ARM.com case SEGMENT_REG_LS: 919380SAndreas.Sandberg@ARM.com ccprintf(os, "LS"); 929380SAndreas.Sandberg@ARM.com break; 939380SAndreas.Sandberg@ARM.com case SEGMENT_REG_MS: 949380SAndreas.Sandberg@ARM.com ccprintf(os, "MS"); 959380SAndreas.Sandberg@ARM.com break; 969380SAndreas.Sandberg@ARM.com case SYS_SEGMENT_REG_TR: 979380SAndreas.Sandberg@ARM.com ccprintf(os, "TR"); 989380SAndreas.Sandberg@ARM.com break; 999380SAndreas.Sandberg@ARM.com case SYS_SEGMENT_REG_IDTR: 1009380SAndreas.Sandberg@ARM.com ccprintf(os, "IDTR"); 1019380SAndreas.Sandberg@ARM.com break; 1029380SAndreas.Sandberg@ARM.com default: 1039380SAndreas.Sandberg@ARM.com panic("Unrecognized segment %d\n", segment); 1049380SAndreas.Sandberg@ARM.com } 1059380SAndreas.Sandberg@ARM.com } 1069380SAndreas.Sandberg@ARM.com 1079674Snilay@cs.wisc.edu void 1089380SAndreas.Sandberg@ARM.com X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const 1099380SAndreas.Sandberg@ARM.com { 1109380SAndreas.Sandberg@ARM.com if(_numSrcRegs > reg) 1119380SAndreas.Sandberg@ARM.com printReg(os, _srcRegIdx[reg], size); 1129380SAndreas.Sandberg@ARM.com } 1139380SAndreas.Sandberg@ARM.com 1149674Snilay@cs.wisc.edu void 1159674Snilay@cs.wisc.edu X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const 1169674Snilay@cs.wisc.edu { 1179674Snilay@cs.wisc.edu if(_numDestRegs > reg) 1189674Snilay@cs.wisc.edu printReg(os, _destRegIdx[reg], size); 1199380SAndreas.Sandberg@ARM.com } 1209654SAndreas.Sandberg@ARM.com 1219654SAndreas.Sandberg@ARM.com void 1229654SAndreas.Sandberg@ARM.com X86StaticInst::printReg(std::ostream &os, int reg, int size) const 1239654SAndreas.Sandberg@ARM.com { 1249654SAndreas.Sandberg@ARM.com assert(size == 1 || size == 2 || size == 4 || size == 8); 1259654SAndreas.Sandberg@ARM.com static const char * abcdFormats[9] = 1269654SAndreas.Sandberg@ARM.com {"", "%s", "%sx", "", "e%sx", "", "", "", "r%sx"}; 1279654SAndreas.Sandberg@ARM.com static const char * piFormats[9] = 1289380SAndreas.Sandberg@ARM.com {"", "%s", "%s", "", "e%s", "", "", "", "r%s"}; 1299380SAndreas.Sandberg@ARM.com static const char * longFormats[9] = 1309380SAndreas.Sandberg@ARM.com {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"}; 1319380SAndreas.Sandberg@ARM.com static const char * microFormats[9] = 1329380SAndreas.Sandberg@ARM.com {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"}; 1339380SAndreas.Sandberg@ARM.com 1349380SAndreas.Sandberg@ARM.com RegIndex rel_reg; 1359380SAndreas.Sandberg@ARM.com 1369654SAndreas.Sandberg@ARM.com switch (regIdxToClass(reg, &rel_reg)) { 1379654SAndreas.Sandberg@ARM.com case IntRegClass: { 1389654SAndreas.Sandberg@ARM.com const char * suffix = ""; 1399654SAndreas.Sandberg@ARM.com bool fold = rel_reg & IntFoldBit; 1409380SAndreas.Sandberg@ARM.com rel_reg &= ~IntFoldBit; 1419380SAndreas.Sandberg@ARM.com 1429674Snilay@cs.wisc.edu if(fold) 1439380SAndreas.Sandberg@ARM.com suffix = "h"; 1449380SAndreas.Sandberg@ARM.com else if(rel_reg < 8 && size == 1) 1459380SAndreas.Sandberg@ARM.com suffix = "l"; 1469380SAndreas.Sandberg@ARM.com 1479380SAndreas.Sandberg@ARM.com switch (rel_reg) { 1489380SAndreas.Sandberg@ARM.com case INTREG_RAX: 1499380SAndreas.Sandberg@ARM.com ccprintf(os, abcdFormats[size], "a"); 1509380SAndreas.Sandberg@ARM.com break; 1519380SAndreas.Sandberg@ARM.com case INTREG_RBX: 1529380SAndreas.Sandberg@ARM.com ccprintf(os, abcdFormats[size], "b"); 1539380SAndreas.Sandberg@ARM.com break; 1549380SAndreas.Sandberg@ARM.com case INTREG_RCX: 1559380SAndreas.Sandberg@ARM.com ccprintf(os, abcdFormats[size], "c"); 1569380SAndreas.Sandberg@ARM.com break; 1579380SAndreas.Sandberg@ARM.com case INTREG_RDX: 1589380SAndreas.Sandberg@ARM.com ccprintf(os, abcdFormats[size], "d"); 1599380SAndreas.Sandberg@ARM.com break; 1609380SAndreas.Sandberg@ARM.com case INTREG_RSP: 1619380SAndreas.Sandberg@ARM.com ccprintf(os, piFormats[size], "sp"); 1629380SAndreas.Sandberg@ARM.com break; 1639380SAndreas.Sandberg@ARM.com case INTREG_RBP: 1649380SAndreas.Sandberg@ARM.com ccprintf(os, piFormats[size], "bp"); 1659408Sandreas.hansson@arm.com break; 1669380SAndreas.Sandberg@ARM.com case INTREG_RSI: 1679380SAndreas.Sandberg@ARM.com ccprintf(os, piFormats[size], "si"); 1689380SAndreas.Sandberg@ARM.com break; 1699380SAndreas.Sandberg@ARM.com case INTREG_RDI: 1709380SAndreas.Sandberg@ARM.com ccprintf(os, piFormats[size], "di"); 1719380SAndreas.Sandberg@ARM.com break; 1729380SAndreas.Sandberg@ARM.com case INTREG_R8W: 1739380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "8"); 1749380SAndreas.Sandberg@ARM.com break; 1759380SAndreas.Sandberg@ARM.com case INTREG_R9W: 1769380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "9"); 1779380SAndreas.Sandberg@ARM.com break; 1789380SAndreas.Sandberg@ARM.com case INTREG_R10W: 1799380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "10"); 1809380SAndreas.Sandberg@ARM.com break; 1819380SAndreas.Sandberg@ARM.com case INTREG_R11W: 1829380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "11"); 1839380SAndreas.Sandberg@ARM.com break; 1849380SAndreas.Sandberg@ARM.com case INTREG_R12W: 1859380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "12"); 1869380SAndreas.Sandberg@ARM.com break; 1879380SAndreas.Sandberg@ARM.com case INTREG_R13W: 1889380SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "13"); 1899380SAndreas.Sandberg@ARM.com break; 1909380SAndreas.Sandberg@ARM.com case INTREG_R14W: 1919447SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "14"); 1929447SAndreas.Sandberg@ARM.com break; 1939447SAndreas.Sandberg@ARM.com case INTREG_R15W: 1949447SAndreas.Sandberg@ARM.com ccprintf(os, longFormats[size], "15"); 1959447SAndreas.Sandberg@ARM.com break; 1969447SAndreas.Sandberg@ARM.com default: 1979447SAndreas.Sandberg@ARM.com ccprintf(os, microFormats[size], rel_reg - NUM_INTREGS); 1989447SAndreas.Sandberg@ARM.com } 1999447SAndreas.Sandberg@ARM.com ccprintf(os, suffix); 2009447SAndreas.Sandberg@ARM.com break; 2019447SAndreas.Sandberg@ARM.com } 2029447SAndreas.Sandberg@ARM.com 2039447SAndreas.Sandberg@ARM.com case FloatRegClass: { 204 if (rel_reg < NumMMXRegs) { 205 ccprintf(os, "%%mmx%d", rel_reg); 206 return; 207 } 208 rel_reg -= NumMMXRegs; 209 if (rel_reg < NumXMMRegs * 2) { 210 ccprintf(os, "%%xmm%d_%s", rel_reg / 2, 211 (rel_reg % 2) ? "high": "low"); 212 return; 213 } 214 rel_reg -= NumXMMRegs * 2; 215 if (rel_reg < NumMicroFpRegs) { 216 ccprintf(os, "%%ufp%d", rel_reg); 217 return; 218 } 219 rel_reg -= NumMicroFpRegs; 220 ccprintf(os, "%%st(%d)", rel_reg); 221 break; 222 } 223 224 case CCRegClass: 225 ccprintf(os, "%%cc%d", rel_reg); 226 break; 227 228 case VectorRegClass: 229 ccprintf(os, "%%cc%d", rel_reg); 230 break; 231 232 case MiscRegClass: 233 switch (rel_reg) { 234 default: 235 ccprintf(os, "%%ctrl%d", rel_reg); 236 } 237 break; 238 239 default: 240 panic("Invalid register class!\n"); 241 } 242 } 243 244 void X86StaticInst::printMem(std::ostream &os, uint8_t segment, 245 uint8_t scale, RegIndex index, RegIndex base, 246 uint64_t disp, uint8_t addressSize, bool rip) const 247 { 248 bool someAddr = false; 249 printSegment(os, segment); 250 os << ":["; 251 if (rip) { 252 os << "rip"; 253 someAddr = true; 254 } else { 255 if (scale != 0 && index != ZeroReg) 256 { 257 if(scale != 1) 258 ccprintf(os, "%d*", scale); 259 printReg(os, index, addressSize); 260 someAddr = true; 261 } 262 if (base != ZeroReg) 263 { 264 if(someAddr) 265 os << " + "; 266 printReg(os, base, addressSize); 267 someAddr = true; 268 } 269 } 270 if (disp != 0) 271 { 272 if(someAddr) 273 os << " + "; 274 ccprintf(os, "%#x", disp); 275 someAddr = true; 276 } 277 if (!someAddr) 278 os << "0"; 279 os << "]"; 280 } 281 282 std::string X86StaticInst::generateDisassembly(Addr pc, 283 const SymbolTable *symtab) const 284 { 285 std::stringstream ss; 286 287 printMnemonic(ss, mnemonic); 288 289 return ss.str(); 290 } 291} 292