mem.isa revision 2132
16145SN/A// -*- mode:c++ -*- 28688SN/A 36145SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan 46145SN/A// All rights reserved. 56145SN/A// 66145SN/A// Redistribution and use in source and binary forms, with or without 76145SN/A// modification, are permitted provided that the following conditions are 86145SN/A// met: redistributions of source code must retain the above copyright 96145SN/A// notice, this list of conditions and the following disclaimer; 106145SN/A// redistributions in binary form must reproduce the above copyright 116145SN/A// notice, this list of conditions and the following disclaimer in the 126145SN/A// documentation and/or other materials provided with the distribution; 136145SN/A// neither the name of the copyright holders nor the names of its 146145SN/A// contributors may be used to endorse or promote products derived from 156145SN/A// this software without specific prior written permission. 166145SN/A// 176145SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145SN/A 296145SN/Aoutput header {{ 307039SN/A /** 317039SN/A * Base class for general Mips memory-format instructions. 327039SN/A */ 336145SN/A class Memory : public MipsStaticInst 346145SN/A { 3512492Sodanrc@yahoo.com.br protected: 3612492Sodanrc@yahoo.com.br 376145SN/A /// Memory request flags. See mem_req_base.hh. 387039SN/A unsigned memAccessFlags; 399350SN/A /// Pointer to EAComp object. 4011108Sdavid.hashe@amd.com const StaticInstPtr eaCompPtr; 4110301SN/A /// Pointer to MemAcc object. 4210301SN/A const StaticInstPtr memAccPtr; 4310301SN/A /// Displacement for EA calculation (signed). 447039SN/A int32_t disp; 459206SN/A 466145SN/A /// Constructor 477039SN/A Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 4810920SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 496285SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 509206SN/A : MipsStaticInst(mnem, _machInst, __opClass), 517039SN/A memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 527039SN/A disp(OFFSET) 536876SN/A { 546876SN/A } 557039SN/A 566145SN/A std::string 577039SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 587039SN/A 599504SN/A public: 609504SN/A 619504SN/A const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 6210837SN/A const StaticInstPtr &memAccInst() const { return memAccPtr; } 6310837SN/A }; 646285SN/A 6510525SN/A}}; 6610918SN/A 6711294Sandreas.hansson@arm.com 6810525SN/Aoutput decoder {{ 697039SN/A std::string 707039SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 717039SN/A { 727039SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 7310012SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 7410012SN/A } 757039SN/A 766285SN/A}}; 7711523Sdavid.guillen@arm.com 7811523Sdavid.guillen@arm.comdef format LoadAddress(code) {{ 7911523Sdavid.guillen@arm.com iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 8011523Sdavid.guillen@arm.com header_output = BasicDeclare.subst(iop) 8110012SN/A decoder_output = BasicConstructor.subst(iop) 8211169Sandreas.hansson@arm.com decode_block = BasicDecode.subst(iop) 836285SN/A exec_output = BasicExecute.subst(iop) 8411169Sandreas.hansson@arm.com}}; 8511168Sandreas.hansson@arm.com 8611168Sandreas.hansson@arm.com 8711168Sandreas.hansson@arm.comdef template LoadStoreDeclare {{ 888688SN/A /** 8911169Sandreas.hansson@arm.com * Static instruction class for "%(mnemonic)s". 909270SN/A */ 919270SN/A class %(class_name)s : public %(base_class)s 927562SN/A { 938436SN/A protected: 948436SN/A 958436SN/A /** 968937SN/A * "Fake" effective address computation class for "%(mnemonic)s". 978937SN/A */ 988937SN/A class EAComp : public %(base_class)s 9912133Sspwilson2@wisc.edu { 10012133Sspwilson2@wisc.edu public: 1018937SN/A /// Constructor 1028937SN/A EAComp(MachInst machInst); 1038937SN/A 1047039SN/A %(BasicExecDeclare)s 1057039SN/A }; 1067039SN/A 1077039SN/A /** 1086285SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 10910991SN/A */ 11011061SN/A class MemAcc : public %(base_class)s 11111061SN/A { 11210991SN/A public: 11311060SN/A /// Constructor 11411060SN/A MemAcc(MachInst machInst); 11511061SN/A 11611060SN/A %(BasicExecDeclare)s 11711061SN/A }; 1187039SN/A 11912133Sspwilson2@wisc.edu public: 1207039SN/A 1217039SN/A /// Constructor. 1227039SN/A %(class_name)s(MachInst machInst); 1239504SN/A 1249504SN/A %(BasicExecDeclare)s 1259504SN/A 12610919SN/A %(InitiateAccDeclare)s 12710837SN/A 12810837SN/A %(CompleteAccDeclare)s 12910837SN/A }; 13010525SN/A}}; 13110706SN/A 1327039SN/A 13310012SN/Adef template InitiateAccDeclare {{ 1349300SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 13510918SN/A}}; 1369103SN/A 1377039SN/A 13810012SN/Adef template CompleteAccDeclare {{ 1398688SN/A Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 14010920SN/A}}; 1416145SN/A 1426145SN/A 14310012SN/Adef template LoadStoreConstructor {{ 1446895SN/A /** TODO: change op_class to AddrGenOp or something (requires 1456895SN/A * creating new member of OpClass enum in op_class.hh, updating 14610919SN/A * config files, etc.). */ 1476895SN/A inline %(class_name)s::EAComp::EAComp(MachInst machInst) 1486895SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 14910012SN/A { 15010919SN/A %(ea_constructor)s; 15110919SN/A } 1526895SN/A 1536895SN/A inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) 15412492Sodanrc@yahoo.com.br : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 155 { 156 %(memacc_constructor)s; 157 } 158 159 inline %(class_name)s::%(class_name)s(MachInst machInst) 160 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 161 new EAComp(machInst), new MemAcc(machInst)) 162 { 163 %(constructor)s; 164 } 165}}; 166 167 168def template EACompExecute {{ 169 Fault 170 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 171 Trace::InstRecord *traceData) const 172 { 173 Addr EA; 174 Fault fault = NoFault; 175 176 %(fp_enable_check)s; 177 %(op_decl)s; 178 %(op_rd)s; 179 %(code)s; 180 181 if (fault == NoFault) { 182 %(op_wb)s; 183 xc->setEA(EA); 184 } 185 186 return fault; 187 } 188}}; 189 190def template LoadMemAccExecute {{ 191 Fault 192 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 193 Trace::InstRecord *traceData) const 194 { 195 Addr EA; 196 Fault fault = NoFault; 197 198 %(fp_enable_check)s; 199 %(op_decl)s; 200 %(op_rd)s; 201 EA = xc->getEA(); 202 203 if (fault == NoFault) { 204 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 205 %(code)s; 206 } 207 208 if (fault == NoFault) { 209 %(op_wb)s; 210 } 211 212 return fault; 213 } 214}}; 215 216 217def template LoadExecute {{ 218 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 219 Trace::InstRecord *traceData) const 220 { 221 Addr EA; 222 Fault fault = NoFault; 223 224 %(fp_enable_check)s; 225 %(op_decl)s; 226 %(op_rd)s; 227 %(ea_code)s; 228 229 if (fault == NoFault) { 230 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 231 %(memacc_code)s; 232 } 233 234 if (fault == NoFault) { 235 %(op_wb)s; 236 } 237 238 return fault; 239 } 240}}; 241 242 243def template LoadInitiateAcc {{ 244 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 245 Trace::InstRecord *traceData) const 246 { 247 Addr EA; 248 Fault fault = NoFault; 249 250 %(fp_enable_check)s; 251 %(op_src_decl)s; 252 %(op_rd)s; 253 %(ea_code)s; 254 255 if (fault == NoFault) { 256 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 257 } 258 259 return fault; 260 } 261}}; 262 263 264def template LoadCompleteAcc {{ 265 Fault %(class_name)s::completeAcc(uint8_t *data, 266 %(CPU_exec_context)s *xc, 267 Trace::InstRecord *traceData) const 268 { 269 Fault fault = NoFault; 270 271 %(fp_enable_check)s; 272 %(op_src_decl)s; 273 %(op_dest_decl)s; 274 275 memcpy(&Mem, data, sizeof(Mem)); 276 277 if (fault == NoFault) { 278 %(memacc_code)s; 279 } 280 281 if (fault == NoFault) { 282 %(op_wb)s; 283 } 284 285 return fault; 286 } 287}}; 288 289 290def template StoreMemAccExecute {{ 291 Fault 292 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 293 Trace::InstRecord *traceData) const 294 { 295 Addr EA; 296 Fault fault = NoFault; 297 uint64_t write_result = 0; 298 299 %(fp_enable_check)s; 300 %(op_decl)s; 301 %(op_rd)s; 302 EA = xc->getEA(); 303 304 if (fault == NoFault) { 305 %(code)s; 306 } 307 308 if (fault == NoFault) { 309 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 310 memAccessFlags, &write_result); 311 if (traceData) { traceData->setData(Mem); } 312 } 313 314 if (fault == NoFault) { 315 %(postacc_code)s; 316 } 317 318 if (fault == NoFault) { 319 %(op_wb)s; 320 } 321 322 return fault; 323 } 324}}; 325 326 327def template StoreExecute {{ 328 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 329 Trace::InstRecord *traceData) const 330 { 331 Addr EA; 332 Fault fault = NoFault; 333 uint64_t write_result = 0; 334 335 %(fp_enable_check)s; 336 %(op_decl)s; 337 %(op_rd)s; 338 %(ea_code)s; 339 340 if (fault == NoFault) { 341 %(memacc_code)s; 342 } 343 344 if (fault == NoFault) { 345 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 346 memAccessFlags, &write_result); 347 if (traceData) { traceData->setData(Mem); } 348 } 349 350 if (fault == NoFault) { 351 %(postacc_code)s; 352 } 353 354 if (fault == NoFault) { 355 %(op_wb)s; 356 } 357 358 return fault; 359 } 360}}; 361 362def template StoreInitiateAcc {{ 363 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 364 Trace::InstRecord *traceData) const 365 { 366 Addr EA; 367 Fault fault = NoFault; 368 uint64_t write_result = 0; 369 370 %(fp_enable_check)s; 371 %(op_src_decl)s; 372 %(op_dest_decl)s; 373 %(op_rd)s; 374 %(ea_code)s; 375 376 if (fault == NoFault) { 377 %(memacc_code)s; 378 } 379 380 if (fault == NoFault) { 381 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 382 memAccessFlags, &write_result); 383 if (traceData) { traceData->setData(Mem); } 384 } 385 386 return fault; 387 } 388}}; 389 390 391def template StoreCompleteAcc {{ 392 Fault %(class_name)s::completeAcc(uint8_t *data, 393 %(CPU_exec_context)s *xc, 394 Trace::InstRecord *traceData) const 395 { 396 Fault fault = NoFault; 397 uint64_t write_result = 0; 398 399 %(fp_enable_check)s; 400 %(op_dest_decl)s; 401 402 memcpy(&write_result, data, sizeof(write_result)); 403 404 if (fault == NoFault) { 405 %(postacc_code)s; 406 } 407 408 if (fault == NoFault) { 409 %(op_wb)s; 410 } 411 412 return fault; 413 } 414}}; 415 416// load instructions use Rt as dest, so check for 417// Rt == 31 to detect nops 418def template LoadNopCheckDecode {{ 419 { 420 MipsStaticInst *i = new %(class_name)s(machInst); 421 if (RT == 0) { 422 i = makeNop(i); 423 } 424 return i; 425 } 426}}; 427 428def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 429 mem_flags = [], inst_flags = []) {{ 430 (header_output, decoder_output, decode_block, exec_output) = \ 431 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 432 decode_template = LoadNopCheckDecode, 433 exec_template_base = 'Load') 434}}; 435 436 437def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 438 mem_flags = [], inst_flags = []) {{ 439 (header_output, decoder_output, decode_block, exec_output) = \ 440 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 441 exec_template_base = 'Store') 442}}; 443 444//FP loads are offloaded to these formats for now ... 445def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }}, 446 mem_flags = [], inst_flags = []) {{ 447 (header_output, decoder_output, decode_block, exec_output) = \ 448 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 449 decode_template = LoadNopCheckDecode, 450 exec_template_base = 'Load') 451}}; 452 453 454//FP stores are offloaded to these formats for now ... 455def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }}, 456 mem_flags = [], inst_flags = []) {{ 457 (header_output, decoder_output, decode_block, exec_output) = \ 458 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 459 decode_template = LoadNopCheckDecode, 460 exec_template_base = 'Store') 461}}; 462 463