fp.isa revision 7366
16657Snate@binkert.org// -*- mode:c++ -*- 26657Snate@binkert.org 36657Snate@binkert.org// Copyright (c) 2010 ARM Limited 46657Snate@binkert.org// All rights reserved 56657Snate@binkert.org// 66657Snate@binkert.org// The license below extends only to copyright in the software and shall 76657Snate@binkert.org// not be construed as granting a license to any other intellectual 86657Snate@binkert.org// property including but not limited to intellectual property relating 96657Snate@binkert.org// to a hardware implementation of the functionality of the software 106657Snate@binkert.org// licensed hereunder. You may use the software subject to the license 116657Snate@binkert.org// terms below provided that you ensure that this notice is replicated 126657Snate@binkert.org// unmodified and in its entirety in all distributions of the software, 136657Snate@binkert.org// modified or unmodified, in source code or in binary form. 146657Snate@binkert.org// 156657Snate@binkert.org// Copyright (c) 2007-2008 The Florida State University 166657Snate@binkert.org// All rights reserved. 176657Snate@binkert.org// 186657Snate@binkert.org// Redistribution and use in source and binary forms, with or without 196657Snate@binkert.org// modification, are permitted provided that the following conditions are 206657Snate@binkert.org// met: redistributions of source code must retain the above copyright 216657Snate@binkert.org// notice, this list of conditions and the following disclaimer; 226657Snate@binkert.org// redistributions in binary form must reproduce the above copyright 236657Snate@binkert.org// notice, this list of conditions and the following disclaimer in the 246657Snate@binkert.org// documentation and/or other materials provided with the distribution; 256657Snate@binkert.org// neither the name of the copyright holders nor the names of its 266657Snate@binkert.org// contributors may be used to endorse or promote products derived from 276657Snate@binkert.org// this software without specific prior written permission. 2813672Sandreas.sandberg@arm.com// 296657Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306657Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316657Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 329302Snilay@cs.wisc.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336657Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3411117Snilay@cs.wisc.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3511117Snilay@cs.wisc.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3611117Snilay@cs.wisc.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3711117Snilay@cs.wisc.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3811117Snilay@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396657Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406657Snate@binkert.org// 416657Snate@binkert.org// Authors: Stephen Hines 426657Snate@binkert.org 436657Snate@binkert.org//////////////////////////////////////////////////////////////////// 446657Snate@binkert.org// 4511283Santhony.gutierrez@amd.com// Floating Point operate instructions 466657Snate@binkert.org// 476657Snate@binkert.org 486657Snate@binkert.orgdef template FPAExecute {{ 496657Snate@binkert.org Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 506657Snate@binkert.org { 516882SBrad.Beckmann@amd.com Fault fault = NoFault; 526657Snate@binkert.org 536657Snate@binkert.org %(fp_enable_check)s; 546657Snate@binkert.org 556657Snate@binkert.org %(op_decl)s; 566657Snate@binkert.org %(op_rd)s; 576657Snate@binkert.org 586657Snate@binkert.org if (%(predicate_test)s) { 596657Snate@binkert.org %(code)s; 606657Snate@binkert.org if (fault == NoFault) { 616657Snate@binkert.org %(op_wb)s; 626657Snate@binkert.org } 636657Snate@binkert.org } 646657Snate@binkert.org 6510895Snilay@cs.wisc.edu return fault; 666657Snate@binkert.org } 676657Snate@binkert.org}}; 686657Snate@binkert.org 6910228Snilay@cs.wisc.edudef template FloatDoubleDecode {{ 706657Snate@binkert.org { 716657Snate@binkert.org ArmStaticInst *i = NULL; 7210228Snilay@cs.wisc.edu switch (OPCODE_19 << 1 | OPCODE_7) 736657Snate@binkert.org { 746657Snate@binkert.org case 0: 756657Snate@binkert.org i = (ArmStaticInst *)new %(class_name)sS(machInst); 766657Snate@binkert.org break; 776657Snate@binkert.org case 1: 786657Snate@binkert.org i = (ArmStaticInst *)new %(class_name)sD(machInst); 796657Snate@binkert.org break; 806657Snate@binkert.org case 2: 816657Snate@binkert.org case 3: 826657Snate@binkert.org default: 836657Snate@binkert.org panic("Cannot decode float/double nature of the instruction"); 846657Snate@binkert.org } 856657Snate@binkert.org return i; 866657Snate@binkert.org } 876657Snate@binkert.org}}; 886657Snate@binkert.org 898086SBrad.Beckmann@amd.com// Primary format for float point operate instructions: 908086SBrad.Beckmann@amd.comdef format FloatOp(code, *flags) {{ 918086SBrad.Beckmann@amd.com orig_code = code 9213672Sandreas.sandberg@arm.com 936657Snate@binkert.org cblk = code 9413672Sandreas.sandberg@arm.com iop = InstObjParams(name, Name, 'PredOp', 956657Snate@binkert.org {"code": cblk, 966657Snate@binkert.org "predicate_test": predicateTest}, 976657Snate@binkert.org flags) 986657Snate@binkert.org header_output = BasicDeclare.subst(iop) 9910895Snilay@cs.wisc.edu decoder_output = BasicConstructor.subst(iop) 1006657Snate@binkert.org exec_output = FPAExecute.subst(iop) 1016657Snate@binkert.org 1026657Snate@binkert.org sng_cblk = code 1036657Snate@binkert.org sng_iop = InstObjParams(name, Name+'S', 'PredOp', 1046657Snate@binkert.org {"code": sng_cblk, 1056657Snate@binkert.org "predicate_test": predicateTest}, 1066657Snate@binkert.org flags) 1076657Snate@binkert.org header_output += BasicDeclare.subst(sng_iop) 1086657Snate@binkert.org decoder_output += BasicConstructor.subst(sng_iop) 1096657Snate@binkert.org exec_output += FPAExecute.subst(sng_iop) 1106657Snate@binkert.org 1116657Snate@binkert.org dbl_code = re.sub(r'\.sf', '.df', orig_code) 1126657Snate@binkert.org 1136657Snate@binkert.org dbl_cblk = dbl_code 1146657Snate@binkert.org dbl_iop = InstObjParams(name, Name+'D', 'PredOp', 1156657Snate@binkert.org {"code": dbl_cblk, 1166657Snate@binkert.org "predicate_test": predicateTest}, 1176657Snate@binkert.org flags) 1186657Snate@binkert.org header_output += BasicDeclare.subst(dbl_iop) 1196657Snate@binkert.org decoder_output += BasicConstructor.subst(dbl_iop) 1206657Snate@binkert.org exec_output += FPAExecute.subst(dbl_iop) 1216657Snate@binkert.org 1226657Snate@binkert.org decode_block = FloatDoubleDecode.subst(iop) 1236657Snate@binkert.org}}; 1246657Snate@binkert.org 1256657Snate@binkert.orglet {{ 1269298Snilay@cs.wisc.edu calcFPCcCode = ''' 1276657Snate@binkert.org uint16_t _in, _iz, _ic, _iv; 1286657Snate@binkert.org 1296657Snate@binkert.org _in = %(fReg1)s < %(fReg2)s; 13011117Snilay@cs.wisc.edu _iz = %(fReg1)s == %(fReg2)s; 13111117Snilay@cs.wisc.edu _ic = %(fReg1)s >= %(fReg2)s; 13211117Snilay@cs.wisc.edu _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1; 1336657Snate@binkert.org 13411117Snilay@cs.wisc.edu CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | 1356657Snate@binkert.org (CondCodes & 0x0FFFFFFF); 1366657Snate@binkert.org ''' 1376657Snate@binkert.org}}; 1386657Snate@binkert.org 1396657Snate@binkert.orgdef format FloatCmp(fReg1, fReg2, *flags) {{ 1406657Snate@binkert.org code = calcFPCcCode % vars() 1416657Snate@binkert.org iop = InstObjParams(name, Name, 'PredOp', 1426657Snate@binkert.org {"code": code, 1436882SBrad.Beckmann@amd.com "predicate_test": predicateTest}, 1446882SBrad.Beckmann@amd.com flags) 1456882SBrad.Beckmann@amd.com header_output = BasicDeclare.subst(iop) 1468086SBrad.Beckmann@amd.com decoder_output = BasicConstructor.subst(iop) 1478086SBrad.Beckmann@amd.com decode_block = BasicDecode.subst(iop) 1488086SBrad.Beckmann@amd.com exec_output = FPAExecute.subst(iop) 14910307Snilay@cs.wisc.edu}}; 15010307Snilay@cs.wisc.edu 1516657Snate@binkert.orglet {{ 1526657Snate@binkert.org header_output = ''' 1536657Snate@binkert.org StaticInstPtr 15410307Snilay@cs.wisc.edu decodeExtensionRegLoadStore(ExtMachInst machInst); 1559298Snilay@cs.wisc.edu ''' 1569298Snilay@cs.wisc.edu decoder_output = ''' 1579298Snilay@cs.wisc.edu StaticInstPtr 1586657Snate@binkert.org decodeExtensionRegLoadStore(ExtMachInst machInst) 1596657Snate@binkert.org { 1606657Snate@binkert.org const uint32_t opcode = bits(machInst, 24, 20); 1616657Snate@binkert.org const uint32_t offset = bits(machInst, 7, 0); 1626657Snate@binkert.org const bool single = (bits(machInst, 8) == 0); 1636657Snate@binkert.org const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1646657Snate@binkert.org RegIndex vd; 1656657Snate@binkert.org if (single) { 1666657Snate@binkert.org vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1676657Snate@binkert.org bits(machInst, 22)); 1686657Snate@binkert.org } else { 16911283Santhony.gutierrez@amd.com vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 17011283Santhony.gutierrez@amd.com (bits(machInst, 22) << 5)); 17111283Santhony.gutierrez@amd.com } 17211283Santhony.gutierrez@amd.com switch (bits(opcode, 4, 3)) { 17311283Santhony.gutierrez@amd.com case 0x0: 17411283Santhony.gutierrez@amd.com if (bits(opcode, 4, 1) == 0x2 && 17511283Santhony.gutierrez@amd.com !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 17611283Santhony.gutierrez@amd.com !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1779219Spower.jg@gmail.com if ((bits(machInst, 7, 4) & 0xd) != 1) { 1786657Snate@binkert.org break; 1796657Snate@binkert.org } 1806657Snate@binkert.org const IntRegIndex rt = 1816657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1826657Snate@binkert.org const IntRegIndex rt2 = 1836657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1846657Snate@binkert.org const bool op = bits(machInst, 20); 1856657Snate@binkert.org uint32_t vm; 1866657Snate@binkert.org if (single) { 1876657Snate@binkert.org vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1886657Snate@binkert.org } else { 1896657Snate@binkert.org vm = (bits(machInst, 3, 0) << 1) | 1906999Snate@binkert.org (bits(machInst, 5) << 5); 1916657Snate@binkert.org } 1926657Snate@binkert.org if (op) { 1936657Snate@binkert.org return new Vmov2Core2Reg(machInst, rt, rt2, 1946657Snate@binkert.org (IntRegIndex)vm); 1956657Snate@binkert.org } else { 1966657Snate@binkert.org return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1976657Snate@binkert.org rt, rt2); 1987007Snate@binkert.org } 1997007Snate@binkert.org } 2006657Snate@binkert.org break; 2017002Snate@binkert.org case 0x1: 2027002Snate@binkert.org switch (bits(opcode, 1, 0)) { 2039466Snilay@cs.wisc.edu case 0x0: 2046657Snate@binkert.org return new VLdmStm(machInst, rn, vd, single, 2056657Snate@binkert.org true, false, false, offset); 2066657Snate@binkert.org case 0x1: 2076657Snate@binkert.org return new VLdmStm(machInst, rn, vd, single, 2086657Snate@binkert.org true, false, true, offset); 2096657Snate@binkert.org case 0x2: 2106657Snate@binkert.org return new VLdmStm(machInst, rn, vd, single, 2116657Snate@binkert.org true, true, false, offset); 2126657Snate@binkert.org case 0x3: 2136657Snate@binkert.org // If rn == sp, then this is called vpop. 2146657Snate@binkert.org return new VLdmStm(machInst, rn, vd, single, 2156657Snate@binkert.org true, true, true, offset); 2167007Snate@binkert.org } 2177007Snate@binkert.org case 0x2: 2186657Snate@binkert.org if (bits(opcode, 1, 0) == 0x2) { 2199466Snilay@cs.wisc.edu // If rn == sp, then this is called vpush. 2206657Snate@binkert.org return new VLdmStm(machInst, rn, vd, single, 2216657Snate@binkert.org false, true, false, offset); 2229466Snilay@cs.wisc.edu } else if (bits(opcode, 1, 0) == 0x3) { 2239508Snilay@cs.wisc.edu return new VLdmStm(machInst, rn, vd, single, 2249466Snilay@cs.wisc.edu false, true, true, offset); 2259466Snilay@cs.wisc.edu } 2269466Snilay@cs.wisc.edu // Fall through on purpose 2276657Snate@binkert.org case 0x3: 2286657Snate@binkert.org const bool up = (bits(machInst, 23) == 1); 2296657Snate@binkert.org const uint32_t imm = bits(machInst, 7, 0) << 2; 2306657Snate@binkert.org RegIndex vd; 2316657Snate@binkert.org if (single) { 2326657Snate@binkert.org vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 2336657Snate@binkert.org (bits(machInst, 22))); 2346657Snate@binkert.org } else { 2356657Snate@binkert.org vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 2366657Snate@binkert.org (bits(machInst, 22) << 5)); 2376657Snate@binkert.org } 2386657Snate@binkert.org if (bits(opcode, 1, 0) == 0x0) { 2396657Snate@binkert.org if (single) { 2406657Snate@binkert.org if (up) { 2416657Snate@binkert.org return new %(vstr_us)s(machInst, vd, rn, up, imm); 2426657Snate@binkert.org } else { 2436657Snate@binkert.org return new %(vstr_s)s(machInst, vd, rn, up, imm); 2447453Snate@binkert.org } 2457453Snate@binkert.org } else { 2467453Snate@binkert.org if (up) { 2477453Snate@binkert.org return new %(vstr_ud)s(machInst, vd, vd + 1, 2487453Snate@binkert.org rn, up, imm); 2497453Snate@binkert.org } else { 2507453Snate@binkert.org return new %(vstr_d)s(machInst, vd, vd + 1, 2517453Snate@binkert.org rn, up, imm); 2527453Snate@binkert.org } 2537453Snate@binkert.org } 2547453Snate@binkert.org } else if (bits(opcode, 1, 0) == 0x1) { 2557453Snate@binkert.org if (single) { 2567453Snate@binkert.org if (up) { 2577453Snate@binkert.org return new %(vldr_us)s(machInst, vd, rn, up, imm); 2587453Snate@binkert.org } else { 2597453Snate@binkert.org return new %(vldr_s)s(machInst, vd, rn, up, imm); 2607453Snate@binkert.org } 2616657Snate@binkert.org } else { 2626657Snate@binkert.org if (up) { 2636657Snate@binkert.org return new %(vldr_ud)s(machInst, vd, vd + 1, 2646657Snate@binkert.org rn, up, imm); 2659466Snilay@cs.wisc.edu } else { 2666657Snate@binkert.org return new %(vldr_d)s(machInst, vd, vd + 1, 2679466Snilay@cs.wisc.edu rn, up, imm); 2689508Snilay@cs.wisc.edu } 2699466Snilay@cs.wisc.edu } 2706657Snate@binkert.org } 2716657Snate@binkert.org } 2726657Snate@binkert.org return new Unknown(machInst); 2736657Snate@binkert.org } 2749466Snilay@cs.wisc.edu ''' % { 2759466Snilay@cs.wisc.edu "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 2769466Snilay@cs.wisc.edu "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 2779466Snilay@cs.wisc.edu "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 2786657Snate@binkert.org "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 2796657Snate@binkert.org "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 2806657Snate@binkert.org "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 2816657Snate@binkert.org "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 2826657Snate@binkert.org "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 2836657Snate@binkert.org } 2846657Snate@binkert.org}}; 2856657Snate@binkert.org 2866657Snate@binkert.orgdef format ExtensionRegLoadStore() {{ 2879466Snilay@cs.wisc.edu decode_block = ''' 28810472Sandreas.hansson@arm.com return decodeExtensionRegLoadStore(machInst); 28910472Sandreas.hansson@arm.com ''' 29010472Sandreas.hansson@arm.com}}; 29110472Sandreas.hansson@arm.com 29210472Sandreas.hansson@arm.comlet {{ 29310472Sandreas.hansson@arm.com header_output = ''' 29410472Sandreas.hansson@arm.com StaticInstPtr 29510472Sandreas.hansson@arm.com decodeShortFpTransfer(ExtMachInst machInst); 29610472Sandreas.hansson@arm.com ''' 29710472Sandreas.hansson@arm.com decoder_output = ''' 2987453Snate@binkert.org StaticInstPtr 2997007Snate@binkert.org decodeShortFpTransfer(ExtMachInst machInst) 3007007Snate@binkert.org { 3017453Snate@binkert.org const uint32_t l = bits(machInst, 20); 3027007Snate@binkert.org const uint32_t c = bits(machInst, 8); 3036657Snate@binkert.org const uint32_t a = bits(machInst, 23, 21); 3046657Snate@binkert.org const uint32_t b = bits(machInst, 6, 5); 3056657Snate@binkert.org if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 3066657Snate@binkert.org (machInst.thumb == 0 && machInst.condCode == 0xf)) { 3076657Snate@binkert.org return new Unknown(machInst); 3086657Snate@binkert.org } 3096657Snate@binkert.org if (l == 0 && c == 0) { 3106657Snate@binkert.org if (a == 0) { 3116657Snate@binkert.org const uint32_t vn = (bits(machInst, 19, 16) << 1) | 3126657Snate@binkert.org bits(machInst, 7); 3137007Snate@binkert.org const IntRegIndex rt = 3147007Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3157007Snate@binkert.org if (bits(machInst, 20) == 1) { 3167007Snate@binkert.org return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 3177007Snate@binkert.org } else { 3186657Snate@binkert.org return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 3196657Snate@binkert.org } 3206657Snate@binkert.org } else if (a == 0x7) { 3216657Snate@binkert.org const IntRegIndex rt = 3226657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3236657Snate@binkert.org uint32_t specReg = bits(machInst, 19, 16); 3246657Snate@binkert.org switch (specReg) { 3256657Snate@binkert.org case 0: 3266657Snate@binkert.org specReg = MISCREG_FPSID; 3277007Snate@binkert.org break; 3287007Snate@binkert.org case 1: 3297007Snate@binkert.org specReg = MISCREG_FPSCR; 3307007Snate@binkert.org break; 3317007Snate@binkert.org case 8: 3326657Snate@binkert.org specReg = MISCREG_FPEXC; 3336657Snate@binkert.org break; 3346657Snate@binkert.org default: 3356657Snate@binkert.org return new Unknown(machInst); 3366657Snate@binkert.org } 3376657Snate@binkert.org return new Vmsr(machInst, (IntRegIndex)specReg, rt); 3386657Snate@binkert.org } 3397007Snate@binkert.org } else if (l == 0 && c == 1) { 3407007Snate@binkert.org if (bits(a, 2) == 0) { 3417007Snate@binkert.org uint32_t vd = (bits(machInst, 7) << 5) | 3427007Snate@binkert.org (bits(machInst, 19, 16) << 1); 3437007Snate@binkert.org uint32_t index, size; 3446657Snate@binkert.org const IntRegIndex rt = 3456657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3467002Snate@binkert.org if (bits(machInst, 22) == 1) { 3476657Snate@binkert.org size = 8; 3486657Snate@binkert.org index = (bits(machInst, 21) << 2) | 3496657Snate@binkert.org bits(machInst, 6, 5); 3506657Snate@binkert.org } else if (bits(machInst, 5) == 1) { 3516657Snate@binkert.org size = 16; 3526657Snate@binkert.org index = (bits(machInst, 21) << 1) | 3536657Snate@binkert.org bits(machInst, 6); 3546657Snate@binkert.org } else if (bits(machInst, 6) == 0) { 3556657Snate@binkert.org size = 32; 3566657Snate@binkert.org index = bits(machInst, 21); 3576657Snate@binkert.org } else { 3586657Snate@binkert.org return new Unknown(machInst); 3596657Snate@binkert.org } 3606657Snate@binkert.org if (index >= (32 / size)) { 3616657Snate@binkert.org index -= (32 / size); 3626657Snate@binkert.org vd++; 3636657Snate@binkert.org } 3646657Snate@binkert.org switch (size) { 3656657Snate@binkert.org case 8: 3666657Snate@binkert.org return new VmovCoreRegB(machInst, (IntRegIndex)vd, 3676657Snate@binkert.org rt, index); 3687007Snate@binkert.org case 16: 3696657Snate@binkert.org return new VmovCoreRegH(machInst, (IntRegIndex)vd, 3707007Snate@binkert.org rt, index); 3716657Snate@binkert.org case 32: 37210307Snilay@cs.wisc.edu return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 37310307Snilay@cs.wisc.edu } 37410307Snilay@cs.wisc.edu } else if (bits(b, 1) == 0) { 3759298Snilay@cs.wisc.edu // A8-594 3769298Snilay@cs.wisc.edu return new WarnUnimplemented("vdup", machInst); 3779298Snilay@cs.wisc.edu } 3786657Snate@binkert.org } else if (l == 1 && c == 0) { 3796657Snate@binkert.org if (a == 0) { 3806657Snate@binkert.org const uint32_t vn = (bits(machInst, 19, 16) << 1) | 3816657Snate@binkert.org bits(machInst, 7); 3827055Snate@binkert.org const IntRegIndex rt = 3837007Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3846657Snate@binkert.org if (bits(machInst, 20) == 1) { 3856657Snate@binkert.org return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 3867002Snate@binkert.org } else { 3876657Snate@binkert.org return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 3886657Snate@binkert.org } 3896657Snate@binkert.org } else if (a == 7) { 3907007Snate@binkert.org const IntRegIndex rt = 3916657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3926657Snate@binkert.org uint32_t specReg = bits(machInst, 19, 16); 3936657Snate@binkert.org switch (specReg) { 3946657Snate@binkert.org case 0: 3956657Snate@binkert.org specReg = MISCREG_FPSID; 3966999Snate@binkert.org break; 3976657Snate@binkert.org case 1: 3986657Snate@binkert.org specReg = MISCREG_FPSCR; 3996657Snate@binkert.org break; 4006657Snate@binkert.org case 6: 4016657Snate@binkert.org specReg = MISCREG_MVFR1; 4026657Snate@binkert.org break; 4036657Snate@binkert.org case 7: 4047002Snate@binkert.org specReg = MISCREG_MVFR0; 40510472Sandreas.hansson@arm.com break; 4067002Snate@binkert.org case 8: 4076657Snate@binkert.org specReg = MISCREG_FPEXC; 40811108Sdavid.hashe@amd.com break; 4097002Snate@binkert.org default: 4107002Snate@binkert.org return new Unknown(machInst); 4116657Snate@binkert.org } 4126657Snate@binkert.org return new Vmrs(machInst, rt, (IntRegIndex)specReg); 4136657Snate@binkert.org } 4146657Snate@binkert.org } else { 4157007Snate@binkert.org uint32_t vd = (bits(machInst, 7) << 5) | 4167007Snate@binkert.org (bits(machInst, 19, 16) << 1); 4176657Snate@binkert.org uint32_t index, size; 4186657Snate@binkert.org const IntRegIndex rt = 4196657Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 4206657Snate@binkert.org const bool u = (bits(machInst, 23) == 1); 4216657Snate@binkert.org if (bits(machInst, 22) == 1) { 4226657Snate@binkert.org size = 8; 4236657Snate@binkert.org index = (bits(machInst, 21) << 2) | 42411118Snilay@cs.wisc.edu bits(machInst, 6, 5); 42511118Snilay@cs.wisc.edu } else if (bits(machInst, 5) == 1) { 42611118Snilay@cs.wisc.edu size = 16; 42711118Snilay@cs.wisc.edu index = (bits(machInst, 21) << 1) | 42811118Snilay@cs.wisc.edu bits(machInst, 6); 4296657Snate@binkert.org } else if (bits(machInst, 6) == 0 && !u) { 4306657Snate@binkert.org size = 32; 4316657Snate@binkert.org index = bits(machInst, 21); 4326657Snate@binkert.org } else { 4336657Snate@binkert.org return new Unknown(machInst); 4346657Snate@binkert.org } 4356657Snate@binkert.org if (index >= (32 / size)) { 4366657Snate@binkert.org index -= (32 / size); 43710307Snilay@cs.wisc.edu vd++; 43810307Snilay@cs.wisc.edu } 43910307Snilay@cs.wisc.edu switch (size) { 4409298Snilay@cs.wisc.edu case 8: 4416657Snate@binkert.org if (u) { 4426657Snate@binkert.org return new VmovRegCoreUB(machInst, rt, 4436657Snate@binkert.org (IntRegIndex)vd, index); 4446999Snate@binkert.org } else { 4456657Snate@binkert.org return new VmovRegCoreSB(machInst, rt, 4466657Snate@binkert.org (IntRegIndex)vd, index); 4476657Snate@binkert.org } 4486657Snate@binkert.org case 16: 4496657Snate@binkert.org if (u) { 4507007Snate@binkert.org return new VmovRegCoreUH(machInst, rt, 4517007Snate@binkert.org (IntRegIndex)vd, index); 4527007Snate@binkert.org } else { 4536657Snate@binkert.org return new VmovRegCoreSH(machInst, rt, 4547002Snate@binkert.org (IntRegIndex)vd, index); 4557002Snate@binkert.org } 4567002Snate@binkert.org case 32: 4578086SBrad.Beckmann@amd.com return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 4588086SBrad.Beckmann@amd.com } 4598086SBrad.Beckmann@amd.com } 4608086SBrad.Beckmann@amd.com return new Unknown(machInst); 4618602Snilay@cs.wisc.edu } 46212065Snikos.nikoleris@arm.com ''' 46312334Sgabeblack@google.com}}; 4648602Snilay@cs.wisc.edu 46511025Snilay@cs.wisc.edudef format ShortFpTransfer() {{ 4668602Snilay@cs.wisc.edu decode_block = ''' 4678602Snilay@cs.wisc.edu return decodeShortFpTransfer(machInst); 4688086SBrad.Beckmann@amd.com ''' 4696657Snate@binkert.org}}; 4707007Snate@binkert.org 4716657Snate@binkert.orglet {{ 4726657Snate@binkert.org header_output = ''' 4736657Snate@binkert.org StaticInstPtr 4746657Snate@binkert.org decodeVfpData(ExtMachInst machInst); 4756657Snate@binkert.org ''' 4766657Snate@binkert.org decoder_output = ''' 4776657Snate@binkert.org StaticInstPtr 4786657Snate@binkert.org decodeVfpData(ExtMachInst machInst) 4796657Snate@binkert.org { 4806657Snate@binkert.org const uint32_t opc1 = bits(machInst, 23, 20); 4816657Snate@binkert.org const uint32_t opc2 = bits(machInst, 19, 16); 48210917Sbrandon.potter@amd.com const uint32_t opc3 = bits(machInst, 7, 6); 48310917Sbrandon.potter@amd.com //const uint32_t opc4 = bits(machInst, 3, 0); 4846862Sdrh5@cs.wisc.edu switch (opc1 & 0xb /* 1011 */) { 4856862Sdrh5@cs.wisc.edu case 0x0: 4866657Snate@binkert.org return new WarnUnimplemented("vmla, vmls", machInst); 4876657Snate@binkert.org case 0x2: 4886657Snate@binkert.org if ((opc3 & 0x1) == 0) { 4896657Snate@binkert.org uint32_t vd; 4906657Snate@binkert.org uint32_t vm; 4917007Snate@binkert.org uint32_t vn; 4927007Snate@binkert.org if (bits(machInst, 8) == 0) { 4937002Snate@binkert.org vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 4947007Snate@binkert.org vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 4957007Snate@binkert.org vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1); 4967002Snate@binkert.org return new VmulS(machInst, (IntRegIndex)vd, 4977007Snate@binkert.org (IntRegIndex)vn, (IntRegIndex)vm); 4987007Snate@binkert.org } else { 4996657Snate@binkert.org vd = (bits(machInst, 22) << 5) | 5006657Snate@binkert.org (bits(machInst, 15, 12) << 1); 5016657Snate@binkert.org vm = (bits(machInst, 5) << 5) | 50212065Snikos.nikoleris@arm.com (bits(machInst, 3, 0) << 1); 50312065Snikos.nikoleris@arm.com vn = (bits(machInst, 7) << 5) | 50412065Snikos.nikoleris@arm.com (bits(machInst, 19, 16) << 1); 50512065Snikos.nikoleris@arm.com return new VmulD(machInst, (IntRegIndex)vd, 50612065Snikos.nikoleris@arm.com (IntRegIndex)vn, (IntRegIndex)vm); 50712065Snikos.nikoleris@arm.com } 50812065Snikos.nikoleris@arm.com } 50912065Snikos.nikoleris@arm.com case 0x1: 51012065Snikos.nikoleris@arm.com return new WarnUnimplemented("vnmla, vnmls, vnmul", machInst); 51112065Snikos.nikoleris@arm.com case 0x3: 51212065Snikos.nikoleris@arm.com if ((opc3 & 0x1) == 0) { 51312065Snikos.nikoleris@arm.com return new WarnUnimplemented("vadd", machInst); 51412065Snikos.nikoleris@arm.com } else { 51512065Snikos.nikoleris@arm.com return new WarnUnimplemented("vsub", machInst); 5166657Snate@binkert.org } 5176657Snate@binkert.org case 0x8: 5186657Snate@binkert.org if ((opc3 & 0x1) == 0) { 5196657Snate@binkert.org return new WarnUnimplemented("vdiv", machInst); 5206657Snate@binkert.org } 5216657Snate@binkert.org break; 5226657Snate@binkert.org case 0xb: 5236657Snate@binkert.org if ((opc3 & 0x1) == 0) { 5246657Snate@binkert.org uint32_t vd; 5256657Snate@binkert.org const uint32_t baseImm = 5268602Snilay@cs.wisc.edu bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 5278602Snilay@cs.wisc.edu if (bits(machInst, 8) == 0) { 5288602Snilay@cs.wisc.edu vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5298602Snilay@cs.wisc.edu uint32_t imm = vfp_modified_imm(baseImm, false); 5308602Snilay@cs.wisc.edu return new VmovImmS(machInst, (IntRegIndex)vd, imm); 5318086SBrad.Beckmann@amd.com } else { 5328086SBrad.Beckmann@amd.com vd = (bits(machInst, 22) << 5) | 5338086SBrad.Beckmann@amd.com (bits(machInst, 15, 12) << 1); 5348086SBrad.Beckmann@amd.com uint64_t imm = vfp_modified_imm(baseImm, true); 5358086SBrad.Beckmann@amd.com return new VmovImmD(machInst, (IntRegIndex)vd, imm); 5368086SBrad.Beckmann@amd.com } 5378086SBrad.Beckmann@amd.com } 5388086SBrad.Beckmann@amd.com switch (opc2) { 5396657Snate@binkert.org case 0x0: 5406657Snate@binkert.org if (opc3 == 1) { 5417002Snate@binkert.org uint32_t vd; 5426657Snate@binkert.org uint32_t vm; 5437007Snate@binkert.org if (bits(machInst, 8) == 0) { 5446657Snate@binkert.org vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5456657Snate@binkert.org vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5466657Snate@binkert.org return new VmovRegS(machInst, 5476657Snate@binkert.org (IntRegIndex)vd, (IntRegIndex)vm); 5486657Snate@binkert.org } else { 5496999Snate@binkert.org vd = (bits(machInst, 22) << 5) | 5506657Snate@binkert.org (bits(machInst, 15, 12) << 1); 5516657Snate@binkert.org vm = (bits(machInst, 5) << 5) | 5526657Snate@binkert.org (bits(machInst, 3, 0) << 1); 5536657Snate@binkert.org return new VmovRegD(machInst, 5546657Snate@binkert.org (IntRegIndex)vd, (IntRegIndex)vm); 5556657Snate@binkert.org } 5567832Snate@binkert.org } else { 5577002Snate@binkert.org uint32_t vd; 5587002Snate@binkert.org uint32_t vm; 5597002Snate@binkert.org if (bits(machInst, 8) == 0) { 56012334Sgabeblack@google.com vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5616657Snate@binkert.org vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5626657Snate@binkert.org return new VabsS(machInst, 5637002Snate@binkert.org (IntRegIndex)vd, (IntRegIndex)vm); 5647002Snate@binkert.org } else { 5656657Snate@binkert.org vd = (bits(machInst, 22) << 5) | 5666657Snate@binkert.org (bits(machInst, 15, 12) << 1); 5678086SBrad.Beckmann@amd.com vm = (bits(machInst, 5) << 5) | 5688086SBrad.Beckmann@amd.com (bits(machInst, 3, 0) << 1); 5698086SBrad.Beckmann@amd.com return new VabsD(machInst, 5708086SBrad.Beckmann@amd.com (IntRegIndex)vd, (IntRegIndex)vm); 5718086SBrad.Beckmann@amd.com } 5728086SBrad.Beckmann@amd.com } 5738086SBrad.Beckmann@amd.com case 0x1: 5748086SBrad.Beckmann@amd.com if (opc3 == 1) { 5758086SBrad.Beckmann@amd.com uint32_t vd; 5768086SBrad.Beckmann@amd.com uint32_t vm; 5778086SBrad.Beckmann@amd.com if (bits(machInst, 8) == 0) { 5788086SBrad.Beckmann@amd.com vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5798086SBrad.Beckmann@amd.com vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5808086SBrad.Beckmann@amd.com return new VnegS(machInst, 5818086SBrad.Beckmann@amd.com (IntRegIndex)vd, (IntRegIndex)vm); 5828086SBrad.Beckmann@amd.com } else { 5838086SBrad.Beckmann@amd.com vd = (bits(machInst, 22) << 5) | 5848086SBrad.Beckmann@amd.com (bits(machInst, 15, 12) << 1); 5858086SBrad.Beckmann@amd.com vm = (bits(machInst, 5) << 5) | 5868086SBrad.Beckmann@amd.com (bits(machInst, 3, 0) << 1); 5878086SBrad.Beckmann@amd.com return new VnegD(machInst, 5886657Snate@binkert.org (IntRegIndex)vd, (IntRegIndex)vm); 5896657Snate@binkert.org } 59011283Santhony.gutierrez@amd.com } else { 5919773Snilay@cs.wisc.edu return new WarnUnimplemented("vsqrt", machInst); 59210301Snilay@cs.wisc.edu } 5936657Snate@binkert.org case 0x2: 5946657Snate@binkert.org case 0x3: 5957007Snate@binkert.org // Between half and single precision. 5967007Snate@binkert.org return new WarnUnimplemented("vcvtb, vcvtt", machInst); 5977007Snate@binkert.org case 0x4: 5986657Snate@binkert.org case 0x5: 5996657Snate@binkert.org return new WarnUnimplemented("vcmp, vcmpe", machInst); 6006657Snate@binkert.org case 0x7: 6016657Snate@binkert.org if (opc3 == 0x3) { 6026657Snate@binkert.org // Between double and single precision. 6036657Snate@binkert.org return new WarnUnimplemented("vcvt", machInst); 6047007Snate@binkert.org } 6057007Snate@binkert.org break; 6067007Snate@binkert.org case 0x8: 6076657Snate@binkert.org // Between FP and int. 6086657Snate@binkert.org return new WarnUnimplemented("vcvt, vcvtr", machInst); 6096657Snate@binkert.org case 0xa: 6106657Snate@binkert.org case 0xb: 6116657Snate@binkert.org // Between FP and fixed point. 6126657Snate@binkert.org return new WarnUnimplemented("vcvt", machInst); 6136657Snate@binkert.org case 0xc: 6146657Snate@binkert.org case 0xd: 6156657Snate@binkert.org // Between FP and int. 6166657Snate@binkert.org return new WarnUnimplemented("vcvt, vcvtr", machInst); 6176657Snate@binkert.org case 0xe: 6186657Snate@binkert.org case 0xf: 6196657Snate@binkert.org // Between FP and fixed point. 6206657Snate@binkert.org return new WarnUnimplemented("vcvt", machInst); 6217805Snilay@cs.wisc.edu } 6226657Snate@binkert.org break; 6236657Snate@binkert.org } 6246657Snate@binkert.org return new Unknown(machInst); 6257007Snate@binkert.org } 6267007Snate@binkert.org ''' 6277007Snate@binkert.org}}; 6286657Snate@binkert.org 6296657Snate@binkert.orgdef format VfpData() {{ 6306657Snate@binkert.org decode_block = ''' 6316657Snate@binkert.org return decodeVfpData(machInst); 6327007Snate@binkert.org ''' 6336657Snate@binkert.org}}; 6346657Snate@binkert.org