15ffd83dbSDimitry Andric//=== ---- PPCMacroFusion.def - PowerPC MacroFuson Candidates -v-*- C++ -*-===// 25ffd83dbSDimitry Andric// 35ffd83dbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric// See https)//llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric// SPDX-License-Identifier) Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric// 75ffd83dbSDimitry Andric//===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric// 95ffd83dbSDimitry Andric// This file contains descriptions of the macro-fusion pair for PowerPC. 105ffd83dbSDimitry Andric// 115ffd83dbSDimitry Andric//===----------------------------------------------------------------------===// 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric// NOTE: NO INCLUDE GUARD DESIRED! 145ffd83dbSDimitry Andric 155ffd83dbSDimitry Andric#ifndef FUSION_FEATURE 165ffd83dbSDimitry Andric 175ffd83dbSDimitry Andric// Each FUSION_FEATURE is assigned with one TYPE, and can be enabled/disabled 185ffd83dbSDimitry Andric// by HAS_FEATURE. The instructions pair is fusable only when the opcode 195ffd83dbSDimitry Andric// of the first instruction is in OPSET1, and the second instruction opcode is 205ffd83dbSDimitry Andric// in OPSET2. And if DEP_OP_IDX >=0, we will check the result of first OP is 215ffd83dbSDimitry Andric// the operand of the second op with DEP_OP_IDX as its operand index. We assume 225ffd83dbSDimitry Andric// that the result of the first op is its operand zero. 235ffd83dbSDimitry Andric#define FUSION_FEATURE(TYPE, HAS_FEATURE, DEP_OP_IDX, OPSET1, OPSET2) 245ffd83dbSDimitry Andric 255ffd83dbSDimitry Andric#endif 265ffd83dbSDimitry Andric 275ffd83dbSDimitry Andric#ifndef FUSION_OP_SET 285ffd83dbSDimitry Andric#define FUSION_OP_SET(...) __VA_ARGS__ 295ffd83dbSDimitry Andric#endif 305ffd83dbSDimitry Andric 315ffd83dbSDimitry Andric// Power8 User Manual Section 10.1.12, Instruction Fusion 325ffd83dbSDimitry Andric// {addi} followed by one of these {lxvd2x, lxvw4x, lxvdsx, lvebx, lvehx, 335ffd83dbSDimitry Andric// lvewx, lvx, lxsdx} 345ffd83dbSDimitry AndricFUSION_FEATURE(AddiLoad, hasAddiLoadFusion, 2, \ 35*0fca6ea1SDimitry Andric FUSION_OP_SET(ADDI, ADDI8, ADDItocL, ADDItocL8), \ 365ffd83dbSDimitry Andric FUSION_OP_SET(LXVD2X, LXVW4X, LXVDSX, LVEBX, LVEHX, LVEWX, \ 375ffd83dbSDimitry Andric LVX, LXSDX)) 385ffd83dbSDimitry Andric 395ffd83dbSDimitry Andric// {addis) followed by one of these {ld, lbz, lhz, lwz} 405ffd83dbSDimitry AndricFUSION_FEATURE(AddisLoad, hasAddisLoadFusion, 2, \ 415ffd83dbSDimitry Andric FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8), \ 425ffd83dbSDimitry Andric FUSION_OP_SET(LD, LBZ, LBZ8, LHZ, LHZ8, LWZ, LWZ8)) 435ffd83dbSDimitry Andric 44349cc55cSDimitry Andric// Power10 User Manual Section 19.1.5.4, Fusion 45349cc55cSDimitry Andric// {add, mulld} - add 46349cc55cSDimitry AndricFUSION_FEATURE(ArithAdd, hasArithAddFusion, -1, 47349cc55cSDimitry Andric FUSION_OP_SET(ADD4, ADD8, MULLD), FUSION_OP_SET(ADD4, ADD8)) 48349cc55cSDimitry Andric 49349cc55cSDimitry Andric// {add, subf} - {and, nand, nor, or} 50349cc55cSDimitry AndricFUSION_FEATURE(ArithLogical, hasAddLogicalFusion, -1, 51349cc55cSDimitry Andric FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8), 52349cc55cSDimitry Andric FUSION_OP_SET(AND, AND8, OR, OR8, NAND, NAND8, NOR, NOR8)) 53349cc55cSDimitry Andric 54349cc55cSDimitry Andric// {and, andc, eqv, nand, nor, or, orc, xor} - {add, subf} 55349cc55cSDimitry AndricFUSION_FEATURE(LogicalArith, hasLogicalAddFusion, -1, 56349cc55cSDimitry Andric FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, 57349cc55cSDimitry Andric ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8), 58349cc55cSDimitry Andric FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8)) 59349cc55cSDimitry Andric 60349cc55cSDimitry Andric// Either of {and, andc, eqv, nand, nor, or, orc, xor} 61349cc55cSDimitry AndricFUSION_FEATURE(Logical, hasLogicalFusion, -1, 62349cc55cSDimitry Andric FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, 63349cc55cSDimitry Andric ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8), 64349cc55cSDimitry Andric FUSION_OP_SET(AND, ANDC, EQV, NAND, NOR, OR, ORC, XOR, AND8, 65349cc55cSDimitry Andric ANDC8, EQV8, NAND8, NOR8, OR8, ORC8, XOR8)) 66349cc55cSDimitry Andric 67349cc55cSDimitry Andric// vaddudm - vaddudm 68349cc55cSDimitry AndricFUSION_FEATURE(VecAdd, hasArithAddFusion, -1, FUSION_OP_SET(VADDUDM), 69349cc55cSDimitry Andric FUSION_OP_SET(VADDUDM)) 70349cc55cSDimitry Andric 71349cc55cSDimitry Andric// Either of {vand, vandc, veqv, vnand, vnor, vor, vorc, vxor} 72349cc55cSDimitry AndricFUSION_FEATURE(VecLogical, hasLogicalFusion, -1, 73349cc55cSDimitry Andric FUSION_OP_SET(VAND, VANDC, VEQV, VNAND, VNOR, VOR, VORC, VXOR), 74349cc55cSDimitry Andric FUSION_OP_SET(VAND, VANDC, VEQV, VNAND, VNOR, VOR, VORC, VXOR)) 75349cc55cSDimitry Andric 76349cc55cSDimitry Andric// sldi rx, ra, {3, 6} - {add, subf} 77349cc55cSDimitry Andric// sldi rx, ra n is alias of rldicr rx, ra, n, 63-n 78349cc55cSDimitry AndricFUSION_FEATURE(SldiAdd, hasArithAddFusion, -1, FUSION_OP_SET(RLDICR, RLDICR_32), 79349cc55cSDimitry Andric FUSION_OP_SET(ADD4, ADD8, SUBF, SUBF8)) 80349cc55cSDimitry Andric 814824e7fdSDimitry Andric// rldicl rx, ra, 1, 0 - xor 824824e7fdSDimitry AndricFUSION_FEATURE(RotateLeftXor, hasSha3Fusion, 1, 834824e7fdSDimitry Andric FUSION_OP_SET(RLDICL, RLDICL_32, RLDICL_32_64), 844824e7fdSDimitry Andric FUSION_OP_SET(XOR, XOR8)) 854824e7fdSDimitry Andric 864824e7fdSDimitry Andric// rldicr rx, ra, 1, 63 - xor 874824e7fdSDimitry AndricFUSION_FEATURE(RotateRightXor, hasSha3Fusion, 1, 884824e7fdSDimitry Andric FUSION_OP_SET(RLDICR, RLDICR_32), FUSION_OP_SET(XOR, XOR8)) 894824e7fdSDimitry Andric 904824e7fdSDimitry Andric// There're two special cases in 'load-compare' series, so we have to split 914824e7fdSDimitry Andric// them into several pattern groups to fit into current framework. This can 924824e7fdSDimitry Andric// be clearer once we switched to a more expressive approach. 934824e7fdSDimitry Andric 944824e7fdSDimitry Andric// { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpi 0,1,rx,{ 0,1,-1 } 954824e7fdSDimitry Andric// { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpli 0,L,rx,{ 0,1 } 964824e7fdSDimitry AndricFUSION_FEATURE(LoadCmp1, hasCompareFusion, 1, 974824e7fdSDimitry Andric FUSION_OP_SET(LBZ, LBZ8, LBZX, LBZX8, LBZXTLS, LBZXTLS_, 984824e7fdSDimitry Andric LBZXTLS_32, LHZ, LHZ8, LHZX, LHZX8, LHZXTLS, 994824e7fdSDimitry Andric LHZXTLS_, LHZXTLS_32, LWZ, LWZ8, LWZX, LWZX8, 1004824e7fdSDimitry Andric LWZXTLS, LWZXTLS_, LWZXTLS_32), 1014824e7fdSDimitry Andric FUSION_OP_SET(CMPDI, CMPLDI, CMPLWI)) 1024824e7fdSDimitry Andric 1034824e7fdSDimitry Andric// { ld,ldx } - cmpi 0,1,rx,{ 0,1,-1 } 1044824e7fdSDimitry Andric// { ld,ldx } - cmpli 0,1,rx,{ 0,1 } 1054824e7fdSDimitry AndricFUSION_FEATURE(LoadCmp2, hasCompareFusion, 1, 1064824e7fdSDimitry Andric FUSION_OP_SET(LD, LDX, LDXTLS, LDXTLS_), 1074824e7fdSDimitry Andric FUSION_OP_SET(CMPDI, CMPLDI)) 1084824e7fdSDimitry Andric 1094824e7fdSDimitry Andric// { lha,lhax,lwa,lwax } - cmpi 0,L,rx,{ 0,1,-1 } 1104824e7fdSDimitry AndricFUSION_FEATURE(LoadCmp3, hasCompareFusion, 1, 1114824e7fdSDimitry Andric FUSION_OP_SET(LHA, LHA8, LHAX, LHAX8, LWA, LWA_32, LWAX, 1124824e7fdSDimitry Andric LWAX_32), 1134824e7fdSDimitry Andric FUSION_OP_SET(CMPLDI, CMPLWI)) 1144824e7fdSDimitry Andric 1154824e7fdSDimitry Andric// ori - oris 1164824e7fdSDimitry AndricFUSION_FEATURE(OriOris, hasWideImmFusion, 1, FUSION_OP_SET(ORI, ORI8), 1174824e7fdSDimitry Andric FUSION_OP_SET(ORIS, ORIS8)) 1184824e7fdSDimitry Andric 1194824e7fdSDimitry Andric// lis - ori 1204824e7fdSDimitry AndricFUSION_FEATURE(LisOri, hasWideImmFusion, 1, FUSION_OP_SET(LIS, LIS8), 1214824e7fdSDimitry Andric FUSION_OP_SET(ORI, ORI8)) 1224824e7fdSDimitry Andric 1234824e7fdSDimitry Andric// oris - ori 1244824e7fdSDimitry AndricFUSION_FEATURE(OrisOri, hasWideImmFusion, 1, FUSION_OP_SET(ORIS, ORIS8), 1254824e7fdSDimitry Andric FUSION_OP_SET(ORI, ORI8)) 1264824e7fdSDimitry Andric 1274824e7fdSDimitry Andric// xori - xoris 1284824e7fdSDimitry AndricFUSION_FEATURE(XoriXoris, hasWideImmFusion, 1, FUSION_OP_SET(XORI, XORI8), 1294824e7fdSDimitry Andric FUSION_OP_SET(XORIS, XORIS8)) 1304824e7fdSDimitry Andric 1314824e7fdSDimitry Andric// xoris - xori 1324824e7fdSDimitry AndricFUSION_FEATURE(XorisXori, hasWideImmFusion, 1, FUSION_OP_SET(XORIS, XORIS8), 1334824e7fdSDimitry Andric FUSION_OP_SET(XORI, XORI8)) 1344824e7fdSDimitry Andric 1354824e7fdSDimitry Andric// addis rx,ra,si - addi rt,rx,SI, SI >= 0 1364824e7fdSDimitry AndricFUSION_FEATURE(AddisAddi, hasWideImmFusion, 1, 137*0fca6ea1SDimitry Andric FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8, ADDIStocHA), 138*0fca6ea1SDimitry Andric FUSION_OP_SET(ADDI, ADDI8, ADDItocL8, ADDItocL)) 1394824e7fdSDimitry Andric 1404824e7fdSDimitry Andric// addi rx,ra,si - addis rt,rx,SI, ra > 0, SI >= 2 1414824e7fdSDimitry AndricFUSION_FEATURE(AddiAddis, hasWideImmFusion, 1, 142*0fca6ea1SDimitry Andric FUSION_OP_SET(ADDI, ADDI8, ADDItocL8, ADDItocL), 143*0fca6ea1SDimitry Andric FUSION_OP_SET(ADDIS, ADDIS8, ADDIStocHA8, ADDIStocHA)) 1444824e7fdSDimitry Andric 1454824e7fdSDimitry Andric// mtctr - { bcctr,bcctrl } 1464824e7fdSDimitry AndricFUSION_FEATURE(ZeroMoveCTR, hasZeroMoveFusion, -1, 1474824e7fdSDimitry Andric FUSION_OP_SET(MTCTR, MTCTRloop, MTSPR8, MTSPR), 1484824e7fdSDimitry Andric FUSION_OP_SET(BCCTR, BCCTRn, BCCTR8, BCCTR8n, BCCTRL, BCCTRLn, 1494824e7fdSDimitry Andric BCCTRL8, BCCTRL8n, gBCCTR, gBCCTRL)) 1504824e7fdSDimitry Andric 1514824e7fdSDimitry Andric// mtlr - { bclr,bclrl } 1524824e7fdSDimitry AndricFUSION_FEATURE(ZeroMoveLR, hasZeroMoveFusion, -1, 1534824e7fdSDimitry Andric FUSION_OP_SET(MTLR8, MTLR, MTSPR8, MTSPR), 1544824e7fdSDimitry Andric FUSION_OP_SET(BCLR, BCLRn, gBCLR, BCLRL, BCLRLn, gBCLRL)) 1554824e7fdSDimitry Andric 1560eae32dcSDimitry Andric#include "PPCBack2BackFusion.def" 1570eae32dcSDimitry Andric 1585ffd83dbSDimitry Andric#undef FUSION_FEATURE 1595ffd83dbSDimitry Andric#undef FUSION_OP_SET 160