gem5/src/arch/arm/insts/macromem.hh

160 lines
5.3 KiB
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
*/
#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__