macromem.isa revision 6755
14120Sgblack@eecs.umich.edu// -*- mode:c++ -*-
24120Sgblack@eecs.umich.edu
34120Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University
44120Sgblack@eecs.umich.edu// All rights reserved.
54120Sgblack@eecs.umich.edu//
64120Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
74120Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
84120Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
94120Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
104120Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
114120Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
124120Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
134120Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
144120Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
154120Sgblack@eecs.umich.edu// this software without specific prior written permission.
164120Sgblack@eecs.umich.edu//
174120Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
184120Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
194120Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
204120Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
214120Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
224120Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
234120Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
244120Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
254120Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
264120Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
274120Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284120Sgblack@eecs.umich.edu//
294120Sgblack@eecs.umich.edu// Authors: Stephen Hines
304120Sgblack@eecs.umich.edu//          Gabe Black
314120Sgblack@eecs.umich.edu
324120Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
334120Sgblack@eecs.umich.edu//
344120Sgblack@eecs.umich.edu// Common microop templates
354120Sgblack@eecs.umich.edu//
364120Sgblack@eecs.umich.edu
374120Sgblack@eecs.umich.edudef template MicroConstructor {{
384120Sgblack@eecs.umich.edu    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
394120Sgblack@eecs.umich.edu                                          RegIndex _ura,
404120Sgblack@eecs.umich.edu                                          RegIndex _urb,
414120Sgblack@eecs.umich.edu                                          uint8_t _imm)
424120Sgblack@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
434120Sgblack@eecs.umich.edu                         _ura, _urb, _imm)
444120Sgblack@eecs.umich.edu    {
454120Sgblack@eecs.umich.edu        %(constructor)s;
464120Sgblack@eecs.umich.edu    }
474120Sgblack@eecs.umich.edu}};
484120Sgblack@eecs.umich.edu
494120Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
504120Sgblack@eecs.umich.edu//
514120Sgblack@eecs.umich.edu// Load/store microops
524120Sgblack@eecs.umich.edu//
534120Sgblack@eecs.umich.edu
544120Sgblack@eecs.umich.edudef template MicroMemDeclare {{
554120Sgblack@eecs.umich.edu    class %(class_name)s : public %(base_class)s
564120Sgblack@eecs.umich.edu    {
574120Sgblack@eecs.umich.edu      public:
584120Sgblack@eecs.umich.edu        %(class_name)s(ExtMachInst machInst,
594120Sgblack@eecs.umich.edu                       RegIndex _ura, RegIndex _urb,
604120Sgblack@eecs.umich.edu                       uint8_t _imm);
614120Sgblack@eecs.umich.edu        %(BasicExecDeclare)s
624120Sgblack@eecs.umich.edu        %(InitiateAccDeclare)s
634120Sgblack@eecs.umich.edu        %(CompleteAccDeclare)s
644120Sgblack@eecs.umich.edu    };
654120Sgblack@eecs.umich.edu}};
664120Sgblack@eecs.umich.edu
674120Sgblack@eecs.umich.edulet {{
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    microLdrRetUopCode = '''
76        Ra = Mem;
77        Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true);
78    '''
79    microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
80                                      'MicroMemOp',
81                                      {'memacc_code': microLdrRetUopCode,
82                                       'ea_code':
83                                          'EA = Rb + (UP ? imm : -imm);',
84                                       'predicate_test': predicateTest},
85                                      ['IsMicroop'])
86
87    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
88                                   'MicroMemOp',
89                                   {'memacc_code': 'Mem = Ra;',
90                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
91                                    'predicate_test': predicateTest},
92                                   ['IsMicroop'])
93
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)
109}};
110
111////////////////////////////////////////////////////////////////////
112//
113// Integer = Integer op Immediate microops
114//
115
116def template MicroIntDeclare {{
117    class %(class_name)s : public %(base_class)s
118    {
119      public:
120        %(class_name)s(ExtMachInst machInst,
121                       RegIndex _ura, RegIndex _urb,
122                       uint8_t _imm);
123        %(BasicExecDeclare)s
124    };
125}};
126
127let {{
128    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
129                                    'MicroIntOp',
130                                    {'code': 'Ra = Rb + imm;',
131                                     'predicate_test': predicateTest},
132                                    ['IsMicroop'])
133
134    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
135                                    'MicroIntOp',
136                                    {'code': 'Ra = Rb - imm;',
137                                     'predicate_test': predicateTest},
138                                    ['IsMicroop'])
139
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)
146}};
147
148////////////////////////////////////////////////////////////////////
149//
150// Moving to/from double floating point registers
151//
152
153let {{
154    microMvtdUopIop = InstObjParams('mvtd_uop', 'MicroMvtdUop',
155                                    'PredOp',
156                                    {'code': 'Fd.ud = (Rhi.ud << 32) | Rlo;',
157                                     'predicate_test': predicateTest},
158                                    ['IsMicroop'])
159
160    microMvfdUopIop = InstObjParams('mvfd_uop', 'MicroMvfdUop',
161                                    'PredOp',
162                                    {'code': '''Rhi = bits(Fd.ud, 63, 32);
163                                                Rlo = bits(Fd.ud, 31, 0);''',
164                                     'predicate_test': predicateTest},
165                                    ['IsMicroop'])
166
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)
173}};
174
175////////////////////////////////////////////////////////////////////
176//
177// Macro Memory-format instructions
178//
179
180def template MacroStoreDeclare {{
181/**
182 * Static instructions class for a store multiple instruction
183 */
184class %(class_name)s : public %(base_class)s
185{
186    public:
187        // Constructor
188        %(class_name)s(ExtMachInst machInst);
189        %(BasicExecDeclare)s
190};
191}};
192
193def template MacroStoreConstructor {{
194inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
195    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
196{
197    %(constructor)s;
198    uint32_t regs = reglist;
199    uint32_t addr = 0;
200    bool up = machInst.puswl.up;
201
202    if (!up)
203        addr = (ones << 2) - 4;
204
205    if (machInst.puswl.prepost)
206        addr += 4;
207
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);
211
212    unsigned reg = 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))
217            reg++;
218        replaceBits(regs, reg, 0);
219
220        unsigned regIdx = reg;
221        if (forceUser) {
222            regIdx = intRegForceUser(regIdx);
223        }
224
225        if (machInst.puswl.loadOp) {
226            if (reg == INTREG_PC && forceUser) {
227                // This must be the exception return form of ldm.
228                microOps[i] =
229                    new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr);
230            } else {
231                microOps[i] =
232                    new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
233            }
234        } else {
235            microOps[i] =
236                new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
237        }
238
239        if (up)
240            addr += 4;
241        else
242            addr -= 4;
243    }
244
245    StaticInstPtr &lastUop = microOps[numMicroops - 1];
246    if (machInst.puswl.writeback) {
247        if (up) {
248            lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
249        } else {
250            lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
251        }
252    }
253    lastUop->setLastMicroop();
254}
255
256}};
257
258def template MacroStoreExecute {{
259Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
260{
261    Fault fault = NoFault;
262
263    %(fp_enable_check)s;
264    %(op_decl)s;
265    %(op_rd)s;
266    %(code)s;
267    if (fault == NoFault)
268    {
269        %(op_wb)s;
270    }
271
272    return fault;
273}
274}};
275
276def template MacroFPAConstructor {{
277inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
278    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
279{
280    %(constructor)s;
281
282    uint32_t start_addr = 0;
283
284    if (prepost)
285        start_addr = disp8;
286    else
287        start_addr = 0;
288
289    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
290
291    if (writeback)
292    {
293        if (up) {
294            microOps[numMicroops - 1] =
295                new MicroAddiUop(machInst, RN, RN, disp8);
296        } else {
297            microOps[numMicroops - 1] =
298                new MicroSubiUop(machInst, RN, RN, disp8);
299        }
300    }
301    microOps[numMicroops - 1]->setLastMicroop();
302}
303
304}};
305
306
307def template MacroFMConstructor {{
308inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
309    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
310{
311    %(constructor)s;
312
313    uint32_t start_addr = 0;
314
315    if (prepost)
316        start_addr = disp8;
317    else
318        start_addr = 0;
319
320    for (int i = 0; i < count; i++)
321        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
322
323    if (writeback) {
324        if (up) {
325            microOps[numMicroops - 1] =
326                new MicroAddiUop(machInst, RN, RN, disp8);
327        } else {
328            microOps[numMicroops - 1] =
329                new MicroSubiUop(machInst, RN, RN, disp8);
330        }
331    }
332    microOps[numMicroops - 1]->setLastMicroop();
333}
334}};
335
336
337def 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)
343}};
344
345def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
346    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
347                        {"code": code,
348                         "predicate_test": predicateTest},
349                        opt_flags)
350    header_output = BasicDeclare.subst(iop)
351    decoder_output = MacroFPAConstructor.subst(iop)
352    decode_block = BasicDecode.subst(iop)
353    exec_output = PredOpExecute.subst(iop)
354}};
355
356def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
357    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
358                        {"code": code,
359                         "predicate_test": predicateTest},
360                        opt_flags)
361    header_output = BasicDeclare.subst(iop)
362    decoder_output = MacroFMConstructor.subst(iop)
363    decode_block = BasicDecode.subst(iop)
364    exec_output = PredOpExecute.subst(iop)
365}};
366