110611SAndreas.Sandberg@ARM.com/*
212530Sgiacomo.travaglini@arm.com * Copyright (c) 2014,2016-2018 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"
4511793Sbrandon.potter@amd.com
4610611SAndreas.Sandberg@ARM.com#include "cpu/exec_context.hh"
4710611SAndreas.Sandberg@ARM.com
4810611SAndreas.Sandberg@ARM.comDecoderFaultInst::DecoderFaultInst(ExtMachInst _machInst)
4910611SAndreas.Sandberg@ARM.com    : ArmStaticInst("gem5decoderFault", _machInst, No_OpClass),
5010611SAndreas.Sandberg@ARM.com      faultId(static_cast<DecoderFault>(
5110611SAndreas.Sandberg@ARM.com                  static_cast<uint8_t>(_machInst.decoderFault)))
5210611SAndreas.Sandberg@ARM.com{
5310611SAndreas.Sandberg@ARM.com    // Don't call execute() if we're on a speculative path and the
5410611SAndreas.Sandberg@ARM.com    // fault is an internal panic fault.
5510611SAndreas.Sandberg@ARM.com    flags[IsNonSpeculative] = (faultId == DecoderFault::PANIC);
5610611SAndreas.Sandberg@ARM.com}
5710611SAndreas.Sandberg@ARM.com
5810611SAndreas.Sandberg@ARM.comFault
5910611SAndreas.Sandberg@ARM.comDecoderFaultInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
6010611SAndreas.Sandberg@ARM.com{
6110611SAndreas.Sandberg@ARM.com    const PCState pc_state(xc->pcState());
6210611SAndreas.Sandberg@ARM.com    const Addr pc(pc_state.instAddr());
6310611SAndreas.Sandberg@ARM.com
6410611SAndreas.Sandberg@ARM.com    switch (faultId) {
6510611SAndreas.Sandberg@ARM.com      case DecoderFault::UNALIGNED:
6610611SAndreas.Sandberg@ARM.com        if (machInst.aarch64) {
6710611SAndreas.Sandberg@ARM.com            return std::make_shared<PCAlignmentFault>(pc);
6810611SAndreas.Sandberg@ARM.com        } else {
6910611SAndreas.Sandberg@ARM.com            // TODO: We should check if we the receiving end is in
7010611SAndreas.Sandberg@ARM.com            // aarch64 mode and raise a PCAlignment fault instead.
7110611SAndreas.Sandberg@ARM.com            return std::make_shared<PrefetchAbort>(
7210611SAndreas.Sandberg@ARM.com                pc, ArmFault::AlignmentFault);
7310611SAndreas.Sandberg@ARM.com        }
7410611SAndreas.Sandberg@ARM.com
7510611SAndreas.Sandberg@ARM.com      case DecoderFault::PANIC:
7610611SAndreas.Sandberg@ARM.com        panic("Internal error in instruction decoder\n");
7710611SAndreas.Sandberg@ARM.com
7810611SAndreas.Sandberg@ARM.com      case DecoderFault::OK:
7910611SAndreas.Sandberg@ARM.com        panic("Decoder fault instruction without decoder fault.\n");
8010611SAndreas.Sandberg@ARM.com    }
8110611SAndreas.Sandberg@ARM.com
8210611SAndreas.Sandberg@ARM.com    panic("Unhandled fault type");
8310611SAndreas.Sandberg@ARM.com}
8410611SAndreas.Sandberg@ARM.com
8510611SAndreas.Sandberg@ARM.comconst char *
8610611SAndreas.Sandberg@ARM.comDecoderFaultInst::faultName() const
8710611SAndreas.Sandberg@ARM.com{
8810611SAndreas.Sandberg@ARM.com    switch (faultId) {
8910611SAndreas.Sandberg@ARM.com      case DecoderFault::OK:
9010611SAndreas.Sandberg@ARM.com        return "OK";
9110611SAndreas.Sandberg@ARM.com
9210611SAndreas.Sandberg@ARM.com      case DecoderFault::UNALIGNED:
9310611SAndreas.Sandberg@ARM.com        return "UnalignedInstruction";
9410611SAndreas.Sandberg@ARM.com
9510611SAndreas.Sandberg@ARM.com      case DecoderFault::PANIC:
9610611SAndreas.Sandberg@ARM.com        return "DecoderPanic";
9710611SAndreas.Sandberg@ARM.com    }
9810611SAndreas.Sandberg@ARM.com
9910611SAndreas.Sandberg@ARM.com    panic("Unhandled fault type");
10010611SAndreas.Sandberg@ARM.com}
10110611SAndreas.Sandberg@ARM.com
10210611SAndreas.Sandberg@ARM.comstd::string
10310611SAndreas.Sandberg@ARM.comDecoderFaultInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
10410611SAndreas.Sandberg@ARM.com{
10510611SAndreas.Sandberg@ARM.com    return csprintf("gem5fault %s", faultName());
10610611SAndreas.Sandberg@ARM.com}
10710696SAndreas.Sandberg@ARM.com
10810696SAndreas.Sandberg@ARM.com
10910696SAndreas.Sandberg@ARM.com
11010696SAndreas.Sandberg@ARM.comFailUnimplemented::FailUnimplemented(const char *_mnemonic,
11110696SAndreas.Sandberg@ARM.com                                     ExtMachInst _machInst)
11210696SAndreas.Sandberg@ARM.com    : ArmStaticInst(_mnemonic, _machInst, No_OpClass)
11310696SAndreas.Sandberg@ARM.com{
11410696SAndreas.Sandberg@ARM.com    // don't call execute() (which panics) if we're on a
11510696SAndreas.Sandberg@ARM.com    // speculative path
11610696SAndreas.Sandberg@ARM.com    flags[IsNonSpeculative] = true;
11710696SAndreas.Sandberg@ARM.com}
11810696SAndreas.Sandberg@ARM.com
11910696SAndreas.Sandberg@ARM.comFailUnimplemented::FailUnimplemented(const char *_mnemonic,
12010696SAndreas.Sandberg@ARM.com                                     ExtMachInst _machInst,
12110696SAndreas.Sandberg@ARM.com                                     const std::string& _fullMnemonic)
12210696SAndreas.Sandberg@ARM.com    : ArmStaticInst(_mnemonic, _machInst, No_OpClass),
12310696SAndreas.Sandberg@ARM.com      fullMnemonic(_fullMnemonic)
12410696SAndreas.Sandberg@ARM.com{
12510696SAndreas.Sandberg@ARM.com    // don't call execute() (which panics) if we're on a
12610696SAndreas.Sandberg@ARM.com    // speculative path
12710696SAndreas.Sandberg@ARM.com    flags[IsNonSpeculative] = true;
12810696SAndreas.Sandberg@ARM.com}
12910696SAndreas.Sandberg@ARM.com
13010696SAndreas.Sandberg@ARM.comFault
13110696SAndreas.Sandberg@ARM.comFailUnimplemented::execute(ExecContext *xc, Trace::InstRecord *traceData) const
13210696SAndreas.Sandberg@ARM.com{
13310696SAndreas.Sandberg@ARM.com    return std::make_shared<UndefinedInstruction>(machInst, false, mnemonic);
13410696SAndreas.Sandberg@ARM.com}
13510696SAndreas.Sandberg@ARM.com
13610696SAndreas.Sandberg@ARM.comstd::string
13710696SAndreas.Sandberg@ARM.comFailUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const
13810696SAndreas.Sandberg@ARM.com{
13910696SAndreas.Sandberg@ARM.com    return csprintf("%-10s (unimplemented)",
14010696SAndreas.Sandberg@ARM.com                    fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic);
14110696SAndreas.Sandberg@ARM.com}
14210696SAndreas.Sandberg@ARM.com
14310696SAndreas.Sandberg@ARM.com
14410696SAndreas.Sandberg@ARM.com
14510696SAndreas.Sandberg@ARM.comWarnUnimplemented::WarnUnimplemented(const char *_mnemonic,
14610696SAndreas.Sandberg@ARM.com                                     ExtMachInst _machInst)
14710696SAndreas.Sandberg@ARM.com    : ArmStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
14810696SAndreas.Sandberg@ARM.com{
14910696SAndreas.Sandberg@ARM.com    // don't call execute() (which panics) if we're on a
15010696SAndreas.Sandberg@ARM.com    // speculative path
15110696SAndreas.Sandberg@ARM.com    flags[IsNonSpeculative] = true;
15210696SAndreas.Sandberg@ARM.com}
15310696SAndreas.Sandberg@ARM.com
15410696SAndreas.Sandberg@ARM.comWarnUnimplemented::WarnUnimplemented(const char *_mnemonic,
15510696SAndreas.Sandberg@ARM.com                                     ExtMachInst _machInst,
15610696SAndreas.Sandberg@ARM.com                                     const std::string& _fullMnemonic)
15710696SAndreas.Sandberg@ARM.com    : ArmStaticInst(_mnemonic, _machInst, No_OpClass), warned(false),
15810696SAndreas.Sandberg@ARM.com      fullMnemonic(_fullMnemonic)
15910696SAndreas.Sandberg@ARM.com{
16010696SAndreas.Sandberg@ARM.com    // don't call execute() (which panics) if we're on a
16110696SAndreas.Sandberg@ARM.com    // speculative path
16210696SAndreas.Sandberg@ARM.com    flags[IsNonSpeculative] = true;
16310696SAndreas.Sandberg@ARM.com}
16410696SAndreas.Sandberg@ARM.com
16510696SAndreas.Sandberg@ARM.comFault
16610696SAndreas.Sandberg@ARM.comWarnUnimplemented::execute(ExecContext *xc, Trace::InstRecord *traceData) const
16710696SAndreas.Sandberg@ARM.com{
16810696SAndreas.Sandberg@ARM.com    if (!warned) {
16910696SAndreas.Sandberg@ARM.com        warn("\tinstruction '%s' unimplemented\n",
17010696SAndreas.Sandberg@ARM.com             fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic);
17110696SAndreas.Sandberg@ARM.com        warned = true;
17210696SAndreas.Sandberg@ARM.com    }
17310696SAndreas.Sandberg@ARM.com
17410696SAndreas.Sandberg@ARM.com    return NoFault;
17510696SAndreas.Sandberg@ARM.com}
17610696SAndreas.Sandberg@ARM.com
17710696SAndreas.Sandberg@ARM.comstd::string
17810696SAndreas.Sandberg@ARM.comWarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab) const
17910696SAndreas.Sandberg@ARM.com{
18010696SAndreas.Sandberg@ARM.com    return csprintf("%-10s (unimplemented)",
18110696SAndreas.Sandberg@ARM.com                    fullMnemonic.size() ? fullMnemonic.c_str() : mnemonic);
18210696SAndreas.Sandberg@ARM.com}
18310696SAndreas.Sandberg@ARM.com
18412763Sgiacomo.travaglini@arm.comIllegalExecInst::IllegalExecInst(ExtMachInst _machInst)
18512763Sgiacomo.travaglini@arm.com    : ArmStaticInst("Illegal Execution", _machInst, No_OpClass)
18612763Sgiacomo.travaglini@arm.com{}
18712763Sgiacomo.travaglini@arm.com
18812763Sgiacomo.travaglini@arm.comFault
18912763Sgiacomo.travaglini@arm.comIllegalExecInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
19012763Sgiacomo.travaglini@arm.com{
19112763Sgiacomo.travaglini@arm.com    return std::make_shared<IllegalInstSetStateFault>();
19212763Sgiacomo.travaglini@arm.com}
193