regop.isa revision 4528:f0b19ee67a7b
15659Sgblack@eecs.umich.edu// Copyright (c) 2007 The Hewlett-Packard Development Company 25659Sgblack@eecs.umich.edu// All rights reserved. 35659Sgblack@eecs.umich.edu// 45659Sgblack@eecs.umich.edu// Redistribution and use of this software in source and binary forms, 55659Sgblack@eecs.umich.edu// with or without modification, are permitted provided that the 65659Sgblack@eecs.umich.edu// following conditions are met: 75659Sgblack@eecs.umich.edu// 85659Sgblack@eecs.umich.edu// The software must be used only for Non-Commercial Use which means any 95659Sgblack@eecs.umich.edu// use which is NOT directed to receiving any direct monetary 105659Sgblack@eecs.umich.edu// compensation for, or commercial advantage from such use. Illustrative 115659Sgblack@eecs.umich.edu// examples of non-commercial use are academic research, personal study, 125659Sgblack@eecs.umich.edu// teaching, education and corporate research & development. 135659Sgblack@eecs.umich.edu// Illustrative examples of commercial use are distributing products for 145659Sgblack@eecs.umich.edu// commercial advantage and providing services using the software for 155659Sgblack@eecs.umich.edu// commercial advantage. 165659Sgblack@eecs.umich.edu// 175659Sgblack@eecs.umich.edu// If you wish to use this software or functionality therein that may be 185659Sgblack@eecs.umich.edu// covered by patents for commercial use, please contact: 195659Sgblack@eecs.umich.edu// Director of Intellectual Property Licensing 205659Sgblack@eecs.umich.edu// Office of Strategy and Technology 215659Sgblack@eecs.umich.edu// Hewlett-Packard Company 225659Sgblack@eecs.umich.edu// 1501 Page Mill Road 235659Sgblack@eecs.umich.edu// Palo Alto, California 94304 245659Sgblack@eecs.umich.edu// 255659Sgblack@eecs.umich.edu// Redistributions of source code must retain the above copyright notice, 265659Sgblack@eecs.umich.edu// this list of conditions and the following disclaimer. Redistributions 275659Sgblack@eecs.umich.edu// in binary form must reproduce the above copyright notice, this list of 285659Sgblack@eecs.umich.edu// conditions and the following disclaimer in the documentation and/or 295659Sgblack@eecs.umich.edu// other materials provided with the distribution. Neither the name of 305659Sgblack@eecs.umich.edu// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 315659Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 325659Sgblack@eecs.umich.edu// this software without specific prior written permission. No right of 335659Sgblack@eecs.umich.edu// sublicense is granted herewith. Derivatives of the software and 345659Sgblack@eecs.umich.edu// output created using the software may be prepared, but only for 355659Sgblack@eecs.umich.edu// Non-Commercial Uses. Derivatives of the software may be shared with 365659Sgblack@eecs.umich.edu// others provided: (i) the others agree to abide by the list of 375659Sgblack@eecs.umich.edu// conditions herein which includes the Non-Commercial Use restrictions; 385659Sgblack@eecs.umich.edu// and (ii) such Derivatives of the software include the above copyright 395659Sgblack@eecs.umich.edu// notice to acknowledge the contribution from this software where 405659Sgblack@eecs.umich.edu// applicable, this list of conditions and the disclaimer below. 415659Sgblack@eecs.umich.edu// 425659Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 435659Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 445659Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 455659Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 465659Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 475659Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 485659Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 495659Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 505659Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 515659Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 525659Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 535659Sgblack@eecs.umich.edu// 545659Sgblack@eecs.umich.edu// Authors: Gabe Black 555659Sgblack@eecs.umich.edu 565659Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////// 575659Sgblack@eecs.umich.edu// 585659Sgblack@eecs.umich.edu// RegOp Microop templates 595659Sgblack@eecs.umich.edu// 605659Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////// 615659Sgblack@eecs.umich.edu 625659Sgblack@eecs.umich.edudef template MicroRegOpExecute {{ 635659Sgblack@eecs.umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 645659Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 655659Sgblack@eecs.umich.edu { 666040Sgblack@eecs.umich.edu Fault fault = NoFault; 675659Sgblack@eecs.umich.edu 685659Sgblack@eecs.umich.edu %(op_decl)s; 695659Sgblack@eecs.umich.edu %(op_rd)s; 705659Sgblack@eecs.umich.edu %(code)s; 715659Sgblack@eecs.umich.edu 725659Sgblack@eecs.umich.edu //Write the resulting state to the execution context 735659Sgblack@eecs.umich.edu if(fault == NoFault) 745659Sgblack@eecs.umich.edu { 755659Sgblack@eecs.umich.edu %(op_wb)s; 765659Sgblack@eecs.umich.edu } 775659Sgblack@eecs.umich.edu return fault; 785659Sgblack@eecs.umich.edu } 795659Sgblack@eecs.umich.edu}}; 805659Sgblack@eecs.umich.edu 815659Sgblack@eecs.umich.edudef template MicroRegOpImmExecute {{ 827072Sgblack@eecs.umich.edu Fault %(class_name)sImm::execute(%(CPU_exec_context)s *xc, 837072Sgblack@eecs.umich.edu Trace::InstRecord *traceData) const 845659Sgblack@eecs.umich.edu { 855659Sgblack@eecs.umich.edu Fault fault = NoFault; 865659Sgblack@eecs.umich.edu 875659Sgblack@eecs.umich.edu %(op_decl)s; 885659Sgblack@eecs.umich.edu %(op_rd)s; 895659Sgblack@eecs.umich.edu %(code)s; 905659Sgblack@eecs.umich.edu 915659Sgblack@eecs.umich.edu //Write the resulting state to the execution context 925659Sgblack@eecs.umich.edu if(fault == NoFault) 936052Sgblack@eecs.umich.edu { 945659Sgblack@eecs.umich.edu %(op_wb)s; 955659Sgblack@eecs.umich.edu } 965659Sgblack@eecs.umich.edu return fault; 975659Sgblack@eecs.umich.edu } 985659Sgblack@eecs.umich.edu}}; 995659Sgblack@eecs.umich.edu 1005659Sgblack@eecs.umich.edudef template MicroRegOpDeclare {{ 1015659Sgblack@eecs.umich.edu class %(class_name)s : public %(base_class)s 1025659Sgblack@eecs.umich.edu { 1035659Sgblack@eecs.umich.edu protected: 1045659Sgblack@eecs.umich.edu const RegIndex src1; 1055659Sgblack@eecs.umich.edu const RegIndex src2; 1065659Sgblack@eecs.umich.edu const RegIndex dest; 1075659Sgblack@eecs.umich.edu const bool setStatus; 1085659Sgblack@eecs.umich.edu const uint8_t dataSize; 1095659Sgblack@eecs.umich.edu const uint8_t ext; 1105659Sgblack@eecs.umich.edu void buildMe(); 1115659Sgblack@eecs.umich.edu 1125659Sgblack@eecs.umich.edu public: 1135659Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 1145659Sgblack@eecs.umich.edu const char * instMnem, 1155659Sgblack@eecs.umich.edu bool isMicro, bool isDelayed, bool isFirst, bool isLast, 1165659Sgblack@eecs.umich.edu RegIndex _src1, RegIndex _src2, RegIndex _dest, 1176068Sgblack@eecs.umich.edu bool _setStatus, uint8_t _dataSize, uint8_t _ext); 1186068Sgblack@eecs.umich.edu 1195659Sgblack@eecs.umich.edu %(class_name)s(ExtMachInst _machInst, 1205659Sgblack@eecs.umich.edu const char * instMnem, 1215659Sgblack@eecs.umich.edu RegIndex _src1, RegIndex _src2, RegIndex _dest, 1225659Sgblack@eecs.umich.edu bool _setStatus, uint8_t _dataSize, uint8_t _ext); 1235659Sgblack@eecs.umich.edu 1245659Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1255659Sgblack@eecs.umich.edu }; 1265659Sgblack@eecs.umich.edu}}; 1275659Sgblack@eecs.umich.edu 1285659Sgblack@eecs.umich.edudef template MicroRegOpImmDeclare {{ 1295659Sgblack@eecs.umich.edu 1305659Sgblack@eecs.umich.edu class %(class_name)sImm : public %(base_class)s 1315659Sgblack@eecs.umich.edu { 1325659Sgblack@eecs.umich.edu protected: 1335659Sgblack@eecs.umich.edu const RegIndex src1; 1345659Sgblack@eecs.umich.edu const uint8_t imm8; 1355659Sgblack@eecs.umich.edu const RegIndex dest; 1365659Sgblack@eecs.umich.edu const bool setStatus; 1375659Sgblack@eecs.umich.edu const uint8_t dataSize; 1389124Snilay@cs.wisc.edu const uint8_t ext; 1395659Sgblack@eecs.umich.edu void buildMe(); 1405659Sgblack@eecs.umich.edu 1415659Sgblack@eecs.umich.edu public: 1425659Sgblack@eecs.umich.edu %(class_name)sImm(ExtMachInst _machInst, 1435659Sgblack@eecs.umich.edu const char * instMnem, 1445659Sgblack@eecs.umich.edu bool isMicro, bool isDelayed, bool isFirst, bool isLast, 1455659Sgblack@eecs.umich.edu RegIndex _src1, uint8_t _imm8, RegIndex _dest, 1465659Sgblack@eecs.umich.edu bool _setStatus, uint8_t _dataSize, uint8_t _ext); 1475659Sgblack@eecs.umich.edu 1485659Sgblack@eecs.umich.edu %(class_name)sImm(ExtMachInst _machInst, 1495659Sgblack@eecs.umich.edu const char * instMnem, 1505659Sgblack@eecs.umich.edu RegIndex _src1, uint8_t _imm8, RegIndex _dest, 1515659Sgblack@eecs.umich.edu bool _setStatus, uint8_t _dataSize, uint8_t _ext); 1525659Sgblack@eecs.umich.edu 1535659Sgblack@eecs.umich.edu %(BasicExecDeclare)s 1546052Sgblack@eecs.umich.edu }; 1555659Sgblack@eecs.umich.edu}}; 1565659Sgblack@eecs.umich.edu 1579124Snilay@cs.wisc.edudef template MicroRegOpConstructor {{ 1585659Sgblack@eecs.umich.edu 1595659Sgblack@eecs.umich.edu inline void %(class_name)s::buildMe() 1609124Snilay@cs.wisc.edu { 1619124Snilay@cs.wisc.edu %(constructor)s; 1629124Snilay@cs.wisc.edu } 1635659Sgblack@eecs.umich.edu 1649124Snilay@cs.wisc.edu inline %(class_name)s::%(class_name)s( 1655659Sgblack@eecs.umich.edu ExtMachInst machInst, const char * instMnem, 1665659Sgblack@eecs.umich.edu RegIndex _src1, RegIndex _src2, RegIndex _dest, 1677811Ssteve.reinhardt@amd.com bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 168 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 169 false, false, false, false, %(op_class)s), 170 src1(_src1), src2(_src2), dest(_dest), 171 setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 172 { 173 buildMe(); 174 } 175 176 inline %(class_name)s::%(class_name)s( 177 ExtMachInst machInst, const char * instMnem, 178 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 179 RegIndex _src1, RegIndex _src2, RegIndex _dest, 180 bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 181 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 182 isMicro, isDelayed, isFirst, isLast, %(op_class)s), 183 src1(_src1), src2(_src2), dest(_dest), 184 setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 185 { 186 buildMe(); 187 } 188}}; 189 190def template MicroRegOpImmConstructor {{ 191 192 inline void %(class_name)sImm::buildMe() 193 { 194 %(constructor)s; 195 } 196 197 inline %(class_name)sImm::%(class_name)sImm( 198 ExtMachInst machInst, const char * instMnem, 199 RegIndex _src1, uint8_t _imm8, RegIndex _dest, 200 bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 201 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 202 false, false, false, false, %(op_class)s), 203 src1(_src1), imm8(_imm8), dest(_dest), 204 setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 205 { 206 buildMe(); 207 } 208 209 inline %(class_name)sImm::%(class_name)sImm( 210 ExtMachInst machInst, const char * instMnem, 211 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 212 RegIndex _src1, uint8_t _imm8, RegIndex _dest, 213 bool _setStatus, uint8_t _dataSize, uint8_t _ext) : 214 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 215 isMicro, isDelayed, isFirst, isLast, %(op_class)s), 216 src1(_src1), imm8(_imm8), dest(_dest), 217 setStatus(_setStatus), dataSize(_dataSize), ext(_ext) 218 { 219 buildMe(); 220 } 221}}; 222 223let {{ 224 class RegOp(X86Microop): 225 def __init__(self, dest, src1, src2): 226 self.dest = dest 227 self.src1 = src1 228 self.src2 = src2 229 self.setStatus = False 230 self.dataSize = 1 231 self.ext = 0 232 233 def getAllocator(self, *microFlags): 234 allocator = '''new %(class_name)s(machInst, %(mnemonic)s, 235 %(flags)s %(src1)s, %(src2)s, %(dest)s, 236 %(setStatus)s, %(dataSize)s, %(ext)s)''' % { 237 "class_name" : self.className, 238 "mnemonic" : self.mnemonic, 239 "flags" : self.microFlagsText(microFlags), 240 "src1" : self.src1, "src2" : self.src2, 241 "dest" : self.dest, 242 "setStatus" : self.setStatus, 243 "dataSize" : self.dataSize, 244 "ext" : self.ext} 245 246 class RegOpImm(X86Microop): 247 def __init__(self, dest, src1, imm): 248 self.dest = dest 249 self.src1 = src1 250 self.imm = imm 251 self.setStatus = False 252 self.dataSize = 1 253 self.ext = 0 254 255 def getAllocator(self, *microFlags): 256 allocator = '''new %(class_name)s(machInst, %(mnemonic)s, 257 %(flags)s %(src1)s, %(imm8)s, %(dest)s, 258 %(setStatus)s, %(dataSize)s, %(ext)s)''' % { 259 "class_name" : self.className, 260 "mnemonic" : self.mnemonic, 261 "flags" : self.microFlagsText(microFlags), 262 "src1" : self.src1, "imm8" : self.imm8, 263 "dest" : self.dest, 264 "setStatus" : self.setStatus, 265 "dataSize" : self.dataSize, 266 "ext" : self.ext} 267}}; 268 269let {{ 270 271 # Make these empty strings so that concatenating onto 272 # them will always work. 273 header_output = "" 274 decoder_output = "" 275 exec_output = "" 276 277 def defineMicroRegOp(mnemonic, code): 278 global header_output 279 global decoder_output 280 global exec_output 281 global microopClasses 282 Name = mnemonic 283 name = mnemonic.lower() 284 285 # Find op2 in each of the instruction definitions. Create two versions 286 # of the code, one with an integer operand, and one with an immediate 287 # operand. 288 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 289 regCode = matcher.sub("SrcReg2", code) 290 immCode = matcher.sub("imm8", code) 291 292 # Build up the all register version of this micro op 293 iop = InstObjParams(name, Name, 'X86MicroOpBase', {"code" : regCode}) 294 header_output += MicroRegOpDeclare.subst(iop) 295 decoder_output += MicroRegOpConstructor.subst(iop) 296 exec_output += MicroRegOpExecute.subst(iop) 297 298 class RegOpChild(RegOp): 299 def __init__(self, dest, src1, src2): 300 super(RegOpChild, self).__init__(dest, src1, src2) 301 self.className = Name 302 self.mnemonic = name 303 304 microopClasses[name] = RegOpChild 305 306 # Build up the immediate version of this micro op 307 iop = InstObjParams(name + "i", Name, 308 'X86MicroOpBase', {"code" : immCode}) 309 header_output += MicroRegOpImmDeclare.subst(iop) 310 decoder_output += MicroRegOpImmConstructor.subst(iop) 311 exec_output += MicroRegOpImmExecute.subst(iop) 312 313 class RegOpImmChild(RegOpImm): 314 def __init__(self, dest, src1, imm): 315 super(RegOpImmChild, self).__init__(dest, src1, imm) 316 self.className = Name + "Imm" 317 self.mnemonic = name + "i" 318 319 microopClasses[name + "i"] = RegOpChild 320 321 defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') #Needs to set OF,CF,SF 322 defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') 323 defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') #Needs to add in CF, set OF,CF,SF 324 defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)') #Needs to subtract CF, set OF,CF,SF 325 defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') 326 defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)') #Needs to set OF,CF,SF 327 defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') 328 defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)') #Needs to set OF,CF,SF and not DestReg 329 defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)') 330 331}}; 332