mem.isa revision 6305
16145Snate@binkert.org// -*- mode:c++ -*- 26145Snate@binkert.org 36145Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University 46145Snate@binkert.org// All rights reserved. 56145Snate@binkert.org// 66145Snate@binkert.org// Redistribution and use in source and binary forms, with or without 76145Snate@binkert.org// modification, are permitted provided that the following conditions are 86145Snate@binkert.org// met: redistributions of source code must retain the above copyright 96145Snate@binkert.org// notice, this list of conditions and the following disclaimer; 106145Snate@binkert.org// redistributions in binary form must reproduce the above copyright 116145Snate@binkert.org// notice, this list of conditions and the following disclaimer in the 126145Snate@binkert.org// documentation and/or other materials provided with the distribution; 136145Snate@binkert.org// neither the name of the copyright holders nor the names of its 146145Snate@binkert.org// contributors may be used to endorse or promote products derived from 156145Snate@binkert.org// this software without specific prior written permission. 166145Snate@binkert.org// 176145Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145Snate@binkert.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145Snate@binkert.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145Snate@binkert.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145Snate@binkert.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145Snate@binkert.org// 296145Snate@binkert.org// Authors: Stephen Hines 306145Snate@binkert.org 316145Snate@binkert.org//////////////////////////////////////////////////////////////////// 326145Snate@binkert.org// 336145Snate@binkert.org// Memory-format instructions 346145Snate@binkert.org// 356145Snate@binkert.org 366145Snate@binkert.orgdef template LoadStoreDeclare {{ 376145Snate@binkert.org /** 386145Snate@binkert.org * Static instruction class for "%(mnemonic)s". 396145Snate@binkert.org */ 406145Snate@binkert.org class %(class_name)s : public %(base_class)s 416145Snate@binkert.org { 426145Snate@binkert.org public: 436145Snate@binkert.org 446145Snate@binkert.org /// Constructor. 456145Snate@binkert.org %(class_name)s(ExtMachInst machInst); 466145Snate@binkert.org 476145Snate@binkert.org %(BasicExecDeclare)s 486145Snate@binkert.org 496145Snate@binkert.org %(InitiateAccDeclare)s 506145Snate@binkert.org 516145Snate@binkert.org %(CompleteAccDeclare)s 526145Snate@binkert.org }; 536145Snate@binkert.org}}; 546145Snate@binkert.org 556145Snate@binkert.org 566145Snate@binkert.orgdef template InitiateAccDeclare {{ 576145Snate@binkert.org Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 586145Snate@binkert.org}}; 596145Snate@binkert.org 606145Snate@binkert.org 616145Snate@binkert.orgdef template CompleteAccDeclare {{ 626145Snate@binkert.org Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 636145Snate@binkert.org}}; 646145Snate@binkert.org 656145Snate@binkert.org 666145Snate@binkert.orgdef template LoadStoreConstructor {{ 676145Snate@binkert.org inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 686145Snate@binkert.org : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 696145Snate@binkert.org { 706145Snate@binkert.org %(constructor)s; 716145Snate@binkert.org } 726145Snate@binkert.org}}; 736145Snate@binkert.org 746145Snate@binkert.org 756145Snate@binkert.orgdef template LoadExecute {{ 766145Snate@binkert.org Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 776145Snate@binkert.org Trace::InstRecord *traceData) const 786145Snate@binkert.org { 796145Snate@binkert.org Addr EA; 806145Snate@binkert.org Fault fault = NoFault; 816145Snate@binkert.org 826145Snate@binkert.org %(op_decl)s; 836145Snate@binkert.org %(op_rd)s; 846145Snate@binkert.org %(ea_code)s; 856145Snate@binkert.org 866145Snate@binkert.org if (%(predicate_test)s) 876145Snate@binkert.org { 886145Snate@binkert.org if (fault == NoFault) { 896145Snate@binkert.org fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 906145Snate@binkert.org %(memacc_code)s; 916145Snate@binkert.org } 926145Snate@binkert.org 936145Snate@binkert.org if (fault == NoFault) { 946145Snate@binkert.org %(op_wb)s; 956145Snate@binkert.org } 966145Snate@binkert.org } 976145Snate@binkert.org 986145Snate@binkert.org return fault; 996145Snate@binkert.org } 1006145Snate@binkert.org}}; 1016145Snate@binkert.org 1026145Snate@binkert.org 1036145Snate@binkert.orgdef template LoadInitiateAcc {{ 1046145Snate@binkert.org Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 1056145Snate@binkert.org Trace::InstRecord *traceData) const 1066145Snate@binkert.org { 1076145Snate@binkert.org Addr EA; 1086145Snate@binkert.org Fault fault = NoFault; 1096145Snate@binkert.org 1106145Snate@binkert.org %(op_src_decl)s; 1116145Snate@binkert.org %(op_rd)s; 1126145Snate@binkert.org %(ea_code)s; 1136145Snate@binkert.org 1146145Snate@binkert.org if (%(predicate_test)s) 1156145Snate@binkert.org { 1166145Snate@binkert.org if (fault == NoFault) { 1176145Snate@binkert.org fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 1186145Snate@binkert.org } 1196145Snate@binkert.org } 1206145Snate@binkert.org 1216145Snate@binkert.org return fault; 1226145Snate@binkert.org } 1236145Snate@binkert.org}}; 1246145Snate@binkert.org 1256145Snate@binkert.org 1266145Snate@binkert.orgdef template LoadCompleteAcc {{ 1276145Snate@binkert.org Fault %(class_name)s::completeAcc(PacketPtr pkt, 1286145Snate@binkert.org %(CPU_exec_context)s *xc, 1296145Snate@binkert.org Trace::InstRecord *traceData) const 1306145Snate@binkert.org { 1316145Snate@binkert.org Fault fault = NoFault; 1326145Snate@binkert.org 1336145Snate@binkert.org %(op_decl)s; 1346145Snate@binkert.org %(op_rd)s; 1356145Snate@binkert.org 1366145Snate@binkert.org if (%(predicate_test)s) 1376145Snate@binkert.org { 1386145Snate@binkert.org // ARM instructions will not have a pkt if the predicate is false 1396145Snate@binkert.org Mem = pkt->get<typeof(Mem)>(); 1406145Snate@binkert.org 1416145Snate@binkert.org if (fault == NoFault) { 1426145Snate@binkert.org %(memacc_code)s; 1436145Snate@binkert.org } 1446145Snate@binkert.org 1456145Snate@binkert.org if (fault == NoFault) { 1466145Snate@binkert.org %(op_wb)s; 1476145Snate@binkert.org } 1486145Snate@binkert.org } 1496145Snate@binkert.org 1506145Snate@binkert.org return fault; 1516145Snate@binkert.org } 1526145Snate@binkert.org}}; 1536145Snate@binkert.org 1546145Snate@binkert.org 1556145Snate@binkert.orgdef template StoreExecute {{ 1566145Snate@binkert.org Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1576145Snate@binkert.org Trace::InstRecord *traceData) const 1586145Snate@binkert.org { 1596145Snate@binkert.org Addr EA; 1606145Snate@binkert.org Fault fault = NoFault; 1616145Snate@binkert.org 1626145Snate@binkert.org %(op_decl)s; 1636145Snate@binkert.org %(op_rd)s; 1646145Snate@binkert.org %(ea_code)s; 1656145Snate@binkert.org 1666145Snate@binkert.org if (%(predicate_test)s) 1676145Snate@binkert.org { 1686145Snate@binkert.org if (fault == NoFault) { 1696145Snate@binkert.org %(memacc_code)s; 1706145Snate@binkert.org } 1716145Snate@binkert.org 1726145Snate@binkert.org if (fault == NoFault) { 1736145Snate@binkert.org fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 1746145Snate@binkert.org memAccessFlags, NULL); 1756145Snate@binkert.org if (traceData) { traceData->setData(Mem); } 1766145Snate@binkert.org } 1776145Snate@binkert.org 1786145Snate@binkert.org if (fault == NoFault) { 1796145Snate@binkert.org %(op_wb)s; 1806145Snate@binkert.org } 1816145Snate@binkert.org } 1826145Snate@binkert.org 1836145Snate@binkert.org return fault; 1846145Snate@binkert.org } 1856145Snate@binkert.org}}; 1866145Snate@binkert.org 1876145Snate@binkert.orgdef template StoreInitiateAcc {{ 1886145Snate@binkert.org Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 1896145Snate@binkert.org Trace::InstRecord *traceData) const 1906145Snate@binkert.org { 1916145Snate@binkert.org Addr EA; 1926145Snate@binkert.org Fault fault = NoFault; 1936145Snate@binkert.org 1946145Snate@binkert.org %(op_decl)s; 1956145Snate@binkert.org %(op_rd)s; 1966145Snate@binkert.org %(ea_code)s; 1976145Snate@binkert.org 1986145Snate@binkert.org if (%(predicate_test)s) 1996145Snate@binkert.org { 2006145Snate@binkert.org if (fault == NoFault) { 2016145Snate@binkert.org %(memacc_code)s; 2026145Snate@binkert.org } 2036145Snate@binkert.org 2046145Snate@binkert.org if (fault == NoFault) { 2056145Snate@binkert.org fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 2066145Snate@binkert.org memAccessFlags, NULL); 2076145Snate@binkert.org if (traceData) { traceData->setData(Mem); } 2086145Snate@binkert.org } 2096145Snate@binkert.org 2106145Snate@binkert.org // Need to write back any potential address register update 2116145Snate@binkert.org if (fault == NoFault) { 2126145Snate@binkert.org %(op_wb)s; 2136145Snate@binkert.org } 2146145Snate@binkert.org } 2156145Snate@binkert.org 2166145Snate@binkert.org return fault; 2176145Snate@binkert.org } 2186145Snate@binkert.org}}; 2196145Snate@binkert.org 2206145Snate@binkert.org 2216145Snate@binkert.orgdef template StoreCompleteAcc {{ 2226145Snate@binkert.org Fault %(class_name)s::completeAcc(PacketPtr pkt, 2236145Snate@binkert.org %(CPU_exec_context)s *xc, 2246145Snate@binkert.org Trace::InstRecord *traceData) const 2256145Snate@binkert.org { 2266145Snate@binkert.org Fault fault = NoFault; 2276145Snate@binkert.org 2286145Snate@binkert.org %(op_decl)s; 2296145Snate@binkert.org %(op_rd)s; 2306145Snate@binkert.org 2316145Snate@binkert.org if (%(predicate_test)s) 2326145Snate@binkert.org { 2336145Snate@binkert.org if (fault == NoFault) { 2346145Snate@binkert.org %(op_wb)s; 2356145Snate@binkert.org } 2366145Snate@binkert.org } 2376145Snate@binkert.org 2386145Snate@binkert.org return fault; 2396145Snate@binkert.org } 2406145Snate@binkert.org}}; 2416145Snate@binkert.org 2426145Snate@binkert.orgdef template StoreCondCompleteAcc {{ 2436145Snate@binkert.org Fault %(class_name)s::completeAcc(PacketPtr pkt, 2446145Snate@binkert.org %(CPU_exec_context)s *xc, 2456145Snate@binkert.org Trace::InstRecord *traceData) const 2466145Snate@binkert.org { 2476145Snate@binkert.org Fault fault = NoFault; 2486145Snate@binkert.org 2496145Snate@binkert.org %(op_dest_decl)s; 2506145Snate@binkert.org 2516145Snate@binkert.org if (%(predicate_test)s) 2526145Snate@binkert.org { 2536145Snate@binkert.org if (fault == NoFault) { 2546145Snate@binkert.org %(op_wb)s; 2556145Snate@binkert.org } 2566145Snate@binkert.org } 2576145Snate@binkert.org 2586145Snate@binkert.org return fault; 2596145Snate@binkert.org } 2606145Snate@binkert.org}}; 2616145Snate@binkert.org 2626145Snate@binkert.orglet {{ 2636145Snate@binkert.org def buildPUBWLCase(p, u, b, w, l): 2646145Snate@binkert.org return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 2656145Snate@binkert.org 2666145Snate@binkert.org def buildMode2Inst(p, u, b, w, l, suffix, offset): 2676145Snate@binkert.org mnem = ("str", "ldr")[l] 2686145Snate@binkert.org op = ("-", "+")[u] 2696145Snate@binkert.org offset = op + ArmGenericCodeSubs(offset); 2706145Snate@binkert.org mem = ("Mem", "Mem.ub")[b] 2716145Snate@binkert.org code = ("%s = Rd;", "Rd = %s;")[l] % mem 2726145Snate@binkert.org ea_code = "EA = Rn %s;" % ("", offset)[p] 2736145Snate@binkert.org if p == 0 or w == 1: 2746145Snate@binkert.org code += "Rn = Rn %s;" % offset 2756145Snate@binkert.org if p == 0 and w == 0: 2766145Snate@binkert.org # Here's where we'll tack on a flag to make this a usermode access. 2776145Snate@binkert.org mnem += "t" 2786145Snate@binkert.org type = ("Store", "Load")[l] 2796145Snate@binkert.org suffix = "_%s_P%dU%dB%dW%d" % (suffix, p, u, b, w) 2806145Snate@binkert.org if b == 1: 2816145Snate@binkert.org mnem += "b" 2826145Snate@binkert.org return LoadStoreBase(mnem, mnem.capitalize() + suffix, 2836145Snate@binkert.org ea_code, code, mem_flags = [], inst_flags = [], 2846145Snate@binkert.org exec_template_base = type.capitalize()) 2856145Snate@binkert.org 2866145Snate@binkert.org def buildMode3Inst(p, u, i, w, type, code, mnem): 2876145Snate@binkert.org op = ("-", "+")[u] 2886145Snate@binkert.org offset = ("%s Rm", "%s hilo")[i] % op 2896145Snate@binkert.org ea_code = "EA = Rn %s;" % ("", offset)[p] 2906145Snate@binkert.org if p == 0 or w == 1: 2916145Snate@binkert.org code += "Rn = Rn %s;" % offset 2926145Snate@binkert.org suffix = "_P%dU%dI%dW%d" % (p, u, i, w) 2936145Snate@binkert.org return LoadStoreBase(mnem, mnem.capitalize() + suffix, 2946145Snate@binkert.org ea_code, code, mem_flags = [], inst_flags = [], 2956145Snate@binkert.org exec_template_base = type.capitalize()) 2966145Snate@binkert.org}}; 2976145Snate@binkert.org 2986145Snate@binkert.orgdef format AddrMode2(suffix, offset) {{ 2996145Snate@binkert.org header_output = decoder_output = exec_output = "" 3006145Snate@binkert.org decode_block = "switch(PUBWL) {\n" 3016145Snate@binkert.org 3026145Snate@binkert.org # Loop over all the values of p, u, b, w and l and build instructions and 3036145Snate@binkert.org # a decode block for them. 3046145Snate@binkert.org for p in (0, 1): 3056145Snate@binkert.org for u in (0, 1): 3066145Snate@binkert.org for b in (0, 1): 3076145Snate@binkert.org for w in (0, 1): 3086145Snate@binkert.org for l in (0, 1): 3096145Snate@binkert.org (new_header_output, 3106145Snate@binkert.org new_decoder_output, 311 new_decode_block, 312 new_exec_output) = buildMode2Inst(p, u, b, w, l, 313 suffix, offset) 314 header_output += new_header_output 315 decoder_output += new_decoder_output 316 exec_output += new_exec_output 317 decode_block += ''' 318 case %#x: 319 {%s} 320 break; 321 ''' % (buildPUBWLCase(p,u,b,w,l), new_decode_block) 322 decode_block += ''' 323 default: 324 return new Unknown(machInst); 325 break; 326 }''' 327}}; 328 329def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{ 330 l0Code = ArmGenericCodeSubs(l0Code); 331 l1Code = ArmGenericCodeSubs(l1Code); 332 333 header_output = decoder_output = exec_output = "" 334 decode_block = "switch(PUBWL) {\n" 335 (l0Mnem, l1Mnem) = name.split("_"); 336 337 # Loop over all the values of p, u, i, w and l and build instructions and 338 # a decode block for them. 339 for (l, type, code, mnem) in ((0, l0Type, l0Code, l0Mnem), 340 (1, l1Type, l1Code, l1Mnem)): 341 for p in (0, 1): 342 wset = (0, 1) 343 if (p == 0): 344 wset = (0,) 345 for u in (0, 1): 346 for i in (0, 1): 347 for w in wset: 348 (new_header_output, 349 new_decoder_output, 350 new_decode_block, 351 new_exec_output) = buildMode3Inst(p, u, i, w, 352 type, code, mnem) 353 header_output += new_header_output 354 decoder_output += new_decoder_output 355 exec_output += new_exec_output 356 decode_block += ''' 357 case %#x: 358 {%s} 359 break; 360 ''' % (buildPUBWLCase(p,u,i,w,l), new_decode_block) 361 362 decode_block += ''' 363 default: 364 return new Unknown(machInst); 365 break; 366 }''' 367}}; 368 369def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 370 mem_flags = [], inst_flags = []) {{ 371 ea_code = ArmGenericCodeSubs(ea_code) 372 memacc_code = ArmGenericCodeSubs(memacc_code) 373 (header_output, decoder_output, decode_block, exec_output) = \ 374 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 375 decode_template = BasicDecode, 376 exec_template_base = 'Load') 377}}; 378 379def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 380 mem_flags = [], inst_flags = []) {{ 381 ea_code = ArmGenericCodeSubs(ea_code) 382 memacc_code = ArmGenericCodeSubs(memacc_code) 383 (header_output, decoder_output, decode_block, exec_output) = \ 384 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 385 exec_template_base = 'Store') 386}}; 387 388