1 //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the VE implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "VEInstrInfo.h"
15 #include "VEMachineFunctionInfo.h"
16 #include "VESubtarget.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineMemOperand.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/MC/TargetRegistry.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/ErrorHandling.h"
27 #define DEBUG_TYPE "ve-instr-info"
31 #define GET_INSTRINFO_CTOR_DTOR
32 #include "VEGenInstrInfo.inc"
34 // Pin the vtable to this file.
35 void VEInstrInfo::anchor() {}
37 VEInstrInfo::VEInstrInfo(VESubtarget
&ST
)
38 : VEGenInstrInfo(VE::ADJCALLSTACKDOWN
, VE::ADJCALLSTACKUP
), RI() {}
40 static bool IsIntegerCC(unsigned CC
) { return (CC
< VECC::CC_AF
); }
42 static VECC::CondCode
GetOppositeBranchCondition(VECC::CondCode CC
) {
59 return VECC::CC_LENAN
;
61 return VECC::CC_GENAN
;
63 return VECC::CC_EQNAN
;
65 return VECC::CC_NENAN
;
91 llvm_unreachable("Invalid cond code");
94 // Treat a branch relative long always instruction as unconditional branch.
95 // For example, br.l.t and br.l.
96 static bool isUncondBranchOpcode(int Opc
) {
97 using namespace llvm::VE
;
99 #define BRKIND(NAME) (Opc == NAME##a || Opc == NAME##a_nt || Opc == NAME##a_t)
100 // VE has other branch relative always instructions for word/double/float,
101 // but we use only long branches in our lower. So, check it here.
102 assert(!BRKIND(BRCFW
) && !BRKIND(BRCFD
) && !BRKIND(BRCFS
) &&
103 "Branch relative word/double/float always instructions should not be "
105 return BRKIND(BRCFL
);
109 // Treat branch relative conditional as conditional branch instructions.
110 // For example, brgt.l.t and brle.s.nt.
111 static bool isCondBranchOpcode(int Opc
) {
112 using namespace llvm::VE
;
114 #define BRKIND(NAME) \
115 (Opc == NAME##rr || Opc == NAME##rr_nt || Opc == NAME##rr_t || \
116 Opc == NAME##ir || Opc == NAME##ir_nt || Opc == NAME##ir_t)
117 return BRKIND(BRCFL
) || BRKIND(BRCFW
) || BRKIND(BRCFD
) || BRKIND(BRCFS
);
121 // Treat branch long always instructions as indirect branch.
122 // For example, b.l.t and b.l.
123 static bool isIndirectBranchOpcode(int Opc
) {
124 using namespace llvm::VE
;
126 #define BRKIND(NAME) \
127 (Opc == NAME##ari || Opc == NAME##ari_nt || Opc == NAME##ari_t)
128 // VE has other branch always instructions for word/double/float, but
129 // we use only long branches in our lower. So, check it here.
130 assert(!BRKIND(BCFW
) && !BRKIND(BCFD
) && !BRKIND(BCFS
) &&
131 "Branch word/double/float always instructions should not be used!");
136 static void parseCondBranch(MachineInstr
*LastInst
, MachineBasicBlock
*&Target
,
137 SmallVectorImpl
<MachineOperand
> &Cond
) {
138 Cond
.push_back(MachineOperand::CreateImm(LastInst
->getOperand(0).getImm()));
139 Cond
.push_back(LastInst
->getOperand(1));
140 Cond
.push_back(LastInst
->getOperand(2));
141 Target
= LastInst
->getOperand(3).getMBB();
144 bool VEInstrInfo::analyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
145 MachineBasicBlock
*&FBB
,
146 SmallVectorImpl
<MachineOperand
> &Cond
,
147 bool AllowModify
) const {
148 MachineBasicBlock::iterator I
= MBB
.getLastNonDebugInstr();
152 if (!isUnpredicatedTerminator(*I
))
155 // Get the last instruction in the block.
156 MachineInstr
*LastInst
= &*I
;
157 unsigned LastOpc
= LastInst
->getOpcode();
159 // If there is only one terminator instruction, process it.
160 if (I
== MBB
.begin() || !isUnpredicatedTerminator(*--I
)) {
161 if (isUncondBranchOpcode(LastOpc
)) {
162 TBB
= LastInst
->getOperand(0).getMBB();
165 if (isCondBranchOpcode(LastOpc
)) {
166 // Block ends with fall-through condbranch.
167 parseCondBranch(LastInst
, TBB
, Cond
);
170 return true; // Can't handle indirect branch.
173 // Get the instruction before it if it is a terminator.
174 MachineInstr
*SecondLastInst
= &*I
;
175 unsigned SecondLastOpc
= SecondLastInst
->getOpcode();
177 // If AllowModify is true and the block ends with two or more unconditional
178 // branches, delete all but the first unconditional branch.
179 if (AllowModify
&& isUncondBranchOpcode(LastOpc
)) {
180 while (isUncondBranchOpcode(SecondLastOpc
)) {
181 LastInst
->eraseFromParent();
182 LastInst
= SecondLastInst
;
183 LastOpc
= LastInst
->getOpcode();
184 if (I
== MBB
.begin() || !isUnpredicatedTerminator(*--I
)) {
185 // Return now the only terminator is an unconditional branch.
186 TBB
= LastInst
->getOperand(0).getMBB();
189 SecondLastInst
= &*I
;
190 SecondLastOpc
= SecondLastInst
->getOpcode();
194 // If there are three terminators, we don't know what sort of block this is.
195 if (SecondLastInst
&& I
!= MBB
.begin() && isUnpredicatedTerminator(*--I
))
198 // If the block ends with a B and a Bcc, handle it.
199 if (isCondBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
200 parseCondBranch(SecondLastInst
, TBB
, Cond
);
201 FBB
= LastInst
->getOperand(0).getMBB();
205 // If the block ends with two unconditional branches, handle it. The second
206 // one is not executed.
207 if (isUncondBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
208 TBB
= SecondLastInst
->getOperand(0).getMBB();
212 // ...likewise if it ends with an indirect branch followed by an unconditional
214 if (isIndirectBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
217 I
->eraseFromParent();
221 // Otherwise, can't handle this.
225 unsigned VEInstrInfo::insertBranch(MachineBasicBlock
&MBB
,
226 MachineBasicBlock
*TBB
,
227 MachineBasicBlock
*FBB
,
228 ArrayRef
<MachineOperand
> Cond
,
229 const DebugLoc
&DL
, int *BytesAdded
) const {
230 assert(TBB
&& "insertBranch must not be told to insert a fallthrough");
231 assert((Cond
.size() == 3 || Cond
.size() == 0) &&
232 "VE branch conditions should have three component!");
233 assert(!BytesAdded
&& "code size not handled");
235 // Uncondition branch
236 assert(!FBB
&& "Unconditional branch with multiple successors!");
237 BuildMI(&MBB
, DL
, get(VE::BRCFLa_t
))
242 // Conditional branch
243 // (BRCFir CC sy sz addr)
244 assert(Cond
[0].isImm() && Cond
[2].isReg() && "not implemented");
247 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
248 MachineFunction
*MF
= MBB
.getParent();
249 const MachineRegisterInfo
&MRI
= MF
->getRegInfo();
250 Register Reg
= Cond
[2].getReg();
251 if (IsIntegerCC(Cond
[0].getImm())) {
252 if (TRI
->getRegSizeInBits(Reg
, MRI
) == 32) {
253 opc
[0] = VE::BRCFWir
;
254 opc
[1] = VE::BRCFWrr
;
256 opc
[0] = VE::BRCFLir
;
257 opc
[1] = VE::BRCFLrr
;
260 if (TRI
->getRegSizeInBits(Reg
, MRI
) == 32) {
261 opc
[0] = VE::BRCFSir
;
262 opc
[1] = VE::BRCFSrr
;
264 opc
[0] = VE::BRCFDir
;
265 opc
[1] = VE::BRCFDrr
;
268 if (Cond
[1].isImm()) {
269 BuildMI(&MBB
, DL
, get(opc
[0]))
270 .add(Cond
[0]) // condition code
275 BuildMI(&MBB
, DL
, get(opc
[1]))
285 BuildMI(&MBB
, DL
, get(VE::BRCFLa_t
))
290 unsigned VEInstrInfo::removeBranch(MachineBasicBlock
&MBB
,
291 int *BytesRemoved
) const {
292 assert(!BytesRemoved
&& "code size not handled");
294 MachineBasicBlock::iterator I
= MBB
.end();
296 while (I
!= MBB
.begin()) {
299 if (I
->isDebugValue())
302 if (!isUncondBranchOpcode(I
->getOpcode()) &&
303 !isCondBranchOpcode(I
->getOpcode()))
304 break; // Not a branch
306 I
->eraseFromParent();
313 bool VEInstrInfo::reverseBranchCondition(
314 SmallVectorImpl
<MachineOperand
> &Cond
) const {
315 VECC::CondCode CC
= static_cast<VECC::CondCode
>(Cond
[0].getImm());
316 Cond
[0].setImm(GetOppositeBranchCondition(CC
));
320 static bool IsAliasOfSX(Register Reg
) {
321 return VE::I32RegClass
.contains(Reg
) || VE::I64RegClass
.contains(Reg
) ||
322 VE::F32RegClass
.contains(Reg
);
325 static void copyPhysSubRegs(MachineBasicBlock
&MBB
,
326 MachineBasicBlock::iterator I
, const DebugLoc
&DL
,
327 MCRegister DestReg
, MCRegister SrcReg
, bool KillSrc
,
328 const MCInstrDesc
&MCID
, unsigned int NumSubRegs
,
329 const unsigned *SubRegIdx
,
330 const TargetRegisterInfo
*TRI
) {
331 MachineInstr
*MovMI
= nullptr;
333 for (unsigned Idx
= 0; Idx
!= NumSubRegs
; ++Idx
) {
334 Register SubDest
= TRI
->getSubReg(DestReg
, SubRegIdx
[Idx
]);
335 Register SubSrc
= TRI
->getSubReg(SrcReg
, SubRegIdx
[Idx
]);
336 assert(SubDest
&& SubSrc
&& "Bad sub-register");
338 if (MCID
.getOpcode() == VE::ORri
) {
339 // generate "ORri, dest, src, 0" instruction.
340 MachineInstrBuilder MIB
=
341 BuildMI(MBB
, I
, DL
, MCID
, SubDest
).addReg(SubSrc
).addImm(0);
342 MovMI
= MIB
.getInstr();
343 } else if (MCID
.getOpcode() == VE::ANDMmm
) {
344 // generate "ANDM, dest, vm0, src" instruction.
345 MachineInstrBuilder MIB
=
346 BuildMI(MBB
, I
, DL
, MCID
, SubDest
).addReg(VE::VM0
).addReg(SubSrc
);
347 MovMI
= MIB
.getInstr();
349 llvm_unreachable("Unexpected reg-to-reg copy instruction");
352 // Add implicit super-register defs and kills to the last MovMI.
353 MovMI
->addRegisterDefined(DestReg
, TRI
);
355 MovMI
->addRegisterKilled(SrcReg
, TRI
, true);
358 void VEInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
359 MachineBasicBlock::iterator I
, const DebugLoc
&DL
,
360 MCRegister DestReg
, MCRegister SrcReg
,
361 bool KillSrc
, bool RenamableDest
,
362 bool RenamableSrc
) const {
364 if (IsAliasOfSX(SrcReg
) && IsAliasOfSX(DestReg
)) {
365 BuildMI(MBB
, I
, DL
, get(VE::ORri
), DestReg
)
366 .addReg(SrcReg
, getKillRegState(KillSrc
))
368 } else if (VE::V64RegClass
.contains(DestReg
, SrcReg
)) {
369 // Generate following instructions
370 // %sw16 = LEA32zii 256
371 // VORmvl %dest, (0)1, %src, %sw16
372 // TODO: reuse a register if vl is already assigned to a register
373 // FIXME: it would be better to scavenge a register here instead of
374 // reserving SX16 all of the time.
375 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
376 Register TmpReg
= VE::SX16
;
377 Register SubTmp
= TRI
->getSubReg(TmpReg
, VE::sub_i32
);
378 BuildMI(MBB
, I
, DL
, get(VE::LEAzii
), TmpReg
)
382 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, DL
, get(VE::VORmvl
), DestReg
)
383 .addImm(M1(0)) // Represent (0)1.
384 .addReg(SrcReg
, getKillRegState(KillSrc
))
385 .addReg(SubTmp
, getKillRegState(true));
386 MIB
.getInstr()->addRegisterKilled(TmpReg
, TRI
, true);
387 } else if (VE::VMRegClass
.contains(DestReg
, SrcReg
)) {
388 BuildMI(MBB
, I
, DL
, get(VE::ANDMmm
), DestReg
)
390 .addReg(SrcReg
, getKillRegState(KillSrc
));
391 } else if (VE::VM512RegClass
.contains(DestReg
, SrcReg
)) {
392 // Use two instructions.
393 const unsigned SubRegIdx
[] = {VE::sub_vm_even
, VE::sub_vm_odd
};
394 unsigned int NumSubRegs
= 2;
395 copyPhysSubRegs(MBB
, I
, DL
, DestReg
, SrcReg
, KillSrc
, get(VE::ANDMmm
),
396 NumSubRegs
, SubRegIdx
, &getRegisterInfo());
397 } else if (VE::F128RegClass
.contains(DestReg
, SrcReg
)) {
398 // Use two instructions.
399 const unsigned SubRegIdx
[] = {VE::sub_even
, VE::sub_odd
};
400 unsigned int NumSubRegs
= 2;
401 copyPhysSubRegs(MBB
, I
, DL
, DestReg
, SrcReg
, KillSrc
, get(VE::ORri
),
402 NumSubRegs
, SubRegIdx
, &getRegisterInfo());
404 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
405 dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg
, TRI
)
406 << " to " << printReg(DestReg
, TRI
) << "\n";
407 llvm_unreachable("Impossible reg-to-reg copy");
411 /// isLoadFromStackSlot - If the specified machine instruction is a direct
412 /// load from a stack slot, return the virtual or physical register number of
413 /// the destination along with the FrameIndex of the loaded stack slot. If
414 /// not, return 0. This predicate must return 0 if the instruction has
415 /// any side effects other than loading from the stack slot.
416 Register
VEInstrInfo::isLoadFromStackSlot(const MachineInstr
&MI
,
417 int &FrameIndex
) const {
418 if (MI
.getOpcode() == VE::LDrii
|| // I64
419 MI
.getOpcode() == VE::LDLSXrii
|| // I32
420 MI
.getOpcode() == VE::LDUrii
|| // F32
421 MI
.getOpcode() == VE::LDQrii
|| // F128 (pseudo)
422 MI
.getOpcode() == VE::LDVMrii
|| // VM (pseudo)
423 MI
.getOpcode() == VE::LDVM512rii
// VM512 (pseudo)
425 if (MI
.getOperand(1).isFI() && MI
.getOperand(2).isImm() &&
426 MI
.getOperand(2).getImm() == 0 && MI
.getOperand(3).isImm() &&
427 MI
.getOperand(3).getImm() == 0) {
428 FrameIndex
= MI
.getOperand(1).getIndex();
429 return MI
.getOperand(0).getReg();
435 /// isStoreToStackSlot - If the specified machine instruction is a direct
436 /// store to a stack slot, return the virtual or physical register number of
437 /// the source reg along with the FrameIndex of the loaded stack slot. If
438 /// not, return 0. This predicate must return 0 if the instruction has
439 /// any side effects other than storing to the stack slot.
440 Register
VEInstrInfo::isStoreToStackSlot(const MachineInstr
&MI
,
441 int &FrameIndex
) const {
442 if (MI
.getOpcode() == VE::STrii
|| // I64
443 MI
.getOpcode() == VE::STLrii
|| // I32
444 MI
.getOpcode() == VE::STUrii
|| // F32
445 MI
.getOpcode() == VE::STQrii
|| // F128 (pseudo)
446 MI
.getOpcode() == VE::STVMrii
|| // VM (pseudo)
447 MI
.getOpcode() == VE::STVM512rii
// VM512 (pseudo)
449 if (MI
.getOperand(0).isFI() && MI
.getOperand(1).isImm() &&
450 MI
.getOperand(1).getImm() == 0 && MI
.getOperand(2).isImm() &&
451 MI
.getOperand(2).getImm() == 0) {
452 FrameIndex
= MI
.getOperand(0).getIndex();
453 return MI
.getOperand(3).getReg();
459 void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
460 MachineBasicBlock::iterator I
,
461 Register SrcReg
, bool isKill
, int FI
,
462 const TargetRegisterClass
*RC
,
463 const TargetRegisterInfo
*TRI
,
464 Register VReg
) const {
467 DL
= I
->getDebugLoc();
469 MachineFunction
*MF
= MBB
.getParent();
470 const MachineFrameInfo
&MFI
= MF
->getFrameInfo();
471 MachineMemOperand
*MMO
= MF
->getMachineMemOperand(
472 MachinePointerInfo::getFixedStack(*MF
, FI
), MachineMemOperand::MOStore
,
473 MFI
.getObjectSize(FI
), MFI
.getObjectAlign(FI
));
475 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
476 if (RC
== &VE::I64RegClass
) {
477 BuildMI(MBB
, I
, DL
, get(VE::STrii
))
481 .addReg(SrcReg
, getKillRegState(isKill
))
483 } else if (RC
== &VE::I32RegClass
) {
484 BuildMI(MBB
, I
, DL
, get(VE::STLrii
))
488 .addReg(SrcReg
, getKillRegState(isKill
))
490 } else if (RC
== &VE::F32RegClass
) {
491 BuildMI(MBB
, I
, DL
, get(VE::STUrii
))
495 .addReg(SrcReg
, getKillRegState(isKill
))
497 } else if (VE::F128RegClass
.hasSubClassEq(RC
)) {
498 BuildMI(MBB
, I
, DL
, get(VE::STQrii
))
502 .addReg(SrcReg
, getKillRegState(isKill
))
504 } else if (RC
== &VE::VMRegClass
) {
505 BuildMI(MBB
, I
, DL
, get(VE::STVMrii
))
509 .addReg(SrcReg
, getKillRegState(isKill
))
511 } else if (VE::VM512RegClass
.hasSubClassEq(RC
)) {
512 BuildMI(MBB
, I
, DL
, get(VE::STVM512rii
))
516 .addReg(SrcReg
, getKillRegState(isKill
))
519 report_fatal_error("Can't store this register to stack slot");
522 void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
523 MachineBasicBlock::iterator I
,
524 Register DestReg
, int FI
,
525 const TargetRegisterClass
*RC
,
526 const TargetRegisterInfo
*TRI
,
527 Register VReg
) const {
530 DL
= I
->getDebugLoc();
532 MachineFunction
*MF
= MBB
.getParent();
533 const MachineFrameInfo
&MFI
= MF
->getFrameInfo();
534 MachineMemOperand
*MMO
= MF
->getMachineMemOperand(
535 MachinePointerInfo::getFixedStack(*MF
, FI
), MachineMemOperand::MOLoad
,
536 MFI
.getObjectSize(FI
), MFI
.getObjectAlign(FI
));
538 if (RC
== &VE::I64RegClass
) {
539 BuildMI(MBB
, I
, DL
, get(VE::LDrii
), DestReg
)
544 } else if (RC
== &VE::I32RegClass
) {
545 BuildMI(MBB
, I
, DL
, get(VE::LDLSXrii
), DestReg
)
550 } else if (RC
== &VE::F32RegClass
) {
551 BuildMI(MBB
, I
, DL
, get(VE::LDUrii
), DestReg
)
556 } else if (VE::F128RegClass
.hasSubClassEq(RC
)) {
557 BuildMI(MBB
, I
, DL
, get(VE::LDQrii
), DestReg
)
562 } else if (RC
== &VE::VMRegClass
) {
563 BuildMI(MBB
, I
, DL
, get(VE::LDVMrii
), DestReg
)
568 } else if (VE::VM512RegClass
.hasSubClassEq(RC
)) {
569 BuildMI(MBB
, I
, DL
, get(VE::LDVM512rii
), DestReg
)
575 report_fatal_error("Can't load this register from stack slot");
578 bool VEInstrInfo::foldImmediate(MachineInstr
&UseMI
, MachineInstr
&DefMI
,
579 Register Reg
, MachineRegisterInfo
*MRI
) const {
580 LLVM_DEBUG(dbgs() << "foldImmediate\n");
582 LLVM_DEBUG(dbgs() << "checking DefMI\n");
584 switch (DefMI
.getOpcode()) {
588 // General move small immediate instruction on VE.
589 LLVM_DEBUG(dbgs() << "checking ORim\n");
590 LLVM_DEBUG(DefMI
.dump());
591 // FIXME: We may need to support FPImm too.
592 assert(DefMI
.getOperand(1).isImm());
593 assert(DefMI
.getOperand(2).isImm());
595 DefMI
.getOperand(1).getImm() + mimm2Val(DefMI
.getOperand(2).getImm());
596 LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal
<< "\n");
599 // General move immediate instruction on VE.
600 LLVM_DEBUG(dbgs() << "checking LEAzii\n");
601 LLVM_DEBUG(DefMI
.dump());
602 // FIXME: We may need to support FPImm too.
603 assert(DefMI
.getOperand(2).isImm());
604 if (!DefMI
.getOperand(3).isImm())
605 // LEAzii may refer label
607 ImmVal
= DefMI
.getOperand(2).getImm() + DefMI
.getOperand(3).getImm();
608 LLVM_DEBUG(dbgs() << "ImmVal is " << ImmVal
<< "\n");
612 // Try to fold like below:
613 // %1:i64 = ORim 0, 0(1)
614 // %2:i64 = CMPSLrr %0, %1
616 // %2:i64 = CMPSLrm %0, 0(1)
619 // %1:i64 = ORim 6, 0(1)
620 // %2:i64 = CMPSLrr %1, %0
622 // %2:i64 = CMPSLir 6, %0
624 // Support commutable instructions like below:
625 // %1:i64 = ORim 6, 0(1)
626 // %2:i64 = ADDSLrr %1, %0
628 // %2:i64 = ADDSLri %0, 6
630 // FIXME: Need to support i32. Current implementtation requires
631 // EXTRACT_SUBREG, so input has following COPY and it avoids folding:
632 // %1:i64 = ORim 6, 0(1)
633 // %2:i32 = COPY %1.sub_i32
634 // %3:i32 = ADDSWSXrr %0, %2
635 // FIXME: Need to support shift, cmov, and more instructions.
636 // FIXME: Need to support lvl too, but LVLGen runs after peephole-opt.
638 LLVM_DEBUG(dbgs() << "checking UseMI\n");
639 LLVM_DEBUG(UseMI
.dump());
640 unsigned NewUseOpcSImm7
;
641 unsigned NewUseOpcMImm
;
643 rr2ri_rm
, // rr -> ri or rm, commutable
644 rr2ir_rm
, // rr -> ir or rm
647 using namespace llvm::VE
;
648 #define INSTRKIND(NAME) \
650 NewUseOpcSImm7 = NAME##ri; \
651 NewUseOpcMImm = NAME##rm; \
652 InstType = rr2ri_rm; \
654 #define NCINSTRKIND(NAME) \
656 NewUseOpcSImm7 = NAME##ir; \
657 NewUseOpcMImm = NAME##rm; \
658 InstType = rr2ir_rm; \
661 switch (UseMI
.getOpcode()) {
670 NCINSTRKIND(SUBSWSX
);
671 NCINSTRKIND(SUBSWZX
);
678 NCINSTRKIND(DIVSWSX
);
679 NCINSTRKIND(DIVSWZX
);
682 NCINSTRKIND(CMPSWSX
);
683 NCINSTRKIND(CMPSWZX
);
703 bool Commute
= false;
704 LLVM_DEBUG(dbgs() << "checking UseMI operands\n");
708 if (UseMI
.getOperand(1).getReg() == Reg
) {
711 assert(UseMI
.getOperand(2).getReg() == Reg
);
713 if (isInt
<7>(ImmVal
)) {
714 // This ImmVal matches to SImm7 slot, so change UseOpc to an instruction
715 // holds a simm7 slot.
716 NewUseOpc
= NewUseOpcSImm7
;
717 } else if (isMImmVal(ImmVal
)) {
718 // Similarly, change UseOpc to an instruction holds a mimm slot.
719 NewUseOpc
= NewUseOpcMImm
;
720 ImmVal
= val2MImm(ImmVal
);
725 if (UseMI
.getOperand(1).getReg() == Reg
) {
726 // Check immediate value whether it matchs to the UseMI instruction.
727 if (!isInt
<7>(ImmVal
))
729 NewUseOpc
= NewUseOpcSImm7
;
732 assert(UseMI
.getOperand(2).getReg() == Reg
);
733 // Check immediate value whether it matchs to the UseMI instruction.
734 if (!isMImmVal(ImmVal
))
736 NewUseOpc
= NewUseOpcMImm
;
737 ImmVal
= val2MImm(ImmVal
);
743 LLVM_DEBUG(dbgs() << "modifying UseMI\n");
744 bool DeleteDef
= MRI
->hasOneNonDBGUse(Reg
);
745 UseMI
.setDesc(get(NewUseOpc
));
747 UseMI
.getOperand(1).setReg(UseMI
.getOperand(UseIdx
).getReg());
749 UseMI
.getOperand(UseIdx
).ChangeToImmediate(ImmVal
);
751 DefMI
.eraseFromParent();
756 Register
VEInstrInfo::getGlobalBaseReg(MachineFunction
*MF
) const {
757 VEMachineFunctionInfo
*VEFI
= MF
->getInfo
<VEMachineFunctionInfo
>();
758 Register GlobalBaseReg
= VEFI
->getGlobalBaseReg();
759 if (GlobalBaseReg
!= 0)
760 return GlobalBaseReg
;
762 // We use %s15 (%got) as a global base register
763 GlobalBaseReg
= VE::SX15
;
765 // Insert a pseudo instruction to set the GlobalBaseReg into the first
766 // MBB of the function
767 MachineBasicBlock
&FirstMBB
= MF
->front();
768 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
770 BuildMI(FirstMBB
, MBBI
, dl
, get(VE::GETGOT
), GlobalBaseReg
);
771 VEFI
->setGlobalBaseReg(GlobalBaseReg
);
772 return GlobalBaseReg
;
775 static Register
getVM512Upper(Register reg
) {
776 return (reg
- VE::VMP0
) * 2 + VE::VM0
;
779 static Register
getVM512Lower(Register reg
) { return getVM512Upper(reg
) + 1; }
781 // Expand pseudo logical vector instructions for VM512 registers.
782 static void expandPseudoLogM(MachineInstr
&MI
, const MCInstrDesc
&MCID
) {
783 MachineBasicBlock
*MBB
= MI
.getParent();
784 DebugLoc DL
= MI
.getDebugLoc();
786 Register VMXu
= getVM512Upper(MI
.getOperand(0).getReg());
787 Register VMXl
= getVM512Lower(MI
.getOperand(0).getReg());
788 Register VMYu
= getVM512Upper(MI
.getOperand(1).getReg());
789 Register VMYl
= getVM512Lower(MI
.getOperand(1).getReg());
791 switch (MI
.getOpcode()) {
793 Register VMZu
= getVM512Upper(MI
.getOperand(2).getReg());
794 Register VMZl
= getVM512Lower(MI
.getOperand(2).getReg());
795 BuildMI(*MBB
, MI
, DL
, MCID
).addDef(VMXu
).addUse(VMYu
).addUse(VMZu
);
796 BuildMI(*MBB
, MI
, DL
, MCID
).addDef(VMXl
).addUse(VMYl
).addUse(VMZl
);
800 BuildMI(*MBB
, MI
, DL
, MCID
).addDef(VMXu
).addUse(VMYu
);
801 BuildMI(*MBB
, MI
, DL
, MCID
).addDef(VMXl
).addUse(VMYl
);
804 MI
.eraseFromParent();
807 static void addOperandsForVFMK(MachineInstrBuilder
&MIB
, MachineInstr
&MI
,
810 MIB
.addReg(Upper
? getVM512Upper(MI
.getOperand(0).getReg())
811 : getVM512Lower(MI
.getOperand(0).getReg()));
813 switch (MI
.getNumExplicitOperands()) {
815 report_fatal_error("unexpected number of operands for pvfmk");
816 case 2: // _Ml: VM512, VL
818 MIB
.addReg(MI
.getOperand(1).getReg());
820 case 4: // _Mvl: VM512, CC, VR, VL
822 MIB
.addImm(MI
.getOperand(1).getImm());
824 MIB
.addReg(MI
.getOperand(2).getReg());
826 MIB
.addReg(MI
.getOperand(3).getReg());
828 case 5: // _MvMl: VM512, CC, VR, VM512, VL
830 MIB
.addImm(MI
.getOperand(1).getImm());
832 MIB
.addReg(MI
.getOperand(2).getReg());
834 MIB
.addReg(Upper
? getVM512Upper(MI
.getOperand(3).getReg())
835 : getVM512Lower(MI
.getOperand(3).getReg()));
837 MIB
.addReg(MI
.getOperand(4).getReg());
842 static void expandPseudoVFMK(const TargetInstrInfo
&TI
, MachineInstr
&MI
) {
843 // replace to pvfmk.w.up and pvfmk.w.lo
844 // replace to pvfmk.s.up and pvfmk.s.lo
846 static const std::pair
<unsigned, std::pair
<unsigned, unsigned>> VFMKMap
[] = {
847 {VE::VFMKyal
, {VE::VFMKLal
, VE::VFMKLal
}},
848 {VE::VFMKynal
, {VE::VFMKLnal
, VE::VFMKLnal
}},
849 {VE::VFMKWyvl
, {VE::PVFMKWUPvl
, VE::PVFMKWLOvl
}},
850 {VE::VFMKWyvyl
, {VE::PVFMKWUPvml
, VE::PVFMKWLOvml
}},
851 {VE::VFMKSyvl
, {VE::PVFMKSUPvl
, VE::PVFMKSLOvl
}},
852 {VE::VFMKSyvyl
, {VE::PVFMKSUPvml
, VE::PVFMKSLOvml
}},
855 unsigned Opcode
= MI
.getOpcode();
858 llvm::find_if(VFMKMap
, [&](auto P
) { return P
.first
== Opcode
; });
859 if (Found
== std::end(VFMKMap
))
860 report_fatal_error("unexpected opcode for pseudo vfmk");
862 unsigned OpcodeUpper
= (*Found
).second
.first
;
863 unsigned OpcodeLower
= (*Found
).second
.second
;
865 MachineBasicBlock
*MBB
= MI
.getParent();
866 DebugLoc DL
= MI
.getDebugLoc();
868 MachineInstrBuilder Bu
= BuildMI(*MBB
, MI
, DL
, TI
.get(OpcodeUpper
));
869 addOperandsForVFMK(Bu
, MI
, /* Upper */ true);
870 MachineInstrBuilder Bl
= BuildMI(*MBB
, MI
, DL
, TI
.get(OpcodeLower
));
871 addOperandsForVFMK(Bl
, MI
, /* Upper */ false);
873 MI
.eraseFromParent();
876 bool VEInstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
877 switch (MI
.getOpcode()) {
878 case VE::EXTEND_STACK
: {
879 return expandExtendStackPseudo(MI
);
881 case VE::EXTEND_STACK_GUARD
: {
882 MI
.eraseFromParent(); // The pseudo instruction is gone now.
885 case VE::GETSTACKTOP
: {
886 return expandGetStackTopPseudo(MI
);
890 expandPseudoLogM(MI
, get(VE::ANDMmm
));
893 expandPseudoLogM(MI
, get(VE::ORMmm
));
896 expandPseudoLogM(MI
, get(VE::XORMmm
));
899 expandPseudoLogM(MI
, get(VE::EQVMmm
));
902 expandPseudoLogM(MI
, get(VE::NNDMmm
));
905 expandPseudoLogM(MI
, get(VE::NEGMm
));
912 Register VMXu
= getVM512Upper(MI
.getOperand(0).getReg());
913 Register VMXl
= getVM512Lower(MI
.getOperand(0).getReg());
914 int64_t Imm
= MI
.getOperand(1).getImm();
916 MI
.getOpcode() == VE::LVMyir
|| MI
.getOpcode() == VE::LVMyir_y
;
917 Register Src
= IsSrcReg
? MI
.getOperand(2).getReg() : VE::NoRegister
;
918 int64_t MImm
= IsSrcReg
? 0 : MI
.getOperand(2).getImm();
919 bool KillSrc
= IsSrcReg
? MI
.getOperand(2).isKill() : false;
925 MachineBasicBlock
*MBB
= MI
.getParent();
926 DebugLoc DL
= MI
.getDebugLoc();
927 switch (MI
.getOpcode()) {
929 BuildMI(*MBB
, MI
, DL
, get(VE::LVMir
))
932 .addReg(Src
, getKillRegState(KillSrc
));
935 BuildMI(*MBB
, MI
, DL
, get(VE::LVMim
))
941 assert(MI
.getOperand(0).getReg() == MI
.getOperand(3).getReg() &&
942 "LVMyir_y has different register in 3rd operand");
943 BuildMI(*MBB
, MI
, DL
, get(VE::LVMir_m
))
946 .addReg(Src
, getKillRegState(KillSrc
))
950 assert(MI
.getOperand(0).getReg() == MI
.getOperand(3).getReg() &&
951 "LVMyim_y has different register in 3rd operand");
952 BuildMI(*MBB
, MI
, DL
, get(VE::LVMim_m
))
959 MI
.eraseFromParent();
963 Register Dest
= MI
.getOperand(0).getReg();
964 Register VMZu
= getVM512Upper(MI
.getOperand(1).getReg());
965 Register VMZl
= getVM512Lower(MI
.getOperand(1).getReg());
966 bool KillSrc
= MI
.getOperand(1).isKill();
967 int64_t Imm
= MI
.getOperand(2).getImm();
973 MachineBasicBlock
*MBB
= MI
.getParent();
974 DebugLoc DL
= MI
.getDebugLoc();
975 MachineInstrBuilder MIB
=
976 BuildMI(*MBB
, MI
, DL
, get(VE::SVMmi
), Dest
).addReg(VMZ
).addImm(Imm
);
977 MachineInstr
*Inst
= MIB
.getInstr();
979 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
980 Inst
->addRegisterKilled(MI
.getOperand(1).getReg(), TRI
, true);
982 MI
.eraseFromParent();
991 expandPseudoVFMK(*this, MI
);
997 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr
&MI
) const {
998 MachineBasicBlock
&MBB
= *MI
.getParent();
999 MachineFunction
&MF
= *MBB
.getParent();
1000 const VESubtarget
&STI
= MF
.getSubtarget
<VESubtarget
>();
1001 const VEInstrInfo
&TII
= *STI
.getInstrInfo();
1002 DebugLoc dl
= MBB
.findDebugLoc(MI
);
1004 // Create following instructions and multiple basic blocks.
1007 // brge.l.t %sp, %sl, sinkBB
1009 // ld %s61, 0x18(, %tp) // load param area
1010 // or %s62, 0, %s0 // spill the value of %s0
1011 // lea %s63, 0x13b // syscall # of grow
1012 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0
1013 // shm.l %sl, 0x8(%s61) // store old limit at addr:8
1014 // shm.l %sp, 0x10(%s61) // store new limit at addr:16
1015 // monc // call monitor
1016 // or %s0, 0, %s62 // restore the value of %s0
1020 MachineBasicBlock
*BB
= &MBB
;
1021 const BasicBlock
*LLVM_BB
= BB
->getBasicBlock();
1022 MachineBasicBlock
*syscallMBB
= MF
.CreateMachineBasicBlock(LLVM_BB
);
1023 MachineBasicBlock
*sinkMBB
= MF
.CreateMachineBasicBlock(LLVM_BB
);
1024 MachineFunction::iterator It
= ++(BB
->getIterator());
1025 MF
.insert(It
, syscallMBB
);
1026 MF
.insert(It
, sinkMBB
);
1028 // Transfer the remainder of BB and its successor edges to sinkMBB.
1029 sinkMBB
->splice(sinkMBB
->begin(), BB
,
1030 std::next(std::next(MachineBasicBlock::iterator(MI
))),
1032 sinkMBB
->transferSuccessorsAndUpdatePHIs(BB
);
1034 // Next, add the true and fallthrough blocks as its successors.
1035 BB
->addSuccessor(syscallMBB
);
1036 BB
->addSuccessor(sinkMBB
);
1037 BuildMI(BB
, dl
, TII
.get(VE::BRCFLrr_t
))
1038 .addImm(VECC::CC_IGE
)
1039 .addReg(VE::SX11
) // %sp
1040 .addReg(VE::SX8
) // %sl
1045 // Update machine-CFG edges
1046 BB
->addSuccessor(sinkMBB
);
1048 BuildMI(BB
, dl
, TII
.get(VE::LDrii
), VE::SX61
)
1052 BuildMI(BB
, dl
, TII
.get(VE::ORri
), VE::SX62
)
1055 BuildMI(BB
, dl
, TII
.get(VE::LEAzii
), VE::SX63
)
1059 BuildMI(BB
, dl
, TII
.get(VE::SHMLri
))
1063 BuildMI(BB
, dl
, TII
.get(VE::SHMLri
))
1067 BuildMI(BB
, dl
, TII
.get(VE::SHMLri
))
1071 BuildMI(BB
, dl
, TII
.get(VE::MONC
));
1073 BuildMI(BB
, dl
, TII
.get(VE::ORri
), VE::SX0
)
1077 MI
.eraseFromParent(); // The pseudo instruction is gone now.
1081 bool VEInstrInfo::expandGetStackTopPseudo(MachineInstr
&MI
) const {
1082 MachineBasicBlock
*MBB
= MI
.getParent();
1083 MachineFunction
&MF
= *MBB
->getParent();
1084 const VESubtarget
&STI
= MF
.getSubtarget
<VESubtarget
>();
1085 const VEInstrInfo
&TII
= *STI
.getInstrInfo();
1086 DebugLoc DL
= MBB
->findDebugLoc(MI
);
1088 // Create following instruction
1090 // dst = %sp + target specific frame + the size of parameter area
1092 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
1093 const VEFrameLowering
&TFL
= *STI
.getFrameLowering();
1095 // The VE ABI requires a reserved area at the top of stack as described
1096 // in VEFrameLowering.cpp. So, we adjust it here.
1097 unsigned NumBytes
= STI
.getAdjustedFrameSize(0);
1099 // Also adds the size of parameter area.
1100 if (MFI
.adjustsStack() && TFL
.hasReservedCallFrame(MF
))
1101 NumBytes
+= MFI
.getMaxCallFrameSize();
1103 BuildMI(*MBB
, MI
, DL
, TII
.get(VE::LEArii
))
1104 .addDef(MI
.getOperand(0).getReg())
1109 MI
.eraseFromParent(); // The pseudo instruction is gone now.