1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Three changes:

1. Introduce some enums and accessors in the InlineAsm class
   that eliminate a ton of magic numbers when handling inline
   asm SDNode.
2. Add a new MDNodeSDNode selection dag node type that holds
   a MDNode (shocking!)
3. Add a new argument to ISD::INLINEASM nodes that hold !srcloc
   metadata, propagating it to the instruction emitter, which
   drops it.

No functionality change.

llvm-svn: 100605
This commit is contained in:
Chris Lattner 2010-04-07 05:20:54 +00:00
parent 0f513e1c22
commit dde7376e9d
9 changed files with 172 additions and 66 deletions

View File

@ -650,6 +650,9 @@ public:
/// getSrcValue - Construct a node to track a Value* through the backend.
SDValue getSrcValue(const Value *v);
/// getMDNode - Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);
/// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type.
SDValue getShiftAmountOperand(SDValue Op);

View File

@ -499,9 +499,16 @@ namespace ISD {
// return values: a chain and a flag result. The inputs are as follows:
// Operand #0 : Input chain.
// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
// Operand #2n+2: A RegisterNode.
// Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
// After this, it is followed by a list of operands with this format:
// ConstantSDNode: Flags that encode whether it is a mem or not, the
// of operands that follow, etc. See InlineAsm.h.
// ... however many operands ...
// Operand #last: Optional, an incoming flag.
//
// The variable width operands are required to represent target addressing
// modes as a single "operand", even though they may have multiple
// SDOperands.
INLINEASM,
// EH_LABEL - Represents a label in mid basic block used to track
@ -542,6 +549,10 @@ namespace ISD {
// SRCVALUE - This is a node type that holds a Value* that is used to
// make reference to a value in the LLVM IR.
SRCVALUE,
// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
// reference metadata in the IR.
MDNODE_SDNODE,
// PCMARKER - This corresponds to the pcmarker intrinsic.
PCMARKER,
@ -2053,6 +2064,21 @@ public:
return N->getOpcode() == ISD::SRCVALUE;
}
};
class MDNodeSDNode : public SDNode {
const MDNode *MD;
friend class SelectionDAG;
explicit MDNodeSDNode(const MDNode *md)
: SDNode(ISD::MDNODE_SDNODE, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {}
public:
const MDNode *getMD() const { return MD; }
static bool classof(const MDNodeSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::MDNODE_SDNODE;
}
};
class RegisterSDNode : public SDNode {

View File

@ -146,6 +146,49 @@ public:
return V->getValueID() == Value::InlineAsmVal;
}
// These are helper methods for dealing with flags in the INLINEASM SDNode
// in the backend.
enum {
Op_InputChain = 0,
Op_AsmString = 1,
Op_MDNode = 2,
Op_FirstOperand = 3,
Kind_RegUse = 1,
Kind_RegDef = 2,
Kind_Imm = 3,
Kind_Mem = 4,
Kind_RegDefEarlyClobber = 6,
Flag_MatchingOperand = 0x80000000
};
static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
return Kind | (NumOps << 3);
}
/// getFlagWordForMatchingOp - Augment an existing flag word returned by
/// getFlagWord with information indicating that this input operand is tied
/// to a previous output operand.
static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
unsigned MatchedOperandNo) {
return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
}
static unsigned getKind(unsigned Flags) {
return Flags & 7;
}
static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
static bool isRegDefEarlyClobberKind(unsigned Flag) {
return getKind(Flag) == Kind_RegDefEarlyClobber;
}
/// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) {
@ -155,9 +198,9 @@ public:
/// isUseOperandTiedToDef - Return true if the flag of the inline asm
/// operand indicates it is an use operand that's matched to a def operand.
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
if ((Flag & 0x80000000) == 0)
if ((Flag & Flag_MatchingOperand) == 0)
return false;
Idx = (Flag & ~0x80000000) >> 16;
Idx = (Flag & ~Flag_MatchingOperand) >> 16;
return true;
}

View File

