From 6788faa06ad77fbfb57db7bcf8bc6a79389775a6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 31 Jan 2006 06:49:09 +0000 Subject: [PATCH] compactify all of the integer conditional moves into one instruction that takes a CC as an operand. Much smaller, much happier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25839 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/Sparc.h | 112 ++++++++++++++++++++- lib/Target/Sparc/SparcAsmPrinter.cpp | 8 ++ lib/Target/Sparc/SparcISelDAGToDAG.cpp | 77 -------------- lib/Target/Sparc/SparcInstrInfo.td | 111 +++++--------------- lib/Target/SparcV8/SparcV8.h | 112 ++++++++++++++++++++- lib/Target/SparcV8/SparcV8AsmPrinter.cpp | 8 ++ lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp | 77 -------------- lib/Target/SparcV8/SparcV8InstrInfo.td | 111 +++++--------------- 8 files changed, 286 insertions(+), 330 deletions(-) diff --git a/lib/Target/Sparc/Sparc.h b/lib/Target/Sparc/Sparc.h index 70f563bfa28..15b80504704 100644 --- a/lib/Target/Sparc/Sparc.h +++ b/lib/Target/Sparc/Sparc.h @@ -16,6 +16,7 @@ #define TARGET_SPARCV8_H #include +#include namespace llvm { @@ -28,7 +29,6 @@ namespace llvm { TargetMachine &TM); FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM); - } // end namespace llvm; // Defines symbolic names for SparcV8 registers. This defines a mapping from @@ -40,4 +40,114 @@ namespace llvm { // #include "SparcV8GenInstrNames.inc" + +namespace llvm { + // Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These + // values must be kept in sync with the ones in the .td file. + namespace V8CC { + enum CondCodes { + //ICC_A = 8 , // Always + //ICC_N = 0 , // Never + ICC_NE = 9 , // Not Equal + ICC_E = 1 , // Equal + ICC_G = 10 , // Greater + ICC_LE = 2 , // Less or Equal + ICC_GE = 11 , // Greater or Equal + ICC_L = 3 , // Less + ICC_GU = 12 , // Greater Unsigned + ICC_LEU = 4 , // Less or Equal Unsigned + ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned + ICC_CS = 5 , // Carry Set/Less Unsigned + ICC_POS = 14 , // Positive + ICC_NEG = 6 , // Negative + ICC_VC = 15 , // Overflow Clear + ICC_VS = 7 , // Overflow Set + + //FCC_A = 8+16, // Always + //FCC_N = 0+16, // Never + FCC_U = 7+16, // Unordered + FCC_G = 6+16, // Greater + FCC_UG = 5+16, // Unordered or Greater + FCC_L = 4+16, // Less + FCC_UL = 3+16, // Unordered or Less + FCC_LG = 2+16, // Less or Greater + FCC_NE = 1+16, // Not Equal + FCC_E = 9+16, // Equal + FCC_UE = 10+16, // Unordered or Equal + FCC_GE = 11+16, // Greater or Equal + FCC_UGE = 12+16, // Unordered or Greater or Equal + FCC_LE = 13+16, // Less or Equal + FCC_ULE = 14+16, // Unordered or Less or Equal + FCC_O = 15+16, // Ordered + }; + } + + static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return V8::BNE; + case V8CC::ICC_E: return V8::BE; + case V8CC::ICC_G: return V8::BG; + case V8CC::ICC_LE: return V8::BLE; + case V8CC::ICC_GE: return V8::BGE; + case V8CC::ICC_L: return V8::BL; + case V8CC::ICC_GU: return V8::BGU; + case V8CC::ICC_LEU: return V8::BLEU; + case V8CC::ICC_CC: return V8::BCC; + case V8CC::ICC_CS: return V8::BCS; + case V8CC::ICC_POS: return V8::BPOS; + case V8CC::ICC_NEG: return V8::BNEG; + case V8CC::ICC_VC: return V8::BVC; + case V8CC::ICC_VS: return V8::BVS; + case V8CC::FCC_U: return V8::FBU; + case V8CC::FCC_G: return V8::FBG; + case V8CC::FCC_UG: return V8::FBUG; + case V8CC::FCC_L: return V8::FBL; + case V8CC::FCC_UL: return V8::FBUL; + case V8CC::FCC_LG: return V8::FBLG; + case V8CC::FCC_NE: return V8::FBNE; + case V8CC::FCC_E: return V8::FBE; + case V8CC::FCC_UE: return V8::FBUE; + case V8CC::FCC_GE: return V8::FBGE; + case V8CC::FCC_UGE: return V8::FBUGE; + case V8CC::FCC_LE: return V8::FBLE; + case V8CC::FCC_ULE: return V8::FBULE; + case V8CC::FCC_O: return V8::FBO; + } + } + + static const char *SPARCCondCodeToString(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return "ne"; + case V8CC::ICC_E: return "e"; + case V8CC::ICC_G: return "g"; + case V8CC::ICC_LE: return "le"; + case V8CC::ICC_GE: return "ge"; + case V8CC::ICC_L: return "l"; + case V8CC::ICC_GU: return "gu"; + case V8CC::ICC_LEU: return "leu"; + case V8CC::ICC_CC: return "cc"; + case V8CC::ICC_CS: return "cs"; + case V8CC::ICC_POS: return "pos"; + case V8CC::ICC_NEG: return "neg"; + case V8CC::ICC_VC: return "vc"; + case V8CC::ICC_VS: return "vs"; + case V8CC::FCC_U: return "u"; + case V8CC::FCC_G: return "g"; + case V8CC::FCC_UG: return "ug"; + case V8CC::FCC_L: return "l"; + case V8CC::FCC_UL: return "ul"; + case V8CC::FCC_LG: return "lg"; + case V8CC::FCC_NE: return "ne"; + case V8CC::FCC_E: return "e"; + case V8CC::FCC_UE: return "ue"; + case V8CC::FCC_GE: return "ge"; + case V8CC::FCC_UGE: return "uge"; + case V8CC::FCC_LE: return "le"; + case V8CC::FCC_ULE: return "ule"; + case V8CC::FCC_O: return "o"; + } + } +} // end namespace llvm #endif diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp index f22185b51a6..dd1b46904d8 100644 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -58,6 +58,8 @@ namespace { void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum); + void printV8CCOperand(const MachineInstr *MI, int opNum); + bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -211,6 +213,12 @@ void SparcV8AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) { } } +void SparcV8AsmPrinter::printV8CCOperand(const MachineInstr *MI, int opNum) { + int CC = (int)MI->getOperand(opNum).getImmedValue(); + O << SPARCCondCodeToString((V8CC::CondCodes)CC); +} + + bool SparcV8AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 982215ac7e7..ff4e861e183 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -50,47 +50,6 @@ namespace V8ISD { }; } -// Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These -// values must be kept in sync with the ones in the .td file. -namespace V8CC { - enum CondCodes { - //ICC_A = 8 , // Always - //ICC_N = 0 , // Never - ICC_NE = 9 , // Not Equal - ICC_E = 1 , // Equal - ICC_G = 10 , // Greater - ICC_LE = 2 , // Less or Equal - ICC_GE = 11 , // Greater or Equal - ICC_L = 3 , // Less - ICC_GU = 12 , // Greater Unsigned - ICC_LEU = 4 , // Less or Equal Unsigned - ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned - ICC_CS = 5 , // Carry Set/Less Unsigned - ICC_POS = 14 , // Positive - ICC_NEG = 6 , // Negative - ICC_VC = 15 , // Overflow Clear - ICC_VS = 7 , // Overflow Set - - //FCC_A = 8+16, // Always - //FCC_N = 0+16, // Never - FCC_U = 7+16, // Unordered - FCC_G = 6+16, // Greater - FCC_UG = 5+16, // Unordered or Greater - FCC_L = 4+16, // Less - FCC_UL = 3+16, // Unordered or Less - FCC_LG = 2+16, // Less or Greater - FCC_NE = 1+16, // Not Equal - FCC_E = 9+16, // Equal - FCC_UE = 10+16, // Unordered or Equal - FCC_GE = 11+16, // Greater or Equal - FCC_UGE = 12+16, // Unordered or Greater or Equal - FCC_LE = 13+16, // Less or Equal - FCC_ULE = 14+16, // Unordered or Less or Equal - FCC_O = 15+16, // Ordered - }; -} - - /// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC /// condition. static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { @@ -130,42 +89,6 @@ static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { case ISD::SETUEQ: return V8CC::FCC_UE; } } - - -static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { - switch (CC) { - default: assert(0 && "Unknown condition code"); - case V8CC::ICC_NE: return V8::BNE; - case V8CC::ICC_E: return V8::BE; - case V8CC::ICC_G: return V8::BG; - case V8CC::ICC_LE: return V8::BLE; - case V8CC::ICC_GE: return V8::BGE; - case V8CC::ICC_L: return V8::BL; - case V8CC::ICC_GU: return V8::BGU; - case V8CC::ICC_LEU: return V8::BLEU; - case V8CC::ICC_CC: return V8::BCC; - case V8CC::ICC_CS: return V8::BCS; - case V8CC::ICC_POS: return V8::BPOS; - case V8CC::ICC_NEG: return V8::BNEG; - case V8CC::ICC_VC: return V8::BVC; - case V8CC::ICC_VS: return V8::BVS; - case V8CC::FCC_U: return V8::FBU; - case V8CC::FCC_G: return V8::FBG; - case V8CC::FCC_UG: return V8::FBUG; - case V8CC::FCC_L: return V8::FBL; - case V8CC::FCC_UL: return V8::FBUL; - case V8CC::FCC_LG: return V8::FBLG; - case V8CC::FCC_NE: return V8::FBNE; - case V8CC::FCC_E: return V8::FBE; - case V8CC::FCC_UE: return V8::FBUE; - case V8CC::FCC_GE: return V8::FBGE; - case V8CC::FCC_UGE: return V8::FBUGE; - case V8CC::FCC_LE: return V8::FBLE; - case V8CC::FCC_ULE: return V8::FBULE; - case V8CC::FCC_O: return V8::FBO; - } -} - namespace { class SparcV8TargetLowering : public TargetLowering { diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 8a39d8175a9..72f6e3335e7 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -86,6 +86,10 @@ def MEMri : Operand { def brtarget : Operand; def calltarget : Operand; +// Operand for printing out a condition code. +let PrintMethod = "printV8CCOperand" in + def V8CC : Operand; + def SDTV8cmpfcc : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>; def SDTV8brcc : @@ -212,12 +216,14 @@ let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F, - imm:$Cond, ICC))]>; + imm:$Cond, ICC))]>, + Requires<[HasNoV9]>; def SELECT_CC_Int_FCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_FCC PSEUDO!", [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F, - imm:$Cond, FCC))]>; + imm:$Cond, FCC))]>, + Requires<[HasNoV9]>; def SELECT_CC_FP_ICC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", @@ -802,96 +808,27 @@ def FCMPD : F3_3<2, 0b110101, 0b001010010, let Predicates = [HasV9], isTwoAddress = 1 in { // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. // FIXME: Add instruction encodings for the JIT some day. - class IntCMOVICCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + def MOVICCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - class IntCMOVICCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>; + def MOVICCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc simm11:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - - // MOV*rr instructions. - def MOVNErr : IntCMOVICCrr< "movne %icc, $F, $dst", ICC_NE>; - def MOVErr : IntCMOVICCrr< "move %icc, $F, $dst", ICC_E>; - def MOVGrr : IntCMOVICCrr< "movg %icc, $F, $dst", ICC_G>; - def MOVLErr : IntCMOVICCrr< "movle %icc, $F, $dst", ICC_LE>; - def MOVGErr : IntCMOVICCrr< "movge %icc, $F, $dst", ICC_GE>; - def MOVLrr : IntCMOVICCrr< "movl %icc, $F, $dst", ICC_L>; - def MOVGUrr : IntCMOVICCrr< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUrr : IntCMOVICCrr<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCrr : IntCMOVICCrr< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSrr : IntCMOVICCrr< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSrr : IntCMOVICCrr<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGrr : IntCMOVICCrr<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCrr : IntCMOVICCrr< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSrr : IntCMOVICCrr< "movvs %icc, $F, $dst", ICC_VS>; - - // MOV*ri instructions. - def MOVNEri : IntCMOVICCri< "movne %icc, $F, $dst", ICC_NE>; - def MOVEri : IntCMOVICCri< "move %icc, $F, $dst", ICC_E>; - def MOVGri : IntCMOVICCri< "movg %icc, $F, $dst", ICC_G>; - def MOVLEri : IntCMOVICCri< "movle %icc, $F, $dst", ICC_LE>; - def MOVGEri : IntCMOVICCri< "movge %icc, $F, $dst", ICC_GE>; - def MOVLri : IntCMOVICCri< "movl %icc, $F, $dst", ICC_L>; - def MOVGUri : IntCMOVICCri< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUri : IntCMOVICCri<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCri : IntCMOVICCri< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSri : IntCMOVICCri< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSri : IntCMOVICCri<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGri : IntCMOVICCri<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCri : IntCMOVICCri< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSri : IntCMOVICCri< "movvs %icc, $F, $dst", ICC_VS>; + (V8selecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>; - // FIXME: Allow regalloc of the fcc condition code some day. - class IntCMOVFCCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + def MOVFCCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - class IntCMOVFCCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; + def MOVFCCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc simm11:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - - // MOVF*rr instructions. - def MOVFUrr : IntCMOVFCCrr< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGrr : IntCMOVFCCrr< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGrr : IntCMOVFCCrr< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLrr : IntCMOVFCCrr< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULrr : IntCMOVFCCrr< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGrr : IntCMOVFCCrr< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNErr : IntCMOVFCCrr< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFErr : IntCMOVFCCrr< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUErr : IntCMOVFCCrr< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGErr : IntCMOVFCCrr< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGErr : IntCMOVFCCrr<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLErr : IntCMOVFCCrr< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULErr : IntCMOVFCCrr<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOrr : IntCMOVFCCrr< "movfo %fcc, $F, $dst", FCC_O>; - - // MOVF*ri instructions. - def MOVFUri : IntCMOVFCCri< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGri : IntCMOVFCCri< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGri : IntCMOVFCCri< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLri : IntCMOVFCCri< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULri : IntCMOVFCCri< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGri : IntCMOVFCCri< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNEri : IntCMOVFCCri< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFEri : IntCMOVFCCri< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUEri : IntCMOVFCCri< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGEri : IntCMOVFCCri< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGEri : IntCMOVFCCri<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLEri : IntCMOVFCCri< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULEri : IntCMOVFCCri<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOri : IntCMOVFCCri< "movfo %fcc, $F, $dst", FCC_O>; + (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. diff --git a/lib/Target/SparcV8/SparcV8.h b/lib/Target/SparcV8/SparcV8.h index 70f563bfa28..15b80504704 100644 --- a/lib/Target/SparcV8/SparcV8.h +++ b/lib/Target/SparcV8/SparcV8.h @@ -16,6 +16,7 @@ #define TARGET_SPARCV8_H #include +#include namespace llvm { @@ -28,7 +29,6 @@ namespace llvm { TargetMachine &TM); FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM); - } // end namespace llvm; // Defines symbolic names for SparcV8 registers. This defines a mapping from @@ -40,4 +40,114 @@ namespace llvm { // #include "SparcV8GenInstrNames.inc" + +namespace llvm { + // Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These + // values must be kept in sync with the ones in the .td file. + namespace V8CC { + enum CondCodes { + //ICC_A = 8 , // Always + //ICC_N = 0 , // Never + ICC_NE = 9 , // Not Equal + ICC_E = 1 , // Equal + ICC_G = 10 , // Greater + ICC_LE = 2 , // Less or Equal + ICC_GE = 11 , // Greater or Equal + ICC_L = 3 , // Less + ICC_GU = 12 , // Greater Unsigned + ICC_LEU = 4 , // Less or Equal Unsigned + ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned + ICC_CS = 5 , // Carry Set/Less Unsigned + ICC_POS = 14 , // Positive + ICC_NEG = 6 , // Negative + ICC_VC = 15 , // Overflow Clear + ICC_VS = 7 , // Overflow Set + + //FCC_A = 8+16, // Always + //FCC_N = 0+16, // Never + FCC_U = 7+16, // Unordered + FCC_G = 6+16, // Greater + FCC_UG = 5+16, // Unordered or Greater + FCC_L = 4+16, // Less + FCC_UL = 3+16, // Unordered or Less + FCC_LG = 2+16, // Less or Greater + FCC_NE = 1+16, // Not Equal + FCC_E = 9+16, // Equal + FCC_UE = 10+16, // Unordered or Equal + FCC_GE = 11+16, // Greater or Equal + FCC_UGE = 12+16, // Unordered or Greater or Equal + FCC_LE = 13+16, // Less or Equal + FCC_ULE = 14+16, // Unordered or Less or Equal + FCC_O = 15+16, // Ordered + }; + } + + static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return V8::BNE; + case V8CC::ICC_E: return V8::BE; + case V8CC::ICC_G: return V8::BG; + case V8CC::ICC_LE: return V8::BLE; + case V8CC::ICC_GE: return V8::BGE; + case V8CC::ICC_L: return V8::BL; + case V8CC::ICC_GU: return V8::BGU; + case V8CC::ICC_LEU: return V8::BLEU; + case V8CC::ICC_CC: return V8::BCC; + case V8CC::ICC_CS: return V8::BCS; + case V8CC::ICC_POS: return V8::BPOS; + case V8CC::ICC_NEG: return V8::BNEG; + case V8CC::ICC_VC: return V8::BVC; + case V8CC::ICC_VS: return V8::BVS; + case V8CC::FCC_U: return V8::FBU; + case V8CC::FCC_G: return V8::FBG; + case V8CC::FCC_UG: return V8::FBUG; + case V8CC::FCC_L: return V8::FBL; + case V8CC::FCC_UL: return V8::FBUL; + case V8CC::FCC_LG: return V8::FBLG; + case V8CC::FCC_NE: return V8::FBNE; + case V8CC::FCC_E: return V8::FBE; + case V8CC::FCC_UE: return V8::FBUE; + case V8CC::FCC_GE: return V8::FBGE; + case V8CC::FCC_UGE: return V8::FBUGE; + case V8CC::FCC_LE: return V8::FBLE; + case V8CC::FCC_ULE: return V8::FBULE; + case V8CC::FCC_O: return V8::FBO; + } + } + + static const char *SPARCCondCodeToString(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return "ne"; + case V8CC::ICC_E: return "e"; + case V8CC::ICC_G: return "g"; + case V8CC::ICC_LE: return "le"; + case V8CC::ICC_GE: return "ge"; + case V8CC::ICC_L: return "l"; + case V8CC::ICC_GU: return "gu"; + case V8CC::ICC_LEU: return "leu"; + case V8CC::ICC_CC: return "cc"; + case V8CC::ICC_CS: return "cs"; + case V8CC::ICC_POS: return "pos"; + case V8CC::ICC_NEG: return "neg"; + case V8CC::ICC_VC: return "vc"; + case V8CC::ICC_VS: return "vs"; + case V8CC::FCC_U: return "u"; + case V8CC::FCC_G: return "g"; + case V8CC::FCC_UG: return "ug"; + case V8CC::FCC_L: return "l"; + case V8CC::FCC_UL: return "ul"; + case V8CC::FCC_LG: return "lg"; + case V8CC::FCC_NE: return "ne"; + case V8CC::FCC_E: return "e"; + case V8CC::FCC_UE: return "ue"; + case V8CC::FCC_GE: return "ge"; + case V8CC::FCC_UGE: return "uge"; + case V8CC::FCC_LE: return "le"; + case V8CC::FCC_ULE: return "ule"; + case V8CC::FCC_O: return "o"; + } + } +} // end namespace llvm #endif diff --git a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp index f22185b51a6..dd1b46904d8 100644 --- a/lib/Target/SparcV8/SparcV8AsmPrinter.cpp +++ b/lib/Target/SparcV8/SparcV8AsmPrinter.cpp @@ -58,6 +58,8 @@ namespace { void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum); + void printV8CCOperand(const MachineInstr *MI, int opNum); + bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -211,6 +213,12 @@ void SparcV8AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) { } } +void SparcV8AsmPrinter::printV8CCOperand(const MachineInstr *MI, int opNum) { + int CC = (int)MI->getOperand(opNum).getImmedValue(); + O << SPARCCondCodeToString((V8CC::CondCodes)CC); +} + + bool SparcV8AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); diff --git a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp index 982215ac7e7..ff4e861e183 100644 --- a/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp +++ b/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp @@ -50,47 +50,6 @@ namespace V8ISD { }; } -// Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These -// values must be kept in sync with the ones in the .td file. -namespace V8CC { - enum CondCodes { - //ICC_A = 8 , // Always - //ICC_N = 0 , // Never - ICC_NE = 9 , // Not Equal - ICC_E = 1 , // Equal - ICC_G = 10 , // Greater - ICC_LE = 2 , // Less or Equal - ICC_GE = 11 , // Greater or Equal - ICC_L = 3 , // Less - ICC_GU = 12 , // Greater Unsigned - ICC_LEU = 4 , // Less or Equal Unsigned - ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned - ICC_CS = 5 , // Carry Set/Less Unsigned - ICC_POS = 14 , // Positive - ICC_NEG = 6 , // Negative - ICC_VC = 15 , // Overflow Clear - ICC_VS = 7 , // Overflow Set - - //FCC_A = 8+16, // Always - //FCC_N = 0+16, // Never - FCC_U = 7+16, // Unordered - FCC_G = 6+16, // Greater - FCC_UG = 5+16, // Unordered or Greater - FCC_L = 4+16, // Less - FCC_UL = 3+16, // Unordered or Less - FCC_LG = 2+16, // Less or Greater - FCC_NE = 1+16, // Not Equal - FCC_E = 9+16, // Equal - FCC_UE = 10+16, // Unordered or Equal - FCC_GE = 11+16, // Greater or Equal - FCC_UGE = 12+16, // Unordered or Greater or Equal - FCC_LE = 13+16, // Less or Equal - FCC_ULE = 14+16, // Unordered or Less or Equal - FCC_O = 15+16, // Ordered - }; -} - - /// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC /// condition. static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { @@ -130,42 +89,6 @@ static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { case ISD::SETUEQ: return V8CC::FCC_UE; } } - - -static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { - switch (CC) { - default: assert(0 && "Unknown condition code"); - case V8CC::ICC_NE: return V8::BNE; - case V8CC::ICC_E: return V8::BE; - case V8CC::ICC_G: return V8::BG; - case V8CC::ICC_LE: return V8::BLE; - case V8CC::ICC_GE: return V8::BGE; - case V8CC::ICC_L: return V8::BL; - case V8CC::ICC_GU: return V8::BGU; - case V8CC::ICC_LEU: return V8::BLEU; - case V8CC::ICC_CC: return V8::BCC; - case V8CC::ICC_CS: return V8::BCS; - case V8CC::ICC_POS: return V8::BPOS; - case V8CC::ICC_NEG: return V8::BNEG; - case V8CC::ICC_VC: return V8::BVC; - case V8CC::ICC_VS: return V8::BVS; - case V8CC::FCC_U: return V8::FBU; - case V8CC::FCC_G: return V8::FBG; - case V8CC::FCC_UG: return V8::FBUG; - case V8CC::FCC_L: return V8::FBL; - case V8CC::FCC_UL: return V8::FBUL; - case V8CC::FCC_LG: return V8::FBLG; - case V8CC::FCC_NE: return V8::FBNE; - case V8CC::FCC_E: return V8::FBE; - case V8CC::FCC_UE: return V8::FBUE; - case V8CC::FCC_GE: return V8::FBGE; - case V8CC::FCC_UGE: return V8::FBUGE; - case V8CC::FCC_LE: return V8::FBLE; - case V8CC::FCC_ULE: return V8::FBULE; - case V8CC::FCC_O: return V8::FBO; - } -} - namespace { class SparcV8TargetLowering : public TargetLowering { diff --git a/lib/Target/SparcV8/SparcV8InstrInfo.td b/lib/Target/SparcV8/SparcV8InstrInfo.td index 8a39d8175a9..72f6e3335e7 100644 --- a/lib/Target/SparcV8/SparcV8InstrInfo.td +++ b/lib/Target/SparcV8/SparcV8InstrInfo.td @@ -86,6 +86,10 @@ def MEMri : Operand { def brtarget : Operand; def calltarget : Operand; +// Operand for printing out a condition code. +let PrintMethod = "printV8CCOperand" in + def V8CC : Operand; + def SDTV8cmpfcc : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>; def SDTV8brcc : @@ -212,12 +216,14 @@ let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F, - imm:$Cond, ICC))]>; + imm:$Cond, ICC))]>, + Requires<[HasNoV9]>; def SELECT_CC_Int_FCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_FCC PSEUDO!", [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F, - imm:$Cond, FCC))]>; + imm:$Cond, FCC))]>, + Requires<[HasNoV9]>; def SELECT_CC_FP_ICC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", @@ -802,96 +808,27 @@ def FCMPD : F3_3<2, 0b110101, 0b001010010, let Predicates = [HasV9], isTwoAddress = 1 in { // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. // FIXME: Add instruction encodings for the JIT some day. - class IntCMOVICCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + def MOVICCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - class IntCMOVICCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>; + def MOVICCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc simm11:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - - // MOV*rr instructions. - def MOVNErr : IntCMOVICCrr< "movne %icc, $F, $dst", ICC_NE>; - def MOVErr : IntCMOVICCrr< "move %icc, $F, $dst", ICC_E>; - def MOVGrr : IntCMOVICCrr< "movg %icc, $F, $dst", ICC_G>; - def MOVLErr : IntCMOVICCrr< "movle %icc, $F, $dst", ICC_LE>; - def MOVGErr : IntCMOVICCrr< "movge %icc, $F, $dst", ICC_GE>; - def MOVLrr : IntCMOVICCrr< "movl %icc, $F, $dst", ICC_L>; - def MOVGUrr : IntCMOVICCrr< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUrr : IntCMOVICCrr<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCrr : IntCMOVICCrr< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSrr : IntCMOVICCrr< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSrr : IntCMOVICCrr<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGrr : IntCMOVICCrr<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCrr : IntCMOVICCrr< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSrr : IntCMOVICCrr< "movvs %icc, $F, $dst", ICC_VS>; - - // MOV*ri instructions. - def MOVNEri : IntCMOVICCri< "movne %icc, $F, $dst", ICC_NE>; - def MOVEri : IntCMOVICCri< "move %icc, $F, $dst", ICC_E>; - def MOVGri : IntCMOVICCri< "movg %icc, $F, $dst", ICC_G>; - def MOVLEri : IntCMOVICCri< "movle %icc, $F, $dst", ICC_LE>; - def MOVGEri : IntCMOVICCri< "movge %icc, $F, $dst", ICC_GE>; - def MOVLri : IntCMOVICCri< "movl %icc, $F, $dst", ICC_L>; - def MOVGUri : IntCMOVICCri< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUri : IntCMOVICCri<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCri : IntCMOVICCri< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSri : IntCMOVICCri< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSri : IntCMOVICCri<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGri : IntCMOVICCri<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCri : IntCMOVICCri< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSri : IntCMOVICCri< "movvs %icc, $F, $dst", ICC_VS>; + (V8selecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>; - // FIXME: Allow regalloc of the fcc condition code some day. - class IntCMOVFCCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + def MOVFCCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - class IntCMOVFCCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; + def MOVFCCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc simm11:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - - // MOVF*rr instructions. - def MOVFUrr : IntCMOVFCCrr< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGrr : IntCMOVFCCrr< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGrr : IntCMOVFCCrr< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLrr : IntCMOVFCCrr< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULrr : IntCMOVFCCrr< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGrr : IntCMOVFCCrr< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNErr : IntCMOVFCCrr< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFErr : IntCMOVFCCrr< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUErr : IntCMOVFCCrr< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGErr : IntCMOVFCCrr< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGErr : IntCMOVFCCrr<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLErr : IntCMOVFCCrr< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULErr : IntCMOVFCCrr<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOrr : IntCMOVFCCrr< "movfo %fcc, $F, $dst", FCC_O>; - - // MOVF*ri instructions. - def MOVFUri : IntCMOVFCCri< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGri : IntCMOVFCCri< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGri : IntCMOVFCCri< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLri : IntCMOVFCCri< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULri : IntCMOVFCCri< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGri : IntCMOVFCCri< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNEri : IntCMOVFCCri< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFEri : IntCMOVFCCri< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUEri : IntCMOVFCCri< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGEri : IntCMOVFCCri< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGEri : IntCMOVFCCri<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLEri : IntCMOVFCCri< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULEri : IntCMOVFCCri<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOri : IntCMOVFCCri< "movfo %fcc, $F, $dst", FCC_O>; + (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; } // Floating-Point Move Instructions, p. 164 of the V9 manual.