summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/templates/mem.isa
diff options
context:
space:
mode:
authorGene WU <gene.wu@arm.com>2010-08-25 19:10:42 -0500
committerGene WU <gene.wu@arm.com>2010-08-25 19:10:42 -0500
commit4d8f4db8d135a23ceb5d54d3096e0598dd31e2fe (patch)
treedfc8029938e5580810c2a6b5cede6e72cf6f0524 /src/arch/arm/isa/templates/mem.isa
parentc2d5d2b53d1d3bfb83ce0cf0332f81c4ffea112f (diff)
downloadgem5-4d8f4db8d135a23ceb5d54d3096e0598dd31e2fe.tar.xz
ARM: Use fewer micro-ops for register update loads if possible.
Allow some loads that update the base register to use just two micro-ops. three micro-ops are only used if the destination register matches the offset register or the PC is the destination regsiter. If the PC is updated it needs to be the last micro-op otherwise O3 will mispredict.
Diffstat (limited to 'src/arch/arm/isa/templates/mem.isa')
-rw-r--r--src/arch/arm/isa/templates/mem.isa296
1 files changed, 279 insertions, 17 deletions
diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa
index 686a8b0aa..1d0e1316c 100644
--- a/src/arch/arm/isa/templates/mem.isa
+++ b/src/arch/arm/isa/templates/mem.isa
@@ -41,6 +41,35 @@
// Authors: Stephen Hines
+def template PanicExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("Execute function executed when it shouldn't be!\n");
+ return NoFault;
+ }
+}};
+
+def template PanicInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("InitiateAcc function executed when it shouldn't be!\n");
+ return NoFault;
+ }
+}};
+
+def template PanicCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("CompleteAcc function executed when it shouldn't be!\n");
+ return NoFault;
+ }
+}};
+
+
def template SwapExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
@@ -73,7 +102,8 @@ def template SwapExecute {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -109,7 +139,8 @@ def template SwapInitiateAcc {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -172,7 +203,8 @@ def template LoadExecute {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -208,7 +240,8 @@ def template NeonLoadExecute {{
}
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -245,7 +278,8 @@ def template StoreExecute {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -285,7 +319,8 @@ def template NeonStoreExecute {{
}
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -328,7 +363,8 @@ def template StoreExExecute {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -365,8 +401,8 @@ def template StoreExInitiateAcc {{
} else {
xc->setPredicate(false);
}
-
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -404,7 +440,8 @@ def template StoreInitiateAcc {{
xc->setPredicate(false);
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -443,7 +480,8 @@ def template NeonStoreInitiateAcc {{
}
}
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -469,7 +507,8 @@ def template LoadInitiateAcc {{
}
} else {
xc->setPredicate(false);
- if (fault == NoFault && machInst.itstateMask != 0) {
+ if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
}
@@ -495,7 +534,8 @@ def template NeonLoadInitiateAcc {{
if (fault == NoFault) {
fault = xc->readBytes(EA, NULL, %(size)d, memAccessFlags);
}
- } else if (fault == NoFault && machInst.itstateMask != 0) {
+ } else if (fault == NoFault && machInst.itstateMask != 0 &&
+ (!isMicroop() || isLastMicroop())) {
xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
}
@@ -791,7 +831,7 @@ def template StoreExImmDeclare {{
};
}};
-def template LoadStoreDRegDeclare {{
+def template StoreDRegDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
@@ -814,7 +854,7 @@ def template LoadStoreDRegDeclare {{
};
}};
-def template LoadStoreRegDeclare {{
+def template StoreRegDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
@@ -836,6 +876,71 @@ def template LoadStoreRegDeclare {{
};
}};
+def template LoadDRegDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _dest2,
+ uint32_t _base, bool _add,
+ int32_t _shiftAmt, uint32_t _shiftType,
+ uint32_t _index);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+def template LoadRegDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _base, bool _add,
+ int32_t _shiftAmt, uint32_t _shiftType,
+ uint32_t _index);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+def template LoadImmDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _base, bool _add, int32_t _imm);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
def template InitiateAccDeclare {{
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
@@ -851,6 +956,13 @@ def template RfeConstructor {{
(IntRegIndex)_base, (AddrMode)_mode, _wb)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
@@ -861,6 +973,13 @@ def template SrsConstructor {{
(OperatingMode)_regMode, (AddrMode)_mode, _wb)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
@@ -883,6 +1002,13 @@ def template LoadStoreDImmConstructor {{
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
@@ -896,6 +1022,14 @@ def template StoreExDImmConstructor {{
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2,
+ _base, _add, _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
@@ -906,6 +1040,13 @@ def template LoadStoreImmConstructor {{
(IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
@@ -918,10 +1059,18 @@ def template StoreExImmConstructor {{
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _result, _dest,
+ _base, _add, _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
-def template LoadStoreDRegConstructor {{
+def template StoreDRegConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
@@ -932,10 +1081,18 @@ def template LoadStoreDRegConstructor {{
(IntRegIndex)_index)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
-def template LoadStoreRegConstructor {{
+def template StoreRegConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _dest, uint32_t _base, bool _add,
int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
@@ -945,5 +1102,110 @@ def template LoadStoreRegConstructor {{
(IntRegIndex)_index)
{
%(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+#endif
}
}};
+
+def template LoadDRegConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add,
+ int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ (IntRegIndex)_dest, (IntRegIndex)_dest2,
+ (IntRegIndex)_base, _add,
+ _shiftAmt, (ArmShiftType)_shiftType,
+ (IntRegIndex)_index)
+ {
+ %(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ if ((_dest == _index) || (_dest2 == _index)) {
+ IntRegIndex wbIndexReg = INTREG_UREG0;
+ uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
+ uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[2] = new %(wb_decl)s;
+ uops[2]->setLastMicroop();
+ } else {
+ IntRegIndex wbIndexReg = index;
+ uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+ }
+#endif
+ }
+}};
+
+def template LoadRegConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _base, bool _add,
+ int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ (IntRegIndex)_dest, (IntRegIndex)_base, _add,
+ _shiftAmt, (ArmShiftType)_shiftType,
+ (IntRegIndex)_index)
+ {
+ %(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ if (_dest == INTREG_PC) {
+ IntRegIndex wbIndexReg = index;
+ uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[1] = new %(wb_decl)s;
+ uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
+ uops[2]->setLastMicroop();
+ } else if(_dest == _index) {
+ IntRegIndex wbIndexReg = INTREG_UREG0;
+ uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
+ uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[2] = new %(wb_decl)s;
+ uops[2]->setLastMicroop();
+ } else {
+ IntRegIndex wbIndexReg = index;
+ uops[0] = new %(acc_name)s(machInst, _dest, _base, _add,
+ _shiftAmt, _shiftType, _index);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+
+ }
+#endif
+ }
+}};
+
+def template LoadImmConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
+ uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm)
+ {
+ %(constructor)s;
+#if %(use_uops)d
+ assert(numMicroops >= 2);
+ uops = new StaticInstPtr[numMicroops];
+ if (_dest == INTREG_PC) {
+ uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add,
+ _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
+ uops[2]->setLastMicroop();
+ } else {
+ uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
+ uops[1] = new %(wb_decl)s;
+ uops[1]->setLastMicroop();
+ }
+#endif
+ }
+}};
+