1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 2// All rights reserved. 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Copyright (c) 2008 The Regents of The University of Michigan 14// All rights reserved. 15// 16// Redistribution and use in source and binary forms, with or without 17// modification, are permitted provided that the following conditions are 18// met: redistributions of source code must retain the above copyright 19// notice, this list of conditions and the following disclaimer; 20// redistributions in binary form must reproduce the above copyright 21// notice, this list of conditions and the following disclaimer in the 22// documentation and/or other materials provided with the distribution; 23// neither the name of the copyright holders nor the names of its 24// contributors may be used to endorse or promote products derived from 25// this software without specific prior written permission. 26// 27// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38// 39// Authors: Gabe Black 40 41////////////////////////////////////////////////////////////////////////// 42// 43// LdStOp Microop templates 44// 45////////////////////////////////////////////////////////////////////////// 46 47// LEA template 48 49def template MicroLeaExecute {{ 50 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 51 Trace::InstRecord *traceData) const 52 { 53 Fault fault = NoFault; 54 Addr EA; 55 56 %(op_decl)s; 57 %(op_rd)s; 58 %(ea_code)s; 59 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 60 61 %(code)s; 62 if(fault == NoFault) 63 { 64 %(op_wb)s; 65 } 66 67 return fault; 68 } 69}}; 70 71def template MicroLeaDeclare {{ 72 class %(class_name)s : public %(base_class)s 73 { 74 public: 75 %(class_name)s(ExtMachInst _machInst, 76 const char * instMnem, uint64_t setFlags, 77 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 78 uint64_t _disp, InstRegIndex _segment, 79 InstRegIndex _data, 80 uint8_t _dataSize, uint8_t _addressSize, 81 Request::FlagsType _memFlags); 82 83 %(BasicExecDeclare)s 84 }; 85}}; 86 87// Load templates 88 89def template MicroLoadExecute {{ 90 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 91 Trace::InstRecord *traceData) const 92 { 93 Fault fault = NoFault; 94 Addr EA; 95 96 %(op_decl)s; 97 %(op_rd)s; 98 %(ea_code)s; 99 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 100 101 fault = read(xc, EA, Mem, memFlags); 102 103 if (fault == NoFault) { 104 %(code)s; 105 } else if (memFlags & Request::PREFETCH) { 106 // For prefetches, ignore any faults/exceptions. 107 return NoFault; 108 } 109 if(fault == NoFault) 110 { 111 %(op_wb)s; 112 } 113 114 return fault; 115 } 116}}; 117 118def template MicroLoadInitiateAcc {{ 119 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 120 Trace::InstRecord * traceData) const 121 { 122 Fault fault = NoFault; 123 Addr EA; 124 125 %(op_decl)s; 126 %(op_rd)s; 127 %(ea_code)s; 128 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 129 130 fault = read(xc, EA, Mem, memFlags); 131 132 return fault; 133 } 134}}; 135 136def template MicroLoadCompleteAcc {{ 137 Fault %(class_name)s::completeAcc(PacketPtr pkt, 138 %(CPU_exec_context)s * xc, 139 Trace::InstRecord * traceData) const 140 { 141 Fault fault = NoFault; 142 143 %(op_decl)s; 144 %(op_rd)s; 145 146 Mem = get(pkt); 147 148 %(code)s; 149 150 if(fault == NoFault) 151 { 152 %(op_wb)s; 153 } 154 155 return fault; 156 } 157}}; 158 159// Store templates 160 161def template MicroStoreExecute {{ 162 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 163 Trace::InstRecord *traceData) const 164 { 165 Fault fault = NoFault; 166 167 Addr EA; 168 %(op_decl)s; 169 %(op_rd)s; 170 %(ea_code)s; 171 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 172 173 %(code)s; 174 175 if(fault == NoFault) 176 { 177 fault = write(xc, Mem, EA, memFlags); 178 if(fault == NoFault) 179 {
| 1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 2// All rights reserved. 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Copyright (c) 2008 The Regents of The University of Michigan 14// All rights reserved. 15// 16// Redistribution and use in source and binary forms, with or without 17// modification, are permitted provided that the following conditions are 18// met: redistributions of source code must retain the above copyright 19// notice, this list of conditions and the following disclaimer; 20// redistributions in binary form must reproduce the above copyright 21// notice, this list of conditions and the following disclaimer in the 22// documentation and/or other materials provided with the distribution; 23// neither the name of the copyright holders nor the names of its 24// contributors may be used to endorse or promote products derived from 25// this software without specific prior written permission. 26// 27// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 33// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 37// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38// 39// Authors: Gabe Black 40 41////////////////////////////////////////////////////////////////////////// 42// 43// LdStOp Microop templates 44// 45////////////////////////////////////////////////////////////////////////// 46 47// LEA template 48 49def template MicroLeaExecute {{ 50 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 51 Trace::InstRecord *traceData) const 52 { 53 Fault fault = NoFault; 54 Addr EA; 55 56 %(op_decl)s; 57 %(op_rd)s; 58 %(ea_code)s; 59 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 60 61 %(code)s; 62 if(fault == NoFault) 63 { 64 %(op_wb)s; 65 } 66 67 return fault; 68 } 69}}; 70 71def template MicroLeaDeclare {{ 72 class %(class_name)s : public %(base_class)s 73 { 74 public: 75 %(class_name)s(ExtMachInst _machInst, 76 const char * instMnem, uint64_t setFlags, 77 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 78 uint64_t _disp, InstRegIndex _segment, 79 InstRegIndex _data, 80 uint8_t _dataSize, uint8_t _addressSize, 81 Request::FlagsType _memFlags); 82 83 %(BasicExecDeclare)s 84 }; 85}}; 86 87// Load templates 88 89def template MicroLoadExecute {{ 90 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 91 Trace::InstRecord *traceData) const 92 { 93 Fault fault = NoFault; 94 Addr EA; 95 96 %(op_decl)s; 97 %(op_rd)s; 98 %(ea_code)s; 99 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 100 101 fault = read(xc, EA, Mem, memFlags); 102 103 if (fault == NoFault) { 104 %(code)s; 105 } else if (memFlags & Request::PREFETCH) { 106 // For prefetches, ignore any faults/exceptions. 107 return NoFault; 108 } 109 if(fault == NoFault) 110 { 111 %(op_wb)s; 112 } 113 114 return fault; 115 } 116}}; 117 118def template MicroLoadInitiateAcc {{ 119 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 120 Trace::InstRecord * traceData) const 121 { 122 Fault fault = NoFault; 123 Addr EA; 124 125 %(op_decl)s; 126 %(op_rd)s; 127 %(ea_code)s; 128 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 129 130 fault = read(xc, EA, Mem, memFlags); 131 132 return fault; 133 } 134}}; 135 136def template MicroLoadCompleteAcc {{ 137 Fault %(class_name)s::completeAcc(PacketPtr pkt, 138 %(CPU_exec_context)s * xc, 139 Trace::InstRecord * traceData) const 140 { 141 Fault fault = NoFault; 142 143 %(op_decl)s; 144 %(op_rd)s; 145 146 Mem = get(pkt); 147 148 %(code)s; 149 150 if(fault == NoFault) 151 { 152 %(op_wb)s; 153 } 154 155 return fault; 156 } 157}}; 158 159// Store templates 160 161def template MicroStoreExecute {{ 162 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 163 Trace::InstRecord *traceData) const 164 { 165 Fault fault = NoFault; 166 167 Addr EA; 168 %(op_decl)s; 169 %(op_rd)s; 170 %(ea_code)s; 171 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 172 173 %(code)s; 174 175 if(fault == NoFault) 176 { 177 fault = write(xc, Mem, EA, memFlags); 178 if(fault == NoFault) 179 {
|
181 %(op_wb)s; 182 } 183 } 184 185 return fault; 186 } 187}}; 188 189def template MicroStoreInitiateAcc {{ 190 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 191 Trace::InstRecord * traceData) const 192 { 193 Fault fault = NoFault; 194 195 Addr EA; 196 %(op_decl)s; 197 %(op_rd)s; 198 %(ea_code)s; 199 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 200 201 %(code)s; 202 203 if(fault == NoFault) 204 { 205 write(xc, Mem, EA, memFlags); 206 } 207 return fault; 208 } 209}}; 210 211def template MicroStoreCompleteAcc {{ 212 Fault %(class_name)s::completeAcc(PacketPtr pkt, 213 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 214 { 215 %(op_decl)s; 216 %(op_rd)s; 217 %(complete_code)s; 218 %(op_wb)s; 219 return NoFault; 220 } 221}}; 222 223// Common templates 224 225//This delcares the initiateAcc function in memory operations 226def template InitiateAccDeclare {{ 227 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 228}}; 229 230//This declares the completeAcc function in memory operations 231def template CompleteAccDeclare {{ 232 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 233}}; 234 235def template MicroLdStOpDeclare {{ 236 class %(class_name)s : public %(base_class)s 237 { 238 public: 239 %(class_name)s(ExtMachInst _machInst, 240 const char * instMnem, uint64_t setFlags, 241 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 242 uint64_t _disp, InstRegIndex _segment, 243 InstRegIndex _data, 244 uint8_t _dataSize, uint8_t _addressSize, 245 Request::FlagsType _memFlags); 246 247 %(BasicExecDeclare)s 248 249 %(InitiateAccDeclare)s 250 251 %(CompleteAccDeclare)s 252 }; 253}}; 254 255def template MicroLdStOpConstructor {{ 256 inline %(class_name)s::%(class_name)s( 257 ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 258 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 259 uint64_t _disp, InstRegIndex _segment, 260 InstRegIndex _data, 261 uint8_t _dataSize, uint8_t _addressSize, 262 Request::FlagsType _memFlags) : 263 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 264 _scale, _index, _base, 265 _disp, _segment, _data, 266 _dataSize, _addressSize, _memFlags, %(op_class)s) 267 { 268 %(constructor)s; 269 } 270}}; 271 272let {{ 273 class LdStOp(X86Microop): 274 def __init__(self, data, segment, addr, disp, 275 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 276 self.data = data 277 [self.scale, self.index, self.base] = addr 278 self.disp = disp 279 self.segment = segment 280 self.dataSize = dataSize 281 self.addressSize = addressSize 282 self.memFlags = baseFlags 283 if atCPL0: 284 self.memFlags += " | (CPL0FlagBit << FlagShift)" 285 self.instFlags = "" 286 if prefetch: 287 self.memFlags += " | Request::PREFETCH" 288 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 289 if nonSpec: 290 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 291 self.memFlags += " | (machInst.legacy.addr ? " + \ 292 "(AddrSizeFlagBit << FlagShift) : 0)" 293 294 def getAllocator(self, microFlags): 295 allocator = '''new %(class_name)s(machInst, macrocodeBlock, 296 %(flags)s, %(scale)s, %(index)s, %(base)s, 297 %(disp)s, %(segment)s, %(data)s, 298 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 299 "class_name" : self.className, 300 "flags" : self.microFlagsText(microFlags) + self.instFlags, 301 "scale" : self.scale, "index" : self.index, 302 "base" : self.base, 303 "disp" : self.disp, 304 "segment" : self.segment, "data" : self.data, 305 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 306 "memFlags" : self.memFlags} 307 return allocator 308 309 class BigLdStOp(X86Microop): 310 def __init__(self, data, segment, addr, disp, 311 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 312 self.data = data 313 [self.scale, self.index, self.base] = addr 314 self.disp = disp 315 self.segment = segment 316 self.dataSize = dataSize 317 self.addressSize = addressSize 318 self.memFlags = baseFlags 319 if atCPL0: 320 self.memFlags += " | (CPL0FlagBit << FlagShift)" 321 self.instFlags = "" 322 if prefetch: 323 self.memFlags += " | Request::PREFETCH" 324 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 325 if nonSpec: 326 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 327 self.memFlags += " | (machInst.legacy.addr ? " + \ 328 "(AddrSizeFlagBit << FlagShift) : 0)" 329 330 def getAllocator(self, microFlags): 331 allocString = ''' 332 (%(dataSize)s >= 4) ? 333 (StaticInstPtr)(new %(class_name)sBig(machInst, 334 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 335 %(base)s, %(disp)s, %(segment)s, %(data)s, 336 %(dataSize)s, %(addressSize)s, %(memFlags)s)) : 337 (StaticInstPtr)(new %(class_name)s(machInst, 338 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 339 %(base)s, %(disp)s, %(segment)s, %(data)s, 340 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 341 ''' 342 allocator = allocString % { 343 "class_name" : self.className, 344 "flags" : self.microFlagsText(microFlags) + self.instFlags, 345 "scale" : self.scale, "index" : self.index, 346 "base" : self.base, 347 "disp" : self.disp, 348 "segment" : self.segment, "data" : self.data, 349 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 350 "memFlags" : self.memFlags} 351 return allocator 352}}; 353 354let {{ 355 356 # Make these empty strings so that concatenating onto 357 # them will always work. 358 header_output = "" 359 decoder_output = "" 360 exec_output = "" 361 362 calculateEA = ''' 363 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); 364 ''' 365 366 def defineMicroLoadOp(mnemonic, code, bigCode='', 367 mem_flags="0", big=True): 368 global header_output 369 global decoder_output 370 global exec_output 371 global microopClasses 372 Name = mnemonic 373 name = mnemonic.lower() 374 375 # Build up the all register version of this micro op 376 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', 377 {"code": code, "ea_code": calculateEA})] 378 if big: 379 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', 380 {"code": bigCode, "ea_code": calculateEA})] 381 for iop in iops: 382 header_output += MicroLdStOpDeclare.subst(iop) 383 decoder_output += MicroLdStOpConstructor.subst(iop) 384 exec_output += MicroLoadExecute.subst(iop) 385 exec_output += MicroLoadInitiateAcc.subst(iop) 386 exec_output += MicroLoadCompleteAcc.subst(iop) 387 388 base = LdStOp 389 if big: 390 base = BigLdStOp 391 class LoadOp(base): 392 def __init__(self, data, segment, addr, disp = 0, 393 dataSize="env.dataSize", 394 addressSize="env.addressSize", 395 atCPL0=False, prefetch=False, nonSpec=False): 396 super(LoadOp, self).__init__(data, segment, addr, 397 disp, dataSize, addressSize, mem_flags, 398 atCPL0, prefetch, nonSpec) 399 self.className = Name 400 self.mnemonic = name 401 402 microopClasses[name] = LoadOp 403 404 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);', 405 'Data = Mem & mask(dataSize * 8);') 406 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 407 'Data = Mem & mask(dataSize * 8);', 408 '(StoreCheck << FlagShift)') 409 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 410 'Data = Mem & mask(dataSize * 8);', 411 '(StoreCheck << FlagShift) | Request::LOCKED') 412 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;', big = False) 413
| 180 %(op_wb)s; 181 } 182 } 183 184 return fault; 185 } 186}}; 187 188def template MicroStoreInitiateAcc {{ 189 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 190 Trace::InstRecord * traceData) const 191 { 192 Fault fault = NoFault; 193 194 Addr EA; 195 %(op_decl)s; 196 %(op_rd)s; 197 %(ea_code)s; 198 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 199 200 %(code)s; 201 202 if(fault == NoFault) 203 { 204 write(xc, Mem, EA, memFlags); 205 } 206 return fault; 207 } 208}}; 209 210def template MicroStoreCompleteAcc {{ 211 Fault %(class_name)s::completeAcc(PacketPtr pkt, 212 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 213 { 214 %(op_decl)s; 215 %(op_rd)s; 216 %(complete_code)s; 217 %(op_wb)s; 218 return NoFault; 219 } 220}}; 221 222// Common templates 223 224//This delcares the initiateAcc function in memory operations 225def template InitiateAccDeclare {{ 226 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 227}}; 228 229//This declares the completeAcc function in memory operations 230def template CompleteAccDeclare {{ 231 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 232}}; 233 234def template MicroLdStOpDeclare {{ 235 class %(class_name)s : public %(base_class)s 236 { 237 public: 238 %(class_name)s(ExtMachInst _machInst, 239 const char * instMnem, uint64_t setFlags, 240 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 241 uint64_t _disp, InstRegIndex _segment, 242 InstRegIndex _data, 243 uint8_t _dataSize, uint8_t _addressSize, 244 Request::FlagsType _memFlags); 245 246 %(BasicExecDeclare)s 247 248 %(InitiateAccDeclare)s 249 250 %(CompleteAccDeclare)s 251 }; 252}}; 253 254def template MicroLdStOpConstructor {{ 255 inline %(class_name)s::%(class_name)s( 256 ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 257 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 258 uint64_t _disp, InstRegIndex _segment, 259 InstRegIndex _data, 260 uint8_t _dataSize, uint8_t _addressSize, 261 Request::FlagsType _memFlags) : 262 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, 263 _scale, _index, _base, 264 _disp, _segment, _data, 265 _dataSize, _addressSize, _memFlags, %(op_class)s) 266 { 267 %(constructor)s; 268 } 269}}; 270 271let {{ 272 class LdStOp(X86Microop): 273 def __init__(self, data, segment, addr, disp, 274 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 275 self.data = data 276 [self.scale, self.index, self.base] = addr 277 self.disp = disp 278 self.segment = segment 279 self.dataSize = dataSize 280 self.addressSize = addressSize 281 self.memFlags = baseFlags 282 if atCPL0: 283 self.memFlags += " | (CPL0FlagBit << FlagShift)" 284 self.instFlags = "" 285 if prefetch: 286 self.memFlags += " | Request::PREFETCH" 287 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 288 if nonSpec: 289 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 290 self.memFlags += " | (machInst.legacy.addr ? " + \ 291 "(AddrSizeFlagBit << FlagShift) : 0)" 292 293 def getAllocator(self, microFlags): 294 allocator = '''new %(class_name)s(machInst, macrocodeBlock, 295 %(flags)s, %(scale)s, %(index)s, %(base)s, 296 %(disp)s, %(segment)s, %(data)s, 297 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 298 "class_name" : self.className, 299 "flags" : self.microFlagsText(microFlags) + self.instFlags, 300 "scale" : self.scale, "index" : self.index, 301 "base" : self.base, 302 "disp" : self.disp, 303 "segment" : self.segment, "data" : self.data, 304 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 305 "memFlags" : self.memFlags} 306 return allocator 307 308 class BigLdStOp(X86Microop): 309 def __init__(self, data, segment, addr, disp, 310 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec): 311 self.data = data 312 [self.scale, self.index, self.base] = addr 313 self.disp = disp 314 self.segment = segment 315 self.dataSize = dataSize 316 self.addressSize = addressSize 317 self.memFlags = baseFlags 318 if atCPL0: 319 self.memFlags += " | (CPL0FlagBit << FlagShift)" 320 self.instFlags = "" 321 if prefetch: 322 self.memFlags += " | Request::PREFETCH" 323 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)" 324 if nonSpec: 325 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)" 326 self.memFlags += " | (machInst.legacy.addr ? " + \ 327 "(AddrSizeFlagBit << FlagShift) : 0)" 328 329 def getAllocator(self, microFlags): 330 allocString = ''' 331 (%(dataSize)s >= 4) ? 332 (StaticInstPtr)(new %(class_name)sBig(machInst, 333 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 334 %(base)s, %(disp)s, %(segment)s, %(data)s, 335 %(dataSize)s, %(addressSize)s, %(memFlags)s)) : 336 (StaticInstPtr)(new %(class_name)s(machInst, 337 macrocodeBlock, %(flags)s, %(scale)s, %(index)s, 338 %(base)s, %(disp)s, %(segment)s, %(data)s, 339 %(dataSize)s, %(addressSize)s, %(memFlags)s)) 340 ''' 341 allocator = allocString % { 342 "class_name" : self.className, 343 "flags" : self.microFlagsText(microFlags) + self.instFlags, 344 "scale" : self.scale, "index" : self.index, 345 "base" : self.base, 346 "disp" : self.disp, 347 "segment" : self.segment, "data" : self.data, 348 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 349 "memFlags" : self.memFlags} 350 return allocator 351}}; 352 353let {{ 354 355 # Make these empty strings so that concatenating onto 356 # them will always work. 357 header_output = "" 358 decoder_output = "" 359 exec_output = "" 360 361 calculateEA = ''' 362 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); 363 ''' 364 365 def defineMicroLoadOp(mnemonic, code, bigCode='', 366 mem_flags="0", big=True): 367 global header_output 368 global decoder_output 369 global exec_output 370 global microopClasses 371 Name = mnemonic 372 name = mnemonic.lower() 373 374 # Build up the all register version of this micro op 375 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp', 376 {"code": code, "ea_code": calculateEA})] 377 if big: 378 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp', 379 {"code": bigCode, "ea_code": calculateEA})] 380 for iop in iops: 381 header_output += MicroLdStOpDeclare.subst(iop) 382 decoder_output += MicroLdStOpConstructor.subst(iop) 383 exec_output += MicroLoadExecute.subst(iop) 384 exec_output += MicroLoadInitiateAcc.subst(iop) 385 exec_output += MicroLoadCompleteAcc.subst(iop) 386 387 base = LdStOp 388 if big: 389 base = BigLdStOp 390 class LoadOp(base): 391 def __init__(self, data, segment, addr, disp = 0, 392 dataSize="env.dataSize", 393 addressSize="env.addressSize", 394 atCPL0=False, prefetch=False, nonSpec=False): 395 super(LoadOp, self).__init__(data, segment, addr, 396 disp, dataSize, addressSize, mem_flags, 397 atCPL0, prefetch, nonSpec) 398 self.className = Name 399 self.mnemonic = name 400 401 microopClasses[name] = LoadOp 402 403 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);', 404 'Data = Mem & mask(dataSize * 8);') 405 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 406 'Data = Mem & mask(dataSize * 8);', 407 '(StoreCheck << FlagShift)') 408 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 409 'Data = Mem & mask(dataSize * 8);', 410 '(StoreCheck << FlagShift) | Request::LOCKED') 411 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;', big = False) 412
|
427 "complete_code": completeCode, 428 "ea_code": calculateEA}) 429 header_output += MicroLdStOpDeclare.subst(iop) 430 decoder_output += MicroLdStOpConstructor.subst(iop) 431 exec_output += MicroStoreExecute.subst(iop) 432 exec_output += MicroStoreInitiateAcc.subst(iop) 433 exec_output += MicroStoreCompleteAcc.subst(iop) 434 435 class StoreOp(LdStOp): 436 def __init__(self, data, segment, addr, disp = 0, 437 dataSize="env.dataSize", 438 addressSize="env.addressSize", 439 atCPL0=False, nonSpec=False): 440 super(StoreOp, self).__init__(data, segment, addr, disp, 441 dataSize, addressSize, mem_flags, atCPL0, False, 442 nonSpec) 443 self.className = Name 444 self.mnemonic = name 445 446 microopClasses[name] = StoreOp 447 448 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 449 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 450 mem_flags="Request::LOCKED") 451 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 452 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 453 454 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 455 {"code": "Data = merge(Data, EA, dataSize);", 456 "ea_code": ''' 457 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 458 '''}) 459 header_output += MicroLeaDeclare.subst(iop) 460 decoder_output += MicroLdStOpConstructor.subst(iop) 461 exec_output += MicroLeaExecute.subst(iop) 462 463 class LeaOp(LdStOp): 464 def __init__(self, data, segment, addr, disp = 0, 465 dataSize="env.dataSize", addressSize="env.addressSize"): 466 super(LeaOp, self).__init__(data, segment, addr, disp, 467 dataSize, addressSize, "0", False, False, False) 468 self.className = "Lea" 469 self.mnemonic = "lea" 470 471 microopClasses["lea"] = LeaOp 472 473 474 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 475 {"code": "xc->demapPage(EA, 0);", 476 "ea_code": calculateEA}) 477 header_output += MicroLeaDeclare.subst(iop) 478 decoder_output += MicroLdStOpConstructor.subst(iop) 479 exec_output += MicroLeaExecute.subst(iop) 480 481 class TiaOp(LdStOp): 482 def __init__(self, segment, addr, disp = 0, 483 dataSize="env.dataSize", 484 addressSize="env.addressSize"): 485 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 486 addr, disp, dataSize, addressSize, "0", False, False, 487 False) 488 self.className = "Tia" 489 self.mnemonic = "tia" 490 491 microopClasses["tia"] = TiaOp 492 493 class CdaOp(LdStOp): 494 def __init__(self, segment, addr, disp = 0, 495 dataSize="env.dataSize", 496 addressSize="env.addressSize", atCPL0=False): 497 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 498 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 499 atCPL0, False, False) 500 self.className = "Cda" 501 self.mnemonic = "cda" 502 503 microopClasses["cda"] = CdaOp 504}}; 505
| 424 "complete_code": completeCode, 425 "ea_code": calculateEA}) 426 header_output += MicroLdStOpDeclare.subst(iop) 427 decoder_output += MicroLdStOpConstructor.subst(iop) 428 exec_output += MicroStoreExecute.subst(iop) 429 exec_output += MicroStoreInitiateAcc.subst(iop) 430 exec_output += MicroStoreCompleteAcc.subst(iop) 431 432 class StoreOp(LdStOp): 433 def __init__(self, data, segment, addr, disp = 0, 434 dataSize="env.dataSize", 435 addressSize="env.addressSize", 436 atCPL0=False, nonSpec=False): 437 super(StoreOp, self).__init__(data, segment, addr, disp, 438 dataSize, addressSize, mem_flags, atCPL0, False, 439 nonSpec) 440 self.className = Name 441 self.mnemonic = name 442 443 microopClasses[name] = StoreOp 444 445 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 446 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 447 mem_flags="Request::LOCKED") 448 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 449 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 450 451 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 452 {"code": "Data = merge(Data, EA, dataSize);", 453 "ea_code": ''' 454 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 455 '''}) 456 header_output += MicroLeaDeclare.subst(iop) 457 decoder_output += MicroLdStOpConstructor.subst(iop) 458 exec_output += MicroLeaExecute.subst(iop) 459 460 class LeaOp(LdStOp): 461 def __init__(self, data, segment, addr, disp = 0, 462 dataSize="env.dataSize", addressSize="env.addressSize"): 463 super(LeaOp, self).__init__(data, segment, addr, disp, 464 dataSize, addressSize, "0", False, False, False) 465 self.className = "Lea" 466 self.mnemonic = "lea" 467 468 microopClasses["lea"] = LeaOp 469 470 471 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 472 {"code": "xc->demapPage(EA, 0);", 473 "ea_code": calculateEA}) 474 header_output += MicroLeaDeclare.subst(iop) 475 decoder_output += MicroLdStOpConstructor.subst(iop) 476 exec_output += MicroLeaExecute.subst(iop) 477 478 class TiaOp(LdStOp): 479 def __init__(self, segment, addr, disp = 0, 480 dataSize="env.dataSize", 481 addressSize="env.addressSize"): 482 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 483 addr, disp, dataSize, addressSize, "0", False, False, 484 False) 485 self.className = "Tia" 486 self.mnemonic = "tia" 487 488 microopClasses["tia"] = TiaOp 489 490 class CdaOp(LdStOp): 491 def __init__(self, segment, addr, disp = 0, 492 dataSize="env.dataSize", 493 addressSize="env.addressSize", atCPL0=False): 494 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 495 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 496 atCPL0, False, False) 497 self.className = "Cda" 498 self.mnemonic = "cda" 499 500 microopClasses["cda"] = CdaOp 501}}; 502
|