pred.isa revision 7110
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Predicated Instruction Execution
46//
47
48let {{
49    predicateTest = 'testPredicate(CondCodes, condCode)'
50}};
51
52def template PredOpExecute {{
53    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
54    {
55        Fault fault = NoFault;
56        uint64_t resTemp = 0;
57        resTemp = resTemp;
58        %(op_decl)s;
59        %(op_rd)s;
60
61        if (%(predicate_test)s)
62        {
63            %(code)s;
64            if (fault == NoFault)
65            {
66                %(op_wb)s;
67            }
68        }
69
70        return fault;
71    }
72}};
73
74def template DataDecode {{
75    if (machInst.opcode4 == 0) {
76        if (machInst.sField == 0)
77            return new %(class_name)sImm(machInst);
78        else
79            return new %(class_name)sImmCc(machInst);
80    } else {
81        if (machInst.sField == 0)
82            return new %(class_name)s(machInst);
83        else
84            return new %(class_name)sCc(machInst);
85    }
86}};
87
88def template DataImmDecode {{
89    if (machInst.sField == 0)
90        return new %(class_name)s(machInst);
91    else
92        return new %(class_name)sCc(machInst);
93}};
94
95let {{
96 
97     calcCcCode = '''
98        if (%(canOverflow)s){
99           cprintf("canOverflow: %%d\\n", Rd < resTemp);
100           replaceBits(CondCodes, 27, Rd < resTemp);
101        } else {
102            uint16_t _ic, _iv, _iz, _in;
103            _in = (resTemp >> %(negBit)d) & 1;
104            _iz = (resTemp == 0);
105            _iv = %(ivValue)s & 1;
106            _ic = %(icValue)s & 1;
107            
108            CondCodes =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
109                (CondCodes & 0x0FFFFFFF);
110
111            DPRINTF(Arm, "in = %%d\\n", _in);
112            DPRINTF(Arm, "iz = %%d\\n", _iz);
113            DPRINTF(Arm, "ic = %%d\\n", _ic);
114            DPRINTF(Arm, "iv = %%d\\n", _iv);
115        }
116        '''
117}};
118
119let {{
120    def getCcCode(flagtype):
121        icReg = icImm = iv = ''
122        negBit = 31
123        canOverflow = 'false'
124
125        if flagtype == "none":
126            icReg = icImm = 'CondCodes<29:>'
127            iv = 'CondCodes<28:>'
128        elif flagtype == "llbit":
129            icReg = icImm = 'CondCodes<29:>'
130            iv = 'CondCodes<28:>'
131            negBit = 63
132        elif flagtype == "overflow":
133            canOverflow = "true" 
134            icReg = icImm = iv = '0'
135        elif flagtype == "add":
136            icReg = icImm = 'findCarry(32, resTemp, Rn, op2)'
137            iv = 'findOverflow(32, resTemp, Rn, op2)'
138        elif flagtype == "sub":
139            icReg = icImm ='findCarry(32, resTemp, Rn, ~op2)'
140            iv = 'findOverflow(32, resTemp, Rn, ~op2)'
141        elif flagtype == "rsb":
142            icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)'
143            iv = 'findOverflow(32, resTemp, op2, ~Rn)'
144        else:
145            icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)'
146            icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)'
147            iv = 'CondCodes<28:>'
148        return (calcCcCode % {"icValue" : icReg, 
149                              "ivValue" : iv, 
150                              "negBit" : negBit,
151                              "canOverflow" : canOverflow },
152               calcCcCode % {"icValue" : icImm, 
153                              "ivValue" : iv, 
154                              "negBit" : negBit,
155                              "canOverflow" : canOverflow })
156
157    def getImmCcCode(flagtype):
158        ivValue = icValue = ''
159        negBit = 31
160        canOverflow = 'false'
161        if flagtype == "none":
162            icValue = 'CondCodes<29:>'
163            ivValue = 'CondCodes<28:>'
164        elif flagtype == "llbit":
165            icValue = 'CondCodes<29:>'
166            ivValue = 'CondCodes<28:>'
167            negBit = 63
168        elif flagtype == "overflow":
169            icVaule = ivValue = '0'
170            canOverflow = "true" 
171        elif flagtype == "add":
172            icValue = 'findCarry(32, resTemp, Rn, rotated_imm)'
173            ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)'
174        elif flagtype == "sub":
175            icValue = 'findCarry(32, resTemp, Rn, ~rotated_imm)'
176            ivValue = 'findOverflow(32, resTemp, Rn, ~rotated_imm)'
177        elif flagtype == "rsb":
178            icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)'
179            ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)'
180        elif flagtype == "modImm":
181            icValue = 'rotated_carry'
182            ivValue = 'CondCodes<28:>'
183        else:
184            icValue = '(rotate ? rotated_carry:CondCodes<29:>)'
185            ivValue = 'CondCodes<28:>'
186        return calcCcCode % vars()
187}};
188
189def format DataOp(code, flagtype = logic) {{
190    (regCcCode, immCcCode) = getCcCode(flagtype)
191    regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>,
192                                            shift, CondCodes<29:>);
193                 op2 = op2;''' + code
194    immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size,
195                                             shift, CondCodes<29:>);
196                 op2 = op2;''' + code
197    regIop = InstObjParams(name, Name, 'PredIntOp',
198                           {"code": regCode,
199                            "predicate_test": predicateTest})
200    immIop = InstObjParams(name, Name + "Imm", 'PredIntOp',
201                           {"code": immCode,
202                            "predicate_test": predicateTest})
203    regCcIop = InstObjParams(name, Name + "Cc", 'PredIntOp',
204                             {"code": regCode + regCcCode,
205                              "predicate_test": predicateTest})
206    immCcIop = InstObjParams(name, Name + "ImmCc", 'PredIntOp',
207                             {"code": immCode + immCcCode,
208                              "predicate_test": predicateTest})
209    header_output = BasicDeclare.subst(regIop) + \
210                    BasicDeclare.subst(immIop) + \
211                    BasicDeclare.subst(regCcIop) + \
212                    BasicDeclare.subst(immCcIop)
213    decoder_output = BasicConstructor.subst(regIop) + \
214                     BasicConstructor.subst(immIop) + \
215                     BasicConstructor.subst(regCcIop) + \
216                     BasicConstructor.subst(immCcIop)
217    exec_output = PredOpExecute.subst(regIop) + \
218                  PredOpExecute.subst(immIop) + \
219                  PredOpExecute.subst(regCcIop) + \
220                  PredOpExecute.subst(immCcIop)
221    decode_block = DataDecode.subst(regIop)
222}};
223
224def format DataImmOp(code, flagtype = logic) {{
225    code += "resTemp = resTemp;"
226    iop = InstObjParams(name, Name, 'PredImmOp',
227                        {"code": code,
228                         "predicate_test": predicateTest})
229    ccIop = InstObjParams(name, Name + "Cc", 'PredImmOp',
230                          {"code": code + getImmCcCode(flagtype),
231                           "predicate_test": predicateTest})
232    header_output = BasicDeclare.subst(iop) + \
233                    BasicDeclare.subst(ccIop)
234    decoder_output = BasicConstructor.subst(iop) + \
235                     BasicConstructor.subst(ccIop)
236    exec_output = PredOpExecute.subst(iop) + \
237                  PredOpExecute.subst(ccIop)
238    decode_block = DataImmDecode.subst(iop)
239}};
240
241def format DataModImmOp(code, flagtype = modImm) {{
242    code += "resTemp = resTemp;"
243    iop = InstObjParams(name, Name + "ModImm", 'PredModImmOp',
244                        {"code": code,
245                         "predicate_test": predicateTest})
246    ccIop = InstObjParams(name, Name + "ModImmCc", 'PredModImmOp',
247                          {"code": code + getImmCcCode(flagtype),
248                           "predicate_test": predicateTest})
249    header_output = BasicDeclare.subst(iop) + \
250                    BasicDeclare.subst(ccIop)
251    decoder_output = BasicConstructor.subst(iop) + \
252                     BasicConstructor.subst(ccIop)
253    exec_output = PredOpExecute.subst(iop) + \
254                  PredOpExecute.subst(ccIop)
255    decode_block = DataImmDecode.subst(iop)
256}};
257
258def format PredOp(code, *opt_flags) {{
259    iop = InstObjParams(name, Name, 'PredOp',
260                        {"code": code,
261                         "predicate_test": predicateTest},
262                        opt_flags)
263    header_output = BasicDeclare.subst(iop)
264    decoder_output = BasicConstructor.subst(iop)
265    decode_block = BasicDecode.subst(iop)
266    exec_output = PredOpExecute.subst(iop)
267}};
268
269def format PredImmOp(code, *opt_flags) {{
270    iop = InstObjParams(name, Name, 'PredImmOp',
271                        {"code": code,
272                         "predicate_test": predicateTest},
273                        opt_flags)
274    header_output = BasicDeclare.subst(iop)
275    decoder_output = BasicConstructor.subst(iop)
276    decode_block = BasicDecode.subst(iop)
277    exec_output = PredOpExecute.subst(iop)
278}};
279
280def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
281    ccCode = calcCcCode % vars()
282    code += ccCode;
283    iop = InstObjParams(name, Name, 'PredImmOp',
284                        {"code": code,
285                         "cc_code": ccCode,
286                         "predicate_test": predicateTest},
287                        opt_flags)
288    header_output = BasicDeclare.subst(iop)
289    decoder_output = BasicConstructor.subst(iop)
290    decode_block = BasicDecode.subst(iop)
291    exec_output = PredOpExecute.subst(iop)
292}};
293
294def format PredIntOp(code, *opt_flags) {{
295    new_code = ArmGenericCodeSubs(code)
296    iop = InstObjParams(name, Name, 'PredIntOp',
297                        {"code": new_code,
298                         "predicate_test": predicateTest},
299                        opt_flags)
300    header_output = BasicDeclare.subst(iop)
301    decoder_output = BasicConstructor.subst(iop)
302    decode_block = BasicDecode.subst(iop)
303    exec_output = PredOpExecute.subst(iop)
304}};
305
306def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
307    ccCode = calcCcCode % vars()
308    code += ccCode;
309    new_code = ArmGenericCodeSubs(code)
310    iop = InstObjParams(name, Name, 'PredIntOp',
311                        {"code": new_code,
312                         "cc_code": ccCode,
313                         "predicate_test": predicateTest},
314                        opt_flags)
315    header_output = BasicDeclare.subst(iop)
316    decoder_output = BasicConstructor.subst(iop)
317    decode_block = BasicDecode.subst(iop)
318    exec_output = PredOpExecute.subst(iop)
319}};
320
321