# 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')
--- /dev/null
+/* 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();
+}
+}
--- /dev/null
+/* 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__
--- /dev/null
+/* 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__
--- /dev/null
+/* 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);
+}
+}
--- /dev/null
+/* 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__
--- /dev/null
+/* 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();
+}
+}
--- /dev/null
+/* 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__
--- /dev/null
+/* 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();
+}
+}
--- /dev/null
+/* 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__
+++ /dev/null
-// -*- 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();
- }
-
-}};
-
// 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
// 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();
+}
}};
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};
-
-
-
// 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".
// 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)'
}};
}
}};
-//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 = '''
#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"
//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"
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 {{