basicmem.isa revision 3385
1////////////////////////////////////////////////////////////////////
2//
3// Mem instructions
4//
5
6output header {{
7        /**
8         * Base class for memory operations.
9         */
10        class Mem : public SparcStaticInst
11        {
12          protected:
13
14            // Constructor
15            Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
16                SparcStaticInst(mnem, _machInst, __opClass)
17            {
18            }
19
20            std::string generateDisassembly(Addr pc,
21                    const SymbolTable *symtab) const;
22        };
23
24        /**
25         * Class for memory operations which use an immediate offset.
26         */
27        class MemImm : public Mem
28        {
29          protected:
30
31            // Constructor
32            MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
33                Mem(mnem, _machInst, __opClass)
34            {
35                imm = sext<13>(SIMM13);
36            }
37
38            std::string generateDisassembly(Addr pc,
39                    const SymbolTable *symtab) const;
40
41            int32_t imm;
42        };
43}};
44
45output decoder {{
46        std::string Mem::generateDisassembly(Addr pc,
47                const SymbolTable *symtab) const
48        {
49            std::stringstream response;
50            bool load = flags[IsLoad];
51            bool save = flags[IsStore];
52
53            printMnemonic(response, mnemonic);
54            if(save)
55            {
56                printReg(response, _srcRegIdx[0]);
57                ccprintf(response, ", ");
58            }
59            ccprintf(response, "[ ");
60            printReg(response, _srcRegIdx[!save ? 0 : 1]);
61            ccprintf(response, " + ");
62            printReg(response, _srcRegIdx[!save ? 1 : 2]);
63            ccprintf(response, " ]");
64            if(load)
65            {
66                ccprintf(response, ", ");
67                printReg(response, _destRegIdx[0]);
68            }
69
70            return response.str();
71        }
72
73        std::string MemImm::generateDisassembly(Addr pc,
74                const SymbolTable *symtab) const
75        {
76            std::stringstream response;
77            bool load = flags[IsLoad];
78            bool save = flags[IsStore];
79
80            printMnemonic(response, mnemonic);
81            if(save)
82            {
83                printReg(response, _srcRegIdx[0]);
84                ccprintf(response, ", ");
85            }
86            ccprintf(response, "[ ");
87            printReg(response, _srcRegIdx[!save ? 0 : 1]);
88            if(imm >= 0)
89                ccprintf(response, " + 0x%x ]", imm);
90            else
91                ccprintf(response, " + -0x%x ]", -imm);
92            if(load)
93            {
94                ccprintf(response, ", ");
95                printReg(response, _destRegIdx[0]);
96            }
97
98            return response.str();
99        }
100
101}};
102
103def template LoadExecute {{
104        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
105                Trace::InstRecord *traceData) const
106        {
107            Fault fault = NoFault;
108            Addr EA;
109            %(op_decl)s;
110            %(op_rd)s;
111            %(priv_check)s;
112            %(ea_code)s;
113            DPRINTF(Sparc, "The address is 0x%x\n", EA);
114            fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
115            %(code)s;
116            if(fault == NoFault)
117            {
118                //Write the resulting state to the execution context
119                %(op_wb)s;
120            }
121
122            return fault;
123        }
124
125        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
126                Trace::InstRecord * traceData) const
127        {
128            Fault fault = NoFault;
129            Addr EA;
130            uint%(mem_acc_size)s_t Mem;
131            %(ea_decl)s;
132            %(ea_rd)s;
133            %(priv_check)s;
134            %(ea_code)s;
135            fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
136            return fault;
137        }
138
139        Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
140                Trace::InstRecord * traceData) const
141        {
142            Fault fault = NoFault;
143            %(code_decl)s;
144            %(code_rd)s;
145            Mem = pkt->get<typeof(Mem)>();
146            %(code)s;
147            if(fault == NoFault)
148            {
149                %(code_wb)s;
150            }
151            return fault;
152        }
153}};
154
155def template StoreExecute {{
156        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
157                Trace::InstRecord *traceData) const
158        {
159            Fault fault = NoFault;
160            uint64_t write_result = 0;
161            Addr EA;
162            %(op_decl)s;
163            %(op_rd)s;
164            %(priv_check)s;
165            %(ea_code)s;
166            DPRINTF(Sparc, "The address is 0x%x\n", EA);
167            %(code)s;
168
169            if(fault == NoFault)
170            {
171                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
172            }
173            if(fault == NoFault)
174            {
175                //Write the resulting state to the execution context
176                %(op_wb)s;
177            }
178
179            return fault;
180        }
181
182        Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
183                Trace::InstRecord * traceData) const
184        {
185            Fault fault = NoFault;
186            uint64_t write_result = 0;
187            Addr EA;
188            %(op_decl)s;
189            %(op_rd)s;
190            %(priv_check)s;
191            %(ea_code)s;
192            DPRINTF(Sparc, "The address is 0x%x\n", EA);
193            %(code)s;
194            if(fault == NoFault)
195            {
196                fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
197            }
198            if(fault == NoFault)
199            {
200                //Write the resulting state to the execution context
201                %(op_wb)s;
202            }
203            return fault;
204        }
205
206        Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
207                Trace::InstRecord * traceData) const
208        {
209            return NoFault;
210        }
211}};
212
213def template LoadStoreExecute {{
214        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
215                Trace::InstRecord *traceData) const
216        {
217            Fault fault = NoFault;
218            uint64_t write_result = 0;
219            Addr EA;
220            %(op_decl)s;
221            %(op_rd)s;
222            %(priv_check)s;
223            %(ea_code)s;
224            DPRINTF(Sparc, "The address is 0x%x\n", EA);
225            xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
226            %(code)s;
227
228            if(fault == NoFault)
229            {
230                xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
231                //Write the resulting state to the execution context
232                %(op_wb)s;
233            }
234
235            return fault;
236        }
237}};
238
239def template MemDeclare {{
240        /**
241         * Static instruction class for "%(mnemonic)s".
242         */
243        class %(class_name)s : public %(base_class)s
244        {
245          public:
246
247            /// Constructor.
248            %(class_name)s(ExtMachInst machInst);
249
250            %(BasicExecDeclare)s
251
252            %(InitiateAccDeclare)s
253
254            %(CompleteAccDeclare)s
255        };
256}};
257
258def template InitiateAccDeclare {{
259    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
260}};
261
262def template CompleteAccDeclare {{
263    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
264}};
265
266
267let {{
268    # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
269    # into ones that are available in priv and hpriv, and those that are only
270    # available in hpriv
271    privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
272                return new PrivilegedAction;
273            if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
274                return new PrivilegedAction;'''
275
276    def doMemFormat(code, execute, priv, name, Name, opt_flags):
277        addrCalcReg = 'EA = Rs1 + Rs2;'
278        addrCalcImm = 'EA = Rs1 + imm;'
279        ea_iop = InstObjParams(name, Name, 'Mem',
280                addrCalcReg, opt_flags, {"priv_check": priv})
281        ea_iop_imm = InstObjParams(name, Name, 'MemImm',
282                addrCalcImm, opt_flags, {"priv_check": priv})
283        code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags)
284        iop = InstObjParams(name, Name, 'Mem', code,
285                opt_flags, {"ea_code": addrCalcReg,
286                "priv_check": priv})
287        (iop.ea_decl,
288         iop.ea_rd,
289         iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb)
290        (iop.code_decl,
291         iop.code_rd,
292         iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
293        iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
294                opt_flags, {"ea_code": addrCalcImm,
295                "priv_check": priv})
296        (iop_imm.ea_decl,
297         iop_imm.ea_rd,
298         iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb)
299        (iop_imm.code_decl,
300         iop_imm.code_rd,
301         iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
302        header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
303        decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
304        decode_block = ROrImmDecode.subst(iop)
305        exec_output = execute.subst(iop) + execute.subst(iop_imm)
306        return (header_output, decoder_output, exec_output, decode_block)
307}};
308
309def format LoadAlt(code, *opt_flags) {{
310        (header_output,
311         decoder_output,
312         exec_output,
313         decode_block) = doMemFormat(code, LoadExecute,
314            privelegedString, name, Name, opt_flags)
315}};
316
317def format StoreAlt(code, *opt_flags) {{
318        (header_output,
319         decoder_output,
320         exec_output,
321         decode_block) = doMemFormat(code, StoreExecute,
322            privilegedString, name, Name, opt_flags)
323}};
324
325def format Load(code, *opt_flags) {{
326        (header_output,
327         decoder_output,
328         exec_output,
329         decode_block) = doMemFormat(code,
330             LoadExecute, '', name, Name, opt_flags)
331}};
332
333def format Store(code, *opt_flags) {{
334        (header_output,
335         decoder_output,
336         exec_output,
337         decode_block) = doMemFormat(code,
338             StoreExecute, '', name, Name, opt_flags)
339}};
340
341def format LoadStore(code, *opt_flags) {{
342        (header_output,
343         decoder_output,
344         exec_output,
345         decode_block) = doMemFormat(code,
346             LoadStoreExecute, '', name, Name, opt_flags)
347}};
348