From 85e31e3a5301c31947e35258dce7efa8e788bd51 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Mon, 28 Jul 2008 19:11:24 +0000 Subject: [PATCH] Added floating point lowering for setcc and brcond. Fixed COMM asm directive usage. ConstantPool using custom FourByteConstantSection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54139 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsAsmPrinter.cpp | 18 +++--- lib/Target/Mips/MipsISelLowering.cpp | 81 +++++++++++++++++++++++++++ lib/Target/Mips/MipsISelLowering.h | 2 + lib/Target/Mips/MipsInstrFPU.td | 15 ++--- lib/Target/Mips/MipsInstrInfo.cpp | 58 ++++++++++++++++--- lib/Target/Mips/MipsInstrInfo.h | 11 +++- lib/Target/Mips/MipsTargetAsmInfo.cpp | 3 +- 7 files changed, 158 insertions(+), 30 deletions(-) diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index d00680e54a1..9e334c15df8 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -518,17 +518,13 @@ printModuleLevelGV(const GlobalVariable* GVar) { (GVar->hasInternalLinkage() || GVar->isWeakForLinker())) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - if (GVar->hasInternalLinkage()) { - if (TAI->getLCOMMDirective()) - O << TAI->getLCOMMDirective() << name << ',' << Size; - else - O << "\t.local\t" << name << '\n'; - } else { - O << TAI->getCOMMDirective() << name << ',' << Size; - // The .comm alignment in bytes. - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } + if (GVar->hasInternalLinkage()) + O << "\t.local\t" << name << '\n'; + + O << TAI->getCOMMDirective() << name << ',' << Size; + if (TAI->getCOMMDirectiveTakesAlignment()) + O << ',' << (1 << Align); + O << '\n'; return; } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 0ba62b37286..f1e0e598faa 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -89,6 +89,8 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); + setOperationAction(ISD::SETCC, MVT::f32, Custom); + setOperationAction(ISD::BRCOND, MVT::Other, Custom); // Operations not directly supported by Mips. setOperationAction(ISD::BR_JT, MVT::Other, Expand); @@ -150,6 +152,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); + case ISD::SETCC: return LowerSETCC(Op, DAG); + case ISD::BRCOND: return LowerBRCOND(Op, DAG); } return SDValue(); } @@ -265,9 +269,86 @@ bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV) return IsInSmallSection(Size); } +// Get fp branch code (not opcode) from condition code. +static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) { + if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT) + return Mips::BRANCH_T; + + if (CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) + return Mips::BRANCH_F; + + return Mips::BRANCH_INVALID; +} + + +static Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) { + switch (CC) { + default: assert(0 && "Unknown fp condition code!"); + case ISD::SETEQ: + case ISD::SETOEQ: return Mips::FCOND_EQ; + case ISD::SETUNE: return Mips::FCOND_OGL; + case ISD::SETLT: + case ISD::SETOLT: return Mips::FCOND_OLT; + case ISD::SETGT: + case ISD::SETOGT: return Mips::FCOND_OGT; + case ISD::SETLE: + case ISD::SETOLE: return Mips::FCOND_OLE; + case ISD::SETGE: + case ISD::SETOGE: return Mips::FCOND_OGE; + case ISD::SETULT: return Mips::FCOND_ULT; + case ISD::SETULE: return Mips::FCOND_ULE; + case ISD::SETUGT: return Mips::FCOND_UGT; + case ISD::SETUGE: return Mips::FCOND_UGE; + case ISD::SETUO: return Mips::FCOND_UN; + case ISD::SETO: return Mips::FCOND_OR; + case ISD::SETNE: + case ISD::SETONE: return Mips::FCOND_NEQ; + case ISD::SETUEQ: return Mips::FCOND_UEQ; + } +} + //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// +SDValue MipsTargetLowering:: +LowerBRCOND(SDValue Op, SelectionDAG &DAG) +{ + // The first operand is the chain, the second is the condition, the third is + // the block to branch to if the condition is true. + SDValue Chain = Op.getOperand(0); + SDValue Dest = Op.getOperand(2); + SDValue CondRes; + + if (Op.getOperand(1).getOpcode() == ISD::AND) + CondRes = Op.getOperand(1).getOperand(0); + else if (Op.getOperand(1).getOpcode() == MipsISD::FPCmp) + CondRes = Op.getOperand(1); + else + assert(0 && "Incoming condition flag unknown"); + + SDValue CCNode = CondRes.getOperand(2); + Mips::CondCode CC = (Mips::CondCode)cast(CCNode)->getValue(); + SDValue BrCode = DAG.getConstant(GetFPBranchCodeFromCond(CC), MVT::i32); + + return DAG.getNode(MipsISD::FPBrcond, Op.getValueType(), Chain, BrCode, + Dest, CondRes); +} + +SDValue MipsTargetLowering:: +LowerSETCC(SDValue Op, SelectionDAG &DAG) +{ + // The operands to this are the left and right operands to compare (ops #0, + // and #1) and the condition code to compare them with (op #2) as a + // CondCodeSDNode. + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + + return DAG.getNode(MipsISD::FPCmp, Op.getValueType(), LHS, RHS, + DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32)); +} + SDValue MipsTargetLowering:: LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index ccc798180bf..136b230688d 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -96,6 +96,8 @@ namespace llvm { SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); + SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG); + SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG); virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB); diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index b0c486dad8f..550c8354117 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -238,12 +238,12 @@ def MIPS_BRANCH_TL : PatLeaf<(i32 3)>; /// Floating Point Branch of False/True (Likely) let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in { - class FBRANCH : FFI<0x11, (ops), + class FBRANCH : FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, " $dst"), [(MipsFPBrcond op, bb:$dst, FCR31)]>; } -def BC1F : FBRANCH; -def BC1T : FBRANCH; +def BC1F : FBRANCH; +def BC1T : FBRANCH; def BC1FL : FBRANCH; def BC1TL : FBRANCH; @@ -271,19 +271,16 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>; /// Floating Point Compare let hasDelaySlot = 1, Defs=[FCR31] in { - -//multiclass FCC1_1 - def FCMP_SO32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc), - "c.$cc.s $fs $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), + "c.$cc.s $fs, $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), (implicit FCR31)]>, Requires<[IsSingleFloat]>; def FCMP_AS32 : FCC<0x0, (outs), (ins AFGR32:$fs, AFGR32:$ft, condcode:$cc), - "c.$cc.s $fs $ft", [(MipsFPCmp AFGR32:$fs, AFGR32:$ft, imm:$cc), + "c.$cc.s $fs, $ft", [(MipsFPCmp AFGR32:$fs, AFGR32:$ft, imm:$cc), (implicit FCR31)]>, Requires<[In32BitMode]>; def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc), - "c.$cc.d $fs $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc), + "c.$cc.d $fs, $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc), (implicit FCR31)]>, Requires<[In32BitMode]>; } diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 3a0e114fdcc..ccd846efed6 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -137,7 +137,13 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, else if ((DestRC == Mips::AFGR32RegisterClass) && (SrcRC == Mips::CPURegsRegisterClass)) BuildMI(MBB, I, get(Mips::MTC1A), DestReg).addReg(SrcReg); - else + else if ((SrcRC == Mips::CCRRegisterClass) && + (SrcReg == Mips::FCR31)) + return; // This register is used implicitly, no copy needed. + else if ((DestRC == Mips::CCRRegisterClass) && + (DestReg == Mips::FCR31)) + return; // This register is used implicitly, no copy needed. + else assert (0 && "DestRC != SrcRC, Can't copy this register"); } @@ -332,12 +338,16 @@ static Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc) { switch (BrOpc) { default: return Mips::COND_INVALID; - case Mips::BEQ : return Mips::COND_E; - case Mips::BNE : return Mips::COND_NE; - case Mips::BGTZ : return Mips::COND_GZ; - case Mips::BGEZ : return Mips::COND_GEZ; - case Mips::BLTZ : return Mips::COND_LZ; - case Mips::BLEZ : return Mips::COND_LEZ; + case Mips::BEQ : return Mips::COND_E; + case Mips::BNE : return Mips::COND_NE; + case Mips::BGTZ : return Mips::COND_GZ; + case Mips::BGEZ : return Mips::COND_GEZ; + case Mips::BLTZ : return Mips::COND_LZ; + case Mips::BLEZ : return Mips::COND_LEZ; + + // We dont do fp branch analysis yet! + case Mips::BC1T : + case Mips::BC1F : return Mips::COND_INVALID; } } @@ -353,6 +363,40 @@ unsigned Mips::GetCondBranchFromCond(Mips::CondCode CC) case Mips::COND_GEZ : return Mips::BGEZ; case Mips::COND_LZ : return Mips::BLTZ; case Mips::COND_LEZ : return Mips::BLEZ; + + case Mips::FCOND_F: + case Mips::FCOND_UN: + case Mips::FCOND_EQ: + case Mips::FCOND_UEQ: + case Mips::FCOND_OLT: + case Mips::FCOND_ULT: + case Mips::FCOND_OLE: + case Mips::FCOND_ULE: + case Mips::FCOND_SF: + case Mips::FCOND_NGLE: + case Mips::FCOND_SEQ: + case Mips::FCOND_NGL: + case Mips::FCOND_LT: + case Mips::FCOND_NGE: + case Mips::FCOND_LE: + case Mips::FCOND_NGT: return Mips::BC1T; + + case Mips::FCOND_T: + case Mips::FCOND_OR: + case Mips::FCOND_NEQ: + case Mips::FCOND_OGL: + case Mips::FCOND_UGE: + case Mips::FCOND_OGE: + case Mips::FCOND_UGT: + case Mips::FCOND_OGT: + case Mips::FCOND_ST: + case Mips::FCOND_GLE: + case Mips::FCOND_SNE: + case Mips::FCOND_GL: + case Mips::FCOND_NLT: + case Mips::FCOND_GE: + case Mips::FCOND_NLE: + case Mips::FCOND_GT: return Mips::BC1F; } } diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index adefbc23a68..80a15ced2d5 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -22,6 +22,15 @@ namespace llvm { namespace Mips { + // Mips Branch Codes + enum FPBranchCode { + BRANCH_F, + BRANCH_T, + BRANCH_FL, + BRANCH_TL, + BRANCH_INVALID + }; + // Mips Condition Codes enum CondCode { // To be used with float branch True @@ -74,7 +83,7 @@ namespace Mips { // Turn condition code into conditional branch opcode. unsigned GetCondBranchFromCond(CondCode CC); - + /// GetOppositeBranchCondition - Return the inverse of the specified cond, /// e.g. turning COND_E to COND_NE. CondCode GetOppositeBranchCondition(Mips::CondCode CC); diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp index d1fadc0e735..f8a14c66da1 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.cpp +++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp @@ -32,9 +32,8 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): ReadOnlySection = "\t.rdata"; ZeroDirective = "\t.space\t"; BSSSection = "\t.section\t.bss"; - LCOMMDirective = "\t.lcomm\t"; CStringSection = ".rodata.str"; - FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; + FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; if (!Subtarget->hasABICall()) { JumpTableDirective = "\t.word\t";