15eb59800SJyotsna Verma //=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
25eb59800SJyotsna Verma //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65eb59800SJyotsna Verma //
75eb59800SJyotsna Verma //===----------------------------------------------------------------------===//
85eb59800SJyotsna Verma //
95eb59800SJyotsna Verma // When the compiler is invoked with no small data, for instance, with the -G0
10a3386501SKrzysztof Parzyszek // command line option, then all CONST* opcodes should be broken down into
115eb59800SJyotsna Verma // appropriate LO and HI instructions. This splitting is done by this pass.
125eb59800SJyotsna Verma // The only reason this is not done in the DAG lowering itself is that there
135eb59800SJyotsna Verma // is no simple way of getting the register allocator to allot the same hard
145eb59800SJyotsna Verma // register to the result of LO and HI instructions. This pass is always
155eb59800SJyotsna Verma // scheduled after register allocation.
165eb59800SJyotsna Verma //
175eb59800SJyotsna Verma //===----------------------------------------------------------------------===//
180cb8c0b1SBill Wendling 
198a8cd2baSChandler Carruth #include "HexagonSubtarget.h"
200120db5fSEric Christopher #include "HexagonTargetMachine.h"
210120db5fSEric Christopher #include "HexagonTargetObjectFile.h"
225eb59800SJyotsna Verma #include "llvm/CodeGen/MachineFunctionPass.h"
230cb8c0b1SBill Wendling #include "llvm/CodeGen/MachineInstrBuilder.h"
240cb8c0b1SBill Wendling #include "llvm/CodeGen/Passes.h"
253f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
26b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
275eb59800SJyotsna Verma 
285eb59800SJyotsna Verma using namespace llvm;
295eb59800SJyotsna Verma 
3084e68b29SChandler Carruth #define DEBUG_TYPE "xfer"
3184e68b29SChandler Carruth 
3256efafc0SColin LeMahieu namespace llvm {
3356efafc0SColin LeMahieu   FunctionPass *createHexagonSplitConst32AndConst64();
3456efafc0SColin LeMahieu   void initializeHexagonSplitConst32AndConst64Pass(PassRegistry&);
3556efafc0SColin LeMahieu }
3656efafc0SColin LeMahieu 
375eb59800SJyotsna Verma namespace {
385eb59800SJyotsna Verma   class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
395eb59800SJyotsna Verma   public:
405eb59800SJyotsna Verma     static char ID;
HexagonSplitConst32AndConst64()410bbad0fcSKrzysztof Parzyszek     HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {
420bbad0fcSKrzysztof Parzyszek       PassRegistry &R = *PassRegistry::getPassRegistry();
430bbad0fcSKrzysztof Parzyszek       initializeHexagonSplitConst32AndConst64Pass(R);
440bbad0fcSKrzysztof Parzyszek     }
getPassName() const45117296c0SMehdi Amini     StringRef getPassName() const override {
465eb59800SJyotsna Verma       return "Hexagon Split Const32s and Const64s";
475eb59800SJyotsna Verma     }
48906c2cd2SCraig Topper     bool runOnMachineFunction(MachineFunction &Fn) override;
getRequiredProperties() const491dbf7a57SDerek Schuff     MachineFunctionProperties getRequiredProperties() const override {
501dbf7a57SDerek Schuff       return MachineFunctionProperties().set(
511eb47368SMatthias Braun           MachineFunctionProperties::Property::NoVRegs);
521dbf7a57SDerek Schuff     }
535eb59800SJyotsna Verma   };
540bbad0fcSKrzysztof Parzyszek }
555eb59800SJyotsna Verma 
565eb59800SJyotsna Verma char HexagonSplitConst32AndConst64::ID = 0;
575eb59800SJyotsna Verma 
580bbad0fcSKrzysztof Parzyszek INITIALIZE_PASS(HexagonSplitConst32AndConst64, "split-const-for-sdata",
590bbad0fcSKrzysztof Parzyszek       "Hexagon Split Const32s and Const64s", false, false)
605eb59800SJyotsna Verma 
runOnMachineFunction(MachineFunction & Fn)615eb59800SJyotsna Verma bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
6244e180baSKrzysztof Parzyszek   auto &HST = Fn.getSubtarget<HexagonSubtarget>();
6344e180baSKrzysztof Parzyszek   auto &HTM = static_cast<const HexagonTargetMachine&>(Fn.getTarget());
6444e180baSKrzysztof Parzyszek   auto &TLOF = *HTM.getObjFileLowering();
65977a1fe5SKrzysztof Parzyszek   if (HST.useSmallData() && TLOF.isSmallDataEnabled(HTM))
6644e180baSKrzysztof Parzyszek     return false;
670120db5fSEric Christopher 
6844e180baSKrzysztof Parzyszek   const TargetInstrInfo *TII = HST.getInstrInfo();
6944e180baSKrzysztof Parzyszek   const TargetRegisterInfo *TRI = HST.getRegisterInfo();
705eb59800SJyotsna Verma 
715eb59800SJyotsna Verma   // Loop over all of the basic blocks
720bbad0fcSKrzysztof Parzyszek   for (MachineBasicBlock &B : Fn) {
73*2887117dSKazu Hirata     for (MachineInstr &MI : llvm::make_early_inc_range(B)) {
740bbad0fcSKrzysztof Parzyszek       unsigned Opc = MI.getOpcode();
755eb59800SJyotsna Verma 
760bbad0fcSKrzysztof Parzyszek       if (Opc == Hexagon::CONST32) {
770c476111SDaniel Sanders         Register DestReg = MI.getOperand(0).getReg();
780bbad0fcSKrzysztof Parzyszek         uint64_t ImmValue = MI.getOperand(1).getImm();
790bbad0fcSKrzysztof Parzyszek         const DebugLoc &DL = MI.getDebugLoc();
800bbad0fcSKrzysztof Parzyszek         BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestReg)
8198226e3dSDuncan P. N. Exon Smith             .addImm(ImmValue);
820bbad0fcSKrzysztof Parzyszek         B.erase(&MI);
830bbad0fcSKrzysztof Parzyszek       } else if (Opc == Hexagon::CONST64) {
840c476111SDaniel Sanders         Register DestReg = MI.getOperand(0).getReg();
85a3386501SKrzysztof Parzyszek         int64_t ImmValue = MI.getOperand(1).getImm();
860bbad0fcSKrzysztof Parzyszek         const DebugLoc &DL = MI.getDebugLoc();
870c476111SDaniel Sanders         Register DestLo = TRI->getSubReg(DestReg, Hexagon::isub_lo);
880c476111SDaniel Sanders         Register DestHi = TRI->getSubReg(DestReg, Hexagon::isub_hi);
895eb59800SJyotsna Verma 
905eb59800SJyotsna Verma         int32_t LowWord = (ImmValue & 0xFFFFFFFF);
915eb59800SJyotsna Verma         int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
925eb59800SJyotsna Verma 
930bbad0fcSKrzysztof Parzyszek         BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestLo)
9498226e3dSDuncan P. N. Exon Smith             .addImm(LowWord);
950bbad0fcSKrzysztof Parzyszek         BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestHi)
9698226e3dSDuncan P. N. Exon Smith             .addImm(HighWord);
970bbad0fcSKrzysztof Parzyszek         B.erase(&MI);
985eb59800SJyotsna Verma       }
995eb59800SJyotsna Verma     }
1005eb59800SJyotsna Verma   }
1015eb59800SJyotsna Verma 
1025eb59800SJyotsna Verma   return true;
1035eb59800SJyotsna Verma }
1045eb59800SJyotsna Verma 
1055eb59800SJyotsna Verma 
1065eb59800SJyotsna Verma //===----------------------------------------------------------------------===//
1075eb59800SJyotsna Verma //                         Public Constructor Functions
1085eb59800SJyotsna Verma //===----------------------------------------------------------------------===//
createHexagonSplitConst32AndConst64()1090bbad0fcSKrzysztof Parzyszek FunctionPass *llvm::createHexagonSplitConst32AndConst64() {
11001f875e8SEric Christopher   return new HexagonSplitConst32AndConst64();
1115eb59800SJyotsna Verma }
112