diff options
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/SConscript | 4 | ||||
-rw-r--r-- | src/arch/arm/insts/branch.cc | 109 | ||||
-rw-r--r-- | src/arch/arm/insts/branch.hh | 139 | ||||
-rw-r--r-- | src/arch/arm/insts/macromem.hh | 159 | ||||
-rw-r--r-- | src/arch/arm/insts/mem.cc | 46 | ||||
-rw-r--r-- | src/arch/arm/insts/mem.hh | 109 | ||||
-rw-r--r-- | src/arch/arm/insts/pred_inst.cc | 106 | ||||
-rw-r--r-- | src/arch/arm/insts/pred_inst.hh | 160 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.cc | 53 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.hh | 55 | ||||
-rw-r--r-- | src/arch/arm/isa/base.isa | 87 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/branch.isa | 184 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/macromem.isa | 460 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/mem.isa | 86 | ||||
-rw-r--r-- | src/arch/arm/isa/formats/pred.isa | 201 | ||||
-rw-r--r-- | src/arch/arm/isa/includes.isa | 5 | ||||
-rw-r--r-- | src/arch/arm/isa/main.isa | 3 | ||||
-rw-r--r-- | src/arch/arm/isa/util.isa | 11 |
18 files changed, 1122 insertions, 855 deletions
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index dbd12e240..60a5ca3b0 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -35,6 +35,10 @@ if env['TARGET_ISA'] == 'arm': # Scons bug id: 2006 M5 Bug id: 308 Dir('isa/formats') Source('faults.cc') + Source('insts/branch.cc') + Source('insts/mem.cc') + Source('insts/pred_inst.cc') + Source('insts/static_inst.cc') Source('pagetable.cc') Source('regfile/regfile.cc') Source('tlb.cc') diff --git a/src/arch/arm/insts/branch.cc b/src/arch/arm/insts/branch.cc new file mode 100644 index 000000000..5160994f4 --- /dev/null +++ b/src/arch/arm/insts/branch.cc @@ -0,0 +1,109 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ + +#include "arch/arm/insts/branch.hh" +#include "base/loader/symtab.hh" + +namespace ArmISA +{ +Addr +Branch::branchTarget(Addr branchPC) const +{ + return branchPC + 8 + disp; +} + +Addr +Jump::branchTarget(ThreadContext *tc) const +{ + Addr NPC = tc->readPC() + 8; + uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); +} + +const std::string & +PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const +{ + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; +} + +std::string +Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + Addr target = pc + 8 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +std::string +BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + return ss.str(); +} + +std::string +Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} +} diff --git a/src/arch/arm/insts/branch.hh b/src/arch/arm/insts/branch.hh new file mode 100644 index 000000000..3c4cd8cd5 --- /dev/null +++ b/src/arch/arm/insts/branch.hh @@ -0,0 +1,139 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ +#ifndef __ARCH_ARM_INSTS_BRANCH_HH__ +#define __ARCH_ARM_INSTS_BRANCH_HH__ + +#include "arch/arm/insts/pred_inst.hh" + +namespace ArmISA +{ +/** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ +class PCDependentDisassembly : public PredOp +{ + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : PredOp(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ +class Branch : public PCDependentDisassembly +{ + protected: + /// target address (signed) Displacement . + int32_t disp; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(machInst.offset << 2) + { + //If Bit 26 is 1 then Sign Extend + if ( (disp & 0x02000000) > 0 ) { + disp |= 0xFC000000; + } + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for branch and exchange instructions on the ARM + */ +class BranchExchange : public PredOp +{ + protected: + /// Constructor + BranchExchange(const char *mnem, MachInst _machInst, + OpClass __opClass) + : PredOp(mnem, _machInst, __opClass) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Base class for jumps (register-indirect control transfers). In + * the Arm ISA, these are always unconditional. + */ +class Jump : public PCDependentDisassembly +{ + protected: + + /// Displacement to target address (signed). + int32_t disp; + + uint32_t target; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(machInst.offset << 2) + { + } + + Addr branchTarget(ThreadContext *tc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; +} + +#endif //__ARCH_ARM_INSTS_BRANCH_HH__ diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh new file mode 100644 index 000000000..cfc2075a1 --- /dev/null +++ b/src/arch/arm/insts/macromem.hh @@ -0,0 +1,159 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ +#ifndef __ARCH_ARM_MACROMEM_HH__ +#define __ARCH_ARM_MACROMEM_HH__ + +#include "arch/arm/insts/pred_inst.hh" + +namespace ArmISA +{ + +static inline unsigned int +number_of_ones(int32_t val) +{ + uint32_t ones = 0; + for (int i = 0; i < 32; i++ ) + { + if ( val & (1<<i) ) + ones++; + } + return ones; +} + +/** + * Arm Macro Memory operations like LDM/STM + */ +class ArmMacroMemoryOp : public PredMacroOp +{ + protected: + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + uint32_t reglist; + uint32_t ones; + uint32_t puswl, + prepost, + up, + psruser, + writeback, + loadop; + + ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, + OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : PredMacroOp(mnem, _machInst, __opClass), + memAccessFlags(0), + eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), + reglist(machInst.regList), ones(0), + puswl(machInst.puswl), + prepost(machInst.puswl.prepost), + up(machInst.puswl.up), + psruser(machInst.puswl.psruser), + writeback(machInst.puswl.writeback), + loadop(machInst.puswl.loadOp) + { + ones = number_of_ones(reglist); + numMicroops = ones + writeback + 1; + // Remember that writeback adds a uop + microOps = new StaticInstPtr[numMicroops]; + } +}; + +/** + * Arm Macro FPA operations to fix ldfd and stfd instructions + */ +class ArmMacroFPAOp : public PredMacroOp +{ + protected: + uint32_t puswl, + prepost, + up, + psruser, + writeback, + loadop; + int32_t disp8; + + ArmMacroFPAOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : PredMacroOp(mnem, _machInst, __opClass), + puswl(machInst.puswl), + prepost(machInst.puswl.prepost), + up(machInst.puswl.up), + psruser(machInst.puswl.psruser), + writeback(machInst.puswl.writeback), + loadop(machInst.puswl.loadOp), + disp8(machInst.immed7_0 << 2) + { + numMicroops = 3 + writeback; + microOps = new StaticInstPtr[numMicroops]; + } +}; + +/** + * Arm Macro FM operations to fix lfm and sfm + */ +class ArmMacroFMOp : public PredMacroOp +{ + protected: + uint32_t punwl, + prepost, + up, + n1bit, + writeback, + loadop, + n0bit, + count; + int32_t disp8; + + ArmMacroFMOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) + : PredMacroOp(mnem, _machInst, __opClass), + punwl(machInst.punwl), + prepost(machInst.puswl.prepost), + up(machInst.puswl.up), + n1bit(machInst.opcode22), + writeback(machInst.puswl.writeback), + loadop(machInst.puswl.loadOp), + n0bit(machInst.opcode15), + disp8(machInst.immed7_0 << 2) + { + // Transfer 1-4 registers based on n1 and n0 bits (with 00 repr. 4) + count = (n1bit << 1) | n0bit; + if (count == 0) + count = 4; + numMicroops = (3*count) + writeback; + microOps = new StaticInstPtr[numMicroops]; + } +}; +} + +#endif //__ARCH_ARM_INSTS_MACROMEM_HH__ diff --git a/src/arch/arm/insts/mem.cc b/src/arch/arm/insts/mem.cc new file mode 100644 index 000000000..e5e91a9ea --- /dev/null +++ b/src/arch/arm/insts/mem.cc @@ -0,0 +1,46 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ + +#include "arch/arm/insts/mem.hh" +#include "base/loader/symtab.hh" + +namespace ArmISA +{ +std::string +Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + return csprintf("%-10s", mnemonic); +} + +std::string +MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + return csprintf("%-10s", mnemonic); +} +} diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh new file mode 100644 index 000000000..80f966e9c --- /dev/null +++ b/src/arch/arm/insts/mem.hh @@ -0,0 +1,109 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ +#ifndef __ARCH_ARM_MEM_HH__ +#define __ARCH_ARM_MEM_HH__ + +#include "arch/arm/insts/pred_inst.hh" + +namespace ArmISA +{ +/** + * Base class for general Arm memory-format instructions. + */ +class Memory : public PredOp +{ + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Displacement for EA calculation (signed). + int32_t disp; + int32_t disp8; + int32_t up; + int32_t hilo, + shift_size, + shift; + + /// Constructor + Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : PredOp(mnem, _machInst, __opClass), + memAccessFlags(0), + eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), + disp(machInst.immed11_0), + disp8(machInst.immed7_0 << 2), + up(machInst.puswl.up), + hilo((machInst.immedHi11_8 << 4) | machInst.immedLo3_0), + shift_size(machInst.shiftSize), shift(machInst.shift) + { + // When Up is not set, then we must subtract by the displacement + if (!up) + { + disp = -disp; + disp8 = -disp8; + hilo = -hilo; + } + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } +}; + + /** + * Base class for a few miscellaneous memory-format insts + * that don't interpret the disp field + */ +class MemoryNoDisp : public Memory +{ + protected: + /// Constructor + MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; +} + +#endif //__ARCH_ARM_INSTS_MEM_HH__ diff --git a/src/arch/arm/insts/pred_inst.cc b/src/arch/arm/insts/pred_inst.cc new file mode 100644 index 000000000..416815aa8 --- /dev/null +++ b/src/arch/arm/insts/pred_inst.cc @@ -0,0 +1,106 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ + +#include "arch/arm/insts/pred_inst.hh" + +namespace ArmISA +{ +std::string +PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + } + + return ss.str(); +} + +std::string +PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + } + + return ss.str(); +} + +std::string +PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ", "; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ", "; + } + + return ss.str(); +} + +std::string +PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} +} diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh new file mode 100644 index 000000000..65661efdd --- /dev/null +++ b/src/arch/arm/insts/pred_inst.hh @@ -0,0 +1,160 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ +#ifndef __ARCH_ARM_INSTS_PREDINST_HH__ +#define __ARCH_ARM_INSTS_PREDINST_HH__ + +#include "arch/arm/insts/static_inst.hh" +#include "base/trace.hh" + +namespace ArmISA +{ +static inline uint32_t +rotate_imm(uint32_t immValue, int rotateValue) +{ + return ((immValue >> (rotateValue & 31)) | + (immValue << (32 - (rotateValue & 31)))); +} + +/** + * Base class for predicated integer operations. + */ +class PredOp : public ArmStaticInst +{ + protected: + + ConditionCode condCode; + + /// Constructor + PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + ArmStaticInst(mnem, _machInst, __opClass), + condCode((ConditionCode)(unsigned)machInst.condCode) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for predicated immediate operations. + */ +class PredImmOp : public PredOp +{ + protected: + + uint32_t imm; + uint32_t rotate; + uint32_t rotated_imm; + uint32_t rotated_carry; + + /// Constructor + PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + imm(machInst.imm), rotate(machInst.rotate << 1), + rotated_imm(0), rotated_carry(0) + { + rotated_imm = rotate_imm(imm, rotate); + if (rotate != 0) + rotated_carry = (rotated_imm >> 31) & 1; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for predicated integer operations. + */ +class PredIntOp : public PredOp +{ + protected: + + uint32_t shift_size; + uint32_t shift; + + /// Constructor + PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + shift_size(machInst.shiftSize), shift(machInst.shift) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for predicated macro-operations. + */ +class PredMacroOp : public PredOp +{ + protected: + + uint32_t numMicroops; + StaticInstPtr * microOps; + + /// Constructor + PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass), + numMicroops(0) + { + // We rely on the subclasses of this object to handle the + // initialization of the micro-operations, since they are + // all of variable length + flags[IsMacroop] = true; + } + + ~PredMacroOp() + { + if (numMicroops) + delete [] microOps; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC) + { + assert(microPC < numMicroops); + return microOps[microPC]; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for predicated micro-operations. + */ +class PredMicroop : public PredOp +{ + /// Constructor + PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : + PredOp(mnem, _machInst, __opClass) + { + flags[IsMicroop] = true; + } +}; +} + +#endif //__ARCH_ARM_INSTS_PREDINST_HH__ diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc new file mode 100644 index 000000000..ae53199fa --- /dev/null +++ b/src/arch/arm/insts/static_inst.cc @@ -0,0 +1,53 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ + +#include "arch/arm/insts/static_inst.hh" + +namespace ArmISA +{ +void ArmStaticInst::printReg(std::ostream &os, int reg) const +{ + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } + else { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } +} + +std::string ArmStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} +} diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh new file mode 100644 index 000000000..5c88657b8 --- /dev/null +++ b/src/arch/arm/insts/static_inst.hh @@ -0,0 +1,55 @@ +/* Copyright (c) 2007-2008 The Florida State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + */ +#ifndef __ARCH_ARM_INSTS_STATICINST_HH__ +#define __ARCH_ARM_INSTS_STATICINST_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +namespace ArmISA +{ + class ArmStaticInst : public StaticInst + { + protected: + + // Constructor + ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void printReg(std::ostream &os, int reg) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +} + +#endif //__ARCH_ARM_INSTS_STATICINST_HH__ diff --git a/src/arch/arm/isa/base.isa b/src/arch/arm/isa/base.isa deleted file mode 100644 index d492bd3cd..000000000 --- a/src/arch/arm/isa/base.isa +++ /dev/null @@ -1,87 +0,0 @@ -// -*- mode:c++ -*- - -// Copyright (c) 2007-2008 The Florida State University -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer; -// redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution; -// neither the name of the copyright holders nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: Stephen Hines - -//////////////////////////////////////////////////////////////////// -// -// Base class for ARM instructions, and some support functions -// - -//Outputs to decoder.hh -output header {{ - - using namespace ArmISA; - - /** - * Base class for all MIPS static instructions. - */ - class ArmStaticInst : public StaticInst - { - protected: - - // Constructor - ArmStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) - { - } - - /// Print a register name for disassembly given the unique - /// dependence tag number (FP or int). - void printReg(std::ostream &os, int reg) const; - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - -}}; - -//Ouputs to decoder.cc -output decoder {{ - - void ArmStaticInst::printReg(std::ostream &os, int reg) const - { - if (reg < FP_Base_DepTag) { - ccprintf(os, "r%d", reg); - } - else { - ccprintf(os, "f%d", reg - FP_Base_DepTag); - } - } - - std::string ArmStaticInst::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - return ss.str(); - } - -}}; - diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index 3e69c9532..b8fbb982d 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -33,190 +33,6 @@ // Control transfer instructions // -output header {{ - -#include <iostream> - - /** - * Base class for instructions whose disassembly is not purely a - * function of the machine instruction (i.e., it depends on the - * PC). This class overrides the disassemble() method to check - * the PC and symbol table values before re-using a cached - * disassembly string. This is necessary for branches and jumps, - * where the disassembly string includes the target address (which - * may depend on the PC and/or symbol table). - */ - class PCDependentDisassembly : public PredOp - { - protected: - /// Cached program counter from last disassembly - mutable Addr cachedPC; - - /// Cached symbol table pointer from last disassembly - mutable const SymbolTable *cachedSymtab; - - /// Constructor - PCDependentDisassembly(const char *mnem, MachInst _machInst, - OpClass __opClass) - : PredOp(mnem, _machInst, __opClass), - cachedPC(0), cachedSymtab(0) - { - } - - const std::string & - disassemble(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for branches (PC-relative control transfers), - * conditional or unconditional. - */ - class Branch : public PCDependentDisassembly - { - protected: - /// target address (signed) Displacement . - int32_t disp; - - /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(OFFSET << 2) - { - //If Bit 26 is 1 then Sign Extend - if ( (disp & 0x02000000) > 0 ) { - disp |= 0xFC000000; - } - } - - Addr branchTarget(Addr branchPC) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for branch and exchange instructions on the ARM - */ - class BranchExchange : public PredOp - { - protected: - /// Constructor - BranchExchange(const char *mnem, MachInst _machInst, - OpClass __opClass) - : PredOp(mnem, _machInst, __opClass) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - - /** - * Base class for jumps (register-indirect control transfers). In - * the Arm ISA, these are always unconditional. - */ - class Jump : public PCDependentDisassembly - { - protected: - - /// Displacement to target address (signed). - int32_t disp; - - uint32_t target; - - public: - /// Constructor - Jump(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(OFFSET << 2) - { - } - - Addr branchTarget(ThreadContext *tc) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - Addr - Branch::branchTarget(Addr branchPC) const - { - return branchPC + 8 + disp; - } - - Addr - Jump::branchTarget(ThreadContext *tc) const - { - Addr NPC = tc->readPC() + 8; - uint64_t Rb = tc->readIntReg(_srcRegIdx[0]); - return (Rb & ~3) | (NPC & 1); - } - - const std::string & - PCDependentDisassembly::disassemble(Addr pc, - const SymbolTable *symtab) const - { - if (!cachedDisassembly || - pc != cachedPC || symtab != cachedSymtab) - { - if (cachedDisassembly) - delete cachedDisassembly; - - cachedDisassembly = - new std::string(generateDisassembly(pc, symtab)); - cachedPC = pc; - cachedSymtab = symtab; - } - - return *cachedDisassembly; - } - - std::string - Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - Addr target = pc + 8 + disp; - - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; - else - ccprintf(ss, "0x%x", target); - - return ss.str(); - } - - std::string - BranchExchange::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - } - - return ss.str(); - } - - std::string - Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - return ss.str(); - } -}}; - def format Branch(code,*opt_flags) {{ #Build Instruction Flags diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index cdbb14efd..942c444fd 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -33,331 +33,228 @@ // Macro Memory-format instructions // -output header {{ - - /** - * Arm Macro Memory operations like LDM/STM - */ - class ArmMacroMemoryOp : public PredMacroOp - { - protected: - /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; - - uint32_t reglist; - uint32_t ones; - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; - - ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : PredMacroOp(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), - reglist(REGLIST), ones(0), puswl(PUSWL), prepost(PREPOST), up(UP), - psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP) - { - ones = number_of_ones(reglist); - numMicroops = ones + writeback + 1; - // Remember that writeback adds a uop - microOps = new StaticInstPtr[numMicroops]; - } - }; - - /** - * Arm Macro FPA operations to fix ldfd and stfd instructions - */ - class ArmMacroFPAOp : public PredMacroOp - { - protected: - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; - int32_t disp8; - - ArmMacroFPAOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - puswl(PUSWL), prepost(PREPOST), up(UP), - psruser(PSRUSER), writeback(WRITEBACK), loadop(LOADOP), - disp8(IMMED_7_0 << 2) - { - numMicroops = 3 + writeback; - microOps = new StaticInstPtr[numMicroops]; - } - }; - - /** - * Arm Macro FM operations to fix lfm and sfm - */ - class ArmMacroFMOp : public PredMacroOp - { - protected: - uint32_t punwl, - prepost, - up, - n1bit, - writeback, - loadop, - n0bit, - count; - int32_t disp8; - - ArmMacroFMOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - punwl(PUNWL), prepost(PREPOST), up(UP), - n1bit(OPCODE_22), writeback(WRITEBACK), loadop(LOADOP), - n0bit(OPCODE_15), disp8(IMMED_7_0 << 2) - { - // Transfer 1-4 registers based on n1 and n0 bits (with 00 repr. 4) - count = (n1bit << 1) | n0bit; - if (count == 0) - count = 4; - numMicroops = (3*count) + writeback; - microOps = new StaticInstPtr[numMicroops]; - } - }; - - -}}; - - -output decoder {{ -}}; - def template MacroStoreDeclare {{ - /** - * Static instructions class for a store multiple instruction - */ - class %(class_name)s : public %(base_class)s - { - public: - // Constructor - %(class_name)s(ExtMachInst machInst); - %(BasicExecDeclare)s - }; +/** + * Static instructions class for a store multiple instruction + */ +class %(class_name)s : public %(base_class)s +{ + public: + // Constructor + %(class_name)s(ExtMachInst machInst); + %(BasicExecDeclare)s +}; }}; def template MacroStoreConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) +inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) +{ + %(constructor)s; + uint32_t regs_to_handle = reglist; + uint32_t j = 0, + start_addr = 0, + end_addr = 0; + + switch (puswl) { - %(constructor)s; - uint32_t regs_to_handle = reglist; - uint32_t j = 0, - start_addr = 0, - end_addr = 0; + case 0x01: // L ldmda_l + start_addr = (ones << 2) - 4; + end_addr = 0; + break; + case 0x03: // WL ldmda_wl + start_addr = (ones << 2) - 4; + end_addr = 0; + break; + case 0x08: // U stmia_u + start_addr = 0; + end_addr = (ones << 2) - 4; + break; + case 0x09: // U L ldmia_ul + start_addr = 0; + end_addr = (ones << 2) - 4; + break; + case 0x0b: // U WL ldmia + start_addr = 0; + end_addr = (ones << 2) - 4; + break; + case 0x11: // P L ldmdb + start_addr = (ones << 2); // U-bit is already 0 for subtract + end_addr = 4; // negative 4 + break; + case 0x12: // P W stmdb + start_addr = (ones << 2); // U-bit is already 0 for subtract + end_addr = 4; // negative 4 + break; + case 0x18: // PU stmib + start_addr = 4; + end_addr = (ones << 2) + 4; + break; + case 0x19: // PU L ldmib + start_addr = 4; + end_addr = (ones << 2) + 4; + break; + default: + panic("Unhandled Load/Store Multiple Instruction"); + break; + } - switch (puswl) - { - case 0x01: // L ldmda_l - start_addr = (ones << 2) - 4; - end_addr = 0; - break; - case 0x03: // WL ldmda_wl - start_addr = (ones << 2) - 4; - end_addr = 0; - break; - case 0x08: // U stmia_u - start_addr = 0; - end_addr = (ones << 2) - 4; - break; - case 0x09: // U L ldmia_ul - start_addr = 0; - end_addr = (ones << 2) - 4; - break; - case 0x0b: // U WL ldmia - start_addr = 0; - end_addr = (ones << 2) - 4; - break; - case 0x11: // P L ldmdb - start_addr = (ones << 2); // U-bit is already 0 for subtract - end_addr = 4; // negative 4 - break; - case 0x12: // P W stmdb - start_addr = (ones << 2); // U-bit is already 0 for subtract - end_addr = 4; // negative 4 - break; - case 0x18: // PU stmib - start_addr = 4; - end_addr = (ones << 2) + 4; - break; - case 0x19: // PU L ldmib - start_addr = 4; - end_addr = (ones << 2) + 4; - break; - default: - panic("Unhandled Load/Store Multiple Instruction"); - break; - } + //TODO - Add addi_uop/subi_uop here to create starting addresses + //Just using addi with 0 offset makes a "copy" of Rn for our use + uint32_t newMachInst = 0; + newMachInst = machInst & 0xffff0000; + microOps[0] = new Addi_uop(newMachInst); - //TODO - Add addi_uop/subi_uop here to create starting addresses - //Just using addi with 0 offset makes a "copy" of Rn for our use - uint32_t newMachInst = 0; - newMachInst = machInst & 0xffff0000; - microOps[0] = new Addi_uop(newMachInst); + for (int i = 1; i < ones+1; i++) + { + // Get next available bit for transfer + while (! ( regs_to_handle & (1<<j))) + j++; + regs_to_handle &= ~(1<<j); - for (int i = 1; i < ones+1; i++) - { - // Get next available bit for transfer - while (! ( regs_to_handle & (1<<j))) - j++; - regs_to_handle &= ~(1<<j); + microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); - microOps[i] = gen_ldrstr_uop(machInst, loadop, j, start_addr); + if (up) + start_addr += 4; + else + start_addr -= 4; + } - if (up) - start_addr += 4; - else - start_addr -= 4; - } + /* TODO: Take a look at how these 2 values should meet together + if (start_addr != (end_addr - 4)) + { + fprintf(stderr, "start_addr: %d\n", start_addr); + fprintf(stderr, "end_addr: %d\n", end_addr); + panic("start_addr does not meet end_addr"); + } + */ - /* TODO: Take a look at how these 2 values should meet together - if (start_addr != (end_addr - 4)) + if (writeback) + { + uint32_t newMachInst = machInst & 0xf0000000; + uint32_t rn = (machInst >> 16) & 0x0f; + // 3322 2222 2222 1111 1111 11 + // 1098 7654 3210 9876 5432 1098 7654 3210 + // COND 0010 0100 [RN] [RD] 0000 [ IMM ] + // sub rn, rn, imm + newMachInst |= 0x02400000; + newMachInst |= ((rn << 16) | (rn << 12)); + newMachInst |= (ones << 2); + if (up) { - fprintf(stderr, "start_addr: %d\n", start_addr); - fprintf(stderr, "end_addr: %d\n", end_addr); - panic("start_addr does not meet end_addr"); + microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); } - */ - - if (writeback) + else { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - newMachInst |= (ones << 2); - if (up) - { - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); - } + microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); } - microOps[numMicroops-1]->setLastMicroop(); } + microOps[numMicroops-1]->setLastMicroop(); +} }}; def template MacroStoreExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const +Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const +{ + Fault fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + if (fault == NoFault) { - Fault fault = NoFault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - if (fault == NoFault) - { - %(op_wb)s; - } - - return fault; + %(op_wb)s; } + + return fault; +} }}; def template MacroFPAConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) - { - %(constructor)s; +inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) +{ + %(constructor)s; - uint32_t start_addr = 0; + uint32_t start_addr = 0; - if (prepost) - start_addr = disp8; - else - start_addr = 0; + if (prepost) + start_addr = disp8; + else + start_addr = 0; - emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr); + emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr); - if (writeback) + if (writeback) + { + uint32_t newMachInst = machInst & 0xf0000000; + uint32_t rn = (machInst >> 16) & 0x0f; + // 3322 2222 2222 1111 1111 11 + // 1098 7654 3210 9876 5432 1098 7654 3210 + // COND 0010 0100 [RN] [RD] 0000 [ IMM ] + // sub rn, rn, imm + newMachInst |= 0x02400000; + newMachInst |= ((rn << 16) | (rn << 12)); + if (up) { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - if (up) - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); - } + newMachInst |= disp8; + microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); + } + else + { + newMachInst |= disp8; + microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); } - microOps[numMicroops-1]->setLastMicroop(); } + microOps[numMicroops-1]->setLastMicroop(); +} }}; def template MacroFMConstructor {{ - inline %(class_name)s::%(class_name)s(ExtMachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) - { - %(constructor)s; +inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) +{ + %(constructor)s; - uint32_t start_addr = 0; + uint32_t start_addr = 0; - if (prepost) - start_addr = disp8; - else - start_addr = 0; + if (prepost) + start_addr = disp8; + else + start_addr = 0; + + for (int i = 0; i < count; i++) + { + emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); + } - for (int i = 0; i < count; i++) + if (writeback) + { + uint32_t newMachInst = machInst & 0xf0000000; + uint32_t rn = (machInst >> 16) & 0x0f; + // 3322 2222 2222 1111 1111 11 + // 1098 7654 3210 9876 5432 1098 7654 3210 + // COND 0010 0100 [RN] [RD] 0000 [ IMM ] + // sub rn, rn, imm + newMachInst |= 0x02400000; + newMachInst |= ((rn << 16) | (rn << 12)); + if (up) { - emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr); + newMachInst |= disp8; + microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); } - - if (writeback) + else { - uint32_t newMachInst = machInst & 0xf0000000; - uint32_t rn = (machInst >> 16) & 0x0f; - // 3322 2222 2222 1111 1111 11 - // 1098 7654 3210 9876 5432 1098 7654 3210 - // COND 0010 0100 [RN] [RD] 0000 [ IMM ] - // sub rn, rn, imm - newMachInst |= 0x02400000; - newMachInst |= ((rn << 16) | (rn << 12)); - if (up) - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Addi_rd_uop(newMachInst); - } - else - { - newMachInst |= disp8; - microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); - } + newMachInst |= disp8; + microOps[numMicroops-1] = new Subi_rd_uop(newMachInst); } - microOps[numMicroops-1]->setLastMicroop(); } - + microOps[numMicroops-1]->setLastMicroop(); +} }}; @@ -390,6 +287,3 @@ def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{ decode_block = BasicDecode.subst(iop) exec_output = PredOpExecute.subst(iop) }}; - - - diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa index 47381add6..c8ac19c61 100644 --- a/src/arch/arm/isa/formats/mem.isa +++ b/src/arch/arm/isa/formats/mem.isa @@ -33,92 +33,6 @@ // Memory-format instructions // -output header {{ - /** - * Base class for general Arm memory-format instructions. - */ - class Memory : public PredOp - { - protected: - - /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; - - /// Displacement for EA calculation (signed). - int32_t disp; - int32_t disp8; - int32_t up; - int32_t hilo, - shift_size, - shift; - - /// Constructor - Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : PredOp(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), - disp(IMMED_11_0), disp8(IMMED_7_0 << 2), up(UP), - hilo((IMMED_HI_11_8 << 4) | IMMED_LO_3_0), - shift_size(SHIFT_SIZE), shift(SHIFT) - { - // When Up is not set, then we must subtract by the displacement - if (!up) - { - disp = -disp; - disp8 = -disp8; - hilo = -hilo; - } - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - - public: - - const StaticInstPtr &eaCompInst() const { return eaCompPtr; } - const StaticInstPtr &memAccInst() const { return memAccPtr; } - }; - - /** - * Base class for a few miscellaneous memory-format insts - * that don't interpret the disp field - */ - class MemoryNoDisp : public Memory - { - protected: - /// Constructor - MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - - -output decoder {{ - std::string - Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s", mnemonic); - } - - std::string - MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s", mnemonic); - } -}}; - def template LoadStoreDeclare {{ /** * Static instruction class for "%(mnemonic)s". diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index 019e46457..1748a09ea 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -33,134 +33,6 @@ // Predicated Instruction Execution // -output header {{ -#include <iostream> - - inline uint32_t - rotate_imm(uint32_t immValue, int rotateValue) - { - return ((immValue >> (rotateValue & 31)) | - (immValue << (32 - (rotateValue & 31)))); - } - - /** - * Base class for predicated integer operations. - */ - class PredOp : public ArmStaticInst - { - protected: - - ArmISA::ConditionCode condCode; - - /// Constructor - PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - ArmStaticInst(mnem, _machInst, __opClass), - condCode((ArmISA::ConditionCode)(unsigned)COND_CODE) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for predicated immediate operations. - */ - class PredImmOp : public PredOp - { - protected: - - uint32_t imm; - uint32_t rotate; - uint32_t rotated_imm; - uint32_t rotated_carry; - - /// Constructor - PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - imm(IMM), rotate(ROTATE << 1), rotated_imm(0), - rotated_carry(0) - { - rotated_imm = rotate_imm(imm, rotate); - if (rotate != 0) - rotated_carry = (rotated_imm >> 31) & 1; - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for predicated integer operations. - */ - class PredIntOp : public PredOp - { - protected: - - uint32_t shift_size; - uint32_t shift; - - /// Constructor - PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - shift_size(SHIFT_SIZE), shift(SHIFT) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for predicated macro-operations. - */ - class PredMacroOp : public PredOp - { - protected: - - uint32_t numMicroops; - StaticInstPtr * microOps; - - /// Constructor - PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass), - numMicroops(0) - { - // We rely on the subclasses of this object to handle the - // initialization of the micro-operations, since they are - // all of variable length - flags[IsMacroop] = true; - } - - ~PredMacroOp() - { - if (numMicroops) - delete [] microOps; - } - - StaticInstPtr fetchMicroop(MicroPC microPC) - { - assert(microPC < numMicroops); - return microOps[microPC]; - } - - %(BasicExecPanic)s - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for predicated micro-operations. - */ - class PredMicroop : public PredOp - { - /// Constructor - PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : - PredOp(mnem, _machInst, __opClass) - { - flags[IsMicroop] = true; - } - }; - -}}; - let {{ predicateTest = 'testPredicate(Cpsr, condCode)' }}; @@ -185,79 +57,6 @@ def template PredOpExecute {{ } }}; -//Outputs to decoder.cc -output decoder {{ - std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - - return ss.str(); - } - - std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - - return ss.str(); - } - - std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - - return ss.str(); - } - - std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - return ss.str(); - } - -}}; - let {{ calcCcCode = ''' diff --git a/src/arch/arm/isa/includes.isa b/src/arch/arm/isa/includes.isa index 6205a8f81..7d5eb4850 100644 --- a/src/arch/arm/isa/includes.isa +++ b/src/arch/arm/isa/includes.isa @@ -38,6 +38,11 @@ output header {{ #include <iostream> #include <iomanip> +#include "arch/arm/insts/branch.hh" +#include "arch/arm/insts/macromem.hh" +#include "arch/arm/insts/mem.hh" +#include "arch/arm/insts/pred_inst.hh" +#include "arch/arm/insts/static_inst.hh" #include "arch/arm/isa_traits.hh" #include "cpu/static_inst.hh" #include "mem/packet.hh" diff --git a/src/arch/arm/isa/main.isa b/src/arch/arm/isa/main.isa index aeb8b69d0..47e6c11dc 100644 --- a/src/arch/arm/isa/main.isa +++ b/src/arch/arm/isa/main.isa @@ -53,9 +53,6 @@ namespace ArmISA; //Include the operand_types and operand definitions ##include "operands.isa" -//Include the base class for Arm instructions, and some support code -##include "base.isa" - //Include the definitions for the instruction formats ##include "formats/formats.isa" diff --git a/src/arch/arm/isa/util.isa b/src/arch/arm/isa/util.isa index 20eb80ecf..b36206d2a 100644 --- a/src/arch/arm/isa/util.isa +++ b/src/arch/arm/isa/util.isa @@ -46,17 +46,6 @@ output header {{ enum ArmShiftMode { }; - inline uint32_t number_of_ones(int32_t val) - { - uint32_t ones = 0; - for (int i = 0; i < 32; i++ ) - { - if ( val & (1<<i) ) - ones++; - } - return ones; - } - }}; output exec {{ |