mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
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
This commit is contained in:
parent
e71ffc291c
commit
20abb6bf45
@ -326,14 +326,69 @@ ISel::visitSetCondInst (SetCondInst & I)
|
|||||||
/// ret long, ulong : Move value into EAX/EDX (?) and return
|
/// ret long, ulong : Move value into EAX/EDX (?) and return
|
||||||
/// ret float/double : ? Top of FP stack? XMM0?
|
/// ret float/double : ? Top of FP stack? XMM0?
|
||||||
///
|
///
|
||||||
void ISel::visitReturnInst(ReturnInst &I) {
|
void
|
||||||
if (I.getNumOperands() != 0) { // Not 'ret void'?
|
ISel::visitReturnInst (ReturnInst & I)
|
||||||
// Move result into a hard register... then emit a ret
|
{
|
||||||
visitInstruction(I); // abort
|
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Emit a simple 'ret' instruction... appending it to the end of the basic
|
else
|
||||||
// block
|
{
|
||||||
|
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);
|
BuildMI (BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,14 +326,69 @@ ISel::visitSetCondInst (SetCondInst & I)
|
|||||||
/// ret long, ulong : Move value into EAX/EDX (?) and return
|
/// ret long, ulong : Move value into EAX/EDX (?) and return
|
||||||
/// ret float/double : ? Top of FP stack? XMM0?
|
/// ret float/double : ? Top of FP stack? XMM0?
|
||||||
///
|
///
|
||||||
void ISel::visitReturnInst(ReturnInst &I) {
|
void
|
||||||
if (I.getNumOperands() != 0) { // Not 'ret void'?
|
ISel::visitReturnInst (ReturnInst & I)
|
||||||
// Move result into a hard register... then emit a ret
|
{
|
||||||
visitInstruction(I); // abort
|
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;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Emit a simple 'ret' instruction... appending it to the end of the basic
|
else
|
||||||
// block
|
{
|
||||||
|
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);
|
BuildMI (BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ I(MOVrr32 , "movl", 0, 0) // R32 = R32 89/r
|
|||||||
I(MOVir8 , "movb", 0, 0) // R8 = imm8 B0+ rb
|
I(MOVir8 , "movb", 0, 0) // R8 = imm8 B0+ rb
|
||||||
I(MOVir16 , "movw", 0, 0) // R16 = imm16 B8+ rw
|
I(MOVir16 , "movw", 0, 0) // R16 = imm16 B8+ rw
|
||||||
I(MOVir32 , "movl", 0, 0) // R32 = imm32 B8+ rd
|
I(MOVir32 , "movl", 0, 0) // R32 = imm32 B8+ rd
|
||||||
|
I(LEAVE , "leave", 0, 0) // leave C9
|
||||||
|
|
||||||
// Arithmetic instructions
|
// Arithmetic instructions
|
||||||
I(ADDrr8 , "addb", 0, 0) // R8 += R8 00/r
|
I(ADDrr8 , "addb", 0, 0) // R8 += R8 00/r
|
||||||
|
Loading…
Reference in New Issue
Block a user