blockmem.isa revision 12294:650a9d8b23cc
1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29 30//////////////////////////////////////////////////////////////////// 31// 32// Block Memory instructions 33// 34 35def template BlockMemDeclare {{ 36 /** 37 * Static instruction class for a block memory operation 38 */ 39 class %(class_name)s : public %(base_class)s 40 { 41 public: 42 // Constructor 43 %(class_name)s(ExtMachInst machInst); 44 45 protected: 46 class %(class_name)s_0 : public %(base_class)sMicro 47 { 48 public: 49 // Constructor 50 %(class_name)s_0(ExtMachInst machInst); 51 Fault execute(ExecContext *, Trace::InstRecord *) const; 52 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 53 Fault completeAcc(PacketPtr, ExecContext *, 54 Trace::InstRecord *) const; 55 }; 56 57 class %(class_name)s_1 : public %(base_class)sMicro 58 { 59 public: 60 // Constructor 61 %(class_name)s_1(ExtMachInst machInst); 62 Fault execute(ExecContext *, Trace::InstRecord *) const; 63 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 64 Fault completeAcc(PacketPtr, ExecContext *, 65 Trace::InstRecord *) const; 66 }; 67 68 class %(class_name)s_2 : public %(base_class)sMicro 69 { 70 public: 71 // Constructor 72 %(class_name)s_2(ExtMachInst machInst); 73 Fault execute(ExecContext *, Trace::InstRecord *) const; 74 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 75 Fault completeAcc(PacketPtr, ExecContext *, 76 Trace::InstRecord *) const; 77 }; 78 79 class %(class_name)s_3 : public %(base_class)sMicro 80 { 81 public: 82 // Constructor 83 %(class_name)s_3(ExtMachInst machInst); 84 Fault execute(ExecContext *, Trace::InstRecord *) const; 85 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 86 Fault completeAcc(PacketPtr, ExecContext *, 87 Trace::InstRecord *) const; 88 }; 89 90 class %(class_name)s_4 : public %(base_class)sMicro 91 { 92 public: 93 // Constructor 94 %(class_name)s_4(ExtMachInst machInst); 95 Fault execute(ExecContext *, Trace::InstRecord *) const; 96 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 97 Fault completeAcc(PacketPtr, ExecContext *, 98 Trace::InstRecord *) const; 99 }; 100 101 class %(class_name)s_5 : public %(base_class)sMicro 102 { 103 public: 104 // Constructor 105 %(class_name)s_5(ExtMachInst machInst); 106 Fault execute(ExecContext *, Trace::InstRecord *) const; 107 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 108 Fault completeAcc(PacketPtr, ExecContext *, 109 Trace::InstRecord *) const; 110 }; 111 112 class %(class_name)s_6 : public %(base_class)sMicro 113 { 114 public: 115 // Constructor 116 %(class_name)s_6(ExtMachInst machInst); 117 Fault execute(ExecContext *, Trace::InstRecord *) const; 118 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 119 Fault completeAcc(PacketPtr, ExecContext *, 120 Trace::InstRecord *) const; 121 }; 122 123 class %(class_name)s_7 : public %(base_class)sMicro 124 { 125 public: 126 // Constructor 127 %(class_name)s_7(ExtMachInst machInst); 128 Fault execute(ExecContext *, Trace::InstRecord *) const; 129 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 130 Fault completeAcc(PacketPtr, ExecContext *, 131 Trace::InstRecord *) const; 132 }; 133 }; 134}}; 135 136// Basic instruction class constructor template. 137def template BlockMemConstructor {{ 138 %(class_name)s::%(class_name)s(ExtMachInst machInst) 139 : %(base_class)s("%(mnemonic)s", machInst) 140 { 141 %(constructor)s; 142 microops[0] = new %(class_name)s_0(machInst); 143 microops[1] = new %(class_name)s_1(machInst); 144 microops[2] = new %(class_name)s_2(machInst); 145 microops[3] = new %(class_name)s_3(machInst); 146 microops[4] = new %(class_name)s_4(machInst); 147 microops[5] = new %(class_name)s_5(machInst); 148 microops[6] = new %(class_name)s_6(machInst); 149 microops[7] = new %(class_name)s_7(machInst); 150 } 151}}; 152 153def template BlockMemMicroConstructor {{ 154 %(class_name)s:: 155 %(class_name)s_%(micro_pc)s:: 156 %(class_name)s_%(micro_pc)s(ExtMachInst machInst) : 157 %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]", 158 machInst, %(op_class)s, %(micro_pc)s * 8) 159 { 160 %(constructor)s; 161 %(set_flags)s; 162 } 163}}; 164 165let {{ 166 167 def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags): 168 # XXX Need to take care of pstate.hpriv as well. The lower ASIs 169 # are split into ones that are available in priv and hpriv, and 170 # those that are only available in hpriv 171 addrCalcReg = 'EA = Rs1 + Rs2 + offset;' 172 addrCalcImm = 'EA = Rs1 + imm + offset;' 173 iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags) 174 iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags) 175 header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm) 176 decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm) 177 decode_block = ROrImmDecode.subst(iop) 178 matcher = re.compile(r'Frd_N') 179 exec_output = '' 180 for microPc in range(8): 181 flag_code = '' 182 if (microPc == 7): 183 flag_code = "flags[IsLastMicroop] = true;" 184 elif (microPc == 0): 185 flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;" 186 else: 187 flag_code = "flags[IsDelayedCommit] = true;" 188 pcedCode = matcher.sub("Frd_%d" % microPc, code) 189 iop = InstObjParams(name, Name, 'BlockMem', 190 {"code": pcedCode, "ea_code": addrCalcReg, 191 "fault_check": faultCode, "micro_pc": microPc, 192 "set_flags": flag_code, "EA_trunc" : TruncateEA}, 193 opt_flags) 194 iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', 195 {"code": pcedCode, "ea_code": addrCalcImm, 196 "fault_check": faultCode, "micro_pc": microPc, 197 "set_flags": flag_code, "EA_trunc" : TruncateEA}, 198 opt_flags) 199 decoder_output += BlockMemMicroConstructor.subst(iop) 200 decoder_output += BlockMemMicroConstructor.subst(iop_imm) 201 exec_output += doDualSplitExecute( 202 pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode, 203 makeMicroName(name, microPc), 204 makeMicroName(name + "Imm", microPc), 205 makeMicroName(Name, microPc), 206 makeMicroName(Name + "Imm", microPc), 207 "EXT_ASI", opt_flags); 208 faultCode = '' 209 return (header_output, decoder_output, exec_output, decode_block) 210}}; 211 212def format BlockLoad(code, *opt_flags) {{ 213 code = filterDoubles(code) 214 # We need to make sure to check the highest priority fault last. 215 # That way, if other faults have been detected, they'll be overwritten 216 # rather than the other way around. 217 faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck 218 (header_output, 219 decoder_output, 220 exec_output, 221 decode_block) = doBlockMemFormat(code, faultCode, 222 LoadFuncs, name, Name, opt_flags) 223}}; 224 225def format BlockStore(code, *opt_flags) {{ 226 code = filterDoubles(code) 227 # We need to make sure to check the highest priority fault last. 228 # That way, if other faults have been detected, they'll be overwritten 229 # rather than the other way around. 230 faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck 231 (header_output, 232 decoder_output, 233 exec_output, 234 decode_block) = doBlockMemFormat(code, faultCode, 235 StoreFuncs, name, Name, opt_flags) 236}}; 237