From 089486acd95e193b8edc2f578a527bdce27f0762 Mon Sep 17 00:00:00 2001 From: chakenas Date: Thu, 16 Dec 2010 22:36:46 +0100 Subject: [PATCH] Fixed some bugs in register stack pass. Still exists some bugs. Included small start for branches. --- lib/Target/ZPU/AsmPrinter/ZPUAsmPrinter.cpp | 12 +- lib/Target/ZPU/ZPUISelLowering.cpp | 131 +++++- lib/Target/ZPU/ZPUISelLowering.h | 15 +- lib/Target/ZPU/ZPUInstrInfo.cpp | 12 +- lib/Target/ZPU/ZPUInstrInfo.td | 56 ++- lib/Target/ZPU/ZPURegisterInfo.td | 6 +- lib/Target/ZPU/ZPUStackSlot.cpp | 610 ++++++++++++++++------------ 7 files changed, 550 insertions(+), 292 deletions(-) mode change 100644 => 100755 lib/Target/ZPU/ZPUISelLowering.cpp mode change 100644 => 100755 lib/Target/ZPU/ZPUISelLowering.h mode change 100644 => 100755 lib/Target/ZPU/ZPUInstrInfo.cpp mode change 100644 => 100755 lib/Target/ZPU/ZPURegisterInfo.td rewrite lib/Target/ZPU/ZPUStackSlot.cpp (69%) diff --git a/lib/Target/ZPU/AsmPrinter/ZPUAsmPrinter.cpp b/lib/Target/ZPU/AsmPrinter/ZPUAsmPrinter.cpp index 4290861c53..4c869b0b2b 100755 --- a/lib/Target/ZPU/AsmPrinter/ZPUAsmPrinter.cpp +++ b/lib/Target/ZPU/AsmPrinter/ZPUAsmPrinter.cpp @@ -178,6 +178,11 @@ bool ZPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, void ZPUAsmPrinter::printOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { + if( opNum >= MI->getNumOperands()) + { + printf("WARNING! Buggy code for now, trying to print opcode %d, count is %d \n",opNum,MI->getNumOperands()); + return; + } const MachineOperand &MO = MI->getOperand (opNum); bool CloseParen = false; switch (MO.getType()) { @@ -212,8 +217,11 @@ void ZPUAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, void ZPUAsmPrinter:: printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier) { - - printOperand(MI, opNum+1, O); + + //if(opNum+1 < MI->getNumOperands()) + //{ + // printOperand(MI, opNum+1, O); + //} O << ", "; printOperand(MI, opNum, O); } diff --git a/lib/Target/ZPU/ZPUISelLowering.cpp b/lib/Target/ZPU/ZPUISelLowering.cpp old mode 100644 new mode 100755 index e5fbff9e34..e0215b60b1 --- a/lib/Target/ZPU/ZPUISelLowering.cpp +++ b/lib/Target/ZPU/ZPUISelLowering.cpp @@ -77,9 +77,13 @@ ZPUTargetLowering(ZPUTargetMachine &TM) // which is used implicitly by brcond and select operations. AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); + + //setOperationAction(ISD::SETCC, MVT::i32, Custom); + // Operations not directly supported by ZPU. - setOperationAction(ISD::BR_JT, MVT::Other, Expand); + //setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::BR_CC, MVT::Other, Expand); + //setOperationAction(ISD::BRCOND, MVT::Other, Expand); setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); @@ -122,14 +126,14 @@ unsigned ZPUTargetLowering::getFunctionAlignment(const Function *) const { return 2; } -SDValue ZPUTargetLowering:: -LowerOperation(SDValue Op, SelectionDAG &DAG) const +SDValue ZPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { - switch (Op.getOpcode()) { + switch (Op.getOpcode()) + { default: llvm_unreachable("Wasn't expecting to be able to lower this!"); - case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::SETCC: return LowerSETCC(Op, DAG); } - return SDValue(); } @@ -329,3 +333,118 @@ bool ZPUTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { return false; return Imm.isZero(); } +#include +static SDValue EmitConditionFunc(SDValue LHS,SDValue RHS,ISD::CondCode CC, + DebugLoc dl, SelectionDAG &DAG) +{ + bool unsign=false; + bool swap=false; + bool emit_equal = false; + printf("opcode is %d \n",CC); + switch(CC) + { + case ISD::SETFALSE: // Always false (always folded) + case ISD::SETOEQ: // True if ordered and equal + case ISD::SETOGT: // True if ordered and greater than + case ISD::SETOGE: // True if ordered and greater than or equal + case ISD::SETOLT: // True if ordered and less than + case ISD::SETOLE: // True if ordered and less than or equal + case ISD::SETONE: // True if ordered and operands are unequal + case ISD::SETO: // True if ordered (no nans) + case ISD::SETUO: // True if unordered: isnan(X) | isnan(Y) + case ISD::SETUEQ: // True if unordered or equal + case ISD::SETUGT: // True if unordered or greater than + case ISD::SETUGE: // True if unordered, greater than, or equal + case ISD::SETULT: // True if unordered or less than + case ISD::SETULE: // True if unordered, less than, or equal + case ISD::SETUNE: // True if unordered or not equal + case ISD::SETTRUE: // Always true (always folded) + case ISD::SETTRUE2: // Always true (always folded) + case ISD::SETFALSE2: // Always false (always folded) + llvm_unreachable("Unkown cmp instruction"); + break; + case ISD::SETEQ: // True if equal + return DAG.getNode(ZPUISD::EQ, dl,MVT::i32, LHS,RHS); + case ISD::SETNE: // True if not equal + return DAG.getNode(ZPUISD::NEQ, dl,MVT::i32, LHS,RHS); + case ISD::SETLT: // True if less than + swap=false; + emit_equal=false; + break; + case ISD::SETLE: // True if less than or equal + swap=false; + emit_equal=true; + break; + case ISD::SETCC_INVALID: + llvm_unreachable("Invalid CC"); + break; + case ISD::SETGE: // True if greater than or equal + swap=true; + emit_equal=true; + break; + case ISD::SETGT: // True if greater than + swap=true; + emit_equal=false; + break; + default: + llvm_unreachable("unimplemented operand"); + } + SDValue cmp_node; + unsigned opcode=0; + if(emit_equal) + { + if(unsign) + { + opcode = ZPUISD::ULESSTHANEQ; + } + else + { + opcode = ZPUISD::LESSTHANEQ; + } + } + else + { + if(unsign) + { + opcode = ZPUISD::ULESSTHAN; + } + else + { + opcode = ZPUISD::LESSTHAN; + } + } + + + if(swap) + { + return DAG.getNode(opcode, dl,MVT::i32, RHS,LHS); + } + else + { + return DAG.getNode(opcode, dl,MVT::i32, LHS,RHS); + } + /* + if(negate) + { + SDValue cmp_res = DAG.getCopyFromReg(DAG.getEntryNode(), dl, , MVT::i32); + + SDValue minus1 = DAG.getConstant(-1, MVT::i32); + + + return DAG.getNode(ISD::XOR,dl,MVT::i32,cmp_node,minus1); + } + else + { + return cmp_node; + }*/ +} + +SDValue ZPUTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + DebugLoc dl = Op.getDebugLoc(); + + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + + return EmitConditionFunc(LHS,RHS, CC,dl,DAG); +} diff --git a/lib/Target/ZPU/ZPUISelLowering.h b/lib/Target/ZPU/ZPUISelLowering.h old mode 100644 new mode 100755 index c4b19595c1..e22d7d724f --- a/lib/Target/ZPU/ZPUISelLowering.h +++ b/lib/Target/ZPU/ZPUISelLowering.h @@ -59,6 +59,18 @@ namespace llvm { Wrapper, // Address wrapper + LESSTHAN, + + LESSTHANEQ, + + ULESSTHAN, + + ULESSTHANEQ, + + EQ, + + NEQ, + // Return Ret }; @@ -105,9 +117,10 @@ namespace llvm { SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; #endif + SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; + virtual SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, diff --git a/lib/Target/ZPU/ZPUInstrInfo.cpp b/lib/Target/ZPU/ZPUInstrInfo.cpp old mode 100644 new mode 100755 index c0b91abc59..0f77f6c703 --- a/lib/Target/ZPU/ZPUInstrInfo.cpp +++ b/lib/Target/ZPU/ZPUInstrInfo.cpp @@ -34,8 +34,6 @@ ZPUInstrInfo::ZPUInstrInfo(ZPUTargetMachine &tm) unsigned ZPUInstrInfo:: isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { - - return 0; } @@ -55,20 +53,25 @@ isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const void ZPUInstrInfo:: insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { + llvm_unreachable("not implemented"); } void ZPUInstrInfo:: copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, - bool KillSrc) const { + bool KillSrc) const +{ + llvm_unreachable("not implemented"); } void ZPUInstrInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { + const TargetRegisterInfo *TRI) const + { + llvm_unreachable("not implemented"); } void ZPUInstrInfo:: @@ -77,5 +80,6 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { + llvm_unreachable("not implemented"); } diff --git a/lib/Target/ZPU/ZPUInstrInfo.td b/lib/Target/ZPU/ZPUInstrInfo.td index 09f011814a..42af6408a1 100755 --- a/lib/Target/ZPU/ZPUInstrInfo.td +++ b/lib/Target/ZPU/ZPUInstrInfo.td @@ -13,6 +13,10 @@ include "ZPUInstrFormats.td" +def brtarget : Operand { + let PrintMethod = "printOperand"; +} + // Address operands def memdst : Operand { let PrintMethod = "printOperand"; @@ -34,10 +38,11 @@ def mem : Operand { let MIOperandInfo = (ops i32imm, CPURegs); } - -def IM : ZPUIm <(outs CPURegs:$dst), (ins i32imm:$a), +let isReMaterializable = 1, isAsCheapAsAMove = 1 in { +def ZPUIM : ZPUIm <(outs CPURegs:$dst), (ins i32imm:$a), "im $a $dst", [(set CPURegs:$dst, imm:$a)]>; +} def ADD : ZPUIm <(outs CPURegs:$dst), (ins CPURegs:$a, CPURegs:$b), "add $dst $a $b", [(set CPURegs:$dst, (add CPURegs:$a, CPURegs:$b))]>; @@ -45,17 +50,18 @@ def ADD : ZPUIm <(outs CPURegs:$dst), (ins CPURegs:$a, CPURegs:$b), // First operands, in the DAG the addressing modes def ZPUSTORE : ZPUIm <(outs), (ins memdst:$dst, i32imm:$a), "store $a $dst", - [(store imm:$a, tglobaladdr:$dst)]>; + [(store imm:$a, tglobaladdr:$dst)]>; // First operands, in the DAG the addressing modes def ZPUSTOREREG : ZPUIm <(outs), (ins memdst:$dst, CPURegs:$a), "storereg $a $dst", [(store CPURegs:$a, tglobaladdr:$dst)]>; + -def ZPULOAD : ZPUIm <(outs CPURegs:$dst), (ins memdst:$src), - "im $src\n\tload $dst", - [(set CPURegs:$dst, (load tglobaladdr:$src))]>; +def ZPULOAD : ZPUIm <(outs CPURegs:$dst), (ins CPURegs:$src), + "load $src $dst", + [(set CPURegs:$dst, (load CPURegs:$src))]>; def ZPUSTORSTACKSLOT : ZPUIm <(outs), (ins mem:$dst, CPURegs:$a), "storestackslot $a $dst", @@ -74,4 +80,40 @@ def ZPUPSEUDOSTORESP : ZPUIm <(outs), (ins i32imm:$dst), def ZPUPSEUDOLOADSP : ZPUIm <(outs), (ins i32imm:$src), "loadsp $src ",[]>; - \ No newline at end of file + + +let isBranch=1, isTerminator=1, isBarrier = 1 in +{ +def ZPUBRANCH : ZPUIm<(outs),(ins brtarget:$dst),"br $dst",[(br bb:$dst)]>; + +def ZPUNEQBRANCH : ZPUIm<(outs), (ins CPURegs:$src, brtarget:$dst),"neqbranch $src $dst",[(brcond (setne CPURegs:$src, 0), bb:$dst)]>; +def ZPUEQBRANCH : ZPUIm<(outs), (ins CPURegs:$src, brtarget:$dst),"eqbranch $src $dst", [(brcond (seteq CPURegs:$src, 0), bb:$dst)]>; + +} + +def SETLT2 : ZPUIm <(outs CPURegs:$a), (ins CPURegs:$b, CPURegs:$c), + "setlt $a $b $c", + [(set CPURegs:$a, (setlt CPURegs:$b, CPURegs:$c))]>; + + +def SETGE2 : ZPUIm <(outs CPURegs:$a), (ins CPURegs:$b, CPURegs:$c), + "setge $a $b $c", + [(set CPURegs:$a, (setge CPURegs:$b, CPURegs:$c))]>; + +def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst), + (ZPUNEQBRANCH (SETLT2 CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; + +def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst), + (ZPUNEQBRANCH (SETGE2 CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; + +def SDT_ZPUCMP : SDTypeProfile<1, 2, []>; + +def ZPULESSTHAN : SDNode<"ZPUISD::LESSTHAN" , SDT_ZPUCMP, []>; +def ZPULESSTHANEQ : SDNode<"ZPUISD::LESSTHANEQ", SDT_ZPUCMP, []>; +def ZPUULESSTHAN : SDNode<"ZPUISD::ULESSTHAN" , SDT_ZPUCMP, []>; +def ZPUULESSTHANEQ : SDNode<"ZPUISD::ULESSTHANEQ", SDT_ZPUCMP, []>; +def ZPUEQ : SDNode<"ZPUISD::EQ", SDT_ZPUCMP, []>; +def ZPUNEQ : SDNode<"ZPUISD::NEQ", SDT_ZPUCMP, []>; + +def LESSTHAN : ZPUIm<(outs CPURegs:$dst), (ins CPURegs:$src1, CPURegs:$src2),"lessthan ;$dst=$src1<$src2", + [(set CPURegs:$dst, (ZPULESSTHAN CPURegs:$src1,CPURegs:$src2))]>; diff --git a/lib/Target/ZPU/ZPURegisterInfo.td b/lib/Target/ZPU/ZPURegisterInfo.td old mode 100644 new mode 100755 index 9b2ceb6ff7..56bfda7490 --- a/lib/Target/ZPU/ZPURegisterInfo.td +++ b/lib/Target/ZPU/ZPURegisterInfo.td @@ -34,6 +34,10 @@ let Namespace = "ZPU" in { def R1 : ZPUReg<"r1">, DwarfRegNum<[5]>; def R2 : ZPUReg<"r2">, DwarfRegNum<[6]>; def R3 : ZPUReg<"r3">, DwarfRegNum<[7]>; + def R4 : ZPUReg<"r4">, DwarfRegNum<[8]>; + def R5 : ZPUReg<"r5">, DwarfRegNum<[9]>; + def R6 : ZPUReg<"r6">, DwarfRegNum<[10]>; + } //===----------------------------------------------------------------------===// @@ -43,6 +47,6 @@ let Namespace = "ZPU" in { def CPURegs : RegisterClass<"ZPU", [i32], 32, // Program counter and stack pointer is all there is [PC, SP, - R0, R1, R2, R3, + R0, R1, R2, R3,R4,R5,R6, FP, RETVAL ]>; diff --git a/lib/Target/ZPU/ZPUStackSlot.cpp b/lib/Target/ZPU/ZPUStackSlot.cpp dissimilarity index 69% index 326bd4d15d..249b534ab7 100755 --- a/lib/Target/ZPU/ZPUStackSlot.cpp +++ b/lib/Target/ZPU/ZPUStackSlot.cpp @@ -1,271 +1,339 @@ -//===-- ZPUFloatingPoint.cpp - Floating point Reg -> Stack converter ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the pass which converts floating point instructions from -// pseudo registers into register stack instructions. This pass uses live -// variable information to indicate where the FPn registers are used and their -// lifetimes. -// -// The x87 hardware tracks liveness of the stack registers, so it is necessary -// to implement exact liveness tracking between basic blocks. The CFG edges are -// partitioned into bundles where the same FP registers must be live in -// identical stack positions. Instructions are inserted at the end of each basic -// block to rearrange the live registers to match the outgoing bundle. -// -// This approach avoids splitting critical edges at the potential cost of more -// live register shuffling instructions when critical edges are present. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "ZPU-codegen" -#include "ZPU.h" -#include "ZPUInstrInfo.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineOperand.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include - -using namespace llvm; - - -namespace { - struct ZPUStackSlot : public MachineFunctionPass { - static char ID; - ZPUStackSlot() : MachineFunctionPass(ID) { - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); - MachineFunctionPass::getAnalysisUsage(AU); - } - - virtual bool runOnMachineFunction(MachineFunction &MF); - virtual bool assignStackSlots(MachineFunction &Fn,int *RegToStack); - virtual void insertStackInstructions(MachineFunction &Fn); - - virtual const char *getPassName() const { return "ZPU Stackslotifier"; } - - }; - char ZPUStackSlot::ID = 0; -} - -FunctionPass *llvm::createZPUStackSlotPass() { return new ZPUStackSlot(); } - -// This function will replace registers with frameindex -bool ZPUStackSlot::assignStackSlots(MachineFunction &Fn,int *RegToStack) -{ - bool foundmore = false; - const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); - for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; - ++MFI) - { - MachineBasicBlock *MBB = MFI; - - - for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end(); - MBBI != EE; ++MBBI) { - /* - * MBBI points to a basic block machine instruction - */ - const MachineInstr &MI = *MBBI; - DebugLoc dl = MI.getDebugLoc(); - - //MBBI->dump(); - bool found = false; - for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI.getOperand(i); - - - if (MO.isReg() ) - { - unsigned Reg = MO.getReg(); - if (Reg >= ZPU::R0 && Reg <= ZPU::R3) - { - /* yes, we need to patch up this instruction! */ - found = true; - break; - } - - } - } - - if (found) - { - foundmore = true; - MachineInstr & MI = *MBBI; - - MachineInstrBuilder b = BuildMI(*MBB, MBBI, dl, TII->get(MI.getOpcode())); - - for (unsigned i = 0, e = MI.getNumOperands(); i!=e;i++) { - - const MachineOperand &MO = MI.getOperand(i); - - if (MO.isReg()) - { - unsigned Reg = MO.getReg(); - if (Reg >= ZPU::R0 && Reg <= ZPU::R3) - { - int FrameIdx; - - MachineFrameInfo *MFI = Fn.getFrameInfo(); - - // Determine if a new stack slot is required - if( RegToStack[Reg] == -1 ) - { - FrameIdx = MFI->CreateStackObject(4, 4, true); - - RegToStack[Reg] = FrameIdx; - } - else - { - FrameIdx = RegToStack[Reg]; - } - - b.addFrameIndex(FrameIdx); - } else - { - ((MachineInstr*) b)->addOperand(MI.getOperand(i)); - } - - } else - { - ((MachineInstr*) b)->addOperand(MI.getOperand(i)); - } - } - - MBBI++; - MI.eraseFromParent(); - //MBB->dump(); - } - } - } - - return foundmore; -} - -// This function will insert loadsp/storesp instructions. -// For each RHS argument an loadsp will be inserted. -// For each LHS argument an storesp will be inserted. -// -// [sp+0] = im ... -// [sp+1] = im ... -// [sp+0] = add [sp+0], [sp+1] -// -// im -// storesp 0 -// im -// storesp 1 -// loadsp 1 -// loadsp 1 -// add -// storesp 1 - -void ZPUStackSlot::insertStackInstructions(MachineFunction &Fn) -{ - const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); - for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; - ++MFI) - { - MachineBasicBlock *MBB = MFI; - - for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end(); - MBBI != EE; ++MBBI) { - /* - * MBBI points to a basic block machine instruction - */ - MachineInstr &MI = *MBBI; - DebugLoc dl = MI.getDebugLoc(); - - //MBBI->dump(); - //MBB->dump(); - - int loadSPIndex = 0; - - // Loop backwards and start to with loadsp - for (int i = MI.getNumOperands()-1; i >= 0; i--) - { - //MI.dump(); - const MachineOperand &MO = MI.getOperand(i); - - // Operand zero is LHS and should be a storesp - MachineInstr *tempInstr; - if (i == 0) - { - MachineInstr *tempInstr = - MBB->getParent()->CreateMachineInstr(TII->get( - ZPU::ZPUPSEUDOSTORESP), dl); - - MBB->insert(MBBI, tempInstr); - - if (MO.getType() == MachineOperand::MO_FrameIndex) - { - MachineInstrBuilder(tempInstr).addImm(MO.getIndex()+1); - } else - { - MachineInstrBuilder(tempInstr).addOperand(MO); - } - } else - { - MachineInstr *tempInstr = - MBB->getParent()->CreateMachineInstr(TII->get( - ZPU::ZPUPSEUDOLOADSP), dl); - - MBB->insert(MBBI, tempInstr); - - if (MO.getType() == MachineOperand::MO_FrameIndex) - { - MachineInstrBuilder(tempInstr).addImm(MO.getIndex() - + loadSPIndex); - } else - { - MachineInstrBuilder(tempInstr).addOperand(MO); - } - - // The second loadsp should have its SP increased by one since the first loadsp - // takes one stack slot. - loadSPIndex++; - } - } - MBBI++; - MI.eraseFromParent(); - } - } -} -/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP -/// register references into FP stack references. -/// -bool ZPUStackSlot::runOnMachineFunction(MachineFunction &Fn) -{ - bool ret; - // Reg to stack mapping, replace by proper map - int RegToStack[1024]; - - memset(&RegToStack[0],-1,sizeof(RegToStack[0])*1024); - - ret = assignStackSlots(Fn,RegToStack); - insertStackInstructions(Fn); - - return ret; -} +//===-- ZPUFloatingPoint.cpp - Floating point Reg -> Stack converter ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the pass which converts floating point instructions from +// pseudo registers into register stack instructions. This pass uses live +// variable information to indicate where the FPn registers are used and their +// lifetimes. +// +// The x87 hardware tracks liveness of the stack registers, so it is necessary +// to implement exact liveness tracking between basic blocks. The CFG edges are +// partitioned into bundles where the same FP registers must be live in +// identical stack positions. Instructions are inserted at the end of each basic +// block to rearrange the live registers to match the outgoing bundle. +// +// This approach avoids splitting critical edges at the potential cost of more +// live register shuffling instructions when critical edges are present. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "ZPU-codegen" +#include "ZPU.h" +#include "ZPUInstrInfo.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include +#include + +using namespace llvm; + + +namespace +{ + struct ZPUStackSlot:public MachineFunctionPass + { + static char ID; + ZPUStackSlot ():MachineFunctionPass (ID) + { + } + + virtual void getAnalysisUsage (AnalysisUsage & AU) const + { + AU.setPreservesCFG (); + AU.addPreservedID (MachineLoopInfoID); + AU.addPreservedID (MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage (AU); + } + + virtual bool runOnMachineFunction (MachineFunction & MF); + virtual bool assignStackSlots (MachineFunction & Fn, int *RegToStack); + virtual void insertStackInstructions (MachineFunction & Fn); + + virtual const char *getPassName () const + { + return "ZPU Stackslotifier"; + } + + }; + char ZPUStackSlot::ID = 0; +} + +FunctionPass * +llvm::createZPUStackSlotPass () +{ + return new ZPUStackSlot (); +} + +// This function will replace registers with frameindex +bool ZPUStackSlot::assignStackSlots (MachineFunction & Fn, int *RegToStack) +{ + bool + foundmore = false; + const TargetInstrInfo * + TII = Fn.getTarget ().getInstrInfo (); + for (MachineFunction::iterator MFI = Fn.begin (), E = Fn.end (); MFI != E; + ++MFI) + { + MachineBasicBlock * + MBB = MFI; + + + for (MachineBasicBlock::iterator MBBI = MBB->begin (), EE = MBB->end (); + MBBI != EE; ++MBBI) + { + const MachineInstr &MI = *MBBI; + DebugLoc dl = MI.getDebugLoc (); + + //MBBI->dump(); + bool found = false; + printf("Testing \n"); + MI.dump(); + for (unsigned i = 0, e = MI.getNumOperands (); i != e; ++i) + { + const MachineOperand &MO = MI.getOperand (i); + + if (MO.isReg ()) + { + unsigned Reg = MO.getReg (); + if (Reg >= ZPU::R0 && Reg <= ZPU::R3) + { + /* yes, we need to patch up this instruction! */ + found = true; + break; + } + } + } + + if (found) + { + foundmore = true; + MachineInstr & MI = *MBBI; + + MachineInstrBuilder b = BuildMI (*MBB, MBBI, dl, TII->get (MI.getOpcode ())); + printf("Selected \n"); + MI.dump(); + for (unsigned i = 0, e = MI.getNumOperands (); i != e; i++) + { + const MachineOperand &MO = MI.getOperand (i); + + if (MO.isReg ()) + { + unsigned Reg = MO.getReg (); + if (Reg >= ZPU::R0 && Reg <= ZPU::R3) + { + int FrameIdx; + MachineFrameInfo *MFI = Fn.getFrameInfo (); + + // Determine if a new stack slot is required + if (RegToStack[Reg] == -1) + { + FrameIdx = MFI->CreateStackObject (4, 4, true); + + RegToStack[Reg] = FrameIdx; + } + else + { + FrameIdx = RegToStack[Reg]; + } + + b.addFrameIndex (FrameIdx); + } + else + { + ((MachineInstr *) b)-> + addOperand (MI.getOperand (i)); + } + } + else + { + ((MachineInstr *) b)->addOperand (MI.getOperand (i)); + } + } + + printf("Created \n"); + ((MachineInstr *) b)->dump(); + printf("remove \n"); + MI.dump(); + + MI.eraseFromParent (); + + // Crappy way out getting the iterator right, slow for big bb. + MBBI = MBB->begin (); + } + } + } + printf("\n"); + return foundmore; +} + +// This function will insert loadsp/storesp instructions. +// For each RHS argument an loadsp will be inserted. +// For each LHS argument an storesp will be inserted. +// +// [sp+0] = im ... +// [sp+1] = im ... +// [sp+0] = add [sp+0], [sp+1] +// +// im +// storesp 0 +// im +// storesp 1 +// loadsp 1 +// loadsp 1 +// add +// storesp 1 +// +// STACKSTORE/STACKLOAD instructions should be removed since +// +// ZPUSTORSTACKSLOT fi#2,0,R0 +// is +// loadsp [R0] +// storesp fi#2 +void +ZPUStackSlot::insertStackInstructions (MachineFunction & Fn) +{ + const TargetInstrInfo *TII = Fn.getTarget ().getInstrInfo (); + for (MachineFunction::iterator MFI = Fn.begin (), E = Fn.end (); MFI != E; + ++MFI) + { + MachineBasicBlock *MBB = MFI; + + for (MachineBasicBlock::iterator MBBI = MBB->begin (), EE = MBB->end (); + MBBI != EE; ++MBBI) + { + /* + * MBBI points to a basic block machine instruction + */ + MachineInstr & MI = *MBBI; + DebugLoc dl = MI.getDebugLoc (); + + //MBBI->dump(); + //MBB->dump(); + + int loadSPIndex = 0; + MI.dump(); + + // Loop backwards and start to with loadsp + for (int i = MI.getNumOperands () - 1; i >= 0; i--) + { + const MachineOperand & MO = MI.getOperand (i); + + // Operand zero is LHS and should be a storesp + MachineInstr *tempInstr; + if (i == 0) + { + MachineInstr *tempInstr = NULL; + + if (MO.getType () == MachineOperand::MO_FrameIndex) + { + tempInstr = MBB->getParent ()-> CreateMachineInstr (TII->get (ZPU::ZPUPSEUDOSTORESP),dl); + + MachineInstrBuilder (tempInstr).addImm (MO.getIndex () + 1); + } + else if(MO.getType() == MachineOperand::MO_GlobalAddress) + { + tempInstr = MBB->getParent ()->CreateMachineInstr (TII->get (ZPU::ZPUIM),dl); + + MachineInstrBuilder (tempInstr).addOperand (MO); + } + if( MI.getOpcode() == ZPU::ZPUSTOREREG) + { + // Store operations needs to have its destination pushed on stack + // Put before instruction + MBB->insert(MBBI, tempInstr); + } + else + { + assert(tempInstr->getOpcode() == ZPU::ZPUPSEUDOSTORESP && "The result of the instruction should be stored to stack. With a storesp"); + // Add the storesp after the instruction + MBB->insertAfter (MBBI, tempInstr); + MBBI++; + } + + if(MI.getOpcode() == ZPU::ZPUSTORSTACKSLOT || + MI.getOpcode() == ZPU::ZPULOADSTACKSLOT) + { + // Remove instruction if stackstore since this is same as storesp + MI.removeFromParent(); + } + } + else + { + MachineInstr *tempInstr = NULL; + + printf("Operand type is %d, %d \n",MO.getType(),i); + if (MO.getType () == MachineOperand::MO_FrameIndex) + { + tempInstr = MBB->getParent ()->CreateMachineInstr (TII->get (ZPU::ZPUPSEUDOLOADSP),dl); + MachineInstrBuilder (tempInstr).addImm (MO.getIndex () + loadSPIndex); + } + else if(MO.getType() == MachineOperand::MO_GlobalAddress) + { + tempInstr = MBB->getParent ()->CreateMachineInstr (TII->get (ZPU::ZPUIM),dl); + + MachineInstrBuilder (tempInstr).addOperand (MO); + } + else + { + if(MI.getOpcode() == ZPU::ZPUSTORSTACKSLOT || + MI.getOpcode() == ZPU::ZPULOADSTACKSLOT) + { + // xxxxSTACKSLOT have a constant, do something with this? + } + else + { + assert(0 && "Don't kow what to do with this"); + } + } + if(tempInstr!=NULL) + { + MBB->insert (MBBI, tempInstr); + } + // The second loadsp should have its SP increased by one since the first loadsp + // takes one stack slot. + loadSPIndex++; + } + } + } + } +} + +/// runOnMachineFunction - Loop over all of the basic blocks, transforming FP +/// register references into FP stack references. +/// +bool ZPUStackSlot::runOnMachineFunction (MachineFunction & Fn) +{ + bool + ret; + // Reg to stack mapping, replace by proper map + int + RegToStack[1024]; + + memset (&RegToStack[0], -1, sizeof (RegToStack[0]) * 1024); + + ret = assignStackSlots (Fn, RegToStack); + insertStackInstructions (Fn); + + return ret; +} -- 2.11.4.GIT