From: Brian Gaeke Date: Fri, 18 Jun 2004 06:27:48 +0000 (+0000) Subject: Support intrinsic calls (although no particular intrinsics are supported yet). X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9d67ea0b611e39e3e58e98222c0dcc51cee412d7;p=oota-llvm.git Support intrinsic calls (although no particular intrinsics are supported yet). Support indirect calls. Support returning a float value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14223 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp index 43e2eade0e3..e86e25b9cfe 100644 --- a/lib/Target/Sparc/InstSelectSimple.cpp +++ b/lib/Target/Sparc/InstSelectSimple.cpp @@ -554,6 +554,16 @@ void V8ISel::visitStoreInst(StoreInst &I) { } void V8ISel::visitCallInst(CallInst &I) { + MachineInstr *TheCall; + // Is it an intrinsic function call? + if (Function *F = I.getCalledFunction()) { + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { + visitIntrinsicCall(ID, I); // Special intrinsics are not handled here + return; + } + } + + // Deal with args assert (I.getNumOperands () < 8 && "Can't handle pushing excess call args on the stack yet"); static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3, @@ -566,19 +576,27 @@ void V8ISel::visitCallInst(CallInst &I) { .addReg (ArgReg); } - assert (I.getCalledFunction() && "don't know what to do with NULL function!"); - BuildMI (BB, V8::CALL, 1).addGlobalAddress(I.getCalledFunction (), true); + // Emit call instruction + if (Function *F = I.getCalledFunction ()) { + BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true); + } else { // Emit an indirect call... + unsigned Reg = getReg (I.getCalledValue ()); + BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0); + } + + // Deal w/ return value: schlep it over into the destination register if (I.getType () == Type::VoidTy) return; unsigned DestReg = getReg (I); - // Deal w/ return value switch (getClass (I.getType ())) { case cByte: case cShort: case cInt: - // Schlep it over into the destination register BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0); break; + case cFloat: + BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0); + break; default: std::cerr << "Return type of call instruction not handled: " << I; abort (); diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp index 43e2eade0e3..e86e25b9cfe 100644 --- a/lib/Target/Sparc/SparcV8ISelSimple.cpp +++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp @@ -554,6 +554,16 @@ void V8ISel::visitStoreInst(StoreInst &I) { } void V8ISel::visitCallInst(CallInst &I) { + MachineInstr *TheCall; + // Is it an intrinsic function call? + if (Function *F = I.getCalledFunction()) { + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { + visitIntrinsicCall(ID, I); // Special intrinsics are not handled here + return; + } + } + + // Deal with args assert (I.getNumOperands () < 8 && "Can't handle pushing excess call args on the stack yet"); static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3, @@ -566,19 +576,27 @@ void V8ISel::visitCallInst(CallInst &I) { .addReg (ArgReg); } - assert (I.getCalledFunction() && "don't know what to do with NULL function!"); - BuildMI (BB, V8::CALL, 1).addGlobalAddress(I.getCalledFunction (), true); + // Emit call instruction + if (Function *F = I.getCalledFunction ()) { + BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true); + } else { // Emit an indirect call... + unsigned Reg = getReg (I.getCalledValue ()); + BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0); + } + + // Deal w/ return value: schlep it over into the destination register if (I.getType () == Type::VoidTy) return; unsigned DestReg = getReg (I); - // Deal w/ return value switch (getClass (I.getType ())) { case cByte: case cShort: case cInt: - // Schlep it over into the destination register BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0); break; + case cFloat: + BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0); + break; default: std::cerr << "Return type of call instruction not handled: " << I; abort (); diff --git a/lib/Target/SparcV8/InstSelectSimple.cpp b/lib/Target/SparcV8/InstSelectSimple.cpp index 43e2eade0e3..e86e25b9cfe 100644 --- a/lib/Target/SparcV8/InstSelectSimple.cpp +++ b/lib/Target/SparcV8/InstSelectSimple.cpp @@ -554,6 +554,16 @@ void V8ISel::visitStoreInst(StoreInst &I) { } void V8ISel::visitCallInst(CallInst &I) { + MachineInstr *TheCall; + // Is it an intrinsic function call? + if (Function *F = I.getCalledFunction()) { + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { + visitIntrinsicCall(ID, I); // Special intrinsics are not handled here + return; + } + } + + // Deal with args assert (I.getNumOperands () < 8 && "Can't handle pushing excess call args on the stack yet"); static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3, @@ -566,19 +576,27 @@ void V8ISel::visitCallInst(CallInst &I) { .addReg (ArgReg); } - assert (I.getCalledFunction() && "don't know what to do with NULL function!"); - BuildMI (BB, V8::CALL, 1).addGlobalAddress(I.getCalledFunction (), true); + // Emit call instruction + if (Function *F = I.getCalledFunction ()) { + BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true); + } else { // Emit an indirect call... + unsigned Reg = getReg (I.getCalledValue ()); + BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0); + } + + // Deal w/ return value: schlep it over into the destination register if (I.getType () == Type::VoidTy) return; unsigned DestReg = getReg (I); - // Deal w/ return value switch (getClass (I.getType ())) { case cByte: case cShort: case cInt: - // Schlep it over into the destination register BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0); break; + case cFloat: + BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0); + break; default: std::cerr << "Return type of call instruction not handled: " << I; abort (); diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp index 43e2eade0e3..e86e25b9cfe 100644 --- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -554,6 +554,16 @@ void V8ISel::visitStoreInst(StoreInst &I) { } void V8ISel::visitCallInst(CallInst &I) { + MachineInstr *TheCall; + // Is it an intrinsic function call? + if (Function *F = I.getCalledFunction()) { + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { + visitIntrinsicCall(ID, I); // Special intrinsics are not handled here + return; + } + } + + // Deal with args assert (I.getNumOperands () < 8 && "Can't handle pushing excess call args on the stack yet"); static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3, @@ -566,19 +576,27 @@ void V8ISel::visitCallInst(CallInst &I) { .addReg (ArgReg); } - assert (I.getCalledFunction() && "don't know what to do with NULL function!"); - BuildMI (BB, V8::CALL, 1).addGlobalAddress(I.getCalledFunction (), true); + // Emit call instruction + if (Function *F = I.getCalledFunction ()) { + BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true); + } else { // Emit an indirect call... + unsigned Reg = getReg (I.getCalledValue ()); + BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0); + } + + // Deal w/ return value: schlep it over into the destination register if (I.getType () == Type::VoidTy) return; unsigned DestReg = getReg (I); - // Deal w/ return value switch (getClass (I.getType ())) { case cByte: case cShort: case cInt: - // Schlep it over into the destination register BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0); break; + case cFloat: + BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0); + break; default: std::cerr << "Return type of call instruction not handled: " << I; abort ();