ARM: Implement the swp and swpb instructions.

This commit is contained in:
Gabe Black
2010-06-02 12:58:05 -05:00
parent 1884ed65bd
commit e157b1f52a
6 changed files with 244 additions and 8 deletions

View File

@@ -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
{

View File

@@ -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:

View File

@@ -52,6 +52,9 @@
//Stores of a single item
##include "str.isa"
//Swaps
##include "swap.isa"
//Load/store multiple
##include "macromem.isa"

View File

@@ -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

View 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
}};

View File

@@ -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)