summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/CSKY/CSKYInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/CSKY/CSKYInstrInfo.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp b/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp
index e12235cf9478..6fcb136cd99b 100644
--- a/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp
+++ b/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp
@@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===//
#include "CSKYInstrInfo.h"
+#include "CSKYMachineFunctionInfo.h"
+#include "CSKYTargetMachine.h"
#include "llvm/MC/MCContext.h"
#define DEBUG_TYPE "csky-instr-info"
@@ -23,3 +25,289 @@ using namespace llvm;
CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI)
: CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) {
}
+
+Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL, int64_t Val,
+ MachineInstr::MIFlag Flag) const {
+ assert(isUInt<32>(Val) && "should be uint32");
+
+ MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+
+ Register DstReg;
+ if (STI.hasE2()) {
+ DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
+
+ if (isUInt<16>(Val)) {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg)
+ .addImm(Val & 0xFFFF)
+ .setMIFlags(Flag);
+ } else if (isShiftedUInt<16, 16>(Val)) {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
+ .addImm((Val >> 16) & 0xFFFF)
+ .setMIFlags(Flag);
+ } else {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
+ .addImm((Val >> 16) & 0xFFFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg)
+ .addReg(DstReg)
+ .addImm(Val & 0xFFFF)
+ .setMIFlags(Flag);
+ }
+
+ } else {
+ DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
+ if (isUInt<8>(Val)) {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
+ .addImm(Val & 0xFF)
+ .setMIFlags(Flag);
+ } else if (isUInt<16>(Val)) {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
+ .addImm((Val >> 8) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if ((Val & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm(Val & 0xFF)
+ .setMIFlags(Flag);
+ } else if (isUInt<24>(Val)) {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
+ .addImm((Val >> 16) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if (((Val >> 8) & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm((Val >> 8) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if ((Val & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm(Val & 0xFF)
+ .setMIFlags(Flag);
+ } else {
+ BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
+ .addImm((Val >> 24) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if (((Val >> 16) & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm((Val >> 16) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if (((Val >> 8) & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm((Val >> 8) & 0xFF)
+ .setMIFlags(Flag);
+ BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
+ .addReg(DstReg)
+ .addImm(8)
+ .setMIFlags(Flag);
+ if ((Val & 0xFF) != 0)
+ BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
+ .addReg(DstReg)
+ .addImm(Val & 0xFF)
+ .setMIFlags(Flag);
+ }
+ }
+
+ return DstReg;
+}
+
+unsigned CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
+ int &FrameIndex) const {
+ switch (MI.getOpcode()) {
+ default:
+ return 0;
+ case CSKY::LD16B:
+ case CSKY::LD16H:
+ case CSKY::LD16W:
+ case CSKY::LD32B:
+ case CSKY::LD32BS:
+ case CSKY::LD32H:
+ case CSKY::LD32HS:
+ case CSKY::LD32W:
+ case CSKY::RESTORE_CARRY:
+ break;
+ }
+
+ if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
+ MI.getOperand(2).getImm() == 0) {
+ FrameIndex = MI.getOperand(1).getIndex();
+ return MI.getOperand(0).getReg();
+ }
+
+ return 0;
+}
+
+unsigned CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
+ int &FrameIndex) const {
+ switch (MI.getOpcode()) {
+ default:
+ return 0;
+ case CSKY::ST16B:
+ case CSKY::ST16H:
+ case CSKY::ST16W:
+ case CSKY::ST32B:
+ case CSKY::ST32H:
+ case CSKY::ST32W:
+ case CSKY::SPILL_CARRY:
+ break;
+ }
+
+ if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
+ MI.getOperand(2).getImm() == 0) {
+ FrameIndex = MI.getOperand(1).getIndex();
+ return MI.getOperand(0).getReg();
+ }
+
+ return 0;
+}
+
+void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ Register SrcReg, bool IsKill, int FI,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ DebugLoc DL;
+ if (I != MBB.end())
+ DL = I->getDebugLoc();
+
+ MachineFunction &MF = *MBB.getParent();
+ CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ unsigned Opcode = 0;
+
+ if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
+ Opcode = CSKY::ST32W; // Optimize for 16bit
+ } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
+ Opcode = CSKY::SPILL_CARRY;
+ CFI->setSpillsCR();
+ } else {
+ llvm_unreachable("Unknown RegisterClass");
+ }
+
+ MachineMemOperand *MMO = MF.getMachineMemOperand(
+ MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
+ MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
+
+ BuildMI(MBB, I, DL, get(Opcode))
+ .addReg(SrcReg, getKillRegState(IsKill))
+ .addFrameIndex(FI)
+ .addImm(0)
+ .addMemOperand(MMO);
+}
+
+void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ Register DestReg, int FI,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ DebugLoc DL;
+ if (I != MBB.end())
+ DL = I->getDebugLoc();
+
+ MachineFunction &MF = *MBB.getParent();
+ CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ unsigned Opcode = 0;
+
+ if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
+ Opcode = CSKY::LD32W;
+ } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
+ Opcode = CSKY::RESTORE_CARRY;
+ CFI->setSpillsCR();
+ } else {
+ llvm_unreachable("Unknown RegisterClass");
+ }
+
+ MachineMemOperand *MMO = MF.getMachineMemOperand(
+ MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
+ MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
+
+ BuildMI(MBB, I, DL, get(Opcode), DestReg)
+ .addFrameIndex(FI)
+ .addImm(0)
+ .addMemOperand(MMO);
+}
+
+void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ const DebugLoc &DL, MCRegister DestReg,
+ MCRegister SrcReg, bool KillSrc) const {
+
+ MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
+
+ if (CSKY::GPRRegClass.contains(SrcReg) &&
+ CSKY::CARRYRegClass.contains(DestReg)) {
+ if (STI.hasE2()) {
+ BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg)
+ .addReg(SrcReg, getKillRegState(KillSrc))
+ .addImm(0);
+ } else {
+ assert(SrcReg < CSKY::R8);
+ BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg)
+ .addReg(SrcReg, getKillRegState(KillSrc))
+ .addImm(0);
+ }
+ return;
+ }
+
+ if (CSKY::CARRYRegClass.contains(SrcReg) &&
+ CSKY::GPRRegClass.contains(DestReg)) {
+
+ if (STI.hasE2()) {
+ BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg)
+ .addReg(SrcReg, getKillRegState(KillSrc));
+ } else {
+ assert(DestReg < CSKY::R16);
+ assert(DestReg < CSKY::R8);
+ BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0);
+ BuildMI(MBB, I, DL, get(CSKY::ADDC16))
+ .addReg(DestReg, RegState::Define)
+ .addReg(SrcReg, RegState::Define)
+ .addReg(DestReg, getKillRegState(true))
+ .addReg(DestReg, getKillRegState(true))
+ .addReg(SrcReg, getKillRegState(true));
+ BuildMI(MBB, I, DL, get(CSKY::BTSTI16))
+ .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc))
+ .addReg(DestReg)
+ .addImm(0);
+ }
+ return;
+ }
+
+ unsigned Opcode = 0;
+ if (CSKY::GPRRegClass.contains(DestReg, SrcReg))
+ Opcode = CSKY::MOV32;
+ else {
+ LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);
+ LLVM_DEBUG(I->dump());
+ llvm_unreachable("Unknown RegisterClass");
+ }
+
+ BuildMI(MBB, I, DL, get(Opcode), DestReg)
+ .addReg(SrcReg, getKillRegState(KillSrc));
+}