}
'''
-computeDivOVCode = '''
- if (divSetOV) {
+setCACode = '''
+ if (setCA) {
+ xer.ca = 1;
+ xer.ca32 = 1;
+ } else {
+ xer.ca = 0;
+ xer.ca32 = 0;
+ }
+'''
+
+setOVCode = '''
+ if (setOV) {
xer.ov = 1;
+ xer.ov32 = 1;
xer.so = 1;
} else {
- if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) {
- xer.ov = 1;
- xer.so = 1;
- } else {
- xer.ov = 0;
- }
+ xer.ov = 0;
+ xer.ov32 = 0;
}
'''
// Instructions that use source registers Ra and Rb, with the result
// placed into Rt. Basically multiply and divide instructions. The
-// carry bit is never set, but overflow can be calculated. Division
-// explicitly sets the overflow bit in certain situations and this is
-// dealt with using the 'divSetOV' boolean in decoder.isa. We generate
-// two versions of each instruction to deal with the Rc bit.
+// carry bit is never set, but overflow can be calculated. In certain
+// situations, the overflow bits have to be set and this is dealt with
+// using the 'setOV' boolean in decoder.isa.
+//
+// In case overflow is to be calculated, we generate four versions of
+// each instruction to deal with different combinations of having the
+// OE bit set or unset and the Rc bit set or unset too. Otherwise, we
+// generate two versions of each instruction to deal with the Rc bit.
def format IntArithOp(code, computeOV = 0, inst_flags = []) {{
# The result is always in Rt, but the source values vary
# Deal with setting the overflow flag
if computeOV:
- code = 'bool divSetOV = false;\n' + code
- code += computeDivOVCode % dict + setXERCode
-
- # Setup the 2 code versions and add code to access XER if necessary
- code_rc1 = readXERCode + code + computeCR0Code % dict
- if computeOV:
- code = readXERCode + code
-
- # Generate the classes
- (header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'IntOp', code, inst_flags,
- CheckRcDecode, BasicConstructor)
-
- # Generate the second class
- (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
- GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags,
- CheckRcDecode, IntRcConstructor)
-
- # Finally, add to the other outputs
- header_output += header_output_rc1
- decoder_output += decoder_output_rc1
- exec_output += exec_output_rc1
+ # Setup the 4 code versions and add code to access XER if necessary
+ code = 'bool setOV M5_VAR_USED = false;\n' + code
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+ code_oe1 = readXERCode + code + setOVCode + setXERCode
+ code_rc1_oe1 = readXERCode + code + setOVCode + setXERCode
+ code_rc1_oe1 += computeCR0Code % dict
+
+ # Generate the classes
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
+ CheckRcOeDecode, BasicConstructor)
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
+ CheckRcOeDecode, IntRcConstructor)
+ (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \
+ GenAluOp(name, Name + 'OeSet', 'IntArithOp', code_oe1, inst_flags,
+ CheckRcOeDecode, IntOeConstructor)
+ (header_output_rc1_oe1, decoder_output_rc1_oe1, _,
+ exec_output_rc1_oe1) = \
+ GenAluOp(name, Name + 'RcSetOeSet', 'IntArithOp', code_rc1_oe1,
+ inst_flags, CheckRcOeDecode, IntRcOeConstructor)
+
+ # Finally, add to the other outputs
+ header_output += \
+ header_output_rc1 + header_output_oe1 + header_output_rc1_oe1
+ decoder_output += \
+ decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1
+ exec_output += \
+ exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1
+
+ else:
+ # Setup the 2 code versions and add code to access XER if necessary
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntArithOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntArithOp', code_rc1, inst_flags,
+ CheckRcDecode, IntRcConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
}};