ARM: Simplify the ISA desc by pulling some classes out of it.

This commit is contained in:
Gabe Black 2009-06-21 17:21:25 -07:00
parent 2a39570b78
commit d4a03f1900
18 changed files with 1140 additions and 873 deletions

View file

@ -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')

View file

@ -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();
}
}

View file

@ -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__

View file

@ -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__

46
src/arch/arm/insts/mem.cc Normal file
View file

@ -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);
}
}

109
src/arch/arm/insts/mem.hh Normal file
View file

@ -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__

View file

@ -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();
}
}

View file

@ -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__

View file

@ -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();
}
}

View file

@ -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__

View file

@ -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();
}
}};

View file

@ -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

View file

@ -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;
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);
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);
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");
}
*/
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)
{
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
}
else
{
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
}
}
microOps[numMicroops-1]->setLastMicroop();
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);
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);
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");
}
*/
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)
{
microOps[numMicroops-1] = new Addi_rd_uop(newMachInst);
}
else
{
microOps[numMicroops-1] = new Subi_rd_uop(newMachInst);
}
}
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)
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;
if (prepost)
start_addr = disp8;
else
start_addr = 0;
emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
if (writeback)
{
%(constructor)s;
uint32_t start_addr = 0;
if (prepost)
start_addr = disp8;
else
start_addr = 0;
emit_ldfstf_uops(microOps, 0, machInst, loadop, up, start_addr);
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)
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;
if (prepost)
start_addr = disp8;
else
start_addr = 0;
for (int i = 0; i < count; i++)
{
%(constructor)s;
uint32_t 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);
}
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)
{
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();
emit_ldfstf_uops(microOps, 3*i, machInst, loadop, up, start_addr);
}
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)
{
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();
}
}};
@ -390,6 +287,3 @@ def format ArmMacroFMOp(code, mem_flags = [], inst_flag = [], *opt_flags) {{
decode_block = BasicDecode.subst(iop)
exec_output = PredOpExecute.subst(iop)
}};

View file

@ -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".

View file

@ -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 = '''

View file

@ -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"

View file

@ -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"

View file

@ -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 {{