| 1 | //=== ---- PPCMacroFusion.def - PowerPC MacroFuson Candidates -v-*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https)//llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier) Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file contains descriptions of the macro-fusion pair for PowerPC. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | // NOTE: NO INCLUDE GUARD DESIRED! |
| 14 | |
| 15 | #ifndef FUSION_FEATURE |
| 16 | |
| 17 | // Each FUSION_FEATURE is assigned with one TYPE, and can be enabled/disabled |
| 18 | // by HAS_FEATURE. The instructions pair is fusable only when the opcode |
| 19 | // of the first instruction is in OPSET1, and the second instruction opcode is |
| 20 | // in OPSET2. And if DEP_OP_IDX >=0, we will check the result of first OP is |
| 21 | // the operand of the second op with DEP_OP_IDX as its operand index. We assume |
| 22 | // that the result of the first op is its operand zero. |
| 23 | #define FUSION_FEATURE(TYPE, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) |
| 24 | |
| 25 | #endif |
| 26 | |
| 27 | #ifndef FUSION_OP_SET |
| 28 | #define FUSION_OP_SET(...) __VA_ARGS__ |
| 29 | #endif |
| 30 | |
| 31 | // Power8 User Manual Section 10.1.12, Instruction Fusion |
| 32 | // {addi} followed by one of these {lxvd2x, lxvw4x, lxvdsx, lvebx, lvehx, |
| 33 | // lvewx, lvx, lxsdx} |
| 34 | FUSION_FEATURE(AddiLoad, hasAddiLoadFusion, 2, \ |
| 35 | FUSION_OP_SET(ADDI, ADDI8, ADDItocL, ADDItocL8), \ |
| 36 | FUSION_OP_SET(LXVD2X, LXVW4X, LXVDSX, LVEBX, LVEHX, LVEWX, \ |
| 37 | LVX, LXSDX)) |
| 38 | |
| 39 | // {addis) followed by one of these {ld, lbz, lhz, lwz} |
| 40 | FUSION_FEATURE(AddisLoad, hasAddisLoadFusion, 2, \ |
| 41 | FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8), \ |
| 42 | FUSION_OP_SET(LD, LBZ, LBZ8, LHZ, LHZ8, LWZ, LWZ8)) |
| 43 | |
| 44 | // Power10 User Manual Section 19.1.5.4, Fusion |
| 45 | // {add, mulld} - add |
| 46 | FUSION_FEATURE(ArithAdd, hasArithAddFusion, -1, |
| 47 | FUSION_OP_SET(ADD4, ADD8, MULLD), FUSION_OP_SET(ADD4, ADD8)) |
| 48 | |
| 49 | // {add, subf} - {and, nand, nor, or} |
| 50 | FUSION_FEATURE(ArithLogical, hasAddLogicalFusion, -1, |
| 51 | FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8), |
| 52 | FUSION_OP_SET(AND, AND8, OR, OR8, NAND, NAND8, NOR, NOR8)) |
| 53 | |
| 54 | // {and, andc, eqv, nand, nor, or, orc, xor} - {add, subf} |
| 55 | FUSION_FEATURE(LogicalArith, hasLogicalAddFusion, -1, |
| 56 | FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, |
| 57 | ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8), |
| 58 | FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8)) |
| 59 | |
| 60 | // Either of {and, andc, eqv, nand, nor, or, orc, xor} |
| 61 | FUSION_FEATURE(Logical, hasLogicalFusion, -1, |
| 62 | FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, |
| 63 | ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8), |
| 64 | FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, |
| 65 | ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8)) |
| 66 | |
| 67 | // vaddudm - vaddudm |
| 68 | FUSION_FEATURE(VecAdd, hasArithAddFusion, -1, FUSION_OP_SET(VADDUDM), |
| 69 | FUSION_OP_SET(VADDUDM)) |
| 70 | |
| 71 | // Either of {vand, vandc, veqv, vnand, vnor, vor, vorc, vxor} |
| 72 | FUSION_FEATURE(VecLogical, hasLogicalFusion, -1, |
| 73 | FUSION_OP_SET(VAND, VANDC, VEQV, VNAND, VNOR, VOR, VORC, VXOR), |
| 74 | FUSION_OP_SET(VAND, VANDC, VEQV, VNAND, VNOR, VOR, VORC, VXOR)) |
| 75 | |
| 76 | // sldi rx, ra, {3, 6} - {add, subf} |
| 77 | // sldi rx, ra n is alias of rldicr rx, ra, n, 63-n |
| 78 | FUSION_FEATURE(SldiAdd, hasArithAddFusion, -1, FUSION_OP_SET(RLDICR, RLDICR_32), |
| 79 | FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8)) |
| 80 | |
| 81 | // rldicl rx, ra, 1, 0 - xor |
| 82 | FUSION_FEATURE(RotateLeftXor, hasSha3Fusion, 1, |
| 83 | FUSION_OP_SET(RLDICL, RLDICL_32, RLDICL_32_64), |
| 84 | FUSION_OP_SET(XOR, XOR8)) |
| 85 | |
| 86 | // rldicr rx, ra, 1, 63 - xor |
| 87 | FUSION_FEATURE(RotateRightXor, hasSha3Fusion, 1, |
| 88 | FUSION_OP_SET(RLDICR, RLDICR_32), FUSION_OP_SET(XOR, XOR8)) |
| 89 | |
| 90 | // There're two special cases in 'load-compare' series, so we have to split |
| 91 | // them into several pattern groups to fit into current framework. This can |
| 92 | // be clearer once we switched to a more expressive approach. |
| 93 | |
| 94 | // { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpi 0,1,rx,{ 0,1,-1 } |
| 95 | // { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpli 0,L,rx,{ 0,1 } |
| 96 | FUSION_FEATURE(LoadCmp1, hasCompareFusion, 1, |
| 97 | FUSION_OP_SET(LBZ, LBZ8, LBZX, LBZX8, LBZXTLS, LBZXTLS_, |
| 98 | LBZXTLS_32, LHZ, LHZ8, LHZX, LHZX8, LHZXTLS, |
| 99 | LHZXTLS_, LHZXTLS_32, LWZ, LWZ8, LWZX, LWZX8, |
| 100 | LWZXTLS, LWZXTLS_, LWZXTLS_32), |
| 101 | FUSION_OP_SET(CMPDI, CMPLDI, CMPLWI)) |
| 102 | |
| 103 | // { ld,ldx } - cmpi 0,1,rx,{ 0,1,-1 } |
| 104 | // { ld,ldx } - cmpli 0,1,rx,{ 0,1 } |
| 105 | FUSION_FEATURE(LoadCmp2, hasCompareFusion, 1, |
| 106 | FUSION_OP_SET(LD, LDX, LDXTLS, LDXTLS_), |
| 107 | FUSION_OP_SET(CMPDI, CMPLDI)) |
| 108 | |
| 109 | // { lha,lhax,lwa,lwax } - cmpi 0,L,rx,{ 0,1,-1 } |
| 110 | FUSION_FEATURE(LoadCmp3, hasCompareFusion, 1, |
| 111 | FUSION_OP_SET(LHA, LHA8, LHAX, LHAX8, LWA, LWA_32, LWAX, |
| 112 | LWAX_32), |
| 113 | FUSION_OP_SET(CMPLDI, CMPLWI)) |
| 114 | |
| 115 | // ori - oris |
| 116 | FUSION_FEATURE(OriOris, hasWideImmFusion, 1, FUSION_OP_SET(ORI, ORI8), |
| 117 | FUSION_OP_SET(ORIS, ORIS8)) |
| 118 | |
| 119 | // lis - ori |
| 120 | FUSION_FEATURE(LisOri, hasWideImmFusion, 1, FUSION_OP_SET(LIS, LIS8), |
| 121 | FUSION_OP_SET(ORI, ORI8)) |
| 122 | |
| 123 | // oris - ori |
| 124 | FUSION_FEATURE(OrisOri, hasWideImmFusion, 1, FUSION_OP_SET(ORIS, ORIS8), |
| 125 | FUSION_OP_SET(ORI, ORI8)) |
| 126 | |
| 127 | // xori - xoris |
| 128 | FUSION_FEATURE(XoriXoris, hasWideImmFusion, 1, FUSION_OP_SET(XORI, XORI8), |
| 129 | FUSION_OP_SET(XORIS, XORIS8)) |
| 130 | |
| 131 | // xoris - xori |
| 132 | FUSION_FEATURE(XorisXori, hasWideImmFusion, 1, FUSION_OP_SET(XORIS, XORIS8), |
| 133 | FUSION_OP_SET(XORI, XORI8)) |
| 134 | |
| 135 | // addis rx,ra,si - addi rt,rx,SI, SI >= 0 |
| 136 | FUSION_FEATURE(AddisAddi, hasWideImmFusion, 1, |
| 137 | FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8, ADDIStocHA), |
| 138 | FUSION_OP_SET(ADDI, ADDI8, ADDItocL8, ADDItocL)) |
| 139 | |
| 140 | // addi rx,ra,si - addis rt,rx,SI, ra > 0, SI >= 2 |
| 141 | FUSION_FEATURE(AddiAddis, hasWideImmFusion, 1, |
| 142 | FUSION_OP_SET(ADDI, ADDI8, ADDItocL8, ADDItocL), |
| 143 | FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8, ADDIStocHA)) |
| 144 | |
| 145 | // mtctr - { bcctr,bcctrl } |
| 146 | FUSION_FEATURE(ZeroMoveCTR, hasZeroMoveFusion, -1, |
| 147 | FUSION_OP_SET(MTCTR, MTCTRloop, MTSPR8, MTSPR), |
| 148 | FUSION_OP_SET(BCCTR, BCCTRn, BCCTR8, BCCTR8n, BCCTRL, BCCTRLn, |
| 149 | BCCTRL8, BCCTRL8n, gBCCTR, gBCCTRL)) |
| 150 | |
| 151 | // mtlr - { bclr,bclrl } |
| 152 | FUSION_FEATURE(ZeroMoveLR, hasZeroMoveFusion, -1, |
| 153 | FUSION_OP_SET(MTLR8, MTLR, MTSPR8, MTSPR), |
| 154 | FUSION_OP_SET(BCLR, BCLRn, gBCLR, BCLRL, BCLRLn, gBCLRL)) |
| 155 | |
| 156 | #include "PPCBack2BackFusion.def" |
| 157 | |
| 158 | #undef FUSION_FEATURE |
| 159 | #undef FUSION_OP_SET |
| 160 | |