InstSelectSimple.cpp: (visitReturnInst) Add return instructions with return
values.
X86InstrInfo.def: add LEAVE instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4691 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index af352ae..f2540a5 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -326,15 +326,70 @@
/// ret long, ulong : Move value into EAX/EDX (?) and return
/// ret float/double : ? Top of FP stack? XMM0?
///
-void ISel::visitReturnInst(ReturnInst &I) {
- if (I.getNumOperands() != 0) { // Not 'ret void'?
- // Move result into a hard register... then emit a ret
- visitInstruction(I); // abort
- }
-
- // Emit a simple 'ret' instruction... appending it to the end of the basic
- // block
- BuildMI(BB, X86::RET, 0);
+void
+ISel::visitReturnInst (ReturnInst & I)
+{
+ if (I.getNumOperands () == 1)
+ {
+ unsigned val = getReg (I.getOperand (0));
+ unsigned operandSize =
+ I.getOperand (0)->getType ()->getPrimitiveSize ();
+ bool isFP = I.getOperand (0)->getType ()->isFloatingPoint ();
+ if (isFP)
+ {
+ // ret float/double: top of FP stack
+ // FLD <val>
+ switch (operandSize)
+ {
+ case 4:
+ BuildMI (BB, X86::FLDr4, 1, X86::NoReg).addReg (val);
+ break;
+ case 8:
+ BuildMI (BB, X86::FLDr8, 1, X86::NoReg).addReg (val);
+ break;
+ default:
+ visitInstruction (I);
+ break;
+ }
+ }
+ else
+ {
+ switch (operandSize)
+ {
+ case 1:
+ // ret sbyte, ubyte: Extend value into EAX and return
+ // MOV AL, <val>
+ // CBW
+ BuildMI (BB, X86::MOVrr8, 1, X86::AL).addReg (val);
+ BuildMI (BB, X86::CBW, 0);
+ break;
+ case 2:
+ // ret short, ushort: Extend value into EAX and return
+ // MOV AX, <val>
+ // CWDE
+ BuildMI (BB, X86::MOVrr16, 1, X86::AX).addReg (val);
+ BuildMI (BB, X86::CWDE, 0);
+ break;
+ case 4:
+ // ret int, uint, ptr: Move value into EAX and return
+ // MOV EAX, <val>
+ BuildMI (BB, X86::MOVrr32, 1, X86::EAX).addReg (val);
+ break;
+ case 8:
+ // ret long: use EAX(least significant 32 bits)/EDX (most
+ // significant 32)...uh, I think so Brain, but how do i call
+ // up the two parts of the value from inside this mouse
+ // cage? *zort*
+ default:
+ // abort
+ visitInstruction (I);
+ break;
+ }
+ }
+ }
+ // Emit a 'leave' and a 'ret'
+ BuildMI (BB, X86::LEAVE, 0);
+ BuildMI (BB, X86::RET, 0);
}
/// visitBranchInst - Handle conditional and unconditional branches here. Note