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