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