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