str.isa revision 7404:bfc74724914e
15222Sksewell@umich.edu// -*- mode:c++ -*-
25268Sksewell@umich.edu
35254Sksewell@umich.edu// Copyright (c) 2010 ARM Limited
45254Sksewell@umich.edu// All rights reserved
55222Sksewell@umich.edu//
65254Sksewell@umich.edu// The license below extends only to copyright in the software and shall
75254Sksewell@umich.edu// not be construed as granting a license to any other intellectual
85254Sksewell@umich.edu// property including but not limited to intellectual property relating
95254Sksewell@umich.edu// to a hardware implementation of the functionality of the software
105254Sksewell@umich.edu// licensed hereunder.  You may use the software subject to the license
115254Sksewell@umich.edu// terms below provided that you ensure that this notice is replicated
125254Sksewell@umich.edu// unmodified and in its entirety in all distributions of the software,
135254Sksewell@umich.edu// modified or unmodified, in source code or in binary form.
145254Sksewell@umich.edu//
155254Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
165222Sksewell@umich.edu// modification, are permitted provided that the following conditions are
175254Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
185254Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
195254Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
205254Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
215254Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
225254Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
235254Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
245254Sksewell@umich.edu// this software without specific prior written permission.
255254Sksewell@umich.edu//
265254Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
275254Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
285222Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
295254Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
305254Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
315222Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
325222Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
335222Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
345222Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
355222Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
365222Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
375222Sksewell@umich.edu//
385222Sksewell@umich.edu// Authors: Gabe Black
395222Sksewell@umich.edu
405222Sksewell@umich.edulet {{
415222Sksewell@umich.edu
425222Sksewell@umich.edu    header_output = ""
435222Sksewell@umich.edu    decoder_output = ""
445222Sksewell@umich.edu    exec_output = ""
455222Sksewell@umich.edu
465222Sksewell@umich.edu    def storeImmClassName(post, add, writeback, \
476378Sgblack@eecs.umich.edu                          size=4, sign=False, user=False):
485222Sksewell@umich.edu        return memClassName("STORE_IMM", post, add, writeback,
495222Sksewell@umich.edu                            size, sign, user)
505222Sksewell@umich.edu
515222Sksewell@umich.edu    def storeRegClassName(post, add, writeback, \
525222Sksewell@umich.edu                          size=4, sign=False, user=False):
537723SAli.Saidi@ARM.com        return memClassName("STORE_REG", post, add, writeback,
545222Sksewell@umich.edu                            size, sign, user)
555222Sksewell@umich.edu
565222Sksewell@umich.edu    def storeDoubleImmClassName(post, add, writeback):
575222Sksewell@umich.edu        return memClassName("STORE_IMMD", post, add, writeback,
585222Sksewell@umich.edu                            4, False, False)
595222Sksewell@umich.edu
605222Sksewell@umich.edu    def storeDoubleRegClassName(post, add, writeback):
615222Sksewell@umich.edu        return memClassName("STORE_REGD", post, add, writeback,
625222Sksewell@umich.edu                            4, False, False)
635222Sksewell@umich.edu
645222Sksewell@umich.edu    def emitStore(name, Name, imm, eaCode, accCode, postAccCode, \
655222Sksewell@umich.edu                  memFlags, instFlags, base, double=False, strex=False,
665222Sksewell@umich.edu                  execTemplateBase = 'Store'):
675222Sksewell@umich.edu        global header_output, decoder_output, exec_output
685222Sksewell@umich.edu
695222Sksewell@umich.edu        (newHeader,
705222Sksewell@umich.edu         newDecoder,
715222Sksewell@umich.edu         newExec) = loadStoreBase(name, Name, imm,
725222Sksewell@umich.edu                                  eaCode, accCode, postAccCode,
737723SAli.Saidi@ARM.com                                  memFlags, instFlags, double, strex,
745222Sksewell@umich.edu                                  base, execTemplateBase = execTemplateBase)
755222Sksewell@umich.edu
765222Sksewell@umich.edu        header_output += newHeader
775222Sksewell@umich.edu        decoder_output += newDecoder
785222Sksewell@umich.edu        exec_output += newExec
795222Sksewell@umich.edu
805222Sksewell@umich.edu    def buildImmStore(mnem, post, add, writeback, \
815222Sksewell@umich.edu                      size=4, sign=False, user=False, \
825222Sksewell@umich.edu                      strex=False, vstr=False):
835222Sksewell@umich.edu        name = mnem
845222Sksewell@umich.edu        Name = storeImmClassName(post, add, writeback, \
855222Sksewell@umich.edu                                 size, sign, user)
865222Sksewell@umich.edu
875222Sksewell@umich.edu        if add:
885222Sksewell@umich.edu            op = " +"
895222Sksewell@umich.edu        else:
905222Sksewell@umich.edu            op = " -"
915222Sksewell@umich.edu
925222Sksewell@umich.edu        offset = op + " imm"
935222Sksewell@umich.edu        eaCode = "EA = Base"
945222Sksewell@umich.edu        if not post:
957723SAli.Saidi@ARM.com            eaCode += offset
965222Sksewell@umich.edu        eaCode += ";"
975222Sksewell@umich.edu
985222Sksewell@umich.edu        if vstr:
995222Sksewell@umich.edu            accCode = '''
1005222Sksewell@umich.edu            Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);
1015222Sksewell@umich.edu            ''' % { "suffix" : buildMemSuffix(sign, size) }
1025222Sksewell@umich.edu        else:
1035222Sksewell@umich.edu            accCode = '''
1045222Sksewell@umich.edu            Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);
1055222Sksewell@umich.edu            ''' % { "suffix" : buildMemSuffix(sign, size) }
1067723SAli.Saidi@ARM.com        if writeback:
1075222Sksewell@umich.edu            accCode += "Base = Base %s;\n" % offset
1087723SAli.Saidi@ARM.com
1096378Sgblack@eecs.umich.edu        memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
1105222Sksewell@umich.edu        if user:
1116378Sgblack@eecs.umich.edu            memFlags.append("ArmISA::TLB::UserMode")
1125222Sksewell@umich.edu
1135222Sksewell@umich.edu        if strex:
1145222Sksewell@umich.edu            memFlags.append("Request::LLSC")
1155222Sksewell@umich.edu            Name = "%s_%s" % (mnem.upper(), Name)
1165222Sksewell@umich.edu            base = buildMemBase("MemoryExImm", post, writeback)
1175222Sksewell@umich.edu            postAccCode = "Result = !writeResult;"
1186378Sgblack@eecs.umich.edu            execTemplateBase = 'StoreEx'
1195222Sksewell@umich.edu        else:
1205222Sksewell@umich.edu            if vstr:
1215222Sksewell@umich.edu                Name = "%s_%s" % (mnem.upper(), Name)
1225222Sksewell@umich.edu            else:
1236378Sgblack@eecs.umich.edu                memFlags.append("ArmISA::TLB::AllowUnaligned")
1245222Sksewell@umich.edu            base = buildMemBase("MemoryImm", post, writeback)
1255222Sksewell@umich.edu            postAccCode = ""
1265222Sksewell@umich.edu            execTemplateBase = 'Store'
1275222Sksewell@umich.edu
1286378Sgblack@eecs.umich.edu        emitStore(name, Name, True, eaCode, accCode, postAccCode, \
1295222Sksewell@umich.edu                  memFlags, [], base, strex=strex,
1305222Sksewell@umich.edu                  execTemplateBase = execTemplateBase)
1315222Sksewell@umich.edu
1325222Sksewell@umich.edu    def buildSrsStore(mnem, post, add, writeback):
1335222Sksewell@umich.edu        name = mnem
1345222Sksewell@umich.edu        Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
1356378Sgblack@eecs.umich.edu
1365222Sksewell@umich.edu        offset = 0
1375222Sksewell@umich.edu        if post != add:
1385222Sksewell@umich.edu            offset += 4
1395222Sksewell@umich.edu        if not add:
1405222Sksewell@umich.edu            offset -= 8
1415222Sksewell@umich.edu
1425222Sksewell@umich.edu        eaCode = "EA = SpMode + %d;" % offset
1435222Sksewell@umich.edu
1445222Sksewell@umich.edu        wbDiff = -8
1455222Sksewell@umich.edu        if add:
1465222Sksewell@umich.edu            wbDiff = 8
1475222Sksewell@umich.edu        accCode = '''
1485222Sksewell@umich.edu        CPSR cpsr = Cpsr;
1495222Sksewell@umich.edu        Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
1505222Sksewell@umich.edu                 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
1515222Sksewell@umich.edu        '''
1525222Sksewell@umich.edu        if writeback:
1535222Sksewell@umich.edu            accCode += "SpMode = SpMode + %s;\n" % wbDiff
1545222Sksewell@umich.edu
1555222Sksewell@umich.edu        global header_output, decoder_output, exec_output
1565222Sksewell@umich.edu
157        (newHeader,
158         newDecoder,
159         newExec) = SrsBase(name, Name, eaCode, accCode,
160             ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [])
161
162        header_output += newHeader
163        decoder_output += newDecoder
164        exec_output += newExec
165
166    def buildRegStore(mnem, post, add, writeback, \
167                      size=4, sign=False, user=False, strex=False):
168        name = mnem
169        Name = storeRegClassName(post, add, writeback,
170                                 size, sign, user)
171
172        if add:
173            op = " +"
174        else:
175            op = " -"
176
177        offset = op + " shift_rm_imm(Index, shiftAmt," + \
178                      " shiftType, CondCodes<29:>)"
179        eaCode = "EA = Base"
180        if not post:
181            eaCode += offset
182        eaCode += ";"
183
184        accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \
185            { "suffix" : buildMemSuffix(sign, size) }
186        if writeback:
187            accCode += "Base = Base %s;\n" % offset
188        base = buildMemBase("MemoryReg", post, writeback)
189
190        memFlags = ["ArmISA::TLB::MustBeOne", \
191                 "ArmISA::TLB::AllowUnaligned", \
192                 "%d" % (size - 1)]
193        if user:
194            memFlags.append("ArmISA::TLB::UserMode")
195
196        emitStore(name, Name, False, eaCode, accCode, "",\
197                memFlags, [], base)
198
199    def buildDoubleImmStore(mnem, post, add, writeback, \
200                            strex=False, vstr=False):
201        name = mnem
202        Name = storeDoubleImmClassName(post, add, writeback)
203
204        if add:
205            op = " +"
206        else:
207            op = " -"
208
209        offset = op + " imm"
210        eaCode = "EA = Base"
211        if not post:
212            eaCode += offset
213        eaCode += ";"
214
215        if vstr:
216            accCode = '''
217            uint64_t swappedMem  = (uint64_t)FpDest.uw |
218                                   ((uint64_t)FpDest2.uw << 32);
219            Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
220            '''
221        else:
222            accCode = '''
223            CPSR cpsr = Cpsr;
224            Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
225                     ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
226            '''
227        if writeback:
228            accCode += "Base = Base %s;\n" % offset
229
230        memFlags = ["ArmISA::TLB::MustBeOne",
231                    "ArmISA::TLB::AlignWord"]
232        if strex:
233            memFlags.append("Request::LLSC")
234            base = buildMemBase("MemoryExDImm", post, writeback)
235            postAccCode = "Result = !writeResult;"
236        else:
237            base = buildMemBase("MemoryDImm", post, writeback)
238            postAccCode = ""
239        if vstr or strex:
240            Name = "%s_%s" % (mnem.upper(), Name)
241
242        emitStore(name, Name, True, eaCode, accCode, postAccCode, \
243                  memFlags, [], base, double=True, strex=strex)
244
245    def buildDoubleRegStore(mnem, post, add, writeback):
246        name = mnem
247        Name = storeDoubleRegClassName(post, add, writeback)
248
249        if add:
250            op = " +"
251        else:
252            op = " -"
253
254        offset = op + " shift_rm_imm(Index, shiftAmt," + \
255                      " shiftType, CondCodes<29:>)"
256        eaCode = "EA = Base"
257        if not post:
258            eaCode += offset
259        eaCode += ";"
260
261        accCode = '''
262        CPSR cpsr = Cpsr;
263        Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
264                 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
265        '''
266        if writeback:
267            accCode += "Base = Base %s;\n" % offset
268        base = buildMemBase("MemoryDReg", post, writeback)
269
270        memFlags = ["ArmISA::TLB::MustBeOne",
271                    "ArmISA::TLB::AlignWord"]
272
273        emitStore(name, Name, False, eaCode, accCode, "", \
274                  memFlags, [], base, double=True)
275
276    def buildStores(mnem, size=4, sign=False, user=False):
277        buildImmStore(mnem, True, True, True, size, sign, user)
278        buildRegStore(mnem, True, True, True, size, sign, user)
279        buildImmStore(mnem, True, False, True, size, sign, user)
280        buildRegStore(mnem, True, False, True, size, sign, user)
281        buildImmStore(mnem, False, True, True, size, sign, user)
282        buildRegStore(mnem, False, True, True, size, sign, user)
283        buildImmStore(mnem, False, False, True, size, sign, user)
284        buildRegStore(mnem, False, False, True, size, sign, user)
285        buildImmStore(mnem, False, True, False, size, sign, user)
286        buildRegStore(mnem, False, True, False, size, sign, user)
287        buildImmStore(mnem, False, False, False, size, sign, user)
288        buildRegStore(mnem, False, False, False, size, sign, user)
289
290    def buildDoubleStores(mnem):
291        buildDoubleImmStore(mnem, True, True, True)
292        buildDoubleRegStore(mnem, True, True, True)
293        buildDoubleImmStore(mnem, True, False, True)
294        buildDoubleRegStore(mnem, True, False, True)
295        buildDoubleImmStore(mnem, False, True, True)
296        buildDoubleRegStore(mnem, False, True, True)
297        buildDoubleImmStore(mnem, False, False, True)
298        buildDoubleRegStore(mnem, False, False, True)
299        buildDoubleImmStore(mnem, False, True, False)
300        buildDoubleRegStore(mnem, False, True, False)
301        buildDoubleImmStore(mnem, False, False, False)
302        buildDoubleRegStore(mnem, False, False, False)
303
304    def buildSrsStores(mnem):
305        buildSrsStore(mnem, True, True, True)
306        buildSrsStore(mnem, True, True, False)
307        buildSrsStore(mnem, True, False, True)
308        buildSrsStore(mnem, True, False, False)
309        buildSrsStore(mnem, False, True, True)
310        buildSrsStore(mnem, False, True, False)
311        buildSrsStore(mnem, False, False, True)
312        buildSrsStore(mnem, False, False, False)
313
314    buildStores("str")
315    buildStores("strt", user=True)
316    buildStores("strb", size=1)
317    buildStores("strbt", size=1, user=True)
318    buildStores("strh", size=2)
319    buildStores("strht", size=2, user=True)
320
321    buildSrsStores("srs")
322
323    buildDoubleStores("strd")
324
325    buildImmStore("strex", False, True, False, size=4, strex=True)
326    buildImmStore("strexh", False, True, False, size=2, strex=True)
327    buildImmStore("strexb", False, True, False, size=1, strex=True)
328    buildDoubleImmStore("strexd", False, True, False, strex=True)
329
330    buildImmStore("vstr", False, True, False, size=4, vstr=True)
331    buildImmStore("vstr", False, False, False, size=4, vstr=True)
332    buildDoubleImmStore("vstr", False, True, False, vstr=True)
333    buildDoubleImmStore("vstr", False, False, False, vstr=True)
334}};
335