1 //===-- CSKYInstrInfo.h - CSKY 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 CSKY implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CSKYInstrInfo.h" 14 #include "CSKYMachineFunctionInfo.h" 15 #include "CSKYTargetMachine.h" 16 #include "llvm/MC/MCContext.h" 17 18 #define DEBUG_TYPE "csky-instr-info" 19 20 using namespace llvm; 21 22 #define GET_INSTRINFO_CTOR_DTOR 23 #include "CSKYGenInstrInfo.inc" 24 25 CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI) 26 : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) { 27 } 28 29 Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB, 30 MachineBasicBlock::iterator MBBI, 31 const DebugLoc &DL, int64_t Val, 32 MachineInstr::MIFlag Flag) const { 33 assert(isUInt<32>(Val) && "should be uint32"); 34 35 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 36 37 Register DstReg; 38 if (STI.hasE2()) { 39 DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); 40 41 if (isUInt<16>(Val)) { 42 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg) 43 .addImm(Val & 0xFFFF) 44 .setMIFlags(Flag); 45 } else if (isShiftedUInt<16, 16>(Val)) { 46 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 47 .addImm((Val >> 16) & 0xFFFF) 48 .setMIFlags(Flag); 49 } else { 50 BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg) 51 .addImm((Val >> 16) & 0xFFFF) 52 .setMIFlags(Flag); 53 BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg) 54 .addReg(DstReg) 55 .addImm(Val & 0xFFFF) 56 .setMIFlags(Flag); 57 } 58 59 } else { 60 DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass); 61 if (isUInt<8>(Val)) { 62 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 63 .addImm(Val & 0xFF) 64 .setMIFlags(Flag); 65 } else if (isUInt<16>(Val)) { 66 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 67 .addImm((Val >> 8) & 0xFF) 68 .setMIFlags(Flag); 69 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 70 .addReg(DstReg) 71 .addImm(8) 72 .setMIFlags(Flag); 73 if ((Val & 0xFF) != 0) 74 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 75 .addReg(DstReg) 76 .addImm(Val & 0xFF) 77 .setMIFlags(Flag); 78 } else if (isUInt<24>(Val)) { 79 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 80 .addImm((Val >> 16) & 0xFF) 81 .setMIFlags(Flag); 82 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 83 .addReg(DstReg) 84 .addImm(8) 85 .setMIFlags(Flag); 86 if (((Val >> 8) & 0xFF) != 0) 87 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 88 .addReg(DstReg) 89 .addImm((Val >> 8) & 0xFF) 90 .setMIFlags(Flag); 91 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 92 .addReg(DstReg) 93 .addImm(8) 94 .setMIFlags(Flag); 95 if ((Val & 0xFF) != 0) 96 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 97 .addReg(DstReg) 98 .addImm(Val & 0xFF) 99 .setMIFlags(Flag); 100 } else { 101 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg) 102 .addImm((Val >> 24) & 0xFF) 103 .setMIFlags(Flag); 104 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 105 .addReg(DstReg) 106 .addImm(8) 107 .setMIFlags(Flag); 108 if (((Val >> 16) & 0xFF) != 0) 109 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 110 .addReg(DstReg) 111 .addImm((Val >> 16) & 0xFF) 112 .setMIFlags(Flag); 113 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 114 .addReg(DstReg) 115 .addImm(8) 116 .setMIFlags(Flag); 117 if (((Val >> 8) & 0xFF) != 0) 118 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 119 .addReg(DstReg) 120 .addImm((Val >> 8) & 0xFF) 121 .setMIFlags(Flag); 122 BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg) 123 .addReg(DstReg) 124 .addImm(8) 125 .setMIFlags(Flag); 126 if ((Val & 0xFF) != 0) 127 BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg) 128 .addReg(DstReg) 129 .addImm(Val & 0xFF) 130 .setMIFlags(Flag); 131 } 132 } 133 134 return DstReg; 135 } 136 137 unsigned CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 138 int &FrameIndex) const { 139 switch (MI.getOpcode()) { 140 default: 141 return 0; 142 case CSKY::LD16B: 143 case CSKY::LD16H: 144 case CSKY::LD16W: 145 case CSKY::LD32B: 146 case CSKY::LD32BS: 147 case CSKY::LD32H: 148 case CSKY::LD32HS: 149 case CSKY::LD32W: 150 case CSKY::RESTORE_CARRY: 151 break; 152 } 153 154 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 155 MI.getOperand(2).getImm() == 0) { 156 FrameIndex = MI.getOperand(1).getIndex(); 157 return MI.getOperand(0).getReg(); 158 } 159 160 return 0; 161 } 162 163 unsigned CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI, 164 int &FrameIndex) const { 165 switch (MI.getOpcode()) { 166 default: 167 return 0; 168 case CSKY::ST16B: 169 case CSKY::ST16H: 170 case CSKY::ST16W: 171 case CSKY::ST32B: 172 case CSKY::ST32H: 173 case CSKY::ST32W: 174 case CSKY::SPILL_CARRY: 175 break; 176 } 177 178 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() && 179 MI.getOperand(2).getImm() == 0) { 180 FrameIndex = MI.getOperand(1).getIndex(); 181 return MI.getOperand(0).getReg(); 182 } 183 184 return 0; 185 } 186 187 void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 188 MachineBasicBlock::iterator I, 189 Register SrcReg, bool IsKill, int FI, 190 const TargetRegisterClass *RC, 191 const TargetRegisterInfo *TRI) const { 192 DebugLoc DL; 193 if (I != MBB.end()) 194 DL = I->getDebugLoc(); 195 196 MachineFunction &MF = *MBB.getParent(); 197 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 198 MachineFrameInfo &MFI = MF.getFrameInfo(); 199 200 unsigned Opcode = 0; 201 202 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 203 Opcode = CSKY::ST32W; // Optimize for 16bit 204 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 205 Opcode = CSKY::SPILL_CARRY; 206 CFI->setSpillsCR(); 207 } else { 208 llvm_unreachable("Unknown RegisterClass"); 209 } 210 211 MachineMemOperand *MMO = MF.getMachineMemOperand( 212 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore, 213 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 214 215 BuildMI(MBB, I, DL, get(Opcode)) 216 .addReg(SrcReg, getKillRegState(IsKill)) 217 .addFrameIndex(FI) 218 .addImm(0) 219 .addMemOperand(MMO); 220 } 221 222 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 223 MachineBasicBlock::iterator I, 224 Register DestReg, int FI, 225 const TargetRegisterClass *RC, 226 const TargetRegisterInfo *TRI) const { 227 DebugLoc DL; 228 if (I != MBB.end()) 229 DL = I->getDebugLoc(); 230 231 MachineFunction &MF = *MBB.getParent(); 232 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>(); 233 MachineFrameInfo &MFI = MF.getFrameInfo(); 234 235 unsigned Opcode = 0; 236 237 if (CSKY::GPRRegClass.hasSubClassEq(RC)) { 238 Opcode = CSKY::LD32W; 239 } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { 240 Opcode = CSKY::RESTORE_CARRY; 241 CFI->setSpillsCR(); 242 } else { 243 llvm_unreachable("Unknown RegisterClass"); 244 } 245 246 MachineMemOperand *MMO = MF.getMachineMemOperand( 247 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad, 248 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 249 250 BuildMI(MBB, I, DL, get(Opcode), DestReg) 251 .addFrameIndex(FI) 252 .addImm(0) 253 .addMemOperand(MMO); 254 } 255 256 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 257 MachineBasicBlock::iterator I, 258 const DebugLoc &DL, MCRegister DestReg, 259 MCRegister SrcReg, bool KillSrc) const { 260 261 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 262 263 if (CSKY::GPRRegClass.contains(SrcReg) && 264 CSKY::CARRYRegClass.contains(DestReg)) { 265 if (STI.hasE2()) { 266 BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg) 267 .addReg(SrcReg, getKillRegState(KillSrc)) 268 .addImm(0); 269 } else { 270 assert(SrcReg < CSKY::R8); 271 BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg) 272 .addReg(SrcReg, getKillRegState(KillSrc)) 273 .addImm(0); 274 } 275 return; 276 } 277 278 if (CSKY::CARRYRegClass.contains(SrcReg) && 279 CSKY::GPRRegClass.contains(DestReg)) { 280 281 if (STI.hasE2()) { 282 BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg) 283 .addReg(SrcReg, getKillRegState(KillSrc)); 284 } else { 285 assert(DestReg < CSKY::R16); 286 assert(DestReg < CSKY::R8); 287 BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0); 288 BuildMI(MBB, I, DL, get(CSKY::ADDC16)) 289 .addReg(DestReg, RegState::Define) 290 .addReg(SrcReg, RegState::Define) 291 .addReg(DestReg, getKillRegState(true)) 292 .addReg(DestReg, getKillRegState(true)) 293 .addReg(SrcReg, getKillRegState(true)); 294 BuildMI(MBB, I, DL, get(CSKY::BTSTI16)) 295 .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc)) 296 .addReg(DestReg) 297 .addImm(0); 298 } 299 return; 300 } 301 302 unsigned Opcode = 0; 303 if (CSKY::GPRRegClass.contains(DestReg, SrcReg)) 304 Opcode = CSKY::MOV32; 305 else { 306 LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg); 307 LLVM_DEBUG(I->dump()); 308 llvm_unreachable("Unknown RegisterClass"); 309 } 310 311 BuildMI(MBB, I, DL, get(Opcode), DestReg) 312 .addReg(SrcReg, getKillRegState(KillSrc)); 313 } 314