110037SARM gem5 Developers// -*- mode:c++ -*-
210037SARM gem5 Developers
312531Sandreas.sandberg@arm.com// Copyright (c) 2011-2013, 2016-2018 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
4010037SARM gem5 Developerslet {{
4110037SARM gem5 Developers    svcCode = '''
4210474Sandreas.hansson@arm.com    fault = std::make_shared<SupervisorCall>(machInst, bits(machInst, 20, 5));
4310037SARM gem5 Developers    '''
4410037SARM gem5 Developers
4512538Sgiacomo.travaglini@arm.com    svcIop = InstObjParams("svc", "Svc64", "ImmOp64",
4610037SARM gem5 Developers                           svcCode, ["IsSyscall", "IsNonSpeculative",
4710037SARM gem5 Developers                                     "IsSerializeAfter"])
4812538Sgiacomo.travaglini@arm.com    header_output = ImmOp64Declare.subst(svcIop)
4912538Sgiacomo.travaglini@arm.com    decoder_output = ImmOp64Constructor.subst(svcIop)
5010037SARM gem5 Developers    exec_output = BasicExecute.subst(svcIop)
5110037SARM gem5 Developers
5211576SDylan.Johnson@ARM.com    hvcCode = '''
5311576SDylan.Johnson@ARM.com    SCR scr = Scr64;
5413362Sgiacomo.travaglini@arm.com    HCR hcr = Hcr64;
5513362Sgiacomo.travaglini@arm.com    CPSR cpsr = Cpsr;
5611576SDylan.Johnson@ARM.com
5713362Sgiacomo.travaglini@arm.com    auto tc = xc->tcBase();
5813362Sgiacomo.travaglini@arm.com    ExceptionLevel pstate_EL = (ExceptionLevel)(uint8_t)(cpsr.el);
5913362Sgiacomo.travaglini@arm.com
6013362Sgiacomo.travaglini@arm.com    bool unalloc_encod = !ArmSystem::haveEL(tc, EL2) || pstate_EL == EL0 ||
6113362Sgiacomo.travaglini@arm.com                         (pstate_EL == EL1 && inSecureState(tc));
6213362Sgiacomo.travaglini@arm.com
6313362Sgiacomo.travaglini@arm.com    bool hvc_enable = ArmSystem::haveEL(tc, EL3) ?
6413362Sgiacomo.travaglini@arm.com        scr.hce : !hcr.hcd;
6513362Sgiacomo.travaglini@arm.com
6613362Sgiacomo.travaglini@arm.com    if (unalloc_encod || !hvc_enable) {
6713362Sgiacomo.travaglini@arm.com        fault = undefinedFault64(tc, pstate_EL);
6811576SDylan.Johnson@ARM.com    } else {
6911576SDylan.Johnson@ARM.com        fault = std::make_shared<HypervisorCall>(machInst, bits(machInst, 20, 5));
7011576SDylan.Johnson@ARM.com    }
7111576SDylan.Johnson@ARM.com    '''
7211576SDylan.Johnson@ARM.com
7312538Sgiacomo.travaglini@arm.com    hvcIop = InstObjParams("hvc", "Hvc64", "ImmOp64",
7411576SDylan.Johnson@ARM.com                           hvcCode, ["IsSyscall", "IsNonSpeculative",
7511576SDylan.Johnson@ARM.com                                     "IsSerializeAfter"])
7612538Sgiacomo.travaglini@arm.com    header_output += ImmOp64Declare.subst(hvcIop)
7712538Sgiacomo.travaglini@arm.com    decoder_output += ImmOp64Constructor.subst(hvcIop)
7811576SDylan.Johnson@ARM.com    exec_output += BasicExecute.subst(hvcIop)
7911576SDylan.Johnson@ARM.com
8010037SARM gem5 Developers    # @todo: extend to take into account Virtualization.
8110037SARM gem5 Developers    smcCode = '''
8210037SARM gem5 Developers    SCR scr = Scr64;
8310037SARM gem5 Developers    CPSR cpsr = Cpsr;
8410037SARM gem5 Developers
8510037SARM gem5 Developers    if (!ArmSystem::haveSecurity(xc->tcBase()) || inUserMode(cpsr) || scr.smd) {
8610037SARM gem5 Developers        fault = disabledFault();
8710037SARM gem5 Developers    } else {
8810474Sandreas.hansson@arm.com        fault = std::make_shared<SecureMonitorCall>(machInst);
8910037SARM gem5 Developers    }
9010037SARM gem5 Developers    '''
9110037SARM gem5 Developers
9212538Sgiacomo.travaglini@arm.com    smcIop = InstObjParams("smc", "Smc64", "ImmOp64",
9310037SARM gem5 Developers                           smcCode, ["IsNonSpeculative", "IsSerializeAfter"])
9412538Sgiacomo.travaglini@arm.com    header_output += ImmOp64Declare.subst(smcIop)
9512538Sgiacomo.travaglini@arm.com    decoder_output += ImmOp64Constructor.subst(smcIop)
9610037SARM gem5 Developers    exec_output += BasicExecute.subst(smcIop)
9710037SARM gem5 Developers
9810037SARM gem5 Developers    def subst(templateBase, iop):
9910037SARM gem5 Developers        global header_output, decoder_output, exec_output
10010037SARM gem5 Developers        header_output += eval(templateBase + "Declare").subst(iop)
10110037SARM gem5 Developers        decoder_output += eval(templateBase + "Constructor").subst(iop)
10210037SARM gem5 Developers        exec_output += BasicExecute.subst(iop)
10310037SARM gem5 Developers
10410037SARM gem5 Developers    bfmMaskCode = '''
10510037SARM gem5 Developers    uint64_t bitMask;
10610037SARM gem5 Developers    int diff = imm2 - imm1;
10710037SARM gem5 Developers    if (imm1 <= imm2) {
10810037SARM gem5 Developers        bitMask = mask(diff + 1);
10910037SARM gem5 Developers    } else {
11010037SARM gem5 Developers        bitMask = mask(imm2 + 1);
11110037SARM gem5 Developers        bitMask = (bitMask >> imm1) | (bitMask << (intWidth - imm1));
11210037SARM gem5 Developers        diff += intWidth;
11310037SARM gem5 Developers    }
11410037SARM gem5 Developers    uint64_t topBits M5_VAR_USED = ~mask(diff+1);
11510537Sandreas.hansson@arm.com    uint64_t result = imm1 == 0 ? Op164 :
11610537Sandreas.hansson@arm.com                      (Op164 >> imm1) | (Op164 << (intWidth - imm1));
11710037SARM gem5 Developers    result &= bitMask;
11810037SARM gem5 Developers    '''
11910037SARM gem5 Developers
12010037SARM gem5 Developers    bfmCode = bfmMaskCode + 'Dest64 = result | (Dest64 & ~bitMask);'
12110037SARM gem5 Developers    bfmIop = InstObjParams("bfm", "Bfm64", "RegRegImmImmOp64", bfmCode);
12210037SARM gem5 Developers    subst("RegRegImmImmOp64", bfmIop)
12310037SARM gem5 Developers
12410037SARM gem5 Developers    ubfmCode = bfmMaskCode + 'Dest64 = result;'
12510037SARM gem5 Developers    ubfmIop = InstObjParams("ubfm", "Ubfm64", "RegRegImmImmOp64", ubfmCode);
12610037SARM gem5 Developers    subst("RegRegImmImmOp64", ubfmIop)
12710037SARM gem5 Developers
12810037SARM gem5 Developers    sbfmCode = bfmMaskCode + \
12910037SARM gem5 Developers        'Dest64 = result | (bits(Op164, imm2) ? topBits : 0);'
13010037SARM gem5 Developers    sbfmIop = InstObjParams("sbfm", "Sbfm64", "RegRegImmImmOp64", sbfmCode);
13110037SARM gem5 Developers    subst("RegRegImmImmOp64", sbfmIop)
13210037SARM gem5 Developers
13310037SARM gem5 Developers    extrCode = '''
13410037SARM gem5 Developers        if (imm == 0) {
13510037SARM gem5 Developers            Dest64 = Op264;
13610037SARM gem5 Developers        } else {
13710037SARM gem5 Developers            Dest64 = (Op164 << (intWidth - imm)) | (Op264 >> imm);
13810037SARM gem5 Developers        }
13910037SARM gem5 Developers    '''
14010037SARM gem5 Developers    extrIop = InstObjParams("extr", "Extr64", "RegRegRegImmOp64", extrCode);
14110037SARM gem5 Developers    subst("RegRegRegImmOp64", extrIop);
14210037SARM gem5 Developers
14310037SARM gem5 Developers    unknownCode = '''
14410474Sandreas.hansson@arm.com            return std::make_shared<UndefinedInstruction>(machInst, true);
14510037SARM gem5 Developers    '''
14610037SARM gem5 Developers    unknown64Iop = InstObjParams("unknown", "Unknown64", "UnknownOp64",
14710037SARM gem5 Developers                                 unknownCode)
14810037SARM gem5 Developers    header_output += BasicDeclare.subst(unknown64Iop)
14910037SARM gem5 Developers    decoder_output += BasicConstructor64.subst(unknown64Iop)
15010037SARM gem5 Developers    exec_output += BasicExecute.subst(unknown64Iop)
15110037SARM gem5 Developers
15212259Sgiacomo.travaglini@arm.com    isbIop = InstObjParams("isb", "Isb64", "ArmStaticInst", "",
15312488Sgiacomo.travaglini@arm.com                           ['IsSquashAfter'])
15410037SARM gem5 Developers    header_output += BasicDeclare.subst(isbIop)
15510037SARM gem5 Developers    decoder_output += BasicConstructor64.subst(isbIop)
15610037SARM gem5 Developers    exec_output += BasicExecute.subst(isbIop)
15710037SARM gem5 Developers
15812259Sgiacomo.travaglini@arm.com    dsbIop = InstObjParams("dsb", "Dsb64", "ArmStaticInst", "",
15912261Sgiacomo.travaglini@arm.com                           ['IsMemBarrier', 'IsSerializeAfter'])
16010037SARM gem5 Developers    header_output += BasicDeclare.subst(dsbIop)
16110037SARM gem5 Developers    decoder_output += BasicConstructor64.subst(dsbIop)
16210037SARM gem5 Developers    exec_output += BasicExecute.subst(dsbIop)
16310037SARM gem5 Developers
16410037SARM gem5 Developers    dmbIop = InstObjParams("dmb", "Dmb64", "ArmStaticInst", "",
16510037SARM gem5 Developers                           ['IsMemBarrier'])
16610037SARM gem5 Developers    header_output += BasicDeclare.subst(dmbIop)
16710037SARM gem5 Developers    decoder_output += BasicConstructor64.subst(dmbIop)
16810037SARM gem5 Developers    exec_output += BasicExecute.subst(dmbIop)
16910037SARM gem5 Developers
17010037SARM gem5 Developers    clrexIop = InstObjParams("clrex", "Clrex64", "ArmStaticInst",
17110037SARM gem5 Developers                             "LLSCLock = 0;")
17210037SARM gem5 Developers    header_output += BasicDeclare.subst(clrexIop)
17310037SARM gem5 Developers    decoder_output += BasicConstructor64.subst(clrexIop)
17410037SARM gem5 Developers    exec_output += BasicExecute.subst(clrexIop)
17512299Sandreas.sandberg@arm.com
17612299Sandreas.sandberg@arm.com
17712299Sandreas.sandberg@arm.com    brkCode = '''
17812299Sandreas.sandberg@arm.com    fault = std::make_shared<SoftwareBreakpoint>(machInst,
17912299Sandreas.sandberg@arm.com                                                 bits(machInst, 20, 5));
18012299Sandreas.sandberg@arm.com    '''
18112299Sandreas.sandberg@arm.com
18212538Sgiacomo.travaglini@arm.com    brkIop = InstObjParams("brk", "Brk64", "ImmOp64",
18312299Sandreas.sandberg@arm.com                           brkCode, ["IsSerializeAfter"])
18412538Sgiacomo.travaglini@arm.com    header_output += ImmOp64Declare.subst(brkIop)
18512538Sgiacomo.travaglini@arm.com    decoder_output += ImmOp64Constructor.subst(brkIop)
18612299Sandreas.sandberg@arm.com    exec_output += BasicExecute.subst(brkIop)
18712531Sandreas.sandberg@arm.com
18812531Sandreas.sandberg@arm.com    hltCode = '''
18912531Sandreas.sandberg@arm.com    ThreadContext *tc = xc->tcBase();
19012539Sgiacomo.travaglini@arm.com    if (ArmSystem::haveSemihosting(tc) && imm == 0xF000) {
19112531Sandreas.sandberg@arm.com        X0 = ArmSystem::callSemihosting64(tc, X0 & mask(32), X1);
19212531Sandreas.sandberg@arm.com    } else {
19312531Sandreas.sandberg@arm.com        // HLT instructions aren't implemented, so treat them as undefined
19412531Sandreas.sandberg@arm.com        // instructions.
19512531Sandreas.sandberg@arm.com        fault = std::make_shared<UndefinedInstruction>(
19612531Sandreas.sandberg@arm.com            machInst, false, mnemonic);
19712531Sandreas.sandberg@arm.com    }
19812531Sandreas.sandberg@arm.com
19912531Sandreas.sandberg@arm.com    '''
20012531Sandreas.sandberg@arm.com
20112538Sgiacomo.travaglini@arm.com    hltIop = InstObjParams("hlt", "Hlt64", "ImmOp64",
20212531Sandreas.sandberg@arm.com                           hltCode, ["IsNonSpeculative"])
20312538Sgiacomo.travaglini@arm.com    header_output += ImmOp64Declare.subst(hltIop)
20412543Sgiacomo.travaglini@arm.com    decoder_output += SemihostConstructor64.subst(hltIop)
20512531Sandreas.sandberg@arm.com    exec_output += BasicExecute.subst(hltIop)
20610037SARM gem5 Developers}};
207