ldr.isa revision 7294:fda2c00880db
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 loadImmClassName(post, add, writeback, \
47                         size=4, sign=False, user=False):
48        return memClassName("LOAD_IMM", post, add, writeback,
49                            size, sign, user)
50
51    def loadRegClassName(post, add, writeback, \
52                         size=4, sign=False, user=False):
53        return memClassName("LOAD_REG", post, add, writeback,
54                            size, sign, user)
55
56    def loadDoubleImmClassName(post, add, writeback):
57        return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
58
59    def loadDoubleRegClassName(post, add, writeback):
60        return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
61
62    def emitLoad(name, Name, imm, eaCode, accCode, \
63                 memFlags, instFlags, base, double=False):
64        global header_output, decoder_output, exec_output
65
66        (newHeader,
67         newDecoder,
68         newExec) = loadStoreBase(name, Name, imm,
69                                  eaCode, accCode,
70                                  memFlags, instFlags, double,
71                                  base, execTemplateBase = 'Load')
72
73        header_output += newHeader
74        decoder_output += newDecoder
75        exec_output += newExec
76
77    def buildImmLoad(mnem, post, add, writeback, \
78                     size=4, sign=False, user=False, \
79                     prefetch=False, ldrex=False):
80        name = mnem
81        Name = loadImmClassName(post, add, writeback, \
82                                size, sign, user)
83
84        if add:
85            op = " +"
86        else:
87            op = " -"
88
89        offset = op + " imm"
90        eaCode = "EA = Base"
91        if not post:
92            eaCode += offset
93        eaCode += ";"
94
95        memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)]
96        if prefetch:
97            Name = "%s_%s" % (mnem.upper(), Name)
98            memFlags.append("Request::PREFETCH")
99            accCode = '''
100            uint64_t temp = Mem%s;\n
101            temp = temp;
102            ''' % buildMemSuffix(sign, size)
103        else:
104            if ldrex:
105                memFlags.append("Request::LLSC")
106                Name = "%s_%s" % (mnem.upper(), Name)
107            accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size)
108
109        if not prefetch and not ldrex:
110            memFlags.append("ArmISA::TLB::AllowUnaligned")
111
112        if writeback:
113            accCode += "Base = Base %s;\n" % offset
114        base = buildMemBase("MemoryImm", post, writeback)
115
116        emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base)
117
118    def buildRfeLoad(mnem, post, add, writeback):
119        name = mnem
120        Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
121
122        offset = 0
123        if post != add:
124            offset += 4
125        if not add:
126            offset -= 8
127
128        eaCode = "EA = Base + %d;" % offset
129
130        wbDiff = -8
131        if add:
132            wbDiff = 8
133        accCode = '''
134        NPC = bits(Mem.ud, 31, 0);
135        uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes,
136                                            bits(Mem.ud, 63, 32),
137                                            0xF, true);
138        Cpsr = ~CondCodesMask & newCpsr;
139        CondCodes = CondCodesMask & newCpsr;
140        '''
141        if writeback:
142            accCode += "Base = Base + %s;\n" % wbDiff
143
144        global header_output, decoder_output, exec_output
145
146        (newHeader,
147         newDecoder,
148         newExec) = RfeBase(name, Name, eaCode, accCode,
149             ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [])
150
151        header_output += newHeader
152        decoder_output += newDecoder
153        exec_output += newExec
154
155    def buildRegLoad(mnem, post, add, writeback, \
156                     size=4, sign=False, user=False, prefetch=False):
157        name = mnem
158        Name = loadRegClassName(post, add, writeback,
159                                size, sign, user)
160
161        if add:
162            op = " +"
163        else:
164            op = " -"
165
166        offset = op + " shift_rm_imm(Index, shiftAmt," + \
167                      " shiftType, CondCodes<29:>)"
168        eaCode = "EA = Base"
169        if not post:
170            eaCode += offset
171        eaCode += ";"
172
173        memFlags = ["%d" % (size - 1), "ArmISA::TLB::MustBeOne"]
174        if prefetch:
175            Name = "%s_%s" % (mnem.upper(), Name)
176            memFlags.append("Request::PREFETCH")
177            accCode = '''
178            uint64_t temp = Mem%s;\n
179            temp = temp;
180            ''' % buildMemSuffix(sign, size)
181        else:
182            accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size)
183        if writeback:
184            accCode += "Base = Base %s;\n" % offset
185
186        if not prefetch:
187            memFlags.append("ArmISA::TLB::AllowUnaligned")
188
189        base = buildMemBase("MemoryReg", post, writeback)
190
191        emitLoad(name, Name, False, eaCode, accCode, \
192                 memFlags, [], base)
193
194    def buildDoubleImmLoad(mnem, post, add, writeback, ldrex=False):
195        name = mnem
196        Name = loadDoubleImmClassName(post, add, writeback)
197
198        if add:
199            op = " +"
200        else:
201            op = " -"
202
203        offset = op + " imm"
204        eaCode = "EA = Base"
205        if not post:
206            eaCode += offset
207        eaCode += ";"
208
209        accCode = '''
210        Dest = bits(Mem.ud, 31, 0);
211        Dest2 = bits(Mem.ud, 63, 32);
212        '''
213        if ldrex:
214            memFlags = ["Request::LLSC"]
215            Name = "%s_%s" % (mnem.upper(), Name)
216        else:
217            memFlags = []
218        if writeback:
219            accCode += "Base = Base %s;\n" % offset
220        base = buildMemBase("MemoryDImm", post, writeback)
221
222        memFlags.extend(["ArmISA::TLB::MustBeOne",
223                         "ArmISA::TLB::AlignWord"])
224
225        emitLoad(name, Name, True, eaCode, accCode, \
226                 memFlags, [], base, double=True)
227
228    def buildDoubleRegLoad(mnem, post, add, writeback):
229        name = mnem
230        Name = loadDoubleRegClassName(post, add, writeback)
231
232        if add:
233            op = " +"
234        else:
235            op = " -"
236
237        offset = op + " shift_rm_imm(Index, shiftAmt," + \
238                      " shiftType, CondCodes<29:>)"
239        eaCode = "EA = Base"
240        if not post:
241            eaCode += offset
242        eaCode += ";"
243
244        accCode = '''
245        Dest = bits(Mem.ud, 31, 0);
246        Dest2 = bits(Mem.ud, 63, 32);
247        '''
248        if writeback:
249            accCode += "Base = Base %s;\n" % offset
250        base = buildMemBase("MemoryDReg", post, writeback)
251
252        emitLoad(name, Name, False, eaCode, accCode,
253                 ["ArmISA::TLB::MustBeOne", "ArmISA::TLB::AlignWord"],
254                 [], base, double=True)
255
256    def buildLoads(mnem, size=4, sign=False, user=False):
257        buildImmLoad(mnem, True, True, True, size, sign, user)
258        buildRegLoad(mnem, True, True, True, size, sign, user)
259        buildImmLoad(mnem, True, False, True, size, sign, user)
260        buildRegLoad(mnem, True, False, True, size, sign, user)
261        buildImmLoad(mnem, False, True, True, size, sign, user)
262        buildRegLoad(mnem, False, True, True, size, sign, user)
263        buildImmLoad(mnem, False, False, True, size, sign, user)
264        buildRegLoad(mnem, False, False, True, size, sign, user)
265        buildImmLoad(mnem, False, True, False, size, sign, user)
266        buildRegLoad(mnem, False, True, False, size, sign, user)
267        buildImmLoad(mnem, False, False, False, size, sign, user)
268        buildRegLoad(mnem, False, False, False, size, sign, user)
269
270    def buildDoubleLoads(mnem):
271        buildDoubleImmLoad(mnem, True, True, True)
272        buildDoubleRegLoad(mnem, True, True, True)
273        buildDoubleImmLoad(mnem, True, False, True)
274        buildDoubleRegLoad(mnem, True, False, True)
275        buildDoubleImmLoad(mnem, False, True, True)
276        buildDoubleRegLoad(mnem, False, True, True)
277        buildDoubleImmLoad(mnem, False, False, True)
278        buildDoubleRegLoad(mnem, False, False, True)
279        buildDoubleImmLoad(mnem, False, True, False)
280        buildDoubleRegLoad(mnem, False, True, False)
281        buildDoubleImmLoad(mnem, False, False, False)
282        buildDoubleRegLoad(mnem, False, False, False)
283
284    def buildRfeLoads(mnem):
285        buildRfeLoad(mnem, True, True, True)
286        buildRfeLoad(mnem, True, True, False)
287        buildRfeLoad(mnem, True, False, True)
288        buildRfeLoad(mnem, True, False, False)
289        buildRfeLoad(mnem, False, True, True)
290        buildRfeLoad(mnem, False, True, False)
291        buildRfeLoad(mnem, False, False, True)
292        buildRfeLoad(mnem, False, False, False)
293
294    def buildPrefetches(mnem):
295        buildRegLoad(mnem, False, False, False, size=1, prefetch=True)
296        buildImmLoad(mnem, False, False, False, size=1, prefetch=True)
297        buildRegLoad(mnem, False, True, False, size=1, prefetch=True)
298        buildImmLoad(mnem, False, True, False, size=1, prefetch=True)
299
300    buildLoads("ldr")
301    buildLoads("ldrt", user=True)
302    buildLoads("ldrb", size=1)
303    buildLoads("ldrbt", size=1, user=True)
304    buildLoads("ldrsb", size=1, sign=True)
305    buildLoads("ldrsbt", size=1, sign=True, user=True)
306    buildLoads("ldrh", size=2)
307    buildLoads("ldrht", size=2, user=True)
308    buildLoads("hdrsh", size=2, sign=True)
309    buildLoads("ldrsht", size=2, sign=True, user=True)
310
311    buildDoubleLoads("ldrd")
312
313    buildRfeLoads("rfe")
314
315    buildPrefetches("pld")
316    buildPrefetches("pldw")
317    buildPrefetches("pli")
318
319    buildImmLoad("ldrex", False, True, False, size=4, ldrex=True)
320    buildImmLoad("ldrexh", False, True, False, size=2, ldrex=True)
321    buildImmLoad("ldrexb", False, True, False, size=1, ldrex=True)
322    buildDoubleImmLoad("ldrexd", False, True, False, ldrex=True)
323}};
324