/**
- * Class for integer operations with a shift.
+ * Class for integer operations with a shift value obtained from
+ * a register or an instruction field.
*/
class IntShiftOp : public IntOp
{
protected:
- uint32_t sh;
+ uint32_t shift;
/// Constructor
IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
: IntOp(mnem, _machInst, __opClass),
- sh(machInst.sh)
+ shift(machInst.sh)
{
}
}
Ra = res;
}});
+ }
+ // Integer instructions with a shift value.
+ format IntShiftOp {
24: slw({{
if (Rb & 0x20) {
Ra = 0;
}});
792: sraw({{
- bool shiftSetCA = false;
int32_t s = Rs;
if (Rb == 0) {
Ra = Rs;
- shiftSetCA = true;
+ setCA = true;
} else if (Rb & 0x20) {
if (s < 0) {
Ra = (uint32_t)-1;
if (s & 0x7fffffff) {
- shiftSetCA = true;
+ setCA = true;
} else {
- shiftSetCA = false;
+ setCA = false;
}
} else {
Ra = 0;
- shiftSetCA = false;
+ setCA = false;
}
} else {
Ra = s >> (Rb & 0x1f);
if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) {
- shiftSetCA = true;
+ setCA = true;
} else {
- shiftSetCA = false;
+ setCA = false;
}
}
- Xer xer1 = XER;
- if (shiftSetCA) {
- xer1.ca = 1;
- } else {
- xer1.ca = 0;
- }
- XER = xer1;
- }});
- }
+ }}, true);
- // Integer logic instructions with a shift value.
- format IntShiftOp {
824: srawi({{
- bool shiftSetCA = false;
if (sh == 0) {
Ra = Rs;
- shiftSetCA = false;
+ setCA = false;
} else {
int32_t s = Rs;
Ra = s >> sh;
if (s < 0 && (s << (32 - sh)) != 0) {
- shiftSetCA = true;
+ setCA = true;
} else {
- shiftSetCA = false;
+ setCA = false;
}
}
- Xer xer1 = XER;
- if (shiftSetCA) {
- xer1.ca = 1;
- } else {
- xer1.ca = 0;
- }
- XER = xer1;
- }});
+ }}, true);
}
format StoreIndexOp {
}
'''
+setCACode = '''
+ if (setCA) {
+ xer.ca = 1;
+ xer.ca32 = 1;
+ } else {
+ xer.ca = 0;
+ xer.ca32 = 0;
+ }
+'''
+
setOVCode = '''
if (setOV) {
xer.ov = 1;
}};
-// Integer instructions with a shift amount. As above, except inheriting
-// from the IntShiftOp class.
-def format IntShiftOp(code, inst_flags = []) {{
+// Integer instructions that perform shift operations. All of these
+// instructions write to Ra and use Rs as a source register. The shift
+// value is obtained from an register or an instruction field. If it
+// from a register, Rb is also used as a source register. In certain
+// situations, the carry bits have to be set and this is dealt with
+// using the 'setCA' boolean in decoder.isa. We need two versions for
+// each instruction to deal with the Rc bit.
+def format IntShiftOp(code, computeCA = 0, inst_flags = []) {{
dict = {'result':'Ra'}
+ # Add code to setup variables and access XER if necessary
+ code = 'M5_VAR_USED bool setCA = false;\n' + code
+
# Code when Rc is set
- code_rc1 = code + readXERCode + computeCR0Code % dict
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+
+ # Add code for calculating the carry, if needed
+ if computeCA:
+ code = readXERCode + code + setCACode + setXERCode
+ code_rc1 += setCACode + setXERCode
# Generate the first class
(header_output, decoder_output, decode_block, exec_output) = \