blob: 6e5122c6aa40df9ebe47b4d3bf7225d6953bed29 [file] [log] [blame]
Gabe Black81fdced2010-06-02 12:58:01 -05001// -*- mode:c++ -*-
2
Giacomo Travaglini6379beb2019-01-18 11:42:59 +00003// Copyright (c) 2010-2011,2019 ARM Limited
Gabe Black81fdced2010-06-02 12:58:01 -05004// 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 {{
ARM gem5 Developers612f8f02014-01-24 15:29:34 -060041 import math
Gabe Black81fdced2010-06-02 12:58:01 -050042
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
Gabe Blackd1362d52010-08-23 11:18:40 -050047 class LoadInst(LoadStoreInst):
48 execBase = 'Load'
Gabe Black81fdced2010-06-02 12:58:01 -050049
Gabe Blackd1362d52010-08-23 11:18:40 -050050 def __init__(self, mnem, post, add, writeback,
51 size=4, sign=False, user=False, flavor="normal"):
52 super(LoadInst, self).__init__()
53
54 self.name = mnem
55 self.post = post
56 self.add = add
57 self.writeback = writeback
58 self.size = size
59 self.sign = sign
60 self.user = user
61 self.flavor = flavor
Ali Saidibe096f92011-04-04 11:42:27 -050062 self.rasPop = False
Gabe Blackd1362d52010-08-23 11:18:40 -050063
64 if self.add:
65 self.op = " +"
66 else:
67 self.op = " -"
68
69 self.memFlags = ["ArmISA::TLB::MustBeOne"]
70 self.codeBlobs = {"postacc_code" : ""}
71
Matt Horsnell031f3962011-03-17 19:20:19 -050072 def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = [], pcDecl = None):
Gabe Blackd1362d52010-08-23 11:18:40 -050073
74 global header_output, decoder_output, exec_output
75
76 codeBlobs = self.codeBlobs
77 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
78 (newHeader,
79 newDecoder,
80 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
Matt Horsnell031f3962011-03-17 19:20:19 -050081 self.memFlags, instFlags, base,
ARM gem5 Developers612f8f02014-01-24 15:29:34 -060082 wbDecl, pcDecl, self.rasPop,
83 self.size, self.sign)
Gabe Blackd1362d52010-08-23 11:18:40 -050084
85 header_output += newHeader
86 decoder_output += newDecoder
87 exec_output += newExec
88
89 class RfeInst(LoadInst):
90 decConstBase = 'Rfe'
91
92 def __init__(self, mnem, post, add, writeback):
93 super(RfeInst, self).__init__(mnem, post, add, writeback)
94 self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
95
96 self.memFlags.append("ArmISA::TLB::AlignWord")
97
98 def emit(self):
99 offset = 0
100 if self.post != self.add:
101 offset += 4
102 if not self.add:
103 offset -= 8
104 self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset
105
106 wbDiff = -8
107 if self.add:
108 wbDiff = 8
109 accCode = '''
110 CPSR cpsr = Cpsr;
Ali Saidi401165c2011-05-13 17:27:01 -0500111 cpsr.nz = CondCodesNZ;
112 cpsr.c = CondCodesC;
113 cpsr.v = CondCodesV;
114 cpsr.ge = CondCodesGE;
115 URc = cpsr;
Gabe Black997cbe12011-09-26 23:48:54 -0700116 URa = cSwap<uint32_t>(Mem_ud, cpsr.e);
117 URb = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e);
Gabe Blackd1362d52010-08-23 11:18:40 -0500118 '''
Gabe Blackd1362d52010-08-23 11:18:40 -0500119 self.codeBlobs["memacc_code"] = accCode
120
Gene WU4d8f4db2010-08-25 19:10:42 -0500121 wbDecl = None
Matt Horsnell031f3962011-03-17 19:20:19 -0500122 pcDecl = "MicroUopSetPCCPSR(machInst, INTREG_UREG0, INTREG_UREG1, INTREG_UREG2);"
123
Gene WU4d8f4db2010-08-25 19:10:42 -0500124 if self.writeback:
125 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
Matt Horsnell031f3962011-03-17 19:20:19 -0500126 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"], pcDecl)
Gabe Blackd1362d52010-08-23 11:18:40 -0500127
128 class LoadImmInst(LoadInst):
129 def __init__(self, *args, **kargs):
130 super(LoadImmInst, self).__init__(*args, **kargs)
131 self.offset = self.op + " imm"
132
Gene WU4d8f4db2010-08-25 19:10:42 -0500133 if self.add:
134 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
135 else:
136 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
137
Ali Saidibe096f92011-04-04 11:42:27 -0500138 if self.add and self.post and self.writeback and not self.sign and \
139 not self.user and self.size == 4:
140 self.rasPop = True
141
Gabe Blackd1362d52010-08-23 11:18:40 -0500142 class LoadRegInst(LoadInst):
143 def __init__(self, *args, **kargs):
144 super(LoadRegInst, self).__init__(*args, **kargs)
145 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
Ali Saidi05866c82011-05-13 17:27:02 -0500146 " shiftType, OptShiftRmCondCodesC)"
Gene WU4d8f4db2010-08-25 19:10:42 -0500147 if self.add:
148 self.wbDecl = '''
149 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
150 '''
151 else:
152 self.wbDecl = '''
153 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
154 '''
Gabe Blackd1362d52010-08-23 11:18:40 -0500155
156 class LoadSingle(LoadInst):
157 def __init__(self, *args, **kargs):
158 super(LoadSingle, self).__init__(*args, **kargs)
159
160 # Build the default class name
161 self.Name = self.nameFunc(self.post, self.add, self.writeback,
162 self.size, self.sign, self.user)
163
164 # Add memory request flags where necessary
ARM gem5 Developers612f8f02014-01-24 15:29:34 -0600165 self.memFlags.append("%d" % int(math.log(self.size, 2)))
Gabe Blackd1362d52010-08-23 11:18:40 -0500166 if self.user:
167 self.memFlags.append("ArmISA::TLB::UserMode")
168
Ali Saidicdacbe72010-11-08 13:58:22 -0600169 self.instFlags = []
170 if self.flavor == "dprefetch":
Gabe Blackd1362d52010-08-23 11:18:40 -0500171 self.memFlags.append("Request::PREFETCH")
Ali Saidicdacbe72010-11-08 13:58:22 -0600172 self.instFlags = ['IsDataPrefetch']
173 elif self.flavor == "iprefetch":
174 self.memFlags.append("Request::PREFETCH")
175 self.instFlags = ['IsInstPrefetch']
Gabe Blackd1362d52010-08-23 11:18:40 -0500176 elif self.flavor == "normal":
177 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
178
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000179 if self.flavor in ("exclusive", "acex"):
180 self.memFlags.append("Request::LLSC")
181
182 if self.flavor in ("acquire", "acex"):
183 self.instFlags.extend(["IsMemBarrier",
184 "IsWriteBarrier",
185 "IsReadBarrier"])
186
Gabe Blackd1362d52010-08-23 11:18:40 -0500187 # Disambiguate the class name for different flavors of loads
188 if self.flavor != "normal":
189 self.Name = "%s_%s" % (self.name.upper(), self.Name)
190
191 def emit(self):
192 # Address compuation code
193 eaCode = "EA = Base"
194 if not self.post:
195 eaCode += self.offset
196 eaCode += ";"
Ali Saidi99fafb72010-08-25 19:10:42 -0500197
198 if self.flavor == "fp":
199 eaCode += vfpEnabledCheckCode
200
Gabe Blackd1362d52010-08-23 11:18:40 -0500201 self.codeBlobs["ea_code"] = eaCode
202
203 # Code that actually handles the access
Ali Saidicdacbe72010-11-08 13:58:22 -0600204 if self.flavor == "dprefetch" or self.flavor == "iprefetch":
Gabe Blackd1362d52010-08-23 11:18:40 -0500205 accCode = 'uint64_t temp = Mem%s; temp = temp;'
206 elif self.flavor == "fp":
Gabe Black997cbe12011-09-26 23:48:54 -0700207 accCode = "FpDest_uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
Gabe Blackd1362d52010-08-23 11:18:40 -0500208 else:
209 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
210 accCode = accCode % buildMemSuffix(self.sign, self.size)
211
Gabe Blackd1362d52010-08-23 11:18:40 -0500212 self.codeBlobs["memacc_code"] = accCode
213
214 # Push it out to the output files
215 base = buildMemBase(self.basePrefix, self.post, self.writeback)
Gene WU4d8f4db2010-08-25 19:10:42 -0500216 wbDecl = None
217 if self.writeback:
218 wbDecl = self.wbDecl
Ali Saidicdacbe72010-11-08 13:58:22 -0600219 self.emitHelper(base, wbDecl, self.instFlags)
Gabe Blackd1362d52010-08-23 11:18:40 -0500220
221 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
222 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
223
224 class LoadImm(LoadImmInst, LoadSingle):
Gene WU4d8f4db2010-08-25 19:10:42 -0500225 decConstBase = 'LoadImm'
Gabe Blackd1362d52010-08-23 11:18:40 -0500226 basePrefix = 'MemoryImm'
227 nameFunc = staticmethod(loadImmClassName)
228
229 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
230 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
231
232 class LoadReg(LoadRegInst, LoadSingle):
Gene WU4d8f4db2010-08-25 19:10:42 -0500233 decConstBase = 'LoadReg'
Gabe Blackd1362d52010-08-23 11:18:40 -0500234 basePrefix = 'MemoryReg'
235 nameFunc = staticmethod(loadRegClassName)
236
237 class LoadDouble(LoadInst):
238 def __init__(self, *args, **kargs):
239 super(LoadDouble, self).__init__(*args, **kargs)
240
241 # Build the default class name
242 self.Name = self.nameFunc(self.post, self.add, self.writeback)
243
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000244 self.instFlags = []
Gabe Blackd1362d52010-08-23 11:18:40 -0500245 # Add memory request flags where necessary
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000246 if self.flavor in ("exclusive", "acex"):
Gabe Blackd1362d52010-08-23 11:18:40 -0500247 self.memFlags.append("Request::LLSC")
Ali Saidi0c434b72010-08-23 11:18:40 -0500248 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
249 else:
250 self.memFlags.append("ArmISA::TLB::AlignWord")
Gabe Blackd1362d52010-08-23 11:18:40 -0500251
252 # Disambiguate the class name for different flavors of loads
253 if self.flavor != "normal":
254 self.Name = "%s_%s" % (self.name.upper(), self.Name)
255
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000256 if self.flavor in ("acquire", "acex"):
257 self.instFlags.extend(["IsMemBarrier",
258 "IsWriteBarrier",
259 "IsReadBarrier"])
260
Gabe Blackd1362d52010-08-23 11:18:40 -0500261 def emit(self):
262 # Address computation code
263 eaCode = "EA = Base"
264 if not self.post:
265 eaCode += self.offset
266 eaCode += ";"
Ali Saidi99fafb72010-08-25 19:10:42 -0500267
268 if self.flavor == "fp":
269 eaCode += vfpEnabledCheckCode
270
Gabe Blackd1362d52010-08-23 11:18:40 -0500271 self.codeBlobs["ea_code"] = eaCode
272
273 # Code that actually handles the access
274 if self.flavor != "fp":
275 accCode = '''
276 CPSR cpsr = Cpsr;
Gabe Black997cbe12011-09-26 23:48:54 -0700277 Dest = cSwap<uint32_t>(Mem_ud, cpsr.e);
278 Dest2 = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e);
Gabe Blackd1362d52010-08-23 11:18:40 -0500279 '''
280 else:
281 accCode = '''
Gabe Black997cbe12011-09-26 23:48:54 -0700282 uint64_t swappedMem = cSwap(Mem_ud, ((CPSR)Cpsr).e);
283 FpDest_uw = (uint32_t)swappedMem;
284 FpDest2_uw = (uint32_t)(swappedMem >> 32);
Gabe Blackd1362d52010-08-23 11:18:40 -0500285 '''
286
Gabe Blackd1362d52010-08-23 11:18:40 -0500287 self.codeBlobs["memacc_code"] = accCode
288
289 # Push it out to the output files
290 base = buildMemBase(self.basePrefix, self.post, self.writeback)
Gene WU4d8f4db2010-08-25 19:10:42 -0500291 wbDecl = None
292 if self.writeback:
293 wbDecl = self.wbDecl
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000294 self.emitHelper(base, wbDecl, self.instFlags)
Gabe Black81fdced2010-06-02 12:58:01 -0500295
Gabe Black36b6ca22010-06-02 12:58:01 -0500296 def loadDoubleImmClassName(post, add, writeback):
297 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
298
Gabe Blackd1362d52010-08-23 11:18:40 -0500299 class LoadDoubleImm(LoadImmInst, LoadDouble):
300 decConstBase = 'LoadStoreDImm'
301 basePrefix = 'MemoryDImm'
302 nameFunc = staticmethod(loadDoubleImmClassName)
303
Gabe Black36b6ca22010-06-02 12:58:01 -0500304 def loadDoubleRegClassName(post, add, writeback):
305 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
306
Gabe Blackd1362d52010-08-23 11:18:40 -0500307 class LoadDoubleReg(LoadRegInst, LoadDouble):
Gene WU4d8f4db2010-08-25 19:10:42 -0500308 decConstBase = 'LoadDReg'
Gabe Blackd1362d52010-08-23 11:18:40 -0500309 basePrefix = 'MemoryDReg'
310 nameFunc = staticmethod(loadDoubleRegClassName)
Gabe Black36b6ca22010-06-02 12:58:01 -0500311
Gabe Black81fdced2010-06-02 12:58:01 -0500312 def buildLoads(mnem, size=4, sign=False, user=False):
Gabe Blackd1362d52010-08-23 11:18:40 -0500313 LoadImm(mnem, True, True, True, size, sign, user).emit()
314 LoadReg(mnem, True, True, True, size, sign, user).emit()
315 LoadImm(mnem, True, False, True, size, sign, user).emit()
316 LoadReg(mnem, True, False, True, size, sign, user).emit()
317 LoadImm(mnem, False, True, True, size, sign, user).emit()
318 LoadReg(mnem, False, True, True, size, sign, user).emit()
319 LoadImm(mnem, False, False, True, size, sign, user).emit()
320 LoadReg(mnem, False, False, True, size, sign, user).emit()
321 LoadImm(mnem, False, True, False, size, sign, user).emit()
322 LoadReg(mnem, False, True, False, size, sign, user).emit()
323 LoadImm(mnem, False, False, False, size, sign, user).emit()
324 LoadReg(mnem, False, False, False, size, sign, user).emit()
Gabe Black81fdced2010-06-02 12:58:01 -0500325
Gabe Black36b6ca22010-06-02 12:58:01 -0500326 def buildDoubleLoads(mnem):
Gabe Blackd1362d52010-08-23 11:18:40 -0500327 LoadDoubleImm(mnem, True, True, True).emit()
328 LoadDoubleReg(mnem, True, True, True).emit()
329 LoadDoubleImm(mnem, True, False, True).emit()
330 LoadDoubleReg(mnem, True, False, True).emit()
331 LoadDoubleImm(mnem, False, True, True).emit()
332 LoadDoubleReg(mnem, False, True, True).emit()
333 LoadDoubleImm(mnem, False, False, True).emit()
334 LoadDoubleReg(mnem, False, False, True).emit()
335 LoadDoubleImm(mnem, False, True, False).emit()
336 LoadDoubleReg(mnem, False, True, False).emit()
337 LoadDoubleImm(mnem, False, False, False).emit()
338 LoadDoubleReg(mnem, False, False, False).emit()
Gabe Black36b6ca22010-06-02 12:58:01 -0500339
Gabe Blacka2cb5032010-06-02 12:58:10 -0500340 def buildRfeLoads(mnem):
Gabe Blackd1362d52010-08-23 11:18:40 -0500341 RfeInst(mnem, True, True, True).emit()
342 RfeInst(mnem, True, True, False).emit()
343 RfeInst(mnem, True, False, True).emit()
344 RfeInst(mnem, True, False, False).emit()
345 RfeInst(mnem, False, True, True).emit()
346 RfeInst(mnem, False, True, False).emit()
347 RfeInst(mnem, False, False, True).emit()
348 RfeInst(mnem, False, False, False).emit()
Gabe Blacka2cb5032010-06-02 12:58:10 -0500349
Ali Saidicdacbe72010-11-08 13:58:22 -0600350 def buildPrefetches(mnem, type):
351 LoadReg(mnem, False, False, False, size=1, flavor=type).emit()
352 LoadImm(mnem, False, False, False, size=1, flavor=type).emit()
353 LoadReg(mnem, False, True, False, size=1, flavor=type).emit()
354 LoadImm(mnem, False, True, False, size=1, flavor=type).emit()
Gabe Blacka1253ec2010-06-02 12:58:05 -0500355
Gabe Black81fdced2010-06-02 12:58:01 -0500356 buildLoads("ldr")
357 buildLoads("ldrt", user=True)
358 buildLoads("ldrb", size=1)
359 buildLoads("ldrbt", size=1, user=True)
360 buildLoads("ldrsb", size=1, sign=True)
361 buildLoads("ldrsbt", size=1, sign=True, user=True)
362 buildLoads("ldrh", size=2)
363 buildLoads("ldrht", size=2, user=True)
Rune Holmf4311d32015-06-09 09:21:15 -0400364 buildLoads("ldrsh", size=2, sign=True)
Gabe Black81fdced2010-06-02 12:58:01 -0500365 buildLoads("ldrsht", size=2, sign=True, user=True)
Gabe Black36b6ca22010-06-02 12:58:01 -0500366
367 buildDoubleLoads("ldrd")
Gabe Blacka1253ec2010-06-02 12:58:05 -0500368
Gabe Blacka2cb5032010-06-02 12:58:10 -0500369 buildRfeLoads("rfe")
370
Ali Saidicdacbe72010-11-08 13:58:22 -0600371 buildPrefetches("pld", "dprefetch")
372 buildPrefetches("pldw", "dprefetch")
373 buildPrefetches("pli", "iprefetch")
Gabe Blackf7f75ad2010-06-02 12:58:07 -0500374
Gabe Blackd1362d52010-08-23 11:18:40 -0500375 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
376 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
377 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
378 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
Gabe Black4f130682010-06-02 12:58:12 -0500379
Giacomo Travaglini6379beb2019-01-18 11:42:59 +0000380 LoadImm("lda", False, True, False, size=4, flavor="acquire").emit()
381 LoadImm("ldah", False, True, False, size=2, flavor="acquire").emit()
382 LoadImm("ldab", False, True, False, size=1, flavor="acquire").emit()
383 LoadImm("ldaex", False, True, False, size=4, flavor="acex").emit()
384 LoadImm("ldaexh", False, True, False, size=2, flavor="acex").emit()
385 LoadImm("ldaexb", False, True, False, size=1, flavor="acex").emit()
386 LoadDoubleImm("ldaexd", False, True, False, flavor="acex").emit()
387
Gabe Blackd1362d52010-08-23 11:18:40 -0500388 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
389 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
390 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
391 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
Gabe Black81fdced2010-06-02 12:58:01 -0500392}};