From 031f396c71e750fede19651ba3a14e262a87e117 Mon Sep 17 00:00:00 2001 From: Matt Horsnell Date: Thu, 17 Mar 2011 19:20:19 -0500 Subject: ARM: Fix RFE macrop. This changes the RFE macroop into 3 microops: URa = [sp]; URb = [sp+4]; // load CPSR,PC values from stack sp = sp + offset; // optionally auto-increment PC = URa; CPSR = URb; // write to the PC and CPSR. Importantly: - writing to PC is handled in the last micro-op. - loading occurs prior to state changes. --- src/arch/arm/isa/templates/macromem.isa | 35 +++++++++++++++++++++++++++++++++ src/arch/arm/isa/templates/mem.isa | 24 +++++++++++++--------- 2 files changed, 50 insertions(+), 9 deletions(-) (limited to 'src/arch/arm/isa/templates') diff --git a/src/arch/arm/isa/templates/macromem.isa b/src/arch/arm/isa/templates/macromem.isa index b7ca7fa48..a7f7f0da8 100644 --- a/src/arch/arm/isa/templates/macromem.isa +++ b/src/arch/arm/isa/templates/macromem.isa @@ -107,6 +107,41 @@ def template MicroNeonMemDeclare {{ }; }}; +//////////////////////////////////////////////////////////////////// +// +// PC = Integer(ura) +// CPSR = Integer(urb) +// + +def template MicroSetPCCPSRDeclare {{ + class %(class_name)s : public %(base_class)s + { + public: + %(class_name)s(ExtMachInst machInst, + IntRegIndex _ura, + IntRegIndex _urb, + IntRegIndex _urc); + %(BasicExecDeclare)s + }; +}}; + +def template MicroSetPCCPSRConstructor {{ + %(class_name)s::%(class_name)s(ExtMachInst machInst, + IntRegIndex _ura, + IntRegIndex _urb, + IntRegIndex _urc) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + _ura, _urb, _urc) + { + %(constructor)s; + if (!(condCode == COND_AL || condCode == COND_UC)) { + for (int x = 0; x < _numDestRegs; x++) { + _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; + } + } + } +}}; + //////////////////////////////////////////////////////////////////// // // Integer = Integer op Integer microops diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index 3d073b322..dcfd47ace 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -917,9 +917,9 @@ def template CompleteAccDeclare {{ def template RfeConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst, - uint32_t _base, int _mode, bool _wb) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, - (IntRegIndex)_base, (AddrMode)_mode, _wb) + uint32_t _base, int _mode, bool _wb) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + (IntRegIndex)_base, (AddrMode)_mode, _wb) { %(constructor)s; if (!(condCode == COND_AL || condCode == COND_UC)) { @@ -928,12 +928,18 @@ def template RfeConstructor {{ } } #if %(use_uops)d - assert(numMicroops >= 2); - uops = new StaticInstPtr[numMicroops]; - uops[0] = new %(acc_name)s(machInst, _base, _mode, _wb); - uops[0]->setDelayedCommit(); - uops[1] = new %(wb_decl)s; - uops[1]->setLastMicroop(); + uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d]; + int uopIdx = 0; + uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb); + uops[uopIdx]->setDelayedCommit(); +#if %(use_wb)d + uops[++uopIdx] = new %(wb_decl)s; + uops[uopIdx]->setDelayedCommit(); +#endif +#if %(use_pc)d + uops[++uopIdx] = new %(pc_decl)s; +#endif + uops[uopIdx]->setLastMicroop(); #endif } }}; -- cgit v1.2.3