macromem.isa revision 6308
112600Sodanrc@yahoo.com.br// -*- mode:c++ -*-
212600Sodanrc@yahoo.com.br
312600Sodanrc@yahoo.com.br// Copyright (c) 2007-2008 The Florida State University
412600Sodanrc@yahoo.com.br// All rights reserved.
512600Sodanrc@yahoo.com.br//
612600Sodanrc@yahoo.com.br// Redistribution and use in source and binary forms, with or without
712600Sodanrc@yahoo.com.br// modification, are permitted provided that the following conditions are
812600Sodanrc@yahoo.com.br// met: redistributions of source code must retain the above copyright
912600Sodanrc@yahoo.com.br// notice, this list of conditions and the following disclaimer;
1012600Sodanrc@yahoo.com.br// redistributions in binary form must reproduce the above copyright
1112600Sodanrc@yahoo.com.br// notice, this list of conditions and the following disclaimer in the
1212600Sodanrc@yahoo.com.br// documentation and/or other materials provided with the distribution;
1312600Sodanrc@yahoo.com.br// neither the name of the copyright holders nor the names of its
1412600Sodanrc@yahoo.com.br// contributors may be used to endorse or promote products derived from
1512600Sodanrc@yahoo.com.br// this software without specific prior written permission.
1612600Sodanrc@yahoo.com.br//
1712600Sodanrc@yahoo.com.br// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812600Sodanrc@yahoo.com.br// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912600Sodanrc@yahoo.com.br// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012600Sodanrc@yahoo.com.br// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112600Sodanrc@yahoo.com.br// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212600Sodanrc@yahoo.com.br// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312600Sodanrc@yahoo.com.br// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412600Sodanrc@yahoo.com.br// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512600Sodanrc@yahoo.com.br// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612600Sodanrc@yahoo.com.br// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712600Sodanrc@yahoo.com.br// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812600Sodanrc@yahoo.com.br//
2912600Sodanrc@yahoo.com.br// Authors: Stephen Hines
3012600Sodanrc@yahoo.com.br//          Gabe Black
3112600Sodanrc@yahoo.com.br
3212600Sodanrc@yahoo.com.br
3312600Sodanrc@yahoo.com.br////////////////////////////////////////////////////////////////////
3412600Sodanrc@yahoo.com.br//
3512600Sodanrc@yahoo.com.br// Integer = Integer op Immediate microops
3612600Sodanrc@yahoo.com.br//
3712600Sodanrc@yahoo.com.br
3812600Sodanrc@yahoo.com.brdef template MicroIntDeclare {{
3912600Sodanrc@yahoo.com.br    class %(class_name)s : public %(base_class)s
4012600Sodanrc@yahoo.com.br    {
4112600Sodanrc@yahoo.com.br      public:
4212600Sodanrc@yahoo.com.br        %(class_name)s(ExtMachInst machInst,
4312600Sodanrc@yahoo.com.br                       RegIndex _ura, RegIndex _urb,
4412600Sodanrc@yahoo.com.br                       uint8_t _imm);
4512684Sodanrc@yahoo.com.br        %(BasicExecDeclare)s
4612684Sodanrc@yahoo.com.br    };
4712684Sodanrc@yahoo.com.br}};
4812684Sodanrc@yahoo.com.br
4912684Sodanrc@yahoo.com.brdef template MicroIntConstructor {{
5012684Sodanrc@yahoo.com.br    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
5112684Sodanrc@yahoo.com.br                                          RegIndex _ura,
5212684Sodanrc@yahoo.com.br                                          RegIndex _urb,
5312684Sodanrc@yahoo.com.br                                          uint8_t _imm)
5412684Sodanrc@yahoo.com.br        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
5512684Sodanrc@yahoo.com.br                         _ura, _urb, _imm)
5612684Sodanrc@yahoo.com.br    {
5712684Sodanrc@yahoo.com.br        %(constructor)s;
5812684Sodanrc@yahoo.com.br    }
5912684Sodanrc@yahoo.com.br}};
6012684Sodanrc@yahoo.com.br
6112600Sodanrc@yahoo.com.brlet {{
6212600Sodanrc@yahoo.com.br    microAddiUopIop = InstObjParams('addi_uop', 'MicroAddiUop',
6312600Sodanrc@yahoo.com.br                                    'MicroIntOp',
6412600Sodanrc@yahoo.com.br                                    {'code': 'Ra = Rb + imm;',
6512600Sodanrc@yahoo.com.br                                     'predicate_test': predicateTest},
6612600Sodanrc@yahoo.com.br                                    ['IsMicroop'])
6712600Sodanrc@yahoo.com.br
6812600Sodanrc@yahoo.com.br    microSubiUopIop = InstObjParams('subi_uop', 'MicroSubiUop',
6912600Sodanrc@yahoo.com.br                                    'MicroIntOp',
7012600Sodanrc@yahoo.com.br                                    {'code': 'Ra = Rb - imm;',
7112600Sodanrc@yahoo.com.br                                     'predicate_test': predicateTest},
7212600Sodanrc@yahoo.com.br                                    ['IsMicroop'])
7312600Sodanrc@yahoo.com.br
7412600Sodanrc@yahoo.com.br    header_output = MicroIntDeclare.subst(microAddiUopIop) + \
7512600Sodanrc@yahoo.com.br                    MicroIntDeclare.subst(microSubiUopIop)
7612684Sodanrc@yahoo.com.br    decoder_output = MicroIntConstructor.subst(microAddiUopIop) + \
7712684Sodanrc@yahoo.com.br                     MicroIntConstructor.subst(microSubiUopIop)
7812684Sodanrc@yahoo.com.br    exec_output = PredOpExecute.subst(microAddiUopIop) + \
7912684Sodanrc@yahoo.com.br                  PredOpExecute.subst(microSubiUopIop)
8012684Sodanrc@yahoo.com.br}};
8112684Sodanrc@yahoo.com.br
8212684Sodanrc@yahoo.com.br////////////////////////////////////////////////////////////////////
8312684Sodanrc@yahoo.com.br//
8412684Sodanrc@yahoo.com.br// Macro Memory-format instructions
8512684Sodanrc@yahoo.com.br//
8612684Sodanrc@yahoo.com.br
8712684Sodanrc@yahoo.com.brdef template MacroStoreDeclare {{
8812684Sodanrc@yahoo.com.br/**
8912684Sodanrc@yahoo.com.br * Static instructions class for a store multiple instruction
9012684Sodanrc@yahoo.com.br */
9112684Sodanrc@yahoo.com.brclass %(class_name)s : public %(base_class)s
9212684Sodanrc@yahoo.com.br{
9312684Sodanrc@yahoo.com.br    public:
9412684Sodanrc@yahoo.com.br        // Constructor
9512684Sodanrc@yahoo.com.br        %(class_name)s(ExtMachInst machInst);
9612684Sodanrc@yahoo.com.br        %(BasicExecDeclare)s
9712684Sodanrc@yahoo.com.br};
9812684Sodanrc@yahoo.com.br}};
9912684Sodanrc@yahoo.com.br
10012684Sodanrc@yahoo.com.brdef template MacroStoreConstructor {{
10112684Sodanrc@yahoo.com.brinline %(class_name)s::%(class_name)s(ExtMachInst machInst)
10212684Sodanrc@yahoo.com.br    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
10312600Sodanrc@yahoo.com.br{
10412684Sodanrc@yahoo.com.br    %(constructor)s;
10512600Sodanrc@yahoo.com.br    uint32_t regs_to_handle = reglist;
10612684Sodanrc@yahoo.com.br    uint32_t start_addr = 0;
10712600Sodanrc@yahoo.com.br
10812684Sodanrc@yahoo.com.br    switch (puswl)
10912684Sodanrc@yahoo.com.br    {
11012684Sodanrc@yahoo.com.br        case 0x00: //       stmda
11112684Sodanrc@yahoo.com.br        case 0x01: //     L ldmda_l
11212684Sodanrc@yahoo.com.br        case 0x02: //    W  stmda_w
11312684Sodanrc@yahoo.com.br        case 0x03: //    WL ldmda_wl
11412684Sodanrc@yahoo.com.br            start_addr = (ones << 2) - 4;
11512684Sodanrc@yahoo.com.br            break;
11612684Sodanrc@yahoo.com.br        case 0x08: //  U    stmia_u
11712600Sodanrc@yahoo.com.br        case 0x09: //  U  L ldmia_ul
11812600Sodanrc@yahoo.com.br        case 0x0a: //  U W  stmia
11912600Sodanrc@yahoo.com.br        case 0x0b: //  U WL ldmia
120            start_addr = 0;
121            break;
122        case 0x10: // P     stmdb
123        case 0x11: // P   L ldmdb
124        case 0x12: // P  W  stmdb
125        case 0x13: // P  WL ldmdb
126            start_addr = (ones << 2); // U-bit is already 0 for subtract
127            break;
128        case 0x18: // PU    stmib
129        case 0x19: // PU  L ldmib
130        case 0x1a: // PU W  stmib
131        case 0x1b: // PU WL ldmib
132            start_addr = 4;
133            break;
134        default:
135            panic("Unhandled Load/Store Multiple Instruction, "
136                "puswl = 0x%x", (unsigned) puswl);
137            break;
138    }
139
140    // Add 0 to Rn and stick it in Raddr (register 17).
141    // This is equivalent to a move.
142    microOps[0] = new MicroAddiUop(machInst, 17, RN, 0);
143
144    unsigned j = 0;
145    for (int i = 1; i < ones+1; i++) {
146        // Get next available bit for transfer
147        while (! ( regs_to_handle & (1<<j)))
148            j++;
149        regs_to_handle &= ~(1<<j);
150
151        microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
152
153        if (up)
154            start_addr += 4;
155        else
156            start_addr -= 4;
157    }
158
159    if (writeback) {
160        if (up) {
161            microOps[numMicroops-1] =
162                new MicroAddiUop(machInst, RN, RN, ones * 4);
163        } else {
164            microOps[numMicroops-1] =
165                new MicroSubiUop(machInst, RN, RN, ones * 4);
166        }
167    }
168    microOps[numMicroops-1]->setLastMicroop();
169}
170
171}};
172
173def template MacroStoreExecute {{
174Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
175{
176    Fault fault = NoFault;
177
178    %(fp_enable_check)s;
179    %(op_decl)s;
180    %(op_rd)s;
181    %(code)s;
182    if (fault == NoFault)
183    {
184        %(op_wb)s;
185    }
186
187    return fault;
188}
189}};
190
191def template MacroFPAConstructor {{
192inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
193    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
194{
195    %(constructor)s;
196
197    uint32_t start_addr = 0;
198
199    if (prepost)
200        start_addr = disp8;
201    else
202        start_addr = 0;
203
204    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
205
206    if (writeback)
207    {
208        if (up) {
209            microOps[numMicroops-1] =
210                new MicroAddiUop(machInst, RN, RN, disp8);
211        } else {
212            microOps[numMicroops-1] =
213                new MicroSubiUop(machInst, RN, RN, disp8);
214        }
215    }
216    microOps[numMicroops-1]->setLastMicroop();
217}
218
219}};
220
221
222def template MacroFMConstructor {{
223inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
224    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
225{
226    %(constructor)s;
227
228    uint32_t start_addr = 0;
229
230    if (prepost)
231        start_addr = disp8;
232    else
233        start_addr = 0;
234
235    for (int i = 0; i < count; i++)
236        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
237
238    if (writeback) {
239        if (up) {
240            microOps[numMicroops-1] =
241                new MicroAddiUop(machInst, RN, RN, disp8);
242        } else {
243            microOps[numMicroops-1] =
244                new MicroSubiUop(machInst, RN, RN, disp8);
245        }
246    }
247    microOps[numMicroops-1]->setLastMicroop();
248}
249}};
250
251
252def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
253    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
254    header_output = MacroStoreDeclare.subst(iop)
255    decoder_output = MacroStoreConstructor.subst(iop)
256    decode_block = BasicDecode.subst(iop)
257    exec_output = MacroStoreExecute.subst(iop)
258}};
259
260def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
261    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
262                        {"code": code,
263                         "predicate_test": predicateTest},
264                        opt_flags)
265    header_output = BasicDeclare.subst(iop)
266    decoder_output = MacroFPAConstructor.subst(iop)
267    decode_block = BasicDecode.subst(iop)
268    exec_output = PredOpExecute.subst(iop)
269}};
270
271def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
272    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
273                        {"code": code,
274                         "predicate_test": predicateTest},
275                        opt_flags)
276    header_output = BasicDeclare.subst(iop)
277    decoder_output = MacroFMConstructor.subst(iop)
278    decode_block = BasicDecode.subst(iop)
279    exec_output = PredOpExecute.subst(iop)
280}};
281