macromem.isa revision 6725
112396SRiken.Gohil@arm.com// -*- mode:c++ -*-
212396SRiken.Gohil@arm.com
312396SRiken.Gohil@arm.com// Copyright (c) 2007-2008 The Florida State University
412396SRiken.Gohil@arm.com// All rights reserved.
512396SRiken.Gohil@arm.com//
612396SRiken.Gohil@arm.com// Redistribution and use in source and binary forms, with or without
712396SRiken.Gohil@arm.com// modification, are permitted provided that the following conditions are
812396SRiken.Gohil@arm.com// met: redistributions of source code must retain the above copyright
912396SRiken.Gohil@arm.com// notice, this list of conditions and the following disclaimer;
1012396SRiken.Gohil@arm.com// redistributions in binary form must reproduce the above copyright
1112396SRiken.Gohil@arm.com// notice, this list of conditions and the following disclaimer in the
1212396SRiken.Gohil@arm.com// documentation and/or other materials provided with the distribution;
1312396SRiken.Gohil@arm.com// neither the name of the copyright holders nor the names of its
1412396SRiken.Gohil@arm.com// contributors may be used to endorse or promote products derived from
1512396SRiken.Gohil@arm.com// this software without specific prior written permission.
1612396SRiken.Gohil@arm.com//
1712396SRiken.Gohil@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812396SRiken.Gohil@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912396SRiken.Gohil@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012396SRiken.Gohil@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112396SRiken.Gohil@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212396SRiken.Gohil@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312396SRiken.Gohil@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412396SRiken.Gohil@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512396SRiken.Gohil@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612396SRiken.Gohil@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712396SRiken.Gohil@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812396SRiken.Gohil@arm.com//
2912396SRiken.Gohil@arm.com// Authors: Stephen Hines
3012396SRiken.Gohil@arm.com//          Gabe Black
3112396SRiken.Gohil@arm.com
3212396SRiken.Gohil@arm.com////////////////////////////////////////////////////////////////////
3312396SRiken.Gohil@arm.com//
3412396SRiken.Gohil@arm.com// Common microop templates
3512396SRiken.Gohil@arm.com//
3612396SRiken.Gohil@arm.com
3712396SRiken.Gohil@arm.comdef template MicroConstructor {{
3812396SRiken.Gohil@arm.com    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
3912396SRiken.Gohil@arm.com                                          RegIndex _ura,
4012396SRiken.Gohil@arm.com                                          RegIndex _urb,
4112396SRiken.Gohil@arm.com                                          uint8_t _imm)
4212396SRiken.Gohil@arm.com        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
4312396SRiken.Gohil@arm.com                         _ura, _urb, _imm)
4412396SRiken.Gohil@arm.com    {
4512396SRiken.Gohil@arm.com        %(constructor)s;
4612396SRiken.Gohil@arm.com    }
4712396SRiken.Gohil@arm.com}};
4812396SRiken.Gohil@arm.com
4912396SRiken.Gohil@arm.com////////////////////////////////////////////////////////////////////
5012396SRiken.Gohil@arm.com//
5112396SRiken.Gohil@arm.com// Load/store microops
5212396SRiken.Gohil@arm.com//
5312396SRiken.Gohil@arm.com
5412396SRiken.Gohil@arm.comdef template MicroMemDeclare {{
5512396SRiken.Gohil@arm.com    class %(class_name)s : public %(base_class)s
5612396SRiken.Gohil@arm.com    {
5712396SRiken.Gohil@arm.com      public:
5812396SRiken.Gohil@arm.com        %(class_name)s(ExtMachInst machInst,
5912396SRiken.Gohil@arm.com                       RegIndex _ura, RegIndex _urb,
6012396SRiken.Gohil@arm.com                       uint8_t _imm);
6112396SRiken.Gohil@arm.com        %(BasicExecDeclare)s
6212396SRiken.Gohil@arm.com        %(InitiateAccDeclare)s
6312396SRiken.Gohil@arm.com        %(CompleteAccDeclare)s
6412396SRiken.Gohil@arm.com    };
6512396SRiken.Gohil@arm.com}};
6612396SRiken.Gohil@arm.com
6712396SRiken.Gohil@arm.comlet {{
6812396SRiken.Gohil@arm.com    microLdrUopIop = InstObjParams('ldr_uop', 'MicroLdrUop',
6912396SRiken.Gohil@arm.com                                   'MicroMemOp',
7012396SRiken.Gohil@arm.com                                   {'memacc_code': 'Ra = Mem;',
7112396SRiken.Gohil@arm.com                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
7212396SRiken.Gohil@arm.com                                    'predicate_test': predicateTest},
7312396SRiken.Gohil@arm.com                                   ['IsMicroop'])
7412396SRiken.Gohil@arm.com
7512396SRiken.Gohil@arm.com    microStrUopIop = InstObjParams('str_uop', 'MicroStrUop',
7612396SRiken.Gohil@arm.com                                   'MicroMemOp',
7712396SRiken.Gohil@arm.com                                   {'memacc_code': 'Mem = Ra;',
7812396SRiken.Gohil@arm.com                                    'ea_code': 'EA = Rb + (UP ? imm : -imm);',
7912396SRiken.Gohil@arm.com                                    'predicate_test': predicateTest},
8012396SRiken.Gohil@arm.com                                   ['IsMicroop'])
8112396SRiken.Gohil@arm.com
8212396SRiken.Gohil@arm.com    header_output = MicroMemDeclare.subst(microLdrUopIop) + \
8312396SRiken.Gohil@arm.com                    MicroMemDeclare.subst(microStrUopIop)
8412396SRiken.Gohil@arm.com    decoder_output = MicroConstructor.subst(microLdrUopIop) + \
8512396SRiken.Gohil@arm.com                     MicroConstructor.subst(microStrUopIop)
8612396SRiken.Gohil@arm.com    exec_output = LoadExecute.subst(microLdrUopIop) + \
8712396SRiken.Gohil@arm.com                  StoreExecute.subst(microStrUopIop) + \
8812396SRiken.Gohil@arm.com                  LoadInitiateAcc.subst(microLdrUopIop) + \
8912396SRiken.Gohil@arm.com                  StoreInitiateAcc.subst(microStrUopIop) + \
9012396SRiken.Gohil@arm.com                  LoadCompleteAcc.subst(microLdrUopIop) + \
9112396SRiken.Gohil@arm.com                  StoreCompleteAcc.subst(microStrUopIop)
9212396SRiken.Gohil@arm.com}};
9312396SRiken.Gohil@arm.com
9412396SRiken.Gohil@arm.com////////////////////////////////////////////////////////////////////
9512396SRiken.Gohil@arm.com//
9612396SRiken.Gohil@arm.com// Integer = Integer op Immediate microops
9712396SRiken.Gohil@arm.com//
9812396SRiken.Gohil@arm.com
9912396SRiken.Gohil@arm.comdef template MicroIntDeclare {{
10012396SRiken.Gohil@arm.com    class %(class_name)s : public %(base_class)s
10112396SRiken.Gohil@arm.com    {
10212396SRiken.Gohil@arm.com      public:
10312396SRiken.Gohil@arm.com        %(class_name)s(ExtMachInst machInst,
10412396SRiken.Gohil@arm.com                       RegIndex _ura, RegIndex _urb,
10512396SRiken.Gohil@arm.com                       uint8_t _imm);
10612396SRiken.Gohil@arm.com        %(BasicExecDeclare)s
10712396SRiken.Gohil@arm.com    };
10812396SRiken.Gohil@arm.com}};
10912396SRiken.Gohil@arm.com
11012396SRiken.Gohil@arm.comlet {{
11112396SRiken.Gohil@arm.com    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
11212396SRiken.Gohil@arm.com                                    'MicroIntOp',
11312396SRiken.Gohil@arm.com                                    {'code': 'Ra = Rb + imm;',
11412396SRiken.Gohil@arm.com                                     'predicate_test': predicateTest},
11512396SRiken.Gohil@arm.com                                    ['IsMicroop'])
11612396SRiken.Gohil@arm.com
11712396SRiken.Gohil@arm.com    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
11812396SRiken.Gohil@arm.com                                    'MicroIntOp',
11912396SRiken.Gohil@arm.com                                    {'code': 'Ra = Rb - imm;',
12012396SRiken.Gohil@arm.com                                     'predicate_test': predicateTest},
12112396SRiken.Gohil@arm.com                                    ['IsMicroop'])
12212396SRiken.Gohil@arm.com
12312396SRiken.Gohil@arm.com    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
12412396SRiken.Gohil@arm.com                    MicroIntDeclare.subst(microSubiUopIop)
12512396SRiken.Gohil@arm.com    decoder_output = MicroConstructor.subst(microAddiUopIop) + \
12612396SRiken.Gohil@arm.com                     MicroConstructor.subst(microSubiUopIop)
12712396SRiken.Gohil@arm.com    exec_output = PredOpExecute.subst(microAddiUopIop) + \
12812396SRiken.Gohil@arm.com                  PredOpExecute.subst(microSubiUopIop)
12912396SRiken.Gohil@arm.com}};
13012396SRiken.Gohil@arm.com
13112396SRiken.Gohil@arm.com////////////////////////////////////////////////////////////////////
13212396SRiken.Gohil@arm.com//
13312396SRiken.Gohil@arm.com// Moving to/from double floating point registers
13412396SRiken.Gohil@arm.com//
13512396SRiken.Gohil@arm.com
13612396SRiken.Gohil@arm.comlet {{
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
184    if (!up)
185        addr = (ones << 2) - 4;
186
187    if (prepost)
188        addr += 4;
189
190    // Add 0 to Rn and stick it in ureg0.
191    // This is equivalent to a move.
192    microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0);
193
194    unsigned reg = 0;
195    for (int i = 1; i < ones + 1; i++) {
196        // Find the next register.
197        while (!bits(regs, reg))
198            reg++;
199        replaceBits(regs, reg, 0);
200
201        if (loadop)
202            microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr);
203        else
204            microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr);
205
206        if (up)
207            addr += 4;
208        else
209            addr -= 4;
210    }
211
212    StaticInstPtr &lastUop = microOps[numMicroops - 1];
213    if (writeback) {
214        if (up) {
215            lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
216        } else {
217            lastUop = new MicroSubiUop(machInst, RN, RN, ones * 4);
218        }
219    }
220    lastUop->setLastMicroop();
221}
222
223}};
224
225def template MacroStoreExecute {{
226Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
227{
228    Fault fault = NoFault;
229
230    %(fp_enable_check)s;
231    %(op_decl)s;
232    %(op_rd)s;
233    %(code)s;
234    if (fault == NoFault)
235    {
236        %(op_wb)s;
237    }
238
239    return fault;
240}
241}};
242
243def template MacroFPAConstructor {{
244inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
245    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
246{
247    %(constructor)s;
248
249    uint32_t start_addr = 0;
250
251    if (prepost)
252        start_addr = disp8;
253    else
254        start_addr = 0;
255
256    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
257
258    if (writeback)
259    {
260        if (up) {
261            microOps[numMicroops - 1] =
262                new MicroAddiUop(machInst, RN, RN, disp8);
263        } else {
264            microOps[numMicroops - 1] =
265                new MicroSubiUop(machInst, RN, RN, disp8);
266        }
267    }
268    microOps[numMicroops - 1]->setLastMicroop();
269}
270
271}};
272
273
274def template MacroFMConstructor {{
275inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
276    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
277{
278    %(constructor)s;
279
280    uint32_t start_addr = 0;
281
282    if (prepost)
283        start_addr = disp8;
284    else
285        start_addr = 0;
286
287    for (int i = 0; i < count; i++)
288        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
289
290    if (writeback) {
291        if (up) {
292            microOps[numMicroops - 1] =
293                new MicroAddiUop(machInst, RN, RN, disp8);
294        } else {
295            microOps[numMicroops - 1] =
296                new MicroSubiUop(machInst, RN, RN, disp8);
297        }
298    }
299    microOps[numMicroops - 1]->setLastMicroop();
300}
301}};
302
303
304def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
305    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
306    header_output = MacroStoreDeclare.subst(iop)
307    decoder_output = MacroStoreConstructor.subst(iop)
308    decode_block = BasicDecode.subst(iop)
309    exec_output = MacroStoreExecute.subst(iop)
310}};
311
312def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
313    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
314                        {"code": code,
315                         "predicate_test": predicateTest},
316                        opt_flags)
317    header_output = BasicDeclare.subst(iop)
318    decoder_output = MacroFPAConstructor.subst(iop)
319    decode_block = BasicDecode.subst(iop)
320    exec_output = PredOpExecute.subst(iop)
321}};
322
323def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
324    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
325                        {"code": code,
326                         "predicate_test": predicateTest},
327                        opt_flags)
328    header_output = BasicDeclare.subst(iop)
329    decoder_output = MacroFMConstructor.subst(iop)
330    decode_block = BasicDecode.subst(iop)
331    exec_output = PredOpExecute.subst(iop)
332}};
333