amo64.isa revision 14150
114150Sjordi.vaquero@metempsy.com// -*- mode:c++ -*- 214150Sjordi.vaquero@metempsy.com 314150Sjordi.vaquero@metempsy.com// Copyright (c) 2018 Metempsy Technology Consulting 414150Sjordi.vaquero@metempsy.com// All rights reserved 514150Sjordi.vaquero@metempsy.com// 614150Sjordi.vaquero@metempsy.com// The license below extends only to copyright in the software and shall 714150Sjordi.vaquero@metempsy.com// not be construed as granting a license to any other intellectual 814150Sjordi.vaquero@metempsy.com// property including but not limited to intellectual property relating 914150Sjordi.vaquero@metempsy.com// to a hardware implementation of the functionality of the software 1014150Sjordi.vaquero@metempsy.com// licensed hereunder. You may use the software subject to the license 1114150Sjordi.vaquero@metempsy.com// terms below provided that you ensure that this notice is replicated 1214150Sjordi.vaquero@metempsy.com// unmodified and in its entirety in all distributions of the software, 1314150Sjordi.vaquero@metempsy.com// modified or unmodified, in source code or in binary form. 1414150Sjordi.vaquero@metempsy.com// 1514150Sjordi.vaquero@metempsy.com// Redistribution and use in source and binary forms, with or without 1614150Sjordi.vaquero@metempsy.com// modification, are permitted provided that the following conditions are 1714150Sjordi.vaquero@metempsy.com// met: redistributions of source code must retain the above copyright 1814150Sjordi.vaquero@metempsy.com// notice, this list of conditions and the following disclaimer; 1914150Sjordi.vaquero@metempsy.com// redistributions in binary form must reproduce the above copyright 2014150Sjordi.vaquero@metempsy.com// notice, this list of conditions and the following disclaimer in the 2114150Sjordi.vaquero@metempsy.com// documentation and/or other materials provided with the distribution; 2214150Sjordi.vaquero@metempsy.com// neither the name of the copyright holders nor the names of its 2314150Sjordi.vaquero@metempsy.com// contributors may be used to endorse or promote products derived from 2414150Sjordi.vaquero@metempsy.com// this software without specific prior written permission. 2514150Sjordi.vaquero@metempsy.com// 2614150Sjordi.vaquero@metempsy.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2714150Sjordi.vaquero@metempsy.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2814150Sjordi.vaquero@metempsy.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2914150Sjordi.vaquero@metempsy.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3014150Sjordi.vaquero@metempsy.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3114150Sjordi.vaquero@metempsy.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3214150Sjordi.vaquero@metempsy.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3314150Sjordi.vaquero@metempsy.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3414150Sjordi.vaquero@metempsy.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3514150Sjordi.vaquero@metempsy.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3614150Sjordi.vaquero@metempsy.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3714150Sjordi.vaquero@metempsy.com// 3814150Sjordi.vaquero@metempsy.com// Authors: Jordi Vaquero 3914150Sjordi.vaquero@metempsy.com 4014150Sjordi.vaquero@metempsy.comlet {{ 4114150Sjordi.vaquero@metempsy.com 4214150Sjordi.vaquero@metempsy.com import math 4314150Sjordi.vaquero@metempsy.com 4414150Sjordi.vaquero@metempsy.com OP_DICT = { "CAS" : 'if (a == *b){*b = c;}', 4514150Sjordi.vaquero@metempsy.com "SWP" : '*b = c;', 4614150Sjordi.vaquero@metempsy.com "ADD" : '*b += c;', 4714150Sjordi.vaquero@metempsy.com "EOR" : '*b ^= c;', 4814150Sjordi.vaquero@metempsy.com "CLR" : '*b &= ~c;', 4914150Sjordi.vaquero@metempsy.com "SET" : '*b |= c;', 5014150Sjordi.vaquero@metempsy.com "MAX" : '*b = std::max(*b, c);', 5114150Sjordi.vaquero@metempsy.com "MIN" : '*b = std::min(*b, c);', } 5214150Sjordi.vaquero@metempsy.com 5314150Sjordi.vaquero@metempsy.com MASKS = { 1: 0xFF, 5414150Sjordi.vaquero@metempsy.com 2: 0xFFFF, 5514150Sjordi.vaquero@metempsy.com 4: 0xFFFFFFFF, 5614150Sjordi.vaquero@metempsy.com 8: 0xFFFFFFFFFFFFFFFF, 5714150Sjordi.vaquero@metempsy.com } 5814150Sjordi.vaquero@metempsy.com 5914150Sjordi.vaquero@metempsy.com header_output = "" 6014150Sjordi.vaquero@metempsy.com decoder_output = "" 6114150Sjordi.vaquero@metempsy.com exec_output = "" 6214150Sjordi.vaquero@metempsy.com 6314150Sjordi.vaquero@metempsy.com class AtomicInst64(LoadStoreInst): 6414150Sjordi.vaquero@metempsy.com execBase = 'AtomicInst64' 6514150Sjordi.vaquero@metempsy.com micro = False 6614150Sjordi.vaquero@metempsy.com 6714150Sjordi.vaquero@metempsy.com def __init__(self, mnem, Name, size=4, user=False, flavor="normal", 6814150Sjordi.vaquero@metempsy.com unsign=True, top = False, paired=False): 6914150Sjordi.vaquero@metempsy.com super(AtomicInst64, self).__init__() 7014150Sjordi.vaquero@metempsy.com 7114150Sjordi.vaquero@metempsy.com self.name= mnem 7214150Sjordi.vaquero@metempsy.com self.Name = Name 7314150Sjordi.vaquero@metempsy.com self.size = size 7414150Sjordi.vaquero@metempsy.com self.user = user 7514150Sjordi.vaquero@metempsy.com self.flavor = flavor 7614150Sjordi.vaquero@metempsy.com self.unsign = unsign 7714150Sjordi.vaquero@metempsy.com self.top = top 7814150Sjordi.vaquero@metempsy.com self.paired = paired 7914150Sjordi.vaquero@metempsy.com 8014150Sjordi.vaquero@metempsy.com self.memFlags = ["ArmISA::TLB::MustBeOne"] 8114150Sjordi.vaquero@metempsy.com self.instFlags = ["IsAtomic"] 8214150Sjordi.vaquero@metempsy.com self.codeBlobs = { "postacc_code" : "" } 8314150Sjordi.vaquero@metempsy.com self.codeBlobs['usrDecl'] = "" 8414150Sjordi.vaquero@metempsy.com 8514150Sjordi.vaquero@metempsy.com # Add memory request flags where necessary 8614150Sjordi.vaquero@metempsy.com if self.user: 8714150Sjordi.vaquero@metempsy.com self.memFlags.append("ArmISA::TLB::UserMode") 8814150Sjordi.vaquero@metempsy.com 8914150Sjordi.vaquero@metempsy.com sz = self.size*2 if paired else self.size 9014150Sjordi.vaquero@metempsy.com self.memFlags.append("%d" % int(math.log(sz, 2))) 9114150Sjordi.vaquero@metempsy.com 9214150Sjordi.vaquero@metempsy.com if self.micro: 9314150Sjordi.vaquero@metempsy.com self.instFlags.append("IsMicroop") 9414150Sjordi.vaquero@metempsy.com 9514150Sjordi.vaquero@metempsy.com if self.flavor in ("release", "acquire_release", "acquire"): 9614150Sjordi.vaquero@metempsy.com self.instFlags.append("IsMemBarrier") 9714150Sjordi.vaquero@metempsy.com if self.flavor in ("release", "acquire_release"): 9814150Sjordi.vaquero@metempsy.com self.instFlags.append("IsWriteBarrier") 9914150Sjordi.vaquero@metempsy.com if self.flavor in ("acquire_release", "acquire"): 10014150Sjordi.vaquero@metempsy.com self.instFlags.append("IsReadBarrier") 10114150Sjordi.vaquero@metempsy.com self.memFlags.append('Request::ATOMIC_RETURN_OP') 10214150Sjordi.vaquero@metempsy.com 10314150Sjordi.vaquero@metempsy.com def emitHelper(self, base = 'Memory64', wbDecl = None, ): 10414150Sjordi.vaquero@metempsy.com global header_output, decoder_output, exec_output 10514150Sjordi.vaquero@metempsy.com 10614150Sjordi.vaquero@metempsy.com # If this is a microop itself, don't allow anything that would 10714150Sjordi.vaquero@metempsy.com # require further microcoding. 10814150Sjordi.vaquero@metempsy.com if self.micro: 10914150Sjordi.vaquero@metempsy.com assert not wbDecl 11014150Sjordi.vaquero@metempsy.com 11114150Sjordi.vaquero@metempsy.com fa_code = None 11214150Sjordi.vaquero@metempsy.com if not self.micro : 11314150Sjordi.vaquero@metempsy.com #and self.flavor in ("normal", "release"): 11414150Sjordi.vaquero@metempsy.com fa_code = ''' 11514150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SAS, %s); 11614150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SSE, false); 11714150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SRT, dest); 11814150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SF, %s); 11914150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::AR, %s); 12014150Sjordi.vaquero@metempsy.com ''' % ("0" if self.size == 1 else 12114150Sjordi.vaquero@metempsy.com "1" if self.size == 2 else 12214150Sjordi.vaquero@metempsy.com "2" if self.size == 4 else "3", 12314150Sjordi.vaquero@metempsy.com "true" if self.size == 8 else "false", 12414150Sjordi.vaquero@metempsy.com "true" if self.flavor != "normal" else "false") 12514150Sjordi.vaquero@metempsy.com sas_code = "3" 12614150Sjordi.vaquero@metempsy.com if self.size == 1 : 12714150Sjordi.vaquero@metempsy.com sas_code = "0" 12814150Sjordi.vaquero@metempsy.com elif self.size == 2: 12914150Sjordi.vaquero@metempsy.com sas_code = "1" 13014150Sjordi.vaquero@metempsy.com elif self.size == 4: 13114150Sjordi.vaquero@metempsy.com sas_code = "2" 13214150Sjordi.vaquero@metempsy.com 13314150Sjordi.vaquero@metempsy.com if self.paired and sas_code == "3": 13414150Sjordi.vaquero@metempsy.com sas_code = "4" 13514150Sjordi.vaquero@metempsy.com if self.paired and sas_code == "2": 13614150Sjordi.vaquero@metempsy.com sas_code = "3" 13714150Sjordi.vaquero@metempsy.com 13814150Sjordi.vaquero@metempsy.com 13914150Sjordi.vaquero@metempsy.com fa_code = ''' 14014150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SAS, %s); 14114150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SSE, %s); 14214150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SRT, dest); 14314150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::SF, %s); 14414150Sjordi.vaquero@metempsy.com fault->annotate(ArmFault::AR, %s); 14514150Sjordi.vaquero@metempsy.com ''' % (sas_code, 14614150Sjordi.vaquero@metempsy.com "true" if not self.unsign else "false", 14714150Sjordi.vaquero@metempsy.com "true" if self.size == 8 else "false", 14814150Sjordi.vaquero@metempsy.com "true" if self.flavor != "normal" else "false") 14914150Sjordi.vaquero@metempsy.com 15014150Sjordi.vaquero@metempsy.com (newHeader, newDecoder, newExec) = \ 15114150Sjordi.vaquero@metempsy.com self.fillTemplates(self.name, self.Name, self.codeBlobs, 15214150Sjordi.vaquero@metempsy.com self.memFlags, self.instFlags, 15314150Sjordi.vaquero@metempsy.com base, wbDecl, faCode=fa_code) 15414150Sjordi.vaquero@metempsy.com 15514150Sjordi.vaquero@metempsy.com header_output += newHeader 15614150Sjordi.vaquero@metempsy.com decoder_output += newDecoder 15714150Sjordi.vaquero@metempsy.com exec_output += newExec 15814150Sjordi.vaquero@metempsy.com 15914150Sjordi.vaquero@metempsy.com def buildEACode(self): 16014150Sjordi.vaquero@metempsy.com # Address computation 16114150Sjordi.vaquero@metempsy.com eaCode = SPAlignmentCheckCode + "EA = XBase" 16214150Sjordi.vaquero@metempsy.com if self.size == 16: 16314150Sjordi.vaquero@metempsy.com if self.top: 16414150Sjordi.vaquero@metempsy.com eaCode += " + (isBigEndian64(xc->tcBase()) ? 0 : 8)" 16514150Sjordi.vaquero@metempsy.com else: 16614150Sjordi.vaquero@metempsy.com eaCode += " + (isBigEndian64(xc->tcBase()) ? 8 : 0)" 16714150Sjordi.vaquero@metempsy.com if not self.post: 16814150Sjordi.vaquero@metempsy.com eaCode += self.offset 16914150Sjordi.vaquero@metempsy.com eaCode += ";" 17014150Sjordi.vaquero@metempsy.com self.codeBlobs["ea_code"] = eaCode 17114150Sjordi.vaquero@metempsy.com 17214150Sjordi.vaquero@metempsy.com 17314150Sjordi.vaquero@metempsy.com class AtomicSingleOp(AtomicInst64): 17414150Sjordi.vaquero@metempsy.com decConstBase = 'AmoOp' 17514150Sjordi.vaquero@metempsy.com base = 'ArmISA::MemoryEx64' 17614150Sjordi.vaquero@metempsy.com writeback = True 17714150Sjordi.vaquero@metempsy.com post = False 17814150Sjordi.vaquero@metempsy.com execBase = 'AmoOp' 17914150Sjordi.vaquero@metempsy.com 18014150Sjordi.vaquero@metempsy.com def __init__(self, *args, **kargs): 18114150Sjordi.vaquero@metempsy.com super(AtomicSingleOp, self).__init__(*args, **kargs) 18214150Sjordi.vaquero@metempsy.com self.suffix = buildMemSuffix(not self.unsign, self.size) 18314150Sjordi.vaquero@metempsy.com if self.size == 8: 18414150Sjordi.vaquero@metempsy.com self.res = 'XResult_ud' #if self.unsign else 'XResult_sd' 18514150Sjordi.vaquero@metempsy.com self.des = 'XDest_ud' #if self.unsign else 'XDest_sd' 18614150Sjordi.vaquero@metempsy.com self.tp = 'uint64_t' if self.unsign else 'int64_t' 18714150Sjordi.vaquero@metempsy.com self.utp = 'uint64_t' 18814150Sjordi.vaquero@metempsy.com self.suffix = '_sd' if not self.unsign else '_ud' 18914150Sjordi.vaquero@metempsy.com elif self.size == 4: 19014150Sjordi.vaquero@metempsy.com self.res = 'XResult_uw' #if self.unsign else 'XResult_sw' 19114150Sjordi.vaquero@metempsy.com self.des = 'XDest_uw' #if self.unsign else 'XDest_sw' 19214150Sjordi.vaquero@metempsy.com self.tp = 'uint32_t' if self.unsign else 'int32_t' 19314150Sjordi.vaquero@metempsy.com self.utp = 'uint32_t' 19414150Sjordi.vaquero@metempsy.com elif self.size == 2: 19514150Sjordi.vaquero@metempsy.com self.res = 'XResult_uh' #if self.unsign else 'XResult_sh' 19614150Sjordi.vaquero@metempsy.com self.des = 'XDest_uh' #if self.unsign else 'XDest_sh' 19714150Sjordi.vaquero@metempsy.com self.tp = 'uint16_t' if self.unsign else 'int16_t' 19814150Sjordi.vaquero@metempsy.com self.utp = 'uint16_t' 19914150Sjordi.vaquero@metempsy.com elif self.size == 1: 20014150Sjordi.vaquero@metempsy.com self.res = 'XResult_ub' #if self.unsign else 'XResult_sb' 20114150Sjordi.vaquero@metempsy.com self.des = 'XDest_ub' #if self.unsign else 'XDest_sb' 20214150Sjordi.vaquero@metempsy.com self.tp = 'uint8_t' if self.unsign else 'int8_t' 20314150Sjordi.vaquero@metempsy.com self.utp = 'uint8_t' 20414150Sjordi.vaquero@metempsy.com self.offset = "" 20514150Sjordi.vaquero@metempsy.com store_res = ''' 20614150Sjordi.vaquero@metempsy.com %(result)s = cSwap(Mem%(suffix)s, 20714150Sjordi.vaquero@metempsy.com isBigEndian64(xc->tcBase())); 20814150Sjordi.vaquero@metempsy.com ''' 20914150Sjordi.vaquero@metempsy.com store_res = store_res % {"result":self.res, "suffix":self.suffix} 21014150Sjordi.vaquero@metempsy.com self.codeBlobs["postacc_code"] = \ 21114150Sjordi.vaquero@metempsy.com store_res + " SevMailbox = 1; LLSCLock = 0;" 21214150Sjordi.vaquero@metempsy.com 21314150Sjordi.vaquero@metempsy.com def emit(self, op): 21414150Sjordi.vaquero@metempsy.com self.buildEACode() 21514150Sjordi.vaquero@metempsy.com usrDecl = "%(type)s valRs;\n" % {'type': self.tp} 21614150Sjordi.vaquero@metempsy.com self.codeBlobs['usrDecl'] = usrDecl 21714150Sjordi.vaquero@metempsy.com 21814150Sjordi.vaquero@metempsy.com opcode = "valRs = cSwap(%(dest)s,"\ 21914150Sjordi.vaquero@metempsy.com " isBigEndian64(xc->tcBase()));\n" 22014150Sjordi.vaquero@metempsy.com opcode += "TypedAtomicOpFunctor<%(type)s> *amo_op = "\ 22114150Sjordi.vaquero@metempsy.com "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\ 22214150Sjordi.vaquero@metempsy.com " valRs, [](%(type)s* b, %(type)s a,"\ 22314150Sjordi.vaquero@metempsy.com " %(type)s c){ %(op)s });\n" 22414150Sjordi.vaquero@metempsy.com 22514150Sjordi.vaquero@metempsy.com opcode = opcode % {"suffix": self.suffix, 22614150Sjordi.vaquero@metempsy.com "type": self.tp , 22714150Sjordi.vaquero@metempsy.com "dest": self.des, 22814150Sjordi.vaquero@metempsy.com "op": op} 22914150Sjordi.vaquero@metempsy.com self.codeBlobs['amo_code'] = opcode 23014150Sjordi.vaquero@metempsy.com accCode = "Mem%(suffix)s = cSwap(%(result)s,"\ 23114150Sjordi.vaquero@metempsy.com " isBigEndian64(xc->tcBase()));" 23214150Sjordi.vaquero@metempsy.com accCode = accCode % { "result": self.res, "type":self.tp, 23314150Sjordi.vaquero@metempsy.com "suffix": self.suffix} 23414150Sjordi.vaquero@metempsy.com self.codeBlobs["memacc_code"] = accCode 23514150Sjordi.vaquero@metempsy.com self.emitHelper(self.base) 23614150Sjordi.vaquero@metempsy.com 23714150Sjordi.vaquero@metempsy.com 23814150Sjordi.vaquero@metempsy.com AtomicSingleOp("cas", "CAS64", 8, unsign=True, 23914150Sjordi.vaquero@metempsy.com flavor="normal").emit(OP_DICT['CAS']) 24014150Sjordi.vaquero@metempsy.com AtomicSingleOp("casa", "CASA64", 8, unsign=True, 24114150Sjordi.vaquero@metempsy.com flavor="acquire").emit(OP_DICT['CAS']) 24214150Sjordi.vaquero@metempsy.com AtomicSingleOp("casal", "CASAL64", 8, unsign=True, 24314150Sjordi.vaquero@metempsy.com flavor="acquire_release").emit(OP_DICT['CAS']) 24414150Sjordi.vaquero@metempsy.com AtomicSingleOp("casl", "CASL64", 8, unsign=True, 24514150Sjordi.vaquero@metempsy.com flavor="release").emit(OP_DICT['CAS']) 24614150Sjordi.vaquero@metempsy.com 24714150Sjordi.vaquero@metempsy.com AtomicSingleOp("casb", "CASB", 1, unsign=True, 24814150Sjordi.vaquero@metempsy.com flavor="normal").emit(OP_DICT['CAS']) 24914150Sjordi.vaquero@metempsy.com AtomicSingleOp("casab", "CASAB", 1, unsign=True, 25014150Sjordi.vaquero@metempsy.com flavor="acquire").emit(OP_DICT['CAS']) 25114150Sjordi.vaquero@metempsy.com AtomicSingleOp("casalb", "CASALB", 1, unsign=True, 25214150Sjordi.vaquero@metempsy.com flavor="acquire_release").emit(OP_DICT['CAS']) 25314150Sjordi.vaquero@metempsy.com AtomicSingleOp("caslb", "CASLB", 1, unsign=True, 25414150Sjordi.vaquero@metempsy.com flavor="release").emit(OP_DICT['CAS']) 25514150Sjordi.vaquero@metempsy.com 25614150Sjordi.vaquero@metempsy.com AtomicSingleOp("cash", "CASH", 2, unsign=True, 25714150Sjordi.vaquero@metempsy.com flavor="normal").emit(OP_DICT['CAS']) 25814150Sjordi.vaquero@metempsy.com AtomicSingleOp("casah", "CASAH", 2, unsign=True, 25914150Sjordi.vaquero@metempsy.com flavor="acquire").emit(OP_DICT['CAS']) 26014150Sjordi.vaquero@metempsy.com AtomicSingleOp("casalh", "CASALH", 2, unsign=True, 26114150Sjordi.vaquero@metempsy.com flavor="acquire_release").emit(OP_DICT['CAS']) 26214150Sjordi.vaquero@metempsy.com AtomicSingleOp("caslh", "CASLH", 2, unsign=True, 26314150Sjordi.vaquero@metempsy.com flavor="release").emit(OP_DICT['CAS']) 26414150Sjordi.vaquero@metempsy.com 26514150Sjordi.vaquero@metempsy.com AtomicSingleOp("cas", "CAS32", 4, unsign=True, 26614150Sjordi.vaquero@metempsy.com flavor="normal").emit(OP_DICT['CAS']) 26714150Sjordi.vaquero@metempsy.com AtomicSingleOp("casa", "CASA32", 4, unsign=True, 26814150Sjordi.vaquero@metempsy.com flavor="acquire").emit(OP_DICT['CAS']) 26914150Sjordi.vaquero@metempsy.com AtomicSingleOp("casal", "CASAL32", 4, unsign=True, 27014150Sjordi.vaquero@metempsy.com flavor="acquire_release").emit(OP_DICT['CAS']) 27114150Sjordi.vaquero@metempsy.com AtomicSingleOp("casl", "CASL32", 4, unsign=True, 27214150Sjordi.vaquero@metempsy.com flavor="release").emit(OP_DICT['CAS']) 27314150Sjordi.vaquero@metempsy.com 27414150Sjordi.vaquero@metempsy.com class CasPair64(AtomicInst64): 27514150Sjordi.vaquero@metempsy.com decConstBase = 'AmoPairOp' 27614150Sjordi.vaquero@metempsy.com base = 'ArmISA::MemoryEx64' 27714150Sjordi.vaquero@metempsy.com writeback = True 27814150Sjordi.vaquero@metempsy.com post = False 27914150Sjordi.vaquero@metempsy.com execBase = 'AmoOp' 28014150Sjordi.vaquero@metempsy.com 28114150Sjordi.vaquero@metempsy.com def __init__(self, *args, **kargs): 28214150Sjordi.vaquero@metempsy.com super(CasPair64, self).__init__(*args, **kargs) 28314150Sjordi.vaquero@metempsy.com self.paired = True 28414150Sjordi.vaquero@metempsy.com self.offset = "" 28514150Sjordi.vaquero@metempsy.com if self.size == 8: 28614150Sjordi.vaquero@metempsy.com self.res = 'XResult_ud' 28714150Sjordi.vaquero@metempsy.com self.des = 'XDest_ud' 28814150Sjordi.vaquero@metempsy.com self.tp = 'std::array<uint64_t, 2>' 28914150Sjordi.vaquero@metempsy.com self.suffix = "_tud" 29014150Sjordi.vaquero@metempsy.com store_res = ''' 29114150Sjordi.vaquero@metempsy.com %(result)s = cSwap(Mem%(suffix)s[0], 29214150Sjordi.vaquero@metempsy.com isBigEndian64(xc->tcBase())); 29314150Sjordi.vaquero@metempsy.com uint64_t result2 = cSwap(Mem%(suffix)s[1], 29414150Sjordi.vaquero@metempsy.com isBigEndian64(xc->tcBase())); 29514150Sjordi.vaquero@metempsy.com xc->setIntRegOperand(this, r2_dst, (result2) 29614150Sjordi.vaquero@metempsy.com & mask(aarch64 ? 64 : 32)); 29714150Sjordi.vaquero@metempsy.com ''' 29814150Sjordi.vaquero@metempsy.com elif self.size == 4: 29914150Sjordi.vaquero@metempsy.com self.res = 'Result_uw' 30014150Sjordi.vaquero@metempsy.com self.des = 'WDest_uw' 30114150Sjordi.vaquero@metempsy.com self.tp = 'uint64_t' 30214150Sjordi.vaquero@metempsy.com self.suffix = "_ud" 30314150Sjordi.vaquero@metempsy.com store_res = ''' 30414150Sjordi.vaquero@metempsy.com uint64_t data = cSwap(Mem%(suffix)s, 30514150Sjordi.vaquero@metempsy.com isBigEndian64(xc->tcBase())); 30614150Sjordi.vaquero@metempsy.com %(result)s = isBigEndian64(xc->tcBase()) 30714150Sjordi.vaquero@metempsy.com ? (data >> 32) 30814150Sjordi.vaquero@metempsy.com : (uint32_t)data; 30914150Sjordi.vaquero@metempsy.com uint32_t result2 = isBigEndian64(xc->tcBase()) 31014150Sjordi.vaquero@metempsy.com ? (uint32_t)data 31114150Sjordi.vaquero@metempsy.com : (data >> 32); 31214150Sjordi.vaquero@metempsy.com xc->setIntRegOperand(this, r2_dst, (result2) & 31314150Sjordi.vaquero@metempsy.com mask(aarch64 ? 64 : 32)); 31414150Sjordi.vaquero@metempsy.com ''' 31514150Sjordi.vaquero@metempsy.com 31614150Sjordi.vaquero@metempsy.com store_res = store_res % {"result":self.res, "suffix":self.suffix} 31714150Sjordi.vaquero@metempsy.com usrDecl = "%(type)s valRs;\n" % {'type': self.tp} 31814150Sjordi.vaquero@metempsy.com self.codeBlobs['usrDecl'] = usrDecl 31914150Sjordi.vaquero@metempsy.com self.codeBlobs["postacc_code"] = \ 32014150Sjordi.vaquero@metempsy.com store_res + " SevMailbox = 1; LLSCLock = 0;" 32114150Sjordi.vaquero@metempsy.com 32214150Sjordi.vaquero@metempsy.com def emit(self): 32314150Sjordi.vaquero@metempsy.com self.buildEACode() 32414150Sjordi.vaquero@metempsy.com 32514150Sjordi.vaquero@metempsy.com # Code that actually handles the access 32614150Sjordi.vaquero@metempsy.com 32714150Sjordi.vaquero@metempsy.com if self.size == 4: 32814150Sjordi.vaquero@metempsy.com accCode = \ 32914150Sjordi.vaquero@metempsy.com "uint32_t result2 = ((xc->readIntRegOperand(this, r2_src))"\ 33014150Sjordi.vaquero@metempsy.com " & mask(aarch64 ? 64 : 32)) ;\n"\ 33114150Sjordi.vaquero@metempsy.com " uint32_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\ 33214150Sjordi.vaquero@metempsy.com " & mask(aarch64 ? 64 : 32)) ;" 33314150Sjordi.vaquero@metempsy.com accCode += ''' 33414150Sjordi.vaquero@metempsy.com uint64_t data = dest2; 33514150Sjordi.vaquero@metempsy.com data = isBigEndian64(xc->tcBase()) 33614150Sjordi.vaquero@metempsy.com ? ((uint64_t(WDest_uw) << 32) | data) 33714150Sjordi.vaquero@metempsy.com : ((data << 32) | WDest_uw); 33814150Sjordi.vaquero@metempsy.com valRs = cSwap(data, isBigEndian64(xc->tcBase())); 33914150Sjordi.vaquero@metempsy.com uint64_t data2 = result2 ; 34014150Sjordi.vaquero@metempsy.com data2 = isBigEndian64(xc->tcBase()) 34114150Sjordi.vaquero@metempsy.com ? ((uint64_t(Result_uw) << 32) | data2) 34214150Sjordi.vaquero@metempsy.com : ((data2 << 32) | Result_uw); 34314150Sjordi.vaquero@metempsy.com Mem_ud = cSwap(data2, isBigEndian64(xc->tcBase())); 34414150Sjordi.vaquero@metempsy.com ''' 34514150Sjordi.vaquero@metempsy.com 34614150Sjordi.vaquero@metempsy.com opcode = "TypedAtomicOpFunctor<%(type)s> *amo_op = "\ 34714150Sjordi.vaquero@metempsy.com "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\ 34814150Sjordi.vaquero@metempsy.com " valRs, [](%(type)s* b, %(type)s a,"\ 34914150Sjordi.vaquero@metempsy.com " %(type)s c){ %(op)s });\n" 35014150Sjordi.vaquero@metempsy.com 35114150Sjordi.vaquero@metempsy.com elif self.size == 8: 35214150Sjordi.vaquero@metempsy.com accCode = ""\ 35314150Sjordi.vaquero@metempsy.com "uint64_t result2 = ((xc->readIntRegOperand(this, r2_src))"\ 35414150Sjordi.vaquero@metempsy.com " & mask(aarch64 ? 64 : 32)) ;\n"\ 35514150Sjordi.vaquero@metempsy.com " uint64_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\ 35614150Sjordi.vaquero@metempsy.com " & mask(aarch64 ? 64 : 32)) ;" 35714150Sjordi.vaquero@metempsy.com accCode += ''' 35814150Sjordi.vaquero@metempsy.com // This temporary needs to be here so that the parser 35914150Sjordi.vaquero@metempsy.com // will correctly identify this instruction as a store. 36014150Sjordi.vaquero@metempsy.com std::array<uint64_t, 2> temp; 36114150Sjordi.vaquero@metempsy.com temp[0] = cSwap(XDest_ud,isBigEndian64(xc->tcBase())); 36214150Sjordi.vaquero@metempsy.com temp[1] = cSwap(dest2,isBigEndian64(xc->tcBase())); 36314150Sjordi.vaquero@metempsy.com valRs = temp; 36414150Sjordi.vaquero@metempsy.com std::array<uint64_t, 2> temp2; 36514150Sjordi.vaquero@metempsy.com temp2[0] = cSwap(XResult_ud,isBigEndian64(xc->tcBase())); 36614150Sjordi.vaquero@metempsy.com temp2[1] = cSwap(result2,isBigEndian64(xc->tcBase())); 36714150Sjordi.vaquero@metempsy.com Mem_tud = temp2; 36814150Sjordi.vaquero@metempsy.com ''' 36914150Sjordi.vaquero@metempsy.com 37014150Sjordi.vaquero@metempsy.com opcode = "TypedAtomicOpFunctor<uint64_t> *amo_op = "\ 37114150Sjordi.vaquero@metempsy.com "new AtomicGenericPair3Op<uint64_t>(Mem_tud, "\ 37214150Sjordi.vaquero@metempsy.com "valRs, [](uint64_t* b, std::array<uint64_t,2> a,"\ 37314150Sjordi.vaquero@metempsy.com ''' 37414150Sjordi.vaquero@metempsy.com std::array<uint64_t,2> c){ 37514150Sjordi.vaquero@metempsy.com if(a[0]==b[0] && a[1]==b[1]){ 37614150Sjordi.vaquero@metempsy.com b[0] = c[0]; b[1] = c[1]; 37714150Sjordi.vaquero@metempsy.com } 37814150Sjordi.vaquero@metempsy.com });''' 37914150Sjordi.vaquero@metempsy.com 38014150Sjordi.vaquero@metempsy.com opcode = opcode % { "suffix" : self.suffix, 38114150Sjordi.vaquero@metempsy.com "type": self.tp, 38214150Sjordi.vaquero@metempsy.com "op": OP_DICT['CAS']} 38314150Sjordi.vaquero@metempsy.com self.codeBlobs['amo_code'] = opcode 38414150Sjordi.vaquero@metempsy.com self.codeBlobs["memacc_code"] = accCode % {"type": self.tp} 38514150Sjordi.vaquero@metempsy.com 38614150Sjordi.vaquero@metempsy.com # Push it out to the output files 38714150Sjordi.vaquero@metempsy.com self.emitHelper(self.base) 38814150Sjordi.vaquero@metempsy.com 38914150Sjordi.vaquero@metempsy.com CasPair64("casp", "CASP64", 8, flavor="normal", paired=True).emit() 39014150Sjordi.vaquero@metempsy.com CasPair64("caspa", "CASPA64", 8, flavor="acquire", paired=True).emit() 39114150Sjordi.vaquero@metempsy.com CasPair64("caspal", "CASPAL64", 8, flavor="acquire_release", 39214150Sjordi.vaquero@metempsy.com paired=True).emit() 39314150Sjordi.vaquero@metempsy.com CasPair64("caspl", "CASPL64", 8, flavor="release", paired=True).emit() 39414150Sjordi.vaquero@metempsy.com 39514150Sjordi.vaquero@metempsy.com CasPair64("casp", "CASP32", 4, flavor="normal", paired=True).emit() 39614150Sjordi.vaquero@metempsy.com CasPair64("caspa", "CASPA32", 4, flavor="acquire", paired=True).emit() 39714150Sjordi.vaquero@metempsy.com CasPair64("caspal", "CASPAL32", 4, flavor="acquire_release", 39814150Sjordi.vaquero@metempsy.com paired=True).emit() 39914150Sjordi.vaquero@metempsy.com CasPair64("caspl", "CASPL32", 4, flavor="release", paired=True).emit() 40014150Sjordi.vaquero@metempsy.com 40114150Sjordi.vaquero@metempsy.com}}; 402