gem5/src/arch/arm/isa/templates/mem.isa
Gabe Black 3a1428365a ExecContext: Rename the readBytes/writeBytes functions to readMem and writeMem.
readBytes and writeBytes had the word "bytes" in their names because they
accessed blobs of bytes. This distinguished them from the read and write
functions which handled higher level data types. Because those functions don't
exist any more, this change renames readBytes and writeBytes to more general
names, readMem and writeMem, which reflect the fact that they are how you read
and write memory. This also makes their names more consistent with the
register reading/writing functions, although those are still read and set for
some reason.
2011-07-02 22:35:04 -07:00

1205 lines
34 KiB
C++

// -*- mode:c++ -*-
// 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
// 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
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
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
uint64_t memData = 0;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
%(preacc_code)s;
if (fault == NoFault) {
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
&memData);
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template SwapInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
uint64_t memData = 0;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
%(preacc_code)s;
if (fault == NoFault) {
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
&memData);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template SwapCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (%(predicate_test)s)
{
// ARM instructions will not have a pkt if the predicate is false
getMem(pkt, Mem, traceData);
uint64_t memData = Mem;
%(postacc_code)s;
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template LoadExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template NeonLoadExecute {{
template <class Element>
Fault %(class_name)s<Element>::execute(
%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(mem_decl)s;
%(op_rd)s;
%(ea_code)s;
MemUnion memUnion;
uint8_t *dataPtr = memUnion.bytes;
if (%(predicate_test)s)
{
if (fault == NoFault) {
fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template StoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemAtomic(xc, traceData, Mem, EA,
memAccessFlags, NULL);
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template NeonStoreExecute {{
template <class Element>
Fault %(class_name)s<Element>::execute(
%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(mem_decl)s;
%(op_rd)s;
%(ea_code)s;
MemUnion memUnion;
uint8_t *dataPtr = memUnion.bytes;
if (%(predicate_test)s)
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = xc->writeMem(dataPtr, %(size)d, EA,
memAccessFlags, NULL);
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template StoreExExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
%(memacc_code)s;
}
uint64_t writeResult;
if (fault == NoFault) {
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
&writeResult);
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template StoreExInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
NULL);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
NULL);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template NeonStoreInitiateAcc {{
template <class Element>
Fault %(class_name)s<Element>::initiateAcc(
%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(mem_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
MemUnion memUnion;
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = xc->writeMem(memUnion.bytes, %(size)d, EA,
memAccessFlags, NULL);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (%(predicate_test)s)
{
if (fault == NoFault) {
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template NeonLoadInitiateAcc {{
template <class Element>
Fault %(class_name)s<Element>::initiateAcc(
%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(mem_decl)s;
%(op_rd)s;
%(ea_code)s;
MemUnion memUnion;
uint8_t *dataPtr = memUnion.bytes;
if (%(predicate_test)s)
{
if (fault == NoFault) {
fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
}
} else {
xc->setPredicate(false);
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (%(predicate_test)s)
{
// ARM instructions will not have a pkt if the predicate is false
getMem(pkt, Mem, traceData);
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template NeonLoadCompleteAcc {{
template <class Element>
Fault %(class_name)s<Element>::completeAcc(
PacketPtr pkt, %(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(mem_decl)s;
%(op_decl)s;
%(op_rd)s;
if (%(predicate_test)s)
{
// ARM instructions will not have a pkt if the predicate is false
MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>();
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return NoFault;
}
}};
def template NeonStoreCompleteAcc {{
template <class Element>
Fault %(class_name)s<Element>::completeAcc(
PacketPtr pkt, %(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return NoFault;
}
}};
def template StoreExCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (%(predicate_test)s)
{
uint64_t writeResult = pkt->req->getExtraData();
%(postacc_code)s;
if (fault == NoFault) {
%(op_wb)s;
}
}
return fault;
}
}};
def template RfeDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst,
uint32_t _base, int _mode, bool _wb);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template SrsDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst,
uint32_t _regMode, int _mode, bool _wb);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template SwapDeclare {{
/**
* 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 _op1, uint32_t _base);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template LoadStoreDImmDeclare {{
/**
* 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 _imm);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template StoreExDImmDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst,
uint32_t _result, uint32_t _dest, uint32_t _dest2,
uint32_t _base, bool _add, int32_t _imm);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template LoadStoreImmDeclare {{
/**
* 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 StoreExImmDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst,
uint32_t _result, uint32_t _dest, uint32_t _base,
bool _add, int32_t _imm);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template StoreDRegDeclare {{
/**
* 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 StoreRegDeclare {{
/**
* 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 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;
}};
def template CompleteAccDeclare {{
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
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)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#if %(use_uops)d
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
}
}};
def template SrsConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _regMode, int _mode, bool _wb)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(OperatingMode)_regMode, (AddrMode)_mode, _wb)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#if %(use_uops)d
assert(numMicroops >= 2);
uops = new StaticInstPtr[numMicroops];
uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb);
uops[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
def template SwapConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _dest, uint32_t _op1, uint32_t _base)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
}
}};
def template LoadStoreDImmConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _dest, uint32_t _dest2,
uint32_t _base, bool _add, int32_t _imm)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_dest, (IntRegIndex)_dest2,
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#if %(use_uops)d
assert(numMicroops >= 2);
uops = new StaticInstPtr[numMicroops];
uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm);
uops[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
def template StoreExDImmConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _result, uint32_t _dest, uint32_t _dest2,
uint32_t _base, bool _add, int32_t _imm)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_result,
(IntRegIndex)_dest, (IntRegIndex)_dest2,
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
def template LoadStoreImmConstructor {{
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 (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#if %(use_uops)d
assert(numMicroops >= 2);
uops = new StaticInstPtr[numMicroops];
uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
uops[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
def template StoreExImmConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
uint32_t _result, uint32_t _dest, uint32_t _base,
bool _add, int32_t _imm)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_result, (IntRegIndex)_dest,
(IntRegIndex)_base, _add, _imm)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#if %(use_uops)d
assert(numMicroops >= 2);
uops = new StaticInstPtr[numMicroops];
uops[0] = new %(acc_name)s(machInst, _result, _dest,
_base, _add, _imm);
uops[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
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)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_dest, (IntRegIndex)_dest2,
(IntRegIndex)_base, _add,
_shiftAmt, (ArmShiftType)_shiftType,
(IntRegIndex)_index)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
#endif
}
}};
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)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
(IntRegIndex)_dest, (IntRegIndex)_base, _add,
_shiftAmt, (ArmShiftType)_shiftType,
(IntRegIndex)_index)
{
%(constructor)s;
if (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
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 (!(condCode == COND_AL || condCode == COND_UC)) {
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add,
_shiftAmt, _shiftType, _index);
uops[1]->setDelayedCommit();
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[0]->setDelayedCommit();
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;
bool conditional = false;
if (!(condCode == COND_AL || condCode == COND_UC)) {
conditional = true;
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setDelayedCommit();
uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
uops[2]->setFlag(StaticInst::IsControl);
uops[2]->setFlag(StaticInst::IsIndirectControl);
if (conditional)
uops[2]->setFlag(StaticInst::IsCondControl);
else
uops[2]->setFlag(StaticInst::IsUncondControl);
uops[2]->setLastMicroop();
} else if(_dest == _index) {
IntRegIndex wbIndexReg = INTREG_UREG0;
uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index);
uops[0]->setDelayedCommit();
uops[1] = new %(acc_name)s(machInst, _dest, _base, _add,
_shiftAmt, _shiftType, _index);
uops[1]->setDelayedCommit();
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[0]->setDelayedCommit();
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;
bool conditional = false;
if (!(condCode == COND_AL || condCode == COND_UC)) {
conditional = true;
for (int x = 0; x < _numDestRegs; x++) {
_srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
}
}
#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[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setDelayedCommit();
uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0);
uops[2]->setFlag(StaticInst::IsControl);
uops[2]->setFlag(StaticInst::IsIndirectControl);
if (conditional)
uops[2]->setFlag(StaticInst::IsCondControl);
else
uops[2]->setFlag(StaticInst::IsUncondControl);
if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s)
uops[2]->setFlag(StaticInst::IsReturn);
uops[2]->setLastMicroop();
} else {
uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm);
uops[0]->setDelayedCommit();
uops[1] = new %(wb_decl)s;
uops[1]->setLastMicroop();
}
#endif
}
}};