str.isa revision 8301:858384f3af1c
16100Sgblack@eecs.umich.edu// -*- mode:c++ -*-
26098Sgblack@eecs.umich.edu
36098Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited
46100Sgblack@eecs.umich.edu// All rights reserved
56100Sgblack@eecs.umich.edu//
66100Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
76100Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
86100Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
96100Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
106100Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
116100Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
126098Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
136100Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
146098Sgblack@eecs.umich.edu//
156098Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
166098Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
176098Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
186098Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
196098Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
206098Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
216098Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
226098Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
236098Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
246098Sgblack@eecs.umich.edu// this software without specific prior written permission.
256098Sgblack@eecs.umich.edu//
266098Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
276098Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
286098Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
296098Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
306098Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
316098Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
326098Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
336098Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
346098Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
356098Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
366098Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
376098Sgblack@eecs.umich.edu//
386098Sgblack@eecs.umich.edu// Authors: Gabe Black
396098Sgblack@eecs.umich.edu
406098Sgblack@eecs.umich.edulet {{
416098Sgblack@eecs.umich.edu
426098Sgblack@eecs.umich.edu    header_output = ""
436098Sgblack@eecs.umich.edu    decoder_output = ""
446098Sgblack@eecs.umich.edu    exec_output = ""
456098Sgblack@eecs.umich.edu
466098Sgblack@eecs.umich.edu    class StoreInst(LoadStoreInst):
476098Sgblack@eecs.umich.edu        execBase = 'Store'
486098Sgblack@eecs.umich.edu
496098Sgblack@eecs.umich.edu        def __init__(self, mnem, post, add, writeback, size=4,
506098Sgblack@eecs.umich.edu                     sign=False, user=False, flavor="normal",
516098Sgblack@eecs.umich.edu                     instFlags = []):
526098Sgblack@eecs.umich.edu            super(StoreInst, self).__init__()
536098Sgblack@eecs.umich.edu
546098Sgblack@eecs.umich.edu            self.name = mnem
556098Sgblack@eecs.umich.edu            self.post = post
566098Sgblack@eecs.umich.edu            self.add = add
576098Sgblack@eecs.umich.edu            self.writeback = writeback
586098Sgblack@eecs.umich.edu            self.size = size
596098Sgblack@eecs.umich.edu            self.sign = sign
606098Sgblack@eecs.umich.edu            self.user = user
616098Sgblack@eecs.umich.edu            self.flavor = flavor
626098Sgblack@eecs.umich.edu            self.instFlags = instFlags
636098Sgblack@eecs.umich.edu            if self.add:
646098Sgblack@eecs.umich.edu                self.op = " +"
656098Sgblack@eecs.umich.edu            else:
666098Sgblack@eecs.umich.edu                self.op = " -"
676098Sgblack@eecs.umich.edu
686098Sgblack@eecs.umich.edu            self.memFlags = ["ArmISA::TLB::MustBeOne"]
696098Sgblack@eecs.umich.edu            self.codeBlobs = { "postacc_code" : "" }
706098Sgblack@eecs.umich.edu
716098Sgblack@eecs.umich.edu        def emitHelper(self, base = 'Memory', wbDecl = None):
726098Sgblack@eecs.umich.edu
736098Sgblack@eecs.umich.edu            global header_output, decoder_output, exec_output
746098Sgblack@eecs.umich.edu
756098Sgblack@eecs.umich.edu            codeBlobs = self.codeBlobs
766098Sgblack@eecs.umich.edu            codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
776098Sgblack@eecs.umich.edu            (newHeader,
786098Sgblack@eecs.umich.edu             newDecoder,
796098Sgblack@eecs.umich.edu             newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
806098Sgblack@eecs.umich.edu                                           self.memFlags, self.instFlags, base, wbDecl)
816098Sgblack@eecs.umich.edu
826098Sgblack@eecs.umich.edu            header_output += newHeader
836098Sgblack@eecs.umich.edu            decoder_output += newDecoder
846098Sgblack@eecs.umich.edu            exec_output += newExec
856098Sgblack@eecs.umich.edu
866098Sgblack@eecs.umich.edu    class SrsInst(LoadStoreInst):
876098Sgblack@eecs.umich.edu        execBase = 'Store'
886098Sgblack@eecs.umich.edu        decConstBase = 'Srs'
896098Sgblack@eecs.umich.edu
906098Sgblack@eecs.umich.edu        def __init__(self, mnem, post, add, writeback):
916098Sgblack@eecs.umich.edu            super(SrsInst, self).__init__()
926098Sgblack@eecs.umich.edu            self.name = mnem
936098Sgblack@eecs.umich.edu            self.post = post
946098Sgblack@eecs.umich.edu            self.add = add
956098Sgblack@eecs.umich.edu            self.writeback = writeback
966098Sgblack@eecs.umich.edu
976098Sgblack@eecs.umich.edu            self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
986098Sgblack@eecs.umich.edu
996098Sgblack@eecs.umich.edu        def emit(self):
1006098Sgblack@eecs.umich.edu            offset = 0
1016098Sgblack@eecs.umich.edu            if self.post != self.add:
1026098Sgblack@eecs.umich.edu                offset += 4
1036098Sgblack@eecs.umich.edu            if not self.add:
1046098Sgblack@eecs.umich.edu                offset -= 8
1056098Sgblack@eecs.umich.edu
1066098Sgblack@eecs.umich.edu            eaCode = "EA = SpMode + %d;" % offset
1076098Sgblack@eecs.umich.edu
1086098Sgblack@eecs.umich.edu            wbDiff = -8
1096098Sgblack@eecs.umich.edu            if self.add:
1106098Sgblack@eecs.umich.edu                wbDiff = 8
1116098Sgblack@eecs.umich.edu            accCode = '''
1126098Sgblack@eecs.umich.edu            CPSR cpsr = Cpsr;
1136098Sgblack@eecs.umich.edu            Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
1146098Sgblack@eecs.umich.edu                     ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
1156098Sgblack@eecs.umich.edu            '''
1166098Sgblack@eecs.umich.edu
1176098Sgblack@eecs.umich.edu            global header_output, decoder_output, exec_output
1186098Sgblack@eecs.umich.edu
1196098Sgblack@eecs.umich.edu            codeBlobs = { "ea_code": eaCode,
1206098Sgblack@eecs.umich.edu                          "memacc_code": accCode,
1216098Sgblack@eecs.umich.edu                          "postacc_code": "" }
1226098Sgblack@eecs.umich.edu            codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
1236098Sgblack@eecs.umich.edu
1246098Sgblack@eecs.umich.edu            wbDecl = None
1256098Sgblack@eecs.umich.edu            if self.writeback:
1266098Sgblack@eecs.umich.edu                wbDecl = '''MicroAddiUop(machInst,
1276098Sgblack@eecs.umich.edu                              intRegInMode((OperatingMode)regMode, INTREG_SP),
1286098Sgblack@eecs.umich.edu                              intRegInMode((OperatingMode)regMode, INTREG_SP),
1296098Sgblack@eecs.umich.edu                              %d);''' % wbDiff
1306098Sgblack@eecs.umich.edu
1316098Sgblack@eecs.umich.edu            (newHeader,
1326098Sgblack@eecs.umich.edu             newDecoder,
1336098Sgblack@eecs.umich.edu             newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
1346098Sgblack@eecs.umich.edu                 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [],
1356098Sgblack@eecs.umich.edu                 'SrsOp', wbDecl)
1366098Sgblack@eecs.umich.edu
1376098Sgblack@eecs.umich.edu            header_output += newHeader
1386098Sgblack@eecs.umich.edu            decoder_output += newDecoder
1396098Sgblack@eecs.umich.edu            exec_output += newExec
1406098Sgblack@eecs.umich.edu
1416098Sgblack@eecs.umich.edu    class StoreImmInst(StoreInst):
1426098Sgblack@eecs.umich.edu        def __init__(self, *args, **kargs):
1436098Sgblack@eecs.umich.edu            super(StoreImmInst, self).__init__(*args, **kargs)
1446098Sgblack@eecs.umich.edu            self.offset = self.op + " imm"
1456098Sgblack@eecs.umich.edu
1466098Sgblack@eecs.umich.edu            if self.add:
1476098Sgblack@eecs.umich.edu                self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
1486098Sgblack@eecs.umich.edu            else:
1496098Sgblack@eecs.umich.edu                self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
1506098Sgblack@eecs.umich.edu
1516098Sgblack@eecs.umich.edu    class StoreRegInst(StoreInst):
1526098Sgblack@eecs.umich.edu        def __init__(self, *args, **kargs):
1536098Sgblack@eecs.umich.edu            super(StoreRegInst, self).__init__(*args, **kargs)
1546098Sgblack@eecs.umich.edu            self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
1556098Sgblack@eecs.umich.edu                                    " shiftType, CondCodesF<29:>)"
1566098Sgblack@eecs.umich.edu            if self.add:
1576098Sgblack@eecs.umich.edu                 self.wbDecl = '''
1586098Sgblack@eecs.umich.edu                     MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);
1596098Sgblack@eecs.umich.edu                 '''
1606098Sgblack@eecs.umich.edu            else:
1616098Sgblack@eecs.umich.edu                 self.wbDecl = '''
1626098Sgblack@eecs.umich.edu                     MicroSubUop(machInst, base, base, index, shiftAmt, shiftType);
1636098Sgblack@eecs.umich.edu                 '''
1646098Sgblack@eecs.umich.edu
1656098Sgblack@eecs.umich.edu    class StoreSingle(StoreInst):
1666098Sgblack@eecs.umich.edu        def __init__(self, *args, **kargs):
1676098Sgblack@eecs.umich.edu            super(StoreSingle, self).__init__(*args, **kargs)
1686098Sgblack@eecs.umich.edu
1696098Sgblack@eecs.umich.edu            # Build the default class name
1706098Sgblack@eecs.umich.edu            self.Name = self.nameFunc(self.post, self.add, self.writeback,
1716098Sgblack@eecs.umich.edu                                      self.size, self.sign, self.user)
1726098Sgblack@eecs.umich.edu
173            # Add memory request flags where necessary
174            self.memFlags.append("%d" % (self.size - 1))
175            if self.user:
176                self.memFlags.append("ArmISA::TLB::UserMode")
177
178            if self.flavor == "exclusive":
179                self.memFlags.append("Request::LLSC")
180            elif self.flavor != "fp":
181                self.memFlags.append("ArmISA::TLB::AllowUnaligned")
182
183            # Disambiguate the class name for different flavors of stores
184            if self.flavor != "normal":
185                self.Name = "%s_%s" % (self.name.upper(), self.Name)
186
187        def emit(self):
188            # Address computation
189            eaCode = "EA = Base"
190            if not self.post:
191                eaCode += self.offset
192            eaCode += ";"
193
194            if self.flavor == "fp":
195                eaCode += vfpEnabledCheckCode
196
197            self.codeBlobs["ea_code"] = eaCode
198
199            # Code that actually handles the access
200            if self.flavor == "fp":
201                accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);'
202            else:
203                accCode = \
204                    'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);'
205            accCode = accCode % \
206                { "suffix" : buildMemSuffix(self.sign, self.size) }
207
208            self.codeBlobs["memacc_code"] = accCode
209
210            # Push it out to the output files
211            base = buildMemBase(self.basePrefix, self.post, self.writeback)
212            wbDecl = None
213            if self.writeback:
214                wbDecl = self.wbDecl
215            self.emitHelper(base, wbDecl)
216
217    def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
218        return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
219
220    class StoreImmEx(StoreImmInst, StoreSingle):
221        execBase = 'StoreEx'
222        decConstBase = 'StoreExImm'
223        basePrefix = 'MemoryExImm'
224        nameFunc = staticmethod(storeImmClassName)
225
226        def __init__(self, *args, **kargs):
227            super(StoreImmEx, self).__init__(*args, **kargs)
228            self.codeBlobs["postacc_code"] = "Result = !writeResult;"
229
230    class StoreImm(StoreImmInst, StoreSingle):
231        decConstBase = 'LoadStoreImm'
232        basePrefix = 'MemoryImm'
233        nameFunc = staticmethod(storeImmClassName)
234
235    def storeRegClassName(post, add, writeback, size=4, sign=False, user=False):
236        return memClassName("STORE_REG", post, add, writeback, size, sign, user)
237
238    class StoreReg(StoreRegInst, StoreSingle):
239        decConstBase = 'StoreReg'
240        basePrefix = 'MemoryReg'
241        nameFunc = staticmethod(storeRegClassName)
242
243    class StoreDouble(StoreInst):
244        def __init__(self, *args, **kargs):
245            super(StoreDouble, self).__init__(*args, **kargs)
246
247            # Build the default class name
248            self.Name = self.nameFunc(self.post, self.add, self.writeback)
249
250            # Add memory request flags where necessary
251            if self.flavor == "exclusive":
252                self.memFlags.append("Request::LLSC")
253                self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
254            else:
255                self.memFlags.append("ArmISA::TLB::AlignWord")
256
257            # Disambiguate the class name for different flavors of stores
258            if self.flavor != "normal":
259                self.Name = "%s_%s" % (self.name.upper(), self.Name)
260
261        def emit(self):
262            # Address computation code
263            eaCode = "EA = Base"
264            if not self.post:
265                eaCode += self.offset
266            eaCode += ";"
267
268            if self.flavor == "fp":
269                eaCode += vfpEnabledCheckCode
270
271            self.codeBlobs["ea_code"] = eaCode
272
273            # Code that actually handles the access
274            if self.flavor == "fp":
275                accCode = '''
276                uint64_t swappedMem  = (uint64_t)FpDest.uw |
277                                       ((uint64_t)FpDest2.uw << 32);
278                Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
279                '''
280            else:
281                accCode = '''
282                CPSR cpsr = Cpsr;
283                Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
284                         ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
285                '''
286
287            self.codeBlobs["memacc_code"] = accCode
288
289            # Push it out to the output files
290            base = buildMemBase(self.basePrefix, self.post, self.writeback)
291            wbDecl = None
292            if self.writeback:
293                wbDecl = self.wbDecl
294            self.emitHelper(base, wbDecl)
295
296    def storeDoubleImmClassName(post, add, writeback):
297        return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
298
299    class StoreDoubleImmEx(StoreImmInst, StoreDouble):
300        execBase = 'StoreEx'
301        decConstBase = 'StoreExDImm'
302        basePrefix = 'MemoryExDImm'
303        nameFunc = staticmethod(storeDoubleImmClassName)
304
305        def __init__(self, *args, **kargs):
306            super(StoreDoubleImmEx, self).__init__(*args, **kargs)
307            self.codeBlobs["postacc_code"] = "Result = !writeResult;"
308
309    class StoreDoubleImm(StoreImmInst, StoreDouble):
310        decConstBase = 'LoadStoreDImm'
311        basePrefix = 'MemoryDImm'
312        nameFunc = staticmethod(storeDoubleImmClassName)
313
314    def storeDoubleRegClassName(post, add, writeback):
315        return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
316
317    class StoreDoubleReg(StoreRegInst, StoreDouble):
318        decConstBase = 'StoreDReg'
319        basePrefix = 'MemoryDReg'
320        nameFunc = staticmethod(storeDoubleRegClassName)
321
322    def buildStores(mnem, size=4, sign=False, user=False):
323        StoreImm(mnem, True, True, True, size, sign, user).emit()
324        StoreReg(mnem, True, True, True, size, sign, user).emit()
325        StoreImm(mnem, True, False, True, size, sign, user).emit()
326        StoreReg(mnem, True, False, True, size, sign, user).emit()
327        StoreImm(mnem, False, True, True, size, sign, user).emit()
328        StoreReg(mnem, False, True, True, size, sign, user).emit()
329        StoreImm(mnem, False, False, True, size, sign, user).emit()
330        StoreReg(mnem, False, False, True, size, sign, user).emit()
331        StoreImm(mnem, False, True, False, size, sign, user).emit()
332        StoreReg(mnem, False, True, False, size, sign, user).emit()
333        StoreImm(mnem, False, False, False, size, sign, user).emit()
334        StoreReg(mnem, False, False, False, size, sign, user).emit()
335
336    def buildDoubleStores(mnem):
337        StoreDoubleImm(mnem, True, True, True).emit()
338        StoreDoubleReg(mnem, True, True, True).emit()
339        StoreDoubleImm(mnem, True, False, True).emit()
340        StoreDoubleReg(mnem, True, False, True).emit()
341        StoreDoubleImm(mnem, False, True, True).emit()
342        StoreDoubleReg(mnem, False, True, True).emit()
343        StoreDoubleImm(mnem, False, False, True).emit()
344        StoreDoubleReg(mnem, False, False, True).emit()
345        StoreDoubleImm(mnem, False, True, False).emit()
346        StoreDoubleReg(mnem, False, True, False).emit()
347        StoreDoubleImm(mnem, False, False, False).emit()
348        StoreDoubleReg(mnem, False, False, False).emit()
349
350    def buildSrsStores(mnem):
351        SrsInst(mnem, True, True, True).emit()
352        SrsInst(mnem, True, True, False).emit()
353        SrsInst(mnem, True, False, True).emit()
354        SrsInst(mnem, True, False, False).emit()
355        SrsInst(mnem, False, True, True).emit()
356        SrsInst(mnem, False, True, False).emit()
357        SrsInst(mnem, False, False, True).emit()
358        SrsInst(mnem, False, False, False).emit()
359
360    buildStores("str")
361    buildStores("strt", user=True)
362    buildStores("strb", size=1)
363    buildStores("strbt", size=1, user=True)
364    buildStores("strh", size=2)
365    buildStores("strht", size=2, user=True)
366
367    buildSrsStores("srs")
368
369    buildDoubleStores("strd")
370
371    StoreImmEx("strex", False, True, False, size=4, flavor="exclusive",
372               instFlags = ['IsStoreConditional']).emit()
373    StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive",
374               instFlags = ['IsStoreConditional']).emit()
375    StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive",
376               instFlags = ['IsStoreConditional']).emit()
377    StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive",
378               instFlags = ['IsStoreConditional']).emit()
379
380    StoreImm("vstr", False, True, False, size=4, flavor="fp").emit()
381    StoreImm("vstr", False, False, False, size=4, flavor="fp").emit()
382    StoreDoubleImm("vstr", False, True, False, flavor="fp").emit()
383    StoreDoubleImm("vstr", False, False, False, flavor="fp").emit()
384}};
385