mt.isa revision 4661
1// -*- mode:c++ -*-
2
3// Copyright (c) 2006 The Regents of The University of Michigan
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: Korey Sewell
30
31////////////////////////////////////////////////////////////////////
32//
33// MT instructions
34//
35
36output header {{
37        /**
38         * Base class for MIPS MT ASE operations.
39         */
40        class MTOp : public MipsStaticInst
41        {
42                protected:
43
44                /// Constructor
45                MTOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
46                    MipsStaticInst(mnem, _machInst, __opClass), user_mode(false)
47                {
48                }
49
50               std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
51
52                bool user_mode;
53        };
54
55        class MTUserModeOp : public MTOp
56        {
57                protected:
58
59                /// Constructor
60                MTUserModeOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
61                    MTOp(mnem, _machInst, __opClass)
62                {
63                    user_mode = true;
64                }
65
66            //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
67        };
68}};
69
70output decoder {{
71    std::string MTOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
72    {
73        std::stringstream ss;
74
75        if (mnemonic == "mttc0" || mnemonic == "mftc0") {
76            ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
77        } else if (mnemonic == "mftgpr") {
78            ccprintf(ss, "%-10s r%d, r%d", mnemonic, RD, RT);
79        } else {
80            ccprintf(ss, "%-10s r%d, r%d", mnemonic, RT, RD);
81        }
82
83        return ss.str();
84    }
85}};
86
87output exec {{
88    void getThrRegExValues(%(CPU_exec_context)s *xc, unsigned &vpe_conf0, unsigned &tc_bind_mt, unsigned &tc_bind, unsigned &vpe_control, unsigned &mvp_conf0)
89    {
90        vpe_conf0 = xc->readMiscReg(VPEConf0);
91        tc_bind_mt = xc->readRegOtherThread(TCBind + Ctrl_Base_DepTag);
92        tc_bind = xc->readMiscReg(TCBind);
93        vpe_control = xc->readMiscReg(VPEControl);
94        mvp_conf0 = xc->readMiscReg(MVPConf0);
95    }
96
97    void getMTExValues(%(CPU_exec_context)s *xc, unsigned &config3)
98    {
99        config3 = xc->readMiscReg(Config3_MT);
100    }
101}};
102
103def template ThreadRegisterExecute {{
104        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
105        {
106            Fault fault = NoFault;
107            int64_t data;
108            %(op_decl)s;
109            %(op_rd)s;
110
111            unsigned vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0;
112
113            getThrRegExValues(xc, vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0);
114
115            if (isCoprocessorEnabled(xc, 0)) {
116                if (bits(vpe_conf0, VPEC0_MVP) == 0 &&
117                    bits(tc_bind_mt, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) !=
118                    bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
119                    data = -1;
120                } else if (bits(vpe_control, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO) >
121                           bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO)) {
122                    data = -1;
123                } else {
124                    int top_bit = 0;
125                    int bottom_bit = 0;
126
127                    if (MT_H == 1) {
128                        top_bit = 63;
129                        bottom_bit = 32;
130                    } else {
131                        top_bit = 31;
132                        bottom_bit = 0;
133                    }
134
135                    %(code)s;
136                }
137            } else {
138                fault = new CoprocessorUnusableFault();
139            }
140
141            if(fault == NoFault)
142            {
143                %(op_wb)s;
144            }
145
146            return fault;
147        }
148}};
149
150def template MTExecute{{
151        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
152        {
153                Fault fault = NoFault;
154                %(op_decl)s;
155                %(op_rd)s;
156
157                unsigned config3;
158
159                getMTExValues(xc, config3);
160
161                if (isCoprocessorEnabled(xc, 0)) {
162                    if (bits(config3, CFG3_MT) == 1) {
163                        %(code)s;
164                    } else {
165                        fault = new ReservedInstructionFault();
166                    }
167                } else {
168                    fault = new CoprocessorUnusableFault();
169                }
170
171                if(fault == NoFault)
172                {
173                    %(op_wb)s;
174                }
175                return fault;
176        }
177}};
178
179// Primary format for integer operate instructions:
180def format MT_Control(code, *opt_flags) {{
181        inst_flags = ('IsNonSpeculative', )
182        op_type = 'MTOp'
183
184        for x in opt_flags:
185            if x == 'UserMode':
186                op_type = 'MTUserModeOp'
187            else:
188                inst_flags += (x, )
189
190        iop = InstObjParams(name, Name, op_type, code, inst_flags)
191        header_output = BasicDeclare.subst(iop)
192        decoder_output = BasicConstructor.subst(iop)
193        decode_block = BasicDecode.subst(iop)
194        exec_output = MTExecute.subst(iop)
195}};
196
197def format MT_MFTR(code, *flags) {{
198        flags += ('IsNonSpeculative', )
199#        code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
200
201        code += 'if (MT_H == 1) {\n'
202        code += 'data = bits(data, top_bit, bottom_bit);\n'
203        code += '}\n'
204        code += 'Rd = data;\n'
205
206        iop = InstObjParams(name, Name, 'MTOp', code, flags)
207        header_output = BasicDeclare.subst(iop)
208        decoder_output = BasicConstructor.subst(iop)
209        decode_block = BasicDecode.subst(iop)
210        exec_output = ThreadRegisterExecute.subst(iop)
211}};
212
213def format MT_MTTR(code, *flags) {{
214        flags += ('IsNonSpeculative', )
215#        code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
216        iop = InstObjParams(name, Name, 'MTOp', code, flags)
217        header_output = BasicDeclare.subst(iop)
218        decoder_output = BasicConstructor.subst(iop)
219        decode_block = BasicDecode.subst(iop)
220        exec_output = ThreadRegisterExecute.subst(iop)
221}};
222