From 738150636824f495fd1961763ada52f44223bad0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 18 Oct 2003 05:56:40 +0000 Subject: Add support for the new varargs intrinsics git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9224 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/InstSelectSimple.cpp | 62 +++++++++++++++++++++---------------- lib/Target/X86/X86ISelSimple.cpp | 62 +++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 52 deletions(-) (limited to 'lib') diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index a6dc7c9fb4..f9b949811b 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -173,7 +173,8 @@ namespace { void visitShiftInst(ShiftInst &I); void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass void visitCastInst(CastInst &I); - void visitVarArgInst(VarArgInst &I); + void visitVANextInst(VANextInst &I); + void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "Cannot instruction select: " << I; @@ -1000,18 +1001,16 @@ void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) { switch (ID) { case LLVMIntrinsic::va_start: // Get the address of the first vararg value... - TmpReg1 = makeAnotherReg(Type::UIntTy); + TmpReg1 = getReg(CI); addFrameReference(BuildMI(BB, X86::LEAr32, 5, TmpReg1), VarArgsFrameIndex); - TmpReg2 = getReg(CI.getOperand(1)); - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1); return; - case LLVMIntrinsic::va_end: return; // Noop on X86 case LLVMIntrinsic::va_copy: - TmpReg1 = getReg(CI.getOperand(2)); // Get existing va_list - TmpReg2 = getReg(CI.getOperand(1)); // Get va_list* to store into - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1); + TmpReg1 = getReg(CI); + TmpReg2 = getReg(CI.getOperand(1)); + BuildMI(BB, X86::MOVrr32, 1, TmpReg1).addReg(TmpReg2); return; + case LLVMIntrinsic::va_end: return; // Noop on X86 case LLVMIntrinsic::longjmp: case LLVMIntrinsic::siglongjmp: @@ -1884,46 +1883,57 @@ void ISel::emitCastOperation(MachineBasicBlock *BB, abort(); } -/// visitVarArgInst - Implement the va_arg instruction... +/// visitVANextInst - Implement the va_next instruction... /// -void ISel::visitVarArgInst(VarArgInst &I) { - unsigned SrcReg = getReg(I.getOperand(0)); +void ISel::visitVANextInst(VANextInst &I) { + unsigned VAList = getReg(I.getOperand(0)); unsigned DestReg = getReg(I); - // Load the va_list into a register... - unsigned VAList = makeAnotherReg(Type::UIntTy); - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, VAList), SrcReg); - unsigned Size; - switch (I.getType()->getPrimitiveID()) { + switch (I.getArgType()->getPrimitiveID()) { default: std::cerr << I; - assert(0 && "Error: bad type for va_arg instruction!"); + assert(0 && "Error: bad type for va_next instruction!"); return; case Type::PointerTyID: case Type::UIntTyID: case Type::IntTyID: Size = 4; - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); break; case Type::ULongTyID: case Type::LongTyID: + case Type::DoubleTyID: Size = 8; + break; + } + + // Increment the VAList pointer... + BuildMI(BB, X86::ADDri32, 2, DestReg).addReg(VAList).addZImm(Size); +} + +void ISel::visitVAArgInst(VAArgInst &I) { + unsigned VAList = getReg(I.getOperand(0)); + unsigned DestReg = getReg(I); + + switch (I.getType()->getPrimitiveID()) { + default: + std::cerr << I; + assert(0 && "Error: bad type for va_next instruction!"); + return; + case Type::PointerTyID: + case Type::UIntTyID: + case Type::IntTyID: + addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); + break; + case Type::ULongTyID: + case Type::LongTyID: addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), VAList, 4); break; case Type::DoubleTyID: - Size = 8; addDirectMem(BuildMI(BB, X86::FLDr64, 4, DestReg), VAList); break; } - - // Increment the VAList pointer... - unsigned NextVAList = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDri32, 2, NextVAList).addReg(VAList).addZImm(Size); - - // Update the VAList in memory... - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), SrcReg).addReg(NextVAList); } diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index a6dc7c9fb4..f9b949811b 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -173,7 +173,8 @@ namespace { void visitShiftInst(ShiftInst &I); void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass void visitCastInst(CastInst &I); - void visitVarArgInst(VarArgInst &I); + void visitVANextInst(VANextInst &I); + void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { std::cerr << "Cannot instruction select: " << I; @@ -1000,18 +1001,16 @@ void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) { switch (ID) { case LLVMIntrinsic::va_start: // Get the address of the first vararg value... - TmpReg1 = makeAnotherReg(Type::UIntTy); + TmpReg1 = getReg(CI); addFrameReference(BuildMI(BB, X86::LEAr32, 5, TmpReg1), VarArgsFrameIndex); - TmpReg2 = getReg(CI.getOperand(1)); - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1); return; - case LLVMIntrinsic::va_end: return; // Noop on X86 case LLVMIntrinsic::va_copy: - TmpReg1 = getReg(CI.getOperand(2)); // Get existing va_list - TmpReg2 = getReg(CI.getOperand(1)); // Get va_list* to store into - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1); + TmpReg1 = getReg(CI); + TmpReg2 = getReg(CI.getOperand(1)); + BuildMI(BB, X86::MOVrr32, 1, TmpReg1).addReg(TmpReg2); return; + case LLVMIntrinsic::va_end: return; // Noop on X86 case LLVMIntrinsic::longjmp: case LLVMIntrinsic::siglongjmp: @@ -1884,46 +1883,57 @@ void ISel::emitCastOperation(MachineBasicBlock *BB, abort(); } -/// visitVarArgInst - Implement the va_arg instruction... +/// visitVANextInst - Implement the va_next instruction... /// -void ISel::visitVarArgInst(VarArgInst &I) { - unsigned SrcReg = getReg(I.getOperand(0)); +void ISel::visitVANextInst(VANextInst &I) { + unsigned VAList = getReg(I.getOperand(0)); unsigned DestReg = getReg(I); - // Load the va_list into a register... - unsigned VAList = makeAnotherReg(Type::UIntTy); - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, VAList), SrcReg); - unsigned Size; - switch (I.getType()->getPrimitiveID()) { + switch (I.getArgType()->getPrimitiveID()) { default: std::cerr << I; - assert(0 && "Error: bad type for va_arg instruction!"); + assert(0 && "Error: bad type for va_next instruction!"); return; case Type::PointerTyID: case Type::UIntTyID: case Type::IntTyID: Size = 4; - addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); break; case Type::ULongTyID: case Type::LongTyID: + case Type::DoubleTyID: Size = 8; + break; + } + + // Increment the VAList pointer... + BuildMI(BB, X86::ADDri32, 2, DestReg).addReg(VAList).addZImm(Size); +} + +void ISel::visitVAArgInst(VAArgInst &I) { + unsigned VAList = getReg(I.getOperand(0)); + unsigned DestReg = getReg(I); + + switch (I.getType()->getPrimitiveID()) { + default: + std::cerr << I; + assert(0 && "Error: bad type for va_next instruction!"); + return; + case Type::PointerTyID: + case Type::UIntTyID: + case Type::IntTyID: + addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); + break; + case Type::ULongTyID: + case Type::LongTyID: addDirectMem(BuildMI(BB, X86::MOVmr32, 4, DestReg), VAList); addRegOffset(BuildMI(BB, X86::MOVmr32, 4, DestReg+1), VAList, 4); break; case Type::DoubleTyID: - Size = 8; addDirectMem(BuildMI(BB, X86::FLDr64, 4, DestReg), VAList); break; } - - // Increment the VAList pointer... - unsigned NextVAList = makeAnotherReg(Type::UIntTy); - BuildMI(BB, X86::ADDri32, 2, NextVAList).addReg(VAList).addZImm(Size); - - // Update the VAList in memory... - addDirectMem(BuildMI(BB, X86::MOVrm32, 5), SrcReg).addReg(NextVAList); } -- cgit v1.2.3