pseudo.cc revision 11572
110611SAndreas.Sandberg@ARM.com/* 211572SDylan.Johnson@ARM.com * Copyright (c) 2014,2016 ARM Limited 310611SAndreas.Sandberg@ARM.com * All rights reserved 410611SAndreas.Sandberg@ARM.com * 510611SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 610611SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 710611SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 810611SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 910611SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 1010611SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 1110611SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 1210611SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 1310611SAndreas.Sandberg@ARM.com * 1410696SAndreas.Sandberg@ARM.com * Copyright (c) 2007-2008 The Florida State University 1510696SAndreas.Sandberg@ARM.com * All rights reserved. 1610696SAndreas.Sandberg@ARM.com * 1710611SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 1810611SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 1910611SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 2010611SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 2110611SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 2210611SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 2310611SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 2410611SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 2510611SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 2610611SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 2710611SAndreas.Sandberg@ARM.com * 2810611SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2910611SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3010611SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3110611SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3210611SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3310611SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3410611SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3510611SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3610611SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3710611SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3810611SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3910611SAndreas.Sandberg@ARM.com * 4010611SAndreas.Sandberg@ARM.com * Authors: Andreas Sandberg 4110696SAndreas.Sandberg@ARM.com * Stephen Hines 4210611SAndreas.Sandberg@ARM.com */ 4310611SAndreas.Sandberg@ARM.com 4410611SAndreas.Sandberg@ARM.com#include "arch/arm/insts/pseudo.hh" 4510611SAndreas.Sandberg@ARM.com#include "cpu/exec_context.hh" 4610611SAndreas.Sandberg@ARM.com 4710611SAndreas.Sandberg@ARM.comDecoderFaultInst::DecoderFaultInst(ExtMachInst _machInst) 4810611SAndreas.Sandberg@ARM.com : ArmStaticInst("gem5decoderFault", _machInst, No_OpClass), 4910611SAndreas.Sandberg@ARM.com faultId(static_cast<DecoderFault>( 5010611SAndreas.Sandberg@ARM.com static_cast<uint8_t>(_machInst.decoderFault))) 5110611SAndreas.Sandberg@ARM.com{ 5210611SAndreas.Sandberg@ARM.com // Don't call execute() if we're on a speculative path and the 5310611SAndreas.Sandberg@ARM.com // fault is an internal panic fault. 5410611SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = (faultId == DecoderFault::PANIC); 5510611SAndreas.Sandberg@ARM.com} 5610611SAndreas.Sandberg@ARM.com 5710611SAndreas.Sandberg@ARM.comFault 5810611SAndreas.Sandberg@ARM.comDecoderFaultInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const 5910611SAndreas.Sandberg@ARM.com{ 6010611SAndreas.Sandberg@ARM.com const PCState pc_state(xc->pcState()); 6110611SAndreas.Sandberg@ARM.com const Addr pc(pc_state.instAddr()); 6210611SAndreas.Sandberg@ARM.com 6310611SAndreas.Sandberg@ARM.com switch (faultId) { 6410611SAndreas.Sandberg@ARM.com case DecoderFault::UNALIGNED: 6510611SAndreas.Sandberg@ARM.com if (machInst.aarch64) { 6610611SAndreas.Sandberg@ARM.com return std::make_shared<PCAlignmentFault>(pc); 6710611SAndreas.Sandberg@ARM.com } else { 6810611SAndreas.Sandberg@ARM.com // TODO: We should check if we the receiving end is in 6910611SAndreas.Sandberg@ARM.com // aarch64 mode and raise a PCAlignment fault instead. 7010611SAndreas.Sandberg@ARM.com return std::make_shared<PrefetchAbort>( 7110611SAndreas.Sandberg@ARM.com pc, ArmFault::AlignmentFault); 7210611SAndreas.Sandberg@ARM.com } 7310611SAndreas.Sandberg@ARM.com 7410611SAndreas.Sandberg@ARM.com case DecoderFault::PANIC: 7510611SAndreas.Sandberg@ARM.com panic("Internal error in instruction decoder\n"); 7610611SAndreas.Sandberg@ARM.com 7710611SAndreas.Sandberg@ARM.com case DecoderFault::OK: 7810611SAndreas.Sandberg@ARM.com panic("Decoder fault instruction without decoder fault.\n"); 7910611SAndreas.Sandberg@ARM.com } 8010611SAndreas.Sandberg@ARM.com 8110611SAndreas.Sandberg@ARM.com panic("Unhandled fault type"); 8210611SAndreas.Sandberg@ARM.com} 8310611SAndreas.Sandberg@ARM.com 8410611SAndreas.Sandberg@ARM.comconst char * 8510611SAndreas.Sandberg@ARM.comDecoderFaultInst::faultName() const 8610611SAndreas.Sandberg@ARM.com{ 8710611SAndreas.Sandberg@ARM.com switch (faultId) { 8810611SAndreas.Sandberg@ARM.com case DecoderFault::OK: 8910611SAndreas.Sandberg@ARM.com return "OK"; 9010611SAndreas.Sandberg@ARM.com 9110611SAndreas.Sandberg@ARM.com case DecoderFault::UNALIGNED: 9210611SAndreas.Sandberg@ARM.com return "UnalignedInstruction"; 9310611SAndreas.Sandberg@ARM.com 9410611SAndreas.Sandberg@ARM.com case DecoderFault::PANIC: 9510611SAndreas.Sandberg@ARM.com return "DecoderPanic"; 9610611SAndreas.Sandberg@ARM.com } 9710611SAndreas.Sandberg@ARM.com 9810611SAndreas.Sandberg@ARM.com panic("Unhandled fault type"); 9910611SAndreas.Sandberg@ARM.com} 10010611SAndreas.Sandberg@ARM.com 10110611SAndreas.Sandberg@ARM.comstd::string 10210611SAndreas.Sandberg@ARM.comDecoderFaultInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const 10310611SAndreas.Sandberg@ARM.com{ 10410611SAndreas.Sandberg@ARM.com return csprintf("gem5fault %s", faultName()); 10510611SAndreas.Sandberg@ARM.com} 10610696SAndreas.Sandberg@ARM.com 10710696SAndreas.Sandberg@ARM.com 10810696SAndreas.Sandberg@ARM.com 10910696SAndreas.Sandberg@ARM.comFailUnimplemented::FailUnimplemented(const char *_mnemonic, 11010696SAndreas.Sandberg@ARM.com ExtMachInst _machInst) 11110696SAndreas.Sandberg@ARM.com : ArmStaticInst(_mnemonic, _machInst, No_OpClass) 11210696SAndreas.Sandberg@ARM.com{ 11310696SAndreas.Sandberg@ARM.com // don't call execute() (which panics) if we're on a 11410696SAndreas.Sandberg@ARM.com // speculative path 11510696SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = true; 11610696SAndreas.Sandberg@ARM.com} 11710696SAndreas.Sandberg@ARM.com 11810696SAndreas.Sandberg@ARM.comFailUnimplemented::FailUnimplemented(const char *_mnemonic, 11910696SAndreas.Sandberg@ARM.com ExtMachInst _machInst, 12010696SAndreas.Sandberg@ARM.com const std::string& _fullMnemonic) 12110696SAndreas.Sandberg@ARM.com : ArmStaticInst(_mnemonic, _machInst, No_OpClass), 12210696SAndreas.Sandberg@ARM.com fullMnemonic(_fullMnemonic) 12310696SAndreas.Sandberg@ARM.com{ 12410696SAndreas.Sandberg@ARM.com // don't call execute() (which panics) if we're on a 12510696SAndreas.Sandberg@ARM.com // speculative path 12610696SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = true; 12710696SAndreas.Sandberg@ARM.com} 12810696SAndreas.Sandberg@ARM.com 12910696SAndreas.Sandberg@ARM.comFault 13010696SAndreas.Sandberg@ARM.comFailUnimplemented::execute(ExecContext *xc, Trace::InstRecord *traceData) const 13110696SAndreas.Sandberg@ARM.com{ 13210696SAndreas.Sandberg@ARM.com return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic); 13310696SAndreas.Sandberg@ARM.com} 13410696SAndreas.Sandberg@ARM.com 13510696SAndreas.Sandberg@ARM.comstd::string 13610696SAndreas.Sandberg@ARM.comFailUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const 13710696SAndreas.Sandberg@ARM.com{ 13810696SAndreas.Sandberg@ARM.com return csprintf("%-10s (unimplemented)", 13910696SAndreas.Sandberg@ARM.com fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic); 14010696SAndreas.Sandberg@ARM.com} 14110696SAndreas.Sandberg@ARM.com 14210696SAndreas.Sandberg@ARM.com 14310696SAndreas.Sandberg@ARM.com 14410696SAndreas.Sandberg@ARM.comWarnUnimplemented::WarnUnimplemented(const char *_mnemonic, 14510696SAndreas.Sandberg@ARM.com ExtMachInst _machInst) 14610696SAndreas.Sandberg@ARM.com : ArmStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) 14710696SAndreas.Sandberg@ARM.com{ 14810696SAndreas.Sandberg@ARM.com // don't call execute() (which panics) if we're on a 14910696SAndreas.Sandberg@ARM.com // speculative path 15010696SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = true; 15110696SAndreas.Sandberg@ARM.com} 15210696SAndreas.Sandberg@ARM.com 15310696SAndreas.Sandberg@ARM.comWarnUnimplemented::WarnUnimplemented(const char *_mnemonic, 15410696SAndreas.Sandberg@ARM.com ExtMachInst _machInst, 15510696SAndreas.Sandberg@ARM.com const std::string& _fullMnemonic) 15610696SAndreas.Sandberg@ARM.com : ArmStaticInst(_mnemonic, _machInst, No_OpClass), warned(false), 15710696SAndreas.Sandberg@ARM.com fullMnemonic(_fullMnemonic) 15810696SAndreas.Sandberg@ARM.com{ 15910696SAndreas.Sandberg@ARM.com // don't call execute() (which panics) if we're on a 16010696SAndreas.Sandberg@ARM.com // speculative path 16110696SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = true; 16210696SAndreas.Sandberg@ARM.com} 16310696SAndreas.Sandberg@ARM.com 16410696SAndreas.Sandberg@ARM.comFault 16510696SAndreas.Sandberg@ARM.comWarnUnimplemented::execute(ExecContext *xc, Trace::InstRecord *traceData) const 16610696SAndreas.Sandberg@ARM.com{ 16710696SAndreas.Sandberg@ARM.com if (!warned) { 16810696SAndreas.Sandberg@ARM.com warn("\tinstruction '%s' unimplemented\n", 16910696SAndreas.Sandberg@ARM.com fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic); 17010696SAndreas.Sandberg@ARM.com warned = true; 17110696SAndreas.Sandberg@ARM.com } 17210696SAndreas.Sandberg@ARM.com 17310696SAndreas.Sandberg@ARM.com return NoFault; 17410696SAndreas.Sandberg@ARM.com} 17510696SAndreas.Sandberg@ARM.com 17610696SAndreas.Sandberg@ARM.comstd::string 17710696SAndreas.Sandberg@ARM.comWarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const 17810696SAndreas.Sandberg@ARM.com{ 17910696SAndreas.Sandberg@ARM.com return csprintf("%-10s (unimplemented)", 18010696SAndreas.Sandberg@ARM.com fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic); 18110696SAndreas.Sandberg@ARM.com} 18210696SAndreas.Sandberg@ARM.com 18310696SAndreas.Sandberg@ARM.com 18410696SAndreas.Sandberg@ARM.com 18511572SDylan.Johnson@ARM.comMcrMrcMiscInst::McrMrcMiscInst(const char *_mnemonic, ExtMachInst _machInst, 18611572SDylan.Johnson@ARM.com uint64_t _iss, MiscRegIndex _miscReg) 18710696SAndreas.Sandberg@ARM.com : ArmStaticInst(_mnemonic, _machInst, No_OpClass) 18810696SAndreas.Sandberg@ARM.com{ 18910696SAndreas.Sandberg@ARM.com flags[IsNonSpeculative] = true; 19011572SDylan.Johnson@ARM.com iss = _iss; 19111572SDylan.Johnson@ARM.com miscReg = _miscReg; 19210696SAndreas.Sandberg@ARM.com} 19310696SAndreas.Sandberg@ARM.com 19410696SAndreas.Sandberg@ARM.comFault 19511572SDylan.Johnson@ARM.comMcrMrcMiscInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const 19610696SAndreas.Sandberg@ARM.com{ 19711572SDylan.Johnson@ARM.com uint32_t cpsr = xc->readMiscReg(MISCREG_CPSR); 19811572SDylan.Johnson@ARM.com uint32_t hcr = xc->readMiscReg(MISCREG_HCR); 19911572SDylan.Johnson@ARM.com uint32_t scr = xc->readMiscReg(MISCREG_SCR); 20011572SDylan.Johnson@ARM.com uint32_t hdcr = xc->readMiscReg(MISCREG_HDCR); 20111572SDylan.Johnson@ARM.com uint32_t hstr = xc->readMiscReg(MISCREG_HSTR); 20211572SDylan.Johnson@ARM.com uint32_t hcptr = xc->readMiscReg(MISCREG_HCPTR); 20311572SDylan.Johnson@ARM.com 20411572SDylan.Johnson@ARM.com bool hypTrap = mcrMrc15TrapToHyp(miscReg, hcr, cpsr, scr, hdcr, hstr, 20511572SDylan.Johnson@ARM.com hcptr, iss); 20611572SDylan.Johnson@ARM.com if (hypTrap) { 20711572SDylan.Johnson@ARM.com return std::make_shared<HypervisorTrap>(machInst, iss, 20811572SDylan.Johnson@ARM.com EC_TRAPPED_CP15_MCR_MRC); 20911572SDylan.Johnson@ARM.com } 21011572SDylan.Johnson@ARM.com 21111572SDylan.Johnson@ARM.com if (miscReg == MISCREG_DCCMVAC) 21211572SDylan.Johnson@ARM.com return std::make_shared<FlushPipe>(); 21311572SDylan.Johnson@ARM.com else 21411572SDylan.Johnson@ARM.com return NoFault; 21510696SAndreas.Sandberg@ARM.com} 21610696SAndreas.Sandberg@ARM.com 21710696SAndreas.Sandberg@ARM.comstd::string 21811572SDylan.Johnson@ARM.comMcrMrcMiscInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const 21910696SAndreas.Sandberg@ARM.com{ 22010696SAndreas.Sandberg@ARM.com return csprintf("%-10s (pipe flush)", mnemonic); 22110696SAndreas.Sandberg@ARM.com} 222