mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
Change Select() from
SDOperand Select(SDOperand N); to void Select(SDOperand &Result, SDOperand N); git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26067 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
418caa1356
commit
34167215a8
@ -96,7 +96,7 @@ namespace {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand Select(SDOperand Op);
|
||||
void Select(SDOperand &Result, SDOperand Op);
|
||||
|
||||
/// InstructionSelectBasicBlock - This callback is invoked by
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
@ -150,55 +150,73 @@ void AlphaDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
void AlphaDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||
N->getOpcode() < AlphaISD::FIRST_NUMBER)
|
||||
return Op; // Already selected.
|
||||
N->getOpcode() < AlphaISD::FIRST_NUMBER) {
|
||||
Result = Op;
|
||||
return; // Already selected.
|
||||
}
|
||||
|
||||
// If this has already been converted, use it.
|
||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
||||
if (CGMI != CodeGenMap.end()) return CGMI->second;
|
||||
|
||||
if (CGMI != CodeGenMap.end()) {
|
||||
Result = CGMI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case AlphaISD::CALL: return SelectCALL(Op);
|
||||
case AlphaISD::CALL:
|
||||
Result = SelectCALL(Op);
|
||||
return;
|
||||
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI64Imm(0));
|
||||
Result = CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI64Imm(0));
|
||||
return;
|
||||
}
|
||||
case AlphaISD::GlobalBaseReg:
|
||||
return getGlobalBaseReg();
|
||||
Result = getGlobalBaseReg();
|
||||
return;
|
||||
|
||||
case AlphaISD::DivCall: {
|
||||
SDOperand Chain = CurDAG->getEntryNode();
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, Select(Op.getOperand(1)),
|
||||
SDOperand N0, N1, N2;
|
||||
Select(N0, Op.getOperand(0));
|
||||
Select(N1, Op.getOperand(1));
|
||||
Select(N2, Op.getOperand(2));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, N1,
|
||||
SDOperand(0,0));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Select(Op.getOperand(2)),
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, N2,
|
||||
Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Select(Op.getOperand(0)),
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, N0,
|
||||
Chain.getValue(1));
|
||||
Chain = CurDAG->getTargetNode(Alpha::JSRs, MVT::Other, MVT::Flag,
|
||||
Chain, Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64,
|
||||
Chain.getValue(1));
|
||||
return CurDAG->SelectNodeTo(N, Alpha::BIS, MVT::i64, Chain, Chain);
|
||||
Result = CurDAG->SelectNodeTo(N, Alpha::BIS, MVT::i64, Chain, Chain);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::READCYCLECOUNTER: {
|
||||
SDOperand Chain = Select(N->getOperand(0)); //Select chain
|
||||
return CurDAG->SelectNodeTo(N, Alpha::RPCC, MVT::i64, Chain);
|
||||
SDOperand Chain;
|
||||
Select(Chain, N->getOperand(0)); //Select chain
|
||||
Result = CurDAG->SelectNodeTo(N, Alpha::RPCC, MVT::i64, Chain);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::RET: {
|
||||
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
||||
SDOperand Chain;
|
||||
Select(Chain, N->getOperand(0)); // Token chain.
|
||||
SDOperand InFlag;
|
||||
|
||||
if (N->getNumOperands() == 2) {
|
||||
SDOperand Val = Select(N->getOperand(1));
|
||||
SDOperand Val;
|
||||
Select(Val, N->getOperand(1));
|
||||
if (N->getOperand(1).getValueType() == MVT::i64) {
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R0, Val, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
@ -212,13 +230,17 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// Finally, select this to a ret instruction.
|
||||
return CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain, InFlag);
|
||||
Result = CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain, InFlag);
|
||||
return;
|
||||
}
|
||||
case ISD::Constant: {
|
||||
uint64_t uval = cast<ConstantSDNode>(N)->getValue();
|
||||
|
||||
if (uval == 0)
|
||||
return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), Alpha::R31, MVT::i64);
|
||||
if (uval == 0) {
|
||||
Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), Alpha::R31,
|
||||
MVT::i64);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t val = (int64_t)uval;
|
||||
int32_t val32 = (int32_t)val;
|
||||
@ -235,21 +257,24 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , uval);
|
||||
SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
|
||||
Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg());
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
|
||||
CPI, Tmp, CurDAG->getEntryNode());
|
||||
Result = CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
|
||||
CPI, Tmp, CurDAG->getEntryNode());
|
||||
return;
|
||||
}
|
||||
case ISD::TargetConstantFP: {
|
||||
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
|
||||
bool isDouble = N->getValueType(0) == MVT::f64;
|
||||
MVT::ValueType T = isDouble ? MVT::f64 : MVT::f32;
|
||||
if (CN->isExactlyValue(+0.0)) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
Result = CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
return;
|
||||
} else if ( CN->isExactlyValue(-0.0)) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
Result = CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
return;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
@ -271,8 +296,9 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
|
||||
case ISD::SETNE: Opc = Alpha::CMPTEQ; isNE = true; break;
|
||||
};
|
||||
SDOperand tmp1 = Select(N->getOperand(0)),
|
||||
tmp2 = Select(N->getOperand(1));
|
||||
SDOperand tmp1, tmp2;
|
||||
Select(tmp1, N->getOperand(0));
|
||||
Select(tmp2, N->getOperand(1));
|
||||
SDOperand cmp = CurDAG->getTargetNode(Opc, MVT::f64,
|
||||
rev?tmp2:tmp1,
|
||||
rev?tmp1:tmp2);
|
||||
@ -296,7 +322,8 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand FP = CurDAG->getTargetNode(Alpha::CMPULT, MVT::i64,
|
||||
CurDAG->getRegister(Alpha::R31, MVT::i64),
|
||||
LD);
|
||||
return FP;
|
||||
Result = FP;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -309,10 +336,10 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
// so that things like this can be caught in fall though code
|
||||
//move int to fp
|
||||
bool isDouble = N->getValueType(0) == MVT::f64;
|
||||
SDOperand LD,
|
||||
cond = Select(N->getOperand(0)),
|
||||
TV = Select(N->getOperand(1)),
|
||||
FV = Select(N->getOperand(2));
|
||||
SDOperand LD, cond, TV, FV;
|
||||
Select(cond, N->getOperand(0));
|
||||
Select(TV, N->getOperand(1));
|
||||
Select(FV, N->getOperand(2));
|
||||
|
||||
if (AlphaLowering.hasITOF()) {
|
||||
LD = CurDAG->getNode(AlphaISD::ITOFT_, MVT::f64, cond);
|
||||
@ -328,30 +355,34 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
|
||||
}
|
||||
SDOperand FP = CurDAG->getTargetNode(isDouble?Alpha::FCMOVNET:Alpha::FCMOVNES,
|
||||
MVT::f64, FV, TV, LD);
|
||||
return FP;
|
||||
Result = FP;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return SelectCode(Op);
|
||||
SelectCode(Result, Op);
|
||||
}
|
||||
|
||||
SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
//TODO: add flag stuff to prevent nondeturministic breakage!
|
||||
|
||||
SDNode *N = Op.Val;
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Chain;
|
||||
SDOperand Addr = N->getOperand(1);
|
||||
SDOperand InFlag; // Null incoming flag value.
|
||||
Select(Chain, N->getOperand(0));
|
||||
|
||||
std::vector<SDOperand> CallOperands;
|
||||
std::vector<MVT::ValueType> TypeOperands;
|
||||
|
||||
//grab the arguments
|
||||
for(int i = 2, e = N->getNumOperands(); i < e; ++i) {
|
||||
SDOperand Tmp;
|
||||
TypeOperands.push_back(N->getOperand(i).getValueType());
|
||||
CallOperands.push_back(Select(N->getOperand(i)));
|
||||
Select(Tmp, N->getOperand(i));
|
||||
CallOperands.push_back(Tmp);
|
||||
}
|
||||
int count = N->getNumOperands() - 2;
|
||||
|
||||
@ -396,7 +427,8 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
Chain = CurDAG->getTargetNode(Alpha::BSR, MVT::Other, MVT::Flag,
|
||||
Addr.getOperand(0), Chain, InFlag);
|
||||
} else {
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Select(Addr), InFlag);
|
||||
Select(Addr, Addr);
|
||||
Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = CurDAG->getTargetNode(Alpha::JSR, MVT::Other, MVT::Flag,
|
||||
Chain, InFlag );
|
||||
|
@ -63,7 +63,7 @@ namespace {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand Select(SDOperand Op);
|
||||
void Select(SDOperand &Result, SDOperand N);
|
||||
|
||||
SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS,
|
||||
unsigned OCHi, unsigned OCLo,
|
||||
@ -143,7 +143,8 @@ void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
}
|
||||
|
||||
// Finally, legalize this node.
|
||||
Select(Node);
|
||||
SDOperand Dummy;
|
||||
Select(Dummy, Node);
|
||||
}
|
||||
|
||||
// Select target instructions for the DAG.
|
||||
@ -157,10 +158,11 @@ void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
|
||||
SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Chain, Tmp1, Tmp2;
|
||||
Select(Chain, N->getOperand(0));
|
||||
|
||||
SDOperand Tmp1 = Select(N->getOperand(0));
|
||||
SDOperand Tmp2 = Select(N->getOperand(1));
|
||||
Select(Tmp1, N->getOperand(0));
|
||||
Select(Tmp2, N->getOperand(1));
|
||||
|
||||
bool isFP=false;
|
||||
|
||||
@ -328,25 +330,31 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||
N->getOpcode() < IA64ISD::FIRST_NUMBER)
|
||||
return Op; // Already selected.
|
||||
N->getOpcode() < IA64ISD::FIRST_NUMBER) {
|
||||
Result = Op;
|
||||
return; // Already selected.
|
||||
}
|
||||
|
||||
// If this has already been converted, use it.
|
||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
||||
if (CGMI != CodeGenMap.end()) return CGMI->second;
|
||||
if (CGMI != CodeGenMap.end()) {
|
||||
Result = CGMI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
|
||||
case IA64ISD::BRCALL: { // XXX: this is also a hack!
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Chain;
|
||||
SDOperand InFlag; // Null incoming flag value.
|
||||
|
||||
Select(Chain, N->getOperand(0));
|
||||
if(N->getNumOperands()==3) // we have an incoming chain, callee and flag
|
||||
InFlag = Select(N->getOperand(2));
|
||||
Select(InFlag, N->getOperand(2));
|
||||
|
||||
unsigned CallOpcode;
|
||||
SDOperand CallOperand;
|
||||
@ -367,7 +375,8 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
// otherwise we need to load the function descriptor,
|
||||
// load the branch target (function)'s entry point and GP,
|
||||
// branch (call) then restore the GP
|
||||
SDOperand FnDescriptor = Select(N->getOperand(1));
|
||||
SDOperand FnDescriptor;
|
||||
Select(FnDescriptor, N->getOperand(1));
|
||||
|
||||
// load the branch target's entry point [mem] and
|
||||
// GP value [mem+8]
|
||||
@ -404,41 +413,47 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
|
||||
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
||||
CodeGenMap[Op.getValue(i)] = CallResults[i];
|
||||
return CallResults[Op.ResNo];
|
||||
Result = CallResults[Op.ResNo];
|
||||
return;
|
||||
}
|
||||
|
||||
case IA64ISD::GETFD: {
|
||||
SDOperand Input = Select(N->getOperand(0));
|
||||
SDOperand Result = CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Input);
|
||||
SDOperand Input;
|
||||
Select(Input, N->getOperand(0));
|
||||
Result = CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Input);
|
||||
CodeGenMap[Op] = Result;
|
||||
return Result;
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::FDIV:
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
case ISD::SREM:
|
||||
case ISD::UREM: return SelectDIV(Op);
|
||||
case ISD::UREM:
|
||||
Result = SelectDIV(Op);
|
||||
return;
|
||||
|
||||
case ISD::TargetConstantFP: {
|
||||
SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so..
|
||||
|
||||
if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0))
|
||||
return CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64);
|
||||
else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0))
|
||||
return CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64);
|
||||
else
|
||||
if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0)) {
|
||||
Result = CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64);
|
||||
} else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0)) {
|
||||
Result = CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64);
|
||||
} else
|
||||
assert(0 && "Unexpected FP constant!");
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::FrameIndex: { // TODO: reduce creepyness
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
if (N->hasOneUse())
|
||||
return CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
|
||||
Result = CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i64));
|
||||
else
|
||||
return CodeGenMap[Op] = CurDAG->getTargetNode(IA64::MOV, MVT::i64,
|
||||
Result = CodeGenMap[Op] = CurDAG->getTargetNode(IA64::MOV, MVT::i64,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i64));
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::ConstantPool: { // TODO: nuke the constant pool
|
||||
@ -447,8 +462,9 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
Constant *C = CP->get();
|
||||
SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64,
|
||||
CP->getAlignment());
|
||||
return CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
|
||||
Result = CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
|
||||
CurDAG->getRegister(IA64::r1, MVT::i64), CPI);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::GlobalAddress: {
|
||||
@ -456,7 +472,8 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64);
|
||||
SDOperand Tmp = CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64,
|
||||
CurDAG->getRegister(IA64::r1, MVT::i64), GA);
|
||||
return CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp);
|
||||
Result = CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX case ISD::ExternalSymbol: {
|
||||
@ -471,8 +488,9 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
case ISD::LOAD:
|
||||
case ISD::EXTLOAD: // FIXME: load -1, not 1, for bools?
|
||||
case ISD::ZEXTLOAD: {
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Address = Select(N->getOperand(1));
|
||||
SDOperand Chain, Address;
|
||||
Select(Chain, N->getOperand(0));
|
||||
Select(Address, N->getOperand(1));
|
||||
|
||||
MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ?
|
||||
N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT();
|
||||
@ -481,11 +499,13 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
default: N->dump(); assert(0 && "Cannot load this type!");
|
||||
case MVT::i1: { // this is a bool
|
||||
Opc = IA64::LD1; // first we load a byte, then compare for != 0
|
||||
if(N->getValueType(0) == MVT::i1) // XXX: early exit!
|
||||
return CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other,
|
||||
if(N->getValueType(0) == MVT::i1) { // XXX: early exit!
|
||||
Result = CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other,
|
||||
CurDAG->getTargetNode(Opc, MVT::i64, Address),
|
||||
CurDAG->getRegister(IA64::r0, MVT::i64),
|
||||
Chain).getValue(Op.ResNo);
|
||||
return;
|
||||
}
|
||||
/* otherwise, we want to load a bool into something bigger: LD1
|
||||
will do that for us, so we just fall through */
|
||||
}
|
||||
@ -499,14 +519,16 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
}
|
||||
|
||||
// TODO: comment this
|
||||
return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
|
||||
Result = CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
|
||||
Address, Chain).getValue(Op.ResNo);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::TRUNCSTORE:
|
||||
case ISD::STORE: {
|
||||
SDOperand Address = Select(N->getOperand(2));
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Address, Chain;
|
||||
Select(Address, N->getOperand(2));
|
||||
Select(Chain, N->getOperand(0));
|
||||
|
||||
unsigned Opc;
|
||||
if (N->getOpcode() == ISD::STORE) {
|
||||
@ -518,11 +540,13 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand Initial = CurDAG->getCopyFromReg(Chain, IA64::r0, MVT::i64);
|
||||
Chain = Initial.getValue(1);
|
||||
// then load 1 into the same reg iff the predicate to store is 1
|
||||
SDOperand Tmp =
|
||||
CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
|
||||
CurDAG->getConstant(1, MVT::i64),
|
||||
Select(N->getOperand(1)));
|
||||
return CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain);
|
||||
SDOperand Tmp;
|
||||
Select(Tmp, N->getOperand(1));
|
||||
CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
|
||||
CurDAG->getConstant(1, MVT::i64),
|
||||
Tmp);
|
||||
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain);
|
||||
return;
|
||||
}
|
||||
case MVT::i64: Opc = IA64::ST8; break;
|
||||
case MVT::f64: Opc = IA64::STF8; break;
|
||||
@ -537,18 +561,23 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
}
|
||||
}
|
||||
|
||||
return CurDAG->SelectNodeTo(N, Opc, MVT::Other, Select(N->getOperand(2)),
|
||||
Select(N->getOperand(1)), Chain);
|
||||
SDOperand N1, N2;
|
||||
Select(N1, N->getOperand(1));
|
||||
Select(N2, N->getOperand(2));
|
||||
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::BRCOND: {
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand CC = Select(N->getOperand(1));
|
||||
SDOperand Chain, CC;
|
||||
Select(Chain, N->getOperand(0));
|
||||
Select(CC, N->getOperand(1));
|
||||
MachineBasicBlock *Dest =
|
||||
cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
|
||||
//FIXME - we do NOT need long branches all the time
|
||||
return CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC,
|
||||
Result = CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC,
|
||||
CurDAG->getBasicBlock(Dest), Chain);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::CALLSEQ_START:
|
||||
@ -556,17 +585,22 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
|
||||
int64_t Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue();
|
||||
unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
|
||||
IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
|
||||
return CurDAG->SelectNodeTo(N, Opc, MVT::Other,
|
||||
getI64Imm(Amt), Select(N->getOperand(0)));
|
||||
SDOperand N0;
|
||||
Select(N0, N->getOperand(0));
|
||||
Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::BR:
|
||||
// FIXME: we don't need long branches all the time!
|
||||
return CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other,
|
||||
N->getOperand(1), Select(N->getOperand(0)));
|
||||
SDOperand N0;
|
||||
Select(N0, N->getOperand(0));
|
||||
Result = CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other,
|
||||
N->getOperand(1), N0);
|
||||
return;
|
||||
}
|
||||
|
||||
return SelectCode(Op);
|
||||
SelectCode(Result, Op);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand Select(SDOperand Op);
|
||||
void Select(SDOperand &Result, SDOperand Op);
|
||||
|
||||
SDNode *SelectBitfieldInsert(SDNode *N);
|
||||
|
||||
@ -149,7 +149,8 @@ void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||
}
|
||||
|
||||
// Finally, legalize this node.
|
||||
Select(Node);
|
||||
SDOperand Dummy;
|
||||
Select(Dummy, Node);
|
||||
}
|
||||
|
||||
// Select target instructions for the DAG.
|
||||
@ -365,15 +366,16 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
||||
// where both bitfield halves are sourced from the same value.
|
||||
if (IsRotate && fullMask &&
|
||||
N->getOperand(0).getOperand(0) == N->getOperand(1).getOperand(0)) {
|
||||
Op0 = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
SDOperand Tmp;
|
||||
Select(Tmp, N->getOperand(0).getOperand(0));
|
||||
Op0 = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Tmp,
|
||||
getI32Imm(SH), getI32Imm(0), getI32Imm(31));
|
||||
return Op0.Val;
|
||||
}
|
||||
SDOperand Tmp1 = (Op0IsAND && fullMask) ? Select(Op0.getOperand(0))
|
||||
: Select(Op0);
|
||||
SDOperand Tmp2 = IsAndWithShiftOp ? Select(Op1.getOperand(0).getOperand(0))
|
||||
: Select(Op1.getOperand(0));
|
||||
SDOperand Tmp1, Tmp2;
|
||||
Select(Tmp1, ((Op0IsAND && fullMask) ? Op0.getOperand(0) : Op0));
|
||||
Select(Tmp2, (IsAndWithShiftOp ? Op1.getOperand(0).getOperand(0)
|
||||
: Op1.getOperand(0)));
|
||||
Op0 = CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
||||
return Op0.Val;
|
||||
@ -457,7 +459,7 @@ bool PPCDAGToDAGISel::SelectAddrIdxOnly(SDOperand N, SDOperand &Base,
|
||||
SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||
ISD::CondCode CC) {
|
||||
// Always select the LHS.
|
||||
LHS = Select(LHS);
|
||||
Select(LHS, LHS);
|
||||
|
||||
// Use U to determine whether the SETCC immediate range is signed or not.
|
||||
if (MVT::isInteger(LHS.getValueType())) {
|
||||
@ -467,12 +469,15 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
|
||||
((U && isUInt16(Imm)) || (!U && isInt16(Imm))))
|
||||
return CurDAG->getTargetNode(U ? PPC::CMPLWI : PPC::CMPWI, MVT::i32,
|
||||
LHS, getI32Imm(Imm & 0xFFFF));
|
||||
Select(RHS, RHS);
|
||||
return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32,
|
||||
LHS, Select(RHS));
|
||||
LHS, RHS);
|
||||
} else if (LHS.getValueType() == MVT::f32) {
|
||||
return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS));
|
||||
Select(RHS, RHS);
|
||||
return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, RHS);
|
||||
} else {
|
||||
return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS));
|
||||
Select(RHS, RHS);
|
||||
return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, RHS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,8 +540,9 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) {
|
||||
|
||||
SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
SDOperand LHSL = Select(N->getOperand(0));
|
||||
SDOperand LHSH = Select(N->getOperand(1));
|
||||
SDOperand LHSL, LHSH;
|
||||
Select(LHSL, N->getOperand(0));
|
||||
Select(LHSH, N->getOperand(1));
|
||||
|
||||
unsigned Imm;
|
||||
bool ME = false, ZE = false;
|
||||
@ -546,7 +552,7 @@ SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||
}
|
||||
|
||||
std::vector<SDOperand> Result;
|
||||
SDOperand CarryFromLo;
|
||||
SDOperand CarryFromLo, Tmp;
|
||||
if (isIntImmediate(N->getOperand(2), Imm) &&
|
||||
((signed)Imm >= -32768 || (signed)Imm < 32768)) {
|
||||
// Codegen the low 32 bits of the add. Interestingly, there is no
|
||||
@ -554,8 +560,9 @@ SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||
CarryFromLo = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
|
||||
LHSL, getI32Imm(Imm));
|
||||
} else {
|
||||
Select(Tmp, N->getOperand(2));
|
||||
CarryFromLo = CurDAG->getTargetNode(PPC::ADDC, MVT::i32, MVT::Flag,
|
||||
LHSL, Select(N->getOperand(2)));
|
||||
LHSL, Tmp);
|
||||
}
|
||||
CarryFromLo = CarryFromLo.getValue(1);
|
||||
|
||||
@ -566,9 +573,11 @@ SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||
ResultHi = CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, LHSH, CarryFromLo);
|
||||
else if (ME)
|
||||
ResultHi = CurDAG->getTargetNode(PPC::ADDME, MVT::i32, LHSH, CarryFromLo);
|
||||
else
|
||||
else {
|
||||
Select(Tmp, N->getOperand(3));
|
||||
ResultHi = CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH,
|
||||
Select(N->getOperand(3)), CarryFromLo);
|
||||
Tmp, CarryFromLo);
|
||||
}
|
||||
Result.push_back(CarryFromLo.getValue(0));
|
||||
Result.push_back(ResultHi);
|
||||
|
||||
@ -578,10 +587,11 @@ SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) {
|
||||
}
|
||||
SDOperand PPCDAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
SDOperand LHSL = Select(N->getOperand(0));
|
||||
SDOperand LHSH = Select(N->getOperand(1));
|
||||
SDOperand RHSL = Select(N->getOperand(2));
|
||||
SDOperand RHSH = Select(N->getOperand(3));
|
||||
SDOperand LHSL, LHSH, RHSL, RHSH;
|
||||
Select(LHSL, N->getOperand(0));
|
||||
Select(LHSH, N->getOperand(1));
|
||||
Select(RHSL, N->getOperand(2));
|
||||
Select(RHSH, N->getOperand(3));
|
||||
|
||||
std::vector<SDOperand> Result;
|
||||
Result.push_back(CurDAG->getTargetNode(PPC::SUBFC, MVT::i32, MVT::Flag,
|
||||
@ -602,7 +612,8 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
||||
// Check for those cases here.
|
||||
// setcc op, 0
|
||||
if (Imm == 0) {
|
||||
SDOperand Op = Select(N->getOperand(0));
|
||||
SDOperand Op;
|
||||
Select(Op, N->getOperand(0));
|
||||
switch (CC) {
|
||||
default: break;
|
||||
case ISD::SETEQ:
|
||||
@ -626,7 +637,8 @@ SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) {
|
||||
}
|
||||
}
|
||||
} else if (Imm == ~0U) { // setcc op, -1
|
||||
SDOperand Op = Select(N->getOperand(0));
|
||||
SDOperand Op;
|
||||
Select(Op, N->getOperand(0));
|
||||
switch (CC) {
|
||||
default: break;
|
||||
case ISD::SETEQ:
|
||||
@ -698,7 +710,8 @@ static bool isCallCompatibleAddress(ConstantSDNode *C) {
|
||||
|
||||
SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Chain;
|
||||
Select(Chain, N->getOperand(0));
|
||||
|
||||
unsigned CallOpcode;
|
||||
std::vector<SDOperand> CallOperands;
|
||||
@ -718,7 +731,8 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
CallOperands.push_back(getI32Imm((int)C->getValue() >> 2));
|
||||
} else {
|
||||
// Copy the callee address into the CTR register.
|
||||
SDOperand Callee = Select(N->getOperand(1));
|
||||
SDOperand Callee;
|
||||
Select(Callee, N->getOperand(1));
|
||||
Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain);
|
||||
|
||||
// Copy the callee address into R12 on darwin.
|
||||
@ -755,7 +769,8 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
}
|
||||
|
||||
if (N->getOperand(i).getOpcode() != ISD::UNDEF) {
|
||||
SDOperand Val = Select(N->getOperand(i));
|
||||
SDOperand Val;
|
||||
Select(Val, N->getOperand(i));
|
||||
Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy));
|
||||
@ -807,34 +822,52 @@ SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||
N->getOpcode() < PPCISD::FIRST_NUMBER)
|
||||
return Op; // Already selected.
|
||||
N->getOpcode() < PPCISD::FIRST_NUMBER) {
|
||||
Result = Op;
|
||||
return; // Already selected.
|
||||
}
|
||||
|
||||
// If this has already been converted, use it.
|
||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
||||
if (CGMI != CodeGenMap.end()) return CGMI->second;
|
||||
if (CGMI != CodeGenMap.end()) {
|
||||
Result = CGMI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case ISD::ADD_PARTS: return SelectADD_PARTS(Op);
|
||||
case ISD::SUB_PARTS: return SelectSUB_PARTS(Op);
|
||||
case ISD::SETCC: return SelectSETCC(Op);
|
||||
case PPCISD::CALL: return SelectCALL(Op);
|
||||
case PPCISD::GlobalBaseReg: return getGlobalBaseReg();
|
||||
case ISD::ADD_PARTS:
|
||||
Result = SelectADD_PARTS(Op);
|
||||
return;
|
||||
case ISD::SUB_PARTS:
|
||||
Result = SelectSUB_PARTS(Op);
|
||||
return;
|
||||
case ISD::SETCC:
|
||||
Result = SelectSETCC(Op);
|
||||
return;
|
||||
case PPCISD::CALL:
|
||||
Result = SelectCALL(Op);
|
||||
return;
|
||||
case PPCISD::GlobalBaseReg:
|
||||
Result = getGlobalBaseReg();
|
||||
return;
|
||||
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
if (N->hasOneUse())
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI32Imm(0));
|
||||
return CodeGenMap[Op] =
|
||||
if (N->hasOneUse()) {
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI32Imm(0));
|
||||
return;
|
||||
}
|
||||
Result = CodeGenMap[Op] =
|
||||
CurDAG->getTargetNode(PPC::ADDI, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI32Imm(0));
|
||||
return;
|
||||
}
|
||||
case ISD::SDIV: {
|
||||
// FIXME: since this depends on the setting of the carry flag from the srawi
|
||||
@ -844,23 +877,24 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
// sra/addze rather than having to handle sdiv ourselves. oh well.
|
||||
unsigned Imm;
|
||||
if (isIntImmediate(N->getOperand(1), Imm)) {
|
||||
SDOperand N0;
|
||||
Select(N0, N->getOperand(0));
|
||||
if ((signed)Imm > 0 && isPowerOf2_32(Imm)) {
|
||||
SDOperand Op =
|
||||
CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
|
||||
Select(N->getOperand(0)),
|
||||
getI32Imm(Log2_32(Imm)));
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
Op.getValue(0), Op.getValue(1));
|
||||
N0, getI32Imm(Log2_32(Imm)));
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
Op.getValue(0), Op.getValue(1));
|
||||
} else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) {
|
||||
SDOperand Op =
|
||||
CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag,
|
||||
Select(N->getOperand(0)),
|
||||
getI32Imm(Log2_32(-Imm)));
|
||||
N0, getI32Imm(Log2_32(-Imm)));
|
||||
SDOperand PT =
|
||||
CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(0),
|
||||
Op.getValue(1));
|
||||
return CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT);
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Other cases are autogenerated.
|
||||
@ -875,17 +909,20 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand Val;
|
||||
unsigned SH, MB, ME;
|
||||
if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) {
|
||||
Val = Select(N->getOperand(0).getOperand(0));
|
||||
Select(Val, N->getOperand(0).getOperand(0));
|
||||
} else if (Imm == 0) {
|
||||
// AND X, 0 -> 0, not "rlwinm 32".
|
||||
return Select(N->getOperand(1));
|
||||
Select(Result, N->getOperand(1));
|
||||
return ;
|
||||
} else {
|
||||
Val = Select(N->getOperand(0));
|
||||
Select(Val, N->getOperand(0));
|
||||
isRunOfOnes(Imm, MB, ME);
|
||||
SH = 0;
|
||||
}
|
||||
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val, getI32Imm(SH),
|
||||
getI32Imm(MB), getI32Imm(ME));
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val,
|
||||
getI32Imm(SH), getI32Imm(MB),
|
||||
getI32Imm(ME));
|
||||
return;
|
||||
}
|
||||
// ISD::OR doesn't get all the bitfield insertion fun.
|
||||
// (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert
|
||||
@ -895,10 +932,13 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
unsigned MB, ME;
|
||||
Imm = ~(Imm^Imm2);
|
||||
if (isRunOfOnes(Imm, MB, ME)) {
|
||||
SDOperand Tmp1 = Select(N->getOperand(0).getOperand(0));
|
||||
SDOperand Tmp2 = Select(N->getOperand(0).getOperand(1));
|
||||
return CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
|
||||
getI32Imm(0), getI32Imm(MB), getI32Imm(ME));
|
||||
SDOperand Tmp1, Tmp2;
|
||||
Select(Tmp1, N->getOperand(0).getOperand(0));
|
||||
Select(Tmp2, N->getOperand(0).getOperand(1));
|
||||
Result = CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2,
|
||||
getI32Imm(0), getI32Imm(MB),
|
||||
getI32Imm(ME));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,8 +946,10 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
break;
|
||||
}
|
||||
case ISD::OR:
|
||||
if (SDNode *I = SelectBitfieldInsert(N))
|
||||
return CodeGenMap[Op] = SDOperand(I, 0);
|
||||
if (SDNode *I = SelectBitfieldInsert(N)) {
|
||||
Result = CodeGenMap[Op] = SDOperand(I, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
@ -915,9 +957,12 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
unsigned Imm, SH, MB, ME;
|
||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
||||
SDOperand Val;
|
||||
Select(Val, N->getOperand(0).getOperand(0));
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Val, getI32Imm(SH), getI32Imm(MB),
|
||||
getI32Imm(ME));
|
||||
return;
|
||||
}
|
||||
|
||||
// Other cases are autogenerated.
|
||||
@ -927,10 +972,12 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
unsigned Imm, SH, MB, ME;
|
||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
getI32Imm(SH & 0x1F), getI32Imm(MB),
|
||||
getI32Imm(ME));
|
||||
SDOperand Val;
|
||||
Select(Val, N->getOperand(0).getOperand(0));
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Val, getI32Imm(SH & 0x1F), getI32Imm(MB),
|
||||
getI32Imm(ME));
|
||||
return;
|
||||
}
|
||||
|
||||
// Other cases are autogenerated.
|
||||
@ -945,12 +992,14 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N->getOperand(3)))
|
||||
if (N1C->isNullValue() && N3C->isNullValue() &&
|
||||
N2C->getValue() == 1ULL && CC == ISD::SETNE) {
|
||||
SDOperand LHS = Select(N->getOperand(0));
|
||||
SDOperand LHS;
|
||||
Select(LHS, N->getOperand(0));
|
||||
SDOperand Tmp =
|
||||
CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
|
||||
LHS, getI32Imm(~0U));
|
||||
return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, Tmp, LHS,
|
||||
Tmp.getValue(1));
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, Tmp, LHS,
|
||||
Tmp.getValue(1));
|
||||
return;
|
||||
}
|
||||
|
||||
SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC);
|
||||
@ -964,14 +1013,17 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
SelectCCOp = PPC::SELECT_CC_F4;
|
||||
else
|
||||
SelectCCOp = PPC::SELECT_CC_F8;
|
||||
return CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
||||
Select(N->getOperand(2)),
|
||||
Select(N->getOperand(3)),
|
||||
getI32Imm(BROpc));
|
||||
SDOperand N2, N3;
|
||||
Select(N2, N->getOperand(2));
|
||||
Select(N3, N->getOperand(3));
|
||||
Result = CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
||||
N2, N3, getI32Imm(BROpc));
|
||||
return;
|
||||
}
|
||||
case ISD::BR_CC:
|
||||
case ISD::BRTWOWAY_CC: {
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
SDOperand Chain;
|
||||
Select(Chain, N->getOperand(0));
|
||||
MachineBasicBlock *Dest =
|
||||
cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock();
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||
@ -1000,7 +1052,7 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
CondCode, getI32Imm(Opc),
|
||||
CondTrueBlock, CondFalseBlock,
|
||||
Chain);
|
||||
return CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB);
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB);
|
||||
} else {
|
||||
// Iterate to the next basic block
|
||||
ilist<MachineBasicBlock>::iterator It = BB;
|
||||
@ -1011,15 +1063,16 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
// we have nothing better to set it to, and leaving it alone will cause
|
||||
// the PowerPC Branch Selection pass to crash.
|
||||
if (It == BB->getParent()->end()) It = Dest;
|
||||
return CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode,
|
||||
getI32Imm(getBCCForSetCC(CC)),
|
||||
N->getOperand(4), CurDAG->getBasicBlock(It),
|
||||
Chain);
|
||||
Result = CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode,
|
||||
getI32Imm(getBCCForSetCC(CC)),
|
||||
N->getOperand(4), CurDAG->getBasicBlock(It),
|
||||
Chain);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return SelectCode(Op);
|
||||
SelectCode(Result, Op);
|
||||
}
|
||||
|
||||
|
||||
|
@ -934,7 +934,7 @@ public:
|
||||
Subtarget(TM.getSubtarget<SparcSubtarget>()) {
|
||||
}
|
||||
|
||||
SDOperand Select(SDOperand Op);
|
||||
void Select(SDOperand &Result, SDOperand Op);
|
||||
|
||||
// Complex Pattern Selectors.
|
||||
bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
|
||||
@ -1025,33 +1025,44 @@ bool SparcDAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
|
||||
return true;
|
||||
}
|
||||
|
||||
SDOperand SparcDAGToDAGISel::Select(SDOperand Op) {
|
||||
void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
|
||||
SDNode *N = Op.Val;
|
||||
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
|
||||
N->getOpcode() < SPISD::FIRST_NUMBER)
|
||||
return Op; // Already selected.
|
||||
N->getOpcode() < SPISD::FIRST_NUMBER) {
|
||||
Result = Op;
|
||||
return; // Already selected.
|
||||
}
|
||||
|
||||
// If this has already been converted, use it.
|
||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
|
||||
if (CGMI != CodeGenMap.end()) return CGMI->second;
|
||||
if (CGMI != CodeGenMap.end()) {
|
||||
Result = CGMI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
if (N->hasOneUse())
|
||||
return CurDAG->SelectNodeTo(N, SP::ADDri, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
return CodeGenMap[Op] =
|
||||
if (N->hasOneUse()) {
|
||||
Result = CurDAG->SelectNodeTo(N, SP::ADDri, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
return;
|
||||
}
|
||||
|
||||
Result = CodeGenMap[Op] =
|
||||
CurDAG->getTargetNode(SP::ADDri, MVT::i32,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
return;
|
||||
}
|
||||
case ISD::ADD_PARTS: {
|
||||
SDOperand LHSL = Select(N->getOperand(0));
|
||||
SDOperand LHSH = Select(N->getOperand(1));
|
||||
SDOperand RHSL = Select(N->getOperand(2));
|
||||
SDOperand RHSH = Select(N->getOperand(3));
|
||||
SDOperand LHSL, LHSH, RHSL, RHSH;
|
||||
Select(LHSL, N->getOperand(0));
|
||||
Select(LHSH, N->getOperand(1));
|
||||
Select(RHSL, N->getOperand(2));
|
||||
Select(RHSH, N->getOperand(3));
|
||||
// FIXME, handle immediate RHS.
|
||||
SDOperand Low = CurDAG->getTargetNode(SP::ADDCCrr, MVT::i32, MVT::Flag,
|
||||
LHSL, RHSL);
|
||||
@ -1059,27 +1070,30 @@ SDOperand SparcDAGToDAGISel::Select(SDOperand Op) {
|
||||
Low.getValue(1));
|
||||
CodeGenMap[SDOperand(N, 0)] = Low;
|
||||
CodeGenMap[SDOperand(N, 1)] = Hi;
|
||||
return Op.ResNo ? Hi : Low;
|
||||
Result = Op.ResNo ? Hi : Low;
|
||||
return;
|
||||
}
|
||||
case ISD::SUB_PARTS: {
|
||||
SDOperand LHSL = Select(N->getOperand(0));
|
||||
SDOperand LHSH = Select(N->getOperand(1));
|
||||
SDOperand RHSL = Select(N->getOperand(2));
|
||||
SDOperand RHSH = Select(N->getOperand(3));
|
||||
// FIXME, handle immediate RHS.
|
||||
SDOperand LHSL, LHSH, RHSL, RHSH;
|
||||
Select(LHSL, N->getOperand(0));
|
||||
Select(LHSH, N->getOperand(1));
|
||||
Select(RHSL, N->getOperand(2));
|
||||
Select(RHSH, N->getOperand(3));
|
||||
SDOperand Low = CurDAG->getTargetNode(SP::SUBCCrr, MVT::i32, MVT::Flag,
|
||||
LHSL, RHSL);
|
||||
SDOperand Hi = CurDAG->getTargetNode(SP::SUBXrr, MVT::i32, LHSH, RHSH,
|
||||
Low.getValue(1));
|
||||
CodeGenMap[SDOperand(N, 0)] = Low;
|
||||
CodeGenMap[SDOperand(N, 1)] = Hi;
|
||||
return Op.ResNo ? Hi : Low;
|
||||
Result = Op.ResNo ? Hi : Low;
|
||||
return;
|
||||
}
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV: {
|
||||
// FIXME: should use a custom expander to expose the SRA to the dag.
|
||||
SDOperand DivLHS = Select(N->getOperand(0));
|
||||
SDOperand DivRHS = Select(N->getOperand(1));
|
||||
SDOperand DivLHS, DivRHS;
|
||||
Select(DivLHS, N->getOperand(0));
|
||||
Select(DivRHS, N->getOperand(1));
|
||||
|
||||
// Set the Y register to the high-part.
|
||||
SDOperand TopPart;
|
||||
@ -1094,18 +1108,21 @@ SDOperand SparcDAGToDAGISel::Select(SDOperand Op) {
|
||||
|
||||
// FIXME: Handle div by immediate.
|
||||
unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
|
||||
return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
|
||||
Result = CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
|
||||
return;
|
||||
}
|
||||
case ISD::MULHU:
|
||||
case ISD::MULHS: {
|
||||
// FIXME: Handle mul by immediate.
|
||||
SDOperand MulLHS = Select(N->getOperand(0));
|
||||
SDOperand MulRHS = Select(N->getOperand(1));
|
||||
SDOperand MulLHS, MulRHS;
|
||||
Select(MulLHS, N->getOperand(0));
|
||||
Select(MulRHS, N->getOperand(1));
|
||||
unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
|
||||
SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
|
||||
MulLHS, MulRHS);
|
||||
// The high part is in the Y register.
|
||||
return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, Mul.getValue(1));
|
||||
Result = CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, Mul.getValue(1));
|
||||
return;
|
||||
}
|
||||
case SPISD::CALL:
|
||||
// FIXME: This is a workaround for a bug in tblgen.
|
||||
@ -1118,10 +1135,9 @@ SDOperand SparcDAGToDAGISel::Select(SDOperand Op) {
|
||||
SDOperand InFlag = SDOperand(0, 0);
|
||||
SDOperand Chain = N->getOperand(0);
|
||||
SDOperand Tmp0 = N1;
|
||||
Chain = Select(Chain);
|
||||
SDOperand Result;
|
||||
Select(Chain, Chain);
|
||||
if (N->getNumOperands() == 3) {
|
||||
InFlag = Select(N->getOperand(2));
|
||||
Select(InFlag, N->getOperand(2));
|
||||
Result = CurDAG->getTargetNode(SP::CALL, MVT::Other, MVT::Flag, Tmp0,
|
||||
Chain, InFlag);
|
||||
} else {
|
||||
@ -1130,13 +1146,14 @@ SDOperand SparcDAGToDAGISel::Select(SDOperand Op) {
|
||||
}
|
||||
Chain = CodeGenMap[SDOperand(N, 0)] = Result.getValue(0);
|
||||
CodeGenMap[SDOperand(N, 1)] = Result.getValue(1);
|
||||
return Result.getValue(Op.ResNo);
|
||||
Result = Result.getValue(Op.ResNo);
|
||||
return;
|
||||
}
|
||||
P47Fail:;
|
||||
|
||||
}
|
||||
|
||||
return SelectCode(Op);
|
||||
SelectCode(Result, Op);
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace {
|
||||
#include "X86GenDAGISel.inc"
|
||||
|
||||
private:
|
||||
SDOperand Select(SDOperand N);
|
||||
void Select(SDOperand &Result, SDOperand N);
|
||||
|
||||
bool MatchAddress(SDOperand N, X86ISelAddressMode &AM);
|
||||
bool SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
|
||||
@ -445,17 +445,22 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base,
|
||||
return false;
|
||||
}
|
||||
|
||||
SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
|
||||
SDNode *Node = N.Val;
|
||||
MVT::ValueType NVT = Node->getValueType(0);
|
||||
unsigned Opc, MOpc;
|
||||
unsigned Opcode = Node->getOpcode();
|
||||
|
||||
if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER)
|
||||
return N; // Already selected.
|
||||
if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) {
|
||||
Result = N;
|
||||
return; // Already selected.
|
||||
}
|
||||
|
||||
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N);
|
||||
if (CGMI != CodeGenMap.end()) return CGMI->second;
|
||||
if (CGMI != CodeGenMap.end()) {
|
||||
Result = CGMI->second;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Opcode) {
|
||||
default: break;
|
||||
@ -499,33 +504,39 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand Chain = foldedLoad ? Select(N1.getOperand(0))
|
||||
: CurDAG->getEntryNode();
|
||||
SDOperand Chain;
|
||||
if (foldedLoad)
|
||||
Select(Chain, N1.getOperand(0));
|
||||
else
|
||||
Chain = CurDAG->getEntryNode();
|
||||
|
||||
SDOperand InFlag;
|
||||
SDOperand InFlag(0, 0);
|
||||
Select(N0, N0);
|
||||
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
||||
Select(N0), InFlag);
|
||||
N0, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
if (foldedLoad) {
|
||||
Tmp0 = Select(Tmp0);
|
||||
Tmp1 = Select(Tmp1);
|
||||
Tmp2 = Select(Tmp2);
|
||||
Tmp3 = Select(Tmp3);
|
||||
Select(Tmp0, Tmp0);
|
||||
Select(Tmp1, Tmp1);
|
||||
Select(Tmp2, Tmp2);
|
||||
Select(Tmp3, Tmp3);
|
||||
Chain = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
||||
Tmp2, Tmp3, Chain, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
} else {
|
||||
InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, Select(N1), InFlag);
|
||||
Select(N1, N1);
|
||||
InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag);
|
||||
}
|
||||
|
||||
SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
|
||||
Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
|
||||
CodeGenMap[N.getValue(0)] = Result;
|
||||
if (foldedLoad) {
|
||||
CodeGenMap[N1.getValue(1)] = Result.getValue(1);
|
||||
AddHandleReplacement(N1.getValue(1), Result.getValue(1));
|
||||
}
|
||||
return Result;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::SDIV:
|
||||
@ -576,12 +587,16 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
bool foldedLoad = false;
|
||||
SDOperand Tmp0, Tmp1, Tmp2, Tmp3;
|
||||
foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
|
||||
SDOperand Chain = foldedLoad ? Select(N1.getOperand(0))
|
||||
: CurDAG->getEntryNode();
|
||||
SDOperand Chain;
|
||||
if (foldedLoad)
|
||||
Select(Chain, N1.getOperand(0));
|
||||
else
|
||||
Chain = CurDAG->getEntryNode();
|
||||
|
||||
SDOperand InFlag;
|
||||
SDOperand InFlag(0, 0);
|
||||
Select(N0, N0);
|
||||
Chain = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
|
||||
Select(N0), InFlag);
|
||||
N0, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
if (isSigned) {
|
||||
@ -598,25 +613,26 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
}
|
||||
|
||||
if (foldedLoad) {
|
||||
Tmp0 = Select(Tmp0);
|
||||
Tmp1 = Select(Tmp1);
|
||||
Tmp2 = Select(Tmp2);
|
||||
Tmp3 = Select(Tmp3);
|
||||
Select(Tmp0, Tmp0);
|
||||
Select(Tmp1, Tmp1);
|
||||
Select(Tmp2, Tmp2);
|
||||
Select(Tmp3, Tmp3);
|
||||
Chain = CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
|
||||
Tmp2, Tmp3, Chain, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
} else {
|
||||
InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, Select(N1), InFlag);
|
||||
Select(N1, N1);
|
||||
InFlag = CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag);
|
||||
}
|
||||
|
||||
SDOperand Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg,
|
||||
NVT, InFlag);
|
||||
Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg,
|
||||
NVT, InFlag);
|
||||
CodeGenMap[N.getValue(0)] = Result;
|
||||
if (foldedLoad) {
|
||||
CodeGenMap[N1.getValue(1)] = Result.getValue(1);
|
||||
AddHandleReplacement(N1.getValue(1), Result.getValue(1));
|
||||
}
|
||||
return Result;
|
||||
return;
|
||||
}
|
||||
|
||||
case ISD::TRUNCATE: {
|
||||
@ -627,11 +643,11 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
case MVT::i16: Reg = X86::AX; Opc = X86::MOV16rr; VT = MVT::i16; break;
|
||||
case MVT::i32: Reg = X86::EAX; Opc = X86::MOV32rr; VT = MVT::i32; break;
|
||||
}
|
||||
SDOperand Tmp0 = Select(Node->getOperand(0));
|
||||
SDOperand Tmp1 = CurDAG->getTargetNode(Opc, VT, Tmp0);
|
||||
SDOperand Tmp0, Tmp1;
|
||||
Select(Tmp0, Node->getOperand(0));
|
||||
Select(Tmp1, CurDAG->getTargetNode(Opc, VT, Tmp0));
|
||||
SDOperand InFlag = SDOperand(0,0);
|
||||
SDOperand Result = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
|
||||
Reg, Tmp1, InFlag);
|
||||
Result = CurDAG->getCopyToReg(CurDAG->getEntryNode(), Reg, Tmp1, InFlag);
|
||||
SDOperand Chain = Result.getValue(0);
|
||||
InFlag = Result.getValue(1);
|
||||
|
||||
@ -641,17 +657,16 @@ SDOperand X86DAGToDAGISel::Select(SDOperand N) {
|
||||
case MVT::i16: Reg = X86::AX; Opc = X86::MOV16rr; VT = MVT::i16; break;
|
||||
}
|
||||
|
||||
Result = CurDAG->getCopyFromReg(Chain,
|
||||
Reg, VT, InFlag);
|
||||
Result = CurDAG->getCopyFromReg(Chain, Reg, VT, InFlag);
|
||||
if (N.Val->hasOneUse())
|
||||
return CurDAG->SelectNodeTo(N.Val, Opc, VT, Result);
|
||||
Result =CurDAG->SelectNodeTo(N.Val, Opc, VT, Result);
|
||||
else
|
||||
return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result);
|
||||
break;
|
||||
Result = CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return SelectCode(N);
|
||||
SelectCode(Result, N);
|
||||
}
|
||||
|
||||
/// createX86ISelDag - This pass converts a legalized DAG into a
|
||||
|
@ -2196,13 +2196,13 @@ public:
|
||||
emitCheck(Code + ")");
|
||||
|
||||
for (unsigned i = 0; i < NumRes; ++i)
|
||||
emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" +
|
||||
emitCode("Select(Tmp" + utostr(i+ResNo) + ", Tmp" +
|
||||
utostr(i+ResNo) + ");");
|
||||
|
||||
TmpNo = ResNo + NumRes;
|
||||
} else {
|
||||
emitDecl("Tmp" + utostr(ResNo));
|
||||
emitCode("Tmp" + utostr(ResNo) + " = Select(" + Val + ");");
|
||||
emitCode("Select(Tmp" + utostr(ResNo) + ", " + Val + ");");
|
||||
}
|
||||
// Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
|
||||
// value if used multiple times by this pattern result.
|
||||
@ -2301,7 +2301,7 @@ public:
|
||||
// Emit all the chain and CopyToReg stuff.
|
||||
bool ChainEmitted = HasChain;
|
||||
if (HasChain)
|
||||
emitCode(ChainName + " = Select(" + ChainName + ");");
|
||||
emitCode("Select(" + ChainName + ", " + ChainName + ");");
|
||||
if (HasInFlag || HasOptInFlag || HasImpInputs)
|
||||
EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
|
||||
|
||||
@ -2329,9 +2329,7 @@ public:
|
||||
utostr(NumResults) + ");");
|
||||
}
|
||||
} else if (HasChain || NodeHasOutFlag) {
|
||||
emitDecl("Result");
|
||||
if (HasOptInFlag) {
|
||||
emitCode("Result = SDOperand(0, 0);");
|
||||
unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren();
|
||||
emitCode("if (HasOptInFlag)");
|
||||
std::string Code = " Result = CurDAG->getTargetNode(" +
|
||||
@ -2445,21 +2443,21 @@ public:
|
||||
|
||||
if (AddedChain && NodeHasOutFlag) {
|
||||
if (NumExpectedResults == 0) {
|
||||
emitCode("return Result.getValue(N.ResNo+1);");
|
||||
emitCode("Result = Result.getValue(N.ResNo+1);");
|
||||
} else {
|
||||
emitCode("if (N.ResNo < " + utostr(NumExpectedResults) + ")");
|
||||
emitCode(" return Result.getValue(N.ResNo);");
|
||||
emitCode(" Result = Result.getValue(N.ResNo);");
|
||||
emitCode("else");
|
||||
emitCode(" return Result.getValue(N.ResNo+1);");
|
||||
emitCode(" Result = Result.getValue(N.ResNo+1);");
|
||||
}
|
||||
} else {
|
||||
emitCode("return Result.getValue(N.ResNo);");
|
||||
emitCode("Result = Result.getValue(N.ResNo);");
|
||||
}
|
||||
} else {
|
||||
// If this instruction is the root, and if there is only one use of it,
|
||||
// use SelectNodeTo instead of getTargetNode to avoid an allocation.
|
||||
emitCode("if (N.Val->hasOneUse()) {");
|
||||
std::string Code = " return CurDAG->SelectNodeTo(N.Val, " +
|
||||
std::string Code = " Result = CurDAG->SelectNodeTo(N.Val, " +
|
||||
II.Namespace + "::" + II.TheDef->getName();
|
||||
if (N->getTypeNum(0) != MVT::isVoid)
|
||||
Code += ", MVT::" + getEnumName(N->getTypeNum(0));
|
||||
@ -2471,7 +2469,7 @@ public:
|
||||
Code += ", InFlag";
|
||||
emitCode(Code + ");");
|
||||
emitCode("} else {");
|
||||
Code = " return CodeGenMap[N] = CurDAG->getTargetNode(" +
|
||||
Code = " Result = CodeGenMap[N] = CurDAG->getTargetNode(" +
|
||||
II.Namespace + "::" + II.TheDef->getName();
|
||||
if (N->getTypeNum(0) != MVT::isVoid)
|
||||
Code += ", MVT::" + getEnumName(N->getTypeNum(0));
|
||||
@ -2485,6 +2483,8 @@ public:
|
||||
emitCode("}");
|
||||
}
|
||||
|
||||
if (isRoot)
|
||||
emitCode("return;");
|
||||
return std::make_pair(1, ResNo);
|
||||
} else if (Op->isSubClassOf("SDNodeXForm")) {
|
||||
assert(N->getNumChildren() == 1 && "node xform should have one child!");
|
||||
@ -2495,7 +2495,8 @@ public:
|
||||
+ "(Tmp" + utostr(OpVal) + ".Val);");
|
||||
if (isRoot) {
|
||||
emitCode("CodeGenMap[N] = Tmp" +utostr(ResNo) + ";");
|
||||
emitCode("return Tmp" + utostr(ResNo) + ";");
|
||||
emitCode("Result = Tmp" + utostr(ResNo) + ";");
|
||||
emitCode("return;");
|
||||
}
|
||||
return std::make_pair(1, ResNo);
|
||||
} else {
|
||||
@ -2556,7 +2557,7 @@ private:
|
||||
if (RR->isSubClassOf("Register")) {
|
||||
MVT::ValueType RVT = getRegisterValueType(RR, T);
|
||||
if (RVT == MVT::Flag) {
|
||||
emitCode("InFlag = Select(" + RootName + utostr(OpNo) + ");");
|
||||
emitCode("Select(InFlag, " + RootName + utostr(OpNo) + ");");
|
||||
} else {
|
||||
if (!ChainEmitted) {
|
||||
emitDecl("Chain");
|
||||
@ -2564,16 +2565,15 @@ private:
|
||||
ChainName = "Chain";
|
||||
ChainEmitted = true;
|
||||
}
|
||||
emitDecl(RootName + "CR" + utostr(i));
|
||||
emitCode(RootName + "CR" + utostr(i) +
|
||||
" = CurDAG->getCopyToReg(" + ChainName +
|
||||
emitCode("Select(" + RootName + utostr(OpNo) + ", " +
|
||||
RootName + utostr(OpNo) + ");");
|
||||
emitDecl("Copy");
|
||||
emitCode("Copy = CurDAG->getCopyToReg(" + ChainName +
|
||||
", CurDAG->getRegister(" + ISE.getQualifiedName(RR) +
|
||||
", MVT::" + getEnumName(RVT) + "), Select(" + RootName +
|
||||
utostr(OpNo) + "), InFlag);");
|
||||
emitCode(ChainName + " = " + RootName + "CR" + utostr(i) +
|
||||
".getValue(0);");
|
||||
emitCode("InFlag = " + RootName + "CR" + utostr(i) +
|
||||
".getValue(1);");
|
||||
", MVT::" + getEnumName(RVT) + "), " +
|
||||
RootName + utostr(OpNo) + ", InFlag);");
|
||||
emitCode(ChainName + " = Copy.getValue(0);");
|
||||
emitCode("InFlag = Copy.getValue(1);");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2587,8 +2587,8 @@ private:
|
||||
") {");
|
||||
Code = " ";
|
||||
}
|
||||
emitCode(Code + "InFlag = Select(" + RootName + ".getOperand(" +
|
||||
utostr(OpNo) + "));");
|
||||
emitCode(Code + "Select(InFlag, " + RootName +
|
||||
".getOperand(" + utostr(OpNo) + "));");
|
||||
if (HasOptInFlag) {
|
||||
emitCode(" HasOptInFlag = true;");
|
||||
emitCode("}");
|
||||
@ -2866,7 +2866,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
CompareByRecordName>::iterator PBOI = PatternsByOpcode.begin(),
|
||||
E = PatternsByOpcode.end(); PBOI != E; ++PBOI) {
|
||||
const std::string &OpName = PBOI->first->getName();
|
||||
OS << "SDOperand Select_" << OpName << "(SDOperand N) {\n";
|
||||
OS << "void Select_" << OpName << "(SDOperand &Result, SDOperand N) {\n";
|
||||
|
||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
||||
bool OptSlctOrder =
|
||||
@ -2874,7 +2874,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
OpcodeInfo.getNumResults() > 0);
|
||||
|
||||
if (OptSlctOrder) {
|
||||
OS << " SDOperand RetVal;\n";
|
||||
OS << " if (N.ResNo == " << OpcodeInfo.getNumResults()
|
||||
<< " && N.getValue(0).hasOneUse()) {\n"
|
||||
<< " SDOperand Dummy = "
|
||||
@ -2883,7 +2882,8 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
<< ")] = Dummy;\n"
|
||||
<< " HandleMap[N.getValue(" << OpcodeInfo.getNumResults()
|
||||
<< ")] = Dummy;\n"
|
||||
<< " return Dummy;\n"
|
||||
<< " Result = Dummy;\n"
|
||||
<< " return;\n"
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
@ -2935,7 +2935,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
// Print all declarations.
|
||||
for (std::set<std::string>::iterator I = GeneratedDecl.begin(),
|
||||
E = GeneratedDecl.end(); I != E; ++I)
|
||||
OS << " SDOperand " << *I << ";\n";
|
||||
OS << " SDOperand " << *I << "(0, 0);\n";
|
||||
|
||||
// Loop through and reverse all of the CodeList vectors, as we will be
|
||||
// accessing them from their logical front, but accessing the end of a
|
||||
@ -2963,29 +2963,35 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
}
|
||||
|
||||
// Emit boilerplate.
|
||||
OS << "SDOperand Select_INLINEASM(SDOperand N) {\n"
|
||||
OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
|
||||
<< " std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end());\n"
|
||||
<< " Ops[0] = Select(N.getOperand(0)); // Select the chain.\n\n"
|
||||
<< " Select(Ops[0], N.getOperand(0)); // Select the chain.\n\n"
|
||||
<< " // Select the flag operand.\n"
|
||||
<< " if (Ops.back().getValueType() == MVT::Flag)\n"
|
||||
<< " Ops.back() = Select(Ops.back());\n"
|
||||
<< " Select(Ops.back(), Ops.back());\n"
|
||||
<< " std::vector<MVT::ValueType> VTs;\n"
|
||||
<< " VTs.push_back(MVT::Other);\n"
|
||||
<< " VTs.push_back(MVT::Flag);\n"
|
||||
<< " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, Ops);\n"
|
||||
<< " CodeGenMap[N.getValue(0)] = New;\n"
|
||||
<< " CodeGenMap[N.getValue(1)] = New.getValue(1);\n"
|
||||
<< " return New.getValue(N.ResNo);\n"
|
||||
<< " Result = New.getValue(N.ResNo);\n"
|
||||
<< " return;\n"
|
||||
<< "}\n\n";
|
||||
|
||||
OS << "// The main instruction selector code.\n"
|
||||
<< "SDOperand SelectCode(SDOperand N) {\n"
|
||||
<< "void SelectCode(SDOperand &Result, SDOperand N) {\n"
|
||||
<< " if (N.getOpcode() >= ISD::BUILTIN_OP_END &&\n"
|
||||
<< " N.getOpcode() < (ISD::BUILTIN_OP_END+" << InstNS
|
||||
<< "INSTRUCTION_LIST_END))\n"
|
||||
<< " return N; // Already selected.\n\n"
|
||||
<< "INSTRUCTION_LIST_END)) {\n"
|
||||
<< " Result = N;\n"
|
||||
<< " return; // Already selected.\n"
|
||||
<< " }\n\n"
|
||||
<< " std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N);\n"
|
||||
<< " if (CGMI != CodeGenMap.end()) return CGMI->second;\n"
|
||||
<< " if (CGMI != CodeGenMap.end()) {\n"
|
||||
<< " Result = CGMI->second;\n"
|
||||
<< " return;\n"
|
||||
<< " }\n\n"
|
||||
<< " switch (N.getOpcode()) {\n"
|
||||
<< " default: break;\n"
|
||||
<< " case ISD::EntryToken: // These leaves remain the same.\n"
|
||||
@ -2995,71 +3001,91 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
<< " case ISD::TargetConstant:\n"
|
||||
<< " case ISD::TargetConstantPool:\n"
|
||||
<< " case ISD::TargetFrameIndex:\n"
|
||||
<< " case ISD::TargetGlobalAddress:\n"
|
||||
<< " return N;\n"
|
||||
<< " case ISD::TargetGlobalAddress: {\n"
|
||||
<< " Result = N;\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " case ISD::AssertSext:\n"
|
||||
<< " case ISD::AssertZext: {\n"
|
||||
<< " SDOperand Tmp0 = Select(N.getOperand(0));\n"
|
||||
<< " SDOperand Tmp0;\n"
|
||||
<< " Select(Tmp0, N.getOperand(0));\n"
|
||||
<< " if (!N.Val->hasOneUse()) CodeGenMap[N] = Tmp0;\n"
|
||||
<< " return Tmp0;\n"
|
||||
<< " Result = Tmp0;\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " case ISD::TokenFactor:\n"
|
||||
<< " if (N.getNumOperands() == 2) {\n"
|
||||
<< " SDOperand Op0 = Select(N.getOperand(0));\n"
|
||||
<< " SDOperand Op1 = Select(N.getOperand(1));\n"
|
||||
<< " return CodeGenMap[N] =\n"
|
||||
<< " SDOperand Op0, Op1;\n"
|
||||
<< " Select(Op0, N.getOperand(0));\n"
|
||||
<< " Select(Op1, N.getOperand(1));\n"
|
||||
<< " Result = CodeGenMap[N] =\n"
|
||||
<< " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);\n"
|
||||
<< " } else {\n"
|
||||
<< " std::vector<SDOperand> Ops;\n"
|
||||
<< " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)\n"
|
||||
<< " Ops.push_back(Select(N.getOperand(i)));\n"
|
||||
<< " return CodeGenMap[N] = \n"
|
||||
<< " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n"
|
||||
<< " SDOperand Val;\n"
|
||||
<< " Select(Val, N.getOperand(i));\n"
|
||||
<< " Ops.push_back(Val);\n"
|
||||
<< " }\n"
|
||||
<< " Result = CodeGenMap[N] = \n"
|
||||
<< " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n"
|
||||
<< " }\n"
|
||||
<< " return;\n"
|
||||
<< " case ISD::CopyFromReg: {\n"
|
||||
<< " SDOperand Chain = Select(N.getOperand(0));\n"
|
||||
<< " SDOperand Chain;\n"
|
||||
<< " Select(Chain, N.getOperand(0));\n"
|
||||
<< " unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();\n"
|
||||
<< " MVT::ValueType VT = N.Val->getValueType(0);\n"
|
||||
<< " if (N.Val->getNumValues() == 2) {\n"
|
||||
<< " if (Chain == N.getOperand(0)) return N; // No change\n"
|
||||
<< " if (Chain == N.getOperand(0)) {\n"
|
||||
<< " Result = N; // No change\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT);\n"
|
||||
<< " CodeGenMap[N.getValue(0)] = New;\n"
|
||||
<< " CodeGenMap[N.getValue(1)] = New.getValue(1);\n"
|
||||
<< " return New.getValue(N.ResNo);\n"
|
||||
<< " Result = New.getValue(N.ResNo);\n"
|
||||
<< " return;\n"
|
||||
<< " } else {\n"
|
||||
<< " SDOperand Flag(0, 0);\n"
|
||||
<< " if (N.getNumOperands() == 3) Flag = Select(N.getOperand(2));\n"
|
||||
<< " SDOperand Flag;\n"
|
||||
<< " if (N.getNumOperands() == 3) Select(Flag, N.getOperand(2));\n"
|
||||
<< " if (Chain == N.getOperand(0) &&\n"
|
||||
<< " (N.getNumOperands() == 2 || Flag == N.getOperand(2)))\n"
|
||||
<< " return N; // No change\n"
|
||||
<< " (N.getNumOperands() == 2 || Flag == N.getOperand(2))) {\n"
|
||||
<< " Result = N; // No change\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " SDOperand New = CurDAG->getCopyFromReg(Chain, Reg, VT, Flag);\n"
|
||||
<< " CodeGenMap[N.getValue(0)] = New;\n"
|
||||
<< " CodeGenMap[N.getValue(1)] = New.getValue(1);\n"
|
||||
<< " CodeGenMap[N.getValue(2)] = New.getValue(2);\n"
|
||||
<< " return New.getValue(N.ResNo);\n"
|
||||
<< " Result = New.getValue(N.ResNo);\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " }\n"
|
||||
<< " case ISD::CopyToReg: {\n"
|
||||
<< " SDOperand Chain = Select(N.getOperand(0));\n"
|
||||
<< " SDOperand Chain;\n"
|
||||
<< " Select(Chain, N.getOperand(0));\n"
|
||||
<< " unsigned Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();\n"
|
||||
<< " SDOperand Val = Select(N.getOperand(2));\n"
|
||||
<< " SDOperand Result = N;\n"
|
||||
<< " SDOperand Val;\n"
|
||||
<< " Select(Val, N.getOperand(2));\n"
|
||||
<< " SDOperand ResNode = N;\n"
|
||||
<< " if (N.Val->getNumValues() == 1) {\n"
|
||||
<< " if (Chain != N.getOperand(0) || Val != N.getOperand(2))\n"
|
||||
<< " Result = CurDAG->getCopyToReg(Chain, Reg, Val);\n"
|
||||
<< " return CodeGenMap[N] = Result;\n"
|
||||
<< " ResNode = CurDAG->getCopyToReg(Chain, Reg, Val);\n"
|
||||
<< " Result = CodeGenMap[N] = ResNode;\n"
|
||||
<< " } else {\n"
|
||||
<< " SDOperand Flag(0, 0);\n"
|
||||
<< " if (N.getNumOperands() == 4) Flag = Select(N.getOperand(3));\n"
|
||||
<< " if (N.getNumOperands() == 4) Select(Flag, N.getOperand(3));\n"
|
||||
<< " if (Chain != N.getOperand(0) || Val != N.getOperand(2) ||\n"
|
||||
<< " (N.getNumOperands() == 4 && Flag != N.getOperand(3)))\n"
|
||||
<< " Result = CurDAG->getCopyToReg(Chain, Reg, Val, Flag);\n"
|
||||
<< " CodeGenMap[N.getValue(0)] = Result;\n"
|
||||
<< " CodeGenMap[N.getValue(1)] = Result.getValue(1);\n"
|
||||
<< " return Result.getValue(N.ResNo);\n"
|
||||
<< " ResNode = CurDAG->getCopyToReg(Chain, Reg, Val, Flag);\n"
|
||||
<< " CodeGenMap[N.getValue(0)] = ResNode;\n"
|
||||
<< " CodeGenMap[N.getValue(1)] = ResNode.getValue(1);\n"
|
||||
<< " Result = ResNode.getValue(N.ResNo);\n"
|
||||
<< " }\n"
|
||||
<< " return;\n"
|
||||
<< " }\n"
|
||||
<< " case ISD::INLINEASM: return Select_INLINEASM(N);\n";
|
||||
<< " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n";
|
||||
|
||||
|
||||
// Loop over all of the case statements, emiting a call to each method we
|
||||
@ -3070,7 +3096,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
|
||||
const SDNodeInfo &OpcodeInfo = getSDNodeInfo(PBOI->first);
|
||||
OS << " case " << OpcodeInfo.getEnumName() << ": "
|
||||
<< std::string(std::max(0, int(24-OpcodeInfo.getEnumName().size())), ' ')
|
||||
<< "return Select_" << PBOI->first->getName() << "(N);\n";
|
||||
<< "Select_" << PBOI->first->getName() << "(Result, N); return;\n";
|
||||
}
|
||||
|
||||
OS << " } // end of big switch.\n\n"
|
||||
@ -3151,7 +3177,9 @@ void DAGISelEmitter::run(std::ostream &OS) {
|
||||
<< "HandleMap.begin(),\n"
|
||||
<< " E = HandleMap.end(); I != E; ++I) {\n";
|
||||
OS << " SDOperand N = I->first;\n";
|
||||
OS << " AddHandleReplacement(N, Select(N.getValue(0)));\n";
|
||||
OS << " SDOperand R;\n";
|
||||
OS << " Select(R, N.getValue(0));\n";
|
||||
OS << " AddHandleReplacement(N, R);\n";
|
||||
OS << " }\n";
|
||||
OS << "}\n";
|
||||
OS << "\n";
|
||||
@ -3183,11 +3211,12 @@ void DAGISelEmitter::run(std::ostream &OS) {
|
||||
OS << "\n";
|
||||
OS << "// SelectRoot - Top level entry to DAG isel.\n";
|
||||
OS << "SDOperand SelectRoot(SDOperand N) {\n";
|
||||
OS << " SDOperand RetVal = Select(N);\n";
|
||||
OS << " SDOperand ResNode;\n";
|
||||
OS << " Select(ResNode, N);\n";
|
||||
OS << " SelectDanglingHandles();\n";
|
||||
OS << " ReplaceHandles();\n";
|
||||
OS << " ReplaceMap.clear();\n";
|
||||
OS << " return RetVal;\n";
|
||||
OS << " return ResNode;\n";
|
||||
OS << "}\n";
|
||||
|
||||
ParseNodeInfo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user