fp.isa revision 7321
114299Sbbruce@ucdavis.edu// -*- mode:c++ -*-
214299Sbbruce@ucdavis.edu
314299Sbbruce@ucdavis.edu// Copyright (c) 2010 ARM Limited
414299Sbbruce@ucdavis.edu// All rights reserved
514299Sbbruce@ucdavis.edu//
614299Sbbruce@ucdavis.edu// The license below extends only to copyright in the software and shall
714299Sbbruce@ucdavis.edu// not be construed as granting a license to any other intellectual
814299Sbbruce@ucdavis.edu// property including but not limited to intellectual property relating
914299Sbbruce@ucdavis.edu// to a hardware implementation of the functionality of the software
1014299Sbbruce@ucdavis.edu// licensed hereunder.  You may use the software subject to the license
1114299Sbbruce@ucdavis.edu// terms below provided that you ensure that this notice is replicated
1214299Sbbruce@ucdavis.edu// unmodified and in its entirety in all distributions of the software,
1314299Sbbruce@ucdavis.edu// modified or unmodified, in source code or in binary form.
1414299Sbbruce@ucdavis.edu//
1514299Sbbruce@ucdavis.edu// Copyright (c) 2007-2008 The Florida State University
1614299Sbbruce@ucdavis.edu// All rights reserved.
1714299Sbbruce@ucdavis.edu//
1814299Sbbruce@ucdavis.edu// Redistribution and use in source and binary forms, with or without
1914299Sbbruce@ucdavis.edu// modification, are permitted provided that the following conditions are
2014299Sbbruce@ucdavis.edu// met: redistributions of source code must retain the above copyright
2114299Sbbruce@ucdavis.edu// notice, this list of conditions and the following disclaimer;
2214299Sbbruce@ucdavis.edu// redistributions in binary form must reproduce the above copyright
2314299Sbbruce@ucdavis.edu// notice, this list of conditions and the following disclaimer in the
2414299Sbbruce@ucdavis.edu// documentation and/or other materials provided with the distribution;
2514299Sbbruce@ucdavis.edu// neither the name of the copyright holders nor the names of its
2614299Sbbruce@ucdavis.edu// contributors may be used to endorse or promote products derived from
2714299Sbbruce@ucdavis.edu// this software without specific prior written permission.
2814299Sbbruce@ucdavis.edu//
2914299Sbbruce@ucdavis.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3014299Sbbruce@ucdavis.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3114299Sbbruce@ucdavis.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3214299Sbbruce@ucdavis.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3314299Sbbruce@ucdavis.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3414299Sbbruce@ucdavis.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3514299Sbbruce@ucdavis.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3614299Sbbruce@ucdavis.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3714299Sbbruce@ucdavis.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3814299Sbbruce@ucdavis.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3914299Sbbruce@ucdavis.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4014299Sbbruce@ucdavis.edu//
4114299Sbbruce@ucdavis.edu// Authors: Stephen Hines
4214299Sbbruce@ucdavis.edu
4314299Sbbruce@ucdavis.edu////////////////////////////////////////////////////////////////////
4414299Sbbruce@ucdavis.edu//
4514299Sbbruce@ucdavis.edu// Floating Point operate instructions
4614299Sbbruce@ucdavis.edu//
4714299Sbbruce@ucdavis.edu
4814299Sbbruce@ucdavis.edudef template FPAExecute {{
4914299Sbbruce@ucdavis.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
5014299Sbbruce@ucdavis.edu        {
5114299Sbbruce@ucdavis.edu                Fault fault = NoFault;
5214299Sbbruce@ucdavis.edu
5314299Sbbruce@ucdavis.edu                %(fp_enable_check)s;
5414299Sbbruce@ucdavis.edu
5514299Sbbruce@ucdavis.edu                %(op_decl)s;
5614299Sbbruce@ucdavis.edu                %(op_rd)s;
5714299Sbbruce@ucdavis.edu
5814299Sbbruce@ucdavis.edu                if (%(predicate_test)s) {
5914299Sbbruce@ucdavis.edu                    %(code)s;
6014299Sbbruce@ucdavis.edu                    if (fault == NoFault) {
6114299Sbbruce@ucdavis.edu                        %(op_wb)s;
6214299Sbbruce@ucdavis.edu                    }
6314299Sbbruce@ucdavis.edu                }
6414299Sbbruce@ucdavis.edu
6514299Sbbruce@ucdavis.edu                return fault;
6614299Sbbruce@ucdavis.edu        }
6714299Sbbruce@ucdavis.edu}};
6814299Sbbruce@ucdavis.edu
6914299Sbbruce@ucdavis.edudef template FloatDoubleDecode {{
7014299Sbbruce@ucdavis.edu    {
7114299Sbbruce@ucdavis.edu        ArmStaticInst *i = NULL;
7214299Sbbruce@ucdavis.edu        switch (OPCODE_19 << 1 | OPCODE_7)
7314299Sbbruce@ucdavis.edu        {
7414299Sbbruce@ucdavis.edu            case 0:
7514299Sbbruce@ucdavis.edu                i = (ArmStaticInst *)new %(class_name)sS(machInst);
7614299Sbbruce@ucdavis.edu                break;
7714299Sbbruce@ucdavis.edu            case 1:
7814299Sbbruce@ucdavis.edu                i = (ArmStaticInst *)new %(class_name)sD(machInst);
7914299Sbbruce@ucdavis.edu                break;
8014299Sbbruce@ucdavis.edu            case 2:
8114299Sbbruce@ucdavis.edu            case 3:
8214299Sbbruce@ucdavis.edu            default:
8314299Sbbruce@ucdavis.edu                panic("Cannot decode float/double nature of the instruction");
8414299Sbbruce@ucdavis.edu        }
8514299Sbbruce@ucdavis.edu        return i;
86    }
87}};
88
89// Primary format for float point operate instructions:
90def format FloatOp(code, *flags) {{
91        orig_code = code
92
93        cblk = code
94        iop = InstObjParams(name, Name, 'PredOp',
95                            {"code": cblk,
96                             "predicate_test": predicateTest},
97                            flags)
98        header_output = BasicDeclare.subst(iop)
99        decoder_output = BasicConstructor.subst(iop)
100        exec_output = FPAExecute.subst(iop)
101
102        sng_cblk = code
103        sng_iop = InstObjParams(name, Name+'S', 'PredOp',
104                                {"code": sng_cblk,
105                                 "predicate_test": predicateTest},
106                                flags)
107        header_output += BasicDeclare.subst(sng_iop)
108        decoder_output += BasicConstructor.subst(sng_iop)
109        exec_output += FPAExecute.subst(sng_iop)
110
111        dbl_code = re.sub(r'\.sf', '.df', orig_code)
112
113        dbl_cblk = dbl_code
114        dbl_iop = InstObjParams(name, Name+'D', 'PredOp',
115                                {"code": dbl_cblk,
116                                 "predicate_test": predicateTest},
117                                flags)
118        header_output += BasicDeclare.subst(dbl_iop)
119        decoder_output += BasicConstructor.subst(dbl_iop)
120        exec_output += FPAExecute.subst(dbl_iop)
121
122        decode_block = FloatDoubleDecode.subst(iop)
123}};
124
125let {{
126        calcFPCcCode = '''
127        uint16_t _in, _iz, _ic, _iv;
128
129        _in = %(fReg1)s < %(fReg2)s;
130        _iz = %(fReg1)s == %(fReg2)s;
131        _ic = %(fReg1)s >= %(fReg2)s;
132        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
133
134        CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
135            (CondCodes & 0x0FFFFFFF);
136        '''
137}};
138
139def format FloatCmp(fReg1, fReg2, *flags) {{
140        code = calcFPCcCode % vars()
141        iop = InstObjParams(name, Name, 'PredOp',
142                            {"code": code,
143                             "predicate_test": predicateTest},
144                             flags)
145        header_output = BasicDeclare.subst(iop)
146        decoder_output = BasicConstructor.subst(iop)
147        decode_block = BasicDecode.subst(iop)
148        exec_output = FPAExecute.subst(iop)
149}};
150
151def format ExtensionRegLoadStore() {{
152    decode_block = '''
153    {
154        const uint32_t opcode = bits(machInst, 24, 20);
155        const uint32_t offset = bits(machInst, 7, 0);
156        const bool single = bits(machInst, 22);
157        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
158        RegIndex vd;
159        if (single) {
160            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
161                                      bits(machInst, 22));
162        } else {
163            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
164                                      (bits(machInst, 22) << 5));
165        }
166        switch (bits(opcode, 4, 3)) {
167          case 0x0:
168            if (bits(opcode, 4, 1) == 0x2) {
169                return new WarnUnimplemented("core-to-extension-transfer",
170                                             machInst);
171            }
172            break;
173          case 0x1:
174            switch (bits(opcode, 1, 0)) {
175              case 0x0:
176                return new VLdmStm(machInst, rn, vd, single,
177                                   true, false, false, offset);
178              case 0x1:
179                return new VLdmStm(machInst, rn, vd, single,
180                                   true, false, true, offset);
181              case 0x2:
182                return new VLdmStm(machInst, rn, vd, single,
183                                   true, true, false, offset);
184              case 0x3:
185                // If rn == sp, then this is called vpop.
186                return new VLdmStm(machInst, rn, vd, single,
187                                   true, true, true, offset);
188            }
189          case 0x2:
190            if (bits(opcode, 1, 0) == 0x2) {
191                // If rn == sp, then this is called vpush.
192                return new VLdmStm(machInst, rn, vd, single,
193                                   false, true, false, offset);
194            } else if (bits(opcode, 1, 0) == 0x3) {
195                return new VLdmStm(machInst, rn, vd, single,
196                                   false, true, true, offset);
197            }
198            // Fall through on purpose
199          case 0x3:
200            if (bits(opcode, 1, 0) == 0x0) {
201                return new WarnUnimplemented("vstr", machInst);
202            } else if (bits(opcode, 1, 0) == 0x1) {
203                return new WarnUnimplemented("vldr", machInst);
204            }
205        }
206        return new Unknown(machInst);
207    }
208    '''
209}};
210
211def format ShortFpTransfer() {{
212    decode_block = '''
213    {
214        const uint32_t l = bits(machInst, 20);
215        const uint32_t c = bits(machInst, 8);
216        const uint32_t a = bits(machInst, 23, 21);
217        const uint32_t b = bits(machInst, 6, 5);
218        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
219            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
220            return new Unknown(machInst);
221        }
222        if (l == 0 && c == 0) {
223            if (a == 0) {
224                // A8-648
225                return new WarnUnimplemented("vmov", machInst);
226            } else if (a == 0x7) {
227                // A8-660
228                // B6-29
229                return new WarnUnimplemented("vmsr", machInst);
230            }
231        } else if (l == 0 && c == 1) {
232            if (bits(a, 2) == 0) {
233                // A8-644
234                return new WarnUnimplemented("vmov", machInst);
235            } else if (bits(b, 1) == 0) {
236                // A8-594
237                return new WarnUnimplemented("vdup", machInst);
238            }
239        } else if (l == 1 && c == 0) {
240            if (a == 0) {
241                // A8-648
242                return new WarnUnimplemented("vmov", machInst);
243            } else if (a == 7) {
244                // A8-658
245                // B6-27
246                return new WarnUnimplemented("vmrs", machInst);
247            }
248        } else {
249            // A8-646
250            return new WarnUnimplemented("vmov", machInst);
251        }
252        return new Unknown(machInst);
253    }
254    '''
255}};
256