Added floating point lowering for setcc and brcond.

Fixed COMM asm directive usage.
ConstantPool using custom FourByteConstantSection.

llvm-svn: 54139
This commit is contained in:
Bruno Cardoso Lopes 2008-07-28 19:11:24 +00:00
parent ced7c7220e
commit bcaf6e5243
7 changed files with 158 additions and 30 deletions

View File

@ -518,17 +518,13 @@ printModuleLevelGV(const GlobalVariable* GVar) {
(GVar->hasInternalLinkage() || GVar->isWeakForLinker())) { (GVar->hasInternalLinkage() || GVar->isWeakForLinker())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (GVar->hasInternalLinkage()) { if (GVar->hasInternalLinkage())
if (TAI->getLCOMMDirective())
O << TAI->getLCOMMDirective() << name << ',' << Size;
else
O << "\t.local\t" << name << '\n'; O << "\t.local\t" << name << '\n';
} else {
O << TAI->getCOMMDirective() << name << ',' << Size; O << TAI->getCOMMDirective() << name << ',' << Size;
// The .comm alignment in bytes.
if (TAI->getCOMMDirectiveTakesAlignment()) if (TAI->getCOMMDirectiveTakesAlignment())
O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); O << ',' << (1 << Align);
}
O << '\n'; O << '\n';
return; return;
} }

View File

@ -89,6 +89,8 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f32, 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. // Operations not directly supported by Mips.
setOperationAction(ISD::BR_JT, MVT::Other, Expand); 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::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(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(); return SDValue();
} }
@ -265,9 +269,86 @@ bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
return IsInSmallSection(Size); 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 // 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<ConstantSDNode>(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<CondCodeSDNode>(Op.getOperand(2))->get();
return DAG.getNode(MipsISD::FPCmp, Op.getValueType(), LHS, RHS,
DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32));
}
SDValue MipsTargetLowering:: SDValue MipsTargetLowering::
LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) LowerGlobalAddress(SDValue Op, SelectionDAG &DAG)
{ {

View File

@ -96,6 +96,8 @@ namespace llvm {
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(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, virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB); MachineBasicBlock *MBB);

View File

@ -238,7 +238,7 @@ def MIPS_BRANCH_TL : PatLeaf<(i32 3)>;
/// Floating Point Branch of False/True (Likely) /// Floating Point Branch of False/True (Likely)
let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in { let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in {
class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (ops), class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
(ins brtarget:$dst), !strconcat(asmstr, " $dst"), (ins brtarget:$dst), !strconcat(asmstr, " $dst"),
[(MipsFPBrcond op, bb:$dst, FCR31)]>; [(MipsFPBrcond op, bb:$dst, FCR31)]>;
} }
@ -271,19 +271,16 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>;
/// Floating Point Compare /// Floating Point Compare
let hasDelaySlot = 1, Defs=[FCR31] in { let hasDelaySlot = 1, Defs=[FCR31] in {
//multiclass FCC1_1<RegisterClass RC>
def FCMP_SO32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc), 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]>; (implicit FCR31)]>, Requires<[IsSingleFloat]>;
def FCMP_AS32 : FCC<0x0, (outs), (ins AFGR32:$fs, AFGR32:$ft, condcode:$cc), 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]>; (implicit FCR31)]>, Requires<[In32BitMode]>;
def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc), 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]>; (implicit FCR31)]>, Requires<[In32BitMode]>;
} }

View File

@ -137,6 +137,12 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
else if ((DestRC == Mips::AFGR32RegisterClass) && else if ((DestRC == Mips::AFGR32RegisterClass) &&
(SrcRC == Mips::CPURegsRegisterClass)) (SrcRC == Mips::CPURegsRegisterClass))
BuildMI(MBB, I, get(Mips::MTC1A), DestReg).addReg(SrcReg); BuildMI(MBB, I, get(Mips::MTC1A), DestReg).addReg(SrcReg);
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 else
assert (0 && "DestRC != SrcRC, Can't copy this register"); assert (0 && "DestRC != SrcRC, Can't copy this register");
} }
@ -338,6 +344,10 @@ static Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc)
case Mips::BGEZ : return Mips::COND_GEZ; case Mips::BGEZ : return Mips::COND_GEZ;
case Mips::BLTZ : return Mips::COND_LZ; case Mips::BLTZ : return Mips::COND_LZ;
case Mips::BLEZ : return Mips::COND_LEZ; 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_GEZ : return Mips::BGEZ;
case Mips::COND_LZ : return Mips::BLTZ; case Mips::COND_LZ : return Mips::BLTZ;
case Mips::COND_LEZ : return Mips::BLEZ; 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;
} }
} }

View File

@ -22,6 +22,15 @@ namespace llvm {
namespace Mips { namespace Mips {
// Mips Branch Codes
enum FPBranchCode {
BRANCH_F,
BRANCH_T,
BRANCH_FL,
BRANCH_TL,
BRANCH_INVALID
};
// Mips Condition Codes // Mips Condition Codes
enum CondCode { enum CondCode {
// To be used with float branch True // To be used with float branch True

View File

@ -32,7 +32,6 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM):
ReadOnlySection = "\t.rdata"; ReadOnlySection = "\t.rdata";
ZeroDirective = "\t.space\t"; ZeroDirective = "\t.space\t";
BSSSection = "\t.section\t.bss"; BSSSection = "\t.section\t.bss";
LCOMMDirective = "\t.lcomm\t";
CStringSection = ".rodata.str"; CStringSection = ".rodata.str";
FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4";