From e3d58b613234373bfc3f8e13dcfc6057dc0c49ce Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sun, 14 Feb 2021 19:44:58 +0530 Subject: [PATCH] arch-power: Fix extended opcode based decoding When multiple instructions share the same primary opcode, the decoder can distinguish between them by looking at the extended opcode field. However, the length and position of the extended opcode field can slightly vary depending on the instruction form. This ensures that the correct extended opcode fields are used for decoding such instructions. Change-Id: I8207568ac975587377abba8a9b221ca3097b8488 Signed-off-by: Sandipan Das Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40885 Reviewed-by: Boris Shingarov Maintainer: Gabe Black Tested-by: kokoro --- src/arch/power/isa/decoder.isa | 332 +++++++++++++++++---------------- 1 file changed, 170 insertions(+), 162 deletions(-) diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 1a8b3757e3..8ffe007018 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -97,7 +97,7 @@ decode PO default Unknown::unknown() { 1: BranchNonPCRel::ba({{ NIA = targetAddr; }}); } - 19: decode XO_XO { + 19: decode XL_XO { 0: CondMoveOp::mcrf({{ uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); @@ -181,12 +181,18 @@ decode PO default Unknown::unknown() { 29: andis_({{ Ra = Rs & (uimm << 16); }}, true); } - // 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 { 0: IntOp::cmp({{ Xer xer = XER; @@ -194,16 +200,6 @@ decode PO default Unknown::unknown() { CR = insertCRField(CR, BF, cr); }}); - 8: IntSumOp::subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, true); - 10: IntSumOp::addc({{ Ra }}, {{ Rb }}, computeCA = true); - - 11: IntArithOp::mulhwu({{ - uint64_t prod = Ra_ud * Rb_ud; - Rt = prod >> 32; - }}); - - 19: IntOp::mfcr({{ Rt = CR; }}); - format LoadIndexOp { 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); 23: lwzx({{ Rt = Mem; }}); @@ -228,35 +224,12 @@ decode PO default Unknown::unknown() { CR = insertCRField(CR, BF, cr); }}); - 40: IntSumOp::subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); 55: LoadIndexUpdateOp::lwzux({{ Rt = Mem; }}); 60: IntLogicOp::andc({{ Ra = Rs & ~Rb; }}); - - 75: IntArithOp::mulhw({{ - int64_t prod = Ra_sd * Rb_sd; - Rt = prod >> 32; - }}); - 87: LoadIndexOp::lbzx({{ Rt = Mem_ub; }}); - 104: IntSumOp::neg({{ ~Ra }}, {{ 1 }}); 119: LoadIndexUpdateOp::lbzux({{ Rt = Mem_ub; }}); 124: IntLogicOp::nor({{ Ra = ~(Rs | Rb); }}); - format IntSumOp { - 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, true); - 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, true); - } - - 144: IntOp::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); - }}); - format StoreIndexOp { 150: stwcx({{ bool store_performed = false; @@ -279,51 +252,15 @@ decode PO default Unknown::unknown() { } 183: StoreIndexUpdateOp::stwux({{ Mem = Rs; }}); - - format IntSumOp { - 200: subfze({{ ~Ra }}, {{ xer.ca }}, computeCA = true); - 202: addze({{ Ra }}, {{ xer.ca }}, computeCA = true); - } - 215: StoreIndexOp::stbx({{ Mem_ub = Rs_ub; }}); - - format IntSumOp { - 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); - 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); - } - - format IntArithOp { - 235: mullw({{ - int64_t prod = Ra_sd * Rb_sd; - Rt = prod; - }}); - - // Another variant of mullw decoded with the OE bit set - 747: mullwo({{ - int64_t src1 = Ra_sd; - int64_t src2 = Rb; - int64_t prod = src1 * src2; - Rt = prod; - }}, true); - } - 246: MiscOp::dcbtst({{ }}); 247: StoreIndexUpdateOp::stbux({{ Mem_ub = Rs_ub; }}); - 266: IntSumOp::add({{ Ra }}, {{ Rb }}); 278: MiscOp::dcbt({{ }}); 279: LoadIndexOp::lhzx({{ Rt = Mem_uh; }}); 284: IntLogicOp::eqv({{ Ra = ~(Rs ^ Rb); }}); 311: LoadIndexUpdateOp::lhzux({{ Rt = Mem_uh; }}); 316: IntLogicOp::xor({{ Ra = Rs ^ Rb; }}); - format IntOp { - 339: decode SPR { - 0x20: mfxer({{ Rt = XER; }}); - 0x100: mflr({{ Rt = LR; }}); - 0x120: mfctr({{ Rt = CTR; }}); - } - } - format LoadIndexOp { 341: lwax({{ Rt = Mem_sw; }}); 343: lhax({{ Rt = Mem_sh; }}); @@ -337,83 +274,22 @@ decode PO default Unknown::unknown() { 407: StoreIndexOp::sthx({{ Mem_uh = Rs_uh; }}); 412: IntLogicOp::orc({{ Ra = Rs | ~Rb; }}); 439: StoreIndexUpdateOp::sthux({{ Mem_uh = Rs_uh; }}); - 444: IntLogicOp::or({{ Ra = Rs | Rb; }}); - format IntArithOp { - 459: divwu({{ - uint32_t src1 = Ra_sw; - uint32_t src2 = Rb_sw; - if (src2 != 0) { - Rt = src1 / src2; - } else { - Rt = 0; + format IntLogicOp { + 444: or({{ Ra = Rs | Rb; }}); + 476: nand({{ Ra = ~(Rs & Rb); }}); + + 508: cmpb({{ + uint32_t val = 0; + for (int n = 0; n < 32; n += 8) { + if(bits(Rs, n+7, n) == bits(Rb, n+7, n)) { + val = insertBits(val, n+7, n, 0xff); + } } + Ra = val; }}); - - // Another variant of divwu decoded with the OE bit set - 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 { - 467: decode SPR { - 0x20: mtxer({{ XER = Rs; }}); - 0x100: mtlr({{ LR = Rs; }}); - 0x120: mtctr({{ CTR = Rs; }}); - } - } - - 476: IntLogicOp::nand({{ Ra = ~(Rs & Rb); }}); - - format IntArithOp { - 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; - } - }}); - - // Another variant of divw decoded with the OE bit set - 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); - } - - 508: IntLogicOp::cmpb({{ - uint32_t val = 0; - for (int n = 0; n < 32; n += 8) { - if(bits(Rs, n+7, n) == bits(Rb, n+7, n)) { - val = insertBits(val, n+7, n, 0xff); - } - } - Ra = val; - }}); - - 512: IntOp::mcrxr({{ - CR = insertCRField(CR, BF, XER<31:28>); - XER = XER<27:0>; - }}); - 535: LoadIndexOp::lfsx({{ Ft_sf = Mem_sf; }}); 536: IntLogicOp::srw({{ @@ -500,6 +376,134 @@ decode PO default Unknown::unknown() { } 983: StoreIndexOp::stfiwx({{ Mem = Fs_uw; }}); + + // These instructions are of XO form with bit 21 as the OE bit. + default: decode XO_XO { + format IntSumOp { + 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, true); + 10: addc({{ Ra }}, {{ Rb }}, computeCA = true); + } + + 11: IntArithOp::mulhwu({{ + uint64_t prod = Ra_ud * Rb_ud; + Rt = prod >> 32; + }}); + + 40: IntSumOp::subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); + + 75: IntArithOp::mulhw({{ + int64_t prod = Ra_sd * Rb_sd; + Rt = prod >> 32; + }}); + + format IntSumOp { + 104: neg({{ ~Ra }}, {{ 1 }}); + 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, true); + 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, true); + 200: subfze({{ ~Ra }}, {{ xer.ca }}, computeCA = true); + 202: addze({{ Ra }}, {{ xer.ca }}, computeCA = true); + 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); + 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, true); + } + + format IntArithOp { + 235: mullw({{ + int64_t prod = Ra_sd * Rb_sd; + Rt = prod; + }}); + + // Another variant of mullw decoded with the OE bit set + 747: mullwo({{ + int64_t src1 = Ra_sd; + int64_t src2 = Rb; + int64_t prod = src1 * src2; + Rt = prod; + }}, true); + } + + 266: IntSumOp::add({{ Ra }}, {{ Rb }}); + + format IntArithOp { + 459: divwu({{ + uint32_t src1 = Ra_sw; + uint32_t src2 = Rb_sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + // Another variant of divwu decoded with the OE bit set + 971: divwuo({{ + uint32_t src1 = Ra_sw; + uint32_t src2 = Rb_sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, 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; + } + }}); + + // Another variant of divw decoded with the OE bit set + 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); + } + + default: decode XFX_XO { + format IntOp { + 19: mfcr({{ Rt = CR; }}); + + 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); + }}); + + 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>; + }}); + } + } + } } 32: LoadDispOp::lwz({{ Rt = Mem; }}); @@ -525,9 +529,11 @@ decode PO default Unknown::unknown() { 54: StoreDispOp::stfd({{ Mem_df = Fs; }}); 55: StoreDispUpdateOp::stfdu({{ Mem_df = Fs; }}); - 58: LoadDispOp::lwa({{ Rt = Mem_sw; }}, - {{ EA = Ra + (disp & 0xfffffffc); }}, - {{ EA = disp & 0xfffffffc; }}); + 58: decode DS_XO { + 2: LoadDispOp::lwa({{ Rt = Mem_sw; }}, + {{ EA = Ra + (disp & 0xfffffffc); }}, + {{ EA = disp & 0xfffffffc; }}); + } format FloatArithOp { 59: decode A_XO { @@ -554,7 +560,7 @@ decode PO default Unknown::unknown() { 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); } - default: decode XO_XO { + default: decode X_XO { 0: FloatOp::fcmpu({{ uint32_t c = makeCRField(Fa, Fb); Fpscr fpscr = FPSCR; @@ -596,18 +602,20 @@ decode PO default Unknown::unknown() { 583: mffs({{ Ft_ud = FPSCR; }}); - 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)); + 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)); + } } } - } - }}); + }}); + } } } }