-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2008 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
+
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(BasicExecDeclare)s
};
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
- if(fault == NoFault)
- {
+ fault = read(xc, EA, Mem, memFlags);
+
+ if (fault == NoFault) {
%(code)s;
+ } else if (memFlags & Request::PF_EXCLUSIVE) {
+ // For prefetches, ignore any faults/exceptions.
+ return NoFault;
}
if(fault == NoFault)
{
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
+ fault = read(xc, EA, Mem, memFlags);
return fault;
}
%(op_decl)s;
%(op_rd)s;
- Mem = pkt->get<typeof(Mem)>();
+ Mem = get(pkt);
+
%(code)s;
if(fault == NoFault)
if(fault == NoFault)
{
- fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
- EA, 0, 0);
- }
- if(fault == NoFault)
- {
- %(op_wb)s;
+ fault = write(xc, Mem, EA, memFlags);
+ if(fault == NoFault)
+ {
+ %(post_code)s;
+ %(op_wb)s;
+ }
}
return fault;
if(fault == NoFault)
{
- fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
- EA, 0, 0);
- }
- if(fault == NoFault)
- {
- %(op_wb)s;
+ write(xc, Mem, EA, memFlags);
}
return fault;
}
}};
def template MicroStoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
- Trace::InstRecord * traceData) const
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
+ %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
{
+ %(op_decl)s;
+ %(op_rd)s;
+ %(complete_code)s;
+ %(op_wb)s;
return NoFault;
}
}};
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize);
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags);
%(BasicExecDeclare)s
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize) :
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false,
_scale, _index, _base,
_disp, _segment, _data,
- _dataSize, _addressSize, %(op_class)s)
+ _dataSize, _addressSize, _memFlags, %(op_class)s)
{
buildMe();
}
uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment,
RegIndex _data,
- uint8_t _dataSize, uint8_t _addressSize) :
+ uint8_t _dataSize, uint8_t _addressSize,
+ Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast,
_scale, _index, _base,
_disp, _segment, _data,
- _dataSize, _addressSize, %(op_class)s)
+ _dataSize, _addressSize, _memFlags, %(op_class)s)
{
buildMe();
}
let {{
class LdStOp(X86Microop):
- def __init__(self, data, segment, addr, disp):
+ def __init__(self, data, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch):
self.data = data
[self.scale, self.index, self.base] = addr
self.disp = disp
self.segment = segment
- self.dataSize = "env.dataSize"
- self.addressSize = "env.addressSize"
+ self.dataSize = dataSize
+ self.addressSize = addressSize
+ self.memFlags = baseFlags
+ if atCPL0:
+ self.memFlags += " | (CPL0FlagBit << FlagShift)"
+ if prefetch:
+ self.memFlags += " | Request::PF_EXCLUSIVE"
+ self.memFlags += " | (machInst.legacy.addr ? " + \
+ "(AddrSizeFlagBit << FlagShift) : 0)"
def getAllocator(self, *microFlags):
- allocator = '''new %(class_name)s(machInst, mnemonic
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(scale)s, %(index)s, %(base)s,
%(disp)s, %(segment)s, %(data)s,
- %(dataSize)s, %(addressSize)s)''' % {
+ %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
"class_name" : self.className,
"flags" : self.microFlagsText(microFlags),
"scale" : self.scale, "index" : self.index,
"base" : self.base,
"disp" : self.disp,
"segment" : self.segment, "data" : self.data,
- "dataSize" : self.dataSize, "addressSize" : self.addressSize}
+ "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+ "memFlags" : self.memFlags}
return allocator
}};
decoder_output = ""
exec_output = ""
- calculateEA = "EA = scale * Index + Base + disp;"
+ calculateEA = '''
+ EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
+ '''
- def defineMicroLoadOp(mnemonic, code):
+ def defineMicroLoadOp(mnemonic, code, mem_flags="0"):
global header_output
global decoder_output
global exec_output
# Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
- {"code": code, "ea_code": calculateEA})
+ {"code": code,
+ "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLoadExecute.subst(iop)
exec_output += MicroLoadCompleteAcc.subst(iop)
class LoadOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LoadOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr, disp = 0,
+ dataSize="env.dataSize",
+ addressSize="env.addressSize",
+ atCPL0=False, prefetch=False):
+ super(LoadOp, self).__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags,
+ atCPL0, prefetch)
self.className = Name
self.mnemonic = name
microopClasses[name] = LoadOp
defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
-
- def defineMicroStoreOp(mnemonic, code):
+ defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
+ 'X86ISA::StoreCheck')
+ defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
+ 'X86ISA::StoreCheck | Request::LOCKED')
+ defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;')
+
+ def defineMicroStoreOp(mnemonic, code, \
+ postCode="", completeCode="", mem_flags="0"):
global header_output
global decoder_output
global exec_output
# Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
- {"code": code, "ea_code": calculateEA})
+ {"code": code,
+ "post_code": postCode,
+ "complete_code": completeCode,
+ "ea_code": calculateEA})
header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroStoreExecute.subst(iop)
exec_output += MicroStoreCompleteAcc.subst(iop)
class StoreOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LoadOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr, disp = 0,
+ dataSize="env.dataSize",
+ addressSize="env.addressSize",
+ atCPL0=False):
+ super(StoreOp, self).__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags, atCPL0, False)
self.className = Name
self.mnemonic = name
microopClasses[name] = StoreOp
- defineMicroLoadOp('St', 'Mem = Data;')
+ defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
+ defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;')
+ defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);',
+ 'Base = merge(Base, EA - SegBase, addressSize);',
+ 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);');
+ defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
- {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
+ {"code": "Data = merge(Data, EA, dataSize);",
+ "ea_code": '''
+ EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
+ '''})
header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
class LeaOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0):
- super(LeaOp, self).__init__(data, segment, addr, disp)
+ def __init__(self, data, segment, addr, disp = 0,
+ dataSize="env.dataSize", addressSize="env.addressSize"):
+ super(LeaOp, self).__init__(data, segment,
+ addr, disp, dataSize, addressSize, "0", False, False)
self.className = "Lea"
self.mnemonic = "lea"
microopClasses["lea"] = LeaOp
+
+
+ iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
+ {"code": "xc->demapPage(EA, 0);",
+ "ea_code": calculateEA})
+ header_output += MicroLeaDeclare.subst(iop)
+ decoder_output += MicroLdStOpConstructor.subst(iop)
+ exec_output += MicroLeaExecute.subst(iop)
+
+ class TiaOp(LdStOp):
+ def __init__(self, segment, addr, disp = 0,
+ dataSize="env.dataSize",
+ addressSize="env.addressSize"):
+ super(TiaOp, self).__init__("NUM_INTREGS", segment,
+ addr, disp, dataSize, addressSize, "0", False, False)
+ self.className = "Tia"
+ self.mnemonic = "tia"
+
+ microopClasses["tia"] = TiaOp
+
+ class CdaOp(LdStOp):
+ def __init__(self, segment, addr, disp = 0,
+ dataSize="env.dataSize",
+ addressSize="env.addressSize", atCPL0=False):
+ super(CdaOp, self).__init__("NUM_INTREGS", segment,
+ addr, disp, dataSize, addressSize, "0", atCPL0, False)
+ self.className = "Cda"
+ self.mnemonic = "cda"
+
+ microopClasses["cda"] = CdaOp
}};