xref: /freebsd/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
181ad6265SDimitry Andric //=- LoongArchInstrInfo.cpp - LoongArch Instruction Information -*- C++ -*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // This file contains the LoongArch implementation of the TargetInstrInfo class.
1081ad6265SDimitry Andric //
1181ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1281ad6265SDimitry Andric 
1381ad6265SDimitry Andric #include "LoongArchInstrInfo.h"
1481ad6265SDimitry Andric #include "LoongArch.h"
15*753f127fSDimitry Andric #include "LoongArchMachineFunctionInfo.h"
1681ad6265SDimitry Andric 
1781ad6265SDimitry Andric using namespace llvm;
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric #define GET_INSTRINFO_CTOR_DTOR
2081ad6265SDimitry Andric #include "LoongArchGenInstrInfo.inc"
2181ad6265SDimitry Andric 
2281ad6265SDimitry Andric LoongArchInstrInfo::LoongArchInstrInfo(LoongArchSubtarget &STI)
23*753f127fSDimitry Andric     : LoongArchGenInstrInfo(LoongArch::ADJCALLSTACKDOWN,
24*753f127fSDimitry Andric                             LoongArch::ADJCALLSTACKUP) {}
2581ad6265SDimitry Andric 
2681ad6265SDimitry Andric void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
2781ad6265SDimitry Andric                                      MachineBasicBlock::iterator MBBI,
2881ad6265SDimitry Andric                                      const DebugLoc &DL, MCRegister DstReg,
2981ad6265SDimitry Andric                                      MCRegister SrcReg, bool KillSrc) const {
3081ad6265SDimitry Andric   if (LoongArch::GPRRegClass.contains(DstReg, SrcReg)) {
3181ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(LoongArch::OR), DstReg)
3281ad6265SDimitry Andric         .addReg(SrcReg, getKillRegState(KillSrc))
3381ad6265SDimitry Andric         .addReg(LoongArch::R0);
3481ad6265SDimitry Andric     return;
3581ad6265SDimitry Andric   }
3681ad6265SDimitry Andric 
3781ad6265SDimitry Andric   // FPR->FPR copies.
3881ad6265SDimitry Andric   unsigned Opc;
3981ad6265SDimitry Andric   if (LoongArch::FPR32RegClass.contains(DstReg, SrcReg)) {
4081ad6265SDimitry Andric     Opc = LoongArch::FMOV_S;
4181ad6265SDimitry Andric   } else if (LoongArch::FPR64RegClass.contains(DstReg, SrcReg)) {
4281ad6265SDimitry Andric     Opc = LoongArch::FMOV_D;
4381ad6265SDimitry Andric   } else {
4481ad6265SDimitry Andric     // TODO: support other copies.
4581ad6265SDimitry Andric     llvm_unreachable("Impossible reg-to-reg copy");
4681ad6265SDimitry Andric   }
4781ad6265SDimitry Andric 
4881ad6265SDimitry Andric   BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
4981ad6265SDimitry Andric       .addReg(SrcReg, getKillRegState(KillSrc));
5081ad6265SDimitry Andric }
51*753f127fSDimitry Andric 
52*753f127fSDimitry Andric void LoongArchInstrInfo::storeRegToStackSlot(
53*753f127fSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg,
54*753f127fSDimitry Andric     bool IsKill, int FI, const TargetRegisterClass *RC,
55*753f127fSDimitry Andric     const TargetRegisterInfo *TRI) const {
56*753f127fSDimitry Andric   DebugLoc DL;
57*753f127fSDimitry Andric   if (I != MBB.end())
58*753f127fSDimitry Andric     DL = I->getDebugLoc();
59*753f127fSDimitry Andric   MachineFunction *MF = MBB.getParent();
60*753f127fSDimitry Andric   MachineFrameInfo &MFI = MF->getFrameInfo();
61*753f127fSDimitry Andric 
62*753f127fSDimitry Andric   unsigned Opcode;
63*753f127fSDimitry Andric   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
64*753f127fSDimitry Andric     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
65*753f127fSDimitry Andric                  ? LoongArch::ST_W
66*753f127fSDimitry Andric                  : LoongArch::ST_D;
67*753f127fSDimitry Andric   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
68*753f127fSDimitry Andric     Opcode = LoongArch::FST_S;
69*753f127fSDimitry Andric   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
70*753f127fSDimitry Andric     Opcode = LoongArch::FST_D;
71*753f127fSDimitry Andric   else
72*753f127fSDimitry Andric     llvm_unreachable("Can't store this register to stack slot");
73*753f127fSDimitry Andric 
74*753f127fSDimitry Andric   MachineMemOperand *MMO = MF->getMachineMemOperand(
75*753f127fSDimitry Andric       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
76*753f127fSDimitry Andric       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
77*753f127fSDimitry Andric 
78*753f127fSDimitry Andric   BuildMI(MBB, I, DL, get(Opcode))
79*753f127fSDimitry Andric       .addReg(SrcReg, getKillRegState(IsKill))
80*753f127fSDimitry Andric       .addFrameIndex(FI)
81*753f127fSDimitry Andric       .addImm(0)
82*753f127fSDimitry Andric       .addMemOperand(MMO);
83*753f127fSDimitry Andric }
84*753f127fSDimitry Andric 
85*753f127fSDimitry Andric void LoongArchInstrInfo::loadRegFromStackSlot(
86*753f127fSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DstReg,
87*753f127fSDimitry Andric     int FI, const TargetRegisterClass *RC,
88*753f127fSDimitry Andric     const TargetRegisterInfo *TRI) const {
89*753f127fSDimitry Andric   DebugLoc DL;
90*753f127fSDimitry Andric   if (I != MBB.end())
91*753f127fSDimitry Andric     DL = I->getDebugLoc();
92*753f127fSDimitry Andric   MachineFunction *MF = MBB.getParent();
93*753f127fSDimitry Andric   MachineFrameInfo &MFI = MF->getFrameInfo();
94*753f127fSDimitry Andric 
95*753f127fSDimitry Andric   unsigned Opcode;
96*753f127fSDimitry Andric   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
97*753f127fSDimitry Andric     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
98*753f127fSDimitry Andric                  ? LoongArch::LD_W
99*753f127fSDimitry Andric                  : LoongArch::LD_D;
100*753f127fSDimitry Andric   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
101*753f127fSDimitry Andric     Opcode = LoongArch::FLD_S;
102*753f127fSDimitry Andric   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
103*753f127fSDimitry Andric     Opcode = LoongArch::FLD_D;
104*753f127fSDimitry Andric   else
105*753f127fSDimitry Andric     llvm_unreachable("Can't load this register from stack slot");
106*753f127fSDimitry Andric 
107*753f127fSDimitry Andric   MachineMemOperand *MMO = MF->getMachineMemOperand(
108*753f127fSDimitry Andric       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
109*753f127fSDimitry Andric       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
110*753f127fSDimitry Andric 
111*753f127fSDimitry Andric   BuildMI(MBB, I, DL, get(Opcode), DstReg)
112*753f127fSDimitry Andric       .addFrameIndex(FI)
113*753f127fSDimitry Andric       .addImm(0)
114*753f127fSDimitry Andric       .addMemOperand(MMO);
115*753f127fSDimitry Andric }
116