ARM: Implement the swp and swpb instructions.
This commit is contained in:
@@ -43,9 +43,25 @@
|
||||
#include "arch/arm/insts/mem.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ArmISA
|
||||
{
|
||||
|
||||
string
|
||||
Swap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
|
||||
{
|
||||
stringstream ss;
|
||||
printMnemonic(ss);
|
||||
printReg(ss, dest);
|
||||
ss << ", ";
|
||||
printReg(ss, op1);
|
||||
ss << ", [";
|
||||
printReg(ss, base);
|
||||
ss << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void
|
||||
Memory::printInst(std::ostream &os, AddrMode addrMode) const
|
||||
{
|
||||
|
||||
@@ -47,6 +47,22 @@
|
||||
namespace ArmISA
|
||||
{
|
||||
|
||||
class Swap : public PredOp
|
||||
{
|
||||
protected:
|
||||
IntRegIndex dest;
|
||||
IntRegIndex op1;
|
||||
IntRegIndex base;
|
||||
|
||||
Swap(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
|
||||
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _base)
|
||||
: PredOp(mnem, _machInst, __opClass),
|
||||
dest(_dest), op1(_op1), base(_base)
|
||||
{}
|
||||
|
||||
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
||||
};
|
||||
|
||||
class Memory : public PredOp
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
//Stores of a single item
|
||||
##include "str.isa"
|
||||
|
||||
//Swaps
|
||||
##include "swap.isa"
|
||||
|
||||
//Load/store multiple
|
||||
##include "macromem.isa"
|
||||
|
||||
|
||||
@@ -38,12 +38,14 @@
|
||||
// Authors: Gabe Black
|
||||
|
||||
let {{
|
||||
def loadStoreBase(name, Name, imm, eaCode, accCode, memFlags,
|
||||
instFlags, base = 'Memory', execTemplateBase = ''):
|
||||
def loadStoreBaseWork(name, Name, imm, swp, codeBlobs, memFlags,
|
||||
instFlags, base = 'Memory', execTemplateBase = ''):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
memFlags = makeList(memFlags)
|
||||
instFlags = makeList(instFlags)
|
||||
|
||||
eaCode = codeBlobs["ea_code"]
|
||||
|
||||
# This shouldn't be part of the eaCode, but until the exec templates
|
||||
# are converted over it's the easiest place to put it.
|
||||
eaCode += '\n unsigned memAccessFlags = '
|
||||
@@ -52,17 +54,18 @@ let {{
|
||||
else:
|
||||
eaCode += '0;'
|
||||
|
||||
iop = InstObjParams(name, Name, base,
|
||||
{'ea_code': eaCode,
|
||||
'memacc_code': accCode,
|
||||
'predicate_test': predicateTest},
|
||||
instFlags)
|
||||
codeBlobs["ea_code"] = eaCode
|
||||
|
||||
iop = InstObjParams(name, Name, base, codeBlobs, instFlags)
|
||||
|
||||
fullExecTemplate = eval(execTemplateBase + 'Execute')
|
||||
initiateAccTemplate = eval(execTemplateBase + 'InitiateAcc')
|
||||
completeAccTemplate = eval(execTemplateBase + 'CompleteAcc')
|
||||
|
||||
if imm:
|
||||
if swp:
|
||||
declareTemplate = SwapDeclare
|
||||
constructTemplate = SwapConstructor
|
||||
elif imm:
|
||||
declareTemplate = LoadStoreImmDeclare
|
||||
constructTemplate = LoadStoreImmConstructor
|
||||
else:
|
||||
@@ -76,6 +79,23 @@ let {{
|
||||
+ initiateAccTemplate.subst(iop)
|
||||
+ completeAccTemplate.subst(iop))
|
||||
|
||||
def loadStoreBase(name, Name, imm, eaCode, accCode, memFlags,
|
||||
instFlags, base = 'Memory', execTemplateBase = ''):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode,
|
||||
"predicate_test": predicateTest }
|
||||
return loadStoreBaseWork(name, Name, imm, False, codeBlobs, memFlags,
|
||||
instFlags, base, execTemplateBase)
|
||||
|
||||
def SwapBase(name, Name, eaCode, preAccCode, postAccCode, memFlags,
|
||||
instFlags):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"preacc_code": preAccCode,
|
||||
"postacc_code": postAccCode,
|
||||
"predicate_test": predicateTest }
|
||||
return loadStoreBaseWork(name, Name, False, True, codeBlobs, memFlags,
|
||||
instFlags, 'Swap', 'Swap')
|
||||
|
||||
def memClassName(base, post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
Name = base
|
||||
|
||||
61
src/arch/arm/isa/insts/swap.isa
Normal file
61
src/arch/arm/isa/insts/swap.isa
Normal file
@@ -0,0 +1,61 @@
|
||||
// -*- 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.
|
||||
//
|
||||
// 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: Gabe Black
|
||||
|
||||
let {{
|
||||
|
||||
header_output = decoder_output = exec_output = ""
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = SwapBase("swp", "Swp", "EA = Base;",
|
||||
"Mem = Op1;", "Dest = memData;",
|
||||
["Request::MEM_SWAP"], [])
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = SwapBase("swpb", "Swpb", "EA = Base;",
|
||||
"Mem.ub = Op1.ub;", "Dest.ub = (uint8_t)memData;",
|
||||
["Request::MEM_SWAP"], [])
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
}};
|
||||
@@ -41,6 +41,96 @@
|
||||
// Authors: Stephen Hines
|
||||
|
||||
|
||||
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 = xc->write((uint%(mem_acc_size)d_t&)Mem,
|
||||
EA, memAccessFlags, &memData);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(postacc_code)s;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
}
|
||||
|
||||
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 = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &memData);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
uint64_t memData = pkt->get<typeof(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
|
||||
@@ -204,6 +294,26 @@ def template StoreCompleteAcc {{
|
||||
}
|
||||
}};
|
||||
|
||||
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 LoadStoreImmDeclare {{
|
||||
/**
|
||||
* Static instruction class for "%(mnemonic)s".
|
||||
@@ -254,6 +364,16 @@ def template CompleteAccDeclare {{
|
||||
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||
}};
|
||||
|
||||
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;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreImmConstructor {{
|
||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
|
||||
uint32_t _dest, uint32_t _base, bool _add, int32_t _imm)
|
||||
|
||||
Reference in New Issue
Block a user