mem.isa revision 10199
17119Sgblack@eecs.umich.edu// -*- mode:c++ -*-
27119Sgblack@eecs.umich.edu
310037SARM gem5 Developers// Copyright (c) 2010-2012 ARM Limited
47119Sgblack@eecs.umich.edu// All rights reserved
57119Sgblack@eecs.umich.edu//
67119Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
77119Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
87119Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
97119Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
107119Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
117119Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
127119Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
137119Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
147119Sgblack@eecs.umich.edu//
157119Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
167119Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
177119Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
187119Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
197119Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
207119Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
217119Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
227119Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
237119Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
247119Sgblack@eecs.umich.edu// this software without specific prior written permission.
257119Sgblack@eecs.umich.edu//
267119Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
277119Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
287119Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
297119Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
307119Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
317119Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
327119Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
337119Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
347119Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
357119Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
367119Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
377119Sgblack@eecs.umich.edu//
387119Sgblack@eecs.umich.edu// Authors: Gabe Black
397119Sgblack@eecs.umich.edu
407119Sgblack@eecs.umich.edulet {{
417119Sgblack@eecs.umich.edu
427590Sgblack@eecs.umich.edu    class LoadStoreInst(object):
437590Sgblack@eecs.umich.edu        def __init__(self):
447590Sgblack@eecs.umich.edu            self.fullExecTemplate = eval(self.execBase + 'Execute')
457590Sgblack@eecs.umich.edu            self.initiateAccTemplate = eval(self.execBase + 'InitiateAcc')
467590Sgblack@eecs.umich.edu            self.completeAccTemplate = eval(self.execBase + 'CompleteAcc')
477590Sgblack@eecs.umich.edu            self.declareTemplate = eval(self.decConstBase + 'Declare')
487590Sgblack@eecs.umich.edu            self.constructTemplate = eval(self.decConstBase + 'Constructor')
497205Sgblack@eecs.umich.edu
507590Sgblack@eecs.umich.edu        def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags,
5110037SARM gem5 Developers                          base='Memory', wbDecl=None, pcDecl=None,
5210037SARM gem5 Developers                          rasPop=False, size=4, sign=False, faCode=None):
537590Sgblack@eecs.umich.edu            # Make sure flags are in lists (convert to lists if not).
547590Sgblack@eecs.umich.edu            memFlags = makeList(memFlags)
557590Sgblack@eecs.umich.edu            instFlags = makeList(instFlags)
567119Sgblack@eecs.umich.edu
577590Sgblack@eecs.umich.edu            eaCode = codeBlobs["ea_code"]
587205Sgblack@eecs.umich.edu
597590Sgblack@eecs.umich.edu            # This shouldn't be part of the eaCode, but until the exec templates
607590Sgblack@eecs.umich.edu            # are converted over it's the easiest place to put it.
617590Sgblack@eecs.umich.edu            eaCode += '\n    unsigned memAccessFlags = '
627590Sgblack@eecs.umich.edu            eaCode += (string.join(memFlags, '|') + ';')
637119Sgblack@eecs.umich.edu
647590Sgblack@eecs.umich.edu            codeBlobs["ea_code"] = eaCode
657119Sgblack@eecs.umich.edu
6610037SARM gem5 Developers            if faCode:
6710037SARM gem5 Developers                # For AArch64 the fa_code snippet comes already assembled here
6810037SARM gem5 Developers                codeBlobs["fa_code"] = faCode
6910037SARM gem5 Developers            elif wbDecl == None:
7010037SARM gem5 Developers                codeBlobs["fa_code"] = '''
7110037SARM gem5 Developers                    if (dest != INTREG_PC) {
7210037SARM gem5 Developers                        fault->annotate(ArmFault::SAS, %s);
7310037SARM gem5 Developers                        fault->annotate(ArmFault::SSE, %s);
7410037SARM gem5 Developers                        fault->annotate(ArmFault::SRT, dest);
7510037SARM gem5 Developers                    }
7610037SARM gem5 Developers                ''' %("0"    if size == 1 else
7710037SARM gem5 Developers                      "1"    if size == 2 else "2",
7810037SARM gem5 Developers                      "true" if sign      else "false")
7910037SARM gem5 Developers            else:
8010037SARM gem5 Developers                codeBlobs["fa_code"] = ''
8110037SARM gem5 Developers
827646Sgene.wu@arm.com            macroName = Name
837646Sgene.wu@arm.com            instFlagsCopy = list(instFlags)
847646Sgene.wu@arm.com            codeBlobsCopy = dict(codeBlobs)
858140SMatt.Horsnell@arm.com
868140SMatt.Horsnell@arm.com            use_uops = 0
878140SMatt.Horsnell@arm.com            if wbDecl is not None or pcDecl is not None:
887646Sgene.wu@arm.com                instFlagsCopy.append('IsMicroop')
897646Sgene.wu@arm.com                Name = Name + 'Acc'
908140SMatt.Horsnell@arm.com                use_uops = 1
918140SMatt.Horsnell@arm.com
928140SMatt.Horsnell@arm.com            use_wb = 0
938140SMatt.Horsnell@arm.com            use_pc = 0
948140SMatt.Horsnell@arm.com            if wbDecl is not None:
958140SMatt.Horsnell@arm.com                use_wb = 1
968140SMatt.Horsnell@arm.com            if pcDecl is not None:
978140SMatt.Horsnell@arm.com                use_pc = 1
988140SMatt.Horsnell@arm.com
997646Sgene.wu@arm.com            codeBlobsCopy['acc_name'] = Name
1007646Sgene.wu@arm.com            codeBlobsCopy['wb_decl'] = wbDecl
1018140SMatt.Horsnell@arm.com            codeBlobsCopy['pc_decl'] = pcDecl
1027646Sgene.wu@arm.com            codeBlobsCopy['use_uops'] = 0
1038140SMatt.Horsnell@arm.com            codeBlobsCopy['use_wb'] = 0
1048140SMatt.Horsnell@arm.com            codeBlobsCopy['use_pc'] = 0
1058203SAli.Saidi@ARM.com            is_ras_pop = "0"
1068203SAli.Saidi@ARM.com            if rasPop:
1078203SAli.Saidi@ARM.com                is_ras_pop = "1"
1088203SAli.Saidi@ARM.com            codeBlobsCopy['is_ras_pop'] = is_ras_pop
1097119Sgblack@eecs.umich.edu
1107646Sgene.wu@arm.com            iop = InstObjParams(name, Name, base,
1117646Sgene.wu@arm.com                                codeBlobsCopy, instFlagsCopy)
1127646Sgene.wu@arm.com
1137646Sgene.wu@arm.com            header_output = self.declareTemplate.subst(iop)
1147646Sgene.wu@arm.com            decoder_output = self.constructTemplate.subst(iop)
1157646Sgene.wu@arm.com            exec_output = self.fullExecTemplate.subst(iop) + \
1167646Sgene.wu@arm.com                          self.initiateAccTemplate.subst(iop) + \
1177646Sgene.wu@arm.com                          self.completeAccTemplate.subst(iop)
1187646Sgene.wu@arm.com
1198140SMatt.Horsnell@arm.com            if wbDecl is not None or pcDecl is not None:
1207646Sgene.wu@arm.com                iop = InstObjParams(name, macroName, base,
1217646Sgene.wu@arm.com                                    { "wb_decl" : wbDecl,
1228140SMatt.Horsnell@arm.com                                      "pc_decl" : pcDecl,
1237646Sgene.wu@arm.com                                      "acc_name" : Name,
1248140SMatt.Horsnell@arm.com                                      "use_uops" : use_uops,
1258140SMatt.Horsnell@arm.com                                      "use_pc" : use_pc,
1268203SAli.Saidi@ARM.com                                      "use_wb" : use_wb,
12710037SARM gem5 Developers                                      "fa_code" : '',
1288203SAli.Saidi@ARM.com                                      "is_ras_pop" : is_ras_pop },
1297646Sgene.wu@arm.com                                    ['IsMacroop'])
1307646Sgene.wu@arm.com                header_output += self.declareTemplate.subst(iop)
1317646Sgene.wu@arm.com                decoder_output += self.constructTemplate.subst(iop)
1327646Sgene.wu@arm.com                exec_output += PanicExecute.subst(iop) + \
1337646Sgene.wu@arm.com                               PanicInitiateAcc.subst(iop) + \
1347646Sgene.wu@arm.com                               PanicCompleteAcc.subst(iop)
1357646Sgene.wu@arm.com
1367646Sgene.wu@arm.com            return (header_output, decoder_output, exec_output)
1377119Sgblack@eecs.umich.edu
1387422Sgblack@eecs.umich.edu    def pickPredicate(blobs):
1398303SAli.Saidi@ARM.com        opt_nz = True
1408304SAli.Saidi@ARM.com        opt_c = 'opt'
1418303SAli.Saidi@ARM.com        opt_v = True
1428304SAli.Saidi@ARM.com
1438304SAli.Saidi@ARM.com        if not isinstance(blobs, dict):
1448304SAli.Saidi@ARM.com            vals = [blobs]
1458304SAli.Saidi@ARM.com        else:
1468304SAli.Saidi@ARM.com            vals = blobs.values()
1478304SAli.Saidi@ARM.com        for val in vals:
1488304SAli.Saidi@ARM.com            if re.search('(?<!Opt)CondCodesNZ(?!.*=)', val):
1498303SAli.Saidi@ARM.com                opt_nz = False
1508304SAli.Saidi@ARM.com            if re.search('OptShiftRmCondCodesC(?!.*=)', val):
1518304SAli.Saidi@ARM.com                opt_c = 'opt_shift_rm'
1528304SAli.Saidi@ARM.com            elif re.search('(?<!Opt)CondCodesC(?!.*=)', val):
1538304SAli.Saidi@ARM.com                opt_c = 'none'
1548304SAli.Saidi@ARM.com            if re.search('(?<!Opt)CondCodesV(?!.*=)', val):
1558303SAli.Saidi@ARM.com                opt_v = False
1568303SAli.Saidi@ARM.com
1578303SAli.Saidi@ARM.com        # Build up the predicate piece by piece depending on which
1588303SAli.Saidi@ARM.com        # flags the instruction needs
1598303SAli.Saidi@ARM.com        predicate = 'testPredicate('
1608303SAli.Saidi@ARM.com        if opt_nz:
1618303SAli.Saidi@ARM.com            predicate += 'OptCondCodesNZ, '
1628303SAli.Saidi@ARM.com        else:
1638303SAli.Saidi@ARM.com            predicate += 'CondCodesNZ, '
1648304SAli.Saidi@ARM.com        if opt_c == 'opt':
1658303SAli.Saidi@ARM.com            predicate += 'OptCondCodesC, '
1668304SAli.Saidi@ARM.com        elif opt_c == 'opt_shift_rm':
1678304SAli.Saidi@ARM.com            predicate += 'OptShiftRmCondCodesC, '
1688303SAli.Saidi@ARM.com        else:
1698303SAli.Saidi@ARM.com            predicate += 'CondCodesC, '
1708303SAli.Saidi@ARM.com        if opt_v:
1718303SAli.Saidi@ARM.com            predicate += 'OptCondCodesV, '
1728303SAli.Saidi@ARM.com        else:
1738303SAli.Saidi@ARM.com            predicate += 'CondCodesV, '
1748303SAli.Saidi@ARM.com        predicate += 'condCode)'
1758304SAli.Saidi@ARM.com        predicate += '/*auto*/'
1768303SAli.Saidi@ARM.com        return predicate
1777422Sgblack@eecs.umich.edu
1787119Sgblack@eecs.umich.edu    def memClassName(base, post, add, writeback, \
1797119Sgblack@eecs.umich.edu                     size=4, sign=False, user=False):
1807119Sgblack@eecs.umich.edu        Name = base
1817119Sgblack@eecs.umich.edu
1827590Sgblack@eecs.umich.edu        parts = { "P" : post, "A" : add, "W" : writeback,
1837590Sgblack@eecs.umich.edu                  "S" : sign, "U" : user }
1847119Sgblack@eecs.umich.edu
1857590Sgblack@eecs.umich.edu        for (letter, val) in parts.items():
1867590Sgblack@eecs.umich.edu            if val:
1877590Sgblack@eecs.umich.edu                Name += "_%sY" % letter
1887590Sgblack@eecs.umich.edu            else:
1897590Sgblack@eecs.umich.edu                Name += "_%sN" % letter
1907119Sgblack@eecs.umich.edu
1917119Sgblack@eecs.umich.edu        Name += ('_SZ%d' % size)
1927119Sgblack@eecs.umich.edu
1937119Sgblack@eecs.umich.edu        return Name
1947119Sgblack@eecs.umich.edu
1957119Sgblack@eecs.umich.edu    def buildMemSuffix(sign, size):
19610037SARM gem5 Developers        if size == 8:
19710037SARM gem5 Developers            memSuffix = '_ud'
19810037SARM gem5 Developers        elif size == 4:
19910037SARM gem5 Developers            if sign:
20010037SARM gem5 Developers                memSuffix = '_sw'
20110037SARM gem5 Developers            else:
20210037SARM gem5 Developers                memSuffix = '_uw'
2037119Sgblack@eecs.umich.edu        elif size == 2:
2047119Sgblack@eecs.umich.edu            if sign:
2058588Sgblack@eecs.umich.edu                memSuffix = '_sh'
2067119Sgblack@eecs.umich.edu            else:
2078588Sgblack@eecs.umich.edu                memSuffix = '_uh'
2087119Sgblack@eecs.umich.edu        elif size == 1:
2097119Sgblack@eecs.umich.edu            if sign:
2108588Sgblack@eecs.umich.edu                memSuffix = '_sb'
2117119Sgblack@eecs.umich.edu            else:
2128588Sgblack@eecs.umich.edu                memSuffix = '_ub'
2137119Sgblack@eecs.umich.edu        else:
2147590Sgblack@eecs.umich.edu            raise Exception, "Unrecognized size for access %d" % size
2157119Sgblack@eecs.umich.edu
2167119Sgblack@eecs.umich.edu        return memSuffix
2177119Sgblack@eecs.umich.edu
2187119Sgblack@eecs.umich.edu    def buildMemBase(base, post, writeback):
2197119Sgblack@eecs.umich.edu        if post and writeback:
2207132Sgblack@eecs.umich.edu            base = "MemoryPostIndex<%s>" % base
2217119Sgblack@eecs.umich.edu        elif not post and writeback:
2227132Sgblack@eecs.umich.edu            base = "MemoryPreIndex<%s>" % base
2237119Sgblack@eecs.umich.edu        elif not post and not writeback:
2247132Sgblack@eecs.umich.edu            base = "MemoryOffset<%s>" % base
2257119Sgblack@eecs.umich.edu        else:
2267119Sgblack@eecs.umich.edu            raise Exception, "Illegal combination of post and writeback"
2277119Sgblack@eecs.umich.edu        return base
2287119Sgblack@eecs.umich.edu}};
2297119Sgblack@eecs.umich.edu
230