diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 754809303112..39f380acfae0 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -219,6 +219,11 @@ static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { // and mask opcode and mask operation. static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask, unsigned &SH, unsigned &MB, unsigned &ME) { + // Don't even go down this path for i64, since different logic will be + // necessary for rldicl/rldicr/rldimi. + if (N->getValueType(0) != MVT::i32) + return false; + unsigned Shift = 32; unsigned Indeterminant = ~0; // bit mask marking indeterminant results unsigned Opcode = N->getOpcode(); @@ -1206,14 +1211,27 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) { // Other cases are autogenerated. break; + case ISD::TRUNCATE: { + 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); + break; + } case ISD::ANY_EXTEND: switch(N->getValueType(0)) { default: assert(0 && "Unhandled type in ANY_EXTEND"); - case MVT::i64: - CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Select(N->getOperand(0)), - Select(N->getOperand(0))); + 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); break; } + } return SDOperand(N, 0); case ISD::ZERO_EXTEND: assert(N->getValueType(0) == MVT::i64 && diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index ad4444bc02cc..7cd35344ede1 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -703,7 +703,6 @@ 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), diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td index 5cecf50f5603..bbc6a4c0bcff 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td @@ -21,6 +21,12 @@ class GPR num, string n> : PPCReg { field bits<5> Num = num; } +// GP8 - One of the 32 64-bit general-purpose registers +class GP8 num, string n, Register Alias> : PPCReg { + field bits<5> Num = num; + let Aliases = [Alias]; +} + // SPR - One of the 32-bit special-purpose registers class SPR num, string n> : PPCReg { field bits<5> Num = num; @@ -54,6 +60,24 @@ def R26 : GPR<26, "r26">; def R27 : GPR<27, "r27">; def R28 : GPR<28, "r28">; def R29 : GPR<29, "r29">; def R30 : GPR<30, "r30">; def R31 : GPR<31, "r31">; +// 64-bit General-purpose registers +def X0 : GP8< 0, "r0", R0>; def X1 : GP8< 1, "r1", R1>; +def X2 : GP8< 2, "r2", R2>; def X3 : GP8< 3, "r3", R3>; +def X4 : GP8< 4, "r4", R4>; def X5 : GP8< 5, "r5", R5>; +def X6 : GP8< 6, "r6", R6>; def X7 : GP8< 7, "r7", R7>; +def X8 : GP8< 8, "r8", R8>; def X9 : GP8< 9, "r9", R9>; +def X10 : GP8<10, "r10", R10>; def X11 : GP8<11, "r11", R11>; +def X12 : GP8<12, "r12", R12>; def X13 : GP8<13, "r13", R13>; +def X14 : GP8<14, "r14", R14>; def X15 : GP8<15, "r15", R15>; +def X16 : GP8<16, "r16", R16>; def X17 : GP8<17, "r17", R17>; +def X18 : GP8<18, "r18", R18>; def X19 : GP8<19, "r19", R19>; +def X20 : GP8<20, "r20", R20>; def X21 : GP8<21, "r21", R21>; +def X22 : GP8<22, "r22", R22>; def X23 : GP8<23, "r23", R23>; +def X24 : GP8<24, "r24", R24>; def X25 : GP8<25, "r25", R25>; +def X26 : GP8<26, "r26", R26>; def X27 : GP8<27, "r27", R27>; +def X28 : GP8<28, "r28", R28>; def X29 : GP8<29, "r29", R29>; +def X30 : GP8<30, "r30", R30>; def X31 : GP8<31, "r31", R31>; + // Floating-point registers def F0 : FPR< 0, "f0">; def F1 : FPR< 1, "f1">; def F2 : FPR< 2, "f2">; def F3 : FPR< 3, "f3">; @@ -111,9 +135,9 @@ def GPRC : RegisterClass<"PPC", i32, 32, }]; } def G8RC : RegisterClass<"PPC", i64, 64, - [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, - R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, - R16, R15, R14, R13, R31, R0, R1, LR]> + [X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, + X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, + X16, X15, X14, X13, X31, X0, X1]> { let MethodProtos = [{ iterator allocation_order_begin(MachineFunction &MF) const; @@ -127,9 +151,9 @@ def G8RC : RegisterClass<"PPC", i64, 64, G8RCClass::iterator G8RCClass::allocation_order_end(MachineFunction &MF) const { if (hasFP(MF)) - return end()-4; - else return end()-3; + else + return end()-2; } }]; }