brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.5 KiB · f3bdaf7 Raw
1106 lines · cpp
1//===- HexagonMCDuplexInfo.cpp - Instruction bundle checking --------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This implements duplexing of instructions to reduce code size10//11//===----------------------------------------------------------------------===//12 13#include "HexagonMCExpr.h"14#include "MCTargetDesc/HexagonBaseInfo.h"15#include "MCTargetDesc/HexagonMCInstrInfo.h"16#include "MCTargetDesc/HexagonMCTargetDesc.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/MC/MCSubtargetInfo.h"19#include "llvm/Support/Debug.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/Support/MathExtras.h"22#include "llvm/Support/raw_ostream.h"23#include <cassert>24#include <cstdint>25#include <iterator>26#include <map>27#include <utility>28 29using namespace llvm;30using namespace Hexagon;31 32#define DEBUG_TYPE "hexagon-mcduplex-info"33 34// pair table of subInstructions with opcodes35static const std::pair<unsigned, unsigned> opcodeData[] = {36    std::make_pair((unsigned)SA1_addi, 0),37    std::make_pair((unsigned)SA1_addrx, 6144),38    std::make_pair((unsigned)SA1_addsp, 3072),39    std::make_pair((unsigned)SA1_and1, 4608),40    std::make_pair((unsigned)SA1_clrf, 6768),41    std::make_pair((unsigned)SA1_clrfnew, 6736),42    std::make_pair((unsigned)SA1_clrt, 6752),43    std::make_pair((unsigned)SA1_clrtnew, 6720),44    std::make_pair((unsigned)SA1_cmpeqi, 6400),45    std::make_pair((unsigned)SA1_combine0i, 7168),46    std::make_pair((unsigned)SA1_combine1i, 7176),47    std::make_pair((unsigned)SA1_combine2i, 7184),48    std::make_pair((unsigned)SA1_combine3i, 7192),49    std::make_pair((unsigned)SA1_combinerz, 7432),50    std::make_pair((unsigned)SA1_combinezr, 7424),51    std::make_pair((unsigned)SA1_dec, 4864),52    std::make_pair((unsigned)SA1_inc, 4352),53    std::make_pair((unsigned)SA1_seti, 2048),54    std::make_pair((unsigned)SA1_setin1, 6656),55    std::make_pair((unsigned)SA1_sxtb, 5376),56    std::make_pair((unsigned)SA1_sxth, 5120),57    std::make_pair((unsigned)SA1_tfr, 4096),58    std::make_pair((unsigned)SA1_zxtb, 5888),59    std::make_pair((unsigned)SA1_zxth, 5632),60    std::make_pair((unsigned)SL1_loadri_io, 0),61    std::make_pair((unsigned)SL1_loadrub_io, 4096),62    std::make_pair((unsigned)SL2_deallocframe, 7936),63    std::make_pair((unsigned)SL2_jumpr31, 8128),64    std::make_pair((unsigned)SL2_jumpr31_f, 8133),65    std::make_pair((unsigned)SL2_jumpr31_fnew, 8135),66    std::make_pair((unsigned)SL2_jumpr31_t, 8132),67    std::make_pair((unsigned)SL2_jumpr31_tnew, 8134),68    std::make_pair((unsigned)SL2_loadrb_io, 4096),69    std::make_pair((unsigned)SL2_loadrd_sp, 7680),70    std::make_pair((unsigned)SL2_loadrh_io, 0),71    std::make_pair((unsigned)SL2_loadri_sp, 7168),72    std::make_pair((unsigned)SL2_loadruh_io, 2048),73    std::make_pair((unsigned)SL2_return, 8000),74    std::make_pair((unsigned)SL2_return_f, 8005),75    std::make_pair((unsigned)SL2_return_fnew, 8007),76    std::make_pair((unsigned)SL2_return_t, 8004),77    std::make_pair((unsigned)SL2_return_tnew, 8006),78    std::make_pair((unsigned)SS1_storeb_io, 4096),79    std::make_pair((unsigned)SS1_storew_io, 0),80    std::make_pair((unsigned)SS2_allocframe, 7168),81    std::make_pair((unsigned)SS2_storebi0, 4608),82    std::make_pair((unsigned)SS2_storebi1, 4864),83    std::make_pair((unsigned)SS2_stored_sp, 2560),84    std::make_pair((unsigned)SS2_storeh_io, 0),85    std::make_pair((unsigned)SS2_storew_sp, 2048),86    std::make_pair((unsigned)SS2_storewi0, 4096),87    std::make_pair((unsigned)SS2_storewi1, 4352)};88 89bool HexagonMCInstrInfo::isDuplexPairMatch(unsigned Ga, unsigned Gb) {90  switch (Ga) {91  case HexagonII::HSIG_None:92  default:93    return false;94  case HexagonII::HSIG_L1:95    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);96  case HexagonII::HSIG_L2:97    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||98            Gb == HexagonII::HSIG_A);99  case HexagonII::HSIG_S1:100    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||101            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);102  case HexagonII::HSIG_S2:103    return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||104            Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||105            Gb == HexagonII::HSIG_A);106  case HexagonII::HSIG_A:107    return (Gb == HexagonII::HSIG_A);108  case HexagonII::HSIG_Compound:109    return (Gb == HexagonII::HSIG_Compound);110  }111  return false;112}113 114unsigned HexagonMCInstrInfo::iClassOfDuplexPair(unsigned Ga, unsigned Gb) {115  switch (Ga) {116  case HexagonII::HSIG_None:117  default:118    break;119  case HexagonII::HSIG_L1:120    switch (Gb) {121    default:122      break;123    case HexagonII::HSIG_L1:124      return 0;125    case HexagonII::HSIG_A:126      return 0x4;127    }128    break;129  case HexagonII::HSIG_L2:130    switch (Gb) {131    default:132      break;133    case HexagonII::HSIG_L1:134      return 0x1;135    case HexagonII::HSIG_L2:136      return 0x2;137    case HexagonII::HSIG_A:138      return 0x5;139    }140    break;141  case HexagonII::HSIG_S1:142    switch (Gb) {143    default:144      break;145    case HexagonII::HSIG_L1:146      return 0x8;147    case HexagonII::HSIG_L2:148      return 0x9;149    case HexagonII::HSIG_S1:150      return 0xA;151    case HexagonII::HSIG_A:152      return 0x6;153    }154    break;155  case HexagonII::HSIG_S2:156    switch (Gb) {157    default:158      break;159    case HexagonII::HSIG_L1:160      return 0xC;161    case HexagonII::HSIG_L2:162      return 0xD;163    case HexagonII::HSIG_S1:164      return 0xB;165    case HexagonII::HSIG_S2:166      return 0xE;167    case HexagonII::HSIG_A:168      return 0x7;169    }170    break;171  case HexagonII::HSIG_A:172    switch (Gb) {173    default:174      break;175    case HexagonII::HSIG_A:176      return 0x3;177    }178    break;179  case HexagonII::HSIG_Compound:180    switch (Gb) {181    case HexagonII::HSIG_Compound:182      return 0xFFFFFFFF;183    }184    break;185  }186  return 0xFFFFFFFF;187}188 189unsigned HexagonMCInstrInfo::getDuplexCandidateGroup(MCInst const &MCI) {190  MCRegister DstReg, PredReg, SrcReg, Src1Reg, Src2Reg;191 192  switch (MCI.getOpcode()) {193  default:194    return HexagonII::HSIG_None;195  //196  // Group L1:197  //198  // Rd = memw(Rs+#u4:2)199  // Rd = memub(Rs+#u4:0)200  case Hexagon::L2_loadri_io:201    DstReg = MCI.getOperand(0).getReg();202    SrcReg = MCI.getOperand(1).getReg();203    // Special case this one from Group L2.204    // Rd = memw(r29+#u5:2)205    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {206      if (HexagonMCInstrInfo::isIntReg(SrcReg) &&207          Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {208        return HexagonII::HSIG_L2;209      }210      // Rd = memw(Rs+#u4:2)211      if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&212          inRange<4, 2>(MCI, 2)) {213        return HexagonII::HSIG_L1;214      }215    }216    break;217  case Hexagon::L2_loadrub_io:218    // Rd = memub(Rs+#u4:0)219    DstReg = MCI.getOperand(0).getReg();220    SrcReg = MCI.getOperand(1).getReg();221    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&222        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&223        inRange<4>(MCI, 2)) {224      return HexagonII::HSIG_L1;225    }226    break;227  //228  // Group L2:229  //230  // Rd = memh/memuh(Rs+#u3:1)231  // Rd = memb(Rs+#u3:0)232  // Rd = memw(r29+#u5:2) - Handled above.233  // Rdd = memd(r29+#u5:3)234  // deallocframe235  // [if ([!]p0[.new])] dealloc_return236  // [if ([!]p0[.new])] jumpr r31237  case Hexagon::L2_loadrh_io:238  case Hexagon::L2_loadruh_io:239    // Rd = memh/memuh(Rs+#u3:1)240    DstReg = MCI.getOperand(0).getReg();241    SrcReg = MCI.getOperand(1).getReg();242    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&243        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&244        inRange<3, 1>(MCI, 2)) {245      return HexagonII::HSIG_L2;246    }247    break;248  case Hexagon::L2_loadrb_io:249    // Rd = memb(Rs+#u3:0)250    DstReg = MCI.getOperand(0).getReg();251    SrcReg = MCI.getOperand(1).getReg();252    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&253        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&254        inRange<3>(MCI, 2)) {255      return HexagonII::HSIG_L2;256    }257    break;258  case Hexagon::L2_loadrd_io:259    // Rdd = memd(r29+#u5:3)260    DstReg = MCI.getOperand(0).getReg();261    SrcReg = MCI.getOperand(1).getReg();262    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&263        HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&264        inRange<5, 3>(MCI, 2)) {265      return HexagonII::HSIG_L2;266    }267    break;268 269  case Hexagon::L4_return:270  case Hexagon::L2_deallocframe:271    return HexagonII::HSIG_L2;272 273  case Hexagon::EH_RETURN_JMPR:274  case Hexagon::J2_jumpr:275  case Hexagon::PS_jmpret:276    // jumpr r31277    // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0.278    DstReg = MCI.getOperand(0).getReg();279    if (Hexagon::R31 == DstReg)280      return HexagonII::HSIG_L2;281    break;282 283  case Hexagon::J2_jumprt:284  case Hexagon::J2_jumprf:285  case Hexagon::J2_jumprtnew:286  case Hexagon::J2_jumprfnew:287  case Hexagon::PS_jmprett:288  case Hexagon::PS_jmpretf:289  case Hexagon::PS_jmprettnew:290  case Hexagon::PS_jmpretfnew:291  case Hexagon::PS_jmprettnewpt:292  case Hexagon::PS_jmpretfnewpt:293    DstReg = MCI.getOperand(1).getReg();294    SrcReg = MCI.getOperand(0).getReg();295    // [if ([!]p0[.new])] jumpr r31296    if ((Hexagon::P0 == SrcReg) && (Hexagon::R31 == DstReg)) {297      return HexagonII::HSIG_L2;298    }299    break;300  case Hexagon::L4_return_t:301  case Hexagon::L4_return_f:302  case Hexagon::L4_return_tnew_pnt:303  case Hexagon::L4_return_fnew_pnt:304    // [if ([!]p0[.new])] dealloc_return305    SrcReg = MCI.getOperand(1).getReg();306    if (Hexagon::P0 == SrcReg) {307      return HexagonII::HSIG_L2;308    }309    break;310  //311  // Group S1:312  //313  // memw(Rs+#u4:2) = Rt314  // memb(Rs+#u4:0) = Rt315  case Hexagon::S2_storeri_io:316    // Special case this one from Group S2.317    // memw(r29+#u5:2) = Rt318    Src1Reg = MCI.getOperand(0).getReg();319    Src2Reg = MCI.getOperand(2).getReg();320    if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&321        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&322        Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {323      return HexagonII::HSIG_S2;324    }325    // memw(Rs+#u4:2) = Rt326    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&327        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&328        inRange<4, 2>(MCI, 1)) {329      return HexagonII::HSIG_S1;330    }331    break;332  case Hexagon::S2_storerb_io:333    // memb(Rs+#u4:0) = Rt334    Src1Reg = MCI.getOperand(0).getReg();335    Src2Reg = MCI.getOperand(2).getReg();336    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&337        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&338        inRange<4>(MCI, 1)) {339      return HexagonII::HSIG_S1;340    }341    break;342  //343  // Group S2:344  //345  // memh(Rs+#u3:1) = Rt346  // memw(r29+#u5:2) = Rt347  // memd(r29+#s6:3) = Rtt348  // memw(Rs+#u4:2) = #U1349  // memb(Rs+#u4) = #U1350  // allocframe(#u5:3)351  case Hexagon::S2_storerh_io:352    // memh(Rs+#u3:1) = Rt353    Src1Reg = MCI.getOperand(0).getReg();354    Src2Reg = MCI.getOperand(2).getReg();355    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&356        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&357        inRange<3, 1>(MCI, 1)) {358      return HexagonII::HSIG_S2;359    }360    break;361  case Hexagon::S2_storerd_io:362    // memd(r29+#s6:3) = Rtt363    Src1Reg = MCI.getOperand(0).getReg();364    Src2Reg = MCI.getOperand(2).getReg();365    if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&366        HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg &&367        inSRange<6, 3>(MCI, 1)) {368      return HexagonII::HSIG_S2;369    }370    break;371  case Hexagon::S4_storeiri_io:372    // memw(Rs+#u4:2) = #U1373    Src1Reg = MCI.getOperand(0).getReg();374    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&375        inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {376      return HexagonII::HSIG_S2;377    }378    break;379  case Hexagon::S4_storeirb_io:380    // memb(Rs+#u4) = #U1381    Src1Reg = MCI.getOperand(0).getReg();382    if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&383        inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {384      return HexagonII::HSIG_S2;385    }386    break;387  case Hexagon::S2_allocframe:388    if (inRange<5, 3>(MCI, 2))389      return HexagonII::HSIG_S2;390    break;391  //392  // Group A:393  //394  // Rx = add(Rx,#s7)395  // Rd = Rs396  // Rd = #u6397  // Rd = #-1398  // if ([!]P0[.new]) Rd = #0399  // Rd = add(r29,#u6:2)400  // Rx = add(Rx,Rs)401  // P0 = cmp.eq(Rs,#u2)402  // Rdd = combine(#0,Rs)403  // Rdd = combine(Rs,#0)404  // Rdd = combine(#u2,#U2)405  // Rd = add(Rs,#1)406  // Rd = add(Rs,#-1)407  // Rd = sxth/sxtb/zxtb/zxth(Rs)408  // Rd = and(Rs,#1)409  case Hexagon::A2_addi:410    DstReg = MCI.getOperand(0).getReg();411    SrcReg = MCI.getOperand(1).getReg();412    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {413      // Rd = add(r29,#u6:2)414      if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&415          inRange<6, 2>(MCI, 2)) {416        return HexagonII::HSIG_A;417      }418      // Rx = add(Rx,#s7)419      if (DstReg == SrcReg) {420        return HexagonII::HSIG_A;421      }422      // Rd = add(Rs,#1)423      // Rd = add(Rs,#-1)424      if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&425          (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {426        return HexagonII::HSIG_A;427      }428    }429    break;430  case Hexagon::A2_add:431    // Rx = add(Rx,Rs)432    DstReg = MCI.getOperand(0).getReg();433    Src1Reg = MCI.getOperand(1).getReg();434    Src2Reg = MCI.getOperand(2).getReg();435    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&436        HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg)) {437      return HexagonII::HSIG_A;438    }439    break;440  case Hexagon::A2_andir:441    DstReg = MCI.getOperand(0).getReg();442    SrcReg = MCI.getOperand(1).getReg();443    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&444        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&445        (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {446      return HexagonII::HSIG_A;447    }448    break;449  case Hexagon::A2_tfr:450    // Rd = Rs451    DstReg = MCI.getOperand(0).getReg();452    SrcReg = MCI.getOperand(1).getReg();453    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&454        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {455      return HexagonII::HSIG_A;456    }457    break;458  case Hexagon::A2_tfrsi:459    DstReg = MCI.getOperand(0).getReg();460 461    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {462      return HexagonII::HSIG_A;463    }464    break;465  case Hexagon::C2_cmoveit:466  case Hexagon::C2_cmovenewit:467  case Hexagon::C2_cmoveif:468  case Hexagon::C2_cmovenewif:469    // if ([!]P0[.new]) Rd = #0470    // Actual form:471    // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;472    DstReg = MCI.getOperand(0).getReg();  // Rd473    PredReg = MCI.getOperand(1).getReg(); // P0474    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&475        Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {476      return HexagonII::HSIG_A;477    }478    break;479  case Hexagon::C2_cmpeqi:480    // P0 = cmp.eq(Rs,#u2)481    DstReg = MCI.getOperand(0).getReg();482    SrcReg = MCI.getOperand(1).getReg();483    if (Hexagon::P0 == DstReg &&484        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&485        inRange<2>(MCI, 2)) {486      return HexagonII::HSIG_A;487    }488    break;489  case Hexagon::A2_combineii:490  case Hexagon::A4_combineii:491    // Rdd = combine(#u2,#U2)492    DstReg = MCI.getOperand(0).getReg();493    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&494        inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {495      return HexagonII::HSIG_A;496    }497    break;498  case Hexagon::A4_combineri:499    // Rdd = combine(Rs,#0)500    DstReg = MCI.getOperand(0).getReg();501    SrcReg = MCI.getOperand(1).getReg();502    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&503        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&504        minConstant(MCI, 2) == 0) {505      return HexagonII::HSIG_A;506    }507    break;508  case Hexagon::A4_combineir:509    // Rdd = combine(#0,Rs)510    DstReg = MCI.getOperand(0).getReg();511    SrcReg = MCI.getOperand(2).getReg();512    if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&513        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&514        minConstant(MCI, 1) == 0) {515      return HexagonII::HSIG_A;516    }517    break;518  case Hexagon::A2_sxtb:519  case Hexagon::A2_sxth:520  case Hexagon::A2_zxtb:521  case Hexagon::A2_zxth:522    // Rd = sxth/sxtb/zxtb/zxth(Rs)523    DstReg = MCI.getOperand(0).getReg();524    SrcReg = MCI.getOperand(1).getReg();525    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&526        HexagonMCInstrInfo::isIntRegForSubInst(SrcReg)) {527      return HexagonII::HSIG_A;528    }529    break;530  }531 532  return HexagonII::HSIG_None;533}534 535bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const &potentialDuplex) {536  MCRegister DstReg, SrcReg;537  switch (potentialDuplex.getOpcode()) {538  case Hexagon::A2_addi:539    // testing for case of: Rx = add(Rx,#s7)540    DstReg = potentialDuplex.getOperand(0).getReg();541    SrcReg = potentialDuplex.getOperand(1).getReg();542    if (DstReg == SrcReg && HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {543      int64_t Value;544      if (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))545        return true;546      if (!isShiftedInt<7, 0>(Value))547        return true;548    }549    break;550  case Hexagon::A2_tfrsi:551    DstReg = potentialDuplex.getOperand(0).getReg();552 553    if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {554      int64_t Value;555      if (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))556        return true;557      // Check for case of Rd = #-1.558      if (Value == -1)559        return false;560      // Check for case of Rd = #u6.561      if (!isShiftedUInt<6, 0>(Value))562        return true;563    }564    break;565  default:566    break;567  }568  return false;569}570 571/// non-Symmetrical. See if these two instructions are fit for duplex pair.572bool HexagonMCInstrInfo::isOrderedDuplexPair(MCInstrInfo const &MCII,573                                             MCInst const &MIa, bool ExtendedA,574                                             MCInst const &MIb, bool ExtendedB,575                                             bool bisReversable,576                                             MCSubtargetInfo const &STI) {577  // Slot 1 cannot be extended in duplexes PRM 10.5578  if (ExtendedA)579    return false;580  // Only A2_addi and A2_tfrsi can be extended in duplex form PRM 10.5581  if (ExtendedB) {582    unsigned Opcode = MIb.getOpcode();583    if ((Opcode != Hexagon::A2_addi) && (Opcode != Hexagon::A2_tfrsi))584      return false;585  }586  unsigned MIaG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIa),587           MIbG = HexagonMCInstrInfo::getDuplexCandidateGroup(MIb);588 589  static std::map<unsigned, unsigned> subinstOpcodeMap(std::begin(opcodeData),590                                                       std::end(opcodeData));591 592  // If a duplex contains 2 insns in the same group, the insns must be593  // ordered such that the numerically smaller opcode is in slot 1.594  if ((MIaG != HexagonII::HSIG_None) && (MIaG == MIbG) && bisReversable) {595    MCInst SubInst0 = HexagonMCInstrInfo::deriveSubInst(MIa);596    MCInst SubInst1 = HexagonMCInstrInfo::deriveSubInst(MIb);597 598    unsigned zeroedSubInstS0 =599        subinstOpcodeMap.find(SubInst0.getOpcode())->second;600    unsigned zeroedSubInstS1 =601        subinstOpcodeMap.find(SubInst1.getOpcode())->second;602 603    if (zeroedSubInstS0 < zeroedSubInstS1)604      // subinstS0 (maps to slot 0) must be greater than605      // subinstS1 (maps to slot 1)606      return false;607  }608 609  // allocframe must always be in slot 0610  if (MIb.getOpcode() == Hexagon::S2_allocframe)611    return false;612 613  if ((MIaG != HexagonII::HSIG_None) && (MIbG != HexagonII::HSIG_None)) {614    // Prevent 2 instructions with extenders from duplexing615    // Note that MIb (slot1) can be extended and MIa (slot0)616    //   can never be extended617    if (subInstWouldBeExtended(MIa))618      return false;619 620    // If duplexing produces an extender, but the original did not621    //   have an extender, do not duplex.622    if (subInstWouldBeExtended(MIb) && !ExtendedB)623      return false;624  }625 626  // If jumpr r31 appears, it must be in slot 0, and never slot 1 (MIb).627  if (MIbG == HexagonII::HSIG_L2) {628    if ((MIb.getNumOperands() > 1) && MIb.getOperand(1).isReg() &&629        (MIb.getOperand(1).getReg() == Hexagon::R31))630      return false;631    if ((MIb.getNumOperands() > 0) && MIb.getOperand(0).isReg() &&632        (MIb.getOperand(0).getReg() == Hexagon::R31))633      return false;634  }635 636  if (STI.getCPU().equals_insensitive("hexagonv5") ||637      STI.getCPU().equals_insensitive("hexagonv55") ||638      STI.getCPU().equals_insensitive("hexagonv60")) {639    // If a store appears, it must be in slot 0 (MIa) 1st, and then slot 1 (MIb);640    //   therefore, not duplexable if slot 1 is a store, and slot 0 is not.641    if ((MIbG == HexagonII::HSIG_S1) || (MIbG == HexagonII::HSIG_S2)) {642      if ((MIaG != HexagonII::HSIG_S1) && (MIaG != HexagonII::HSIG_S2))643        return false;644    }645  }646 647  return (isDuplexPairMatch(MIaG, MIbG));648}649 650/// Symmetrical. See if these two instructions are fit for duplex pair.651bool HexagonMCInstrInfo::isDuplexPair(MCInst const &MIa, MCInst const &MIb) {652  unsigned MIaG = getDuplexCandidateGroup(MIa),653           MIbG = getDuplexCandidateGroup(MIb);654  return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));655}656 657inline static void addOps(MCInst &subInstPtr, MCInst const &Inst,658                          unsigned opNum) {659  if (Inst.getOperand(opNum).isReg()) {660    switch (Inst.getOperand(opNum).getReg().id()) {661    default:662      llvm_unreachable("Not Duplexable Register");663      break;664    case Hexagon::R0:665    case Hexagon::R1:666    case Hexagon::R2:667    case Hexagon::R3:668    case Hexagon::R4:669    case Hexagon::R5:670    case Hexagon::R6:671    case Hexagon::R7:672    case Hexagon::D0:673    case Hexagon::D1:674    case Hexagon::D2:675    case Hexagon::D3:676    case Hexagon::R16:677    case Hexagon::R17:678    case Hexagon::R18:679    case Hexagon::R19:680    case Hexagon::R20:681    case Hexagon::R21:682    case Hexagon::R22:683    case Hexagon::R23:684    case Hexagon::D8:685    case Hexagon::D9:686    case Hexagon::D10:687    case Hexagon::D11:688    case Hexagon::P0:689      subInstPtr.addOperand(Inst.getOperand(opNum));690      break;691    }692  } else693    subInstPtr.addOperand(Inst.getOperand(opNum));694}695 696MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {697  MCInst Result;698  Result.setLoc(Inst.getLoc());699  bool Absolute;700  int64_t Value;701  switch (Inst.getOpcode()) {702  default:703    // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";704    llvm_unreachable("Unimplemented subinstruction \n");705    break;706  case Hexagon::A2_addi:707    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);708    if (Absolute) {709      if (Value == 1) {710        Result.setOpcode(Hexagon::SA1_inc);711        addOps(Result, Inst, 0);712        addOps(Result, Inst, 1);713        break;714      } //  1,2 SUBInst $Rd = add($Rs, #1)715      if (Value == -1) {716        Result.setOpcode(Hexagon::SA1_dec);717        addOps(Result, Inst, 0);718        addOps(Result, Inst, 1);719        addOps(Result, Inst, 2);720        break;721      } //  1,2 SUBInst $Rd = add($Rs,#-1)722      if (Inst.getOperand(1).getReg() == Hexagon::R29) {723        Result.setOpcode(Hexagon::SA1_addsp);724        addOps(Result, Inst, 0);725        addOps(Result, Inst, 2);726        break;727      } //  1,3 SUBInst $Rd = add(r29, #$u6_2)728    }729    Result.setOpcode(Hexagon::SA1_addi);730    addOps(Result, Inst, 0);731    addOps(Result, Inst, 1);732    addOps(Result, Inst, 2);733    break; //    1,2,3 SUBInst $Rx = add($Rx, #$s7)734  case Hexagon::A2_add:735    Result.setOpcode(Hexagon::SA1_addrx);736    addOps(Result, Inst, 0);737    addOps(Result, Inst, 1);738    addOps(Result, Inst, 2);739    break; //    1,2,3 SUBInst $Rx = add($_src_, $Rs)740  case Hexagon::S2_allocframe:741    Result.setOpcode(Hexagon::SS2_allocframe);742    addOps(Result, Inst, 2);743    break; //    1 SUBInst allocframe(#$u5_3)744  case Hexagon::A2_andir:745    if (minConstant(Inst, 2) == 255) {746      Result.setOpcode(Hexagon::SA1_zxtb);747      addOps(Result, Inst, 0);748      addOps(Result, Inst, 1);749      break; //    1,2    $Rd = and($Rs, #255)750    } else {751      Result.setOpcode(Hexagon::SA1_and1);752      addOps(Result, Inst, 0);753      addOps(Result, Inst, 1);754      break; //    1,2 SUBInst $Rd = and($Rs, #1)755    }756  case Hexagon::C2_cmpeqi:757    Result.setOpcode(Hexagon::SA1_cmpeqi);758    addOps(Result, Inst, 1);759    addOps(Result, Inst, 2);760    break; //    2,3 SUBInst p0 = cmp.eq($Rs, #$u2)761  case Hexagon::A4_combineii:762  case Hexagon::A2_combineii:763    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);764    assert(Absolute);(void)Absolute;765    if (Value == 1) {766      Result.setOpcode(Hexagon::SA1_combine1i);767      addOps(Result, Inst, 0);768      addOps(Result, Inst, 2);769      break; //  1,3 SUBInst $Rdd = combine(#1, #$u2)770    }771    if (Value == 3) {772      Result.setOpcode(Hexagon::SA1_combine3i);773      addOps(Result, Inst, 0);774      addOps(Result, Inst, 2);775      break; //  1,3 SUBInst $Rdd = combine(#3, #$u2)776    }777    if (Value == 0) {778      Result.setOpcode(Hexagon::SA1_combine0i);779      addOps(Result, Inst, 0);780      addOps(Result, Inst, 2);781      break; //  1,3 SUBInst $Rdd = combine(#0, #$u2)782    }783    if (Value == 2) {784      Result.setOpcode(Hexagon::SA1_combine2i);785      addOps(Result, Inst, 0);786      addOps(Result, Inst, 2);787      break; //  1,3 SUBInst $Rdd = combine(#2, #$u2)788    }789    break;790  case Hexagon::A4_combineir:791    Result.setOpcode(Hexagon::SA1_combinezr);792    addOps(Result, Inst, 0);793    addOps(Result, Inst, 2);794    break; //    1,3 SUBInst $Rdd = combine(#0, $Rs)795  case Hexagon::A4_combineri:796    Result.setOpcode(Hexagon::SA1_combinerz);797    addOps(Result, Inst, 0);798    addOps(Result, Inst, 1);799    break; //    1,2 SUBInst $Rdd = combine($Rs, #0)800  case Hexagon::L4_return_tnew_pnt:801  case Hexagon::L4_return_tnew_pt:802    Result.setOpcode(Hexagon::SL2_return_tnew);803    break; //    none  SUBInst if (p0.new) dealloc_return:nt804  case Hexagon::L4_return_fnew_pnt:805  case Hexagon::L4_return_fnew_pt:806    Result.setOpcode(Hexagon::SL2_return_fnew);807    break; //    none  SUBInst if (!p0.new) dealloc_return:nt808  case Hexagon::L4_return_f:809    Result.setOpcode(Hexagon::SL2_return_f);810    break; //    none  SUBInst if (!p0) dealloc_return811  case Hexagon::L4_return_t:812    Result.setOpcode(Hexagon::SL2_return_t);813    break; //    none  SUBInst if (p0) dealloc_return814  case Hexagon::L4_return:815    Result.setOpcode(Hexagon::SL2_return);816    break; //    none  SUBInst dealloc_return817  case Hexagon::L2_deallocframe:818    Result.setOpcode(Hexagon::SL2_deallocframe);819    break; //    none  SUBInst deallocframe820  case Hexagon::EH_RETURN_JMPR:821  case Hexagon::J2_jumpr:822  case Hexagon::PS_jmpret:823    Result.setOpcode(Hexagon::SL2_jumpr31);824    break; //    none  SUBInst jumpr r31825  case Hexagon::J2_jumprf:826  case Hexagon::PS_jmpretf:827    Result.setOpcode(Hexagon::SL2_jumpr31_f);828    break; //    none  SUBInst if (!p0) jumpr r31829  case Hexagon::J2_jumprfnew:830  case Hexagon::PS_jmpretfnewpt:831  case Hexagon::PS_jmpretfnew:832    Result.setOpcode(Hexagon::SL2_jumpr31_fnew);833    break; //    none  SUBInst if (!p0.new) jumpr:nt r31834  case Hexagon::J2_jumprt:835  case Hexagon::PS_jmprett:836    Result.setOpcode(Hexagon::SL2_jumpr31_t);837    break; //    none  SUBInst if (p0) jumpr r31838  case Hexagon::J2_jumprtnew:839  case Hexagon::PS_jmprettnewpt:840  case Hexagon::PS_jmprettnew:841    Result.setOpcode(Hexagon::SL2_jumpr31_tnew);842    break; //    none  SUBInst if (p0.new) jumpr:nt r31843  case Hexagon::L2_loadrb_io:844    Result.setOpcode(Hexagon::SL2_loadrb_io);845    addOps(Result, Inst, 0);846    addOps(Result, Inst, 1);847    addOps(Result, Inst, 2);848    break; //    1,2,3 SUBInst $Rd = memb($Rs + #$u3_0)849  case Hexagon::L2_loadrd_io:850    Result.setOpcode(Hexagon::SL2_loadrd_sp);851    addOps(Result, Inst, 0);852    addOps(Result, Inst, 2);853    break; //    1,3 SUBInst $Rdd = memd(r29 + #$u5_3)854  case Hexagon::L2_loadrh_io:855    Result.setOpcode(Hexagon::SL2_loadrh_io);856    addOps(Result, Inst, 0);857    addOps(Result, Inst, 1);858    addOps(Result, Inst, 2);859    break; //    1,2,3 SUBInst $Rd = memh($Rs + #$u3_1)860  case Hexagon::L2_loadrub_io:861    Result.setOpcode(Hexagon::SL1_loadrub_io);862    addOps(Result, Inst, 0);863    addOps(Result, Inst, 1);864    addOps(Result, Inst, 2);865    break; //    1,2,3 SUBInst $Rd = memub($Rs + #$u4_0)866  case Hexagon::L2_loadruh_io:867    Result.setOpcode(Hexagon::SL2_loadruh_io);868    addOps(Result, Inst, 0);869    addOps(Result, Inst, 1);870    addOps(Result, Inst, 2);871    break; //    1,2,3 SUBInst $Rd = memuh($Rs + #$u3_1)872  case Hexagon::L2_loadri_io:873    if (Inst.getOperand(1).getReg() == Hexagon::R29) {874      Result.setOpcode(Hexagon::SL2_loadri_sp);875      addOps(Result, Inst, 0);876      addOps(Result, Inst, 2);877      break; //  2 1,3 SUBInst $Rd = memw(r29 + #$u5_2)878    } else {879      Result.setOpcode(Hexagon::SL1_loadri_io);880      addOps(Result, Inst, 0);881      addOps(Result, Inst, 1);882      addOps(Result, Inst, 2);883      break; //    1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)884    }885  case Hexagon::S4_storeirb_io:886    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);887    assert(Absolute);(void)Absolute;888    if (Value == 0) {889      Result.setOpcode(Hexagon::SS2_storebi0);890      addOps(Result, Inst, 0);891      addOps(Result, Inst, 1);892      break; //    1,2 SUBInst memb($Rs + #$u4_0)=#0893    } else if (Value == 1) {894      Result.setOpcode(Hexagon::SS2_storebi1);895      addOps(Result, Inst, 0);896      addOps(Result, Inst, 1);897      break; //  2 1,2 SUBInst memb($Rs + #$u4_0)=#1898    }899    break;900  case Hexagon::S2_storerb_io:901    Result.setOpcode(Hexagon::SS1_storeb_io);902    addOps(Result, Inst, 0);903    addOps(Result, Inst, 1);904    addOps(Result, Inst, 2);905    break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt906  case Hexagon::S2_storerd_io:907    Result.setOpcode(Hexagon::SS2_stored_sp);908    addOps(Result, Inst, 1);909    addOps(Result, Inst, 2);910    break; //    2,3 SUBInst memd(r29 + #$s6_3) = $Rtt911  case Hexagon::S2_storerh_io:912    Result.setOpcode(Hexagon::SS2_storeh_io);913    addOps(Result, Inst, 0);914    addOps(Result, Inst, 1);915    addOps(Result, Inst, 2);916    break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt917  case Hexagon::S4_storeiri_io:918    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);919    assert(Absolute);(void)Absolute;920    if (Value == 0) {921      Result.setOpcode(Hexagon::SS2_storewi0);922      addOps(Result, Inst, 0);923      addOps(Result, Inst, 1);924      break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#0925    } else if (Value == 1) {926      Result.setOpcode(Hexagon::SS2_storewi1);927      addOps(Result, Inst, 0);928      addOps(Result, Inst, 1);929      break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#1930    } else if (Inst.getOperand(0).getReg() == Hexagon::R29) {931      Result.setOpcode(Hexagon::SS2_storew_sp);932      addOps(Result, Inst, 1);933      addOps(Result, Inst, 2);934      break; //  1 2,3 SUBInst memw(r29 + #$u5_2) = $Rt935    }936    break;937  case Hexagon::S2_storeri_io:938    if (Inst.getOperand(0).getReg() == Hexagon::R29) {939      Result.setOpcode(Hexagon::SS2_storew_sp);940      addOps(Result, Inst, 1);941      addOps(Result, Inst, 2); //  1,2,3 SUBInst memw(sp + #$u5_2) = $Rt942    } else {943      Result.setOpcode(Hexagon::SS1_storew_io);944      addOps(Result, Inst, 0);945      addOps(Result, Inst, 1);946      addOps(Result, Inst, 2); //  1,2,3 SUBInst memw($Rs + #$u4_2) = $Rt947    }948    break;949  case Hexagon::A2_sxtb:950    Result.setOpcode(Hexagon::SA1_sxtb);951    addOps(Result, Inst, 0);952    addOps(Result, Inst, 1);953    break; //  1,2 SUBInst $Rd = sxtb($Rs)954  case Hexagon::A2_sxth:955    Result.setOpcode(Hexagon::SA1_sxth);956    addOps(Result, Inst, 0);957    addOps(Result, Inst, 1);958    break; //  1,2 SUBInst $Rd = sxth($Rs)959  case Hexagon::A2_tfr:960    Result.setOpcode(Hexagon::SA1_tfr);961    addOps(Result, Inst, 0);962    addOps(Result, Inst, 1);963    break; //  1,2 SUBInst $Rd = $Rs964  case Hexagon::C2_cmovenewif:965    Result.setOpcode(Hexagon::SA1_clrfnew);966    addOps(Result, Inst, 0);967    addOps(Result, Inst, 1);968    break; //  2 SUBInst if (!p0.new) $Rd = #0969  case Hexagon::C2_cmovenewit:970    Result.setOpcode(Hexagon::SA1_clrtnew);971    addOps(Result, Inst, 0);972    addOps(Result, Inst, 1);973    break; //  2 SUBInst if (p0.new) $Rd = #0974  case Hexagon::C2_cmoveif:975    Result.setOpcode(Hexagon::SA1_clrf);976    addOps(Result, Inst, 0);977    addOps(Result, Inst, 1);978    break; //  2 SUBInst if (!p0) $Rd = #0979  case Hexagon::C2_cmoveit:980    Result.setOpcode(Hexagon::SA1_clrt);981    addOps(Result, Inst, 0);982    addOps(Result, Inst, 1);983    break; //  2 SUBInst if (p0) $Rd = #0984  case Hexagon::A2_tfrsi:985    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);986    if (Absolute && Value == -1) {987      Result.setOpcode(Hexagon::SA1_setin1);988      addOps(Result, Inst, 0);989      addOps(Result, Inst, 1);990      break; //  2 1 SUBInst $Rd = #-1991    } else {992      Result.setOpcode(Hexagon::SA1_seti);993      addOps(Result, Inst, 0);994      addOps(Result, Inst, 1);995      break; //    1,2 SUBInst $Rd = #$u6996    }997  case Hexagon::A2_zxtb:998    Result.setOpcode(Hexagon::SA1_zxtb);999    addOps(Result, Inst, 0);1000    addOps(Result, Inst, 1);1001    break; //    1,2    $Rd = and($Rs, #255)1002 1003  case Hexagon::A2_zxth:1004    Result.setOpcode(Hexagon::SA1_zxth);1005    addOps(Result, Inst, 0);1006    addOps(Result, Inst, 1);1007    break; //    1,2 SUBInst $Rd = zxth($Rs)1008  }1009  return Result;1010}1011 1012static bool isStoreInst(unsigned opCode) {1013  switch (opCode) {1014  case Hexagon::S2_storeri_io:1015  case Hexagon::S2_storerb_io:1016  case Hexagon::S2_storerh_io:1017  case Hexagon::S2_storerd_io:1018  case Hexagon::S4_storeiri_io:1019  case Hexagon::S4_storeirb_io:1020  case Hexagon::S2_allocframe:1021    return true;1022  default:1023    return false;1024  }1025}1026 1027SmallVector<DuplexCandidate, 8>1028HexagonMCInstrInfo::getDuplexPossibilties(MCInstrInfo const &MCII,1029                                          MCSubtargetInfo const &STI,1030                                          MCInst const &MCB) {1031  assert(isBundle(MCB));1032  SmallVector<DuplexCandidate, 8> duplexToTry;1033  // Use an "order matters" version of isDuplexPair.1034  unsigned numInstrInPacket = MCB.getNumOperands();1035 1036  for (unsigned distance = 1; distance < numInstrInPacket; ++distance) {1037    for (unsigned j = HexagonMCInstrInfo::bundleInstructionsOffset,1038                  k = j + distance;1039         (j < numInstrInPacket) && (k < numInstrInPacket); ++j, ++k) {1040 1041      // Check if reversible.1042      bool bisReversable = true;1043      if (isStoreInst(MCB.getOperand(j).getInst()->getOpcode()) &&1044          isStoreInst(MCB.getOperand(k).getInst()->getOpcode())) {1045        LLVM_DEBUG(dbgs() << "skip out of order write pair: " << k << "," << j1046                          << "\n");1047        bisReversable = false;1048      }1049      if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf1050        bisReversable = false;1051 1052      // Try in order.1053      if (isOrderedDuplexPair(1054              MCII, *MCB.getOperand(k).getInst(),1055              HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),1056              *MCB.getOperand(j).getInst(),1057              HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),1058              bisReversable, STI)) {1059        // Get iClass.1060        unsigned iClass = iClassOfDuplexPair(1061            getDuplexCandidateGroup(*MCB.getOperand(k).getInst()),1062            getDuplexCandidateGroup(*MCB.getOperand(j).getInst()));1063 1064        // Save off pairs for duplex checking.1065        duplexToTry.push_back(DuplexCandidate(j, k, iClass));1066        LLVM_DEBUG(dbgs() << "adding pair: " << j << "," << k << ":"1067                          << MCB.getOperand(j).getInst()->getOpcode() << ","1068                          << MCB.getOperand(k).getInst()->getOpcode() << "\n");1069        continue;1070      } else {1071        LLVM_DEBUG(dbgs() << "skipping pair: " << j << "," << k << ":"1072                          << MCB.getOperand(j).getInst()->getOpcode() << ","1073                          << MCB.getOperand(k).getInst()->getOpcode() << "\n");1074      }1075 1076      // Try reverse.1077      if (bisReversable) {1078        if (isOrderedDuplexPair(1079                MCII, *MCB.getOperand(j).getInst(),1080                HexagonMCInstrInfo::hasExtenderForIndex(MCB, j - 1),1081                *MCB.getOperand(k).getInst(),1082                HexagonMCInstrInfo::hasExtenderForIndex(MCB, k - 1),1083                bisReversable, STI)) {1084          // Get iClass.1085          unsigned iClass = iClassOfDuplexPair(1086              getDuplexCandidateGroup(*MCB.getOperand(j).getInst()),1087              getDuplexCandidateGroup(*MCB.getOperand(k).getInst()));1088 1089          // Save off pairs for duplex checking.1090          duplexToTry.push_back(DuplexCandidate(k, j, iClass));1091          LLVM_DEBUG(dbgs()1092                     << "adding pair:" << k << "," << j << ":"1093                     << MCB.getOperand(j).getInst()->getOpcode() << ","1094                     << MCB.getOperand(k).getInst()->getOpcode() << "\n");1095        } else {1096          LLVM_DEBUG(dbgs()1097                     << "skipping pair: " << k << "," << j << ":"1098                     << MCB.getOperand(j).getInst()->getOpcode() << ","1099                     << MCB.getOperand(k).getInst()->getOpcode() << "\n");1100        }1101      }1102    }1103  }1104  return duplexToTry;1105}1106