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