fp.isa revision 7367
12292SN/A// -*- mode:c++ -*- 210333Smitch.hayenga@arm.com 310239Sbinhpham@cs.rutgers.edu// Copyright (c) 2010 ARM Limited 48707Sandreas.hansson@arm.com// All rights reserved 58707Sandreas.hansson@arm.com// 68707Sandreas.hansson@arm.com// The license below extends only to copyright in the software and shall 78707Sandreas.hansson@arm.com// not be construed as granting a license to any other intellectual 88707Sandreas.hansson@arm.com// property including but not limited to intellectual property relating 98707Sandreas.hansson@arm.com// to a hardware implementation of the functionality of the software 108707Sandreas.hansson@arm.com// licensed hereunder. You may use the software subject to the license 118707Sandreas.hansson@arm.com// terms below provided that you ensure that this notice is replicated 128707Sandreas.hansson@arm.com// unmodified and in its entirety in all distributions of the software, 138707Sandreas.hansson@arm.com// modified or unmodified, in source code or in binary form. 148707Sandreas.hansson@arm.com// 152727Sktlim@umich.edu// Copyright (c) 2007-2008 The Florida State University 162292SN/A// All rights reserved. 172292SN/A// 182292SN/A// Redistribution and use in source and binary forms, with or without 192292SN/A// modification, are permitted provided that the following conditions are 202292SN/A// met: redistributions of source code must retain the above copyright 212292SN/A// notice, this list of conditions and the following disclaimer; 222292SN/A// redistributions in binary form must reproduce the above copyright 232292SN/A// notice, this list of conditions and the following disclaimer in the 242292SN/A// documentation and/or other materials provided with the distribution; 252292SN/A// neither the name of the copyright holders nor the names of its 262292SN/A// contributors may be used to endorse or promote products derived from 272292SN/A// this software without specific prior written permission. 282292SN/A// 292292SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302292SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312292SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322292SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332292SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352292SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362292SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372292SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382292SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392292SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402689Sktlim@umich.edu// 412689Sktlim@umich.edu// Authors: Stephen Hines 422292SN/A 432292SN/A//////////////////////////////////////////////////////////////////// 449944Smatt.horsnell@ARM.com// 459944Smatt.horsnell@ARM.com// Floating Point operate instructions 469944Smatt.horsnell@ARM.com// 472329SN/A 482980Sgblack@eecs.umich.edudef template FPAExecute {{ 492329SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 502329SN/A { 512292SN/A Fault fault = NoFault; 529444SAndreas.Sandberg@ARM.com 538232Snate@binkert.org %(fp_enable_check)s; 548232Snate@binkert.org 558232Snate@binkert.org %(op_decl)s; 566221Snate@binkert.org %(op_rd)s; 572292SN/A 586221Snate@binkert.org if (%(predicate_test)s) { 595529Snate@binkert.org %(code)s; 602292SN/A if (fault == NoFault) { 615529Snate@binkert.org %(op_wb)s; 628707Sandreas.hansson@arm.com } 634329Sktlim@umich.edu } 644329Sktlim@umich.edu 6510333Smitch.hayenga@arm.com return fault; 662292SN/A } 679868Sjthestness@gmail.com}}; 689868Sjthestness@gmail.com 692292SN/Adef template FloatDoubleDecode {{ 702292SN/A { 712292SN/A ArmStaticInst *i = NULL; 722980Sgblack@eecs.umich.edu switch (OPCODE_19 << 1 | OPCODE_7) 732292SN/A { 742292SN/A case 0: 752292SN/A i = (ArmStaticInst *)new %(class_name)sS(machInst); 762292SN/A break; 772292SN/A case 1: 782292SN/A i = (ArmStaticInst *)new %(class_name)sD(machInst); 792292SN/A break; 802292SN/A case 2: 812292SN/A case 3: 822292SN/A default: 832292SN/A panic("Cannot decode float/double nature of the instruction"); 844329Sktlim@umich.edu } 852292SN/A return i; 862292SN/A } 872292SN/A}}; 882292SN/A 892292SN/A// Primary format for float point operate instructions: 902292SN/Adef format FloatOp(code, *flags) {{ 912292SN/A orig_code = code 924329Sktlim@umich.edu 932292SN/A cblk = code 948346Sksewell@umich.edu iop = InstObjParams(name, Name, 'PredOp', 952292SN/A {"code": cblk, 962292SN/A "predicate_test": predicateTest}, 972292SN/A flags) 982292SN/A header_output = BasicDeclare.subst(iop) 992292SN/A decoder_output = BasicConstructor.subst(iop) 1002292SN/A exec_output = FPAExecute.subst(iop) 1012292SN/A 1022292SN/A sng_cblk = code 1032292SN/A sng_iop = InstObjParams(name, Name+'S', 'PredOp', 1042292SN/A {"code": sng_cblk, 1052292SN/A "predicate_test": predicateTest}, 1062292SN/A flags) 1074329Sktlim@umich.edu header_output += BasicDeclare.subst(sng_iop) 1082292SN/A decoder_output += BasicConstructor.subst(sng_iop) 1098346Sksewell@umich.edu exec_output += FPAExecute.subst(sng_iop) 1102292SN/A 1112292SN/A dbl_code = re.sub(r'\.sf', '.df', orig_code) 1122292SN/A 1132292SN/A dbl_cblk = dbl_code 1142292SN/A dbl_iop = InstObjParams(name, Name+'D', 'PredOp', 1152292SN/A {"code": dbl_cblk, 1162292SN/A "predicate_test": predicateTest}, 1179868Sjthestness@gmail.com flags) 1186221Snate@binkert.org header_output += BasicDeclare.subst(dbl_iop) 1194329Sktlim@umich.edu decoder_output += BasicConstructor.subst(dbl_iop) 1204329Sktlim@umich.edu exec_output += FPAExecute.subst(dbl_iop) 1218850Sandreas.hansson@arm.com 1222292SN/A decode_block = FloatDoubleDecode.subst(iop) 1232292SN/A}}; 1242292SN/A 1252292SN/Alet {{ 1262292SN/A calcFPCcCode = ''' 1272292SN/A uint16_t _in, _iz, _ic, _iv; 1282292SN/A 1292292SN/A _in = %(fReg1)s < %(fReg2)s; 1302292SN/A _iz = %(fReg1)s == %(fReg2)s; 1312292SN/A _ic = %(fReg1)s >= %(fReg2)s; 1322292SN/A _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1; 1332292SN/A 1342292SN/A CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | 1352727Sktlim@umich.edu (CondCodes & 0x0FFFFFFF); 1362727Sktlim@umich.edu ''' 1372727Sktlim@umich.edu}}; 1386221Snate@binkert.org 1392727Sktlim@umich.edudef format FloatCmp(fReg1, fReg2, *flags) {{ 1402727Sktlim@umich.edu code = calcFPCcCode % vars() 1412727Sktlim@umich.edu iop = InstObjParams(name, Name, 'PredOp', 1422727Sktlim@umich.edu {"code": code, 1432727Sktlim@umich.edu "predicate_test": predicateTest}, 1442727Sktlim@umich.edu flags) 1456221Snate@binkert.org header_output = BasicDeclare.subst(iop) 1462292SN/A decoder_output = BasicConstructor.subst(iop) 1472292SN/A decode_block = BasicDecode.subst(iop) 1482292SN/A exec_output = FPAExecute.subst(iop) 1492292SN/A}}; 1502292SN/A 1512292SN/Alet {{ 1522307SN/A header_output = ''' 1539444SAndreas.Sandberg@ARM.com StaticInstPtr 1542307SN/A decodeExtensionRegLoadStore(ExtMachInst machInst); 1559444SAndreas.Sandberg@ARM.com ''' 1569444SAndreas.Sandberg@ARM.com decoder_output = ''' 1579444SAndreas.Sandberg@ARM.com StaticInstPtr 1589444SAndreas.Sandberg@ARM.com decodeExtensionRegLoadStore(ExtMachInst machInst) 1599444SAndreas.Sandberg@ARM.com { 1609444SAndreas.Sandberg@ARM.com const uint32_t opcode = bits(machInst, 24, 20); 1619444SAndreas.Sandberg@ARM.com const uint32_t offset = bits(machInst, 7, 0); 1629444SAndreas.Sandberg@ARM.com const bool single = (bits(machInst, 8) == 0); 1639444SAndreas.Sandberg@ARM.com const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1649444SAndreas.Sandberg@ARM.com RegIndex vd; 1659444SAndreas.Sandberg@ARM.com if (single) { 1669444SAndreas.Sandberg@ARM.com vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1679444SAndreas.Sandberg@ARM.com bits(machInst, 22)); 1689444SAndreas.Sandberg@ARM.com } else { 1699444SAndreas.Sandberg@ARM.com vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1702307SN/A (bits(machInst, 22) << 5)); 1719444SAndreas.Sandberg@ARM.com } 1729444SAndreas.Sandberg@ARM.com switch (bits(opcode, 4, 3)) { 1739444SAndreas.Sandberg@ARM.com case 0x0: 1749444SAndreas.Sandberg@ARM.com if (bits(opcode, 4, 1) == 0x2 && 1759444SAndreas.Sandberg@ARM.com !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1769444SAndreas.Sandberg@ARM.com !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1779444SAndreas.Sandberg@ARM.com if ((bits(machInst, 7, 4) & 0xd) != 1) { 1782307SN/A break; 1792307SN/A } 1802307SN/A const IntRegIndex rt = 1812307SN/A (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1822307SN/A const IntRegIndex rt2 = 1832307SN/A (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1846221Snate@binkert.org const bool op = bits(machInst, 20); 1852307SN/A uint32_t vm; 1862307SN/A if (single) { 1872307SN/A vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1882307SN/A } else { 1892307SN/A vm = (bits(machInst, 3, 0) << 1) | 1902292SN/A (bits(machInst, 5) << 5); 1916221Snate@binkert.org } 1922292SN/A if (op) { 1932292SN/A return new Vmov2Core2Reg(machInst, rt, rt2, 1942292SN/A (IntRegIndex)vm); 1952292SN/A } else { 1962292SN/A return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1972292SN/A rt, rt2); 1982292SN/A } 1992292SN/A } 2002292SN/A break; 2012292SN/A case 0x1: 2022292SN/A switch (bits(opcode, 1, 0)) { 2032292SN/A case 0x0: 2042292SN/A return new VLdmStm(machInst, rn, vd, single, 2053867Sbinkertn@umich.edu true, false, false, offset); 2062292SN/A case 0x1: 2072292SN/A return new VLdmStm(machInst, rn, vd, single, 2082292SN/A true, false, true, offset); 2092292SN/A case 0x2: 2102292SN/A return new VLdmStm(machInst, rn, vd, single, 2112292SN/A true, true, false, offset); 2122292SN/A case 0x3: 2132292SN/A // If rn == sp, then this is called vpop. 2142292SN/A return new VLdmStm(machInst, rn, vd, single, 2152292SN/A true, true, true, offset); 2162292SN/A } 2176221Snate@binkert.org case 0x2: 2186221Snate@binkert.org if (bits(opcode, 1, 0) == 0x2) { 2193867Sbinkertn@umich.edu // If rn == sp, then this is called vpush. 2203867Sbinkertn@umich.edu return new VLdmStm(machInst, rn, vd, single, 2216221Snate@binkert.org false, true, false, offset); 2223867Sbinkertn@umich.edu } else if (bits(opcode, 1, 0) == 0x3) { 2233867Sbinkertn@umich.edu return new VLdmStm(machInst, rn, vd, single, 2242292SN/A false, true, true, offset); 2252292SN/A } 2262292SN/A // Fall through on purpose 2272292SN/A case 0x3: 2282292SN/A const bool up = (bits(machInst, 23) == 1); 2292292SN/A const uint32_t imm = bits(machInst, 7, 0) << 2; 2306221Snate@binkert.org RegIndex vd; 2312292SN/A if (single) { 2322292SN/A vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 2332292SN/A (bits(machInst, 22))); 2342292SN/A } else { 2352292SN/A vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 2362292SN/A (bits(machInst, 22) << 5)); 2372292SN/A } 2386221Snate@binkert.org if (bits(opcode, 1, 0) == 0x0) { 2392292SN/A if (single) { 2402292SN/A if (up) { 2412292SN/A return new %(vstr_us)s(machInst, vd, rn, up, imm); 2422292SN/A } else { 2432292SN/A return new %(vstr_s)s(machInst, vd, rn, up, imm); 2442292SN/A } 2452292SN/A } else { 2462292SN/A if (up) { 2472292SN/A return new %(vstr_ud)s(machInst, vd, vd + 1, 2486221Snate@binkert.org rn, up, imm); 2496221Snate@binkert.org } else { 2502292SN/A return new %(vstr_d)s(machInst, vd, vd + 1, 2513867Sbinkertn@umich.edu rn, up, imm); 2526221Snate@binkert.org } 2532292SN/A } 2542292SN/A } else if (bits(opcode, 1, 0) == 0x1) { 2552292SN/A if (single) { 2562292SN/A if (up) { 2572292SN/A return new %(vldr_us)s(machInst, vd, rn, up, imm); 2582292SN/A } else { 2592292SN/A return new %(vldr_s)s(machInst, vd, rn, up, imm); 2602292SN/A } 2612292SN/A } else { 2626221Snate@binkert.org if (up) { 2632292SN/A return new %(vldr_ud)s(machInst, vd, vd + 1, 2642292SN/A rn, up, imm); 2652292SN/A } else { 2662292SN/A return new %(vldr_d)s(machInst, vd, vd + 1, 2672292SN/A rn, up, imm); 2682292SN/A } 2692292SN/A } 2702292SN/A } 2716221Snate@binkert.org } 2722292SN/A return new Unknown(machInst); 2732292SN/A } 2742292SN/A ''' % { 2752292SN/A "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 2762292SN/A "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 2772292SN/A "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 2782292SN/A "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 2792292SN/A "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 2806221Snate@binkert.org "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 2812292SN/A "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 2822292SN/A "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 2832292SN/A } 2842292SN/A}}; 2852292SN/A 2862292SN/Adef format ExtensionRegLoadStore() {{ 2872292SN/A decode_block = ''' 2882292SN/A return decodeExtensionRegLoadStore(machInst); 2896221Snate@binkert.org ''' 2902292SN/A}}; 2912292SN/A 2922292SN/Alet {{ 2932292SN/A header_output = ''' 2942292SN/A StaticInstPtr 2952292SN/A decodeShortFpTransfer(ExtMachInst machInst); 2962292SN/A ''' 2972292SN/A decoder_output = ''' 2986221Snate@binkert.org StaticInstPtr 2996221Snate@binkert.org decodeShortFpTransfer(ExtMachInst machInst) 3002292SN/A { 3013867Sbinkertn@umich.edu const uint32_t l = bits(machInst, 20); 3026221Snate@binkert.org const uint32_t c = bits(machInst, 8); 3032292SN/A const uint32_t a = bits(machInst, 23, 21); 3042292SN/A const uint32_t b = bits(machInst, 6, 5); 3052329SN/A if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 3062329SN/A (machInst.thumb == 0 && machInst.condCode == 0xf)) { 3072292SN/A return new Unknown(machInst); 3082292SN/A } 3092292SN/A if (l == 0 && c == 0) { 3102292SN/A if (a == 0) { 3112292SN/A const uint32_t vn = (bits(machInst, 19, 16) << 1) | 3122292SN/A bits(machInst, 7); 3132292SN/A const IntRegIndex rt = 3142292SN/A (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3152292SN/A if (bits(machInst, 20) == 1) { 3162292SN/A return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 3172292SN/A } else { 3186221Snate@binkert.org return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 3196221Snate@binkert.org } 3202292SN/A } else if (a == 0x7) { 3213867Sbinkertn@umich.edu const IntRegIndex rt = 3226221Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3233867Sbinkertn@umich.edu uint32_t specReg = bits(machInst, 19, 16); 3242292SN/A switch (specReg) { 3252292SN/A case 0: 3262292SN/A specReg = MISCREG_FPSID; 3272292SN/A break; 3282292SN/A case 1: 3292292SN/A specReg = MISCREG_FPSCR; 3302292SN/A break; 3318707Sandreas.hansson@arm.com case 8: 3328707Sandreas.hansson@arm.com specReg = MISCREG_FPEXC; 3338707Sandreas.hansson@arm.com break; 3348707Sandreas.hansson@arm.com default: 33510333Smitch.hayenga@arm.com return new Unknown(machInst); 33610333Smitch.hayenga@arm.com } 33710333Smitch.hayenga@arm.com return new Vmsr(machInst, (IntRegIndex)specReg, rt); 33810333Smitch.hayenga@arm.com } 3398707Sandreas.hansson@arm.com } else if (l == 0 && c == 1) { 3408707Sandreas.hansson@arm.com if (bits(a, 2) == 0) { 3418707Sandreas.hansson@arm.com uint32_t vd = (bits(machInst, 7) << 5) | 3428707Sandreas.hansson@arm.com (bits(machInst, 19, 16) << 1); 3438707Sandreas.hansson@arm.com uint32_t index, size; 3448975Sandreas.hansson@arm.com const IntRegIndex rt = 3458707Sandreas.hansson@arm.com (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3468707Sandreas.hansson@arm.com if (bits(machInst, 22) == 1) { 3478707Sandreas.hansson@arm.com size = 8; 3488707Sandreas.hansson@arm.com index = (bits(machInst, 21) << 2) | 34910575SMarco.Elver@ARM.com bits(machInst, 6, 5); 3508948Sandreas.hansson@arm.com } else if (bits(machInst, 5) == 1) { 35110575SMarco.Elver@ARM.com size = 16; 35210575SMarco.Elver@ARM.com index = (bits(machInst, 21) << 1) | 35310575SMarco.Elver@ARM.com bits(machInst, 6); 35410575SMarco.Elver@ARM.com } else if (bits(machInst, 6) == 0) { 35510575SMarco.Elver@ARM.com size = 32; 35610575SMarco.Elver@ARM.com index = bits(machInst, 21); 35710575SMarco.Elver@ARM.com } else { 35810575SMarco.Elver@ARM.com return new Unknown(machInst); 35910575SMarco.Elver@ARM.com } 36010575SMarco.Elver@ARM.com if (index >= (32 / size)) { 36110575SMarco.Elver@ARM.com index -= (32 / size); 36210575SMarco.Elver@ARM.com vd++; 36310575SMarco.Elver@ARM.com } 36410575SMarco.Elver@ARM.com switch (size) { 36510575SMarco.Elver@ARM.com case 8: 36610575SMarco.Elver@ARM.com return new VmovCoreRegB(machInst, (IntRegIndex)vd, 36710575SMarco.Elver@ARM.com rt, index); 36810575SMarco.Elver@ARM.com case 16: 36910575SMarco.Elver@ARM.com return new VmovCoreRegH(machInst, (IntRegIndex)vd, 37010575SMarco.Elver@ARM.com rt, index); 37110575SMarco.Elver@ARM.com case 32: 37210573Sstephan.diestelhorst@arm.com return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 37310573Sstephan.diestelhorst@arm.com } 3748948Sandreas.hansson@arm.com } else if (bits(b, 1) == 0) { 3758948Sandreas.hansson@arm.com // A8-594 3768707Sandreas.hansson@arm.com return new WarnUnimplemented("vdup", machInst); 3778948Sandreas.hansson@arm.com } 3788975Sandreas.hansson@arm.com } else if (l == 1 && c == 0) { 3798975Sandreas.hansson@arm.com if (a == 0) { 3808948Sandreas.hansson@arm.com const uint32_t vn = (bits(machInst, 19, 16) << 1) | 3818948Sandreas.hansson@arm.com bits(machInst, 7); 3828948Sandreas.hansson@arm.com const IntRegIndex rt = 3838948Sandreas.hansson@arm.com (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3848948Sandreas.hansson@arm.com if (bits(machInst, 20) == 1) { 3858948Sandreas.hansson@arm.com return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 3868948Sandreas.hansson@arm.com } else { 3878948Sandreas.hansson@arm.com return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 3888948Sandreas.hansson@arm.com } 3898948Sandreas.hansson@arm.com } else if (a == 7) { 3908707Sandreas.hansson@arm.com const IntRegIndex rt = 3918707Sandreas.hansson@arm.com (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 3928707Sandreas.hansson@arm.com uint32_t specReg = bits(machInst, 19, 16); 3938707Sandreas.hansson@arm.com switch (specReg) { 3942292SN/A case 0: 3952292SN/A specReg = MISCREG_FPSID; 3962292SN/A break; 3972292SN/A case 1: 3982292SN/A specReg = MISCREG_FPSCR; 3992292SN/A break; 4006221Snate@binkert.org case 6: 4016221Snate@binkert.org specReg = MISCREG_MVFR1; 4022292SN/A break; 4033867Sbinkertn@umich.edu case 7: 4046221Snate@binkert.org specReg = MISCREG_MVFR0; 4053867Sbinkertn@umich.edu break; 4062292SN/A case 8: 4072292SN/A specReg = MISCREG_FPEXC; 4082292SN/A break; 4092292SN/A default: 4102292SN/A return new Unknown(machInst); 4112292SN/A } 4122292SN/A return new Vmrs(machInst, rt, (IntRegIndex)specReg); 4132292SN/A } 4142292SN/A } else { 4152292SN/A uint32_t vd = (bits(machInst, 7) << 5) | 4162292SN/A (bits(machInst, 19, 16) << 1); 4172292SN/A uint32_t index, size; 4186221Snate@binkert.org const IntRegIndex rt = 4196221Snate@binkert.org (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 4202292SN/A const bool u = (bits(machInst, 23) == 1); 4213867Sbinkertn@umich.edu if (bits(machInst, 22) == 1) { 4226221Snate@binkert.org size = 8; 4233867Sbinkertn@umich.edu index = (bits(machInst, 21) << 2) | 4242292SN/A bits(machInst, 6, 5); 4252292SN/A } else if (bits(machInst, 5) == 1) { 4262292SN/A size = 16; 4272292SN/A index = (bits(machInst, 21) << 1) | 4282292SN/A bits(machInst, 6); 4292292SN/A } else if (bits(machInst, 6) == 0 && !u) { 4302292SN/A size = 32; 4312292SN/A index = bits(machInst, 21); 4322292SN/A } else { 4332292SN/A return new Unknown(machInst); 4342292SN/A } 4352292SN/A if (index >= (32 / size)) { 4366221Snate@binkert.org index -= (32 / size); 4376221Snate@binkert.org vd++; 4382292SN/A } 4393867Sbinkertn@umich.edu switch (size) { 4406221Snate@binkert.org case 8: 4413867Sbinkertn@umich.edu if (u) { 4422292SN/A return new VmovRegCoreUB(machInst, rt, 4432292SN/A (IntRegIndex)vd, index); 4442292SN/A } else { 4452292SN/A return new VmovRegCoreSB(machInst, rt, 4462292SN/A (IntRegIndex)vd, index); 4472292SN/A } 4482292SN/A case 16: 4492292SN/A if (u) { 45010239Sbinhpham@cs.rutgers.edu return new VmovRegCoreUH(machInst, rt, 4512292SN/A (IntRegIndex)vd, index); 4522292SN/A } else { 4532292SN/A return new VmovRegCoreSH(machInst, rt, 4546221Snate@binkert.org (IntRegIndex)vd, index); 4556221Snate@binkert.org } 4562292SN/A case 32: 4573867Sbinkertn@umich.edu return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 4586221Snate@binkert.org } 4593867Sbinkertn@umich.edu } 46010239Sbinhpham@cs.rutgers.edu return new Unknown(machInst); 4612292SN/A } 4622292SN/A ''' 4632292SN/A}}; 4642292SN/A 4652292SN/Adef format ShortFpTransfer() {{ 4662292SN/A decode_block = ''' 4672292SN/A return decodeShortFpTransfer(machInst); 46810239Sbinhpham@cs.rutgers.edu ''' 4692292SN/A}}; 47010239Sbinhpham@cs.rutgers.edu 47110239Sbinhpham@cs.rutgers.edulet {{ 47210239Sbinhpham@cs.rutgers.edu header_output = ''' 47310239Sbinhpham@cs.rutgers.edu StaticInstPtr 47410239Sbinhpham@cs.rutgers.edu decodeVfpData(ExtMachInst machInst); 47510239Sbinhpham@cs.rutgers.edu ''' 47610239Sbinhpham@cs.rutgers.edu decoder_output = ''' 47710239Sbinhpham@cs.rutgers.edu StaticInstPtr 47810239Sbinhpham@cs.rutgers.edu decodeVfpData(ExtMachInst machInst) 47910239Sbinhpham@cs.rutgers.edu { 48010239Sbinhpham@cs.rutgers.edu const uint32_t opc1 = bits(machInst, 23, 20); 48110239Sbinhpham@cs.rutgers.edu const uint32_t opc2 = bits(machInst, 19, 16); 48210239Sbinhpham@cs.rutgers.edu const uint32_t opc3 = bits(machInst, 7, 6); 48310239Sbinhpham@cs.rutgers.edu //const uint32_t opc4 = bits(machInst, 3, 0); 48410239Sbinhpham@cs.rutgers.edu switch (opc1 & 0xb /* 1011 */) { 48510239Sbinhpham@cs.rutgers.edu case 0x0: 48610239Sbinhpham@cs.rutgers.edu return new WarnUnimplemented("vmla, vmls", machInst); 48710239Sbinhpham@cs.rutgers.edu case 0x2: 48810239Sbinhpham@cs.rutgers.edu if ((opc3 & 0x1) == 0) { 48910239Sbinhpham@cs.rutgers.edu uint32_t vd; 49010239Sbinhpham@cs.rutgers.edu uint32_t vm; 49110239Sbinhpham@cs.rutgers.edu uint32_t vn; 49210239Sbinhpham@cs.rutgers.edu if (bits(machInst, 8) == 0) { 49310239Sbinhpham@cs.rutgers.edu vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 49410239Sbinhpham@cs.rutgers.edu vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 49510239Sbinhpham@cs.rutgers.edu vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1); 4962292SN/A return new VmulS(machInst, (IntRegIndex)vd, 4972292SN/A (IntRegIndex)vn, (IntRegIndex)vm); 4982292SN/A } else { 4992292SN/A vd = (bits(machInst, 22) << 5) | 5002292SN/A (bits(machInst, 15, 12) << 1); 5012292SN/A vm = (bits(machInst, 5) << 5) | 5026221Snate@binkert.org (bits(machInst, 3, 0) << 1); 5036221Snate@binkert.org vn = (bits(machInst, 7) << 5) | 5042292SN/A (bits(machInst, 19, 16) << 1); 5053867Sbinkertn@umich.edu return new VmulD(machInst, (IntRegIndex)vd, 5066221Snate@binkert.org (IntRegIndex)vn, (IntRegIndex)vm); 5073867Sbinkertn@umich.edu } 5083867Sbinkertn@umich.edu } 5092292SN/A case 0x1: 5102292SN/A return new WarnUnimplemented("vnmla, vnmls, vnmul", machInst); 5112292SN/A case 0x3: 5122292SN/A if ((opc3 & 0x1) == 0) { 5132292SN/A uint32_t vd; 5142292SN/A uint32_t vm; 5152292SN/A uint32_t vn; 5162292SN/A if (bits(machInst, 8) == 0) { 5176221Snate@binkert.org vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5182292SN/A vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5192292SN/A vn = bits(machInst, 7) | (bits(machInst, 19, 16) << 1); 5202292SN/A return new VaddS(machInst, (IntRegIndex)vd, 5213867Sbinkertn@umich.edu (IntRegIndex)vn, (IntRegIndex)vm); 5222292SN/A } else { 5232292SN/A vd = (bits(machInst, 22) << 5) | 5242292SN/A (bits(machInst, 15, 12) << 1); 5252292SN/A vm = (bits(machInst, 5) << 5) | 5262292SN/A (bits(machInst, 3, 0) << 1); 5272292SN/A vn = (bits(machInst, 7) << 5) | 5282292SN/A (bits(machInst, 19, 16) << 1); 5299444SAndreas.Sandberg@ARM.com return new VaddD(machInst, (IntRegIndex)vd, 5309444SAndreas.Sandberg@ARM.com (IntRegIndex)vn, (IntRegIndex)vm); 5319444SAndreas.Sandberg@ARM.com } 5329444SAndreas.Sandberg@ARM.com } else { 5339444SAndreas.Sandberg@ARM.com return new WarnUnimplemented("vsub", machInst); 5349444SAndreas.Sandberg@ARM.com } 5359444SAndreas.Sandberg@ARM.com case 0x8: 5369444SAndreas.Sandberg@ARM.com if ((opc3 & 0x1) == 0) { 5379444SAndreas.Sandberg@ARM.com return new WarnUnimplemented("vdiv", machInst); 5389444SAndreas.Sandberg@ARM.com } 5399444SAndreas.Sandberg@ARM.com break; 5409444SAndreas.Sandberg@ARM.com case 0xb: 5419444SAndreas.Sandberg@ARM.com if ((opc3 & 0x1) == 0) { 5429444SAndreas.Sandberg@ARM.com uint32_t vd; 5439444SAndreas.Sandberg@ARM.com const uint32_t baseImm = 5449444SAndreas.Sandberg@ARM.com bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 5459444SAndreas.Sandberg@ARM.com if (bits(machInst, 8) == 0) { 5469444SAndreas.Sandberg@ARM.com vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5479444SAndreas.Sandberg@ARM.com uint32_t imm = vfp_modified_imm(baseImm, false); 5489444SAndreas.Sandberg@ARM.com return new VmovImmS(machInst, (IntRegIndex)vd, imm); 5499444SAndreas.Sandberg@ARM.com } else { 5509444SAndreas.Sandberg@ARM.com vd = (bits(machInst, 22) << 5) | 5519444SAndreas.Sandberg@ARM.com (bits(machInst, 15, 12) << 1); 5529444SAndreas.Sandberg@ARM.com uint64_t imm = vfp_modified_imm(baseImm, true); 5539444SAndreas.Sandberg@ARM.com return new VmovImmD(machInst, (IntRegIndex)vd, imm); 5549444SAndreas.Sandberg@ARM.com } 5559444SAndreas.Sandberg@ARM.com } 5569444SAndreas.Sandberg@ARM.com switch (opc2) { 5579444SAndreas.Sandberg@ARM.com case 0x0: 5589444SAndreas.Sandberg@ARM.com if (opc3 == 1) { 5599444SAndreas.Sandberg@ARM.com uint32_t vd; 5609444SAndreas.Sandberg@ARM.com uint32_t vm; 5619444SAndreas.Sandberg@ARM.com if (bits(machInst, 8) == 0) { 5629444SAndreas.Sandberg@ARM.com vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5639444SAndreas.Sandberg@ARM.com vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5649444SAndreas.Sandberg@ARM.com return new VmovRegS(machInst, 5659444SAndreas.Sandberg@ARM.com (IntRegIndex)vd, (IntRegIndex)vm); 5669444SAndreas.Sandberg@ARM.com } else { 5679444SAndreas.Sandberg@ARM.com vd = (bits(machInst, 22) << 5) | 5689444SAndreas.Sandberg@ARM.com (bits(machInst, 15, 12) << 1); 5699444SAndreas.Sandberg@ARM.com vm = (bits(machInst, 5) << 5) | 5702292SN/A (bits(machInst, 3, 0) << 1); 5712292SN/A return new VmovRegD(machInst, 5726221Snate@binkert.org (IntRegIndex)vd, (IntRegIndex)vm); 5736221Snate@binkert.org } 5742292SN/A } else { 5753867Sbinkertn@umich.edu uint32_t vd; 5766221Snate@binkert.org uint32_t vm; 5773867Sbinkertn@umich.edu if (bits(machInst, 8) == 0) { 5782292SN/A vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5792292SN/A vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5802292SN/A return new VabsS(machInst, 5812292SN/A (IntRegIndex)vd, (IntRegIndex)vm); 5822292SN/A } else { 5832292SN/A vd = (bits(machInst, 22) << 5) | 5842292SN/A (bits(machInst, 15, 12) << 1); 5852292SN/A vm = (bits(machInst, 5) << 5) | 5862292SN/A (bits(machInst, 3, 0) << 1); 5876221Snate@binkert.org return new VabsD(machInst, 5882292SN/A (IntRegIndex)vd, (IntRegIndex)vm); 5892292SN/A } 5902292SN/A } 5913870Sbinkertn@umich.edu case 0x1: 5922292SN/A if (opc3 == 1) { 5932292SN/A uint32_t vd; 5942292SN/A uint32_t vm; 5952292SN/A if (bits(machInst, 8) == 0) { 5962292SN/A vd = bits(machInst, 22) | (bits(machInst, 15, 12) << 1); 5972292SN/A vm = bits(machInst, 5) | (bits(machInst, 3, 0) << 1); 5982292SN/A return new VnegS(machInst, 5992292SN/A (IntRegIndex)vd, (IntRegIndex)vm); 6002292SN/A } else { 6016221Snate@binkert.org vd = (bits(machInst, 22) << 5) | 6026221Snate@binkert.org (bits(machInst, 15, 12) << 1); 6032292SN/A vm = (bits(machInst, 5) << 5) | 6043867Sbinkertn@umich.edu (bits(machInst, 3, 0) << 1); 6056221Snate@binkert.org return new VnegD(machInst, 6063867Sbinkertn@umich.edu (IntRegIndex)vd, (IntRegIndex)vm); 6072292SN/A } 6082292SN/A } else { 6092292SN/A return new WarnUnimplemented("vsqrt", machInst); 6102292SN/A } 6112292SN/A case 0x2: 6122292SN/A case 0x3: 6132292SN/A // Between half and single precision. 6142292SN/A return new WarnUnimplemented("vcvtb, vcvtt", machInst); 6152292SN/A case 0x4: 6166221Snate@binkert.org case 0x5: 6172292SN/A return new WarnUnimplemented("vcmp, vcmpe", machInst); 6182292SN/A case 0x7: 6192292SN/A if (opc3 == 0x3) { 6203870Sbinkertn@umich.edu // Between double and single precision. 6212292SN/A return new WarnUnimplemented("vcvt", machInst); 6222292SN/A } 6232292SN/A break; 6242292SN/A case 0x8: 6252292SN/A // Between FP and int. 6262292SN/A return new WarnUnimplemented("vcvt, vcvtr", machInst); 6272292SN/A case 0xa: 6282292SN/A case 0xb: 6292292SN/A // Between FP and fixed point. 6306221Snate@binkert.org return new WarnUnimplemented("vcvt", machInst); 6316221Snate@binkert.org case 0xc: 6322292SN/A case 0xd: 6333867Sbinkertn@umich.edu // Between FP and int. 6346221Snate@binkert.org return new WarnUnimplemented("vcvt, vcvtr", machInst); 6353867Sbinkertn@umich.edu case 0xe: 6362292SN/A case 0xf: 6372292SN/A // Between FP and fixed point. 6382292SN/A return new WarnUnimplemented("vcvt", machInst); 6392292SN/A } 6402292SN/A break; 6412292SN/A } 6422292SN/A return new Unknown(machInst); 6432292SN/A } 6442292SN/A ''' 6456221Snate@binkert.org}}; 6462292SN/A 6473870Sbinkertn@umich.edudef format VfpData() {{ 6482292SN/A decode_block = ''' 6492292SN/A return decodeVfpData(machInst); 6502292SN/A ''' 6512292SN/A}}; 6522292SN/A