branch64.isa revision 10037
110037SARM gem5 Developers// -*- mode:c++ -*- 210037SARM gem5 Developers 310037SARM gem5 Developers// Copyright (c) 2011-2013 ARM Limited 410037SARM gem5 Developers// All rights reserved 510037SARM gem5 Developers// 610037SARM gem5 Developers// The license below extends only to copyright in the software and shall 710037SARM gem5 Developers// not be construed as granting a license to any other intellectual 810037SARM gem5 Developers// property including but not limited to intellectual property relating 910037SARM gem5 Developers// to a hardware implementation of the functionality of the software 1010037SARM gem5 Developers// licensed hereunder. You may use the software subject to the license 1110037SARM gem5 Developers// terms below provided that you ensure that this notice is replicated 1210037SARM gem5 Developers// unmodified and in its entirety in all distributions of the software, 1310037SARM gem5 Developers// modified or unmodified, in source code or in binary form. 1410037SARM gem5 Developers// 1510037SARM gem5 Developers// Redistribution and use in source and binary forms, with or without 1610037SARM gem5 Developers// modification, are permitted provided that the following conditions are 1710037SARM gem5 Developers// met: redistributions of source code must retain the above copyright 1810037SARM gem5 Developers// notice, this list of conditions and the following disclaimer; 1910037SARM gem5 Developers// redistributions in binary form must reproduce the above copyright 2010037SARM gem5 Developers// notice, this list of conditions and the following disclaimer in the 2110037SARM gem5 Developers// documentation and/or other materials provided with the distribution; 2210037SARM gem5 Developers// neither the name of the copyright holders nor the names of its 2310037SARM gem5 Developers// contributors may be used to endorse or promote products derived from 2410037SARM gem5 Developers// this software without specific prior written permission. 2510037SARM gem5 Developers// 2610037SARM gem5 Developers// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2710037SARM gem5 Developers// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2810037SARM gem5 Developers// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2910037SARM gem5 Developers// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3010037SARM gem5 Developers// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3110037SARM gem5 Developers// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3210037SARM gem5 Developers// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3310037SARM gem5 Developers// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3410037SARM gem5 Developers// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3510037SARM gem5 Developers// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3610037SARM gem5 Developers// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3710037SARM gem5 Developers// 3810037SARM gem5 Developers// Authors: Gabe Black 3910037SARM gem5 Developers// Giacomo Gabrielli 4010037SARM gem5 Developers 4110037SARM gem5 Developerslet {{ 4210037SARM gem5 Developers 4310037SARM gem5 Developers header_output = "" 4410037SARM gem5 Developers decoder_output = "" 4510037SARM gem5 Developers exec_output = "" 4610037SARM gem5 Developers 4710037SARM gem5 Developers # B, BL 4810037SARM gem5 Developers for (mnem, link) in (("b", False), ("bl", True)): 4910037SARM gem5 Developers bCode = ('NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(), ' 5010037SARM gem5 Developers 'currEL(xc->tcBase()));\n') 5110037SARM gem5 Developers instFlags = ['IsDirectControl', 'IsUncondControl'] 5210037SARM gem5 Developers if (link): 5310037SARM gem5 Developers bCode += 'XLR = RawPC + 4;\n' 5410037SARM gem5 Developers instFlags += ['IsCall'] 5510037SARM gem5 Developers 5610037SARM gem5 Developers bIop = InstObjParams(mnem, mnem.capitalize() + "64", 5710037SARM gem5 Developers "BranchImm64", bCode, instFlags) 5810037SARM gem5 Developers header_output += BranchImm64Declare.subst(bIop) 5910037SARM gem5 Developers decoder_output += BranchImm64Constructor.subst(bIop) 6010037SARM gem5 Developers exec_output += BasicExecute.subst(bIop) 6110037SARM gem5 Developers 6210037SARM gem5 Developers # BR, BLR 6310037SARM gem5 Developers for (mnem, link) in (("br", False), ("blr", True)): 6410037SARM gem5 Developers bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), ' 6510037SARM gem5 Developers 'currEL(xc->tcBase()));\n') 6610037SARM gem5 Developers instFlags = ['IsIndirectControl', 'IsUncondControl'] 6710037SARM gem5 Developers if (link): 6810037SARM gem5 Developers bCode += 'XLR = RawPC + 4;\n' 6910037SARM gem5 Developers instFlags += ['IsCall'] 7010037SARM gem5 Developers 7110037SARM gem5 Developers bIop = InstObjParams(mnem, mnem.capitalize() + "64", 7210037SARM gem5 Developers "BranchReg64", bCode, instFlags) 7310037SARM gem5 Developers header_output += BranchReg64Declare.subst(bIop) 7410037SARM gem5 Developers decoder_output += BranchReg64Constructor.subst(bIop) 7510037SARM gem5 Developers exec_output += BasicExecute.subst(bIop) 7610037SARM gem5 Developers 7710037SARM gem5 Developers # B conditional 7810037SARM gem5 Developers bCode = ''' 7910037SARM gem5 Developers if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) 8010037SARM gem5 Developers NPC = purifyTaggedAddr(RawPC + imm, xc->tcBase(), 8110037SARM gem5 Developers currEL(xc->tcBase())); 8210037SARM gem5 Developers else 8310037SARM gem5 Developers NPC = NPC; 8410037SARM gem5 Developers ''' 8510037SARM gem5 Developers bIop = InstObjParams("b", "BCond64", "BranchImmCond64", bCode, 8610037SARM gem5 Developers ['IsCondControl', 'IsDirectControl']) 8710037SARM gem5 Developers header_output += BranchImmCond64Declare.subst(bIop) 8810037SARM gem5 Developers decoder_output += BranchImmCond64Constructor.subst(bIop) 8910037SARM gem5 Developers exec_output += BasicExecute.subst(bIop) 9010037SARM gem5 Developers 9110037SARM gem5 Developers # RET 9210037SARM gem5 Developers bCode = ('NPC = purifyTaggedAddr(XOp1, xc->tcBase(), ' 9310037SARM gem5 Developers 'currEL(xc->tcBase()));\n') 9410037SARM gem5 Developers instFlags = ['IsIndirectControl', 'IsUncondControl', 'IsReturn'] 9510037SARM gem5 Developers 9610037SARM gem5 Developers bIop = InstObjParams('ret', 'Ret64', "BranchRet64", bCode, instFlags) 9710037SARM gem5 Developers header_output += BranchReg64Declare.subst(bIop) 9810037SARM gem5 Developers decoder_output += BranchReg64Constructor.subst(bIop) 9910037SARM gem5 Developers exec_output += BasicExecute.subst(bIop) 10010037SARM gem5 Developers 10110037SARM gem5 Developers # ERET 10210037SARM gem5 Developers bCode = '''Addr newPc; 10310037SARM gem5 Developers CPSR cpsr = Cpsr; 10410037SARM gem5 Developers CPSR spsr = Spsr; 10510037SARM gem5 Developers 10610037SARM gem5 Developers ExceptionLevel curr_el = opModeToEL((OperatingMode) (uint8_t) cpsr.mode); 10710037SARM gem5 Developers switch (curr_el) { 10810037SARM gem5 Developers case EL3: 10910037SARM gem5 Developers newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL3); 11010037SARM gem5 Developers break; 11110037SARM gem5 Developers case EL2: 11210037SARM gem5 Developers newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL2); 11310037SARM gem5 Developers break; 11410037SARM gem5 Developers case EL1: 11510037SARM gem5 Developers newPc = xc->tcBase()->readMiscReg(MISCREG_ELR_EL1); 11610037SARM gem5 Developers break; 11710037SARM gem5 Developers default: 11810037SARM gem5 Developers return new UndefinedInstruction(machInst, false, mnemonic); 11910037SARM gem5 Developers break; 12010037SARM gem5 Developers } 12110037SARM gem5 Developers if (spsr.width && (newPc & mask(2))) { 12210037SARM gem5 Developers // To avoid PC Alignment fault when returning to AArch32 12310037SARM gem5 Developers if (spsr.t) 12410037SARM gem5 Developers newPc = newPc & ~mask(1); 12510037SARM gem5 Developers else 12610037SARM gem5 Developers newPc = newPc & ~mask(2); 12710037SARM gem5 Developers } 12810037SARM gem5 Developers spsr.q = 0; 12910037SARM gem5 Developers spsr.it1 = 0; 13010037SARM gem5 Developers spsr.j = 0; 13110037SARM gem5 Developers spsr.res0_23_22 = 0; 13210037SARM gem5 Developers spsr.ge = 0; 13310037SARM gem5 Developers spsr.it2 = 0; 13410037SARM gem5 Developers spsr.t = 0; 13510037SARM gem5 Developers 13610037SARM gem5 Developers OperatingMode mode = (OperatingMode) (uint8_t) spsr.mode; 13710037SARM gem5 Developers bool illegal = false; 13810037SARM gem5 Developers ExceptionLevel target_el; 13910037SARM gem5 Developers if (badMode(mode)) { 14010037SARM gem5 Developers illegal = true; 14110037SARM gem5 Developers } else { 14210037SARM gem5 Developers target_el = opModeToEL(mode); 14310037SARM gem5 Developers if (((target_el == EL2) && 14410037SARM gem5 Developers !ArmSystem::haveVirtualization(xc->tcBase())) || 14510037SARM gem5 Developers (target_el > curr_el) || 14610037SARM gem5 Developers (spsr.width == 1)) { 14710037SARM gem5 Developers illegal = true; 14810037SARM gem5 Developers } else { 14910037SARM gem5 Developers bool known = true; 15010037SARM gem5 Developers bool from32 = (spsr.width == 1); 15110037SARM gem5 Developers bool to32 = false; 15210037SARM gem5 Developers if (false) { // TODO: !haveAArch32EL 15310037SARM gem5 Developers to32 = false; 15410037SARM gem5 Developers } else if (!ArmSystem::highestELIs64(xc->tcBase())) { 15510037SARM gem5 Developers to32 = true; 15610037SARM gem5 Developers } else { 15710037SARM gem5 Developers bool scr_rw, hcr_rw; 15810037SARM gem5 Developers if (ArmSystem::haveSecurity(xc->tcBase())) { 15910037SARM gem5 Developers SCR scr = xc->tcBase()->readMiscReg(MISCREG_SCR_EL3); 16010037SARM gem5 Developers scr_rw = scr.rw; 16110037SARM gem5 Developers } else { 16210037SARM gem5 Developers scr_rw = true; 16310037SARM gem5 Developers } 16410037SARM gem5 Developers 16510037SARM gem5 Developers if (ArmSystem::haveVirtualization(xc->tcBase())) { 16610037SARM gem5 Developers HCR hcr = xc->tcBase()->readMiscReg(MISCREG_HCR_EL2); 16710037SARM gem5 Developers hcr_rw = hcr.rw; 16810037SARM gem5 Developers } else { 16910037SARM gem5 Developers hcr_rw = scr_rw; 17010037SARM gem5 Developers } 17110037SARM gem5 Developers 17210037SARM gem5 Developers switch (target_el) { 17310037SARM gem5 Developers case EL3: 17410037SARM gem5 Developers to32 = false; 17510037SARM gem5 Developers break; 17610037SARM gem5 Developers case EL2: 17710037SARM gem5 Developers to32 = !scr_rw; 17810037SARM gem5 Developers break; 17910037SARM gem5 Developers case EL1: 18010037SARM gem5 Developers to32 = !scr_rw || !hcr_rw; 18110037SARM gem5 Developers break; 18210037SARM gem5 Developers case EL0: 18310037SARM gem5 Developers if (curr_el == EL0) { 18410037SARM gem5 Developers to32 = cpsr.width; 18510037SARM gem5 Developers } else if (!scr_rw || !hcr_rw) { 18610037SARM gem5 Developers // EL0 using AArch32 if EL1 using AArch32 18710037SARM gem5 Developers to32 = true; 18810037SARM gem5 Developers } else { 18910037SARM gem5 Developers known = false; 19010037SARM gem5 Developers to32 = false; 19110037SARM gem5 Developers } 19210037SARM gem5 Developers } 19310037SARM gem5 Developers } 19410037SARM gem5 Developers if (known) 19510037SARM gem5 Developers illegal = (from32 != to32); 19610037SARM gem5 Developers } 19710037SARM gem5 Developers } 19810037SARM gem5 Developers 19910037SARM gem5 Developers if (illegal) { 20010037SARM gem5 Developers uint8_t old_mode = cpsr.mode; 20110037SARM gem5 Developers spsr.mode = old_mode; // Preserve old mode when invalid 20210037SARM gem5 Developers spsr.il = 1; 20310037SARM gem5 Developers } else { 20410037SARM gem5 Developers if (cpsr.width != spsr.width) 20510037SARM gem5 Developers panic("AArch32/AArch64 interprocessing not supported yet"); 20610037SARM gem5 Developers } 20710037SARM gem5 Developers Cpsr = spsr; 20810037SARM gem5 Developers 20910037SARM gem5 Developers CondCodesNZ = spsr.nz; 21010037SARM gem5 Developers CondCodesC = spsr.c; 21110037SARM gem5 Developers CondCodesV = spsr.v; 21210037SARM gem5 Developers NPC = purifyTaggedAddr(newPc, xc->tcBase(), 21310037SARM gem5 Developers opModeToEL((OperatingMode) (uint8_t) spsr.mode)); 21410037SARM gem5 Developers LLSCLock = 0; // Clear exclusive monitor 21510037SARM gem5 Developers SevMailbox = 1; //Set Event Register 21610037SARM gem5 Developers ''' 21710037SARM gem5 Developers instFlags = ['IsSerializeAfter', 'IsNonSpeculative', 'IsSquashAfter'] 21810037SARM gem5 Developers bIop = InstObjParams('eret', 'Eret64', "BranchEret64", bCode, instFlags) 21910037SARM gem5 Developers header_output += BasicDeclare.subst(bIop) 22010037SARM gem5 Developers decoder_output += BasicConstructor64.subst(bIop) 22110037SARM gem5 Developers exec_output += BasicExecute.subst(bIop) 22210037SARM gem5 Developers 22310037SARM gem5 Developers # CBNZ, CBZ 22410037SARM gem5 Developers for (mnem, test) in (("cbz", "=="), ("cbnz", "!=")): 22510037SARM gem5 Developers code = ('NPC = (Op164 %(test)s 0) ? ' 22610037SARM gem5 Developers 'purifyTaggedAddr(RawPC + imm, xc->tcBase(), ' 22710037SARM gem5 Developers 'currEL(xc->tcBase())) : NPC;\n') 22810037SARM gem5 Developers code = code % {"test": test} 22910037SARM gem5 Developers iop = InstObjParams(mnem, mnem.capitalize() + "64", 23010037SARM gem5 Developers "BranchImmReg64", code, 23110037SARM gem5 Developers ['IsCondControl', 'IsDirectControl']) 23210037SARM gem5 Developers header_output += BranchImmReg64Declare.subst(iop) 23310037SARM gem5 Developers decoder_output += BranchImmReg64Constructor.subst(iop) 23410037SARM gem5 Developers exec_output += BasicExecute.subst(iop) 23510037SARM gem5 Developers 23610037SARM gem5 Developers # TBNZ, TBZ 23710037SARM gem5 Developers for (mnem, test) in (("tbz", "=="), ("tbnz", "!=")): 23810037SARM gem5 Developers code = ('NPC = ((Op164 & imm1) %(test)s 0) ? ' 23910037SARM gem5 Developers 'purifyTaggedAddr(RawPC + imm2, xc->tcBase(), ' 24010037SARM gem5 Developers 'currEL(xc->tcBase())) : NPC;\n') 24110037SARM gem5 Developers code = code % {"test": test} 24210037SARM gem5 Developers iop = InstObjParams(mnem, mnem.capitalize() + "64", 24310037SARM gem5 Developers "BranchImmImmReg64", code, 24410037SARM gem5 Developers ['IsCondControl', 'IsDirectControl']) 24510037SARM gem5 Developers header_output += BranchImmImmReg64Declare.subst(iop) 24610037SARM gem5 Developers decoder_output += BranchImmImmReg64Constructor.subst(iop) 24710037SARM gem5 Developers exec_output += BasicExecute.subst(iop) 24810037SARM gem5 Developers}}; 249