integer.isa (6691:cd68b6ecd68d) integer.isa (10184:bbfa3152bdea)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
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.
16//
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.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Integer ALU instructions
34//
35
36
37// Instruction class constructor template when Rc is set.
38def template IntRcConstructor {{
1// -*- mode:c++ -*-
2
3// Copyright (c) 2009 The University of Edinburgh
4// All rights reserved.
5//
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.
16//
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.
28//
29// Authors: Timothy M. Jones
30
31////////////////////////////////////////////////////////////////////
32//
33// Integer ALU instructions
34//
35
36
37// Instruction class constructor template when Rc is set.
38def template IntRcConstructor {{
39 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
39 %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
40 {
41 %(constructor)s;
42 rcSet = true;
43 }
44}};
45
46
47// Instruction class constructor template when OE is set.
48def template IntOeConstructor {{
40 {
41 %(constructor)s;
42 rcSet = true;
43 }
44}};
45
46
47// Instruction class constructor template when OE is set.
48def template IntOeConstructor {{
49 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
49 %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
50 {
51 %(constructor)s;
52 oeSet = true;
53 }
54}};
55
56
57// Instruction class constructor template when both Rc and OE are set.
58def template IntRcOeConstructor {{
50 {
51 %(constructor)s;
52 oeSet = true;
53 }
54}};
55
56
57// Instruction class constructor template when both Rc and OE are set.
58def template IntRcOeConstructor {{
59 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
59 %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
60 {
61 %(constructor)s;
62 rcSet = true;
63 oeSet = true;
64 }
65}};
66
67
68let {{
69
70readXERCode = 'Xer xer = XER;'
71
72setXERCode = 'XER = xer;'
73
74computeCR0Code = '''
75 Cr cr = CR;
76 cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
77 CR = cr;
78'''
79
80computeCACode = '''
81 if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
82 xer.ca = 1;
83 } else {
84 xer.ca = 0;
85 }
86'''
87
88computeOVCode = '''
89 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
90 xer.ov = 1;
91 xer.so = 1;
92 } else {
93 xer.ov = 0;
94 }
95'''
96
97computeDivOVCode = '''
98 if (divSetOV) {
99 xer.ov = 1;
100 xer.so = 1;
101 } else {
102 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
103 xer.ov = 1;
104 xer.so = 1;
105 } else {
106 xer.ov = 0;
107 }
108 }
109'''
110
111}};
112
113
114// A basic integer instruction.
115def format IntOp(code, inst_flags = []) {{
116 (header_output, decoder_output, decode_block, exec_output) = \
117 GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
118 BasicConstructor)
119}};
120
121
122// Integer instructions with immediate (signed or unsigned).
123def format IntImmOp(code, inst_flags = []) {{
124 (header_output, decoder_output, decode_block, exec_output) = \
125 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
126 BasicConstructor)
127}};
128
129
130// Integer instructions with immediate that perform arithmetic.
131// These instructions all write to Rt and use an altered form of the
132// value in source register Ra, hence the use of src to hold the actual
133// value. The control flags include the use of code to compute the
134// carry bit or the CR0 code.
135def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{
136
137 # Set up the dictionary and deal with control flags
138 dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'}
139 if ctrl_flags:
140 code += readXERCode
141 for val in ctrl_flags:
142 if val == 'computeCA':
143 code += computeCACode % dict + setXERCode
144 elif val == 'computeCR0':
145 code += computeCR0Code % dict
146
147 # Generate the class
148 (header_output, decoder_output, decode_block, exec_output) = \
149 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
150 BasicConstructor)
151}};
152
153
154// Integer instructions with immediate that perform arithmetic but use
155// the value 0 when Ra == 0. We generate two versions of each instruction
156// corresponding to these two different scenarios. The correct version is
157// determined at decode (see the CheckRaDecode template).
158def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
159
160 # First the version where Ra is non-zero
161 (header_output, decoder_output, decode_block, exec_output) = \
162 GenAluOp(name, Name, 'IntImmOp', code, inst_flags,
163 CheckRaDecode, BasicConstructor)
164
165 # Now another version where Ra == 0
166 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
167 GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags,
168 CheckRaDecode, BasicConstructor)
169
170 # Finally, add to the other outputs
171 header_output += header_output_ra0
172 decoder_output += decoder_output_ra0
173 exec_output += exec_output_ra0
174}};
175
176
177// Integer instructions with immediate that perform logic operations.
178// All instructions write to Ra and use Rs as a source register. Some
179// also compute the CR0 code too.
180def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
181
182 # Set up the dictionary and deal with computing CR0
183 dict = {'result':'Ra'}
184 if computeCR0:
185 code += readXERCode + computeCR0Code % dict
186
187 # Generate the class
188 (header_output, decoder_output, decode_block, exec_output) = \
189 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
190 BasicConstructor)
191}};
192
193
194// Integer instructions that perform logic operations. The result is
195// always written into Ra. All instructions have 2 versions depending on
196// whether the Rc bit is set to compute the CR0 code. This is determined
197// at decode as before.
198def format IntLogicOp(code, inst_flags = []) {{
199 dict = {'result':'Ra'}
200
201 # Code when Rc is set
202 code_rc1 = code + readXERCode + computeCR0Code % dict
203
204 # Generate the first class
205 (header_output, decoder_output, decode_block, exec_output) = \
206 GenAluOp(name, Name, 'IntOp', code, inst_flags,
207 CheckRcDecode, BasicConstructor)
208
209 # Generate the second class
210 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
211 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
212 CheckRcDecode, IntRcConstructor)
213
214 # Finally, add to the other outputs
215 header_output += header_output_rc1
216 decoder_output += decoder_output_rc1
217 exec_output += exec_output_rc1
218}};
219
220
221// Integer instructions with a shift amount. As above, except inheriting
222// from the IntShiftOp class.
223def format IntShiftOp(code, inst_flags = []) {{
224 dict = {'result':'Ra'}
225
226 # Code when Rc is set
227 code_rc1 = code + readXERCode + computeCR0Code % dict
228
229 # Generate the first class
230 (header_output, decoder_output, decode_block, exec_output) = \
231 GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
232 CheckRcDecode, BasicConstructor)
233
234 # Generate the second class
235 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
236 GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
237 CheckRcDecode, IntRcConstructor)
238
239 # Finally, add to the other outputs
240 header_output += header_output_rc1
241 decoder_output += decoder_output_rc1
242 exec_output += exec_output_rc1
243}};
244
245
246// Instructions in this format are all reduced to the form Rt = src1 + src2,
247// therefore we just give src1 and src2 definitions. In working out the
248// template we first put in the definitions of the variables and then
249// the code for the addition. We also deal with computing the carry flag
250// if required.
251//
252// We generate 4 versions of each instruction. This correspond to the
253// different combinations of having the OE bit set or unset (which controls
254// whether the overflow flag is computed) and the Rc bit set or unset too
255// (which controls whether the CR0 code is computed).
256def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
257 inst_flags = []) {{
258
259 # The result is always in Rt, but the source values vary
260 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
261
262 # Add code to set up variables and do the sum
263 code = 'uint32_t src1 = ' + src1 + ';\n'
264 code += 'uint32_t src2 = ' + src2 + ';\n'
265 code += 'uint32_t ca = ' + ca + ';\n'
266 code += 'Rt = src1 + src2 + ca;\n'
267
268 # Add code for calculating the carry, if needed
269 if computeCA:
270 code += computeCACode % dict + setXERCode
271
272 # Setup the 4 code versions and add code to access XER if necessary
273 code_rc1 = readXERCode + code
274 code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
275 code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
276 if (computeCA or ca == 'xer.ca'):
277 code = readXERCode + code
278 code_rc1 += computeCR0Code % dict
279 code_rc1_oe1 += computeCR0Code % dict
280
281 # Generate the classes
282 (header_output, decoder_output, decode_block, exec_output) = \
283 GenAluOp(name, Name, 'IntOp', code, inst_flags,
284 CheckRcOeDecode, BasicConstructor)
285 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
286 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
287 CheckRcOeDecode, IntRcConstructor)
288 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
289 GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags,
290 CheckRcOeDecode, IntOeConstructor)
291 (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
292 GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1,
293 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
294
295 # Finally, add to the other outputs
296 header_output += \
297 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
298 decoder_output += \
299 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
300 exec_output += \
301 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
302
303}};
304
305
306// Instructions that use source registers Ra and Rb, with the result
307// placed into Rt. Basically multiply and divide instructions. The
308// carry bit is never set, but overflow can be calculated. Division
309// explicitly sets the overflow bit in certain situations and this is
310// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
311// two versions of each instruction to deal with the Rc bit.
312def format IntArithOp(code, computeOV = 0, inst_flags = []) {{
313
314 # The result is always in Rt, but the source values vary
315 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
316
317 # Deal with setting the overflow flag
318 if computeOV:
319 code = 'bool divSetOV = false;\n' + code
320 code += computeDivOVCode % dict + setXERCode
321
322 # Setup the 2 code versions and add code to access XER if necessary
323 code_rc1 = readXERCode + code + computeCR0Code % dict
324 if computeOV:
325 code = readXERCode + code
326
327 # Generate the classes
328 (header_output, decoder_output, decode_block, exec_output) = \
329 GenAluOp(name, Name, 'IntOp', code, inst_flags,
330 CheckRcDecode, BasicConstructor)
331
332 # Generate the second class
333 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
334 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
335 CheckRcDecode, IntRcConstructor)
336
337 # Finally, add to the other outputs
338 header_output += header_output_rc1
339 decoder_output += decoder_output_rc1
340 exec_output += exec_output_rc1
341}};
342
343
344// A special format for rotate instructions which use certain fields
345// from the instruction's binary encoding. We need two versions for each
346// instruction to deal with the Rc bit.
347def format IntRotateOp(code, inst_flags = []) {{
348
349 # The result is always in Ra
350 dict = {'result':'Ra'}
351
352 # Setup the code for when Rc is set
353 code_rc1 = readXERCode + code + computeCR0Code % dict
354
355 # Generate the first class
356 (header_output, decoder_output, decode_block, exec_output) = \
357 GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
358 CheckRcDecode, BasicConstructor)
359
360 # Generate the second class
361 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
362 GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
363 CheckRcDecode, IntRcConstructor)
364
365 # Finally, add to the other outputs
366 header_output += header_output_rc1
367 decoder_output += decoder_output_rc1
368 exec_output += exec_output_rc1
369}};
60 {
61 %(constructor)s;
62 rcSet = true;
63 oeSet = true;
64 }
65}};
66
67
68let {{
69
70readXERCode = 'Xer xer = XER;'
71
72setXERCode = 'XER = xer;'
73
74computeCR0Code = '''
75 Cr cr = CR;
76 cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so);
77 CR = cr;
78'''
79
80computeCACode = '''
81 if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) {
82 xer.ca = 1;
83 } else {
84 xer.ca = 0;
85 }
86'''
87
88computeOVCode = '''
89 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
90 xer.ov = 1;
91 xer.so = 1;
92 } else {
93 xer.ov = 0;
94 }
95'''
96
97computeDivOVCode = '''
98 if (divSetOV) {
99 xer.ov = 1;
100 xer.so = 1;
101 } else {
102 if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
103 xer.ov = 1;
104 xer.so = 1;
105 } else {
106 xer.ov = 0;
107 }
108 }
109'''
110
111}};
112
113
114// A basic integer instruction.
115def format IntOp(code, inst_flags = []) {{
116 (header_output, decoder_output, decode_block, exec_output) = \
117 GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode,
118 BasicConstructor)
119}};
120
121
122// Integer instructions with immediate (signed or unsigned).
123def format IntImmOp(code, inst_flags = []) {{
124 (header_output, decoder_output, decode_block, exec_output) = \
125 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
126 BasicConstructor)
127}};
128
129
130// Integer instructions with immediate that perform arithmetic.
131// These instructions all write to Rt and use an altered form of the
132// value in source register Ra, hence the use of src to hold the actual
133// value. The control flags include the use of code to compute the
134// carry bit or the CR0 code.
135def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{
136
137 # Set up the dictionary and deal with control flags
138 dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'}
139 if ctrl_flags:
140 code += readXERCode
141 for val in ctrl_flags:
142 if val == 'computeCA':
143 code += computeCACode % dict + setXERCode
144 elif val == 'computeCR0':
145 code += computeCR0Code % dict
146
147 # Generate the class
148 (header_output, decoder_output, decode_block, exec_output) = \
149 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
150 BasicConstructor)
151}};
152
153
154// Integer instructions with immediate that perform arithmetic but use
155// the value 0 when Ra == 0. We generate two versions of each instruction
156// corresponding to these two different scenarios. The correct version is
157// determined at decode (see the CheckRaDecode template).
158def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{
159
160 # First the version where Ra is non-zero
161 (header_output, decoder_output, decode_block, exec_output) = \
162 GenAluOp(name, Name, 'IntImmOp', code, inst_flags,
163 CheckRaDecode, BasicConstructor)
164
165 # Now another version where Ra == 0
166 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \
167 GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags,
168 CheckRaDecode, BasicConstructor)
169
170 # Finally, add to the other outputs
171 header_output += header_output_ra0
172 decoder_output += decoder_output_ra0
173 exec_output += exec_output_ra0
174}};
175
176
177// Integer instructions with immediate that perform logic operations.
178// All instructions write to Ra and use Rs as a source register. Some
179// also compute the CR0 code too.
180def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{
181
182 # Set up the dictionary and deal with computing CR0
183 dict = {'result':'Ra'}
184 if computeCR0:
185 code += readXERCode + computeCR0Code % dict
186
187 # Generate the class
188 (header_output, decoder_output, decode_block, exec_output) = \
189 GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode,
190 BasicConstructor)
191}};
192
193
194// Integer instructions that perform logic operations. The result is
195// always written into Ra. All instructions have 2 versions depending on
196// whether the Rc bit is set to compute the CR0 code. This is determined
197// at decode as before.
198def format IntLogicOp(code, inst_flags = []) {{
199 dict = {'result':'Ra'}
200
201 # Code when Rc is set
202 code_rc1 = code + readXERCode + computeCR0Code % dict
203
204 # Generate the first class
205 (header_output, decoder_output, decode_block, exec_output) = \
206 GenAluOp(name, Name, 'IntOp', code, inst_flags,
207 CheckRcDecode, BasicConstructor)
208
209 # Generate the second class
210 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
211 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
212 CheckRcDecode, IntRcConstructor)
213
214 # Finally, add to the other outputs
215 header_output += header_output_rc1
216 decoder_output += decoder_output_rc1
217 exec_output += exec_output_rc1
218}};
219
220
221// Integer instructions with a shift amount. As above, except inheriting
222// from the IntShiftOp class.
223def format IntShiftOp(code, inst_flags = []) {{
224 dict = {'result':'Ra'}
225
226 # Code when Rc is set
227 code_rc1 = code + readXERCode + computeCR0Code % dict
228
229 # Generate the first class
230 (header_output, decoder_output, decode_block, exec_output) = \
231 GenAluOp(name, Name, 'IntShiftOp', code, inst_flags,
232 CheckRcDecode, BasicConstructor)
233
234 # Generate the second class
235 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
236 GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags,
237 CheckRcDecode, IntRcConstructor)
238
239 # Finally, add to the other outputs
240 header_output += header_output_rc1
241 decoder_output += decoder_output_rc1
242 exec_output += exec_output_rc1
243}};
244
245
246// Instructions in this format are all reduced to the form Rt = src1 + src2,
247// therefore we just give src1 and src2 definitions. In working out the
248// template we first put in the definitions of the variables and then
249// the code for the addition. We also deal with computing the carry flag
250// if required.
251//
252// We generate 4 versions of each instruction. This correspond to the
253// different combinations of having the OE bit set or unset (which controls
254// whether the overflow flag is computed) and the Rc bit set or unset too
255// (which controls whether the CR0 code is computed).
256def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0,
257 inst_flags = []) {{
258
259 # The result is always in Rt, but the source values vary
260 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
261
262 # Add code to set up variables and do the sum
263 code = 'uint32_t src1 = ' + src1 + ';\n'
264 code += 'uint32_t src2 = ' + src2 + ';\n'
265 code += 'uint32_t ca = ' + ca + ';\n'
266 code += 'Rt = src1 + src2 + ca;\n'
267
268 # Add code for calculating the carry, if needed
269 if computeCA:
270 code += computeCACode % dict + setXERCode
271
272 # Setup the 4 code versions and add code to access XER if necessary
273 code_rc1 = readXERCode + code
274 code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
275 code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode
276 if (computeCA or ca == 'xer.ca'):
277 code = readXERCode + code
278 code_rc1 += computeCR0Code % dict
279 code_rc1_oe1 += computeCR0Code % dict
280
281 # Generate the classes
282 (header_output, decoder_output, decode_block, exec_output) = \
283 GenAluOp(name, Name, 'IntOp', code, inst_flags,
284 CheckRcOeDecode, BasicConstructor)
285 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
286 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
287 CheckRcOeDecode, IntRcConstructor)
288 (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
289 GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags,
290 CheckRcOeDecode, IntOeConstructor)
291 (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \
292 GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1,
293 inst_flags, CheckRcOeDecode, IntRcOeConstructor)
294
295 # Finally, add to the other outputs
296 header_output += \
297 header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
298 decoder_output += \
299 decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
300 exec_output += \
301 exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
302
303}};
304
305
306// Instructions that use source registers Ra and Rb, with the result
307// placed into Rt. Basically multiply and divide instructions. The
308// carry bit is never set, but overflow can be calculated. Division
309// explicitly sets the overflow bit in certain situations and this is
310// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
311// two versions of each instruction to deal with the Rc bit.
312def format IntArithOp(code, computeOV = 0, inst_flags = []) {{
313
314 # The result is always in Rt, but the source values vary
315 dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'}
316
317 # Deal with setting the overflow flag
318 if computeOV:
319 code = 'bool divSetOV = false;\n' + code
320 code += computeDivOVCode % dict + setXERCode
321
322 # Setup the 2 code versions and add code to access XER if necessary
323 code_rc1 = readXERCode + code + computeCR0Code % dict
324 if computeOV:
325 code = readXERCode + code
326
327 # Generate the classes
328 (header_output, decoder_output, decode_block, exec_output) = \
329 GenAluOp(name, Name, 'IntOp', code, inst_flags,
330 CheckRcDecode, BasicConstructor)
331
332 # Generate the second class
333 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
334 GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
335 CheckRcDecode, IntRcConstructor)
336
337 # Finally, add to the other outputs
338 header_output += header_output_rc1
339 decoder_output += decoder_output_rc1
340 exec_output += exec_output_rc1
341}};
342
343
344// A special format for rotate instructions which use certain fields
345// from the instruction's binary encoding. We need two versions for each
346// instruction to deal with the Rc bit.
347def format IntRotateOp(code, inst_flags = []) {{
348
349 # The result is always in Ra
350 dict = {'result':'Ra'}
351
352 # Setup the code for when Rc is set
353 code_rc1 = readXERCode + code + computeCR0Code % dict
354
355 # Generate the first class
356 (header_output, decoder_output, decode_block, exec_output) = \
357 GenAluOp(name, Name, 'IntRotateOp', code, inst_flags,
358 CheckRcDecode, BasicConstructor)
359
360 # Generate the second class
361 (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
362 GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags,
363 CheckRcDecode, IntRcConstructor)
364
365 # Finally, add to the other outputs
366 header_output += header_output_rc1
367 decoder_output += decoder_output_rc1
368 exec_output += exec_output_rc1
369}};