}
}
- 19: decode XO_XO {
+ 19: decode XL_XO {
// Conditionally branch to address in LR based on CR and CTR.
format BranchLrCondCtr {
40: lhz({{ Rt = Mem_uh; }});
42: lha({{ Rt = Mem_sh; }});
32: lwz({{ Rt = Mem; }});
- 58: lwa({{ Rt = Mem_sw; }},
- {{ EA = Ra + (disp & 0xfffffffc); }},
- {{ EA = disp & 0xfffffffc; }});
+ }
+
+ 58: decode DS_XO {
+ format LoadDispOp {
+ 2: lwa({{ Rt = Mem_sw; }},
+ {{ EA = Ra + (disp & 0xfffffffc); }},
+ {{ EA = disp & 0xfffffffc; }});
+ }
}
format LoadDispUpdateOp {
(Ra & ~fullMask); }});
}
- // Some instructions use bits 21 - 30, others 22 - 30. We have to use
- // the larger size to account for all opcodes. For those that use the
- // smaller value, the OE bit is bit 21. Therefore, we have two versions
- // of each instruction: 1 with OE set, the other without. For an
- // example see 'add' and 'addo'.
- 31: decode XO_XO {
+ // There are a large number of instructions that have the same primary
+ // opcode (PO) of 31. In this case, the instructions are of different
+ // forms. For every form, the XO fields may vary in position and width.
+ // The X, XFL, XFX and XL form instructions use bits 21 - 30 and the
+ // XO form instructions use bits 22 - 30 as extended opcode (XO). To
+ // avoid conflicts, instructions of each form have to be defined under
+ // separate decode blocks. However, only a single decode block can be
+ // associated with a particular PO and it will recognize only one type
+ // of XO field. A solution for associating decode blocks for the other
+ // types of XO fields with the same PO is to have the other blocks as
+ // nested default cases.
+ 31: decode X_XO {
// All loads with an index register. The non-update versions
// all use the value 0 if Ra == R0, not the value contained in
183: stwux({{ Mem = Rs; }});
}
- // These instructions can all be reduced to the form
- // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2
- // (and, if necessary, CA) definitions and let the python script
- // deal with setting things up correctly. We also give flags to
- // say which control registers to set.
- format IntSumOp {
- 266: add({{ Ra }}, {{ Rb }});
- 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }});
- 10: addc({{ Ra }}, {{ Rb }},
- computeCA = true);
- 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }},
- true);
- 104: neg({{ ~Ra }}, {{ 1 }});
- 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }},
- true);
- 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
- true);
- 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }},
- true);
- 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
- true);
- 202: addze({{ Ra }}, {{ xer.ca }},
- computeCA = true);
- 200: subfze({{ ~Ra }}, {{ xer.ca }},
- computeCA = true);
- }
-
- // Arithmetic instructions all use source registers Ra and Rb,
- // with destination register Rt.
- format IntArithOp {
- 75: mulhw({{ int64_t prod = Ra_sd * Rb_sd; Rt = prod >> 32; }});
- 11: mulhwu({{ uint64_t prod = Ra_ud * Rb_ud; Rt = prod >> 32; }});
- 235: mullw({{ int64_t prod = Ra_sd * Rb_sd; Rt = prod; }});
- 747: mullwo({{
- int64_t src1 = Ra_sd;
- int64_t src2 = Rb;
- int64_t prod = src1 * src2;
- Rt = prod;
- }},
- true);
-
- 491: divw({{
- int32_t src1 = Ra_sw;
- int32_t src2 = Rb_sw;
- if ((src1 != 0x80000000 || src2 != 0xffffffff)
- && src2 != 0) {
- Rt = src1 / src2;
- } else {
- Rt = 0;
- }
- }});
-
- 1003: divwo({{
- int32_t src1 = Ra_sw;
- int32_t src2 = Rb_sw;
- if ((src1 != 0x80000000 || src2 != 0xffffffff)
- && src2 != 0) {
- Rt = src1 / src2;
- } else {
- Rt = 0;
- divSetOV = true;
- }
- }},
- true);
-
- 459: divwu({{
- uint32_t src1 = Ra_sw;
- uint32_t src2 = Rb_sw;
- if (src2 != 0) {
- Rt = src1 / src2;
- } else {
- Rt = 0;
- }
- }});
-
- 971: divwuo({{
- uint32_t src1 = Ra_sw;
- uint32_t src2 = Rb_sw;
- if (src2 != 0) {
- Rt = src1 / src2;
- } else {
- Rt = 0;
- divSetOV = true;
- }
- }},
- true);
- }
-
format IntOp {
0: cmp({{
Xer xer = XER;
}});
}
- // Generic integer format instructions.
- format IntOp {
- 144: mtcrf({{
- uint32_t mask = 0;
- for (int i = 0; i < 8; ++i) {
- if (((FXM >> i) & 0x1) == 0x1) {
- mask |= 0xf << (4 * i);
- }
- }
- CR = (Rs & mask) | (CR & ~mask);
- }});
- 19: mfcr({{ Rt = CR; }});
- 339: decode SPR {
- 0x20: mfxer({{ Rt = XER; }});
- 0x100: mflr({{ Rt = LR; }});
- 0x120: mfctr({{ Rt = CTR; }});
- }
- 467: decode SPR {
- 0x20: mtxer({{ XER = Rs; }});
- 0x100: mtlr({{ LR = Rs; }});
- 0x120: mtctr({{ CTR = Rs; }});
- }
- 512: mcrxr({{
- CR = insertCRField(CR, BF, XER<31:28>);
- XER = XER<27:0>;
- }});
- }
-
format StoreIndexOp {
663: stfsx({{ Mem_sf = Fs_sf; }});
727: stfdx({{ Mem_df = Fs; }});
598: sync({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
854: eieio({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
}
+
+ // These instructions are of XO form with bit 21 as the OE bit.
+ default: decode XO_XO {
+
+ // These instructions can all be reduced to the form
+ // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2
+ // (and, if necessary, CA) definitions and let the python script
+ // deal with setting things up correctly. We also give flags to
+ // say which control registers to set.
+ format IntSumOp {
+ 266: add({{ Ra }}, {{ Rb }});
+ 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }});
+ 10: addc({{ Ra }}, {{ Rb }},
+ computeCA = true);
+ 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }},
+ true);
+ 104: neg({{ ~Ra }}, {{ 1 }});
+ 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }},
+ true);
+ 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
+ true);
+ 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }},
+ true);
+ 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
+ true);
+ 202: addze({{ Ra }}, {{ xer.ca }},
+ computeCA = true);
+ 200: subfze({{ ~Ra }}, {{ xer.ca }},
+ computeCA = true);
+ }
+
+ // Arithmetic instructions all use source registers Ra and Rb,
+ // with destination register Rt.
+ format IntArithOp {
+ 75: mulhw({{
+ int64_t prod = Ra_sd * Rb_sd;
+ Rt = prod >> 32;
+ }});
+ 11: mulhwu({{
+ uint64_t prod = Ra_ud * Rb_ud;
+ Rt = prod >> 32;
+ }});
+ 235: mullw({{ int64_t prod = Ra_sd * Rb_sd; Rt = prod; }});
+ 747: mullwo({{
+ int64_t src1 = Ra_sd;
+ int64_t src2 = Rb;
+ int64_t prod = src1 * src2;
+ Rt = prod;
+ }},
+ true);
+
+ 491: divw({{
+ int32_t src1 = Ra_sw;
+ int32_t src2 = Rb_sw;
+ if ((src1 != 0x80000000 || src2 != 0xffffffff)
+ && src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ }
+ }});
+
+ 1003: divwo({{
+ int32_t src1 = Ra_sw;
+ int32_t src2 = Rb_sw;
+ if ((src1 != 0x80000000 || src2 != 0xffffffff)
+ && src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ divSetOV = true;
+ }
+ }},
+ true);
+
+ 459: divwu({{
+ uint32_t src1 = Ra_sw;
+ uint32_t src2 = Rb_sw;
+ if (src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ }
+ }});
+
+ 971: divwuo({{
+ uint32_t src1 = Ra_sw;
+ uint32_t src2 = Rb_sw;
+ if (src2 != 0) {
+ Rt = src1 / src2;
+ } else {
+ Rt = 0;
+ divSetOV = true;
+ }
+ }},
+ true);
+ }
+
+ default: decode XFX_XO {
+ format IntOp {
+ 339: decode SPR {
+ 0x20: mfxer({{ Rt = XER; }});
+ 0x100: mflr({{ Rt = LR; }});
+ 0x120: mfctr({{ Rt = CTR; }});
+ }
+
+ 467: decode SPR {
+ 0x20: mtxer({{ XER = Rs; }});
+ 0x100: mtlr({{ LR = Rs; }});
+ 0x120: mtctr({{ CTR = Rs; }});
+ }
+
+ 144: mtcrf({{
+ uint32_t mask = 0;
+ for (int i = 0; i < 8; ++i) {
+ if (((FXM >> i) & 0x1) == 0x1) {
+ mask |= 0xf << (4 * i);
+ }
+ }
+ CR = (Rs & mask) | (CR & ~mask);
+ }});
+
+ 19: mfcr({{ Rt = CR; }});
+
+ 512: mcrxr({{
+ CR = insertCRField(CR, BF, XER<31:28>);
+ XER = XER<27:0>;
+ }});
+ }
+ }
+ }
}
format LoadDispOp {
30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }});
}
- default: decode XO_XO {
+ default: decode X_XO {
format FloatRCCheckOp {
72: fmr({{ Ft = Fb; }});
264: fabs({{
FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W_FIELD)),
U_FIELD);
}});
- 711: mtfsf({{
- if (L_FIELD == 1) { FPSCR = Fb_ud; }
- else {
- for (int i = 0; i < 8; ++i) {
- if (bits(FLM, i) == 1) {
- int k = 4 * (i + (8 * (1 - W_FIELD)));
- FPSCR = insertBits(FPSCR, k + 3, k,
- bits(Fb_ud, k + 3, k));
- }
- }
- }
- }});
70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }});
38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }});
+
+ default: decode XFL_XO {
+ 711: mtfsf({{
+ if (L_FIELD == 1) { FPSCR = Fb_ud; }
+ else {
+ for (int i = 0; i < 8; ++i) {
+ if (bits(FLM, i) == 1) {
+ int k = 4 * (i + (8 * (1 - W_FIELD)));
+ FPSCR = insertBits(FPSCR, k + 3, k,
+ bits(Fb_ud, k + 3, k));
+ }
+ }
+ }
+ }});
+ }
}
}
}