pred_inst.hh revision 10537
12SN/A/* 21762SN/A * Copyright (c) 2010, 2012-2013 ARM Limited 35502Snate@binkert.org * All rights reserved 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2007-2008 The Florida State University 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272SN/A * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345501Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395502Snate@binkert.org * 405501Snate@binkert.org * Authors: Stephen Hines 415501Snate@binkert.org */ 421717SN/A#ifndef __ARCH_ARM_INSTS_PREDINST_HH__ 435501Snate@binkert.org#define __ARCH_ARM_INSTS_PREDINST_HH__ 4456SN/A 452SN/A#include "arch/arm/insts/static_inst.hh" 462SN/A#include "base/trace.hh" 472SN/A 482SN/Anamespace ArmISA 492SN/A{ 502SN/Astatic inline uint32_t 512SN/Arotate_imm(uint32_t immValue, uint32_t rotateValue) 522SN/A{ 532SN/A rotateValue &= 31; 545605Snate@binkert.org return rotateValue == 0 ? immValue : 552SN/A (immValue >> rotateValue) | (immValue << (32 - rotateValue)); 564017Sstever@eecs.umich.edu} 574016Sstever@eecs.umich.edu 584017Sstever@eecs.umich.edustatic inline uint32_t 594016Sstever@eecs.umich.edumodified_imm(uint8_t ctrlImm, uint8_t dataImm) 605602Snate@binkert.org{ 615602Snate@binkert.org uint32_t bigData = dataImm; 625502Snate@binkert.org uint32_t bigCtrl = ctrlImm; 635503Snate@binkert.org if (bigCtrl < 4) { 645502Snate@binkert.org switch (bigCtrl) { 655502Snate@binkert.org case 0: 665502Snate@binkert.org return bigData; 675502Snate@binkert.org case 1: 685502Snate@binkert.org return bigData | (bigData << 16); 695503Snate@binkert.org case 2: 705502Snate@binkert.org return (bigData << 8) | (bigData << 24); 715502Snate@binkert.org case 3: 725502Snate@binkert.org return (bigData << 0) | (bigData << 8) | 735502Snate@binkert.org (bigData << 16) | (bigData << 24); 745503Snate@binkert.org } 755503Snate@binkert.org } 765503Snate@binkert.org bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1); 775502Snate@binkert.org bigData |= (1 << 7); 785503Snate@binkert.org return bigData << (32 - bigCtrl); 795502Snate@binkert.org} 805502Snate@binkert.org 812SN/Astatic inline uint64_t 822SN/Asimd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid, 832SN/A bool isAarch64 = false) 845502Snate@binkert.org{ 855502Snate@binkert.org uint64_t bigData = data; 865602Snate@binkert.org immValid = true; 875502Snate@binkert.org switch (cmode) { 885502Snate@binkert.org case 0x0: 892SN/A case 0x1: 905502Snate@binkert.org bigData = (bigData << 0) | (bigData << 32); 915502Snate@binkert.org break; 925503Snate@binkert.org case 0x2: 935503Snate@binkert.org case 0x3: 945503Snate@binkert.org bigData = (bigData << 8) | (bigData << 40); 955503Snate@binkert.org break; 965503Snate@binkert.org case 0x4: 975502Snate@binkert.org case 0x5: 982SN/A bigData = (bigData << 16) | (bigData << 48); 995503Snate@binkert.org break; 1005503Snate@binkert.org case 0x6: 1015602Snate@binkert.org case 0x7: 1025502Snate@binkert.org bigData = (bigData << 24) | (bigData << 56); 1032SN/A break; 1045602Snate@binkert.org case 0x8: 1055602Snate@binkert.org case 0x9: 1065502Snate@binkert.org bigData = (bigData << 0) | (bigData << 16) | 1075503Snate@binkert.org (bigData << 32) | (bigData << 48); 1085503Snate@binkert.org break; 1095502Snate@binkert.org case 0xa: 1105503Snate@binkert.org case 0xb: 1115503Snate@binkert.org bigData = (bigData << 8) | (bigData << 24) | 1125503Snate@binkert.org (bigData << 40) | (bigData << 56); 1135503Snate@binkert.org break; 1145503Snate@binkert.org case 0xc: 1155503Snate@binkert.org bigData = (0xffULL << 0) | (bigData << 8) | 1165503Snate@binkert.org (0xffULL << 32) | (bigData << 40); 1175503Snate@binkert.org break; 1185503Snate@binkert.org case 0xd: 1195503Snate@binkert.org bigData = (0xffffULL << 0) | (bigData << 16) | 1205503Snate@binkert.org (0xffffULL << 32) | (bigData << 48); 1215503Snate@binkert.org break; 1225503Snate@binkert.org case 0xe: 1235503Snate@binkert.org if (op) { 1245502Snate@binkert.org bigData = 0; 1255502Snate@binkert.org for (int i = 7; i >= 0; i--) { 1265503Snate@binkert.org if (bits(data, i)) { 1275503Snate@binkert.org bigData |= (ULL(0xFF) << (i * 8)); 1282SN/A } 1295502Snate@binkert.org } 1305503Snate@binkert.org } else { 1315503Snate@binkert.org bigData = (bigData << 0) | (bigData << 8) | 1325503Snate@binkert.org (bigData << 16) | (bigData << 24) | 1332SN/A (bigData << 32) | (bigData << 40) | 1342SN/A (bigData << 48) | (bigData << 56); 1352SN/A } 1362SN/A break; 1372SN/A case 0xf: 1382SN/A { 1395502Snate@binkert.org uint64_t bVal = 0; 1402SN/A if (!op) { 1415502Snate@binkert.org bVal = bits(bigData, 6) ? (0x1F) : (0x20); 1425502Snate@binkert.org bigData = (bits(bigData, 5, 0) << 19) | 1435502Snate@binkert.org (bVal << 25) | (bits(bigData, 7) << 31); 1445602Snate@binkert.org bigData |= (bigData << 32); 1452SN/A break; 1462SN/A } else if (isAarch64) { 1472SN/A bVal = bits(bigData, 6) ? (0x0FF) : (0x100); 1485502Snate@binkert.org bigData = (bits(bigData, 5, 0) << 48) | 1492SN/A (bVal << 54) | (bits(bigData, 7) << 63); 1505502Snate@binkert.org break; 1515502Snate@binkert.org } 1522SN/A } 1535502Snate@binkert.org // Fall through, immediate encoding is invalid. 1542SN/A default: 1552SN/A immValid = false; 1565502Snate@binkert.org break; 1575502Snate@binkert.org } 1585502Snate@binkert.org return bigData; 1595503Snate@binkert.org} 1605503Snate@binkert.org 1615502Snate@binkert.orgstatic inline uint64_t 1625602Snate@binkert.orgvfp_modified_imm(uint8_t data, bool wide) 1632SN/A{ 1642SN/A uint64_t bigData = data; 1652667Sstever@eecs.umich.edu uint64_t repData; 1662SN/A if (wide) { 1672SN/A repData = bits(data, 6) ? 0xFF : 0; 1685503Snate@binkert.org bigData = (bits(bigData, 5, 0) << 48) | 1695503Snate@binkert.org (repData << 54) | (bits(~bigData, 6) << 62) | 1702SN/A (bits(bigData, 7) << 63); 1715502Snate@binkert.org } else { 1725503Snate@binkert.org repData = bits(data, 6) ? 0x1F : 0; 1735503Snate@binkert.org bigData = (bits(bigData, 5, 0) << 19) | 1745503Snate@binkert.org (repData << 25) | (bits(~bigData, 6) << 30) | 1755503Snate@binkert.org (bits(bigData, 7) << 31); 1765503Snate@binkert.org } 1775503Snate@binkert.org return bigData; 1785503Snate@binkert.org} 1795502Snate@binkert.org 1805502Snate@binkert.org 1815503Snate@binkert.org/** 1825502Snate@binkert.org * Base class for predicated integer operations. 1832SN/A */ 1842SN/Aclass PredOp : public ArmStaticInst 1852667Sstever@eecs.umich.edu{ 1862SN/A protected: 1872667Sstever@eecs.umich.edu 1882667Sstever@eecs.umich.edu ConditionCode condCode; 1892667Sstever@eecs.umich.edu 1902667Sstever@eecs.umich.edu /// Constructor 1912667Sstever@eecs.umich.edu PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 1922SN/A ArmStaticInst(mnem, _machInst, __opClass) 1932667Sstever@eecs.umich.edu { 1942SN/A if (machInst.aarch64) 195294SN/A condCode = COND_UC; 1962SN/A else if (machInst.itstateMask) 1972667Sstever@eecs.umich.edu condCode = (ConditionCode)(uint8_t)machInst.itstateCond; 1982667Sstever@eecs.umich.edu else 1992SN/A condCode = (ConditionCode)(unsigned)machInst.condCode; 2002SN/A } 201224SN/A}; 202224SN/A 203224SN/A/** 204224SN/A * Base class for predicated immediate operations. 205224SN/A */ 206224SN/Aclass PredImmOp : public PredOp 207224SN/A{ 208224SN/A protected: 209224SN/A 210237SN/A uint32_t imm; 211224SN/A uint32_t rotated_imm; 2125695Snate@binkert.org uint32_t rotated_carry; 2135695Snate@binkert.org uint32_t rotate; 214224SN/A 215224SN/A /// Constructor 216224SN/A PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 217224SN/A PredOp(mnem, _machInst, __opClass), 218224SN/A imm(machInst.imm), rotated_imm(0), rotated_carry(0), 219224SN/A rotate(machInst.rotate << 1) 220224SN/A { 221224SN/A rotated_imm = rotate_imm(imm, rotate); 222224SN/A if (rotate != 0) 223224SN/A rotated_carry = bits(rotated_imm, 31); 224224SN/A } 225224SN/A 226224SN/A std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 2275695Snate@binkert.org}; 228224SN/A 229224SN/A/** 230224SN/A * Base class for predicated integer operations. 2312SN/A */ 232217SN/Aclass PredIntOp : public PredOp 2332SN/A{ 234265SN/A protected: 235237SN/A 236237SN/A uint32_t shift_size; 2375502Snate@binkert.org uint32_t shift; 2385502Snate@binkert.org 2395503Snate@binkert.org /// Constructor 2405502Snate@binkert.org PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 2415503Snate@binkert.org PredOp(mnem, _machInst, __opClass), 2425502Snate@binkert.org shift_size(machInst.shiftSize), shift(machInst.shift) 2435502Snate@binkert.org { 2445502Snate@binkert.org } 2455502Snate@binkert.org 2465502Snate@binkert.org std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 2475502Snate@binkert.org}; 2485503Snate@binkert.org 2495502Snate@binkert.orgclass DataImmOp : public PredOp 2505502Snate@binkert.org{ 2512SN/A protected: 252237SN/A IntRegIndex dest, op1; 253265SN/A uint32_t imm; 254265SN/A // Whether the carry flag should be modified if that's an option for 2555502Snate@binkert.org // this instruction. 256265SN/A bool rotC; 257265SN/A 258265SN/A DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 259265SN/A IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) : 2602SN/A PredOp(mnem, _machInst, __opClass), 2612SN/A dest(_dest), op1(_op1), imm(_imm), rotC(_rotC) 262237SN/A {} 263237SN/A 264237SN/A std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 265265SN/A}; 266265SN/A 267265SN/Aclass DataRegOp : public PredOp 268270SN/A{ 269265SN/A protected: 270265SN/A IntRegIndex dest, op1, op2; 271270SN/A int32_t shiftAmt; 272265SN/A ArmShiftType shiftType; 273265SN/A 274395SN/A DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 275237SN/A IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 276237SN/A int32_t _shiftAmt, ArmShiftType _shiftType) : 277237SN/A PredOp(mnem, _machInst, __opClass), 2782SN/A dest(_dest), op1(_op1), op2(_op2), 2795501Snate@binkert.org shiftAmt(_shiftAmt), shiftType(_shiftType) 2802SN/A {} 2812SN/A 2822SN/A std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 2832SN/A}; 2842SN/A 2852SN/Aclass DataRegRegOp : public PredOp 2862SN/A{ 2872SN/A protected: 2885502Snate@binkert.org IntRegIndex dest, op1, op2, shift; 2895502Snate@binkert.org ArmShiftType shiftType; 2905502Snate@binkert.org 2915503Snate@binkert.org DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 2925503Snate@binkert.org IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 2935502Snate@binkert.org IntRegIndex _shift, ArmShiftType _shiftType) : 2945503Snate@binkert.org PredOp(mnem, _machInst, __opClass), 2955502Snate@binkert.org dest(_dest), op1(_op1), op2(_op2), shift(_shift), 2965502Snate@binkert.org shiftType(_shiftType) 2972SN/A {} 2982SN/A 2992SN/A std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 3002SN/A}; 3012SN/A 3022SN/A/** 3035502Snate@binkert.org * Base class for predicated macro-operations. 3045502Snate@binkert.org */ 3055502Snate@binkert.orgclass PredMacroOp : public PredOp 3065502Snate@binkert.org{ 3075502Snate@binkert.org protected: 3085502Snate@binkert.org 3095502Snate@binkert.org uint32_t numMicroops; 3105502Snate@binkert.org StaticInstPtr * microOps; 3115502Snate@binkert.org 3125502Snate@binkert.org /// Constructor 3135503Snate@binkert.org PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 3145503Snate@binkert.org PredOp(mnem, _machInst, __opClass), 3155502Snate@binkert.org numMicroops(0), microOps(nullptr) 3165502Snate@binkert.org { 3175502Snate@binkert.org // We rely on the subclasses of this object to handle the 3185502Snate@binkert.org // initialization of the micro-operations, since they are 3195502Snate@binkert.org // all of variable length 3205502Snate@binkert.org flags[IsMacroop] = true; 3215502Snate@binkert.org } 3225502Snate@binkert.org 3235502Snate@binkert.org ~PredMacroOp() 3245502Snate@binkert.org { 3255502Snate@binkert.org if (numMicroops) 3265502Snate@binkert.org delete [] microOps; 3275502Snate@binkert.org } 3285502Snate@binkert.org 3295502Snate@binkert.org StaticInstPtr 3305502Snate@binkert.org fetchMicroop(MicroPC microPC) const 3315502Snate@binkert.org { 3325502Snate@binkert.org assert(microPC < numMicroops); 3335502Snate@binkert.org return microOps[microPC]; 3345502Snate@binkert.org } 3355502Snate@binkert.org 3365502Snate@binkert.org std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 3375503Snate@binkert.org}; 3385502Snate@binkert.org 3395502Snate@binkert.org/** 3405502Snate@binkert.org * Base class for predicated micro-operations. 3415502Snate@binkert.org */ 3425502Snate@binkert.orgclass PredMicroop : public PredOp 3435502Snate@binkert.org{ 3445502Snate@binkert.org /// Constructor 3451019SN/A PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 3461019SN/A PredOp(mnem, _machInst, __opClass) 3471019SN/A { 3481019SN/A flags[IsMicroop] = true; 3491019SN/A } 3501019SN/A 3512SN/A void 3522SN/A advancePC(PCState &pcState) const 3535336Shines@cs.fsu.edu { 3542SN/A if (flags[IsLastMicroop]) 3552SN/A pcState.uEnd(); 3562SN/A else 3572SN/A pcState.uAdvance(); 3582SN/A } 3592SN/A}; 3602SN/A} 3612SN/A 3622SN/A#endif //__ARCH_ARM_INSTS_PREDINST_HH__ 3632SN/A