mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
Switch visitRet to use getClass()
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4710 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7e1ba8be09
commit
43189d17c3
@ -17,7 +17,6 @@
|
|||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct ISel : public FunctionPass, InstVisitor<ISel> {
|
struct ISel : public FunctionPass, InstVisitor<ISel> {
|
||||||
@ -113,26 +112,33 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TypeClass - Used by the X86 backend to group LLVM types by their basic X86
|
||||||
|
/// Representation.
|
||||||
|
///
|
||||||
|
enum TypeClass {
|
||||||
|
cByte, cShort, cInt, cLong, cFloat, cDouble
|
||||||
|
};
|
||||||
|
|
||||||
/// getClass - Turn a primitive type into a "class" number which is based on the
|
/// getClass - Turn a primitive type into a "class" number which is based on the
|
||||||
/// size of the type, and whether or not it is floating point.
|
/// size of the type, and whether or not it is floating point.
|
||||||
///
|
///
|
||||||
static inline unsigned getClass(const Type *Ty) {
|
static inline TypeClass getClass(const Type *Ty) {
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
case Type::SByteTyID:
|
case Type::SByteTyID:
|
||||||
case Type::UByteTyID: return 0; // Byte operands are class #0
|
case Type::UByteTyID: return cByte; // Byte operands are class #0
|
||||||
case Type::ShortTyID:
|
case Type::ShortTyID:
|
||||||
case Type::UShortTyID: return 1; // Short operands are class #1
|
case Type::UShortTyID: return cShort; // Short operands are class #1
|
||||||
case Type::IntTyID:
|
case Type::IntTyID:
|
||||||
case Type::UIntTyID:
|
case Type::UIntTyID:
|
||||||
case Type::PointerTyID: return 2; // Int's and pointers are class #2
|
case Type::PointerTyID: return cInt; // Int's and pointers are class #2
|
||||||
|
|
||||||
case Type::LongTyID:
|
case Type::LongTyID:
|
||||||
case Type::ULongTyID: return 3; // Longs are class #3
|
case Type::ULongTyID: return cLong; // Longs are class #3
|
||||||
case Type::FloatTyID: return 4; // Float is class #4
|
case Type::FloatTyID: return cFloat; // Float is class #4
|
||||||
case Type::DoubleTyID: return 5; // Doubles are class #5
|
case Type::DoubleTyID: return cDouble; // Doubles are class #5
|
||||||
default:
|
default:
|
||||||
assert(0 && "Invalid type to getClass!");
|
assert(0 && "Invalid type to getClass!");
|
||||||
return 0; // not reached
|
return cByte; // not reached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,71 +325,58 @@ 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
|
void ISel::visitReturnInst (ReturnInst & I) {
|
||||||
ISel::visitReturnInst (ReturnInst & I)
|
if (I.getNumOperands() == 0) {
|
||||||
{
|
// Emit a 'ret' instruction
|
||||||
if (I.getNumOperands () == 1)
|
BuildMI(BB, X86::RET, 0);
|
||||||
{
|
return;
|
||||||
bool unsignedReturnValue = I.getOperand(0)->getType()->isUnsigned();
|
}
|
||||||
unsigned val = getReg (I.getOperand (0));
|
|
||||||
unsigned operandSize =
|
unsigned val = getReg(I.getOperand(0));
|
||||||
I.getOperand (0)->getType ()->getPrimitiveSize ();
|
unsigned Class = getClass(I.getType());
|
||||||
bool isFP = I.getOperand (0)->getType ()->isFloatingPoint ();
|
bool isUnsigned = I.getOperand(0)->getType()->isUnsigned();
|
||||||
if (isFP)
|
switch (Class) {
|
||||||
{
|
case cByte:
|
||||||
// ret float/double: top of FP stack
|
// ret sbyte, ubyte: Extend value into EAX and return
|
||||||
// FLD <val>
|
if (isUnsigned) {
|
||||||
switch (operandSize)
|
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
||||||
{
|
} else {
|
||||||
case 4:
|
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
||||||
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
|
|
||||||
if (unsignedReturnValue) {
|
|
||||||
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
} else {
|
|
||||||
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// ret short, ushort: Extend value into EAX and return
|
|
||||||
if (unsignedReturnValue) {
|
|
||||||
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
} else {
|
|
||||||
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
// ret int, uint, ptr: Move value into EAX and return
|
|
||||||
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 'ret' -- the 'leave' will be added by the reg allocator, I guess?
|
break;
|
||||||
BuildMI (BB, X86::RET, 0);
|
case cShort:
|
||||||
|
// ret short, ushort: Extend value into EAX and return
|
||||||
|
if (unsignedReturnValue) {
|
||||||
|
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
||||||
|
} else {
|
||||||
|
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case cInt:
|
||||||
|
// ret int, uint, ptr: Move value into EAX and return
|
||||||
|
// MOV EAX, <val>
|
||||||
|
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ret float/double: top of FP stack
|
||||||
|
// FLD <val>
|
||||||
|
case cFloat: // Floats
|
||||||
|
BuildMI(BB, X86::FLDr4, 1).addReg(val);
|
||||||
|
break;
|
||||||
|
case cDouble: // Doubles
|
||||||
|
BuildMI(BB, X86::FLDr8, 1).addReg(val);
|
||||||
|
break;
|
||||||
|
case cLong:
|
||||||
|
// 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:
|
||||||
|
visitInstruction(I);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit a 'ret' instruction
|
||||||
|
BuildMI(BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct ISel : public FunctionPass, InstVisitor<ISel> {
|
struct ISel : public FunctionPass, InstVisitor<ISel> {
|
||||||
@ -113,26 +112,33 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TypeClass - Used by the X86 backend to group LLVM types by their basic X86
|
||||||
|
/// Representation.
|
||||||
|
///
|
||||||
|
enum TypeClass {
|
||||||
|
cByte, cShort, cInt, cLong, cFloat, cDouble
|
||||||
|
};
|
||||||
|
|
||||||
/// getClass - Turn a primitive type into a "class" number which is based on the
|
/// getClass - Turn a primitive type into a "class" number which is based on the
|
||||||
/// size of the type, and whether or not it is floating point.
|
/// size of the type, and whether or not it is floating point.
|
||||||
///
|
///
|
||||||
static inline unsigned getClass(const Type *Ty) {
|
static inline TypeClass getClass(const Type *Ty) {
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
case Type::SByteTyID:
|
case Type::SByteTyID:
|
||||||
case Type::UByteTyID: return 0; // Byte operands are class #0
|
case Type::UByteTyID: return cByte; // Byte operands are class #0
|
||||||
case Type::ShortTyID:
|
case Type::ShortTyID:
|
||||||
case Type::UShortTyID: return 1; // Short operands are class #1
|
case Type::UShortTyID: return cShort; // Short operands are class #1
|
||||||
case Type::IntTyID:
|
case Type::IntTyID:
|
||||||
case Type::UIntTyID:
|
case Type::UIntTyID:
|
||||||
case Type::PointerTyID: return 2; // Int's and pointers are class #2
|
case Type::PointerTyID: return cInt; // Int's and pointers are class #2
|
||||||
|
|
||||||
case Type::LongTyID:
|
case Type::LongTyID:
|
||||||
case Type::ULongTyID: return 3; // Longs are class #3
|
case Type::ULongTyID: return cLong; // Longs are class #3
|
||||||
case Type::FloatTyID: return 4; // Float is class #4
|
case Type::FloatTyID: return cFloat; // Float is class #4
|
||||||
case Type::DoubleTyID: return 5; // Doubles are class #5
|
case Type::DoubleTyID: return cDouble; // Doubles are class #5
|
||||||
default:
|
default:
|
||||||
assert(0 && "Invalid type to getClass!");
|
assert(0 && "Invalid type to getClass!");
|
||||||
return 0; // not reached
|
return cByte; // not reached
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,71 +325,58 @@ 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
|
void ISel::visitReturnInst (ReturnInst & I) {
|
||||||
ISel::visitReturnInst (ReturnInst & I)
|
if (I.getNumOperands() == 0) {
|
||||||
{
|
// Emit a 'ret' instruction
|
||||||
if (I.getNumOperands () == 1)
|
BuildMI(BB, X86::RET, 0);
|
||||||
{
|
return;
|
||||||
bool unsignedReturnValue = I.getOperand(0)->getType()->isUnsigned();
|
}
|
||||||
unsigned val = getReg (I.getOperand (0));
|
|
||||||
unsigned operandSize =
|
unsigned val = getReg(I.getOperand(0));
|
||||||
I.getOperand (0)->getType ()->getPrimitiveSize ();
|
unsigned Class = getClass(I.getType());
|
||||||
bool isFP = I.getOperand (0)->getType ()->isFloatingPoint ();
|
bool isUnsigned = I.getOperand(0)->getType()->isUnsigned();
|
||||||
if (isFP)
|
switch (Class) {
|
||||||
{
|
case cByte:
|
||||||
// ret float/double: top of FP stack
|
// ret sbyte, ubyte: Extend value into EAX and return
|
||||||
// FLD <val>
|
if (isUnsigned) {
|
||||||
switch (operandSize)
|
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
||||||
{
|
} else {
|
||||||
case 4:
|
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
||||||
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
|
|
||||||
if (unsignedReturnValue) {
|
|
||||||
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
} else {
|
|
||||||
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// ret short, ushort: Extend value into EAX and return
|
|
||||||
if (unsignedReturnValue) {
|
|
||||||
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
} else {
|
|
||||||
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
// ret int, uint, ptr: Move value into EAX and return
|
|
||||||
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 'ret' -- the 'leave' will be added by the reg allocator, I guess?
|
break;
|
||||||
BuildMI (BB, X86::RET, 0);
|
case cShort:
|
||||||
|
// ret short, ushort: Extend value into EAX and return
|
||||||
|
if (unsignedReturnValue) {
|
||||||
|
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
||||||
|
} else {
|
||||||
|
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case cInt:
|
||||||
|
// ret int, uint, ptr: Move value into EAX and return
|
||||||
|
// MOV EAX, <val>
|
||||||
|
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ret float/double: top of FP stack
|
||||||
|
// FLD <val>
|
||||||
|
case cFloat: // Floats
|
||||||
|
BuildMI(BB, X86::FLDr4, 1).addReg(val);
|
||||||
|
break;
|
||||||
|
case cDouble: // Doubles
|
||||||
|
BuildMI(BB, X86::FLDr8, 1).addReg(val);
|
||||||
|
break;
|
||||||
|
case cLong:
|
||||||
|
// 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:
|
||||||
|
visitInstruction(I);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit a 'ret' instruction
|
||||||
|
BuildMI(BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
||||||
|
Loading…
x
Reference in New Issue
Block a user