3 // Copyright (c) 2010-2012 ARM Limited
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.
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.
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.
40 class LoadStoreInst(object):
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')
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)
55 eaCode = codeBlobs["ea_code"]
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) + ';')
62 codeBlobs["ea_code"] = eaCode
65 # For AArch64 the fa_code snippet comes already assembled here
66 codeBlobs["fa_code"] = faCode
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);
74 ''' %("0" if size == 1 else
75 "1" if size == 2 else "2",
76 "true" if sign else "false")
78 codeBlobs["fa_code"] = ''
81 instFlagsCopy = list(instFlags)
82 codeBlobsCopy = dict(codeBlobs)
85 if wbDecl is not None or pcDecl is not None:
86 instFlagsCopy.append('IsMicroop')
92 if wbDecl is not None:
94 if pcDecl is not None:
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
106 codeBlobsCopy['is_ras_pop'] = is_ras_pop
107 if 'memacc_epilog_code' in codeBlobsCopy:
108 del codeBlobsCopy['memacc_epilog_code']
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)
120 if wbDecl is not None or pcDecl is not None:
121 iop = InstObjParams(name, macroName, base,
122 { "wb_decl" : wbDecl,
125 "use_uops" : use_uops,
129 "is_ras_pop" : is_ras_pop },
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)
137 return (header_output, decoder_output, exec_output)
139 def pickPredicate(blobs):
144 if not isinstance(blobs, dict):
147 vals = blobs.values()
149 if re.search('(?<!Opt)CondCodesNZ(?!.*=)', val):
151 if re.search('OptShiftRmCondCodesC(?!.*=)', val):
152 opt_c = 'opt_shift_rm'
153 elif re.search('(?<!Opt)CondCodesC(?!.*=)', val):
155 if re.search('(?<!Opt)CondCodesV(?!.*=)', val):
158 # Build up the predicate piece by piece depending on which
159 # flags the instruction needs
160 predicate = 'testPredicate('
162 predicate += 'OptCondCodesNZ, '
164 predicate += 'CondCodesNZ, '
166 predicate += 'OptCondCodesC, '
167 elif opt_c == 'opt_shift_rm':
168 predicate += 'OptShiftRmCondCodesC, '
170 predicate += 'CondCodesC, '
172 predicate += 'OptCondCodesV, '
174 predicate += 'CondCodesV, '
175 predicate += 'condCode)'
176 predicate += '/*auto*/'
179 def memClassName(base, post, add, writeback, \
180 size=4, sign=False, user=False):
183 parts = { "P" : post, "A" : add, "W" : writeback,
184 "S" : sign, "U" : user }
186 for (letter, val) in parts.items():
188 Name += "_%sY" % letter
190 Name += "_%sN" % letter
192 Name += ('_SZ%d' % size)
196 def buildMemSuffix(sign, size):
217 raise Exception, "Unrecognized size for access %d" % size
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
229 raise Exception, "Illegal combination of post and writeback"