xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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