fp.isa revision 7326:299edea3e5a2
110515SN/A// -*- mode:c++ -*-
210515SN/A
310515SN/A// Copyright (c) 2010 ARM Limited
410515SN/A// All rights reserved
510515SN/A//
610515SN/A// The license below extends only to copyright in the software and shall
710515SN/A// not be construed as granting a license to any other intellectual
810515SN/A// property including but not limited to intellectual property relating
910515SN/A// to a hardware implementation of the functionality of the software
1010515SN/A// licensed hereunder.  You may use the software subject to the license
1110515SN/A// terms below provided that you ensure that this notice is replicated
1210515SN/A// unmodified and in its entirety in all distributions of the software,
1310515SN/A// modified or unmodified, in source code or in binary form.
1410515SN/A//
1510636SN/A// Copyright (c) 2007-2008 The Florida State University
1610515SN/A// All rights reserved.
1710515SN/A//
1810515SN/A// Redistribution and use in source and binary forms, with or without
1910636SN/A// modification, are permitted provided that the following conditions are
2010515SN/A// met: redistributions of source code must retain the above copyright
2110515SN/A// notice, this list of conditions and the following disclaimer;
2210515SN/A// redistributions in binary form must reproduce the above copyright
2310515SN/A// notice, this list of conditions and the following disclaimer in the
2410515SN/A// documentation and/or other materials provided with the distribution;
2510515SN/A// neither the name of the copyright holders nor the names of its
2610515SN/A// contributors may be used to endorse or promote products derived from
2710515SN/A// this software without specific prior written permission.
2810515SN/A//
2910515SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3010515SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3110636SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3210515SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3310515SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3410515SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3510515SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610515SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3710515SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3810636SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910736SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4010515SN/A//
4110515SN/A// Authors: Stephen Hines
4210515SN/A
4310515SN/A////////////////////////////////////////////////////////////////////
4410515SN/A//
4510636SN/A// Floating Point operate instructions
4610515SN/A//
4710515SN/A
4810515SN/Adef template FPAExecute {{
4910515SN/A        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
5010515SN/A        {
5110515SN/A                Fault fault = NoFault;
5210515SN/A
5310515SN/A                %(fp_enable_check)s;
5410515SN/A
5510515SN/A                %(op_decl)s;
5610515SN/A                %(op_rd)s;
5710515SN/A
5810515SN/A                if (%(predicate_test)s) {
5910515SN/A                    %(code)s;
6010515SN/A                    if (fault == NoFault) {
6110515SN/A                        %(op_wb)s;
6210515SN/A                    }
6310515SN/A                }
6410515SN/A
6510515SN/A                return fault;
6610515SN/A        }
6710515SN/A}};
6810515SN/A
6910515SN/Adef template FloatDoubleDecode {{
7010515SN/A    {
7110515SN/A        ArmStaticInst *i = NULL;
7210515SN/A        switch (OPCODE_19 << 1 | OPCODE_7)
7310515SN/A        {
7410515SN/A            case 0:
7510515SN/A                i = (ArmStaticInst *)new %(class_name)sS(machInst);
7610515SN/A                break;
7710515SN/A            case 1:
7810515SN/A                i = (ArmStaticInst *)new %(class_name)sD(machInst);
7910515SN/A                break;
8010515SN/A            case 2:
8110515SN/A            case 3:
8210515SN/A            default:
8310515SN/A                panic("Cannot decode float/double nature of the instruction");
8410515SN/A        }
8510515SN/A        return i;
8610515SN/A    }
8710515SN/A}};
8810636SN/A
8910515SN/A// Primary format for float point operate instructions:
9010515SN/Adef format FloatOp(code, *flags) {{
9110515SN/A        orig_code = code
9210515SN/A
9310515SN/A        cblk = code
9410515SN/A        iop = InstObjParams(name, Name, 'PredOp',
9510515SN/A                            {"code": cblk,
9610515SN/A                             "predicate_test": predicateTest},
9710515SN/A                            flags)
9810515SN/A        header_output = BasicDeclare.subst(iop)
9910515SN/A        decoder_output = BasicConstructor.subst(iop)
10010515SN/A        exec_output = FPAExecute.subst(iop)
10110515SN/A
10210515SN/A        sng_cblk = code
10310515SN/A        sng_iop = InstObjParams(name, Name+'S', 'PredOp',
10410515SN/A                                {"code": sng_cblk,
10510515SN/A                                 "predicate_test": predicateTest},
10610515SN/A                                flags)
10710515SN/A        header_output += BasicDeclare.subst(sng_iop)
10810515SN/A        decoder_output += BasicConstructor.subst(sng_iop)
10910515SN/A        exec_output += FPAExecute.subst(sng_iop)
11010515SN/A
11110515SN/A        dbl_code = re.sub(r'\.sf', '.df', orig_code)
11210515SN/A
11310515SN/A        dbl_cblk = dbl_code
11410515SN/A        dbl_iop = InstObjParams(name, Name+'D', 'PredOp',
11510515SN/A                                {"code": dbl_cblk,
11610515SN/A                                 "predicate_test": predicateTest},
11710515SN/A                                flags)
11810515SN/A        header_output += BasicDeclare.subst(dbl_iop)
11910515SN/A        decoder_output += BasicConstructor.subst(dbl_iop)
12010515SN/A        exec_output += FPAExecute.subst(dbl_iop)
12110515SN/A
12210515SN/A        decode_block = FloatDoubleDecode.subst(iop)
12310515SN/A}};
12410515SN/A
12510515SN/Alet {{
12610515SN/A        calcFPCcCode = '''
12710515SN/A        uint16_t _in, _iz, _ic, _iv;
12810515SN/A
12910515SN/A        _in = %(fReg1)s < %(fReg2)s;
13010515SN/A        _iz = %(fReg1)s == %(fReg2)s;
13110515SN/A        _ic = %(fReg1)s >= %(fReg2)s;
13210515SN/A        _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1;
13310515SN/A
13410515SN/A        CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
13510515SN/A            (CondCodes & 0x0FFFFFFF);
13610515SN/A        '''
13710515SN/A}};
13810515SN/A
13910515SN/Adef format FloatCmp(fReg1, fReg2, *flags) {{
14010515SN/A        code = calcFPCcCode % vars()
14110515SN/A        iop = InstObjParams(name, Name, 'PredOp',
14210515SN/A                            {"code": code,
14310515SN/A                             "predicate_test": predicateTest},
14410636SN/A                             flags)
14510515SN/A        header_output = BasicDeclare.subst(iop)
14610515SN/A        decoder_output = BasicConstructor.subst(iop)
14710515SN/A        decode_block = BasicDecode.subst(iop)
14810900Snilay@cs.wisc.edu        exec_output = FPAExecute.subst(iop)
14910515SN/A}};
15010515SN/A
15110515SN/Adef format ExtensionRegLoadStore() {{
15210515SN/A    decode_block = '''
15310515SN/A    {
15410515SN/A        const uint32_t opcode = bits(machInst, 24, 20);
15510515SN/A        const uint32_t offset = bits(machInst, 7, 0);
15610515SN/A        const bool single = bits(machInst, 22);
15710515SN/A        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
15810515SN/A        RegIndex vd;
15910515SN/A        if (single) {
16010515SN/A            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
16110515SN/A                                      bits(machInst, 22));
16210515SN/A        } else {
16310515SN/A            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
16410515SN/A                                      (bits(machInst, 22) << 5));
16510515SN/A        }
16610515SN/A        switch (bits(opcode, 4, 3)) {
16710515SN/A          case 0x0:
16810515SN/A            if (bits(opcode, 4, 1) == 0x2) {
16910515SN/A                return new WarnUnimplemented("core-to-extension-transfer",
17010515SN/A                                             machInst);
17110515SN/A            }
17210515SN/A            break;
17310515SN/A          case 0x1:
17410515SN/A            switch (bits(opcode, 1, 0)) {
17510515SN/A              case 0x0:
17610515SN/A                return new VLdmStm(machInst, rn, vd, single,
17710515SN/A                                   true, false, false, offset);
17810736SN/A              case 0x1:
17910515SN/A                return new VLdmStm(machInst, rn, vd, single,
18010515SN/A                                   true, false, true, offset);
18110515SN/A              case 0x2:
18210515SN/A                return new VLdmStm(machInst, rn, vd, single,
18310515SN/A                                   true, true, false, offset);
18410515SN/A              case 0x3:
18510515SN/A                // If rn == sp, then this is called vpop.
18610515SN/A                return new VLdmStm(machInst, rn, vd, single,
18710515SN/A                                   true, true, true, offset);
18810515SN/A            }
18910515SN/A          case 0x2:
19010515SN/A            if (bits(opcode, 1, 0) == 0x2) {
19110515SN/A                // If rn == sp, then this is called vpush.
19210515SN/A                return new VLdmStm(machInst, rn, vd, single,
19310515SN/A                                   false, true, false, offset);
19410515SN/A            } else if (bits(opcode, 1, 0) == 0x3) {
19510515SN/A                return new VLdmStm(machInst, rn, vd, single,
19610515SN/A                                   false, true, true, offset);
19710515SN/A            }
19810515SN/A            // Fall through on purpose
19910515SN/A          case 0x3:
20010515SN/A            if (bits(opcode, 1, 0) == 0x0) {
20110515SN/A                return new WarnUnimplemented("vstr", machInst);
20210515SN/A            } else if (bits(opcode, 1, 0) == 0x1) {
20310515SN/A                return new WarnUnimplemented("vldr", machInst);
20410515SN/A            }
20510515SN/A        }
20610515SN/A        return new Unknown(machInst);
20710515SN/A    }
20810515SN/A    '''
20910515SN/A}};
21010515SN/A
21110515SN/Adef format ShortFpTransfer() {{
21210515SN/A    decode_block = '''
21310515SN/A    {
21410515SN/A        const uint32_t l = bits(machInst, 20);
21510515SN/A        const uint32_t c = bits(machInst, 8);
21610515SN/A        const uint32_t a = bits(machInst, 23, 21);
21710515SN/A        const uint32_t b = bits(machInst, 6, 5);
21810515SN/A        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
21910515SN/A            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
22010636SN/A            return new Unknown(machInst);
22110515SN/A        }
22210515SN/A        if (l == 0 && c == 0) {
22310515SN/A            if (a == 0) {
22410900Snilay@cs.wisc.edu                // A8-648
22510515SN/A                return new WarnUnimplemented("vmov", machInst);
22610515SN/A            } else if (a == 0x7) {
22710515SN/A                const IntRegIndex rt =
22810515SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
22910515SN/A                uint32_t specReg = bits(machInst, 19, 16);
23010515SN/A                switch (specReg) {
23110515SN/A                  case 0:
23210515SN/A                    specReg = MISCREG_FPSID;
23310515SN/A                    break;
23410515SN/A                  case 1:
23510515SN/A                    specReg = MISCREG_FPSCR;
23610515SN/A                    break;
23710515SN/A                  case 8:
23810515SN/A                    specReg = MISCREG_FPEXC;
23910515SN/A                    break;
24010515SN/A                  default:
24110515SN/A                    return new Unknown(machInst);
24210515SN/A                }
24310515SN/A                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
24410515SN/A            }
24510515SN/A        } else if (l == 0 && c == 1) {
24610515SN/A            if (bits(a, 2) == 0) {
24710515SN/A                // A8-644
24810515SN/A                return new WarnUnimplemented("vmov", machInst);
24910515SN/A            } else if (bits(b, 1) == 0) {
25010515SN/A                // A8-594
25110515SN/A                return new WarnUnimplemented("vdup", machInst);
25210515SN/A            }
25310515SN/A        } else if (l == 1 && c == 0) {
25410515SN/A            if (a == 0) {
25510515SN/A                // A8-648
25610515SN/A                return new WarnUnimplemented("vmov", machInst);
25710515SN/A            } else if (a == 7) {
25810515SN/A                const IntRegIndex rt =
25910515SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
26010515SN/A                uint32_t specReg = bits(machInst, 19, 16);
26110515SN/A                switch (specReg) {
26210515SN/A                  case 0:
26310515SN/A                    specReg = MISCREG_FPSID;
26410515SN/A                    break;
26510515SN/A                  case 1:
26610515SN/A                    specReg = MISCREG_FPSCR;
26710515SN/A                    break;
26810515SN/A                  case 6:
26910515SN/A                    specReg = MISCREG_MVFR1;
27010515SN/A                    break;
27110515SN/A                  case 7:
27210515SN/A                    specReg = MISCREG_MVFR0;
27310515SN/A                    break;
27410515SN/A                  case 8:
27510515SN/A                    specReg = MISCREG_FPEXC;
27610515SN/A                    break;
27710515SN/A                  default:
27810515SN/A                    return new Unknown(machInst);
27910515SN/A                }
28010515SN/A                return new Vmrs(machInst, rt, (IntRegIndex)specReg);
28110515SN/A            }
28210515SN/A        } else {
28310515SN/A            // A8-646
28410515SN/A            return new WarnUnimplemented("vmov", machInst);
28510515SN/A        }
28610515SN/A        return new Unknown(machInst);
28710515SN/A    }
28810736SN/A    '''
28910515SN/A}};
29010515SN/A