summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:01 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:01 -0500
commit321d3a6e8c9ed9511f7944c8ad8dbd16508cb5ad (patch)
treebee1da6554b4396837070b89cbc7241fb8dda628
parent8933857af75c2419bb41cbd92e7190fd91cc8837 (diff)
downloadgem5-321d3a6e8c9ed9511f7944c8ad8dbd16508cb5ad.tar.xz
ARM: Implement a new set of base classes for non macro memory instructions.
-rw-r--r--src/arch/arm/insts/mem.cc38
-rw-r--r--src/arch/arm/insts/mem.hh199
2 files changed, 235 insertions, 2 deletions
diff --git a/src/arch/arm/insts/mem.cc b/src/arch/arm/insts/mem.cc
index afbf05e44..f62786979 100644
--- a/src/arch/arm/insts/mem.cc
+++ b/src/arch/arm/insts/mem.cc
@@ -1,4 +1,17 @@
-/* Copyright (c) 2007-2008 The Florida State University
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +45,28 @@
namespace ArmISA
{
+
+void
+MemoryNew::printInst(std::ostream &os, AddrMode addrMode) const
+{
+ printMnemonic(os);
+ printReg(os, dest);
+ os << ", [";
+ printReg(os, base);
+ if (addrMode != AddrMd_PostIndex) {
+ os << ", ";
+ printOffset(os);
+ os << "]";
+ if (addrMode == AddrMd_PreIndex) {
+ os << "!";
+ }
+ } else {
+ os << "] ";
+ printOffset(os);
+
+ }
+}
+
std::string
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
@@ -50,4 +85,5 @@ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
ss << "!";
return ss.str();
}
+
}
diff --git a/src/arch/arm/insts/mem.hh b/src/arch/arm/insts/mem.hh
index bf0aa1c92..3c7a50505 100644
--- a/src/arch/arm/insts/mem.hh
+++ b/src/arch/arm/insts/mem.hh
@@ -1,4 +1,17 @@
-/* Copyright (c) 2007-2008 The Florida State University
+/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,6 +46,190 @@
namespace ArmISA
{
+
+class MemoryNew : public PredOp
+{
+ public:
+ enum AddrMode {
+ AddrMd_Offset,
+ AddrMd_PreIndex,
+ AddrMd_PostIndex
+ };
+
+ protected:
+
+ IntRegIndex dest;
+ IntRegIndex base;
+ bool add;
+
+ MemoryNew(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _dest, IntRegIndex _base, bool _add)
+ : PredOp(mnem, _machInst, __opClass),
+ dest(_dest), base(_base), add(_add)
+ {}
+
+ virtual void
+ printOffset(std::ostream &os) const
+ {}
+
+ void printInst(std::ostream &os, AddrMode addrMode) const;
+};
+
+// The address is a base register plus an immediate.
+class MemoryNewImm : public MemoryNew
+{
+ protected:
+ int32_t imm;
+
+ MemoryNewImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
+ : MemoryNew(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
+ {}
+
+ void
+ printOffset(std::ostream &os) const
+ {
+ int32_t pImm = imm;
+ if (!add)
+ pImm = -pImm;
+ ccprintf(os, "#%d", pImm);
+ }
+};
+
+// The address is a shifted register plus an immediate
+class MemoryNewReg : public MemoryNew
+{
+ protected:
+ int32_t shiftAmt;
+ ArmShiftType shiftType;
+ IntRegIndex index;
+
+ MemoryNewReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ IntRegIndex _dest, IntRegIndex _base, bool _add,
+ int32_t _shiftAmt, ArmShiftType _shiftType,
+ IntRegIndex _index)
+ : MemoryNew(mnem, _machInst, __opClass, _dest, _base, _add),
+ shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
+ {}
+
+ void
+ printOffset(std::ostream &os) const
+ {
+ if (!add)
+ os << "-";
+ printReg(os, index);
+ if (shiftType != LSL || shiftAmt != 0) {
+ switch (shiftType) {
+ case LSL:
+ ccprintf(os, " LSL #%d", shiftAmt);
+ break;
+ case LSR:
+ if (shiftAmt == 0) {
+ ccprintf(os, " LSR #%d", 32);
+ } else {
+ ccprintf(os, " LSR #%d", shiftAmt);
+ }
+ break;
+ case ASR:
+ if (shiftAmt == 0) {
+ ccprintf(os, " ASR #%d", 32);
+ } else {
+ ccprintf(os, " ASR #%d", shiftAmt);
+ }
+ break;
+ case ROR:
+ if (shiftAmt == 0) {
+ ccprintf(os, " RRX");
+ } else {
+ ccprintf(os, " ROR #%d", shiftAmt);
+ }
+ break;
+ }
+ }
+ }
+};
+
+template<class Base>
+class MemoryNewOffset : public Base
+{
+ protected:
+ MemoryNewOffset(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
+ {}
+
+ MemoryNewOffset(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
+ IntRegIndex _index)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index)
+ {}
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ this->printInst(ss, MemoryNew::AddrMd_Offset);
+ return ss.str();
+ }
+};
+
+template<class Base>
+class MemoryNewPreIndex : public Base
+{
+ protected:
+ MemoryNewPreIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
+ {}
+
+ MemoryNewPreIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
+ IntRegIndex _index)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index)
+ {}
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ this->printInst(ss, MemoryNew::AddrMd_PreIndex);
+ return ss.str();
+ }
+};
+
+template<class Base>
+class MemoryNewPostIndex : public Base
+{
+ protected:
+ MemoryNewPostIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _imm)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
+ {}
+
+ MemoryNewPostIndex(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
+ IntRegIndex _index)
+ : Base(mnem, _machInst, __opClass, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index)
+ {}
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ this->printInst(ss, MemoryNew::AddrMd_PostIndex);
+ return ss.str();
+ }
+};
+
/**
* Base class for general Arm memory-format instructions.
*/