assert(N->getValueType(0) == MVT::i32 &&
N->getOperand(0).getValueType() == MVT::i64 &&
"TRUNCATE only supported for i64 -> i32");
- // FIXME: this code breaks ScheduleDAG since Op0 is an i64 and OR4
- // takes i32s.
SDOperand Op0 = Select(N->getOperand(0));
- CurDAG->SelectNodeTo(N, PPC::OR4, MVT::i32, Op0, Op0);
+ CurDAG->SelectNodeTo(N, PPC::OR8To4, MVT::i32, Op0, Op0);
break;
}
case ISD::ANY_EXTEND:
switch(N->getValueType(0)) {
default: assert(0 && "Unhandled type in ANY_EXTEND");
case MVT::i64: {
- // FIXME: this code breaks ScheduleDAG since Op0 is an i32 and OR8
- // takes i64s.
SDOperand Op0 = Select(N->getOperand(0));
- CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Op0, Op0);
+ CurDAG->SelectNodeTo(N, PPC::OR4To8, MVT::i64, Op0, Op0);
break;
}
}
return SDOperand(N, 0);
- case ISD::ZERO_EXTEND:
+ case ISD::ZERO_EXTEND: {
assert(N->getValueType(0) == MVT::i64 &&
N->getOperand(0).getValueType() == MVT::i32 &&
"ZERO_EXTEND only supported for i32 -> i64");
- CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
+ SDOperand Op0 = Select(N->getOperand(0));
+ Op0 = CurDAG->getTargetNode(PPC::OR4To8, MVT::i64, Op0, Op0);
+ CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Op0, getI32Imm(0),
getI32Imm(32));
return SDOperand(N, 0);
+ }
case ISD::SHL: {
unsigned Imm, SH, MB, ME;
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
Select(N->getOperand(0).getOperand(0)),
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
- else if (isIntImmediate(N->getOperand(1), Imm))
- CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
- getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm));
- else
- CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)),
- Select(N->getOperand(1)));
+ else if (isIntImmediate(N->getOperand(1), Imm)) {
+ if (N->getValueType(0) == MVT::i64)
+ CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Select(N->getOperand(0)),
+ getI32Imm(Imm), getI32Imm(63-Imm));
+ else
+ CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
+ getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm));
+ } else {
+ if (N->getValueType(0) == MVT::i64)
+ CurDAG->SelectNodeTo(N, PPC::SLD, MVT::i64, Select(N->getOperand(0)),
+ Select(N->getOperand(1)));
+ else
+ CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)),
+ Select(N->getOperand(1)));
+ }
return SDOperand(N, 0);
}
case ISD::SRL: {
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
Select(N->getOperand(0).getOperand(0)),
getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME));
- else if (isIntImmediate(N->getOperand(1), Imm))
- CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
- getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
- getI32Imm(31));
- else
- CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
- Select(N->getOperand(1)));
+ else if (isIntImmediate(N->getOperand(1), Imm)) {
+ if (N->getValueType(0) == MVT::i64)
+ CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
+ getI32Imm(64-Imm), getI32Imm(Imm));
+ else
+ CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
+ getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
+ getI32Imm(31));
+ } else {
+ if (N->getValueType(0) == MVT::i64)
+ CurDAG->SelectNodeTo(N, PPC::SRD, MVT::i64, Select(N->getOperand(0)),
+ Select(N->getOperand(1)));
+ else
+ CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
+ Select(N->getOperand(1)));
+ }
return SDOperand(N, 0);
}
case ISD::FNEG: {
//===----------------------------------------------------------------------===//
// PowerPC specific transformation functions and pattern fragments.
//
+def GET_ZERO : SDNodeXForm<imm, [{
+ // Transformation function: get the low 16 bits.
+ return getI32Imm(0);
+}]>;
+def GET_32 : SDNodeXForm<imm, [{
+ // Transformation function: get the low 16 bits.
+ return getI32Imm(32);
+}]>;
+
def LO16 : SDNodeXForm<imm, [{
// Transformation function: get the low 16 bits.
return getI32Imm((unsigned short)N->getValue());
def OR8 : XForm_6<31, 444, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
"or $rA, $rS, $rB",
[(set G8RC:$rA, (or G8RC:$rS, G8RC:$rB))]>;
+def OR4To8 : XForm_6<31, 444, (ops G8RC:$rA, GPRC:$rS, GPRC:$rB),
+ "or $rA, $rS, $rB",
+ []>;
+def OR8To4 : XForm_6<31, 444, (ops GPRC:$rA, G8RC:$rS, G8RC:$rB),
+ "or $rA, $rS, $rB",
+ []>;
def NOR : XForm_6<31, 124, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
"nor $rA, $rS, $rB",
[(set GPRC:$rA, (not (or GPRC:$rS, GPRC:$rB)))]>;
// XOR an arbitrary immediate.
def : Pat<(xor GPRC:$in, imm:$imm),
(XORIS (XORI GPRC:$in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
-
-
+
// Same as above, but using a temporary. FIXME: implement temporaries :)
/*
def : Pattern<(xor GPRC:$in, imm:$imm),