xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCMacroFusion.def (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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