3 // Copyright (c) 2009 The University of Edinburgh
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met: redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer;
10 // redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution;
13 // neither the name of the copyright holders nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ////////////////////////////////////////////////////////////////////
31 // Integer ALU instructions
35 // Instruction class constructor template when Rc is set.
36 def template IntRcConstructor {{
37 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
38 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
47 // Instruction class constructor template when OE is set.
48 def template IntOeConstructor {{
49 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
50 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
59 // Instruction class constructor template when both Rc and OE are set.
60 def template IntRcOeConstructor {{
61 %(class_name)s::%(class_name)s(ExtMachInst machInst) :
62 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
74 readXERCode = 'Xer xer = XER;'
76 setXERCode = 'XER = xer;'
80 cr.cr0 = makeCRField((int64_t)%(result)s, (int64_t)0, xer.so);
85 if (findCarry(64, %(result)s, %(inputa)s, %(inputb)s)) {
91 if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
99 if (findOverflow(64, %(result)s, %(inputa)s, %(inputb)s)) {
106 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
127 // A basic integer instruction.
128 def format IntOp(code, inst_flags = []) {{
129 (header_output, decoder_output, decode_block, exec_output) = \
130 GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
135 // Integer instructions with immediate (signed or unsigned).
136 def format IntImmOp(code, inst_flags = []) {{
137 (header_output, decoder_output, decode_block, exec_output) = \
138 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
143 // Integer instructions with immediate that perform arithmetic.
144 // These instructions all write to Rt and use an altered form of the
145 // value in source register Ra, hence the use of src to hold the actual
146 // value. The control flags include the use of code to compute the
147 // carry bit or the CR0 code.
148 def format IntImmArithOp(code, computeCA = 0, computeCR0 = 0,
151 # Set up the dictionary
152 dict = {'result':'Rt', 'inputa':'src', 'inputb':'simm'}
154 # Deal with computing CR0 and carry
155 if computeCA or computeCR0:
158 code += computeCACode % dict + setXERCode
160 code += computeCR0Code % dict
163 (header_output, decoder_output, decode_block, exec_output) = \
164 GenAluOp(name, Name, 'IntImmArithOp', code, inst_flags, BasicDecode,
169 // Integer instructions with immediate that perform arithmetic but use
170 // the value 0 when Ra == 0. We generate two versions of each instruction
171 // corresponding to these two different scenarios. The correct version is
172 // determined at decode (see the CheckRaDecode template).
173 def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
175 # First the version where Ra is non-zero
176 (header_output, decoder_output, decode_block, exec_output) = \
177 GenAluOp(name, Name, 'IntImmArithOp', code, inst_flags,
178 CheckRaDecode, BasicConstructor)
180 # Now another version where Ra == 0
181 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
182 GenAluOp(name, Name + 'RaZero', 'IntImmArithOp', code_ra0, inst_flags,
183 CheckRaDecode, BasicConstructor)
185 # Finally, add to the other outputs
186 header_output += header_output_ra0
187 decoder_output += decoder_output_ra0
188 exec_output += exec_output_ra0
192 // Integer instructions with immediate that perform logic operations.
193 // All instructions write to Ra and use Rs as a source register. Some
194 // also compute the CR0 code too.
195 def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
197 # Set up the dictionary and deal with computing CR0
198 dict = {'result':'Ra'}
200 code += readXERCode + computeCR0Code % dict
203 (header_output, decoder_output, decode_block, exec_output) = \
204 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
209 // Integer instructions that perform logic operations. The result is
210 // always written into Ra. All instructions have 2 versions depending on
211 // whether the Rc bit is set to compute the CR0 code. This is determined
212 // at decode as before.
213 def format IntLogicOp(code, inst_flags = []) {{
214 dict = {'result':'Ra'}
216 # Code when Rc is set
217 code_rc1 = code + readXERCode + computeCR0Code % dict
219 # Generate the first class
220 (header_output, decoder_output, decode_block, exec_output) = \
221 GenAluOp(name, Name, 'IntOp', code, inst_flags,
222 CheckRcDecode, BasicConstructor)
224 # Generate the second class
225 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
226 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
227 CheckRcDecode, IntRcConstructor)
229 # Finally, add to the other outputs
230 header_output += header_output_rc1
231 decoder_output += decoder_output_rc1
232 exec_output += exec_output_rc1
236 // Integer instructions with a shift amount. As above, except inheriting
237 // from the IntShiftOp class.
238 def format IntShiftOp(code, inst_flags = []) {{
239 dict = {'result':'Ra'}
241 # Code when Rc is set
242 code_rc1 = code + readXERCode + computeCR0Code % dict
244 # Generate the first class
245 (header_output, decoder_output, decode_block, exec_output) = \
246 GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
247 CheckRcDecode, BasicConstructor)
249 # Generate the second class
250 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
251 GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
252 CheckRcDecode, IntRcConstructor)
254 # Finally, add to the other outputs
255 header_output += header_output_rc1
256 decoder_output += decoder_output_rc1
257 exec_output += exec_output_rc1
261 // Instructions in this format are all reduced to the form Rt = src1 + src2,
262 // therefore we just give src1 and src2 definitions. In working out the
263 // template we first put in the definitions of the variables and then
264 // the code for the addition. We also deal with computing the carry flag
267 // We generate 4 versions of each instruction. This correspond to the
268 // different combinations of having the OE bit set or unset (which controls
269 // whether the overflow flag is computed) and the Rc bit set or unset too
270 // (which controls whether the CR0 code is computed).
271 def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
274 # The result is always in Rt, but the source values vary
275 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
277 # Add code to set up variables and do the sum
278 code = 'uint64_t src1 = ' + src1 + ';\n'
279 code += 'uint64_t src2 = ' + src2 + ';\n'
280 code += 'uint64_t ca = ' + ca + ';\n'
281 code += 'Rt = src1 + src2 + ca;\n'
283 # Add code for calculating the carry, if needed
285 code += computeCACode % dict + setXERCode
287 # Setup the 4 code versions and add code to access XER if necessary
288 code_rc1 = readXERCode + code
289 code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
290 code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
291 if (computeCA or ca == 'xer.ca'):
292 code = readXERCode + code
293 code_rc1 += computeCR0Code % dict
294 code_rc1_oe1 += computeCR0Code % dict
296 # Generate the classes
297 (header_output, decoder_output, decode_block, exec_output) = \
298 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
299 CheckRcOeDecode, BasicConstructor)
300 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
301 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
302 CheckRcOeDecode, IntRcConstructor)
303 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
304 GenAluOp(name, Name + 'OeSet', 'IntArithOp', code_oe1, inst_flags,
305 CheckRcOeDecode, IntOeConstructor)
306 (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
307 GenAluOp(name, Name + 'RcSetOeSet', 'IntArithOp', code_rc1_oe1,
308 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
310 # Finally, add to the other outputs
312 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
314 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
316 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
321 // Instructions that use source registers Ra and Rb, with the result
322 // placed into Rt. Basically multiply and divide instructions. The
323 // carry bit is never set, but overflow can be calculated. In certain
324 // situations, the overflow bits have to be set and this is dealt with
325 // using the 'setOV' boolean in decoder.isa.
327 // In case overflow is to be calculated, we generate four versions of
328 // each instruction to deal with different combinations of having the
329 // OE bit set or unset and the Rc bit set or unset too. Otherwise, we
330 // generate two versions of each instruction to deal with the Rc bit.
331 def format IntArithCheckRcOp(code, computeOV = 0, inst_flags = []) {{
333 # The result is always in Rt, but the source values vary
334 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
336 # Deal with setting the overflow flag
338 # Setup the 4 code versions and add code to access XER if necessary
339 code = 'M5_VAR_USED bool setOV = false;\n' + code
340 code_rc1 = readXERCode + code + computeCR0Code % dict
341 code_oe1 = readXERCode + code + setOVCode + setXERCode
342 code_rc1_oe1 = readXERCode + code + setOVCode + setXERCode
343 code_rc1_oe1 += computeCR0Code % dict
345 # Generate the classes
346 (header_output, decoder_output, decode_block, exec_output) = \
347 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
348 CheckRcOeDecode, BasicConstructor)
349 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
350 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
351 CheckRcOeDecode, IntRcConstructor)
352 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
353 GenAluOp(name, Name + 'OeSet', 'IntArithOp', code_oe1, inst_flags,
354 CheckRcOeDecode, IntOeConstructor)
355 (header_output_rc1_oe1, decoder_output_rc1_oe1, _,
356 exec_output_rc1_oe1) = \
357 GenAluOp(name, Name + 'RcSetOeSet', 'IntArithOp', code_rc1_oe1,
358 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
360 # Finally, add to the other outputs
362 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
364 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
366 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
369 # Setup the 2 code versions and add code to access XER if necessary
370 code_rc1 = readXERCode + code + computeCR0Code % dict
372 # Generate the first class
373 (header_output, decoder_output, decode_block, exec_output) = \
374 GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
375 CheckRcDecode, BasicConstructor)
377 # Generate the second class
378 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
379 GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
380 CheckRcDecode, IntRcConstructor)
382 # Finally, add to the other outputs
383 header_output += header_output_rc1
384 decoder_output += decoder_output_rc1
385 exec_output += exec_output_rc1
389 // A special format for rotate instructions which use certain fields
390 // from the instruction's binary encoding. We need two versions for each
391 // instruction to deal with the Rc bit.
392 def format IntRotateOp(code, inst_flags = []) {{
394 # The result is always in Ra
395 dict = {'result':'Ra'}
397 # Setup the code for when Rc is set
398 code_rc1 = readXERCode + code + computeCR0Code % dict
400 # Generate the first class
401 (header_output, decoder_output, decode_block, exec_output) = \
402 GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
403 CheckRcDecode, BasicConstructor)
405 # Generate the second class
406 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
407 GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
408 CheckRcDecode, IntRcConstructor)
410 # Finally, add to the other outputs
411 header_output += header_output_rc1
412 decoder_output += decoder_output_rc1
413 exec_output += exec_output_rc1