1 //=- LoongArchInstrInfo.cpp - LoongArch Instruction Information -*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the LoongArch implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "LoongArchInstrInfo.h"
14 #include "LoongArch.h"
15 #include "LoongArchMachineFunctionInfo.h"
16 
17 using namespace llvm;
18 
19 #define GET_INSTRINFO_CTOR_DTOR
20 #include "LoongArchGenInstrInfo.inc"
21 
22 LoongArchInstrInfo::LoongArchInstrInfo(LoongArchSubtarget &STI)
23     : LoongArchGenInstrInfo(LoongArch::ADJCALLSTACKDOWN,
24                             LoongArch::ADJCALLSTACKUP) {}
25 
26 void LoongArchInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
27                                      MachineBasicBlock::iterator MBBI,
28                                      const DebugLoc &DL, MCRegister DstReg,
29                                      MCRegister SrcReg, bool KillSrc) const {
30   if (LoongArch::GPRRegClass.contains(DstReg, SrcReg)) {
31     BuildMI(MBB, MBBI, DL, get(LoongArch::OR), DstReg)
32         .addReg(SrcReg, getKillRegState(KillSrc))
33         .addReg(LoongArch::R0);
34     return;
35   }
36 
37   // FPR->FPR copies.
38   unsigned Opc;
39   if (LoongArch::FPR32RegClass.contains(DstReg, SrcReg)) {
40     Opc = LoongArch::FMOV_S;
41   } else if (LoongArch::FPR64RegClass.contains(DstReg, SrcReg)) {
42     Opc = LoongArch::FMOV_D;
43   } else {
44     // TODO: support other copies.
45     llvm_unreachable("Impossible reg-to-reg copy");
46   }
47 
48   BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
49       .addReg(SrcReg, getKillRegState(KillSrc));
50 }
51 
52 void LoongArchInstrInfo::storeRegToStackSlot(
53     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg,
54     bool IsKill, int FI, const TargetRegisterClass *RC,
55     const TargetRegisterInfo *TRI) const {
56   DebugLoc DL;
57   if (I != MBB.end())
58     DL = I->getDebugLoc();
59   MachineFunction *MF = MBB.getParent();
60   MachineFrameInfo &MFI = MF->getFrameInfo();
61 
62   unsigned Opcode;
63   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
64     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
65                  ? LoongArch::ST_W
66                  : LoongArch::ST_D;
67   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
68     Opcode = LoongArch::FST_S;
69   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
70     Opcode = LoongArch::FST_D;
71   else
72     llvm_unreachable("Can't store this register to stack slot");
73 
74   MachineMemOperand *MMO = MF->getMachineMemOperand(
75       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
76       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
77 
78   BuildMI(MBB, I, DL, get(Opcode))
79       .addReg(SrcReg, getKillRegState(IsKill))
80       .addFrameIndex(FI)
81       .addImm(0)
82       .addMemOperand(MMO);
83 }
84 
85 void LoongArchInstrInfo::loadRegFromStackSlot(
86     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DstReg,
87     int FI, const TargetRegisterClass *RC,
88     const TargetRegisterInfo *TRI) const {
89   DebugLoc DL;
90   if (I != MBB.end())
91     DL = I->getDebugLoc();
92   MachineFunction *MF = MBB.getParent();
93   MachineFrameInfo &MFI = MF->getFrameInfo();
94 
95   unsigned Opcode;
96   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
97     Opcode = TRI->getRegSizeInBits(LoongArch::GPRRegClass) == 32
98                  ? LoongArch::LD_W
99                  : LoongArch::LD_D;
100   else if (LoongArch::FPR32RegClass.hasSubClassEq(RC))
101     Opcode = LoongArch::FLD_S;
102   else if (LoongArch::FPR64RegClass.hasSubClassEq(RC))
103     Opcode = LoongArch::FLD_D;
104   else
105     llvm_unreachable("Can't load this register from stack slot");
106 
107   MachineMemOperand *MMO = MF->getMachineMemOperand(
108       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
109       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
110 
111   BuildMI(MBB, I, DL, get(Opcode), DstReg)
112       .addFrameIndex(FI)
113       .addImm(0)
114       .addMemOperand(MMO);
115 }
116