regop.isa revision 4519
1// Copyright (c) 2007 The Hewlett-Packard Development Company 2// All rights reserved. 3// 4// Redistribution and use of this software in source and binary forms, 5// with or without modification, are permitted provided that the 6// following conditions are met: 7// 8// The software must be used only for Non-Commercial Use which means any 9// use which is NOT directed to receiving any direct monetary 10// compensation for, or commercial advantage from such use. Illustrative 11// examples of non-commercial use are academic research, personal study, 12// teaching, education and corporate research & development. 13// Illustrative examples of commercial use are distributing products for 14// commercial advantage and providing services using the software for 15// commercial advantage. 16// 17// If you wish to use this software or functionality therein that may be 18// covered by patents for commercial use, please contact: 19// Director of Intellectual Property Licensing 20// Office of Strategy and Technology 21// Hewlett-Packard Company 22// 1501 Page Mill Road 23// Palo Alto, California 94304 24// 25// Redistributions of source code must retain the above copyright notice, 26// this list of conditions and the following disclaimer. Redistributions 27// in binary form must reproduce the above copyright notice, this list of 28// conditions and the following disclaimer in the documentation and/or 29// other materials provided with the distribution. Neither the name of 30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 31// contributors may be used to endorse or promote products derived from 32// this software without specific prior written permission. No right of 33// sublicense is granted herewith. Derivatives of the software and 34// output created using the software may be prepared, but only for 35// Non-Commercial Uses. Derivatives of the software may be shared with 36// others provided: (i) the others agree to abide by the list of 37// conditions herein which includes the Non-Commercial Use restrictions; 38// and (ii) such Derivatives of the software include the above copyright 39// notice to acknowledge the contribution from this software where 40// applicable, this list of conditions and the disclaimer below. 41// 42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53// 54// Authors: Gabe Black 55 56////////////////////////////////////////////////////////////////////////// 57// 58// RegOp Microop templates 59// 60////////////////////////////////////////////////////////////////////////// 61 62def template MicroRegOpExecute {{ 63 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 64 Trace::InstRecord *traceData) const 65 { 66 Fault fault = NoFault; 67 68 %(op_decl)s; 69 %(op_rd)s; 70 %(code)s; 71 72 //Write the resulting state to the execution context 73 if(fault == NoFault) 74 { 75 %(op_wb)s; 76 } 77 return fault; 78 } 79}}; 80 81def template MicroRegOpImmExecute {{ 82 Fault %(class_name)sImm::execute(%(CPU_exec_context)s *xc, 83 Trace::InstRecord *traceData) const 84 { 85 Fault fault = NoFault; 86 87 %(op_decl)s; 88 %(op_rd)s; 89 %(code)s; 90 91 //Write the resulting state to the execution context 92 if(fault == NoFault) 93 { 94 %(op_wb)s; 95 } 96 return fault; 97 } 98}}; 99 100def template MicroRegOpDeclare {{ 101 class %(class_name)s : public %(base_class)s 102 { 103 protected: 104 const RegIndex src1; 105 const RegIndex src2; 106 const RegIndex dest; 107 const bool setStatus; 108 const uint8_t dataSize; 109 const uint8_t ext; 110 void buildMe(); 111 112 public: 113 %(class_name)s(ExtMachInst _machInst, 114 const char * instMnem, 115 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 116 RegIndex _src1, RegIndex _src2, RegIndex _dest, 117 bool _setStatus, uint8_t _dataSize, uint8_t _ext); 118 119 %(class_name)s(ExtMachInst _machInst, 120 const char * instMnem, 121 RegIndex _src1, RegIndex _src2, RegIndex _dest, 122 bool _setStatus, uint8_t _dataSize, uint8_t _ext); 123 124 %(BasicExecDeclare)s 125 }; 126}}; 127 128def template MicroRegOpImmDeclare {{ 129 130 class %(class_name)sImm : public %(base_class)s 131 { 132 protected: 133 const RegIndex src1; 134 const uint8_t imm8; 135 const RegIndex dest; 136 const bool setStatus; 137 const uint8_t dataSize; 138 const uint8_t ext; 139 void buildMe(); 140 141 public: 142 %(class_name)sImm(ExtMachInst _machInst, 143 const char * instMnem, 144 bool isMicro, bool isDelayed, bool isFirst, bool isLast, 145 RegIndex _src1, uint8_t _imm8, RegIndex _dest, 146 bool _setStatus, uint8_t _dataSize, uint8_t _ext); 147 148 %(class_name)sImm(ExtMachInst _machInst, 149 const char * instMnem, 150 RegIndex _src1, uint8_t _imm8, RegIndex _dest, 151 bool _setStatus, uint8_t _dataSize, uint8_t _ext); 152 153 %(BasicExecDeclare)s 154 }; 155}}; 156 157def template MicroRegOpConstructor {{ 158 159 inline void %(class_name)s::buildMe() 160 { 161 %(constructor)s; 162 } 163 164 inline %(class_name)s::%(class_name)s( 165 ExtMachInst machInst, const char * instMnem, 166 RegIndex _src1, RegIndex _src2, RegIndex _dest, 167 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(object): 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(object): 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 defineMicroIntOp(mnemonic, code): 278 global header_output 279 global decoder_output 280 global exec_output 281 Name = mnemonic 282 name = mnemonic.lower() 283 284 # Find op2 in each of the instruction definitions. Create two versions 285 # of the code, one with an integer operand, and one with an immediate 286 # operand. 287 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?") 288 regCode = matcher.sub("SrcReg2", code) 289 immCode = matcher.sub("imm8", code) 290 291 # Build up the all register version of this micro op 292 iop = InstObjParams(name, Name, 'X86MicroOpBase', {"code" : regCode}) 293 header_output += MicroRegOpDeclare.subst(iop) 294 decoder_output += MicroRegOpConstructor.subst(iop) 295 exec_output += MicroRegOpExecute.subst(iop) 296 297 class RegOpChild(RegOp): 298 def __init__(self, dest, src1, src2): 299 super(RegOpChild, self).__init__(self, dest, src1, src2) 300 self.mnemonic = name 301 302 microopClasses[name] = RegOpChild 303 304 # Build up the immediate version of this micro op 305 iop = InstObjParams(name + "i", Name, 306 'X86MicroOpBase', {"code" : immCode}) 307 header_output += MicroRegOpImmDeclare.subst(iop) 308 decoder_output += MicroRegOpImmConstructor.subst(iop) 309 exec_output += MicroRegOpImmExecute.subst(iop) 310 311 class RegOpImmChild(RegOpImm): 312 def __init__(self, dest, src1, imm): 313 super(RegOpImmChild, self).__init__(self, dest, src1, imm) 314 self.mnemonic = name + "i" 315 316 microopClasses[name + "i"] = RegOpChild 317 318 defineMicroIntOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') #Needs to set OF,CF,SF 319 defineMicroIntOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') 320 defineMicroIntOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') #Needs to add in CF, set OF,CF,SF 321 defineMicroIntOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)') #Needs to subtract CF, set OF,CF,SF 322 defineMicroIntOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') 323 defineMicroIntOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)') #Needs to set OF,CF,SF 324 defineMicroIntOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') 325 defineMicroIntOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)') #Needs to set OF,CF,SF and not DestReg 326 defineMicroIntOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)') 327 328}}; 329