InstSelectSimple.cpp: (visitReturnInst) Add return instructions with return
authorBrian Gaeke <gaeke@uiuc.edu>
Mon, 11 Nov 2002 19:37:09 +0000 (19:37 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Mon, 11 Nov 2002 19:37:09 +0000 (19:37 +0000)
 values.
X86InstrInfo.def: add LEAVE instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4691 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp
lib/Target/X86/X86InstrInfo.def

index af352ae6059ebbc206e83a0acb83cf3d1f5226b4..f2540a520dd7511c8970c2280c26662ecb320bc4 100644 (file)
@@ -326,15 +326,70 @@ ISel::visitSetCondInst (SetCondInst & I)
 ///   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
index af352ae6059ebbc206e83a0acb83cf3d1f5226b4..f2540a520dd7511c8970c2280c26662ecb320bc4 100644 (file)
@@ -326,15 +326,70 @@ ISel::visitSetCondInst (SetCondInst & I)
 ///   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
index e6c6b073e39fc5e244bb6fd96e5cc2becfe428d9..1a6f2f5fca937f61a6d11969aede30032b7cd362 100644 (file)
@@ -44,6 +44,7 @@ I(MOVrr32     , "movl",               0, 0)           // R32 = R32    89/r
 I(MOVir8      , "movb",               0, 0)           // R8  = imm8   B0+ rb
 I(MOVir16     , "movw",               0, 0)           // R16 = imm16  B8+ rw
 I(MOVir32     , "movl",               0, 0)           // R32 = imm32  B8+ rd
+I(LEAVE       , "leave",              0, 0)           // leave        C9
 
 // Arithmetic instructions
 I(ADDrr8      , "addb",               0, 0)           // R8  += R8    00/r