ARM: Simplify the ISA desc by pulling some classes out of it.
This commit is contained in:
parent
2a39570b78
commit
d4a03f1900
18 changed files with 1140 additions and 873 deletions
|
@ -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')
|
||||
|
|
109
src/arch/arm/insts/branch.cc
Normal file
109
src/arch/arm/insts/branch.cc
Normal 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();
|
||||
}
|
||||
}
|
139
src/arch/arm/insts/branch.hh
Normal file
139
src/arch/arm/insts/branch.hh
Normal 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__
|
159
src/arch/arm/insts/macromem.hh
Normal file
159
src/arch/arm/insts/macromem.hh
Normal 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
46
src/arch/arm/insts/mem.cc
Normal 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
109
src/arch/arm/insts/mem.hh
Normal 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__
|
106
src/arch/arm/insts/pred_inst.cc
Normal file
106
src/arch/arm/insts/pred_inst.cc
Normal 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();
|
||||
}
|
||||
}
|
160
src/arch/arm/insts/pred_inst.hh
Normal file
160
src/arch/arm/insts/pred_inst.hh
Normal 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__
|
53
src/arch/arm/insts/static_inst.cc
Normal file
53
src/arch/arm/insts/static_inst.cc
Normal 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();
|
||||
}
|
||||
}
|
55
src/arch/arm/insts/static_inst.hh
Normal file
55
src/arch/arm/insts/static_inst.hh
Normal 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__
|
|
@ -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();
|
||||
}
|
||||
|
||||
}};
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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 = '''
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 {{
|
||||
|
|
Loading…
Reference in a new issue