str.isa revision 7345
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 strex:
111            memFlags.append("Request::LLSC")
112            Name = "%s_%s" % (mnem.upper(), Name)
113            base = buildMemBase("MemoryExImm", post, writeback)
114            postAccCode = "Result = !writeResult;"
115            execTemplateBase = 'StoreEx'
116        else:
117            if vstr:
118                Name = "%s_%s" % (mnem.upper(), Name)
119            else:
120                memFlags.append("ArmISA::TLB::AllowUnaligned")
121            base = buildMemBase("MemoryImm", post, writeback)
122            postAccCode = ""
123            execTemplateBase = 'Store'
124
125        emitStore(name, Name, True, eaCode, accCode, postAccCode, \
126                  memFlags, [], base, strex=strex,
127                  execTemplateBase = execTemplateBase)
128
129    def buildSrsStore(mnem, post, add, writeback):
130        name = mnem
131        Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
132
133        offset = 0
134        if post != add:
135            offset += 4
136        if not add:
137            offset -= 8
138
139        eaCode = "EA = SpMode + %d;" % offset
140
141        wbDiff = -8
142        if add:
143            wbDiff = 8
144        accCode = '''
145        CPSR cpsr = Cpsr;
146        Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
147                 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
148        '''
149        if writeback:
150            accCode += "SpMode = SpMode + %s;\n" % wbDiff
151
152        global header_output, decoder_output, exec_output
153
154        (newHeader,
155         newDecoder,
156         newExec) = SrsBase(name, Name, eaCode, accCode,
157             ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [])
158
159        header_output += newHeader
160        decoder_output += newDecoder
161        exec_output += newExec
162
163    def buildRegStore(mnem, post, add, writeback, \
164                      size=4, sign=False, user=False, strex=False):
165        name = mnem
166        Name = storeRegClassName(post, add, writeback,
167                                 size, sign, user)
168
169        if add:
170            op = " +"
171        else:
172            op = " -"
173
174        offset = op + " shift_rm_imm(Index, shiftAmt," + \
175                      " shiftType, CondCodes<29:>)"
176        eaCode = "EA = Base"
177        if not post:
178            eaCode += offset
179        eaCode += ";"
180
181        accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \
182            { "suffix" : buildMemSuffix(sign, size) }
183        if writeback:
184            accCode += "Base = Base %s;\n" % offset
185        base = buildMemBase("MemoryReg", post, writeback)
186
187        emitStore(name, Name, False, eaCode, accCode, "",\
188                ["ArmISA::TLB::MustBeOne", \
189                 "ArmISA::TLB::AllowUnaligned", \
190                 "%d" % (size - 1)], [], base)
191
192    def buildDoubleImmStore(mnem, post, add, writeback, \
193                            strex=False, vstr=False):
194        name = mnem
195        Name = storeDoubleImmClassName(post, add, writeback)
196
197        if add:
198            op = " +"
199        else:
200            op = " -"
201
202        offset = op + " imm"
203        eaCode = "EA = Base"
204        if not post:
205            eaCode += offset
206        eaCode += ";"
207
208        if vstr:
209            accCode = '''
210            uint64_t swappedMem  = (uint64_t)FpDest.uw |
211                                   ((uint64_t)FpDest2.uw << 32);
212            Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
213            '''
214        else:
215            accCode = '''
216            CPSR cpsr = Cpsr;
217            Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
218                     ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
219            '''
220        if writeback:
221            accCode += "Base = Base %s;\n" % offset
222
223        memFlags = ["ArmISA::TLB::MustBeOne",
224                    "ArmISA::TLB::AlignWord"]
225        if strex:
226            memFlags.append("Request::LLSC")
227            base = buildMemBase("MemoryExDImm", post, writeback)
228            postAccCode = "Result = !writeResult;"
229        else:
230            base = buildMemBase("MemoryDImm", post, writeback)
231            postAccCode = ""
232        if vstr or strex:
233            Name = "%s_%s" % (mnem.upper(), Name)
234
235        emitStore(name, Name, True, eaCode, accCode, postAccCode, \
236                  memFlags, [], base, double=True, strex=strex)
237
238    def buildDoubleRegStore(mnem, post, add, writeback):
239        name = mnem
240        Name = storeDoubleRegClassName(post, add, writeback)
241
242        if add:
243            op = " +"
244        else:
245            op = " -"
246
247        offset = op + " shift_rm_imm(Index, shiftAmt," + \
248                      " shiftType, CondCodes<29:>)"
249        eaCode = "EA = Base"
250        if not post:
251            eaCode += offset
252        eaCode += ";"
253
254        accCode = '''
255        CPSR cpsr = Cpsr;
256        Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
257                 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
258        '''
259        if writeback:
260            accCode += "Base = Base %s;\n" % offset
261        base = buildMemBase("MemoryDReg", post, writeback)
262
263        memFlags = ["ArmISA::TLB::MustBeOne",
264                    "ArmISA::TLB::AlignWord"]
265
266        emitStore(name, Name, False, eaCode, accCode, "", \
267                  memFlags, [], base, double=True)
268
269    def buildStores(mnem, size=4, sign=False, user=False):
270        buildImmStore(mnem, True, True, True, size, sign, user)
271        buildRegStore(mnem, True, True, True, size, sign, user)
272        buildImmStore(mnem, True, False, True, size, sign, user)
273        buildRegStore(mnem, True, False, True, size, sign, user)
274        buildImmStore(mnem, False, True, True, size, sign, user)
275        buildRegStore(mnem, False, True, True, size, sign, user)
276        buildImmStore(mnem, False, False, True, size, sign, user)
277        buildRegStore(mnem, False, False, True, size, sign, user)
278        buildImmStore(mnem, False, True, False, size, sign, user)
279        buildRegStore(mnem, False, True, False, size, sign, user)
280        buildImmStore(mnem, False, False, False, size, sign, user)
281        buildRegStore(mnem, False, False, False, size, sign, user)
282
283    def buildDoubleStores(mnem):
284        buildDoubleImmStore(mnem, True, True, True)
285        buildDoubleRegStore(mnem, True, True, True)
286        buildDoubleImmStore(mnem, True, False, True)
287        buildDoubleRegStore(mnem, True, False, True)
288        buildDoubleImmStore(mnem, False, True, True)
289        buildDoubleRegStore(mnem, False, True, True)
290        buildDoubleImmStore(mnem, False, False, True)
291        buildDoubleRegStore(mnem, False, False, True)
292        buildDoubleImmStore(mnem, False, True, False)
293        buildDoubleRegStore(mnem, False, True, False)
294        buildDoubleImmStore(mnem, False, False, False)
295        buildDoubleRegStore(mnem, False, False, False)
296
297    def buildSrsStores(mnem):
298        buildSrsStore(mnem, True, True, True)
299        buildSrsStore(mnem, True, True, False)
300        buildSrsStore(mnem, True, False, True)
301        buildSrsStore(mnem, True, False, False)
302        buildSrsStore(mnem, False, True, True)
303        buildSrsStore(mnem, False, True, False)
304        buildSrsStore(mnem, False, False, True)
305        buildSrsStore(mnem, False, False, False)
306
307    buildStores("str")
308    buildStores("strt", user=True)
309    buildStores("strb", size=1)
310    buildStores("strbt", size=1, user=True)
311    buildStores("strh", size=2)
312    buildStores("strht", size=2, user=True)
313
314    buildSrsStores("srs")
315
316    buildDoubleStores("strd")
317
318    buildImmStore("strex", False, True, False, size=4, strex=True)
319    buildImmStore("strexh", False, True, False, size=2, strex=True)
320    buildImmStore("strexb", False, True, False, size=1, strex=True)
321    buildDoubleImmStore("strexd", False, True, False, strex=True)
322
323    buildImmStore("vstr", False, True, False, size=4, vstr=True)
324    buildImmStore("vstr", False, False, False, size=4, vstr=True)
325    buildDoubleImmStore("vstr", False, True, False, vstr=True)
326    buildDoubleImmStore("vstr", False, False, False, vstr=True)
327}};
328