From 20abb6bf45ae187577a6aa4271ddef295d847202 Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Mon, 11 Nov 2002 19:37:09 +0000 Subject: [PATCH] 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 --- lib/Target/X86/InstSelectSimple.cpp | 73 +++++++++++++++++++++++++---- lib/Target/X86/X86ISelSimple.cpp | 73 +++++++++++++++++++++++++---- lib/Target/X86/X86InstrInfo.def | 1 + 3 files changed, 129 insertions(+), 18 deletions(-) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index af352ae6059..f2540a520dd 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -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 + 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, + // 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, + // 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, + 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 diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index af352ae6059..f2540a520dd 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -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 + 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, + // 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, + // 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, + 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 diff --git a/lib/Target/X86/X86InstrInfo.def b/lib/Target/X86/X86InstrInfo.def index e6c6b073e39..1a6f2f5fca9 100644 --- a/lib/Target/X86/X86InstrInfo.def +++ b/lib/Target/X86/X86InstrInfo.def @@ -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 -- 2.34.1