int.isa revision 5222:bb733a878f85
1// -*- mode:c++ -*-
2
3// Copyright .AN) 2007 MIPS Technologies, Inc.  All Rights Reserved
4
5//  This software is part of the M5 simulator.
6
7//  THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING
8//  DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
9//  TO THESE TERMS AND CONDITIONS.
10
11//  Permission is granted to use, copy, create derivative works and
12//  distribute this software and such derivative works for any purpose,
13//  so long as (1) the copyright notice above, this grant of permission,
14//  and the disclaimer below appear in all copies and derivative works
15//  made, (2) the copyright notice above is augmented as appropriate to
16//  reflect the addition of any new copyrightable work in a derivative
17//  work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3)
18//  the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any
19//  advertising or publicity pertaining to the use or distribution of
20//  this software without specific, written prior authorization.
21
22//  THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B  MIPS MAKES NO WARRANTIES AND
23//  DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
24//  OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
26//  NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
27//  IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
28//  INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
29//  ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
30//  THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
31//  IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
32//  STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
33//  POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
34
35//Authors: Korey L. Sewell
36
37////////////////////////////////////////////////////////////////////
38//
39// Integer operate instructions
40//
41output header {{
42#include <iostream>
43    using namespace std;
44        /**
45         * Base class for integer operations.
46         */
47        class IntOp : public MipsStaticInst
48        {
49                protected:
50
51                /// Constructor
52                IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
53                                MipsStaticInst(mnem, _machInst, __opClass)
54                {
55                }
56
57                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
58        };
59
60
61        class HiLoOp: public IntOp
62        {
63                protected:
64
65                /// Constructor
66                HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
67                                IntOp(mnem, _machInst, __opClass)
68                {
69                }
70
71                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
72        };
73
74        class HiLoRsSelOp: public HiLoOp
75        {
76                protected:
77
78                /// Constructor
79                HiLoRsSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
80                                HiLoOp(mnem, _machInst, __opClass)
81                {
82                }
83
84                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
85        };
86
87        class HiLoRdSelOp: public HiLoOp
88        {
89                protected:
90
91                /// Constructor
92                HiLoRdSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
93                                HiLoOp(mnem, _machInst, __opClass)
94                {
95                }
96
97                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
98        };
99
100        class HiLoRdSelValOp: public HiLoOp
101        {
102                protected:
103
104                /// Constructor
105                HiLoRdSelValOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
106                                HiLoOp(mnem, _machInst, __opClass)
107                {
108                }
109
110                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
111        };
112
113        class IntImmOp : public MipsStaticInst
114        {
115                protected:
116
117                int16_t imm;
118                int32_t sextImm;
119                uint32_t zextImm;
120
121                /// Constructor
122                IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
123                    MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM),
124                    sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM)
125                {
126                    //If Bit 15 is 1 then Sign Extend
127                    int32_t temp = sextImm & 0x00008000;
128                    if (temp > 0 && mnemonic != "lui") {
129                        sextImm |= 0xFFFF0000;
130                    }
131                }
132
133                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
134
135
136        };
137
138}};
139
140// HiLo instruction class execute method template.
141def template HiLoExecute {{
142        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
143        {
144                Fault fault = NoFault;
145
146                %(fp_enable_check)s;
147                %(op_decl)s;
148                %(op_rd)s;
149                %(code)s;
150
151                if(fault == NoFault)
152                {
153                    %(op_wb)s;
154                }
155                return fault;
156        }
157}};
158
159// HiLoRsSel instruction class execute method template.
160def template HiLoRsSelExecute {{
161        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
162        {
163                Fault fault = NoFault;
164
165                %(op_decl)s;
166
167                if( ACSRC > 0 && !isDspEnabled(xc) )
168                {
169                    fault = new DspStateDisabledFault();
170                }
171                else
172                {
173                    %(op_rd)s;
174                    %(code)s;
175                }
176
177                if(fault == NoFault)
178                {
179                    %(op_wb)s;
180                }
181                return fault;
182        }
183}};
184
185// HiLoRdSel instruction class execute method template.
186def template HiLoRdSelExecute {{
187        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
188        {
189                Fault fault = NoFault;
190
191                %(op_decl)s;
192
193                if( ACDST > 0 && !isDspEnabled(xc) )
194                {
195                    fault = new DspStateDisabledFault();
196                }
197                else
198                {
199                    %(op_rd)s;
200                    %(code)s;
201                }
202
203                if(fault == NoFault)
204                {
205                    %(op_wb)s;
206                }
207                return fault;
208        }
209}};
210
211//Outputs to decoder.cc
212output decoder {{
213        std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
214        {
215            std::stringstream ss;
216
217            ccprintf(ss, "%-10s ", mnemonic);
218
219            // just print the first dest... if there's a second one,
220            // it's generally implicit
221            if (_numDestRegs > 0) {
222                printReg(ss, _destRegIdx[0]);
223                ss << ", ";
224            }
225
226            // just print the first two source regs... if there's
227            // a third one, it's a read-modify-write dest (Rc),
228            // e.g. for CMOVxx
229            if (_numSrcRegs > 0) {
230                printReg(ss, _srcRegIdx[0]);
231            }
232
233            if (_numSrcRegs > 1) {
234                ss << ", ";
235                printReg(ss, _srcRegIdx[1]);
236            }
237
238            return ss.str();
239        }
240
241        std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
242        {
243            std::stringstream ss;
244
245            ccprintf(ss, "%-10s ", mnemonic);
246
247            //Destination Registers are implicit for HI/LO ops
248            if (_numSrcRegs > 0) {
249                printReg(ss, _srcRegIdx[0]);
250            }
251
252            if (_numSrcRegs > 1) {
253                ss << ", ";
254                printReg(ss, _srcRegIdx[1]);
255            }
256
257            return ss.str();
258        }
259
260        std::string HiLoRsSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
261        {
262            std::stringstream ss;
263
264            ccprintf(ss, "%-10s ", mnemonic);
265
266            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
267                printReg(ss, _destRegIdx[0]);
268            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
269                printReg(ss, _srcRegIdx[0]);
270            }
271
272            return ss.str();
273        }
274
275        std::string HiLoRdSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
276        {
277            std::stringstream ss;
278
279            ccprintf(ss, "%-10s ", mnemonic);
280
281            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
282                printReg(ss, _destRegIdx[0]);
283            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
284                printReg(ss, _srcRegIdx[0]);
285            }
286
287            return ss.str();
288        }
289
290        std::string HiLoRdSelValOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
291        {
292            std::stringstream ss;
293
294            ccprintf(ss, "%-10s ", mnemonic);
295
296            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
297                printReg(ss, _destRegIdx[0]);
298            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
299                printReg(ss, _srcRegIdx[0]);
300            }
301
302            return ss.str();
303        }
304
305        std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
306        {
307            std::stringstream ss;
308
309            ccprintf(ss, "%-10s ", mnemonic);
310
311            if (_numDestRegs > 0) {
312                printReg(ss, _destRegIdx[0]);
313            }
314
315            ss << ", ";
316
317            if (_numSrcRegs > 0) {
318                printReg(ss, _srcRegIdx[0]);
319                ss << ", ";
320            }
321
322            if( mnemonic == "lui")
323                ccprintf(ss, "0x%x ", sextImm);
324            else
325                ss << (int) sextImm;
326
327            return ss.str();
328        }
329
330}};
331
332def format IntOp(code, *opt_flags) {{
333    iop = InstObjParams(name, Name, 'IntOp', code, opt_flags)
334    header_output = BasicDeclare.subst(iop)
335    decoder_output = BasicConstructor.subst(iop)
336    decode_block = RegNopCheckDecode.subst(iop)
337    exec_output = BasicExecute.subst(iop)
338}};
339
340def format IntImmOp(code, *opt_flags) {{
341    iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags)
342    header_output = BasicDeclare.subst(iop)
343    decoder_output = BasicConstructor.subst(iop)
344    decode_block = ImmNopCheckDecode.subst(iop)
345    exec_output = BasicExecute.subst(iop)
346}};
347
348def format HiLoRsSelOp(code, *opt_flags) {{
349    iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
350    header_output = BasicDeclare.subst(iop)
351    decoder_output = BasicConstructor.subst(iop)
352    decode_block = BasicDecode.subst(iop)
353    exec_output = HiLoRsSelExecute.subst(iop)
354}};
355
356def format HiLoRdSelOp(code, *opt_flags) {{
357    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
358    header_output = BasicDeclare.subst(iop)
359    decoder_output = BasicConstructor.subst(iop)
360    decode_block = BasicDecode.subst(iop)
361    exec_output = HiLoRdSelExecute.subst(iop)
362}};
363
364def format HiLoRdSelValOp(code, *opt_flags) {{
365
366    if '.sd' in code:
367        code = 'int64_t ' + code
368    elif '.ud' in code:
369        code = 'uint64_t ' + code
370
371    code += 'HI_RD_SEL = val<63:32>;\n'
372    code += 'LO_RD_SEL = val<31:0>;\n'
373
374    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
375    header_output = BasicDeclare.subst(iop)
376    decoder_output = BasicConstructor.subst(iop)
377    decode_block = BasicDecode.subst(iop)
378    exec_output = HiLoRdSelExecute.subst(iop)
379}};
380
381def format HiLoOp(code, *opt_flags) {{
382    iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
383    header_output = BasicDeclare.subst(iop)
384    decoder_output = BasicConstructor.subst(iop)
385    decode_block = BasicDecode.subst(iop)
386    exec_output = HiLoExecute.subst(iop)
387}};
388