macromem.isa revision 6258:dadfc8d8b6dd
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
31////////////////////////////////////////////////////////////////////
32//
33// Macro Memory-format instructions
34//
35
36def template MacroStoreDeclare {{
37/**
38 * Static instructions class for a store multiple instruction
39 */
40class %(class_name)s : public %(base_class)s
41{
42    public:
43        // Constructor
44        %(class_name)s(ExtMachInst machInst);
45        %(BasicExecDeclare)s
46};
47}};
48
49def template MacroStoreConstructor {{
50inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
51    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
52{
53    %(constructor)s;
54    uint32_t regs_to_handle = reglist;
55    uint32_t j = 0,
56             start_addr = 0,
57             end_addr = 0;
58
59    switch (puswl)
60    {
61        case 0x00: //       stmda
62        case 0x01: //     L ldmda_l
63        case 0x02: //    W  stmda_w
64        case 0x03: //    WL ldmda_wl
65            start_addr = (ones << 2) - 4;
66            end_addr = 0;
67            break;
68        case 0x08: //  U    stmia_u
69        case 0x09: //  U  L ldmia_ul
70        case 0x0a: //  U W  stmia
71        case 0x0b: //  U WL ldmia
72            start_addr = 0;
73            end_addr = (ones << 2) - 4;
74            break;
75        case 0x10: // P     stmdb
76        case 0x11: // P   L ldmdb
77        case 0x12: // P  W  stmdb
78        case 0x13: // P  WL ldmdb
79            start_addr = (ones << 2); // U-bit is already 0 for subtract
80            end_addr = 4; // negative 4
81            break;
82        case 0x18: // PU    stmib
83        case 0x19: // PU  L ldmib
84        case 0x1a: // PU W  stmib
85        case 0x1b: // PU WL ldmib
86            start_addr = 4;
87            end_addr = (ones << 2) + 4;
88            break;
89        default:
90            panic("Unhandled Load/Store Multiple Instruction, "
91                "puswl = 0x%x", (unsigned) puswl);
92            break;
93    }
94
95    //TODO - Add addi_uop/subi_uop here to create starting addresses
96    //Just using addi with 0 offset makes a "copy" of Rn for our use
97    uint32_t newMachInst = 0;
98    newMachInst = machInst & 0xffff0000;
99    microOps[0] = new Addi_uop(newMachInst);
100
101    for (int i = 1; i < ones+1; i++)
102    {
103        // Get next available bit for transfer
104        while (! ( regs_to_handle & (1<<j)))
105            j++;
106        regs_to_handle &= ~(1<<j);
107
108        microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr);
109
110        if (up)
111            start_addr += 4;
112        else
113            start_addr -= 4;
114    }
115
116    /* TODO: Take a look at how these 2 values should meet together
117    if (start_addr != (end_addr - 4))
118    {
119        fprintf(stderr, "start_addr: %d\n", start_addr);
120        fprintf(stderr, "end_addr:   %d\n", end_addr);
121        panic("start_addr does not meet end_addr");
122    }
123    */
124
125    if (writeback)
126    {
127        uint32_t newMachInst = machInst & 0xf0000000;
128        uint32_t rn = (machInst >> 16) & 0x0f;
129        // 3322 2222 2222 1111 1111 11
130        // 1098 7654 3210 9876 5432 1098 7654 3210
131        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
132        // sub rn, rn, imm
133        newMachInst |= 0x02400000;
134        newMachInst |= ((rn << 16) | (rn << 12));
135        newMachInst |= (ones << 2);
136        if (up)
137        {
138            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
139        }
140        else
141        {
142            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
143        }
144    }
145    microOps[numMicroops-1]->setLastMicroop();
146}
147
148}};
149
150def template MacroStoreExecute {{
151Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
152{
153    Fault fault = NoFault;
154
155    %(fp_enable_check)s;
156    %(op_decl)s;
157    %(op_rd)s;
158    %(code)s;
159    if (fault == NoFault)
160    {
161        %(op_wb)s;
162    }
163
164    return fault;
165}
166}};
167
168def template MacroFPAConstructor {{
169inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
170    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
171{
172    %(constructor)s;
173
174    uint32_t start_addr = 0;
175
176    if (prepost)
177        start_addr = disp8;
178    else
179        start_addr = 0;
180
181    emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
182
183    if (writeback)
184    {
185        uint32_t newMachInst = machInst & 0xf0000000;
186        uint32_t rn = (machInst >> 16) & 0x0f;
187        // 3322 2222 2222 1111 1111 11
188        // 1098 7654 3210 9876 5432 1098 7654 3210
189        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
190        // sub rn, rn, imm
191        newMachInst |= 0x02400000;
192        newMachInst |= ((rn << 16) | (rn << 12));
193        if (up)
194        {
195            newMachInst |= disp8;
196            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
197        }
198        else
199        {
200            newMachInst |= disp8;
201            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
202        }
203    }
204    microOps[numMicroops-1]->setLastMicroop();
205}
206
207}};
208
209
210def template MacroFMConstructor {{
211inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
212    : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
213{
214    %(constructor)s;
215
216    uint32_t start_addr = 0;
217
218    if (prepost)
219        start_addr = disp8;
220    else
221        start_addr = 0;
222
223    for (int i = 0; i < count; i++)
224    {
225        emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
226    }
227
228    if (writeback)
229    {
230        uint32_t newMachInst = machInst & 0xf0000000;
231        uint32_t rn = (machInst >> 16) & 0x0f;
232        // 3322 2222 2222 1111 1111 11
233        // 1098 7654 3210 9876 5432 1098 7654 3210
234        // COND 0010 0100 [RN] [RD] 0000 [  IMM  ]
235        // sub rn, rn, imm
236        newMachInst |= 0x02400000;
237        newMachInst |= ((rn << 16) | (rn << 12));
238        if (up)
239        {
240            newMachInst |= disp8;
241            microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
242        }
243        else
244        {
245            newMachInst |= disp8;
246            microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
247        }
248    }
249    microOps[numMicroops-1]->setLastMicroop();
250}
251}};
252
253
254def format ArmMacroStore(code, mem_flags = [], inst_flag = [], *opt_flags) {{
255    iop = InstObjParams(name, Name, 'ArmMacroMemoryOp', code, opt_flags)
256    header_output = MacroStoreDeclare.subst(iop)
257    decoder_output = MacroStoreConstructor.subst(iop)
258    decode_block = BasicDecode.subst(iop)
259    exec_output = MacroStoreExecute.subst(iop)
260}};
261
262def format ArmMacroFPAOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
263    iop = InstObjParams(name, Name, 'ArmMacroFPAOp',
264                        {"code": code,
265                         "predicate_test": predicateTest},
266                        opt_flags)
267    header_output = BasicDeclare.subst(iop)
268    decoder_output = MacroFPAConstructor.subst(iop)
269    decode_block = BasicDecode.subst(iop)
270    exec_output = PredOpExecute.subst(iop)
271}};
272
273def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
274    iop = InstObjParams(name, Name, 'ArmMacroFMOp',
275                        {"code": code,
276                         "predicate_test": predicateTest},
277                        opt_flags)
278    header_output = BasicDeclare.subst(iop)
279    decoder_output = MacroFMConstructor.subst(iop)
280    decode_block = BasicDecode.subst(iop)
281    exec_output = PredOpExecute.subst(iop)
282}};
283