ARM: Clean up the ISA desc portion of the ARM memory instructions.
This commit is contained in:
parent
ef3a3dc28a
commit
d1362d582a
4 changed files with 585 additions and 649 deletions
|
@ -43,285 +43,265 @@ let {{
|
|||
decoder_output = ""
|
||||
exec_output = ""
|
||||
|
||||
def loadImmClassName(post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
return memClassName("LOAD_IMM", post, add, writeback,
|
||||
size, sign, user)
|
||||
class LoadInst(LoadStoreInst):
|
||||
execBase = 'Load'
|
||||
|
||||
def loadRegClassName(post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
return memClassName("LOAD_REG", post, add, writeback,
|
||||
size, sign, user)
|
||||
def __init__(self, mnem, post, add, writeback,
|
||||
size=4, sign=False, user=False, flavor="normal"):
|
||||
super(LoadInst, self).__init__()
|
||||
|
||||
self.name = mnem
|
||||
self.post = post
|
||||
self.add = add
|
||||
self.writeback = writeback
|
||||
self.size = size
|
||||
self.sign = sign
|
||||
self.user = user
|
||||
self.flavor = flavor
|
||||
|
||||
if self.add:
|
||||
self.op = " +"
|
||||
else:
|
||||
self.op = " -"
|
||||
|
||||
self.memFlags = ["ArmISA::TLB::MustBeOne"]
|
||||
self.codeBlobs = {"postacc_code" : ""}
|
||||
|
||||
def emitHelper(self, base = 'Memory'):
|
||||
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
codeBlobs = self.codeBlobs
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
|
||||
self.memFlags, [], base)
|
||||
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
class RfeInst(LoadInst):
|
||||
decConstBase = 'Rfe'
|
||||
|
||||
def __init__(self, mnem, post, add, writeback):
|
||||
super(RfeInst, self).__init__(mnem, post, add, writeback)
|
||||
self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
|
||||
|
||||
self.memFlags.append("ArmISA::TLB::AlignWord")
|
||||
|
||||
def emit(self):
|
||||
offset = 0
|
||||
if self.post != self.add:
|
||||
offset += 4
|
||||
if not self.add:
|
||||
offset -= 8
|
||||
self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset
|
||||
|
||||
wbDiff = -8
|
||||
if self.add:
|
||||
wbDiff = 8
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
SCTLR sctlr = Sctlr;
|
||||
NPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
|
||||
uint32_t newCpsr =
|
||||
cpsrWriteByInstr(cpsr | CondCodes,
|
||||
cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
|
||||
0xF, true, sctlr.nmfi);
|
||||
Cpsr = ~CondCodesMask & newCpsr;
|
||||
CondCodes = CondCodesMask & newCpsr;
|
||||
'''
|
||||
if self.writeback:
|
||||
accCode += "Base = Base + %s;\n" % wbDiff
|
||||
self.codeBlobs["memacc_code"] = accCode
|
||||
|
||||
self.emitHelper('RfeOp')
|
||||
|
||||
class LoadImmInst(LoadInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(LoadImmInst, self).__init__(*args, **kargs)
|
||||
self.offset = self.op + " imm"
|
||||
|
||||
class LoadRegInst(LoadInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(LoadRegInst, self).__init__(*args, **kargs)
|
||||
self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
|
||||
class LoadSingle(LoadInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(LoadSingle, self).__init__(*args, **kargs)
|
||||
|
||||
# Build the default class name
|
||||
self.Name = self.nameFunc(self.post, self.add, self.writeback,
|
||||
self.size, self.sign, self.user)
|
||||
|
||||
# Add memory request flags where necessary
|
||||
self.memFlags.append("%d" % (self.size - 1))
|
||||
if self.user:
|
||||
self.memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
if self.flavor == "prefetch":
|
||||
self.memFlags.append("Request::PREFETCH")
|
||||
elif self.flavor == "exclusive":
|
||||
self.memFlags.append("Request::LLSC")
|
||||
elif self.flavor == "normal":
|
||||
self.memFlags.append("ArmISA::TLB::AllowUnaligned")
|
||||
|
||||
# Disambiguate the class name for different flavors of loads
|
||||
if self.flavor != "normal":
|
||||
self.Name = "%s_%s" % (self.name.upper(), self.Name)
|
||||
|
||||
def emit(self):
|
||||
# Address compuation code
|
||||
eaCode = "EA = Base"
|
||||
if not self.post:
|
||||
eaCode += self.offset
|
||||
eaCode += ";"
|
||||
self.codeBlobs["ea_code"] = eaCode
|
||||
|
||||
# Code that actually handles the access
|
||||
if self.flavor == "prefetch":
|
||||
accCode = 'uint64_t temp = Mem%s; temp = temp;'
|
||||
elif self.flavor == "fp":
|
||||
accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
|
||||
else:
|
||||
accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
|
||||
accCode = accCode % buildMemSuffix(self.sign, self.size)
|
||||
|
||||
if self.writeback:
|
||||
accCode += "Base = Base %s;\n" % self.offset
|
||||
|
||||
self.codeBlobs["memacc_code"] = accCode
|
||||
|
||||
# Push it out to the output files
|
||||
base = buildMemBase(self.basePrefix, self.post, self.writeback)
|
||||
self.emitHelper(base)
|
||||
|
||||
def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
|
||||
return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
|
||||
|
||||
class LoadImm(LoadImmInst, LoadSingle):
|
||||
decConstBase = 'LoadStoreImm'
|
||||
basePrefix = 'MemoryImm'
|
||||
nameFunc = staticmethod(loadImmClassName)
|
||||
|
||||
def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
|
||||
return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
|
||||
|
||||
class LoadReg(LoadRegInst, LoadSingle):
|
||||
decConstBase = 'LoadStoreReg'
|
||||
basePrefix = 'MemoryReg'
|
||||
nameFunc = staticmethod(loadRegClassName)
|
||||
|
||||
class LoadDouble(LoadInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(LoadDouble, self).__init__(*args, **kargs)
|
||||
|
||||
# Build the default class name
|
||||
self.Name = self.nameFunc(self.post, self.add, self.writeback)
|
||||
|
||||
# Add memory request flags where necessary
|
||||
if self.flavor == "exclusive":
|
||||
self.memFlags.append("Request::LLSC")
|
||||
self.memFlags.append("ArmISA::TLB::AlignWord")
|
||||
|
||||
# Disambiguate the class name for different flavors of loads
|
||||
if self.flavor != "normal":
|
||||
self.Name = "%s_%s" % (self.name.upper(), self.Name)
|
||||
|
||||
def emit(self):
|
||||
# Address computation code
|
||||
eaCode = "EA = Base"
|
||||
if not self.post:
|
||||
eaCode += self.offset
|
||||
eaCode += ";"
|
||||
self.codeBlobs["ea_code"] = eaCode
|
||||
|
||||
# Code that actually handles the access
|
||||
if self.flavor != "fp":
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
|
||||
Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
|
||||
'''
|
||||
else:
|
||||
accCode = '''
|
||||
uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
|
||||
FpDest.uw = (uint32_t)swappedMem;
|
||||
FpDest2.uw = (uint32_t)(swappedMem >> 32);
|
||||
'''
|
||||
|
||||
if self.writeback:
|
||||
accCode += "Base = Base %s;\n" % self.offset
|
||||
|
||||
self.codeBlobs["memacc_code"] = accCode
|
||||
|
||||
# Push it out to the output files
|
||||
base = buildMemBase(self.basePrefix, self.post, self.writeback)
|
||||
self.emitHelper(base)
|
||||
|
||||
def loadDoubleImmClassName(post, add, writeback):
|
||||
return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
|
||||
|
||||
class LoadDoubleImm(LoadImmInst, LoadDouble):
|
||||
decConstBase = 'LoadStoreDImm'
|
||||
basePrefix = 'MemoryDImm'
|
||||
nameFunc = staticmethod(loadDoubleImmClassName)
|
||||
|
||||
def loadDoubleRegClassName(post, add, writeback):
|
||||
return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
|
||||
|
||||
def emitLoad(name, Name, imm, eaCode, accCode, \
|
||||
memFlags, instFlags, base, double=False):
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = loadStoreBase(name, Name, imm,
|
||||
eaCode, accCode, "",
|
||||
memFlags, instFlags, double, False,
|
||||
base, execTemplateBase = 'Load')
|
||||
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
def buildImmLoad(mnem, post, add, writeback, \
|
||||
size=4, sign=False, user=False, \
|
||||
prefetch=False, ldrex=False, vldr=False):
|
||||
name = mnem
|
||||
Name = loadImmClassName(post, add, writeback, \
|
||||
size, sign, user)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " imm"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
|
||||
if user:
|
||||
memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
if prefetch:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
memFlags.append("Request::PREFETCH")
|
||||
accCode = '''
|
||||
uint64_t temp = Mem%s;\n
|
||||
temp = temp;
|
||||
''' % buildMemSuffix(sign, size)
|
||||
elif vldr:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n" % \
|
||||
buildMemSuffix(sign, size)
|
||||
else:
|
||||
if ldrex:
|
||||
memFlags.append("Request::LLSC")
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \
|
||||
buildMemSuffix(sign, size)
|
||||
|
||||
if not prefetch and not ldrex and not vldr:
|
||||
memFlags.append("ArmISA::TLB::AllowUnaligned")
|
||||
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryImm", post, writeback)
|
||||
|
||||
emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base)
|
||||
|
||||
def buildRfeLoad(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
|
||||
|
||||
offset = 0
|
||||
if post != add:
|
||||
offset += 4
|
||||
if not add:
|
||||
offset -= 8
|
||||
|
||||
eaCode = "EA = Base + %d;" % offset
|
||||
|
||||
wbDiff = -8
|
||||
if add:
|
||||
wbDiff = 8
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
SCTLR sctlr = Sctlr;
|
||||
NPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
|
||||
uint32_t newCpsr =
|
||||
cpsrWriteByInstr(cpsr | CondCodes,
|
||||
cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
|
||||
0xF, true, sctlr.nmfi);
|
||||
Cpsr = ~CondCodesMask & newCpsr;
|
||||
CondCodes = CondCodesMask & newCpsr;
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "Base = Base + %s;\n" % wbDiff
|
||||
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = RfeBase(name, Name, eaCode, accCode,
|
||||
["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [])
|
||||
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
def buildRegLoad(mnem, post, add, writeback, size=4, sign=False, \
|
||||
user=False, prefetch=False):
|
||||
name = mnem
|
||||
Name = loadRegClassName(post, add, writeback,
|
||||
size, sign, user)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
memFlags = ["%d" % (size - 1), "ArmISA::TLB::MustBeOne"]
|
||||
if user:
|
||||
memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
if prefetch:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
memFlags.append("Request::PREFETCH")
|
||||
accCode = '''
|
||||
uint64_t temp = Mem%s;\n
|
||||
temp = temp;
|
||||
''' % buildMemSuffix(sign, size)
|
||||
else:
|
||||
accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \
|
||||
buildMemSuffix(sign, size)
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
|
||||
if not prefetch:
|
||||
memFlags.append("ArmISA::TLB::AllowUnaligned")
|
||||
|
||||
base = buildMemBase("MemoryReg", post, writeback)
|
||||
|
||||
emitLoad(name, Name, False, eaCode, accCode, \
|
||||
memFlags, [], base)
|
||||
|
||||
def buildDoubleImmLoad(mnem, post, add, writeback, \
|
||||
ldrex=False, vldr=False):
|
||||
name = mnem
|
||||
Name = loadDoubleImmClassName(post, add, writeback)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " imm"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
if not vldr:
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
|
||||
Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
|
||||
'''
|
||||
else:
|
||||
accCode = '''
|
||||
uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
|
||||
FpDest.uw = (uint32_t)swappedMem;
|
||||
FpDest2.uw = (uint32_t)(swappedMem >> 32);
|
||||
'''
|
||||
if ldrex:
|
||||
memFlags = ["Request::LLSC"]
|
||||
else:
|
||||
memFlags = []
|
||||
if ldrex or vldr:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryDImm", post, writeback)
|
||||
|
||||
memFlags.extend(["ArmISA::TLB::MustBeOne",
|
||||
"ArmISA::TLB::AlignWord"])
|
||||
|
||||
emitLoad(name, Name, True, eaCode, accCode, \
|
||||
memFlags, [], base, double=True)
|
||||
|
||||
def buildDoubleRegLoad(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
Name = loadDoubleRegClassName(post, add, writeback)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
|
||||
Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryDReg", post, writeback)
|
||||
|
||||
emitLoad(name, Name, False, eaCode, accCode,
|
||||
["ArmISA::TLB::MustBeOne", "ArmISA::TLB::AlignWord"],
|
||||
[], base, double=True)
|
||||
class LoadDoubleReg(LoadRegInst, LoadDouble):
|
||||
decConstBase = 'LoadStoreDReg'
|
||||
basePrefix = 'MemoryDReg'
|
||||
nameFunc = staticmethod(loadDoubleRegClassName)
|
||||
|
||||
def buildLoads(mnem, size=4, sign=False, user=False):
|
||||
buildImmLoad(mnem, True, True, True, size, sign, user)
|
||||
buildRegLoad(mnem, True, True, True, size, sign, user)
|
||||
buildImmLoad(mnem, True, False, True, size, sign, user)
|
||||
buildRegLoad(mnem, True, False, True, size, sign, user)
|
||||
buildImmLoad(mnem, False, True, True, size, sign, user)
|
||||
buildRegLoad(mnem, False, True, True, size, sign, user)
|
||||
buildImmLoad(mnem, False, False, True, size, sign, user)
|
||||
buildRegLoad(mnem, False, False, True, size, sign, user)
|
||||
buildImmLoad(mnem, False, True, False, size, sign, user)
|
||||
buildRegLoad(mnem, False, True, False, size, sign, user)
|
||||
buildImmLoad(mnem, False, False, False, size, sign, user)
|
||||
buildRegLoad(mnem, False, False, False, size, sign, user)
|
||||
LoadImm(mnem, True, True, True, size, sign, user).emit()
|
||||
LoadReg(mnem, True, True, True, size, sign, user).emit()
|
||||
LoadImm(mnem, True, False, True, size, sign, user).emit()
|
||||
LoadReg(mnem, True, False, True, size, sign, user).emit()
|
||||
LoadImm(mnem, False, True, True, size, sign, user).emit()
|
||||
LoadReg(mnem, False, True, True, size, sign, user).emit()
|
||||
LoadImm(mnem, False, False, True, size, sign, user).emit()
|
||||
LoadReg(mnem, False, False, True, size, sign, user).emit()
|
||||
LoadImm(mnem, False, True, False, size, sign, user).emit()
|
||||
LoadReg(mnem, False, True, False, size, sign, user).emit()
|
||||
LoadImm(mnem, False, False, False, size, sign, user).emit()
|
||||
LoadReg(mnem, False, False, False, size, sign, user).emit()
|
||||
|
||||
def buildDoubleLoads(mnem):
|
||||
buildDoubleImmLoad(mnem, True, True, True)
|
||||
buildDoubleRegLoad(mnem, True, True, True)
|
||||
buildDoubleImmLoad(mnem, True, False, True)
|
||||
buildDoubleRegLoad(mnem, True, False, True)
|
||||
buildDoubleImmLoad(mnem, False, True, True)
|
||||
buildDoubleRegLoad(mnem, False, True, True)
|
||||
buildDoubleImmLoad(mnem, False, False, True)
|
||||
buildDoubleRegLoad(mnem, False, False, True)
|
||||
buildDoubleImmLoad(mnem, False, True, False)
|
||||
buildDoubleRegLoad(mnem, False, True, False)
|
||||
buildDoubleImmLoad(mnem, False, False, False)
|
||||
buildDoubleRegLoad(mnem, False, False, False)
|
||||
LoadDoubleImm(mnem, True, True, True).emit()
|
||||
LoadDoubleReg(mnem, True, True, True).emit()
|
||||
LoadDoubleImm(mnem, True, False, True).emit()
|
||||
LoadDoubleReg(mnem, True, False, True).emit()
|
||||
LoadDoubleImm(mnem, False, True, True).emit()
|
||||
LoadDoubleReg(mnem, False, True, True).emit()
|
||||
LoadDoubleImm(mnem, False, False, True).emit()
|
||||
LoadDoubleReg(mnem, False, False, True).emit()
|
||||
LoadDoubleImm(mnem, False, True, False).emit()
|
||||
LoadDoubleReg(mnem, False, True, False).emit()
|
||||
LoadDoubleImm(mnem, False, False, False).emit()
|
||||
LoadDoubleReg(mnem, False, False, False).emit()
|
||||
|
||||
def buildRfeLoads(mnem):
|
||||
buildRfeLoad(mnem, True, True, True)
|
||||
buildRfeLoad(mnem, True, True, False)
|
||||
buildRfeLoad(mnem, True, False, True)
|
||||
buildRfeLoad(mnem, True, False, False)
|
||||
buildRfeLoad(mnem, False, True, True)
|
||||
buildRfeLoad(mnem, False, True, False)
|
||||
buildRfeLoad(mnem, False, False, True)
|
||||
buildRfeLoad(mnem, False, False, False)
|
||||
RfeInst(mnem, True, True, True).emit()
|
||||
RfeInst(mnem, True, True, False).emit()
|
||||
RfeInst(mnem, True, False, True).emit()
|
||||
RfeInst(mnem, True, False, False).emit()
|
||||
RfeInst(mnem, False, True, True).emit()
|
||||
RfeInst(mnem, False, True, False).emit()
|
||||
RfeInst(mnem, False, False, True).emit()
|
||||
RfeInst(mnem, False, False, False).emit()
|
||||
|
||||
def buildPrefetches(mnem):
|
||||
buildRegLoad(mnem, False, False, False, size=1, prefetch=True)
|
||||
buildImmLoad(mnem, False, False, False, size=1, prefetch=True)
|
||||
buildRegLoad(mnem, False, True, False, size=1, prefetch=True)
|
||||
buildImmLoad(mnem, False, True, False, size=1, prefetch=True)
|
||||
LoadReg(mnem, False, False, False, size=1, flavor="prefetch").emit()
|
||||
LoadImm(mnem, False, False, False, size=1, flavor="prefetch").emit()
|
||||
LoadReg(mnem, False, True, False, size=1, flavor="prefetch").emit()
|
||||
LoadImm(mnem, False, True, False, size=1, flavor="prefetch").emit()
|
||||
|
||||
buildLoads("ldr")
|
||||
buildLoads("ldrt", user=True)
|
||||
|
@ -342,13 +322,13 @@ let {{
|
|||
buildPrefetches("pldw")
|
||||
buildPrefetches("pli")
|
||||
|
||||
buildImmLoad("ldrex", False, True, False, size=4, ldrex=True)
|
||||
buildImmLoad("ldrexh", False, True, False, size=2, ldrex=True)
|
||||
buildImmLoad("ldrexb", False, True, False, size=1, ldrex=True)
|
||||
buildDoubleImmLoad("ldrexd", False, True, False, ldrex=True)
|
||||
LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
|
||||
LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
|
||||
LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
|
||||
LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
|
||||
|
||||
buildImmLoad("vldr", False, True, False, size=4, vldr=True)
|
||||
buildImmLoad("vldr", False, False, False, size=4, vldr=True)
|
||||
buildDoubleImmLoad("vldr", False, True, False, vldr=True)
|
||||
buildDoubleImmLoad("vldr", False, False, False, vldr=True)
|
||||
LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
|
||||
LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
|
||||
LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
|
||||
LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
|
||||
}};
|
||||
|
|
|
@ -38,64 +38,38 @@
|
|||
// Authors: Gabe Black
|
||||
|
||||
let {{
|
||||
def loadStoreBaseWork(name, Name, imm, swp, rfe, srs, codeBlobs,
|
||||
memFlags, instFlags, double, strex,
|
||||
base = 'Memory', execTemplateBase = ''):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
memFlags = makeList(memFlags)
|
||||
instFlags = makeList(instFlags)
|
||||
|
||||
eaCode = codeBlobs["ea_code"]
|
||||
class LoadStoreInst(object):
|
||||
def __init__(self):
|
||||
self.fullExecTemplate = eval(self.execBase + 'Execute')
|
||||
self.initiateAccTemplate = eval(self.execBase + 'InitiateAcc')
|
||||
self.completeAccTemplate = eval(self.execBase + 'CompleteAcc')
|
||||
self.declareTemplate = eval(self.decConstBase + 'Declare')
|
||||
self.constructTemplate = eval(self.decConstBase + 'Constructor')
|
||||
|
||||
# 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 = '
|
||||
eaCode += (string.join(memFlags, '|') + ';')
|
||||
def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags,
|
||||
base = 'Memory'):
|
||||
# Make sure flags are in lists (convert to lists if not).
|
||||
memFlags = makeList(memFlags)
|
||||
instFlags = makeList(instFlags)
|
||||
|
||||
codeBlobs["ea_code"] = eaCode
|
||||
eaCode = codeBlobs["ea_code"]
|
||||
|
||||
iop = InstObjParams(name, Name, base, codeBlobs, instFlags)
|
||||
# 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 = '
|
||||
eaCode += (string.join(memFlags, '|') + ';')
|
||||
|
||||
fullExecTemplate = eval(execTemplateBase + 'Execute')
|
||||
initiateAccTemplate = eval(execTemplateBase + 'InitiateAcc')
|
||||
completeAccTemplate = eval(execTemplateBase + 'CompleteAcc')
|
||||
codeBlobs["ea_code"] = eaCode
|
||||
|
||||
if swp:
|
||||
declareTemplate = SwapDeclare
|
||||
constructTemplate = SwapConstructor
|
||||
elif rfe:
|
||||
declareTemplate = RfeDeclare
|
||||
constructTemplate = RfeConstructor
|
||||
elif srs:
|
||||
declareTemplate = SrsDeclare
|
||||
constructTemplate = SrsConstructor
|
||||
elif imm:
|
||||
if double:
|
||||
declareTemplate = LoadStoreDImmDeclare
|
||||
constructTemplate = LoadStoreDImmConstructor
|
||||
if strex:
|
||||
declareTemplate = StoreExDImmDeclare
|
||||
constructTemplate = StoreExDImmConstructor
|
||||
elif strex:
|
||||
declareTemplate = StoreExImmDeclare
|
||||
constructTemplate = StoreExImmConstructor
|
||||
else:
|
||||
declareTemplate = LoadStoreImmDeclare
|
||||
constructTemplate = LoadStoreImmConstructor
|
||||
else:
|
||||
if double:
|
||||
declareTemplate = LoadStoreDRegDeclare
|
||||
constructTemplate = LoadStoreDRegConstructor
|
||||
else:
|
||||
declareTemplate = LoadStoreRegDeclare
|
||||
constructTemplate = LoadStoreRegConstructor
|
||||
iop = InstObjParams(name, Name, base, codeBlobs, instFlags)
|
||||
|
||||
# (header_output, decoder_output, decode_block, exec_output)
|
||||
return (declareTemplate.subst(iop),
|
||||
constructTemplate.subst(iop),
|
||||
fullExecTemplate.subst(iop)
|
||||
+ initiateAccTemplate.subst(iop)
|
||||
+ completeAccTemplate.subst(iop))
|
||||
# (header_output, decoder_output, decode_block, exec_output)
|
||||
return (self.declareTemplate.subst(iop),
|
||||
self.constructTemplate.subst(iop),
|
||||
self.fullExecTemplate.subst(iop)
|
||||
+ self.initiateAccTemplate.subst(iop)
|
||||
+ self.completeAccTemplate.subst(iop))
|
||||
|
||||
def pickPredicate(blobs):
|
||||
for val in blobs.values():
|
||||
|
@ -103,75 +77,21 @@ let {{
|
|||
return condPredicateTest
|
||||
return predicateTest
|
||||
|
||||
def loadStoreBase(name, Name, imm, eaCode, accCode, postAccCode,
|
||||
memFlags, instFlags, double, strex, base = 'Memory',
|
||||
execTemplateBase = ''):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode,
|
||||
"postacc_code": postAccCode }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
return loadStoreBaseWork(name, Name, imm, False, False, False,
|
||||
codeBlobs, memFlags, instFlags, double,
|
||||
strex, base, execTemplateBase)
|
||||
|
||||
def RfeBase(name, Name, eaCode, accCode, memFlags, instFlags):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
return loadStoreBaseWork(name, Name, False, False, True, False,
|
||||
codeBlobs, memFlags, instFlags, False, False,
|
||||
'RfeOp', 'Load')
|
||||
|
||||
def SrsBase(name, Name, eaCode, accCode, memFlags, instFlags):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode,
|
||||
"postacc_code": "" }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
return loadStoreBaseWork(name, Name, False, False, False, True,
|
||||
codeBlobs, memFlags, instFlags, False, False,
|
||||
'SrsOp', 'Store')
|
||||
|
||||
def SwapBase(name, Name, eaCode, preAccCode, postAccCode, memFlags,
|
||||
instFlags):
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"preacc_code": preAccCode,
|
||||
"postacc_code": postAccCode }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
return loadStoreBaseWork(name, Name, False, True, False, False,
|
||||
codeBlobs, memFlags, instFlags, False, False,
|
||||
'Swap', 'Swap')
|
||||
|
||||
def memClassName(base, post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
Name = base
|
||||
|
||||
if post:
|
||||
Name += '_PY'
|
||||
else:
|
||||
Name += '_PN'
|
||||
parts = { "P" : post, "A" : add, "W" : writeback,
|
||||
"S" : sign, "U" : user }
|
||||
|
||||
if add:
|
||||
Name += '_AY'
|
||||
else:
|
||||
Name += '_AN'
|
||||
|
||||
if writeback:
|
||||
Name += '_WY'
|
||||
else:
|
||||
Name += '_WN'
|
||||
for (letter, val) in parts.items():
|
||||
if val:
|
||||
Name += "_%sY" % letter
|
||||
else:
|
||||
Name += "_%sN" % letter
|
||||
|
||||
Name += ('_SZ%d' % size)
|
||||
|
||||
if sign:
|
||||
Name += '_SY'
|
||||
else:
|
||||
Name += '_SN'
|
||||
|
||||
if user:
|
||||
Name += '_UY'
|
||||
else:
|
||||
Name += '_UN'
|
||||
|
||||
return Name
|
||||
|
||||
def buildMemSuffix(sign, size):
|
||||
|
@ -188,7 +108,7 @@ let {{
|
|||
else:
|
||||
memSuffix = '.ub'
|
||||
else:
|
||||
raise Exception, "Unrecognized size for load %d" % size
|
||||
raise Exception, "Unrecognized size for access %d" % size
|
||||
|
||||
return memSuffix
|
||||
|
||||
|
|
|
@ -43,273 +43,290 @@ let {{
|
|||
decoder_output = ""
|
||||
exec_output = ""
|
||||
|
||||
def storeImmClassName(post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
return memClassName("STORE_IMM", post, add, writeback,
|
||||
size, sign, user)
|
||||
class StoreInst(LoadStoreInst):
|
||||
execBase = 'Store'
|
||||
|
||||
def storeRegClassName(post, add, writeback, \
|
||||
size=4, sign=False, user=False):
|
||||
return memClassName("STORE_REG", post, add, writeback,
|
||||
size, sign, user)
|
||||
def __init__(self, mnem, post, add, writeback, size=4,
|
||||
sign=False, user=False, flavor="normal"):
|
||||
super(StoreInst, self).__init__()
|
||||
|
||||
def storeDoubleImmClassName(post, add, writeback):
|
||||
return memClassName("STORE_IMMD", post, add, writeback,
|
||||
4, False, False)
|
||||
self.name = mnem
|
||||
self.post = post
|
||||
self.add = add
|
||||
self.writeback = writeback
|
||||
self.size = size
|
||||
self.sign = sign
|
||||
self.user = user
|
||||
self.flavor = flavor
|
||||
|
||||
def storeDoubleRegClassName(post, add, writeback):
|
||||
return memClassName("STORE_REGD", post, add, writeback,
|
||||
4, False, False)
|
||||
|
||||
def emitStore(name, Name, imm, eaCode, accCode, postAccCode, \
|
||||
memFlags, instFlags, base, double=False, strex=False,
|
||||
execTemplateBase = 'Store'):
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = loadStoreBase(name, Name, imm,
|
||||
eaCode, accCode, postAccCode,
|
||||
memFlags, instFlags, double, strex,
|
||||
base, execTemplateBase = execTemplateBase)
|
||||
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
def buildImmStore(mnem, post, add, writeback, \
|
||||
size=4, sign=False, user=False, \
|
||||
strex=False, vstr=False):
|
||||
name = mnem
|
||||
Name = storeImmClassName(post, add, writeback, \
|
||||
size, sign, user)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " imm"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
if vstr:
|
||||
accCode = '''
|
||||
Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);
|
||||
''' % { "suffix" : buildMemSuffix(sign, size) }
|
||||
else:
|
||||
accCode = '''
|
||||
Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);
|
||||
''' % { "suffix" : buildMemSuffix(sign, size) }
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
|
||||
memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
|
||||
if user:
|
||||
memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
if strex:
|
||||
memFlags.append("Request::LLSC")
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
base = buildMemBase("MemoryExImm", post, writeback)
|
||||
postAccCode = "Result = !writeResult;"
|
||||
execTemplateBase = 'StoreEx'
|
||||
else:
|
||||
if vstr:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
if self.add:
|
||||
self.op = " +"
|
||||
else:
|
||||
memFlags.append("ArmISA::TLB::AllowUnaligned")
|
||||
base = buildMemBase("MemoryImm", post, writeback)
|
||||
postAccCode = ""
|
||||
execTemplateBase = 'Store'
|
||||
self.op = " -"
|
||||
|
||||
emitStore(name, Name, True, eaCode, accCode, postAccCode, \
|
||||
memFlags, [], base, strex=strex,
|
||||
execTemplateBase = execTemplateBase)
|
||||
self.memFlags = ["ArmISA::TLB::MustBeOne"]
|
||||
self.codeBlobs = { "postacc_code" : "" }
|
||||
|
||||
def buildSrsStore(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
|
||||
def emitHelper(self, base = 'Memory'):
|
||||
|
||||
offset = 0
|
||||
if post != add:
|
||||
offset += 4
|
||||
if not add:
|
||||
offset -= 8
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
eaCode = "EA = SpMode + %d;" % offset
|
||||
codeBlobs = self.codeBlobs
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
|
||||
self.memFlags, [], base)
|
||||
|
||||
wbDiff = -8
|
||||
if add:
|
||||
wbDiff = 8
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
|
||||
((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "SpMode = SpMode + %s;\n" % wbDiff
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
global header_output, decoder_output, exec_output
|
||||
class SrsInst(LoadStoreInst):
|
||||
execBase = 'Store'
|
||||
decConstBase = 'Srs'
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = SrsBase(name, Name, eaCode, accCode,
|
||||
["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [])
|
||||
def __init__(self, mnem, post, add, writeback):
|
||||
super(SrsInst, self).__init__()
|
||||
self.name = mnem
|
||||
self.post = post
|
||||
self.add = add
|
||||
self.writeback = writeback
|
||||
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
|
||||
|
||||
def buildRegStore(mnem, post, add, writeback, \
|
||||
size=4, sign=False, user=False, strex=False):
|
||||
name = mnem
|
||||
Name = storeRegClassName(post, add, writeback,
|
||||
size, sign, user)
|
||||
def emit(self):
|
||||
offset = 0
|
||||
if self.post != self.add:
|
||||
offset += 4
|
||||
if not self.add:
|
||||
offset -= 8
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
eaCode = "EA = SpMode + %d;" % offset
|
||||
|
||||
offset = op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \
|
||||
{ "suffix" : buildMemSuffix(sign, size) }
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryReg", post, writeback)
|
||||
|
||||
memFlags = ["ArmISA::TLB::MustBeOne", \
|
||||
"ArmISA::TLB::AllowUnaligned", \
|
||||
"%d" % (size - 1)]
|
||||
if user:
|
||||
memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
emitStore(name, Name, False, eaCode, accCode, "",\
|
||||
memFlags, [], base)
|
||||
|
||||
def buildDoubleImmStore(mnem, post, add, writeback, \
|
||||
strex=False, vstr=False):
|
||||
name = mnem
|
||||
Name = storeDoubleImmClassName(post, add, writeback)
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
|
||||
offset = op + " imm"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
|
||||
if vstr:
|
||||
accCode = '''
|
||||
uint64_t swappedMem = (uint64_t)FpDest.uw |
|
||||
((uint64_t)FpDest2.uw << 32);
|
||||
Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
|
||||
'''
|
||||
else:
|
||||
wbDiff = -8
|
||||
if self.add:
|
||||
wbDiff = 8
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
|
||||
((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
|
||||
Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
|
||||
((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
if self.writeback:
|
||||
accCode += "SpMode = SpMode + %s;\n" % wbDiff
|
||||
|
||||
memFlags = ["ArmISA::TLB::MustBeOne",
|
||||
"ArmISA::TLB::AlignWord"]
|
||||
if strex:
|
||||
memFlags.append("Request::LLSC")
|
||||
base = buildMemBase("MemoryExDImm", post, writeback)
|
||||
postAccCode = "Result = !writeResult;"
|
||||
else:
|
||||
base = buildMemBase("MemoryDImm", post, writeback)
|
||||
postAccCode = ""
|
||||
if vstr or strex:
|
||||
Name = "%s_%s" % (mnem.upper(), Name)
|
||||
global header_output, decoder_output, exec_output
|
||||
|
||||
emitStore(name, Name, True, eaCode, accCode, postAccCode, \
|
||||
memFlags, [], base, double=True, strex=strex)
|
||||
codeBlobs = { "ea_code": eaCode,
|
||||
"memacc_code": accCode,
|
||||
"postacc_code": "" }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
|
||||
def buildDoubleRegStore(mnem, post, add, writeback):
|
||||
name = mnem
|
||||
Name = storeDoubleRegClassName(post, add, writeback)
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
|
||||
["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [],
|
||||
base = 'SrsOp')
|
||||
|
||||
if add:
|
||||
op = " +"
|
||||
else:
|
||||
op = " -"
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
offset = op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
eaCode = "EA = Base"
|
||||
if not post:
|
||||
eaCode += offset
|
||||
eaCode += ";"
|
||||
class StoreImmInst(StoreInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreImmInst, self).__init__(*args, **kargs)
|
||||
self.offset = self.op + " imm"
|
||||
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
|
||||
((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
|
||||
'''
|
||||
if writeback:
|
||||
accCode += "Base = Base %s;\n" % offset
|
||||
base = buildMemBase("MemoryDReg", post, writeback)
|
||||
class StoreRegInst(StoreInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreRegInst, self).__init__(*args, **kargs)
|
||||
self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
|
||||
" shiftType, CondCodes<29:>)"
|
||||
|
||||
memFlags = ["ArmISA::TLB::MustBeOne",
|
||||
"ArmISA::TLB::AlignWord"]
|
||||
class StoreSingle(StoreInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreSingle, self).__init__(*args, **kargs)
|
||||
|
||||
emitStore(name, Name, False, eaCode, accCode, "", \
|
||||
memFlags, [], base, double=True)
|
||||
# Build the default class name
|
||||
self.Name = self.nameFunc(self.post, self.add, self.writeback,
|
||||
self.size, self.sign, self.user)
|
||||
|
||||
# Add memory request flags where necessary
|
||||
self.memFlags.append("%d" % (self.size - 1))
|
||||
if self.user:
|
||||
self.memFlags.append("ArmISA::TLB::UserMode")
|
||||
|
||||
if self.flavor == "exclusive":
|
||||
self.memFlags.append("Request::LLSC")
|
||||
elif self.flavor != "fp":
|
||||
self.memFlags.append("ArmISA::TLB::AllowUnaligned")
|
||||
|
||||
# Disambiguate the class name for different flavors of stores
|
||||
if self.flavor != "normal":
|
||||
self.Name = "%s_%s" % (self.name.upper(), self.Name)
|
||||
|
||||
def emit(self):
|
||||
# Address computation
|
||||
eaCode = "EA = Base"
|
||||
if not self.post:
|
||||
eaCode += self.offset
|
||||
eaCode += ";"
|
||||
self.codeBlobs["ea_code"] = eaCode
|
||||
|
||||
# Code that actually handles the access
|
||||
if self.flavor == "fp":
|
||||
accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);'
|
||||
else:
|
||||
accCode = \
|
||||
'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);'
|
||||
accCode = accCode % \
|
||||
{ "suffix" : buildMemSuffix(self.sign, self.size) }
|
||||
|
||||
if self.writeback:
|
||||
accCode += "Base = Base %s;\n" % self.offset
|
||||
|
||||
self.codeBlobs["memacc_code"] = accCode
|
||||
|
||||
# Push it out to the output files
|
||||
base = buildMemBase(self.basePrefix, self.post, self.writeback)
|
||||
self.emitHelper(base)
|
||||
|
||||
def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
|
||||
return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
|
||||
|
||||
class StoreImmEx(StoreImmInst, StoreSingle):
|
||||
execBase = 'StoreEx'
|
||||
decConstBase = 'StoreExImm'
|
||||
basePrefix = 'MemoryExImm'
|
||||
nameFunc = staticmethod(storeImmClassName)
|
||||
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreImmEx, self).__init__(*args, **kargs)
|
||||
self.codeBlobs["postacc_code"] = "Result = !writeResult;"
|
||||
|
||||
class StoreImm(StoreImmInst, StoreSingle):
|
||||
decConstBase = 'LoadStoreImm'
|
||||
basePrefix = 'MemoryImm'
|
||||
nameFunc = staticmethod(storeImmClassName)
|
||||
|
||||
def storeRegClassName(post, add, writeback, size=4, sign=False, user=False):
|
||||
return memClassName("STORE_REG", post, add, writeback, size, sign, user)
|
||||
|
||||
class StoreReg(StoreRegInst, StoreSingle):
|
||||
decConstBase = 'LoadStoreReg'
|
||||
basePrefix = 'MemoryReg'
|
||||
nameFunc = staticmethod(storeRegClassName)
|
||||
|
||||
class StoreDouble(StoreInst):
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreDouble, self).__init__(*args, **kargs)
|
||||
|
||||
# Build the default class name
|
||||
self.Name = self.nameFunc(self.post, self.add, self.writeback)
|
||||
|
||||
# Add memory request flags where necessary
|
||||
self.memFlags.append("ArmISA::TLB::AlignWord")
|
||||
if self.flavor == "exclusive":
|
||||
self.memFlags.append("Request::LLSC")
|
||||
|
||||
# Disambiguate the class name for different flavors of stores
|
||||
if self.flavor != "normal":
|
||||
self.Name = "%s_%s" % (self.name.upper(), self.Name)
|
||||
|
||||
def emit(self):
|
||||
# Address computation code
|
||||
eaCode = "EA = Base"
|
||||
if not self.post:
|
||||
eaCode += self.offset
|
||||
eaCode += ";"
|
||||
self.codeBlobs["ea_code"] = eaCode
|
||||
|
||||
# Code that actually handles the access
|
||||
if self.flavor == "fp":
|
||||
accCode = '''
|
||||
uint64_t swappedMem = (uint64_t)FpDest.uw |
|
||||
((uint64_t)FpDest2.uw << 32);
|
||||
Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
|
||||
'''
|
||||
else:
|
||||
accCode = '''
|
||||
CPSR cpsr = Cpsr;
|
||||
Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
|
||||
((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
|
||||
'''
|
||||
|
||||
if self.writeback:
|
||||
accCode += "Base = Base %s;\n" % self.offset
|
||||
|
||||
self.codeBlobs["memacc_code"] = accCode
|
||||
|
||||
# Push it out to the output files
|
||||
base = buildMemBase(self.basePrefix, self.post, self.writeback)
|
||||
self.emitHelper(base)
|
||||
|
||||
def storeDoubleImmClassName(post, add, writeback):
|
||||
return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
|
||||
|
||||
class StoreDoubleImmEx(StoreImmInst, StoreDouble):
|
||||
execBase = 'StoreEx'
|
||||
decConstBase = 'StoreExDImm'
|
||||
basePrefix = 'MemoryExDImm'
|
||||
nameFunc = staticmethod(storeDoubleImmClassName)
|
||||
|
||||
def __init__(self, *args, **kargs):
|
||||
super(StoreDoubleImmEx, self).__init__(*args, **kargs)
|
||||
self.codeBlobs["postacc_code"] = "Result = !writeResult;"
|
||||
|
||||
class StoreDoubleImm(StoreImmInst, StoreDouble):
|
||||
decConstBase = 'LoadStoreDImm'
|
||||
basePrefix = 'MemoryDImm'
|
||||
nameFunc = staticmethod(storeDoubleImmClassName)
|
||||
|
||||
def storeDoubleRegClassName(post, add, writeback):
|
||||
return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
|
||||
|
||||
class StoreDoubleReg(StoreRegInst, StoreDouble):
|
||||
decConstBase = 'LoadStoreDReg'
|
||||
basePrefix = 'MemoryDReg'
|
||||
nameFunc = staticmethod(storeDoubleRegClassName)
|
||||
|
||||
def buildStores(mnem, size=4, sign=False, user=False):
|
||||
buildImmStore(mnem, True, True, True, size, sign, user)
|
||||
buildRegStore(mnem, True, True, True, size, sign, user)
|
||||
buildImmStore(mnem, True, False, True, size, sign, user)
|
||||
buildRegStore(mnem, True, False, True, size, sign, user)
|
||||
buildImmStore(mnem, False, True, True, size, sign, user)
|
||||
buildRegStore(mnem, False, True, True, size, sign, user)
|
||||
buildImmStore(mnem, False, False, True, size, sign, user)
|
||||
buildRegStore(mnem, False, False, True, size, sign, user)
|
||||
buildImmStore(mnem, False, True, False, size, sign, user)
|
||||
buildRegStore(mnem, False, True, False, size, sign, user)
|
||||
buildImmStore(mnem, False, False, False, size, sign, user)
|
||||
buildRegStore(mnem, False, False, False, size, sign, user)
|
||||
StoreImm(mnem, True, True, True, size, sign, user).emit()
|
||||
StoreReg(mnem, True, True, True, size, sign, user).emit()
|
||||
StoreImm(mnem, True, False, True, size, sign, user).emit()
|
||||
StoreReg(mnem, True, False, True, size, sign, user).emit()
|
||||
StoreImm(mnem, False, True, True, size, sign, user).emit()
|
||||
StoreReg(mnem, False, True, True, size, sign, user).emit()
|
||||
StoreImm(mnem, False, False, True, size, sign, user).emit()
|
||||
StoreReg(mnem, False, False, True, size, sign, user).emit()
|
||||
StoreImm(mnem, False, True, False, size, sign, user).emit()
|
||||
StoreReg(mnem, False, True, False, size, sign, user).emit()
|
||||
StoreImm(mnem, False, False, False, size, sign, user).emit()
|
||||
StoreReg(mnem, False, False, False, size, sign, user).emit()
|
||||
|
||||
def buildDoubleStores(mnem):
|
||||
buildDoubleImmStore(mnem, True, True, True)
|
||||
buildDoubleRegStore(mnem, True, True, True)
|
||||
buildDoubleImmStore(mnem, True, False, True)
|
||||
buildDoubleRegStore(mnem, True, False, True)
|
||||
buildDoubleImmStore(mnem, False, True, True)
|
||||
buildDoubleRegStore(mnem, False, True, True)
|
||||
buildDoubleImmStore(mnem, False, False, True)
|
||||
buildDoubleRegStore(mnem, False, False, True)
|
||||
buildDoubleImmStore(mnem, False, True, False)
|
||||
buildDoubleRegStore(mnem, False, True, False)
|
||||
buildDoubleImmStore(mnem, False, False, False)
|
||||
buildDoubleRegStore(mnem, False, False, False)
|
||||
StoreDoubleImm(mnem, True, True, True).emit()
|
||||
StoreDoubleReg(mnem, True, True, True).emit()
|
||||
StoreDoubleImm(mnem, True, False, True).emit()
|
||||
StoreDoubleReg(mnem, True, False, True).emit()
|
||||
StoreDoubleImm(mnem, False, True, True).emit()
|
||||
StoreDoubleReg(mnem, False, True, True).emit()
|
||||
StoreDoubleImm(mnem, False, False, True).emit()
|
||||
StoreDoubleReg(mnem, False, False, True).emit()
|
||||
StoreDoubleImm(mnem, False, True, False).emit()
|
||||
StoreDoubleReg(mnem, False, True, False).emit()
|
||||
StoreDoubleImm(mnem, False, False, False).emit()
|
||||
StoreDoubleReg(mnem, False, False, False).emit()
|
||||
|
||||
def buildSrsStores(mnem):
|
||||
buildSrsStore(mnem, True, True, True)
|
||||
buildSrsStore(mnem, True, True, False)
|
||||
buildSrsStore(mnem, True, False, True)
|
||||
buildSrsStore(mnem, True, False, False)
|
||||
buildSrsStore(mnem, False, True, True)
|
||||
buildSrsStore(mnem, False, True, False)
|
||||
buildSrsStore(mnem, False, False, True)
|
||||
buildSrsStore(mnem, False, False, False)
|
||||
SrsInst(mnem, True, True, True).emit()
|
||||
SrsInst(mnem, True, True, False).emit()
|
||||
SrsInst(mnem, True, False, True).emit()
|
||||
SrsInst(mnem, True, False, False).emit()
|
||||
SrsInst(mnem, False, True, True).emit()
|
||||
SrsInst(mnem, False, True, False).emit()
|
||||
SrsInst(mnem, False, False, True).emit()
|
||||
SrsInst(mnem, False, False, False).emit()
|
||||
|
||||
buildStores("str")
|
||||
buildStores("strt", user=True)
|
||||
|
@ -322,13 +339,13 @@ let {{
|
|||
|
||||
buildDoubleStores("strd")
|
||||
|
||||
buildImmStore("strex", False, True, False, size=4, strex=True)
|
||||
buildImmStore("strexh", False, True, False, size=2, strex=True)
|
||||
buildImmStore("strexb", False, True, False, size=1, strex=True)
|
||||
buildDoubleImmStore("strexd", False, True, False, strex=True)
|
||||
StoreImmEx("strex", False, True, False, size=4, flavor="exclusive").emit()
|
||||
StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive").emit()
|
||||
StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive").emit()
|
||||
StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit()
|
||||
|
||||
buildImmStore("vstr", False, True, False, size=4, vstr=True)
|
||||
buildImmStore("vstr", False, False, False, size=4, vstr=True)
|
||||
buildDoubleImmStore("vstr", False, True, False, vstr=True)
|
||||
buildDoubleImmStore("vstr", False, False, False, vstr=True)
|
||||
StoreImm("vstr", False, True, False, size=4, flavor="fp").emit()
|
||||
StoreImm("vstr", False, False, False, size=4, flavor="fp").emit()
|
||||
StoreDoubleImm("vstr", False, True, False, flavor="fp").emit()
|
||||
StoreDoubleImm("vstr", False, False, False, flavor="fp").emit()
|
||||
}};
|
||||
|
|
|
@ -41,27 +41,46 @@ let {{
|
|||
|
||||
header_output = decoder_output = exec_output = ""
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = SwapBase("swp", "Swp", "EA = Base;",
|
||||
"Mem = cSwap(Op1.uw, ((CPSR)Cpsr).e);",
|
||||
"Dest = cSwap((uint32_t)memData, ((CPSR)Cpsr).e);",
|
||||
["Request::MEM_SWAP",
|
||||
"ArmISA::TLB::AlignWord",
|
||||
"ArmISA::TLB::MustBeOne"], [])
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
class SwapInst(LoadStoreInst):
|
||||
execBase = 'Swap'
|
||||
decConstBase = 'Swap'
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = SwapBase("swpb", "Swpb", "EA = Base;",
|
||||
"Mem.ub = cSwap(Op1.ub, ((CPSR)Cpsr).e);",
|
||||
"Dest.ub = cSwap((uint8_t)memData, ((CPSR)Cpsr).e);",
|
||||
["Request::MEM_SWAP",
|
||||
"ArmISA::TLB::AlignByte",
|
||||
"ArmISA::TLB::MustBeOne"], [])
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
def __init__(self, name, Name, eaCode,
|
||||
preAccCode, postAccCode, memFlags):
|
||||
super(SwapInst, self).__init__()
|
||||
self.name = name
|
||||
self.Name = Name
|
||||
self.eaCode = eaCode
|
||||
self.preAccCode = preAccCode
|
||||
self.postAccCode = postAccCode
|
||||
self.memFlags = memFlags
|
||||
|
||||
def emit(self):
|
||||
global header_output, decoder_output, exec_output
|
||||
codeBlobs = { "ea_code": self.eaCode,
|
||||
"preacc_code": self.preAccCode,
|
||||
"postacc_code": self.postAccCode }
|
||||
codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
|
||||
|
||||
(newHeader,
|
||||
newDecoder,
|
||||
newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
|
||||
self.memFlags, [], base = 'Swap')
|
||||
header_output += newHeader
|
||||
decoder_output += newDecoder
|
||||
exec_output += newExec
|
||||
|
||||
SwapInst('swp', 'Swp', 'EA = Base;',
|
||||
'Mem = cSwap(Op1.uw, ((CPSR)Cpsr).e);',
|
||||
'Dest = cSwap((uint32_t)memData, ((CPSR)Cpsr).e);',
|
||||
['Request::MEM_SWAP',
|
||||
'ArmISA::TLB::AlignWord',
|
||||
'ArmISA::TLB::MustBeOne']).emit()
|
||||
|
||||
SwapInst('swpb', 'Swpb', 'EA = Base;',
|
||||
'Mem.ub = cSwap(Op1.ub, ((CPSR)Cpsr).e);',
|
||||
'Dest.ub = cSwap((uint8_t)memData, ((CPSR)Cpsr).e);',
|
||||
['Request::MEM_SWAP',
|
||||
'ArmISA::TLB::AlignByte',
|
||||
'ArmISA::TLB::MustBeOne']).emit()
|
||||
}};
|
||||
|
|
Loading…
Reference in a new issue