X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV8%2FSparcV8ISelSimple.cpp;h=ac33ef574b8ff7a40efda02c0fd02e0a440ea0e2;hb=5b5708106e409d2b8bb23335f7de8dda361dca3e;hp=5cf9131b1ef284831bf481b37e38bde25ec35d5d;hpb=38343f6cfe505139118efa65b2ecabb7b5a59ff1;p=oota-llvm.git diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp index 5cf9131b1ef..ac33ef574b8 100644 --- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -232,8 +232,8 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB, // Copy the value into the register pair. // R = top(more-significant) half, R+1 = bottom(less-significant) half uint64_t Val = cast(C)->getRawValue(); - unsigned topHalf = Val & 0xffffffffU; - unsigned bottomHalf = Val >> 32; + unsigned bottomHalf = Val & 0xffffffffU; + unsigned topHalf = Val >> 32; unsigned HH = topHalf >> 10; unsigned HM = topHalf & 0x03ff; unsigned LM = bottomHalf >> 10; @@ -288,28 +288,47 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB, } else if (isa(C)) { // Copy zero (null pointer) to the register. BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm (0); - } else if (ConstantPointerRef *CPR = dyn_cast(C)) { + } else if (GlobalValue *GV = dyn_cast(C)) { // Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize // that SETHI %reg,global == SETHI %reg,%hi(global) and // OR %reg,global,%reg == OR %reg,%lo(global),%reg. unsigned TmpReg = makeAnotherReg (C->getType ()); - BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress (CPR->getValue()); - BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg) - .addGlobalAddress (CPR->getValue ()); + BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress(GV); + BuildMI (*MBB, IP, V8::ORri, 2, R).addReg(TmpReg).addGlobalAddress(GV); } else { std::cerr << "Offending constant: " << *C << "\n"; assert (0 && "Can't copy this kind of constant into register yet"); } } -void V8ISel::LoadArgumentsToVirtualRegs (Function *F) { - unsigned ArgOffset = 0; +void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) { + unsigned ArgOffset; static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 }; - assert (F->asize () < 7 + assert (LF->asize () < 7 && "Can't handle loading excess call args off the stack yet"); - for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I) { + // Add IMPLICIT_DEFs of input regs. + ArgOffset = 0; + for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) { + unsigned Reg = getReg(*I); + switch (getClassB(I->getType())) { + case cByte: + case cShort: + case cInt: + case cFloat: + BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgOffset]); + break; + default: + // FIXME: handle cDouble, cLong + assert (0 && "64-bit (double, long, etc.) function args not handled"); + return; + } + ++ArgOffset; + } + + ArgOffset = 0; + for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) { unsigned Reg = getReg(*I); switch (getClassB(I->getType())) { case cByte: @@ -318,12 +337,24 @@ void V8ISel::LoadArgumentsToVirtualRegs (Function *F) { BuildMI(BB, V8::ORrr, 2, Reg).addReg (V8::G0) .addReg (IncomingArgRegs[ArgOffset]); break; + case cFloat: { + // Single-fp args are passed in integer registers; go through + // memory to get them into FP registers. (Bleh!) + unsigned FltAlign = TM.getTargetData().getFloatAlignment(); + int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign); + BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0) + .addReg (IncomingArgRegs[ArgOffset]); + BuildMI (BB, V8::LDFri, 2, Reg).addFrameIndex (FI).addSImm (0); + break; + } default: - assert (0 && "Only <=32-bit, integral arguments currently handled"); + // FIXME: handle cDouble, cLong + assert (0 && "64-bit (double, long, etc.) function args not handled"); return; } ++ArgOffset; } + } void V8ISel::SelectPHINodes() { @@ -565,6 +596,17 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; } } + } else if (newTyClass == cLong) { + if (oldTyClass == cLong) { + // Just copy it + BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); + BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0) + .addReg (SrcReg+1); + } else { + std::cerr << "Cast still unsupported: SrcTy = " + << *SrcTy << ", DestTy = " << *DestTy << "\n"; + abort (); + } } else { std::cerr << "Cast still unsupported: SrcTy = " << *SrcTy << ", DestTy = " << *DestTy << "\n"; @@ -657,12 +699,23 @@ void V8ISel::visitCallInst(CallInst &I) { V8::O4, V8::O5 }; for (unsigned i = 1; i < 7; ++i) if (i < I.getNumOperands ()) { - assert (getClassB (I.getOperand (i)->getType ()) < cLong - && "Can't handle long or fp function call arguments yet"); unsigned ArgReg = getReg (I.getOperand (i)); - // Schlep it over into the incoming arg register - BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0) - .addReg (ArgReg); + if (getClassB (I.getOperand (i)->getType ()) < cLong) { + // Schlep it over into the incoming arg register + BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0) + .addReg (ArgReg); + } else if (getClassB (I.getOperand (i)->getType ()) == cFloat) { + // Single-fp args are passed in integer registers; go through + // memory to get them out of FP registers. (Bleh!) + unsigned FltAlign = TM.getTargetData().getFloatAlignment(); + int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign); + BuildMI (BB, V8::STFri, 3).addFrameIndex (FI).addSImm (0) + .addReg (ArgReg); + BuildMI (BB, V8::LD, 2, OutgoingArgRegs[i - 1]).addFrameIndex (FI) + .addSImm (0); + } else { + assert (0 && "64-bit (double, long, etc.) 'call' opnds not handled"); + } } // Emit call instruction @@ -702,6 +755,21 @@ void V8ISel::visitReturnInst(ReturnInst &I) { // Schlep it over into i0 (where it will become o0 after restore). BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg); break; + case cFloat: + BuildMI (BB, V8::FMOVS, 2, V8::F0).addReg(RetValReg); + break; + case cDouble: { + unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment(); + int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment); + BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0) + .addReg (RetValReg); + BuildMI (BB, V8::LDDFri, 2, V8::F0).addFrameIndex (FI).addSImm (0); + break; + } + case cLong: + BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg); + BuildMI (BB, V8::ORrr, 2, V8::I1).addReg(V8::G0).addReg(RetValReg+1); + break; default: std::cerr << "Return instruction of this type not handled: " << I; abort (); @@ -886,7 +954,7 @@ void V8ISel::visitBinaryOperator (Instruction &I) { BuildMI (BB, Opcodes[OpCase], 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg); } - switch (getClass (I.getType ())) { + switch (getClassB (I.getType ())) { case cByte: if (I.getType ()->isSigned ()) { // add byte BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff); @@ -908,7 +976,7 @@ void V8ISel::visitBinaryOperator (Instruction &I) { } break; case cInt: - // Nothing todo here. + // Nothing to do here. break; case cLong: // Only support and, or, xor. @@ -931,9 +999,15 @@ void V8ISel::visitSetCondInst(SetCondInst &I) { unsigned DestReg = getReg (I); const Type *Ty = I.getOperand (0)->getType (); - assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet"); // Compare the two values. - BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg); + assert (getClass (Ty) != cLong && "can't setcc on longs yet"); + if (getClass (Ty) < cLong) { + BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg); + } else if (getClass (Ty) == cFloat) { + BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg); + } else if (getClass (Ty) == cDouble) { + BuildMI(BB, V8::FCMPD, 2).addReg(Op0Reg).addReg(Op1Reg); + } unsigned BranchIdx; switch (I.getOpcode()) { @@ -945,17 +1019,20 @@ void V8ISel::visitSetCondInst(SetCondInst &I) { case Instruction::SetLE: BranchIdx = 4; break; case Instruction::SetGE: BranchIdx = 5; break; } - static unsigned OpcodeTab[12] = { - // LLVM SparcV8 - // unsigned signed - V8::BE, V8::BE, // seteq = be be - V8::BNE, V8::BNE, // setne = bne bne - V8::BCS, V8::BL, // setlt = bcs bl - V8::BGU, V8::BG, // setgt = bgu bg - V8::BLEU, V8::BLE, // setle = bleu ble - V8::BCC, V8::BGE // setge = bcc bge + unsigned Column = 0; + if (Ty->isSigned()) ++Column; + if (Ty->isFloatingPoint()) ++Column; + static unsigned OpcodeTab[3*6] = { + // LLVM SparcV8 + // unsigned signed fp + V8::BE, V8::BE, V8::FBE, // seteq = be be fbe + V8::BNE, V8::BNE, V8::FBNE, // setne = bne bne fbne + V8::BCS, V8::BL, V8::FBL, // setlt = bcs bl fbl + V8::BGU, V8::BG, V8::FBG, // setgt = bgu bg fbg + V8::BLEU, V8::BLE, V8::FBLE, // setle = bleu ble fble + V8::BCC, V8::BGE, V8::FBGE // setge = bcc bge fbge }; - unsigned Opcode = OpcodeTab[2*BranchIdx + (Ty->isSigned() ? 1 : 0)]; + unsigned Opcode = OpcodeTab[3*BranchIdx + Column]; MachineBasicBlock *thisMBB = BB; const BasicBlock *LLVM_BB = BB->getBasicBlock ();