arm: Delete authors lists from the arm files.
[gem5.git] / src / arch / arm / isa / insts / ldr.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2010-2011,2019 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 let {{
39 import math
40
41 header_output = ""
42 decoder_output = ""
43 exec_output = ""
44
45 class LoadInst(LoadStoreInst):
46 execBase = 'Load'
47
48 def __init__(self, mnem, post, add, writeback,
49 size=4, sign=False, user=False, flavor="normal"):
50 super(LoadInst, self).__init__()
51
52 self.name = mnem
53 self.post = post
54 self.add = add
55 self.writeback = writeback
56 self.size = size
57 self.sign = sign
58 self.user = user
59 self.flavor = flavor
60 self.rasPop = False
61
62 if self.add:
63 self.op = " +"
64 else:
65 self.op = " -"
66
67 self.memFlags = ["ArmISA::TLB::MustBeOne"]
68 self.codeBlobs = {"postacc_code" : ""}
69
70 def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = [], pcDecl = None):
71
72 global header_output, decoder_output, exec_output
73
74 codeBlobs = self.codeBlobs
75 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
76 (newHeader,
77 newDecoder,
78 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
79 self.memFlags, instFlags, base,
80 wbDecl, pcDecl, self.rasPop,
81 self.size, self.sign)
82
83 header_output += newHeader
84 decoder_output += newDecoder
85 exec_output += newExec
86
87 class RfeInst(LoadInst):
88 decConstBase = 'Rfe'
89
90 def __init__(self, mnem, post, add, writeback):
91 super(RfeInst, self).__init__(mnem, post, add, writeback)
92 self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
93
94 self.memFlags.append("ArmISA::TLB::AlignWord")
95
96 def emit(self):
97 offset = 0
98 if self.post != self.add:
99 offset += 4
100 if not self.add:
101 offset -= 8
102 self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset
103
104 wbDiff = -8
105 if self.add:
106 wbDiff = 8
107 accCode = '''
108 CPSR cpsr = Cpsr;
109 cpsr.nz = CondCodesNZ;
110 cpsr.c = CondCodesC;
111 cpsr.v = CondCodesV;
112 cpsr.ge = CondCodesGE;
113 URc = cpsr;
114 URa = cSwap<uint32_t>(Mem_ud, cpsr.e);
115 URb = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e);
116 '''
117 self.codeBlobs["memacc_code"] = accCode
118
119 wbDecl = None
120 pcDecl = "MicroUopSetPCCPSR(machInst, INTREG_UREG0, INTREG_UREG1, INTREG_UREG2);"
121
122 if self.writeback:
123 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
124 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"], pcDecl)
125
126 class LoadImmInst(LoadInst):
127 def __init__(self, *args, **kargs):
128 super(LoadImmInst, self).__init__(*args, **kargs)
129 self.offset = self.op + " imm"
130
131 if self.add:
132 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
133 else:
134 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
135
136 if self.add and self.post and self.writeback and not self.sign and \
137 not self.user and self.size == 4:
138 self.rasPop = True
139
140 class LoadRegInst(LoadInst):
141 def __init__(self, *args, **kargs):
142 super(LoadRegInst, self).__init__(*args, **kargs)
143 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
144 " shiftType, OptShiftRmCondCodesC)"
145 if self.add:
146 self.wbDecl = '''
147 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
148 '''
149 else:
150 self.wbDecl = '''
151 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
152 '''
153
154 class LoadSingle(LoadInst):
155 def __init__(self, *args, **kargs):
156 super(LoadSingle, self).__init__(*args, **kargs)
157
158 # Build the default class name
159 self.Name = self.nameFunc(self.post, self.add, self.writeback,
160 self.size, self.sign, self.user)
161
162 # Add memory request flags where necessary
163 self.memFlags.append("%d" % int(math.log(self.size, 2)))
164 if self.user:
165 self.memFlags.append("ArmISA::TLB::UserMode")
166
167 self.instFlags = []
168 if self.flavor == "dprefetch":
169 self.memFlags.append("Request::PREFETCH")
170 self.instFlags = ['IsDataPrefetch']
171 elif self.flavor == "iprefetch":
172 self.memFlags.append("Request::PREFETCH")
173 self.instFlags = ['IsInstPrefetch']
174 elif self.flavor == "normal":
175 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
176
177 if self.flavor in ("exclusive", "acex"):
178 self.memFlags.append("Request::LLSC")
179
180 if self.flavor in ("acquire", "acex"):
181 self.instFlags.extend(["IsMemBarrier",
182 "IsWriteBarrier",
183 "IsReadBarrier"])
184
185 # Disambiguate the class name for different flavors of loads
186 if self.flavor != "normal":
187 self.Name = "%s_%s" % (self.name.upper(), self.Name)
188
189 def emit(self):
190 # Address compuation code
191 eaCode = "EA = Base"
192 if not self.post:
193 eaCode += self.offset
194 eaCode += ";"
195
196 if self.flavor == "fp":
197 eaCode += vfpEnabledCheckCode
198
199 self.codeBlobs["ea_code"] = eaCode
200
201 # Code that actually handles the access
202 if self.flavor == "dprefetch" or self.flavor == "iprefetch":
203 accCode = 'uint64_t temp = Mem%s; temp = temp;'
204 elif self.flavor == "fp":
205 accCode = "FpDest_uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
206 else:
207 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
208 accCode = accCode % buildMemSuffix(self.sign, self.size)
209
210 self.codeBlobs["memacc_code"] = accCode
211
212 # Push it out to the output files
213 base = buildMemBase(self.basePrefix, self.post, self.writeback)
214 wbDecl = None
215 if self.writeback:
216 wbDecl = self.wbDecl
217 self.emitHelper(base, wbDecl, self.instFlags)
218
219 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
220 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
221
222 class LoadImm(LoadImmInst, LoadSingle):
223 decConstBase = 'LoadImm'
224 basePrefix = 'MemoryImm'
225 nameFunc = staticmethod(loadImmClassName)
226
227 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
228 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
229
230 class LoadReg(LoadRegInst, LoadSingle):
231 decConstBase = 'LoadReg'
232 basePrefix = 'MemoryReg'
233 nameFunc = staticmethod(loadRegClassName)
234
235 class LoadDouble(LoadInst):
236 def __init__(self, *args, **kargs):
237 super(LoadDouble, self).__init__(*args, **kargs)
238
239 # Build the default class name
240 self.Name = self.nameFunc(self.post, self.add, self.writeback)
241
242 self.instFlags = []
243 # Add memory request flags where necessary
244 if self.flavor in ("exclusive", "acex"):
245 self.memFlags.append("Request::LLSC")
246 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
247 else:
248 self.memFlags.append("ArmISA::TLB::AlignWord")
249
250 # Disambiguate the class name for different flavors of loads
251 if self.flavor != "normal":
252 self.Name = "%s_%s" % (self.name.upper(), self.Name)
253
254 if self.flavor in ("acquire", "acex"):
255 self.instFlags.extend(["IsMemBarrier",
256 "IsWriteBarrier",
257 "IsReadBarrier"])
258
259 def emit(self):
260 # Address computation code
261 eaCode = "EA = Base"
262 if not self.post:
263 eaCode += self.offset
264 eaCode += ";"
265
266 if self.flavor == "fp":
267 eaCode += vfpEnabledCheckCode
268
269 self.codeBlobs["ea_code"] = eaCode
270
271 # Code that actually handles the access
272 if self.flavor != "fp":
273 accCode = '''
274 CPSR cpsr = Cpsr;
275 Dest = cSwap<uint32_t>(Mem_ud, cpsr.e);
276 Dest2 = cSwap<uint32_t>(Mem_ud >> 32, cpsr.e);
277 '''
278 else:
279 accCode = '''
280 uint64_t swappedMem = cSwap(Mem_ud, ((CPSR)Cpsr).e);
281 FpDest_uw = (uint32_t)swappedMem;
282 FpDest2_uw = (uint32_t)(swappedMem >> 32);
283 '''
284
285 self.codeBlobs["memacc_code"] = accCode
286
287 # Push it out to the output files
288 base = buildMemBase(self.basePrefix, self.post, self.writeback)
289 wbDecl = None
290 if self.writeback:
291 wbDecl = self.wbDecl
292 self.emitHelper(base, wbDecl, self.instFlags)
293
294 def loadDoubleImmClassName(post, add, writeback):
295 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
296
297 class LoadDoubleImm(LoadImmInst, LoadDouble):
298 decConstBase = 'LoadStoreDImm'
299 basePrefix = 'MemoryDImm'
300 nameFunc = staticmethod(loadDoubleImmClassName)
301
302 def loadDoubleRegClassName(post, add, writeback):
303 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
304
305 class LoadDoubleReg(LoadRegInst, LoadDouble):
306 decConstBase = 'LoadDReg'
307 basePrefix = 'MemoryDReg'
308 nameFunc = staticmethod(loadDoubleRegClassName)
309
310 def buildLoads(mnem, size=4, sign=False, user=False):
311 LoadImm(mnem, True, True, True, size, sign, user).emit()
312 LoadReg(mnem, True, True, True, size, sign, user).emit()
313 LoadImm(mnem, True, False, True, size, sign, user).emit()
314 LoadReg(mnem, True, False, True, size, sign, user).emit()
315 LoadImm(mnem, False, True, True, size, sign, user).emit()
316 LoadReg(mnem, False, True, True, size, sign, user).emit()
317 LoadImm(mnem, False, False, True, size, sign, user).emit()
318 LoadReg(mnem, False, False, True, size, sign, user).emit()
319 LoadImm(mnem, False, True, False, size, sign, user).emit()
320 LoadReg(mnem, False, True, False, size, sign, user).emit()
321 LoadImm(mnem, False, False, False, size, sign, user).emit()
322 LoadReg(mnem, False, False, False, size, sign, user).emit()
323
324 def buildDoubleLoads(mnem):
325 LoadDoubleImm(mnem, True, True, True).emit()
326 LoadDoubleReg(mnem, True, True, True).emit()
327 LoadDoubleImm(mnem, True, False, True).emit()
328 LoadDoubleReg(mnem, True, False, True).emit()
329 LoadDoubleImm(mnem, False, True, True).emit()
330 LoadDoubleReg(mnem, False, True, True).emit()
331 LoadDoubleImm(mnem, False, False, True).emit()
332 LoadDoubleReg(mnem, False, False, True).emit()
333 LoadDoubleImm(mnem, False, True, False).emit()
334 LoadDoubleReg(mnem, False, True, False).emit()
335 LoadDoubleImm(mnem, False, False, False).emit()
336 LoadDoubleReg(mnem, False, False, False).emit()
337
338 def buildRfeLoads(mnem):
339 RfeInst(mnem, True, True, True).emit()
340 RfeInst(mnem, True, True, False).emit()
341 RfeInst(mnem, True, False, True).emit()
342 RfeInst(mnem, True, False, False).emit()
343 RfeInst(mnem, False, True, True).emit()
344 RfeInst(mnem, False, True, False).emit()
345 RfeInst(mnem, False, False, True).emit()
346 RfeInst(mnem, False, False, False).emit()
347
348 def buildPrefetches(mnem, type):
349 LoadReg(mnem, False, False, False, size=1, flavor=type).emit()
350 LoadImm(mnem, False, False, False, size=1, flavor=type).emit()
351 LoadReg(mnem, False, True, False, size=1, flavor=type).emit()
352 LoadImm(mnem, False, True, False, size=1, flavor=type).emit()
353
354 buildLoads("ldr")
355 buildLoads("ldrt", user=True)
356 buildLoads("ldrb", size=1)
357 buildLoads("ldrbt", size=1, user=True)
358 buildLoads("ldrsb", size=1, sign=True)
359 buildLoads("ldrsbt", size=1, sign=True, user=True)
360 buildLoads("ldrh", size=2)
361 buildLoads("ldrht", size=2, user=True)
362 buildLoads("ldrsh", size=2, sign=True)
363 buildLoads("ldrsht", size=2, sign=True, user=True)
364
365 buildDoubleLoads("ldrd")
366
367 buildRfeLoads("rfe")
368
369 buildPrefetches("pld", "dprefetch")
370 buildPrefetches("pldw", "dprefetch")
371 buildPrefetches("pli", "iprefetch")
372
373 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
374 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
375 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
376 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
377
378 LoadImm("lda", False, True, False, size=4, flavor="acquire").emit()
379 LoadImm("ldah", False, True, False, size=2, flavor="acquire").emit()
380 LoadImm("ldab", False, True, False, size=1, flavor="acquire").emit()
381 LoadImm("ldaex", False, True, False, size=4, flavor="acex").emit()
382 LoadImm("ldaexh", False, True, False, size=2, flavor="acex").emit()
383 LoadImm("ldaexb", False, True, False, size=1, flavor="acex").emit()
384 LoadDoubleImm("ldaexd", False, True, False, flavor="acex").emit()
385
386 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
387 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
388 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
389 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
390 }};