misc: string.join has been removed in python3
[gem5.git] / src / arch / arm / isa / insts / mem.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2010-2012 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
40 class LoadStoreInst(object):
41 def __init__(self):
42 self.fullExecTemplate = eval(self.execBase + 'Execute')
43 self.initiateAccTemplate = eval(self.execBase + 'InitiateAcc')
44 self.completeAccTemplate = eval(self.execBase + 'CompleteAcc')
45 self.declareTemplate = eval(self.decConstBase + 'Declare')
46 self.constructTemplate = eval(self.decConstBase + 'Constructor')
47
48 def fillTemplates(self, name, Name, codeBlobs, memFlags, instFlags,
49 base='Memory', wbDecl=None, pcDecl=None,
50 rasPop=False, size=4, sign=False, faCode=None):
51 # Make sure flags are in lists (convert to lists if not).
52 memFlags = makeList(memFlags)
53 instFlags = makeList(instFlags)
54
55 eaCode = codeBlobs["ea_code"]
56
57 # This shouldn't be part of the eaCode, but until the exec templates
58 # are converted over it's the easiest place to put it.
59 eaCode += '\n unsigned memAccessFlags = '
60 eaCode += ('|'.join(memFlags) + ';')
61
62 codeBlobs["ea_code"] = eaCode
63
64 if faCode:
65 # For AArch64 the fa_code snippet comes already assembled here
66 codeBlobs["fa_code"] = faCode
67 elif wbDecl == None:
68 codeBlobs["fa_code"] = '''
69 if (dest != INTREG_PC) {
70 fault->annotate(ArmFault::SAS, %s);
71 fault->annotate(ArmFault::SSE, %s);
72 fault->annotate(ArmFault::SRT, dest);
73 }
74 ''' %("0" if size == 1 else
75 "1" if size == 2 else "2",
76 "true" if sign else "false")
77 else:
78 codeBlobs["fa_code"] = ''
79
80 macroName = Name
81 instFlagsCopy = list(instFlags)
82 codeBlobsCopy = dict(codeBlobs)
83
84 use_uops = 0
85 if wbDecl is not None or pcDecl is not None:
86 instFlagsCopy.append('IsMicroop')
87 Name = Name + 'Acc'
88 use_uops = 1
89
90 use_wb = 0
91 use_pc = 0
92 if wbDecl is not None:
93 use_wb = 1
94 if pcDecl is not None:
95 use_pc = 1
96
97 codeBlobsCopy['acc_name'] = Name
98 codeBlobsCopy['wb_decl'] = wbDecl
99 codeBlobsCopy['pc_decl'] = pcDecl
100 codeBlobsCopy['use_uops'] = 0
101 codeBlobsCopy['use_wb'] = 0
102 codeBlobsCopy['use_pc'] = 0
103 is_ras_pop = "0"
104 if rasPop:
105 is_ras_pop = "1"
106 codeBlobsCopy['is_ras_pop'] = is_ras_pop
107 if 'memacc_epilog_code' in codeBlobsCopy:
108 del codeBlobsCopy['memacc_epilog_code']
109
110 iop = InstObjParams(name, Name, base,
111 codeBlobsCopy, instFlagsCopy)
112 if 'memacc_epilog_code' in codeBlobs:
113 iop.snippets['memacc_code'] += codeBlobs['memacc_epilog_code']
114 header_output = self.declareTemplate.subst(iop)
115 decoder_output = self.constructTemplate.subst(iop)
116 exec_output = self.fullExecTemplate.subst(iop) + \
117 self.initiateAccTemplate.subst(iop) + \
118 self.completeAccTemplate.subst(iop)
119
120 if wbDecl is not None or pcDecl is not None:
121 iop = InstObjParams(name, macroName, base,
122 { "wb_decl" : wbDecl,
123 "pc_decl" : pcDecl,
124 "acc_name" : Name,
125 "use_uops" : use_uops,
126 "use_pc" : use_pc,
127 "use_wb" : use_wb,
128 "fa_code" : '',
129 "is_ras_pop" : is_ras_pop },
130 ['IsMacroop'])
131 header_output += self.declareTemplate.subst(iop)
132 decoder_output += self.constructTemplate.subst(iop)
133 exec_output += PanicExecute.subst(iop) + \
134 PanicInitiateAcc.subst(iop) + \
135 PanicCompleteAcc.subst(iop)
136
137 return (header_output, decoder_output, exec_output)
138
139 def pickPredicate(blobs):
140 opt_nz = True
141 opt_c = 'opt'
142 opt_v = True
143
144 if not isinstance(blobs, dict):
145 vals = [blobs]
146 else:
147 vals = blobs.values()
148 for val in vals:
149 if re.search('(?<!Opt)CondCodesNZ(?!.*=)', val):
150 opt_nz = False
151 if re.search('OptShiftRmCondCodesC(?!.*=)', val):
152 opt_c = 'opt_shift_rm'
153 elif re.search('(?<!Opt)CondCodesC(?!.*=)', val):
154 opt_c = 'none'
155 if re.search('(?<!Opt)CondCodesV(?!.*=)', val):
156 opt_v = False
157
158 # Build up the predicate piece by piece depending on which
159 # flags the instruction needs
160 predicate = 'testPredicate('
161 if opt_nz:
162 predicate += 'OptCondCodesNZ, '
163 else:
164 predicate += 'CondCodesNZ, '
165 if opt_c == 'opt':
166 predicate += 'OptCondCodesC, '
167 elif opt_c == 'opt_shift_rm':
168 predicate += 'OptShiftRmCondCodesC, '
169 else:
170 predicate += 'CondCodesC, '
171 if opt_v:
172 predicate += 'OptCondCodesV, '
173 else:
174 predicate += 'CondCodesV, '
175 predicate += 'condCode)'
176 predicate += '/*auto*/'
177 return predicate
178
179 def memClassName(base, post, add, writeback, \
180 size=4, sign=False, user=False):
181 Name = base
182
183 parts = { "P" : post, "A" : add, "W" : writeback,
184 "S" : sign, "U" : user }
185
186 for (letter, val) in parts.items():
187 if val:
188 Name += "_%sY" % letter
189 else:
190 Name += "_%sN" % letter
191
192 Name += ('_SZ%d' % size)
193
194 return Name
195
196 def buildMemSuffix(sign, size):
197 if size == 16:
198 memSuffix = '_tud'
199 elif size == 8:
200 memSuffix = '_ud'
201 elif size == 4:
202 if sign:
203 memSuffix = '_sw'
204 else:
205 memSuffix = '_uw'
206 elif size == 2:
207 if sign:
208 memSuffix = '_sh'
209 else:
210 memSuffix = '_uh'
211 elif size == 1:
212 if sign:
213 memSuffix = '_sb'
214 else:
215 memSuffix = '_ub'
216 else:
217 raise Exception, "Unrecognized size for access %d" % size
218
219 return memSuffix
220
221 def buildMemBase(base, post, writeback):
222 if post and writeback:
223 base = "MemoryPostIndex<%s>" % base
224 elif not post and writeback:
225 base = "MemoryPreIndex<%s>" % base
226 elif not post and not writeback:
227 base = "MemoryOffset<%s>" % base
228 else:
229 raise Exception, "Illegal combination of post and writeback"
230 return base
231 }};
232