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 protected: 75 void buildMe(); 76 77 public: 78 %(class_name)s(ExtMachInst _machInst,
| 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 protected: 75 void buildMe(); 76 77 public: 78 %(class_name)s(ExtMachInst _machInst,
|
79 const char * instMnem, 80 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
| 79 const char * instMnem, uint64_t setFlags,
|
81 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 82 uint64_t _disp, InstRegIndex _segment, 83 InstRegIndex _data, 84 uint8_t _dataSize, uint8_t _addressSize, 85 Request::FlagsType _memFlags); 86 87 %(class_name)s(ExtMachInst _machInst, 88 const char * instMnem, 89 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 90 uint64_t _disp, InstRegIndex _segment, 91 InstRegIndex _data, 92 uint8_t _dataSize, uint8_t _addressSize, 93 Request::FlagsType _memFlags); 94 95 %(BasicExecDeclare)s 96 }; 97}}; 98 99// Load templates 100 101def template MicroLoadExecute {{ 102 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 103 Trace::InstRecord *traceData) const 104 { 105 Fault fault = NoFault; 106 Addr EA; 107 108 %(op_decl)s; 109 %(op_rd)s; 110 %(ea_code)s; 111 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 112 113 fault = read(xc, EA, Mem, memFlags); 114 115 if (fault == NoFault) { 116 %(code)s; 117 } else if (memFlags & Request::PREFETCH) { 118 // For prefetches, ignore any faults/exceptions. 119 return NoFault; 120 } 121 if(fault == NoFault) 122 { 123 %(op_wb)s; 124 } 125 126 return fault; 127 } 128}}; 129 130def template MicroLoadInitiateAcc {{ 131 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 132 Trace::InstRecord * traceData) const 133 { 134 Fault fault = NoFault; 135 Addr EA; 136 137 %(op_decl)s; 138 %(op_rd)s; 139 %(ea_code)s; 140 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 141 142 fault = read(xc, EA, Mem, memFlags); 143 144 return fault; 145 } 146}}; 147 148def template MicroLoadCompleteAcc {{ 149 Fault %(class_name)s::completeAcc(PacketPtr pkt, 150 %(CPU_exec_context)s * xc, 151 Trace::InstRecord * traceData) const 152 { 153 Fault fault = NoFault; 154 155 %(op_decl)s; 156 %(op_rd)s; 157 158 Mem = get(pkt); 159 160 %(code)s; 161 162 if(fault == NoFault) 163 { 164 %(op_wb)s; 165 } 166 167 return fault; 168 } 169}}; 170 171// Store templates 172 173def template MicroStoreExecute {{ 174 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 175 Trace::InstRecord *traceData) const 176 { 177 Fault fault = NoFault; 178 179 Addr EA; 180 %(op_decl)s; 181 %(op_rd)s; 182 %(ea_code)s; 183 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 184 185 %(code)s; 186 187 if(fault == NoFault) 188 { 189 fault = write(xc, Mem, EA, memFlags); 190 if(fault == NoFault) 191 { 192 %(post_code)s; 193 %(op_wb)s; 194 } 195 } 196 197 return fault; 198 } 199}}; 200 201def template MicroStoreInitiateAcc {{ 202 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 203 Trace::InstRecord * traceData) const 204 { 205 Fault fault = NoFault; 206 207 Addr EA; 208 %(op_decl)s; 209 %(op_rd)s; 210 %(ea_code)s; 211 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 212 213 %(code)s; 214 215 if(fault == NoFault) 216 { 217 write(xc, Mem, EA, memFlags); 218 } 219 return fault; 220 } 221}}; 222 223def template MicroStoreCompleteAcc {{ 224 Fault %(class_name)s::completeAcc(PacketPtr pkt, 225 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 226 { 227 %(op_decl)s; 228 %(op_rd)s; 229 %(complete_code)s; 230 %(op_wb)s; 231 return NoFault; 232 } 233}}; 234 235// Common templates 236 237//This delcares the initiateAcc function in memory operations 238def template InitiateAccDeclare {{ 239 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 240}}; 241 242//This declares the completeAcc function in memory operations 243def template CompleteAccDeclare {{ 244 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 245}}; 246 247def template MicroLdStOpDeclare {{ 248 class %(class_name)s : public %(base_class)s 249 { 250 protected: 251 void buildMe(); 252 253 public: 254 %(class_name)s(ExtMachInst _machInst,
| 80 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 81 uint64_t _disp, InstRegIndex _segment, 82 InstRegIndex _data, 83 uint8_t _dataSize, uint8_t _addressSize, 84 Request::FlagsType _memFlags); 85 86 %(class_name)s(ExtMachInst _machInst, 87 const char * instMnem, 88 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 89 uint64_t _disp, InstRegIndex _segment, 90 InstRegIndex _data, 91 uint8_t _dataSize, uint8_t _addressSize, 92 Request::FlagsType _memFlags); 93 94 %(BasicExecDeclare)s 95 }; 96}}; 97 98// Load templates 99 100def template MicroLoadExecute {{ 101 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 102 Trace::InstRecord *traceData) const 103 { 104 Fault fault = NoFault; 105 Addr EA; 106 107 %(op_decl)s; 108 %(op_rd)s; 109 %(ea_code)s; 110 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 111 112 fault = read(xc, EA, Mem, memFlags); 113 114 if (fault == NoFault) { 115 %(code)s; 116 } else if (memFlags & Request::PREFETCH) { 117 // For prefetches, ignore any faults/exceptions. 118 return NoFault; 119 } 120 if(fault == NoFault) 121 { 122 %(op_wb)s; 123 } 124 125 return fault; 126 } 127}}; 128 129def template MicroLoadInitiateAcc {{ 130 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 131 Trace::InstRecord * traceData) const 132 { 133 Fault fault = NoFault; 134 Addr EA; 135 136 %(op_decl)s; 137 %(op_rd)s; 138 %(ea_code)s; 139 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 140 141 fault = read(xc, EA, Mem, memFlags); 142 143 return fault; 144 } 145}}; 146 147def template MicroLoadCompleteAcc {{ 148 Fault %(class_name)s::completeAcc(PacketPtr pkt, 149 %(CPU_exec_context)s * xc, 150 Trace::InstRecord * traceData) const 151 { 152 Fault fault = NoFault; 153 154 %(op_decl)s; 155 %(op_rd)s; 156 157 Mem = get(pkt); 158 159 %(code)s; 160 161 if(fault == NoFault) 162 { 163 %(op_wb)s; 164 } 165 166 return fault; 167 } 168}}; 169 170// Store templates 171 172def template MicroStoreExecute {{ 173 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc, 174 Trace::InstRecord *traceData) const 175 { 176 Fault fault = NoFault; 177 178 Addr EA; 179 %(op_decl)s; 180 %(op_rd)s; 181 %(ea_code)s; 182 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 183 184 %(code)s; 185 186 if(fault == NoFault) 187 { 188 fault = write(xc, Mem, EA, memFlags); 189 if(fault == NoFault) 190 { 191 %(post_code)s; 192 %(op_wb)s; 193 } 194 } 195 196 return fault; 197 } 198}}; 199 200def template MicroStoreInitiateAcc {{ 201 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 202 Trace::InstRecord * traceData) const 203 { 204 Fault fault = NoFault; 205 206 Addr EA; 207 %(op_decl)s; 208 %(op_rd)s; 209 %(ea_code)s; 210 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); 211 212 %(code)s; 213 214 if(fault == NoFault) 215 { 216 write(xc, Mem, EA, memFlags); 217 } 218 return fault; 219 } 220}}; 221 222def template MicroStoreCompleteAcc {{ 223 Fault %(class_name)s::completeAcc(PacketPtr pkt, 224 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const 225 { 226 %(op_decl)s; 227 %(op_rd)s; 228 %(complete_code)s; 229 %(op_wb)s; 230 return NoFault; 231 } 232}}; 233 234// Common templates 235 236//This delcares the initiateAcc function in memory operations 237def template InitiateAccDeclare {{ 238 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 239}}; 240 241//This declares the completeAcc function in memory operations 242def template CompleteAccDeclare {{ 243 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 244}}; 245 246def template MicroLdStOpDeclare {{ 247 class %(class_name)s : public %(base_class)s 248 { 249 protected: 250 void buildMe(); 251 252 public: 253 %(class_name)s(ExtMachInst _machInst,
|
255 const char * instMnem, 256 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
| 254 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 263 %(class_name)s(ExtMachInst _machInst, 264 const char * instMnem, 265 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 266 uint64_t _disp, InstRegIndex _segment, 267 InstRegIndex _data, 268 uint8_t _dataSize, uint8_t _addressSize, 269 Request::FlagsType _memFlags); 270 271 %(BasicExecDeclare)s 272 273 %(InitiateAccDeclare)s 274 275 %(CompleteAccDeclare)s 276 }; 277}}; 278 279def template MicroLdStOpConstructor {{ 280 281 inline void %(class_name)s::buildMe() 282 { 283 %(constructor)s; 284 } 285 286 inline %(class_name)s::%(class_name)s( 287 ExtMachInst machInst, const char * instMnem, 288 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 289 uint64_t _disp, InstRegIndex _segment, 290 InstRegIndex _data, 291 uint8_t _dataSize, uint8_t _addressSize, 292 Request::FlagsType _memFlags) :
| 255 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 256 uint64_t _disp, InstRegIndex _segment, 257 InstRegIndex _data, 258 uint8_t _dataSize, uint8_t _addressSize, 259 Request::FlagsType _memFlags); 260 261 %(class_name)s(ExtMachInst _machInst, 262 const char * instMnem, 263 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 264 uint64_t _disp, InstRegIndex _segment, 265 InstRegIndex _data, 266 uint8_t _dataSize, uint8_t _addressSize, 267 Request::FlagsType _memFlags); 268 269 %(BasicExecDeclare)s 270 271 %(InitiateAccDeclare)s 272 273 %(CompleteAccDeclare)s 274 }; 275}}; 276 277def template MicroLdStOpConstructor {{ 278 279 inline void %(class_name)s::buildMe() 280 { 281 %(constructor)s; 282 } 283 284 inline %(class_name)s::%(class_name)s( 285 ExtMachInst machInst, const char * instMnem, 286 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 287 uint64_t _disp, InstRegIndex _segment, 288 InstRegIndex _data, 289 uint8_t _dataSize, uint8_t _addressSize, 290 Request::FlagsType _memFlags) :
|
293 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 294 false, false, false, false,
| 291 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 0,
|
295 _scale, _index, _base, 296 _disp, _segment, _data, 297 _dataSize, _addressSize, _memFlags, %(op_class)s) 298 { 299 buildMe(); 300 } 301 302 inline %(class_name)s::%(class_name)s(
| 292 _scale, _index, _base, 293 _disp, _segment, _data, 294 _dataSize, _addressSize, _memFlags, %(op_class)s) 295 { 296 buildMe(); 297 } 298 299 inline %(class_name)s::%(class_name)s(
|
303 ExtMachInst machInst, const char * instMnem, 304 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
| 300 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
|
305 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 306 uint64_t _disp, InstRegIndex _segment, 307 InstRegIndex _data, 308 uint8_t _dataSize, uint8_t _addressSize, 309 Request::FlagsType _memFlags) :
| 301 uint8_t _scale, InstRegIndex _index, InstRegIndex _base, 302 uint64_t _disp, InstRegIndex _segment, 303 InstRegIndex _data, 304 uint8_t _dataSize, uint8_t _addressSize, 305 Request::FlagsType _memFlags) :
|
310 %(base_class)s(machInst, "%(mnemonic)s", instMnem, 311 isMicro, isDelayed, isFirst, isLast,
| 306 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
|
312 _scale, _index, _base, 313 _disp, _segment, _data, 314 _dataSize, _addressSize, _memFlags, %(op_class)s) 315 { 316 buildMe(); 317 } 318}}; 319 320let {{ 321 class LdStOp(X86Microop): 322 def __init__(self, data, segment, addr, disp, 323 dataSize, addressSize, baseFlags, atCPL0, prefetch): 324 self.data = data 325 [self.scale, self.index, self.base] = addr 326 self.disp = disp 327 self.segment = segment 328 self.dataSize = dataSize 329 self.addressSize = addressSize 330 self.memFlags = baseFlags 331 if atCPL0: 332 self.memFlags += " | (CPL0FlagBit << FlagShift)" 333 if prefetch: 334 self.memFlags += " | Request::PREFETCH" 335 self.memFlags += " | (machInst.legacy.addr ? " + \ 336 "(AddrSizeFlagBit << FlagShift) : 0)" 337
| 307 _scale, _index, _base, 308 _disp, _segment, _data, 309 _dataSize, _addressSize, _memFlags, %(op_class)s) 310 { 311 buildMe(); 312 } 313}}; 314 315let {{ 316 class LdStOp(X86Microop): 317 def __init__(self, data, segment, addr, disp, 318 dataSize, addressSize, baseFlags, atCPL0, prefetch): 319 self.data = data 320 [self.scale, self.index, self.base] = addr 321 self.disp = disp 322 self.segment = segment 323 self.dataSize = dataSize 324 self.addressSize = addressSize 325 self.memFlags = baseFlags 326 if atCPL0: 327 self.memFlags += " | (CPL0FlagBit << FlagShift)" 328 if prefetch: 329 self.memFlags += " | Request::PREFETCH" 330 self.memFlags += " | (machInst.legacy.addr ? " + \ 331 "(AddrSizeFlagBit << FlagShift) : 0)" 332
|
338 def getAllocator(self, *microFlags): 339 allocator = '''new %(class_name)s(machInst, macrocodeBlock
| 333 def getAllocator(self, microFlags): 334 allocator = '''new %(class_name)s(machInst, macrocodeBlock,
|
340 %(flags)s, %(scale)s, %(index)s, %(base)s, 341 %(disp)s, %(segment)s, %(data)s, 342 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 343 "class_name" : self.className, 344 "flags" : self.microFlagsText(microFlags), 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, mem_flags="0"): 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 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 376 {"code": code, 377 "ea_code": calculateEA}) 378 header_output += MicroLdStOpDeclare.subst(iop) 379 decoder_output += MicroLdStOpConstructor.subst(iop) 380 exec_output += MicroLoadExecute.subst(iop) 381 exec_output += MicroLoadInitiateAcc.subst(iop) 382 exec_output += MicroLoadCompleteAcc.subst(iop) 383 384 class LoadOp(LdStOp): 385 def __init__(self, data, segment, addr, disp = 0, 386 dataSize="env.dataSize", 387 addressSize="env.addressSize", 388 atCPL0=False, prefetch=False): 389 super(LoadOp, self).__init__(data, segment, addr, 390 disp, dataSize, addressSize, mem_flags, 391 atCPL0, prefetch) 392 self.className = Name 393 self.mnemonic = name 394 395 microopClasses[name] = LoadOp 396 397 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 398 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 399 '(StoreCheck << FlagShift)') 400 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 401 '(StoreCheck << FlagShift) | Request::LOCKED') 402 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') 403 404 def defineMicroStoreOp(mnemonic, code, \ 405 postCode="", completeCode="", mem_flags="0"): 406 global header_output 407 global decoder_output 408 global exec_output 409 global microopClasses 410 Name = mnemonic 411 name = mnemonic.lower() 412 413 # Build up the all register version of this micro op 414 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 415 {"code": code, 416 "post_code": postCode, 417 "complete_code": completeCode, 418 "ea_code": calculateEA}) 419 header_output += MicroLdStOpDeclare.subst(iop) 420 decoder_output += MicroLdStOpConstructor.subst(iop) 421 exec_output += MicroStoreExecute.subst(iop) 422 exec_output += MicroStoreInitiateAcc.subst(iop) 423 exec_output += MicroStoreCompleteAcc.subst(iop) 424 425 class StoreOp(LdStOp): 426 def __init__(self, data, segment, addr, disp = 0, 427 dataSize="env.dataSize", 428 addressSize="env.addressSize", 429 atCPL0=False): 430 super(StoreOp, self).__init__(data, segment, addr, 431 disp, dataSize, addressSize, mem_flags, atCPL0, False) 432 self.className = Name 433 self.mnemonic = name 434 435 microopClasses[name] = StoreOp 436 437 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 438 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 439 mem_flags="Request::LOCKED") 440 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 441 defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);', 442 'Base = merge(Base, EA - SegBase, addressSize);', 443 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); 444 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 445 446 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 447 {"code": "Data = merge(Data, EA, dataSize);", 448 "ea_code": ''' 449 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 450 '''}) 451 header_output += MicroLeaDeclare.subst(iop) 452 decoder_output += MicroLdStOpConstructor.subst(iop) 453 exec_output += MicroLeaExecute.subst(iop) 454 455 class LeaOp(LdStOp): 456 def __init__(self, data, segment, addr, disp = 0, 457 dataSize="env.dataSize", addressSize="env.addressSize"): 458 super(LeaOp, self).__init__(data, segment, 459 addr, disp, dataSize, addressSize, "0", False, False) 460 self.className = "Lea" 461 self.mnemonic = "lea" 462 463 microopClasses["lea"] = LeaOp 464 465 466 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 467 {"code": "xc->demapPage(EA, 0);", 468 "ea_code": calculateEA}) 469 header_output += MicroLeaDeclare.subst(iop) 470 decoder_output += MicroLdStOpConstructor.subst(iop) 471 exec_output += MicroLeaExecute.subst(iop) 472 473 class TiaOp(LdStOp): 474 def __init__(self, segment, addr, disp = 0, 475 dataSize="env.dataSize", 476 addressSize="env.addressSize"): 477 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 478 addr, disp, dataSize, addressSize, "0", False, False) 479 self.className = "Tia" 480 self.mnemonic = "tia" 481 482 microopClasses["tia"] = TiaOp 483 484 class CdaOp(LdStOp): 485 def __init__(self, segment, addr, disp = 0, 486 dataSize="env.dataSize", 487 addressSize="env.addressSize", atCPL0=False): 488 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 489 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 490 atCPL0, False) 491 self.className = "Cda" 492 self.mnemonic = "cda" 493 494 microopClasses["cda"] = CdaOp 495}}; 496
| 335 %(flags)s, %(scale)s, %(index)s, %(base)s, 336 %(disp)s, %(segment)s, %(data)s, 337 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { 338 "class_name" : self.className, 339 "flags" : self.microFlagsText(microFlags), 340 "scale" : self.scale, "index" : self.index, 341 "base" : self.base, 342 "disp" : self.disp, 343 "segment" : self.segment, "data" : self.data, 344 "dataSize" : self.dataSize, "addressSize" : self.addressSize, 345 "memFlags" : self.memFlags} 346 return allocator 347}}; 348 349let {{ 350 351 # Make these empty strings so that concatenating onto 352 # them will always work. 353 header_output = "" 354 decoder_output = "" 355 exec_output = "" 356 357 calculateEA = ''' 358 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); 359 ''' 360 361 def defineMicroLoadOp(mnemonic, code, mem_flags="0"): 362 global header_output 363 global decoder_output 364 global exec_output 365 global microopClasses 366 Name = mnemonic 367 name = mnemonic.lower() 368 369 # Build up the all register version of this micro op 370 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 371 {"code": code, 372 "ea_code": calculateEA}) 373 header_output += MicroLdStOpDeclare.subst(iop) 374 decoder_output += MicroLdStOpConstructor.subst(iop) 375 exec_output += MicroLoadExecute.subst(iop) 376 exec_output += MicroLoadInitiateAcc.subst(iop) 377 exec_output += MicroLoadCompleteAcc.subst(iop) 378 379 class LoadOp(LdStOp): 380 def __init__(self, data, segment, addr, disp = 0, 381 dataSize="env.dataSize", 382 addressSize="env.addressSize", 383 atCPL0=False, prefetch=False): 384 super(LoadOp, self).__init__(data, segment, addr, 385 disp, dataSize, addressSize, mem_flags, 386 atCPL0, prefetch) 387 self.className = Name 388 self.mnemonic = name 389 390 microopClasses[name] = LoadOp 391 392 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') 393 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 394 '(StoreCheck << FlagShift)') 395 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);', 396 '(StoreCheck << FlagShift) | Request::LOCKED') 397 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') 398 399 def defineMicroStoreOp(mnemonic, code, \ 400 postCode="", completeCode="", mem_flags="0"): 401 global header_output 402 global decoder_output 403 global exec_output 404 global microopClasses 405 Name = mnemonic 406 name = mnemonic.lower() 407 408 # Build up the all register version of this micro op 409 iop = InstObjParams(name, Name, 'X86ISA::LdStOp', 410 {"code": code, 411 "post_code": postCode, 412 "complete_code": completeCode, 413 "ea_code": calculateEA}) 414 header_output += MicroLdStOpDeclare.subst(iop) 415 decoder_output += MicroLdStOpConstructor.subst(iop) 416 exec_output += MicroStoreExecute.subst(iop) 417 exec_output += MicroStoreInitiateAcc.subst(iop) 418 exec_output += MicroStoreCompleteAcc.subst(iop) 419 420 class StoreOp(LdStOp): 421 def __init__(self, data, segment, addr, disp = 0, 422 dataSize="env.dataSize", 423 addressSize="env.addressSize", 424 atCPL0=False): 425 super(StoreOp, self).__init__(data, segment, addr, 426 disp, dataSize, addressSize, mem_flags, atCPL0, False) 427 self.className = Name 428 self.mnemonic = name 429 430 microopClasses[name] = StoreOp 431 432 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') 433 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);', 434 mem_flags="Request::LOCKED") 435 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') 436 defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);', 437 'Base = merge(Base, EA - SegBase, addressSize);', 438 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); 439 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") 440 441 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', 442 {"code": "Data = merge(Data, EA, dataSize);", 443 "ea_code": ''' 444 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0); 445 '''}) 446 header_output += MicroLeaDeclare.subst(iop) 447 decoder_output += MicroLdStOpConstructor.subst(iop) 448 exec_output += MicroLeaExecute.subst(iop) 449 450 class LeaOp(LdStOp): 451 def __init__(self, data, segment, addr, disp = 0, 452 dataSize="env.dataSize", addressSize="env.addressSize"): 453 super(LeaOp, self).__init__(data, segment, 454 addr, disp, dataSize, addressSize, "0", False, False) 455 self.className = "Lea" 456 self.mnemonic = "lea" 457 458 microopClasses["lea"] = LeaOp 459 460 461 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', 462 {"code": "xc->demapPage(EA, 0);", 463 "ea_code": calculateEA}) 464 header_output += MicroLeaDeclare.subst(iop) 465 decoder_output += MicroLdStOpConstructor.subst(iop) 466 exec_output += MicroLeaExecute.subst(iop) 467 468 class TiaOp(LdStOp): 469 def __init__(self, segment, addr, disp = 0, 470 dataSize="env.dataSize", 471 addressSize="env.addressSize"): 472 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 473 addr, disp, dataSize, addressSize, "0", False, False) 474 self.className = "Tia" 475 self.mnemonic = "tia" 476 477 microopClasses["tia"] = TiaOp 478 479 class CdaOp(LdStOp): 480 def __init__(self, segment, addr, disp = 0, 481 dataSize="env.dataSize", 482 addressSize="env.addressSize", atCPL0=False): 483 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, 484 addr, disp, dataSize, addressSize, "Request::NO_ACCESS", 485 atCPL0, False) 486 self.className = "Cda" 487 self.mnemonic = "cda" 488 489 microopClasses["cda"] = CdaOp 490}}; 491
|