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