str.isa revision 7404:bfc74724914e
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39
40let {{
41
42    header_output = ""
43    decoder_output = ""
44    exec_output = ""
45
46    def storeImmClassName(post, add, writeback, \
47                          size=4, sign=False, user=False):
48        return memClassName("STORE_IMM", post, add, writeback,
49                            size, sign, user)
50
51    def storeRegClassName(post, add, writeback, \
52                          size=4, sign=False, user=False):
53        return memClassName("STORE_REG", post, add, writeback,
54                            size, sign, user)
55
56    def storeDoubleImmClassName(post, add, writeback):
57        return memClassName("STORE_IMMD", post, add, writeback,
58                            4, False, False)
59
60    def storeDoubleRegClassName(post, add, writeback):
61        return memClassName("STORE_REGD", post, add, writeback,
62                            4, False, False)
63
64    def emitStore(name, Name, imm, eaCode, accCode, postAccCode, \
65                  memFlags, instFlags, base, double=False, strex=False,
66                  execTemplateBase = 'Store'):
67        global header_output, decoder_output, exec_output
68
69        (newHeader,
70         newDecoder,
71         newExec) = loadStoreBase(name, Name, imm,
72                                  eaCode, accCode, postAccCode,
73                                  memFlags, instFlags, double, strex,
74                                  base, execTemplateBase = execTemplateBase)
75
76        header_output += newHeader
77        decoder_output += newDecoder
78        exec_output += newExec
79
80    def buildImmStore(mnem, post, add, writeback, \
81                      size=4, sign=False, user=False, \
82                      strex=False, vstr=False):
83        name = mnem
84        Name = storeImmClassName(post, add, writeback, \
85                                 size, sign, user)
86
87        if add:
88            op = " +"
89        else:
90            op = " -"
91
92        offset = op + " imm"
93        eaCode = "EA = Base"
94        if not post:
95            eaCode += offset
96        eaCode += ";"
97
98        if vstr:
99            accCode = '''
100            Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);
101            ''' % { "suffix" : buildMemSuffix(sign, size) }
102        else:
103            accCode = '''
104            Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);
105            ''' % { "suffix" : buildMemSuffix(sign, size) }
106        if writeback:
107            accCode += "Base = Base %s;\n" % offset
108
109        memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
110        if user:
111            memFlags.append("ArmISA::TLB::UserMode")
112
113        if strex:
114            memFlags.append("Request::LLSC")
115            Name = "%s_%s" % (mnem.upper(), Name)
116            base = buildMemBase("MemoryExImm", post, writeback)
117            postAccCode = "Result = !writeResult;"
118            execTemplateBase = 'StoreEx'
119        else:
120            if vstr:
121                Name = "%s_%s" % (mnem.upper(), Name)
122            else:
123                memFlags.append("ArmISA::TLB::AllowUnaligned")
124            base = buildMemBase("MemoryImm", post, writeback)
125            postAccCode = ""
126            execTemplateBase = 'Store'
127
128        emitStore(name, Name, True, eaCode, accCode, postAccCode, \
129                  memFlags, [], base, strex=strex,
130                  execTemplateBase = execTemplateBase)
131
132    def buildSrsStore(mnem, post, add, writeback):
133        name = mnem
134        Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
135
136        offset = 0
137        if post != add:
138            offset += 4
139        if not add:
140            offset -= 8
141
142        eaCode = "EA = SpMode + %d;" % offset
143
144        wbDiff = -8
145        if add:
146            wbDiff = 8
147        accCode = '''
148        CPSR cpsr = Cpsr;
149        Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
150                 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
151        '''
152        if writeback:
153            accCode += "SpMode = SpMode + %s;\n" % wbDiff
154
155        global header_output, decoder_output, exec_output
156
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