macromem.isa revision 6726
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
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.
16//
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.
28//
29// Authors: Stephen Hines
30//          Gabe Black
31
32////////////////////////////////////////////////////////////////////
33//
34// Common microop templates
35//
36
37def template MicroConstructor {{
38    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
39                                          RegIndex _ura,
40                                          RegIndex _urb,
41                                          uint8_t _imm)
42        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
43                         _ura, _urb, _imm)
44    {
45        %(constructor)s;
46    }
47}};
48
49////////////////////////////////////////////////////////////////////
50//
51// Load/store microops
52//
53
54def template MicroMemDeclare {{
55    class %(class_name)s : public %(base_class)s
56    {
57      public:
58        %(class_name)s(ExtMachInst machInst,
59                       RegIndex _ura, RegIndex _urb,
60                       uint8_t _imm);
61        %(BasicExecDeclare)s
62        %(InitiateAccDeclare)s
63        %(CompleteAccDeclare)s
64    };
65}};
66
67let {{
68    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
69                                   'MicroMemOp',
70                                   {'memacc_code': 'Ra = Mem;',
71                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
72                                    'predicate_test': predicateTest},
73                                   ['IsMicroop'])
74
75    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
76                                   'MicroMemOp',
77                                   {'memacc_code': 'Mem = Ra;',
78                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
79                                    'predicate_test': predicateTest},
80                                   ['IsMicroop'])
81
82    header_output = MicroMemDeclare.subst(microLdrUopIop) + \
83                    MicroMemDeclare.subst(microStrUopIop)
84    decoder_output = MicroConstructor.subst(microLdrUopIop) + \
85                     MicroConstructor.subst(microStrUopIop)
86    exec_output = LoadExecute.subst(microLdrUopIop) + \
87                  StoreExecute.subst(microStrUopIop) + \
88                  LoadInitiateAcc.subst(microLdrUopIop) + \
89                  StoreInitiateAcc.subst(microStrUopIop) + \
90                  LoadCompleteAcc.subst(microLdrUopIop) + \
91                  StoreCompleteAcc.subst(microStrUopIop)
92}};
93
94////////////////////////////////////////////////////////////////////
95//
96// Integer = Integer op Immediate microops
97//
98
99def template MicroIntDeclare {{
100    class %(class_name)s : public %(base_class)s
101    {
102      public:
103        %(class_name)s(ExtMachInst machInst,
104                       RegIndex _ura, RegIndex _urb,
105                       uint8_t _imm);
106        %(BasicExecDeclare)s
107    };
108}};
109
110let {{
111    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
112                                    'MicroIntOp',
113                                    {'code': 'Ra = Rb + imm;',
114                                     'predicate_test': predicateTest},
115                                    ['IsMicroop'])
116
117    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
118                                    'MicroIntOp',
119                                    {'code': 'Ra = Rb - imm;',
120                                     'predicate_test': predicateTest},
121                                    ['IsMicroop'])
122
123    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
124                    MicroIntDeclare.subst(microSubiUopIop)
125    decoder_output = MicroConstructor.subst(microAddiUopIop) + \
126                     MicroConstructor.subst(microSubiUopIop)
127    exec_output = PredOpExecute.subst(microAddiUopIop) + \
128                  PredOpExecute.subst(microSubiUopIop)
129}};
130
131////////////////////////////////////////////////////////////////////
132//
133// Moving to/from double floating point registers
134//
135
136let {{
137    microMvtdUopIop = InstObjParams('mvtd_uop', 'MicroMvtdUop',
138                                    'PredOp',
139                                    {'code': 'Fd.ud = (Rhi.ud << 32) | Rlo;',
140                                     'predicate_test': predicateTest},
141                                    ['IsMicroop'])
142
143    microMvfdUopIop = InstObjParams('mvfd_uop', 'MicroMvfdUop',
144                                    'PredOp',
145                                    {'code': '''Rhi = bits(Fd.ud, 63, 32);
146                                                Rlo = bits(Fd.ud, 31, 0);''',
147                                     'predicate_test': predicateTest},
148                                    ['IsMicroop'])
149
150    header_output = BasicDeclare.subst(microMvtdUopIop) + \
151                    BasicDeclare.subst(microMvfdUopIop)
152    decoder_output = BasicConstructor.subst(microMvtdUopIop) + \
153                     BasicConstructor.subst(microMvfdUopIop)
154    exec_output = PredOpExecute.subst(microMvtdUopIop) + \
155                  PredOpExecute.subst(microMvfdUopIop)
156}};
157
158////////////////////////////////////////////////////////////////////
159//
160// Macro Memory-format instructions
161//
162
163def template MacroStoreDeclare {{
164/**
165 * Static instructions class for a store multiple instruction
166 */
167class %(class_name)s : public %(base_class)s
168{
169    public:
170        // Constructor
171        %(class_name)s(ExtMachInst machInst);
172        %(BasicExecDeclare)s
173};
174}};
175
176def template MacroStoreConstructor {{
177inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
178    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
179{
180    %(constructor)s;
181    uint32_t regs = reglist;
182    uint32_t addr = 0;
183    bool up = machInst.puswl.up;
184
185    if (!up)
186        addr = (ones << 2) - 4;
187
188    if (machInst.puswl.prepost)
189        addr += 4;
190
191    // Add 0 to Rn and stick it in ureg0.
192    // This is equivalent to a move.
193    microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
194
195    unsigned reg = 0;
196    for (int i = 1; i < ones + 1; i++) {
197        // Find the next register.
198        while (!bits(regs, reg))
199            reg++;
200        replaceBits(regs, reg, 0);
201
202        unsigned regIdx = reg;
203        if (machInst.puswl.psruser) {
204            regIdx = intRegForceUser(regIdx);
205        }
206
207        if (machInst.puswl.loadOp) {
208            microOps[i] =
209                new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
210        } else {
211            microOps[i] =
212                new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
213        }
214
215        if (up)
216            addr += 4;
217        else
218            addr -= 4;
219    }
220
221    StaticInstPtr &lastUop = microOps[numMicroops - 1];
222    if (machInst.puswl.writeback) {
223        if (up) {
224            lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
225        } else {
226            lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
227        }
228    }
229    lastUop->setLastMicroop();
230}
231
232}};
233
234def template MacroStoreExecute {{
235Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
236{
237    Fault fault = NoFault;
238
239    %(fp_enable_check)s;
240    %(op_decl)s;
241    %(op_rd)s;
242    %(code)s;
243    if (fault == NoFault)
244    {
245        %(op_wb)s;
246    }
247
248    return fault;
249}
250}};
251
252def template MacroFPAConstructor {{
253inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
254    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
255{
256    %(constructor)s;
257
258    uint32_t start_addr = 0;
259
260    if (prepost)
261        start_addr = disp8;
262    else
263        start_addr = 0;
264
265    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
266
267    if (writeback)
268    {
269        if (up) {
270            microOps[numMicroops - 1] =
271                new MicroAddiUop(machInst, RN, RN, disp8);
272        } else {
273            microOps[numMicroops - 1] =
274                new MicroSubiUop(machInst, RN, RN, disp8);
275        }
276    }
277    microOps[numMicroops - 1]->setLastMicroop();
278}
279
280}};
281
282
283def template MacroFMConstructor {{
284inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
285    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
286{
287    %(constructor)s;
288
289    uint32_t start_addr = 0;
290
291    if (prepost)
292        start_addr = disp8;
293    else
294        start_addr = 0;
295
296    for (int i = 0; i < count; i++)
297        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
298
299    if (writeback) {
300        if (up) {
301            microOps[numMicroops - 1] =
302                new MicroAddiUop(machInst, RN, RN, disp8);
303        } else {
304            microOps[numMicroops - 1] =
305                new MicroSubiUop(machInst, RN, RN, disp8);
306        }
307    }
308    microOps[numMicroops - 1]->setLastMicroop();
309}
310}};
311
312
313def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
314    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
315    header_output = MacroStoreDeclare.subst(iop)
316    decoder_output = MacroStoreConstructor.subst(iop)
317    decode_block = BasicDecode.subst(iop)
318    exec_output = MacroStoreExecute.subst(iop)
319}};
320
321def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
322    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
323                        {"code": code,
324                         "predicate_test": predicateTest},
325                        opt_flags)
326    header_output = BasicDeclare.subst(iop)
327    decoder_output = MacroFPAConstructor.subst(iop)
328    decode_block = BasicDecode.subst(iop)
329    exec_output = PredOpExecute.subst(iop)
330}};
331
332def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
333    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
334                        {"code": code,
335                         "predicate_test": predicateTest},
336                        opt_flags)
337    header_output = BasicDeclare.subst(iop)
338    decoder_output = MacroFMConstructor.subst(iop)
339    decode_block = BasicDecode.subst(iop)
340    exec_output = PredOpExecute.subst(iop)
341}};
342