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

Support shr long/ulong.

llvm-svn: 18173
This commit is contained in:
Brian Gaeke 2004-11-23 21:10:50 +00:00
parent 29093f7ec7
commit ce245ef743

View File

@ -1119,58 +1119,124 @@ void V8ISel::emitShift64 (MachineBasicBlock *MBB,
bool isSigned = I.getType()->isSigned();
switch (I.getOpcode ()) {
case Instruction::Shr: {
unsigned CarryReg = makeAnotherReg (Type::IntTy),
ThirtyTwo = makeAnotherReg (Type::IntTy),
HalfShiftReg = makeAnotherReg (Type::IntTy),
NegHalfShiftReg = makeAnotherReg (Type::IntTy),
TempReg = makeAnotherReg (Type::IntTy);
unsigned OneShiftOutReg = makeAnotherReg (Type::ULongTy),
TwoShiftsOutReg = makeAnotherReg (Type::ULongTy);
MachineBasicBlock *thisMBB = BB;
const BasicBlock *LLVM_BB = BB->getBasicBlock ();
MachineBasicBlock *shiftMBB = new MachineBasicBlock (LLVM_BB);
F->getBasicBlockList ().push_back (shiftMBB);
MachineBasicBlock *oneShiftMBB = new MachineBasicBlock (LLVM_BB);
F->getBasicBlockList ().push_back (oneShiftMBB);
MachineBasicBlock *twoShiftsMBB = new MachineBasicBlock (LLVM_BB);
F->getBasicBlockList ().push_back (twoShiftsMBB);
MachineBasicBlock *continueMBB = new MachineBasicBlock (LLVM_BB);
F->getBasicBlockList ().push_back (continueMBB);
// .lshr_begin:
// ...
// subcc %g0, ShiftAmtReg, %g0 ! Is ShAmt == 0?
// be .lshr_continue ! Then don't shift.
// ba .lshr_shift ! else shift.
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0)
.addReg (ShiftAmtReg);
BuildMI (BB, V8::BE, 1).addMBB (continueMBB);
BuildMI (BB, V8::BA, 1).addMBB (shiftMBB);
// Update machine-CFG edges
BB->addSuccessor (continueMBB);
BB->addSuccessor (shiftMBB);
// .lshr_shift: ! [preds: begin]
// or %g0, 32, ThirtyTwo
// subcc ThirtyTwo, ShiftAmtReg, HalfShiftReg ! Calculate 32 - shamt
// bg .lshr_two_shifts ! If >0, b two_shifts
// ba .lshr_one_shift ! else one_shift.
BB = shiftMBB;
BuildMI (BB, V8::ORri, 2, ThirtyTwo).addReg (V8::G0).addSImm (32);
BuildMI (BB, V8::SUBCCrr, 2, HalfShiftReg).addReg (ThirtyTwo)
.addReg (ShiftAmtReg);
BuildMI (BB, V8::BG, 1).addMBB (twoShiftsMBB);
BuildMI (BB, V8::BA, 1).addMBB (oneShiftMBB);
// Update machine-CFG edges
BB->addSuccessor (twoShiftsMBB);
BB->addSuccessor (oneShiftMBB);
// .lshr_two_shifts: ! [preds: shift]
// sll SrcReg, HalfShiftReg, CarryReg ! Save the borrows
// ! <SHIFT> in following is sra if signed, srl if unsigned
// <SHIFT> SrcReg, ShiftAmtReg, TwoShiftsOutReg ! Shift top half
// srl SrcReg+1, ShiftAmtReg, TempReg ! Shift bottom half
// or TempReg, CarryReg, TwoShiftsOutReg+1 ! Restore the borrows
// ba .lshr_continue
unsigned ShiftOpcode = (isSigned ? V8::SRArr : V8::SRLrr);
BB = twoShiftsMBB;
BuildMI (BB, V8::SLLrr, 2, CarryReg).addReg (SrcReg)
.addReg (HalfShiftReg);
BuildMI (BB, ShiftOpcode, 2, TwoShiftsOutReg).addReg (SrcReg)
.addReg (ShiftAmtReg);
BuildMI (BB, V8::SRLrr, 2, TempReg).addReg (SrcReg+1)
.addReg (ShiftAmtReg);
BuildMI (BB, V8::ORrr, 2, TwoShiftsOutReg+1).addReg (TempReg)
.addReg (CarryReg);
BuildMI (BB, V8::BA, 1).addMBB (continueMBB);
// Update machine-CFG edges
BB->addSuccessor (continueMBB);
// .lshr_one_shift: ! [preds: shift]
// ! if unsigned:
// or %g0, %g0, OneShiftOutReg ! Zero top half
// ! or, if signed:
// sra SrcReg, 31, OneShiftOutReg ! Sign-ext top half
// sub %g0, HalfShiftReg, NegHalfShiftReg ! Make ShiftAmt >0
// <SHIFT> SrcReg, NegHalfShiftReg, OneShiftOutReg+1 ! Shift bottom half
// ba .lshr_continue
BB = oneShiftMBB;
if (isSigned)
BuildMI (BB, V8::SRAri, 2, OneShiftOutReg).addReg (SrcReg).addZImm (31);
else
BuildMI (BB, V8::ORrr, 2, OneShiftOutReg).addReg (V8::G0)
.addReg (V8::G0);
BuildMI (BB, V8::SUBrr, 2, NegHalfShiftReg).addReg (V8::G0)
.addReg (HalfShiftReg);
BuildMI (BB, ShiftOpcode, 2, OneShiftOutReg+1).addReg (SrcReg)
.addReg (NegHalfShiftReg);
BuildMI (BB, V8::BA, 1).addMBB (continueMBB);
// Update machine-CFG edges
BB->addSuccessor (continueMBB);
// .lshr_continue: ! [preds: begin, do_one_shift, do_two_shifts]
// phi (SrcReg, begin), (TwoShiftsOutReg, two_shifts),
// (OneShiftOutReg, one_shift), DestReg ! Phi top half...
// phi (SrcReg+1, begin), (TwoShiftsOutReg+1, two_shifts),
// (OneShiftOutReg+1, one_shift), DestReg+1 ! And phi bottom half.
BB = continueMBB;
BuildMI (BB, V8::PHI, 6, DestReg).addReg (SrcReg).addMBB (thisMBB)
.addReg (TwoShiftsOutReg).addMBB (twoShiftsMBB)
.addReg (OneShiftOutReg).addMBB (oneShiftMBB);
BuildMI (BB, V8::PHI, 6, DestReg+1).addReg (SrcReg+1).addMBB (thisMBB)
.addReg (TwoShiftsOutReg+1).addMBB (twoShiftsMBB)
.addReg (OneShiftOutReg+1).addMBB (oneShiftMBB);
return;
}
case Instruction::Shl:
case Instruction::Shr:
if (!isSigned) {
unsigned CarryReg = makeAnotherReg (Type::IntTy),
ThirtyTwo = makeAnotherReg (Type::IntTy),
HalfShiftReg = makeAnotherReg (Type::IntTy),
NegHalfShiftReg = makeAnotherReg (Type::IntTy),
TempReg = makeAnotherReg (Type::IntTy);
unsigned OneShiftOutReg = makeAnotherReg (Type::ULongTy),
TwoShiftsOutReg = makeAnotherReg (Type::ULongTy);
/*
.lshr_begin:
...
// Check whether the shift amount is zero:
V8::G0 = V8::SUBCCrr V8::G0, ShiftAmountReg
V8::BE .lshr_continue
V8::BA .lshr_shift
.lshr_shift: // [preds: begin]
// Calculate 32 - shamt:
ThirtyTwo = V8::ORri V8::G0, 32
HalfShiftReg = V8::SUBCCrr ThirtyTwo, ShiftAmountReg
// See whether it was greater than 0:
V8::BG .lshr_two_shifts
V8::BA .lshr_one_shift
.lshr_two_shifts: // [preds: shift]
CarryReg = V8::SLLrr SrcReg, HalfShiftReg
TwoShiftsOutReg = V8::SRLrr SrcReg, ShiftAmountReg
TempReg = V8::SRLrr SrcReg+1, ShiftAmountReg
TwoShiftsOutReg+1 = V8::ORrr TempReg, CarryReg
V8::BA .lshr_continue
.lshr_one_shift: // [preds: shift]
OneShiftOutReg = V8::ORrr V8::G0, V8::G0
NegHalfShiftReg = V8::SUBrr V8::G0, HalfShiftReg
OneShiftOutReg+1 = V8::SRLrr SrcReg, NegHalfShiftReg
V8::BA .lshr_continue
.lshr_continue: // [preds: begin, do_one_shift, do_two_shifts]
DestReg = V8::PHI (SrcReg, begin), (TwoShiftsOutReg, two_shifts),
(OneShiftOutReg, one_shift)
DestReg+1 = V8::PHI (SrcReg+1, begin), (TwoShiftsOutReg+1, two_shifts),
(OneShiftOutReg+1, one_shift)
...
*/
std::cerr << "Sorry, 64-bit lshr is not yet supported:\n" << I;
abort ();
return;
}
default:
std::cerr << "Sorry, 64-bit shifts are not yet supported:\n" << I;
abort ();