Broke Load/Store instructions into microcode, and partially refactored memory operations in the SPARC ISA description.
--HG-- rename : src/arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats/formats.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/basicmem.isa rename : src/arch/sparc/isa/formats/blockmem.isa => src/arch/sparc/isa/formats/mem/blockmem.isa rename : src/arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem/mem.isa extra : convert_revision : dbbb00f997a102871b084b209b9fa08c5e1853ee
This commit is contained in:
parent
e9908e3c85
commit
20208d00e6
11 changed files with 545 additions and 438 deletions
|
@ -846,11 +846,10 @@ decode OP default Unknown::unknown()
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
0x0E: Store::stx({{Mem.udw = Rd}});
|
0x0E: Store::stx({{Mem.udw = Rd}});
|
||||||
0x0F: LoadStore::swap({{
|
0x0F: LoadStore::swap(
|
||||||
uint32_t temp = Rd;
|
{{*temp = Rd.uw;
|
||||||
Rd = Mem.uw;
|
Rd.uw = Mem.uw;}},
|
||||||
Mem.uw = temp;
|
{{Mem.uw = *temp;}});
|
||||||
}});
|
|
||||||
format Load {
|
format Load {
|
||||||
0x10: lduwa({{Rd = Mem.uw;}});
|
0x10: lduwa({{Rd = Mem.uw;}});
|
||||||
0x11: lduba({{Rd = Mem.ub;}});
|
0x11: lduba({{Rd = Mem.ub;}});
|
||||||
|
@ -873,16 +872,14 @@ decode OP default Unknown::unknown()
|
||||||
0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
|
0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
|
||||||
0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
|
0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
|
||||||
}
|
}
|
||||||
0x1D: LoadStore::ldstuba({{
|
0x1D: LoadStore::ldstuba(
|
||||||
Rd = Mem.ub;
|
{{Rd = Mem.ub;}},
|
||||||
Mem.ub = 0xFF;
|
{{Mem.ub = 0xFF}});
|
||||||
}});
|
|
||||||
0x1E: Store::stxa({{Mem.udw = Rd}});
|
0x1E: Store::stxa({{Mem.udw = Rd}});
|
||||||
0x1F: LoadStore::swapa({{
|
0x1F: LoadStore::swapa(
|
||||||
uint32_t temp = Rd;
|
{{*temp = Rd.uw;
|
||||||
Rd = Mem.uw;
|
Rd.uw = Mem.uw;}},
|
||||||
Mem.uw = temp;
|
{{Mem.uw = *temp;}});
|
||||||
}});
|
|
||||||
format Trap {
|
format Trap {
|
||||||
0x20: Load::ldf({{Frd.uw = Mem.uw;}});
|
0x20: Load::ldf({{Frd.uw = Mem.uw;}});
|
||||||
0x21: decode X {
|
0x21: decode X {
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
//Include the basic format
|
|
||||||
//Templates from this format are used later
|
|
||||||
##include "formats/basic.isa"
|
|
||||||
|
|
||||||
//Include base classes for microcoding instructions
|
|
||||||
##include "formats/micro.isa"
|
|
||||||
|
|
||||||
//Include the noop format
|
|
||||||
##include "formats/nop.isa"
|
|
||||||
|
|
||||||
//Include the integerOp and integerOpCc format
|
|
||||||
##include "formats/integerop.isa"
|
|
||||||
|
|
||||||
//Include the memory format
|
|
||||||
##include "formats/mem.isa"
|
|
||||||
|
|
||||||
//Include the block memory format
|
|
||||||
##include "formats/blockmem.isa"
|
|
||||||
|
|
||||||
//Include the compare and swap format
|
|
||||||
##include "formats/cas.isa"
|
|
||||||
|
|
||||||
//Include the trap format
|
|
||||||
##include "formats/trap.isa"
|
|
||||||
|
|
||||||
//Include the unimplemented format
|
|
||||||
##include "formats/unimp.isa"
|
|
||||||
|
|
||||||
//Include the "unknown" format
|
|
||||||
##include "formats/unknown.isa"
|
|
||||||
|
|
||||||
//Include the priveleged mode format
|
|
||||||
##include "formats/priv.isa"
|
|
||||||
|
|
||||||
//Include the branch format
|
|
||||||
##include "formats/branch.isa"
|
|
||||||
|
|
62
src/arch/sparc/isa/formats/formats.isa
Normal file
62
src/arch/sparc/isa/formats/formats.isa
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
// 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: Gabe Black
|
||||||
|
|
||||||
|
//Include the basic format
|
||||||
|
//Templates from this format are used later
|
||||||
|
##include "basic.isa"
|
||||||
|
|
||||||
|
//Include base classes for microcoding instructions
|
||||||
|
##include "micro.isa"
|
||||||
|
|
||||||
|
//Include the noop format
|
||||||
|
##include "nop.isa"
|
||||||
|
|
||||||
|
//Include the integerOp and integerOpCc format
|
||||||
|
##include "integerop.isa"
|
||||||
|
|
||||||
|
//Include the memory formats
|
||||||
|
##include "mem/mem.isa"
|
||||||
|
|
||||||
|
//Include the compare and swap format
|
||||||
|
##include "cas.isa"
|
||||||
|
|
||||||
|
//Include the trap format
|
||||||
|
##include "trap.isa"
|
||||||
|
|
||||||
|
//Include the unimplemented format
|
||||||
|
##include "unimp.isa"
|
||||||
|
|
||||||
|
//Include the "unknown" format
|
||||||
|
##include "unknown.isa"
|
||||||
|
|
||||||
|
//Include the priveleged mode format
|
||||||
|
##include "priv.isa"
|
||||||
|
|
||||||
|
//Include the branch format
|
||||||
|
##include "branch.isa"
|
||||||
|
|
|
@ -1,347 +0,0 @@
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Mem instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
output header {{
|
|
||||||
/**
|
|
||||||
* Base class for memory operations.
|
|
||||||
*/
|
|
||||||
class Mem : public SparcStaticInst
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
|
|
||||||
SparcStaticInst(mnem, _machInst, __opClass)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for memory operations which use an immediate offset.
|
|
||||||
*/
|
|
||||||
class MemImm : public Mem
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
|
|
||||||
Mem(mnem, _machInst, __opClass)
|
|
||||||
{
|
|
||||||
imm = sext<13>(SIMM13);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const;
|
|
||||||
|
|
||||||
int32_t imm;
|
|
||||||
};
|
|
||||||
}};
|
|
||||||
|
|
||||||
output decoder {{
|
|
||||||
std::string Mem::generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const
|
|
||||||
{
|
|
||||||
std::stringstream response;
|
|
||||||
bool load = flags[IsLoad];
|
|
||||||
bool save = flags[IsStore];
|
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
|
||||||
if(save)
|
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[0]);
|
|
||||||
ccprintf(response, ", ");
|
|
||||||
}
|
|
||||||
ccprintf(response, "[ ");
|
|
||||||
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
|
||||||
ccprintf(response, " + ");
|
|
||||||
printReg(response, _srcRegIdx[!save ? 1 : 2]);
|
|
||||||
ccprintf(response, " ]");
|
|
||||||
if(load)
|
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
|
||||||
printReg(response, _destRegIdx[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MemImm::generateDisassembly(Addr pc,
|
|
||||||
const SymbolTable *symtab) const
|
|
||||||
{
|
|
||||||
std::stringstream response;
|
|
||||||
bool load = flags[IsLoad];
|
|
||||||
bool save = flags[IsStore];
|
|
||||||
|
|
||||||
printMnemonic(response, mnemonic);
|
|
||||||
if(save)
|
|
||||||
{
|
|
||||||
printReg(response, _srcRegIdx[0]);
|
|
||||||
ccprintf(response, ", ");
|
|
||||||
}
|
|
||||||
ccprintf(response, "[ ");
|
|
||||||
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
|
||||||
if(imm >= 0)
|
|
||||||
ccprintf(response, " + 0x%x ]", imm);
|
|
||||||
else
|
|
||||||
ccprintf(response, " + -0x%x ]", -imm);
|
|
||||||
if(load)
|
|
||||||
{
|
|
||||||
ccprintf(response, ", ");
|
|
||||||
printReg(response, _destRegIdx[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
}};
|
|
||||||
|
|
||||||
def template LoadExecute {{
|
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
|
||||||
Trace::InstRecord *traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
Addr EA;
|
|
||||||
%(op_decl)s;
|
|
||||||
%(op_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
|
||||||
fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
|
||||||
%(code)s;
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
|
||||||
Trace::InstRecord * traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
Addr EA;
|
|
||||||
uint%(mem_acc_size)s_t Mem;
|
|
||||||
%(ea_decl)s;
|
|
||||||
%(ea_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
|
|
||||||
Trace::InstRecord * traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
%(code_decl)s;
|
|
||||||
%(code_rd)s;
|
|
||||||
Mem = pkt->get<typeof(Mem)>();
|
|
||||||
%(code)s;
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
%(code_wb)s;
|
|
||||||
}
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
def template StoreExecute {{
|
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
|
||||||
Trace::InstRecord *traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
uint64_t write_result = 0;
|
|
||||||
Addr EA;
|
|
||||||
%(op_decl)s;
|
|
||||||
%(op_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
|
||||||
%(code)s;
|
|
||||||
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
|
||||||
}
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
|
||||||
Trace::InstRecord * traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
uint64_t write_result = 0;
|
|
||||||
Addr EA;
|
|
||||||
%(op_decl)s;
|
|
||||||
%(op_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
|
||||||
%(code)s;
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
|
||||||
}
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
|
|
||||||
Trace::InstRecord * traceData) const
|
|
||||||
{
|
|
||||||
return NoFault;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
def template LoadStoreExecute {{
|
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
|
||||||
Trace::InstRecord *traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
uint64_t write_result = 0;
|
|
||||||
Addr EA;
|
|
||||||
%(op_decl)s;
|
|
||||||
%(op_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
|
||||||
xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
|
||||||
%(code)s;
|
|
||||||
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
def template MemDeclare {{
|
|
||||||
/**
|
|
||||||
* Static instruction class for "%(mnemonic)s".
|
|
||||||
*/
|
|
||||||
class %(class_name)s : public %(base_class)s
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Constructor.
|
|
||||||
%(class_name)s(ExtMachInst machInst);
|
|
||||||
|
|
||||||
%(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;
|
|
||||||
}};
|
|
||||||
|
|
||||||
|
|
||||||
let {{
|
|
||||||
# XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
|
|
||||||
# into ones that are available in priv and hpriv, and those that are only
|
|
||||||
# available in hpriv
|
|
||||||
privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
|
|
||||||
return new PrivilegedAction;
|
|
||||||
if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
|
|
||||||
return new PrivilegedAction;'''
|
|
||||||
|
|
||||||
def doMemFormat(code, execute, priv, name, Name, opt_flags):
|
|
||||||
addrCalcReg = 'EA = Rs1 + Rs2;'
|
|
||||||
addrCalcImm = 'EA = Rs1 + imm;'
|
|
||||||
ea_iop = InstObjParams(name, Name, 'Mem',
|
|
||||||
addrCalcReg, opt_flags, {"priv_check": priv})
|
|
||||||
ea_iop_imm = InstObjParams(name, Name, 'MemImm',
|
|
||||||
addrCalcImm, opt_flags, {"priv_check": priv})
|
|
||||||
code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags)
|
|
||||||
iop = InstObjParams(name, Name, 'Mem', code,
|
|
||||||
opt_flags, {"ea_code": addrCalcReg,
|
|
||||||
"priv_check": priv})
|
|
||||||
(iop.ea_decl,
|
|
||||||
iop.ea_rd,
|
|
||||||
iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb)
|
|
||||||
(iop.code_decl,
|
|
||||||
iop.code_rd,
|
|
||||||
iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
|
|
||||||
iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
|
|
||||||
opt_flags, {"ea_code": addrCalcImm,
|
|
||||||
"priv_check": priv})
|
|
||||||
(iop_imm.ea_decl,
|
|
||||||
iop_imm.ea_rd,
|
|
||||||
iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb)
|
|
||||||
(iop_imm.code_decl,
|
|
||||||
iop_imm.code_rd,
|
|
||||||
iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb)
|
|
||||||
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
|
|
||||||
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
|
|
||||||
decode_block = ROrImmDecode.subst(iop)
|
|
||||||
exec_output = execute.subst(iop) + execute.subst(iop_imm)
|
|
||||||
return (header_output, decoder_output, exec_output, decode_block)
|
|
||||||
}};
|
|
||||||
|
|
||||||
def format LoadAlt(code, *opt_flags) {{
|
|
||||||
(header_output,
|
|
||||||
decoder_output,
|
|
||||||
exec_output,
|
|
||||||
decode_block) = doMemFormat(code, LoadExecute,
|
|
||||||
privelegedString, name, Name, opt_flags)
|
|
||||||
}};
|
|
||||||
|
|
||||||
def format StoreAlt(code, *opt_flags) {{
|
|
||||||
(header_output,
|
|
||||||
decoder_output,
|
|
||||||
exec_output,
|
|
||||||
decode_block) = doMemFormat(code, StoreExecute,
|
|
||||||
privilegedString, name, Name, opt_flags)
|
|
||||||
}};
|
|
||||||
|
|
||||||
def format Load(code, *opt_flags) {{
|
|
||||||
(header_output,
|
|
||||||
decoder_output,
|
|
||||||
exec_output,
|
|
||||||
decode_block) = doMemFormat(code,
|
|
||||||
LoadExecute, '', name, Name, opt_flags)
|
|
||||||
}};
|
|
||||||
|
|
||||||
def format Store(code, *opt_flags) {{
|
|
||||||
(header_output,
|
|
||||||
decoder_output,
|
|
||||||
exec_output,
|
|
||||||
decode_block) = doMemFormat(code,
|
|
||||||
StoreExecute, '', name, Name, opt_flags)
|
|
||||||
}};
|
|
||||||
|
|
||||||
def format LoadStore(code, *opt_flags) {{
|
|
||||||
(header_output,
|
|
||||||
decoder_output,
|
|
||||||
exec_output,
|
|
||||||
decode_block) = doMemFormat(code,
|
|
||||||
LoadStoreExecute, '', name, Name, opt_flags)
|
|
||||||
}};
|
|
202
src/arch/sparc/isa/formats/mem/basicmem.isa
Normal file
202
src/arch/sparc/isa/formats/mem/basicmem.isa
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
// 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: Ali Saidi
|
||||||
|
// Gabe Black
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Mem instructions
|
||||||
|
//
|
||||||
|
|
||||||
|
output header {{
|
||||||
|
/**
|
||||||
|
* Base class for memory operations.
|
||||||
|
*/
|
||||||
|
class Mem : public SparcStaticInst
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
|
||||||
|
SparcStaticInst(mnem, _machInst, __opClass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for memory operations which use an immediate offset.
|
||||||
|
*/
|
||||||
|
class MemImm : public Mem
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
|
||||||
|
Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const;
|
||||||
|
|
||||||
|
const int32_t imm;
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
|
||||||
|
output decoder {{
|
||||||
|
std::string Mem::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
bool load = flags[IsLoad];
|
||||||
|
bool save = flags[IsStore];
|
||||||
|
|
||||||
|
printMnemonic(response, mnemonic);
|
||||||
|
if(save)
|
||||||
|
{
|
||||||
|
printReg(response, _srcRegIdx[0]);
|
||||||
|
ccprintf(response, ", ");
|
||||||
|
}
|
||||||
|
ccprintf(response, "[ ");
|
||||||
|
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
||||||
|
ccprintf(response, " + ");
|
||||||
|
printReg(response, _srcRegIdx[!save ? 1 : 2]);
|
||||||
|
ccprintf(response, " ]");
|
||||||
|
if(load)
|
||||||
|
{
|
||||||
|
ccprintf(response, ", ");
|
||||||
|
printReg(response, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemImm::generateDisassembly(Addr pc,
|
||||||
|
const SymbolTable *symtab) const
|
||||||
|
{
|
||||||
|
std::stringstream response;
|
||||||
|
bool load = flags[IsLoad];
|
||||||
|
bool save = flags[IsStore];
|
||||||
|
|
||||||
|
printMnemonic(response, mnemonic);
|
||||||
|
if(save)
|
||||||
|
{
|
||||||
|
printReg(response, _srcRegIdx[0]);
|
||||||
|
ccprintf(response, ", ");
|
||||||
|
}
|
||||||
|
ccprintf(response, "[ ");
|
||||||
|
printReg(response, _srcRegIdx[!save ? 0 : 1]);
|
||||||
|
if(imm >= 0)
|
||||||
|
ccprintf(response, " + 0x%x ]", imm);
|
||||||
|
else
|
||||||
|
ccprintf(response, " + -0x%x ]", -imm);
|
||||||
|
if(load)
|
||||||
|
{
|
||||||
|
ccprintf(response, ", ");
|
||||||
|
printReg(response, _destRegIdx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.str();
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
def template MemDeclare {{
|
||||||
|
/**
|
||||||
|
* Static instruction class for "%(mnemonic)s".
|
||||||
|
*/
|
||||||
|
class %(class_name)s : public %(base_class)s
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
%(class_name)s(ExtMachInst machInst);
|
||||||
|
|
||||||
|
%(BasicExecDeclare)s
|
||||||
|
|
||||||
|
%(InitiateAccDeclare)s
|
||||||
|
|
||||||
|
%(CompleteAccDeclare)s
|
||||||
|
};
|
||||||
|
}};
|
||||||
|
|
||||||
|
let {{
|
||||||
|
# XXX Need to take care of pstate.hpriv as well. The lower ASIs are split
|
||||||
|
# into ones that are available in priv and hpriv, and those that are only
|
||||||
|
# available in hpriv
|
||||||
|
privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
|
||||||
|
return new PrivilegedAction;
|
||||||
|
if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2))
|
||||||
|
return new PrivilegedAction;'''
|
||||||
|
|
||||||
|
def doMemFormat(code, execute, priv, name, Name, opt_flags):
|
||||||
|
addrCalcReg = 'EA = Rs1 + Rs2;'
|
||||||
|
addrCalcImm = 'EA = Rs1 + imm;'
|
||||||
|
iop = InstObjParams(name, Name, 'Mem', code,
|
||||||
|
opt_flags, {"priv_check": priv, "ea_code": addrCalcReg})
|
||||||
|
iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
|
||||||
|
opt_flags, {"priv_check": priv, "ea_code": addrCalcImm})
|
||||||
|
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
|
||||||
|
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
|
||||||
|
decode_block = ROrImmDecode.subst(iop)
|
||||||
|
exec_output = doSplitExecute(code, addrCalcReg, addrCalcImm, execute,
|
||||||
|
priv, name, name + "Imm", Name, Name + "Imm", opt_flags)
|
||||||
|
return (header_output, decoder_output, exec_output, decode_block)
|
||||||
|
}};
|
||||||
|
|
||||||
|
def format LoadAlt(code, *opt_flags) {{
|
||||||
|
(header_output,
|
||||||
|
decoder_output,
|
||||||
|
exec_output,
|
||||||
|
decode_block) = doMemFormat(code, LoadExecute,
|
||||||
|
privelegedString, name, Name, opt_flags)
|
||||||
|
}};
|
||||||
|
|
||||||
|
def format StoreAlt(code, *opt_flags) {{
|
||||||
|
(header_output,
|
||||||
|
decoder_output,
|
||||||
|
exec_output,
|
||||||
|
decode_block) = doMemFormat(code, StoreExecute,
|
||||||
|
privilegedString, name, Name, opt_flags)
|
||||||
|
}};
|
||||||
|
|
||||||
|
def format Load(code, *opt_flags) {{
|
||||||
|
(header_output,
|
||||||
|
decoder_output,
|
||||||
|
exec_output,
|
||||||
|
decode_block) = doMemFormat(code,
|
||||||
|
LoadExecute, '', name, Name, opt_flags)
|
||||||
|
}};
|
||||||
|
|
||||||
|
def format Store(code, *opt_flags) {{
|
||||||
|
(header_output,
|
||||||
|
decoder_output,
|
||||||
|
exec_output,
|
||||||
|
decode_block) = doMemFormat(code,
|
||||||
|
StoreExecute, '', name, Name, opt_flags)
|
||||||
|
}};
|
|
@ -1,3 +1,32 @@
|
||||||
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
// 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: Ali Saidi
|
||||||
|
// Gabe Black
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Block Memory instructions
|
// Block Memory instructions
|
||||||
|
@ -12,9 +41,8 @@ output header {{
|
||||||
// Constructor
|
// Constructor
|
||||||
// We make the assumption that all block memory operations
|
// We make the assumption that all block memory operations
|
||||||
// Will take 8 instructions to execute
|
// Will take 8 instructions to execute
|
||||||
BlockMem(const char *mnem,
|
BlockMem(const char *mnem, ExtMachInst _machInst) :
|
||||||
ExtMachInst _machInst, OpClass __opClass) :
|
SparcMacroInst(mnem, _machInst, No_OpClass, 8)
|
||||||
SparcMacroInst(mnem, _machInst, __opClass, 8)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,13 +51,9 @@ output header {{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
BlockMemImm(const char *mnem,
|
BlockMemImm(const char *mnem, ExtMachInst _machInst) :
|
||||||
ExtMachInst _machInst, OpClass __opClass) :
|
BlockMem(mnem, _machInst)
|
||||||
BlockMem(mnem, _machInst, __opClass),
|
|
||||||
imm(sext<13>(SIMM13))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const int32_t imm;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockMemMicro : public SparcDelayedMicroInst
|
class BlockMemMicro : public SparcDelayedMicroInst
|
||||||
|
@ -125,32 +149,6 @@ output decoder {{
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
def template LoadStoreExecute {{
|
|
||||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
|
||||||
Trace::InstRecord *traceData) const
|
|
||||||
{
|
|
||||||
Fault fault = NoFault;
|
|
||||||
uint64_t write_result = 0;
|
|
||||||
Addr EA;
|
|
||||||
%(op_decl)s;
|
|
||||||
%(op_rd)s;
|
|
||||||
%(priv_check)s;
|
|
||||||
%(ea_code)s;
|
|
||||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
|
||||||
xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
|
||||||
%(code)s;
|
|
||||||
|
|
||||||
if(fault == NoFault)
|
|
||||||
{
|
|
||||||
xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
|
||||||
//Write the resulting state to the execution context
|
|
||||||
%(op_wb)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fault;
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
def template BlockMemDeclare {{
|
def template BlockMemDeclare {{
|
||||||
/**
|
/**
|
||||||
* Static instruction class for a block memory operation
|
* Static instruction class for a block memory operation
|
||||||
|
@ -231,7 +229,7 @@ def template BlockMemDeclare {{
|
||||||
// Basic instruction class constructor template.
|
// Basic instruction class constructor template.
|
||||||
def template BlockMemConstructor {{
|
def template BlockMemConstructor {{
|
||||||
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
||||||
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
|
: %(base_class)s("%(mnemonic)s", machInst)
|
||||||
{
|
{
|
||||||
%(constructor)s;
|
%(constructor)s;
|
||||||
microOps[0] = new %(class_name)s_0(machInst);
|
microOps[0] = new %(class_name)s_0(machInst);
|
||||||
|
@ -335,7 +333,7 @@ let {{
|
||||||
for microPC in range(8):
|
for microPC in range(8):
|
||||||
flag_code = ''
|
flag_code = ''
|
||||||
if (microPC == 7):
|
if (microPC == 7):
|
||||||
flag_code = "flags[IsLastMicroOp] = true"
|
flag_code = "flags[IsLastMicroOp] = true;"
|
||||||
pcedCode = matcher.sub("Frd_%d" % microPC, code)
|
pcedCode = matcher.sub("Frd_%d" % microPC, code)
|
||||||
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
|
iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
|
||||||
opt_flags, {"ea_code": addrCalcReg,
|
opt_flags, {"ea_code": addrCalcReg,
|
45
src/arch/sparc/isa/formats/mem/mem.isa
Normal file
45
src/arch/sparc/isa/formats/mem/mem.isa
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
// 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: Ali Saidi
|
||||||
|
// Gabe Black
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Mem formats
|
||||||
|
//
|
||||||
|
|
||||||
|
//Include mem utility templates and functions
|
||||||
|
##include "util.isa"
|
||||||
|
|
||||||
|
//Include the basic memory format
|
||||||
|
##include "basicmem.isa"
|
||||||
|
|
||||||
|
//Include the block memory format
|
||||||
|
##include "blockmem.isa"
|
||||||
|
|
||||||
|
//Include the load/store memory format
|
||||||
|
##include "loadstore.isa"
|
183
src/arch/sparc/isa/formats/mem/util.isa
Normal file
183
src/arch/sparc/isa/formats/mem/util.isa
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
// Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
|
// 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: Ali Saidi
|
||||||
|
// Gabe Black
|
||||||
|
// Steve Reinhardt
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Mem utility templates and functions
|
||||||
|
//
|
||||||
|
|
||||||
|
//This template provides the execute functions for a load
|
||||||
|
def template LoadExecute {{
|
||||||
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
|
Trace::InstRecord *traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
Addr EA;
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(priv_check)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||||
|
fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
||||||
|
%(code)s;
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
//Write the resulting state to the execution context
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
Addr EA;
|
||||||
|
uint%(mem_acc_size)s_t Mem;
|
||||||
|
%(ea_decl)s;
|
||||||
|
%(ea_rd)s;
|
||||||
|
%(priv_check)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
%(code_decl)s;
|
||||||
|
%(code_rd)s;
|
||||||
|
Mem = pkt->get<typeof(Mem)>();
|
||||||
|
%(code)s;
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
%(code_wb)s;
|
||||||
|
}
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
//This template provides the execute functions for a store
|
||||||
|
def template StoreExecute {{
|
||||||
|
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||||
|
Trace::InstRecord *traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
uint64_t write_result = 0;
|
||||||
|
Addr EA;
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(priv_check)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||||
|
%(code)s;
|
||||||
|
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
||||||
|
}
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
//Write the resulting state to the execution context
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
Fault fault = NoFault;
|
||||||
|
uint64_t write_result = 0;
|
||||||
|
Addr EA;
|
||||||
|
%(op_decl)s;
|
||||||
|
%(op_rd)s;
|
||||||
|
%(priv_check)s;
|
||||||
|
%(ea_code)s;
|
||||||
|
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||||
|
%(code)s;
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
|
||||||
|
}
|
||||||
|
if(fault == NoFault)
|
||||||
|
{
|
||||||
|
//Write the resulting state to the execution context
|
||||||
|
%(op_wb)s;
|
||||||
|
}
|
||||||
|
return fault;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
|
||||||
|
Trace::InstRecord * traceData) const
|
||||||
|
{
|
||||||
|
return NoFault;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
//This delcares the initiateAcc function in memory operations
|
||||||
|
def template InitiateAccDeclare {{
|
||||||
|
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
|
}};
|
||||||
|
|
||||||
|
//This declares the completeAcc function in memory operations
|
||||||
|
def template CompleteAccDeclare {{
|
||||||
|
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
|
||||||
|
}};
|
||||||
|
|
||||||
|
//This function properly generates the execute functions for one of the
|
||||||
|
//templates above. This is needed because in one case, ea computation,
|
||||||
|
//privelege checks and the actual code all occur in the same function,
|
||||||
|
//and in the other they're distributed across two. Also note that for
|
||||||
|
//execute functions, the name of the base class doesn't matter.
|
||||||
|
let {{
|
||||||
|
def doSplitExecute(code, eaRegCode, eaImmCode, execute,
|
||||||
|
priv, nameReg, nameImm, NameReg, NameImm, opt_flags):
|
||||||
|
codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
|
||||||
|
executeCode = ''
|
||||||
|
for (eaCode, name, Name) in (
|
||||||
|
(eaRegCode, nameReg, NameReg),
|
||||||
|
(eaImmCode, nameImm, NameImm)):
|
||||||
|
eaIop = InstObjParams(name, Name, '', eaCode,
|
||||||
|
opt_flags, {"priv_check": priv})
|
||||||
|
iop = InstObjParams(name, Name, '', code, opt_flags,
|
||||||
|
{"priv_check": priv, "ea_code" : eaCode})
|
||||||
|
(iop.ea_decl,
|
||||||
|
iop.ea_rd,
|
||||||
|
iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
|
||||||
|
(iop.code_decl,
|
||||||
|
iop.code_rd,
|
||||||
|
iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
|
||||||
|
executeCode += execute.subst(iop)
|
||||||
|
return executeCode
|
||||||
|
}};
|
|
@ -49,6 +49,7 @@ output decoder {{
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.hh" // for Jump::branchTarget()
|
#include "cpu/thread_context.hh" // for Jump::branchTarget()
|
||||||
|
#include "mem/packet.hh"
|
||||||
|
|
||||||
#if defined(linux)
|
#if defined(linux)
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
|
@ -66,6 +67,8 @@ output exec {{
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/exetrace.hh"
|
#include "cpu/exetrace.hh"
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
|
#include "mem/packet.hh"
|
||||||
|
#include "mem/packet_access.hh"
|
||||||
|
|
||||||
using namespace SparcISA;
|
using namespace SparcISA;
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace SparcISA;
|
||||||
##include "base.isa"
|
##include "base.isa"
|
||||||
|
|
||||||
//Include the definitions for the instruction formats
|
//Include the definitions for the instruction formats
|
||||||
##include "formats.isa"
|
##include "formats/formats.isa"
|
||||||
|
|
||||||
//Include the decoder definition
|
//Include the decoder definition
|
||||||
##include "decoder.isa"
|
##include "decoder.isa"
|
||||||
|
|
|
@ -77,7 +77,6 @@ def operands {{
|
||||||
'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
|
'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
|
||||||
'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
|
'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
|
||||||
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
|
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
|
||||||
'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
|
|
||||||
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
|
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
|
||||||
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
|
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
|
||||||
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
|
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
|
||||||
|
@ -107,6 +106,8 @@ def operands {{
|
||||||
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
|
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
|
||||||
|
|
||||||
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
|
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
|
||||||
'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56)
|
'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56),
|
||||||
|
# Mem gets a large number so it's always last
|
||||||
|
'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
|
||||||
|
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue