From d1362d582a10c1207e4edb5792600d7ba6303cb6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 23 Aug 2010 11:18:40 -0500 Subject: [PATCH] ARM: Clean up the ISA desc portion of the ARM memory instructions. --- src/arch/arm/isa/insts/ldr.isa | 522 +++++++++++++++----------------- src/arch/arm/isa/insts/mem.isa | 146 ++------- src/arch/arm/isa/insts/str.isa | 503 +++++++++++++++--------------- src/arch/arm/isa/insts/swap.isa | 63 ++-- 4 files changed, 585 insertions(+), 649 deletions(-) diff --git a/src/arch/arm/isa/insts/ldr.isa b/src/arch/arm/isa/insts/ldr.isa index 093ff7a60..cc6b6351b 100644 --- a/src/arch/arm/isa/insts/ldr.isa +++ b/src/arch/arm/isa/insts/ldr.isa @@ -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(Mem.ud, cpsr.e); + uint32_t newCpsr = + cpsrWriteByInstr(cpsr | CondCodes, + cSwap(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(Mem.ud, cpsr.e); + Dest2 = cSwap(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(Mem.ud, cpsr.e); - uint32_t newCpsr = - cpsrWriteByInstr(cpsr | CondCodes, - cSwap(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(Mem.ud, cpsr.e); - Dest2 = cSwap(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(Mem.ud, cpsr.e); - Dest2 = cSwap(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() }}; diff --git a/src/arch/arm/isa/insts/mem.isa b/src/arch/arm/isa/insts/mem.isa index f5631a3b7..aa47d5b7f 100644 --- a/src/arch/arm/isa/insts/mem.isa +++ b/src/arch/arm/isa/insts/mem.isa @@ -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 diff --git a/src/arch/arm/isa/insts/str.isa b/src/arch/arm/isa/insts/str.isa index d86000947..589758529 100644 --- a/src/arch/arm/isa/insts/str.isa +++ b/src/arch/arm/isa/insts/str.isa @@ -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() }}; diff --git a/src/arch/arm/isa/insts/swap.isa b/src/arch/arm/isa/insts/swap.isa index 29b5b444f..c5c92c935 100644 --- a/src/arch/arm/isa/insts/swap.isa +++ b/src/arch/arm/isa/insts/swap.isa @@ -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() }};