3 // Copyright (c) 2007-2008 The Florida State University
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met: redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer;
10 // redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution;
13 // neither the name of the copyright holders nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // Authors: Stephen Hines
32 ////////////////////////////////////////////////////////////////////
34 // Common microop templates
37 def template MicroConstructor {{
38 inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
42 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
49 ////////////////////////////////////////////////////////////////////
51 // Load/store microops
54 def template MicroMemDeclare {{
55 class %(class_name)s : public %(base_class)s
58 %(class_name)s(ExtMachInst machInst,
59 RegIndex _ura, RegIndex _urb,
62 %(InitiateAccDeclare)s
63 %(CompleteAccDeclare)s
68 microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
70 {'memacc_code': 'Ra = Mem;',
71 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
72 'predicate_test': predicateTest},
75 microLdrRetUopCode = '''
77 Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
79 microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
81 {'memacc_code': microLdrRetUopCode,
83 'EA = Rb + (UP ? imm : -imm);',
84 'predicate_test': predicateTest},
87 microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
89 {'memacc_code': 'Mem = Ra;',
90 'ea_code': 'EA = Rb + (UP ? imm : -imm);',
91 'predicate_test': predicateTest},
94 header_output = MicroMemDeclare.subst(microLdrUopIop) + \
95 MicroMemDeclare.subst(microLdrRetUopIop) + \
96 MicroMemDeclare.subst(microStrUopIop)
97 decoder_output = MicroConstructor.subst(microLdrUopIop) + \
98 MicroConstructor.subst(microLdrRetUopIop) + \
99 MicroConstructor.subst(microStrUopIop)
100 exec_output = LoadExecute.subst(microLdrUopIop) + \
101 LoadExecute.subst(microLdrRetUopIop) + \
102 StoreExecute.subst(microStrUopIop) + \
103 LoadInitiateAcc.subst(microLdrUopIop) + \
104 LoadInitiateAcc.subst(microLdrRetUopIop) + \
105 StoreInitiateAcc.subst(microStrUopIop) + \
106 LoadCompleteAcc.subst(microLdrUopIop) + \
107 LoadCompleteAcc.subst(microLdrRetUopIop) + \
108 StoreCompleteAcc.subst(microStrUopIop)
111 ////////////////////////////////////////////////////////////////////
113 // Integer = Integer op Immediate microops
116 def template MicroIntDeclare {{
117 class %(class_name)s : public %(base_class)s
120 %(class_name)s(ExtMachInst machInst,
121 RegIndex _ura, RegIndex _urb,
128 microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
130 {'code': 'Ra = Rb + imm;',
131 'predicate_test': predicateTest},
134 microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
136 {'code': 'Ra = Rb - imm;',
137 'predicate_test': predicateTest},
140 header_output = MicroIntDeclare.subst(microAddiUopIop) + \
141 MicroIntDeclare.subst(microSubiUopIop)
142 decoder_output = MicroConstructor.subst(microAddiUopIop) + \
143 MicroConstructor.subst(microSubiUopIop)
144 exec_output = PredOpExecute.subst(microAddiUopIop) + \
145 PredOpExecute.subst(microSubiUopIop)
148 ////////////////////////////////////////////////////////////////////
150 // Moving to/from double floating point registers
154 microMvtdUopIop = InstObjParams('mvtd_uop', 'MicroMvtdUop',
156 {'code': 'Fd.ud = (Rhi.ud << 32) | Rlo;',
157 'predicate_test': predicateTest},
160 microMvfdUopIop = InstObjParams('mvfd_uop', 'MicroMvfdUop',
162 {'code': '''Rhi = bits(Fd.ud, 63, 32);
163 Rlo = bits(Fd.ud, 31, 0);''',
164 'predicate_test': predicateTest},
167 header_output = BasicDeclare.subst(microMvtdUopIop) + \
168 BasicDeclare.subst(microMvfdUopIop)
169 decoder_output = BasicConstructor.subst(microMvtdUopIop) + \
170 BasicConstructor.subst(microMvfdUopIop)
171 exec_output = PredOpExecute.subst(microMvtdUopIop) + \
172 PredOpExecute.subst(microMvfdUopIop)
175 ////////////////////////////////////////////////////////////////////
177 // Macro Memory-format instructions
180 def template MacroStoreDeclare {{
182 * Static instructions class for a store multiple instruction
184 class %(class_name)s : public %(base_class)s
188 %(class_name)s(ExtMachInst machInst);
193 def template MacroStoreConstructor {{
194 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
195 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
198 uint32_t regs = reglist;
200 bool up = machInst.puswl.up;
203 addr = (ones << 2) - 4;
205 if (machInst.puswl.prepost)
208 // Add 0 to Rn and stick it in ureg0.
209 // This is equivalent to a move.
210 microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
213 bool forceUser = machInst.puswl.psruser;
214 for (int i = 1; i < ones + 1; i++) {
215 // Find the next register.
216 while (!bits(regs, reg))
218 replaceBits(regs, reg, 0);
220 unsigned regIdx = reg;
222 regIdx = intRegForceUser(regIdx);
225 if (machInst.puswl.loadOp) {
226 if (reg == INTREG_PC && forceUser) {
227 // This must be the exception return form of ldm.
229 new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
232 new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
236 new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
245 StaticInstPtr &lastUop = microOps[numMicroops - 1];
246 if (machInst.puswl.writeback) {
248 lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
250 lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
253 lastUop->setLastMicroop();
258 def template MacroStoreExecute {{
259 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
261 Fault fault = NoFault;
267 if (fault == NoFault)
276 def template MacroFPAConstructor {{
277 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
278 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
282 uint32_t start_addr = 0;
289 emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
294 microOps[numMicroops - 1] =
295 new MicroAddiUop(machInst, RN, RN, disp8);
297 microOps[numMicroops - 1] =
298 new MicroSubiUop(machInst, RN, RN, disp8);
301 microOps[numMicroops - 1]->setLastMicroop();
307 def template MacroFMConstructor {{
308 inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
309 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
313 uint32_t start_addr = 0;
320 for (int i = 0; i < count; i++)
321 emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
325 microOps[numMicroops - 1] =
326 new MicroAddiUop(machInst, RN, RN, disp8);
328 microOps[numMicroops - 1] =
329 new MicroSubiUop(machInst, RN, RN, disp8);
332 microOps[numMicroops - 1]->setLastMicroop();
337 def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
338 iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
339 header_output = MacroStoreDeclare.subst(iop)
340 decoder_output = MacroStoreConstructor.subst(iop)
341 decode_block = BasicDecode.subst(iop)
342 exec_output = MacroStoreExecute.subst(iop)
345 def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
346 iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
348 "predicate_test": predicateTest},
350 header_output = BasicDeclare.subst(iop)
351 decoder_output = MacroFPAConstructor.subst(iop)
352 decode_block = BasicDecode.subst(iop)
353 exec_output = PredOpExecute.subst(iop)
356 def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
357 iop = InstObjParams(name, Name, 'ArmMacroFMOp',
359 "predicate_test": predicateTest},
361 header_output = BasicDeclare.subst(iop)
362 decoder_output = MacroFMConstructor.subst(iop)
363 decode_block = BasicDecode.subst(iop)
364 exec_output = PredOpExecute.subst(iop)