@ -731,12 +731,12 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
TII->get(TargetOpcode::INLINEASM));
// Add the asm string as an external symbol operand.
const char *AsmStr =
cast<ExternalSymbolSDNode>(Node->getOperand(1))->getSymbol();
SDValue AsmStrV = Node->getOperand(InlineAsm::Op_AsmString);
const char *AsmStr = cast<ExternalSymbolSDNode>(AsmStrV)->getSymbol();
MI->addOperand(MachineOperand::CreateES(AsmStr));
// Add all of the operand registers to the instruction.
for (unsigned i = 2; i != NumOps;) {
for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
@ -744,24 +744,24 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
MI->addOperand(MachineOperand::CreateImm(Flags));
++i; // Skip the ID value.
switch (Flags & 7) {
switch (InlineAsm::getKind(Flags)) {
default: llvm_unreachable("Bad flags!");
case 2: // Def of register.
case InlineAsm::Kind_RegDef:
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
MI->addOperand(MachineOperand::CreateReg(Reg, true));
}
break;
case 6: // Def of earlyclobber register.
case InlineAsm::Kind_RegDefEarlyClobber:
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
MI->addOperand(MachineOperand::CreateReg(Reg, true, false, false,
false, false, true));
}
break;
case 1: // Use of register.
case 3: // Immediate.
case 4: // Addressing mode.
case InlineAsm::Kind_RegUse: // Use of register.
case InlineAsm::Kind_Imm: // Immediate.
case InlineAsm::Kind_Mem: // Addressing mode.
// The addressing mode has been selected, just add all of the
// operands to the machine instruction.
for (; NumVals; --NumVals, ++i)

View File

@ -17,18 +17,19 @@
#define DEBUG_TYPE "pre-RA-sched"
#include "ScheduleDAGSDNodes.h"
#include "llvm/InlineAsm.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <climits>
using namespace llvm;
@ -647,13 +648,14 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU,
if (Node->getOperand(NumOps-1).getValueType() == MVT::Flag)
--NumOps; // Ignore the flag operand.
for (unsigned i = 2; i != NumOps;) {
for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
unsigned NumVals = (Flags & 0xffff) >> 3;
unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);
++i; // Skip the ID value.
if ((Flags & 7) == 2 || (Flags & 7) == 6) {
if (InlineAsm::isRegDefKind(Flags) ||
InlineAsm::isRegDefEarlyClobberKind(Flags)) {
// Check for def of register or earlyclobber register.
for (; NumVals; --NumVals, ++i) {
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();

View File

@ -59,7 +59,8 @@ namespace llvm {
if (isa<JumpTableSDNode>(Node)) return true;
if (isa<ExternalSymbolSDNode>(Node)) return true;
if (isa<BlockAddressSDNode>(Node)) return true;
if (Node->getOpcode() == ISD::EntryToken) return true;
if (Node->getOpcode() == ISD::EntryToken ||
isa<MDNodeSDNode>(Node)) return true;
return false;
}

View File

@ -1356,6 +1356,23 @@ SDValue SelectionDAG::getSrcValue(const Value *V) {
return SDValue(N, 0);
}
/// getMDNode - Return an MDNodeSDNode which holds an MDNode.
SDValue SelectionDAG::getMDNode(const MDNode *MD) {
FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::MDNODE_SDNODE, getVTList(MVT::Other), 0, 0);
ID.AddPointer(MD);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = new (NodeAllocator) MDNodeSDNode(MD);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
}
/// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type.
SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) {
@ -5559,6 +5576,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::PCMARKER: return "PCMarker";
case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
case ISD::SRCVALUE: return "SrcValue";
case ISD::MDNODE_SDNODE: return "MDNode";
case ISD::EntryToken: return "EntryToken";
case ISD::TokenFactor: return "TokenFactor";
case ISD::AssertSext: return "AssertSext";
@ -5927,6 +5945,11 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << "<" << M->getValue() << ">";
else
OS << "<null>";
} else if (const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(this)) {
if (MD->getMD())
OS << "<" << MD->getMD() << ">";
else
OS << "<null>";
} else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
OS << ":" << N->getVT().getEVTString();
}

View File

@ -168,7 +168,7 @@ namespace {
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker, matching input operand index
/// (if applicable), and includes the number of values added into it.
void AddInlineAsmOperands(unsigned Code,
void AddInlineAsmOperands(unsigned Kind,
bool HasMatching, unsigned MatchingIdx,
SelectionDAG &DAG,
std::vector<SDValue> &Ops) const;
@ -4871,14 +4871,13 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
/// operand list. This adds the code marker and includes the number of
/// values added into it.
void RegsForValue::AddInlineAsmOperands(unsigned Code,
bool HasMatching,unsigned MatchingIdx,
void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
unsigned MatchingIdx,
SelectionDAG &DAG,
std::vector<SDValue> &Ops) const {
assert(Regs.size() < (1 << 13) && "Too many inline asm outputs!");
unsigned Flag = Code | (Regs.size() << 3);
unsigned Flag = InlineAsm::getFlagWord(Code, Regs.size());
if (HasMatching)
Flag |= 0x80000000 | (MatchingIdx << 16);
Flag = InlineAsm::getFlagWordForMatchingOp(Flag, MatchingIdx);
SDValue Res = DAG.getTargetConstant(Flag, MVT::i32);
Ops.push_back(Res);
@ -5409,6 +5408,11 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
DAG.getTargetExternalSymbol(IA->getAsmString().c_str(),
TLI.getPointerTy()));
// If we have a !srcloc metadata node associated with it, we want to attach
// this to the ultimately generated inline asm machineinstr. To do this, we
// pass in the third operand as this (potentially null) inline asm MDNode.
const MDNode *SrcLoc = CS.getInstruction()->getMetadata("srcloc");
AsmNodeOperands.push_back(DAG.getMDNode(SrcLoc));
// Loop over all of the inputs, copying the operand values into the
// appropriate registers and processing the output regs.
@ -5428,8 +5432,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
assert(OpInfo.isIndirect && "Memory output must be indirect operand");
// Add information to the INLINEASM node to know about this output.
unsigned ResOpType = 4/*MEM*/ | (1<<3);
AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlags,
TLI.getPointerTy()));
AsmNodeOperands.push_back(OpInfo.CallOperand);
break;
@ -5439,10 +5443,9 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Copy the output from the appropriate register. Find a register that
// we can use.
if (OpInfo.AssignedRegs.Regs.empty()) {
if (OpInfo.AssignedRegs.Regs.empty())
llvm_report_error("Couldn't allocate output reg for"
" constraint '" + OpInfo.ConstraintCode + "'!");
}
// If this is an indirect operand, store through the pointer after the
// asm.
@ -5459,8 +5462,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Add information to the INLINEASM node to know that this register is
// set.
OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
6 /* EARLYCLOBBER REGDEF */ :
2 /* REGDEF */ ,
InlineAsm::Kind_RegDefEarlyClobber :
InlineAsm::Kind_RegDef,
false,
0,
DAG,
@ -5477,27 +5480,25 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Scan until we find the definition we already emitted of this operand.
// When we find it, create a RegsForValue operand.
unsigned CurOp = 2; // The first operand.
unsigned CurOp = InlineAsm::Op_FirstOperand;
for (; OperandNo; --OperandNo) {
// Advance to the next operand.
unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert(((OpFlag & 7) == 2 /*REGDEF*/ ||
(OpFlag & 7) == 6 /*EARLYCLOBBER REGDEF*/ ||
(OpFlag & 7) == 4 /*MEM*/) &&
"Skipped past definitions?");
assert((InlineAsm::isRegDefKind(OpFlag) ||
InlineAsm::isRegDefEarlyClobberKind(OpFlag) ||
InlineAsm::isMemKind(OpFlag)) && "Skipped past definitions?");
CurOp += InlineAsm::getNumOperandRegisters(OpFlag)+1;
}
unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
if ((OpFlag & 7) == 2 /*REGDEF*/
|| (OpFlag & 7) == 6 /* EARLYCLOBBER REGDEF */) {
if (InlineAsm::isRegDefKind(OpFlag) ||
InlineAsm::isRegDefEarlyClobberKind(OpFlag)) {
// Add (OpFlag&0xffff)>>3 registers to MatchedRegs.
if (OpInfo.isIndirect) {
if (OpInfo.isIndirect)
llvm_report_error("Don't know how to handle tied indirect "
"register inputs yet!");
}
RegsForValue MatchedRegs;
MatchedRegs.TLI = &TLI;
MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
@ -5512,22 +5513,23 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Use the produced MatchedRegs object to
MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/,
MatchedRegs.AddInlineAsmOperands(InlineAsm::Kind_RegUse,
true, OpInfo.getMatchedOperand(),
DAG, AsmNodeOperands);
break;
} else {
assert(((OpFlag & 7) == 4) && "Unknown matching constraint!");
assert((InlineAsm::getNumOperandRegisters(OpFlag)) == 1 &&
"Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
// See InlineAsm.h isUseOperandTiedToDef.
OpFlag |= 0x80000000 | (OpInfo.getMatchedOperand() << 16);
AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
TLI.getPointerTy()));
AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
break;
}
assert(InlineAsm::isMemKind(OpFlag) && "Unknown matching constraint!");
assert(InlineAsm::getNumOperandRegisters(OpFlag) == 1 &&
"Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
// See InlineAsm.h isUseOperandTiedToDef.
OpFlag = InlineAsm::getFlagWordForMatchingOp(OpFlag,
OpInfo.getMatchedOperand());
AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
TLI.getPointerTy()));
AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
break;
}
if (OpInfo.ConstraintType == TargetLowering::C_Other) {
@ -5543,18 +5545,21 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
}
// Add information to the INLINEASM node to know about this input.
unsigned ResOpType = 3 /*IMM*/ | (Ops.size() << 3);
unsigned ResOpType =
InlineAsm::getFlagWord(InlineAsm::Kind_Imm, Ops.size());
AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
TLI.getPointerTy()));
AsmNodeOperands.insert(AsmNodeOperands.end(), Ops.begin(), Ops.end());
break;
} else if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
}
if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
assert(InOperandVal.getValueType() == TLI.getPointerTy() &&
"Memory operands expect pointer values");
// Add information to the INLINEASM node to know about this input.
unsigned ResOpType = 4/*MEM*/ | (1<<3);
unsigned ResOpType = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
TLI.getPointerTy()));
AsmNodeOperands.push_back(InOperandVal);
@ -5577,7 +5582,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, false, 0,
OpInfo.AssignedRegs.AddInlineAsmOperands(InlineAsm::Kind_RegUse, false, 0,
DAG, AsmNodeOperands);
break;
}
@ -5585,7 +5590,8 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
// Add the clobbered value to the operand list, so that the register
// allocator is aware that the physreg got clobbered.
if (!OpInfo.AssignedRegs.Regs.empty())
OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */,
OpInfo.AssignedRegs.AddInlineAsmOperands(
InlineAsm::Kind_RegDefEarlyClobber,
false, 0, DAG,
AsmNodeOperands);
break;
@ -5593,7 +5599,7 @@ void SelectionDAGBuilder::visitInlineAsm(CallSite CS) {
}
}
// Finish up input operands.
// Finish up input operands. Set the input chain and add the flag last.
AsmNodeOperands[0] = Chain;
if (Flag.getNode()) AsmNodeOperands.push_back(Flag);

