mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Add new SIGN_EXTEND_INREG, ZERO_EXTEND_INREG, and FP_ROUND_INREG operators.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
45554a61f2
commit
859157daee
@ -145,9 +145,11 @@ public:
|
||||
std::vector<SDOperand> &Children);
|
||||
|
||||
// getNode - These versions take an extra value type for extending and
|
||||
// truncating loads and stores.
|
||||
// truncating loads, stores, rounds, extends etc.
|
||||
SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1,
|
||||
SDOperand N2, MVT::ValueType EVT);
|
||||
SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand N, MVT::ValueType EVT);
|
||||
SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1,
|
||||
SDOperand N2, SDOperand N3, MVT::ValueType EVT);
|
||||
|
||||
|
@ -126,15 +126,30 @@ namespace ISD {
|
||||
SINT_TO_FP,
|
||||
UINT_TO_FP,
|
||||
|
||||
// SIGN_EXTEND_INREG/ZERO_EXTEND_INREG - These operators atomically performs
|
||||
// a SHL/(SRA|SHL) pair to (sign|zero) extend a small value in a large
|
||||
// integer register (e.g. sign extending the low 8 bits of a 32-bit register
|
||||
// to fill the top 24 bits with the 7th bit). The size of the smaller type
|
||||
// is indicated by the ExtraValueType in the MVTSDNode for the operator.
|
||||
SIGN_EXTEND_INREG,
|
||||
ZERO_EXTEND_INREG,
|
||||
|
||||
// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
|
||||
// integer.
|
||||
FP_TO_SINT,
|
||||
FP_TO_UINT,
|
||||
|
||||
// FP_ROUND - Perform a rounding operation from the current
|
||||
// precision down to the specified precision.
|
||||
// precision down to the specified precision (currently always 64->32).
|
||||
FP_ROUND,
|
||||
|
||||
// FP_ROUND_INREG - This operator takes a floating point register, and
|
||||
// rounds it to a floating point value. It then promotes it and returns it
|
||||
// in a register of the same size. This operation effectively just discards
|
||||
// excess precision. The type to round down to is specified by the
|
||||
// ExtraValueType in the MVTSDNode (currently always 64->32->64).
|
||||
FP_ROUND_INREG,
|
||||
|
||||
// FP_EXTEND - Extend a smaller FP type into a larger FP type.
|
||||
FP_EXTEND,
|
||||
|
||||
@ -706,6 +721,10 @@ class MVTSDNode : public SDNode {
|
||||
MVT::ValueType ExtraValueType;
|
||||
protected:
|
||||
friend class SelectionDAG;
|
||||
MVTSDNode(unsigned Opc, MVT::ValueType VT1, SDOperand Op0, MVT::ValueType EVT)
|
||||
: SDNode(Opc, Op0), ExtraValueType(EVT) {
|
||||
setValueTypes(VT1);
|
||||
}
|
||||
MVTSDNode(unsigned Opc, MVT::ValueType VT1, MVT::ValueType VT2,
|
||||
SDOperand Op0, SDOperand Op1, MVT::ValueType EVT)
|
||||
: SDNode(Opc, Op0, Op1), ExtraValueType(EVT) {
|
||||
@ -723,6 +742,9 @@ public:
|
||||
static bool classof(const MVTSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return
|
||||
N->getOpcode() == ISD::SIGN_EXTEND_INREG ||
|
||||
N->getOpcode() == ISD::ZERO_EXTEND_INREG ||
|
||||
N->getOpcode() == ISD::FP_ROUND_INREG ||
|
||||
N->getOpcode() == ISD::EXTLOAD ||
|
||||
N->getOpcode() == ISD::SEXTLOAD ||
|
||||
N->getOpcode() == ISD::ZEXTLOAD ||
|
||||
|
@ -220,26 +220,19 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
|
||||
N->getOperand(1)),
|
||||
cast<SetCCSDNode>(N)->getCondition()));
|
||||
break;
|
||||
case ISD::TRUNCSTORE: {
|
||||
EVTStruct NN;
|
||||
NN.Opcode = ISD::TRUNCSTORE;
|
||||
NN.VT = N->getValueType(0);
|
||||
NN.EVT = cast<MVTSDNode>(N)->getExtraValueType();
|
||||
NN.Ops.push_back(N->getOperand(0));
|
||||
NN.Ops.push_back(N->getOperand(1));
|
||||
NN.Ops.push_back(N->getOperand(2));
|
||||
MVTSDNodes.erase(NN);
|
||||
break;
|
||||
}
|
||||
case ISD::TRUNCSTORE:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
case ISD::ZERO_EXTEND_INREG:
|
||||
case ISD::FP_ROUND_INREG:
|
||||
case ISD::EXTLOAD:
|
||||
case ISD::SEXTLOAD:
|
||||
case ISD::ZEXTLOAD: {
|
||||
EVTStruct NN;
|
||||
NN.Opcode = N->getOpcode();
|
||||
NN.Opcode = ISD::TRUNCSTORE;
|
||||
NN.VT = N->getValueType(0);
|
||||
NN.EVT = cast<MVTSDNode>(N)->getExtraValueType();
|
||||
NN.Ops.push_back(N->getOperand(0));
|
||||
NN.Ops.push_back(N->getOperand(1));
|
||||
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
|
||||
NN.Ops.push_back(N->getOperand(i));
|
||||
MVTSDNodes.erase(NN);
|
||||
break;
|
||||
}
|
||||
@ -856,6 +849,41 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
MVT::ValueType EVT) {
|
||||
|
||||
switch (Opcode) {
|
||||
default: assert(0 && "Bad opcode for this accessor!");
|
||||
case ISD::FP_ROUND_INREG:
|
||||
assert(VT == N1.getValueType() && "Not an inreg round!");
|
||||
assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
|
||||
"Cannot FP_ROUND_INREG integer types");
|
||||
if (EVT == VT) return N1; // Not actually rounding
|
||||
assert(EVT < VT && "Not rounding down!");
|
||||
break;
|
||||
case ISD::ZERO_EXTEND_INREG:
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
assert(VT == N1.getValueType() && "Not an inreg extend!");
|
||||
assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
|
||||
"Cannot *_EXTEND_INREG FP types");
|
||||
if (EVT == VT) return N1; // Not actually extending
|
||||
assert(EVT < VT && "Not extending!");
|
||||
break;
|
||||
}
|
||||
|
||||
EVTStruct NN;
|
||||
NN.Opcode = Opcode;
|
||||
NN.VT = VT;
|
||||
NN.EVT = EVT;
|
||||
NN.Ops.push_back(N1);
|
||||
|
||||
SDNode *&N = MVTSDNodes[NN];
|
||||
if (N) return SDOperand(N, 0);
|
||||
N = new MVTSDNode(Opcode, VT, N1, EVT);
|
||||
AllNodes.push_back(N);
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
SDOperand N2, MVT::ValueType EVT) {
|
||||
switch (Opcode) {
|
||||
@ -894,10 +922,20 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,SDOperand N1,
|
||||
switch (Opcode) {
|
||||
default: assert(0 && "Bad opcode for this accessor!");
|
||||
case ISD::TRUNCSTORE:
|
||||
#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store
|
||||
// If this is a truncating store of a constant, convert to the desired type
|
||||
// and store it instead.
|
||||
if (isa<Constant>(N1)) {
|
||||
SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1);
|
||||
if (isa<Constant>(Op))
|
||||
N1 = Op;
|
||||
}
|
||||
// Also for ConstantFP?
|
||||
#endif
|
||||
if (N1.getValueType() == EVT) // Normal store?
|
||||
return getNode(ISD::STORE, VT, N1, N2, N3);
|
||||
assert(N1.getValueType() > EVT && "Not a truncation?");
|
||||
assert(MVT::isInteger(N1.getValueType()) == MVT::isInteger(EVT) &&
|
||||
assert(N2.getValueType() > EVT && "Not a truncation?");
|
||||
assert(MVT::isInteger(N2.getValueType()) == MVT::isInteger(EVT) &&
|
||||
"Can't do FP-INT conversion!");
|
||||
break;
|
||||
}
|
||||
@ -988,8 +1026,11 @@ const char *SDNode::getOperationName() const {
|
||||
// Conversion operators.
|
||||
case ISD::SIGN_EXTEND: return "sign_extend";
|
||||
case ISD::ZERO_EXTEND: return "zero_extend";
|
||||
case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
|
||||
case ISD::ZERO_EXTEND_INREG: return "zero_extend_inreg";
|
||||
case ISD::TRUNCATE: return "truncate";
|
||||
case ISD::FP_ROUND: return "fp_round";
|
||||
case ISD::FP_ROUND_INREG: return "fp_round_inreg";
|
||||
case ISD::FP_EXTEND: return "fp_extend";
|
||||
|
||||
case ISD::SINT_TO_FP: return "sint_to_fp";
|
||||
|
@ -570,7 +570,6 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
|
||||
SDOperand Src = getValue(SrcV);
|
||||
SDOperand Ptr = getValue(I.getOperand(1));
|
||||
DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), Src, Ptr));
|
||||
return;
|
||||
}
|
||||
|
||||
void SelectionDAGLowering::visitCall(CallInst &I) {
|
||||
|
Loading…
Reference in New Issue
Block a user