View File

@ -1333,16 +1333,17 @@ SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
std::vector<SDValue> InOps;
std::swap(InOps, Ops);
Ops.push_back(InOps[0]); // input chain.
Ops.push_back(InOps[1]); // input asm string.
Ops.push_back(InOps[InlineAsm::Op_InputChain]); // 0
Ops.push_back(InOps[InlineAsm::Op_AsmString]); // 1
Ops.push_back(InOps[InlineAsm::Op_MDNode]); // 2, !srcloc
unsigned i = 2, e = InOps.size();
unsigned i = InlineAsm::Op_FirstOperand, e = InOps.size();
if (InOps[e-1].getValueType() == MVT::Flag)
--e; // Don't process a flag operand if it is here.
while (i != e) {
unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
if ((Flags & 7) != 4 /*MEM*/) {
if (!InlineAsm::isMemKind(Flags)) {
// Just skip over this operand, copying the operands verbatim.
Ops.insert(Ops.end(), InOps.begin()+i,
InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
@ -1352,14 +1353,14 @@ SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
"Memory operand with multiple values?");
// Otherwise, this is a memory operand. Ask the target to select it.
std::vector<SDValue> SelOps;
if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {
if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps))
llvm_report_error("Could not match memory address. Inline asm"
" failure!");
}
// Add this to the output node.
Ops.push_back(CurDAG->getTargetConstant(4/*MEM*/ | (SelOps.size()<< 3),
MVT::i32));
unsigned NewFlags =
InlineAsm::getFlagWord(InlineAsm::Kind_Mem, SelOps.size());
Ops.push_back(CurDAG->getTargetConstant(NewFlags, MVT::i32));
Ops.insert(Ops.end(), SelOps.begin(), SelOps.end());
i += 2;
}
@ -2045,6 +2046,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
//case ISD::VALUETYPE:
//case ISD::CONDCODE:
case ISD::HANDLENODE:
case ISD::MDNODE_SDNODE:
case ISD::TargetConstant:
case ISD::TargetConstantFP:
case ISD::TargetConstantPool: