mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 06:32:24 +00:00
brg
InstSelectSimple.cpp: Refactor out conversion of byte, short -> int from visitReturnInst() to new method, promote32(). Use it in both visitReturnInst() and visitCallInst(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4839 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
18a20212d9
commit
c2505985ce
@ -107,6 +107,7 @@ namespace {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void promote32 (const unsigned targetReg, Value *v);
|
||||||
|
|
||||||
/// copyConstantToRegister - Output the instructions required to put the
|
/// copyConstantToRegister - Output the instructions required to put the
|
||||||
/// specified constant into the specified register.
|
/// specified constant into the specified register.
|
||||||
@ -272,6 +273,38 @@ void ISel::visitSetCCInst(SetCondInst &I, unsigned OpNum) {
|
|||||||
BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL);
|
BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide
|
||||||
|
/// operand, in the specified target register.
|
||||||
|
void
|
||||||
|
ISel::promote32 (const unsigned targetReg, Value *v)
|
||||||
|
{
|
||||||
|
unsigned vReg = getReg (v);
|
||||||
|
unsigned Class = getClass (v->getType ());
|
||||||
|
bool isUnsigned = v->getType ()->isUnsigned ();
|
||||||
|
assert (((Class == cByte) || (Class == cShort) || (Class == cInt))
|
||||||
|
&& "Unpromotable operand class in promote32");
|
||||||
|
switch (Class)
|
||||||
|
{
|
||||||
|
case cByte:
|
||||||
|
// Extend value into target register (8->32)
|
||||||
|
if (isUnsigned)
|
||||||
|
BuildMI (BB, X86::MOVZXr32r8, 1, targetReg).addReg (vReg);
|
||||||
|
else
|
||||||
|
BuildMI (BB, X86::MOVSXr32r8, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
case cShort:
|
||||||
|
// Extend value into target register (16->32)
|
||||||
|
if (isUnsigned)
|
||||||
|
BuildMI (BB, X86::MOVZXr32r16, 1, targetReg).addReg (vReg);
|
||||||
|
else
|
||||||
|
BuildMI (BB, X86::MOVSXr32r16, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
case cInt:
|
||||||
|
// Move value into target register (32->32)
|
||||||
|
BuildMI (BB, X86::MOVrr32, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
|
/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
|
||||||
/// we have the following possibilities:
|
/// we have the following possibilities:
|
||||||
@ -284,44 +317,32 @@ void ISel::visitSetCCInst(SetCondInst &I, unsigned OpNum) {
|
|||||||
/// 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
|
/// ret float/double : Top of FP stack
|
||||||
///
|
///
|
||||||
void ISel::visitReturnInst (ReturnInst &I) {
|
void
|
||||||
if (I.getNumOperands() == 0) {
|
ISel::visitReturnInst (ReturnInst &I)
|
||||||
|
{
|
||||||
|
if (I.getNumOperands () == 0)
|
||||||
|
{
|
||||||
// Emit a 'ret' instruction
|
// Emit a 'ret' instruction
|
||||||
BuildMI(BB, X86::RET, 0);
|
BuildMI (BB, X86::RET, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Value *rv = I.getOperand (0);
|
||||||
unsigned val = getReg(I.getOperand(0));
|
unsigned Class = getClass (rv->getType ());
|
||||||
unsigned Class = getClass(I.getOperand(0)->getType());
|
switch (Class)
|
||||||
bool isUnsigned = I.getOperand(0)->getType()->isUnsigned();
|
{
|
||||||
switch (Class) {
|
// integral return values: extend or move into EAX and return.
|
||||||
case cByte:
|
case cByte:
|
||||||
// ret sbyte, ubyte: Extend value into EAX and return
|
|
||||||
if (isUnsigned)
|
|
||||||
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
else
|
|
||||||
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
break;
|
|
||||||
case cShort:
|
case cShort:
|
||||||
// ret short, ushort: Extend value into EAX and return
|
|
||||||
if (isUnsigned)
|
|
||||||
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
else
|
|
||||||
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
break;
|
|
||||||
case cInt:
|
case cInt:
|
||||||
// ret int, uint, ptr: Move value into EAX and return
|
promote32 (X86::EAX, rv);
|
||||||
// MOV EAX, <val>
|
|
||||||
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ret float/double: top of FP stack
|
// ret float/double: top of FP stack
|
||||||
// FLD <val>
|
// FLD <val>
|
||||||
case cFloat: // Floats
|
case cFloat: // Floats
|
||||||
BuildMI(BB, X86::FLDr4, 1).addReg(val);
|
BuildMI (BB, X86::FLDr4, 1).addReg (getReg (rv));
|
||||||
break;
|
break;
|
||||||
case cDouble: // Doubles
|
case cDouble: // Doubles
|
||||||
BuildMI(BB, X86::FLDr8, 1).addReg(val);
|
BuildMI (BB, X86::FLDr8, 1).addReg (getReg (rv));
|
||||||
break;
|
break;
|
||||||
case cLong:
|
case cLong:
|
||||||
// ret long: use EAX(least significant 32 bits)/EDX (most
|
// ret long: use EAX(least significant 32 bits)/EDX (most
|
||||||
@ -329,11 +350,10 @@ void ISel::visitReturnInst (ReturnInst &I) {
|
|||||||
// up the two parts of the value from inside this mouse
|
// up the two parts of the value from inside this mouse
|
||||||
// cage? *zort*
|
// cage? *zort*
|
||||||
default:
|
default:
|
||||||
visitInstruction(I);
|
visitInstruction (I);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit a 'ret' instruction
|
// Emit a 'ret' instruction
|
||||||
BuildMI(BB, X86::RET, 0);
|
BuildMI (BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
||||||
@ -375,6 +395,11 @@ ISel::visitCallInst (CallInst & CI)
|
|||||||
unsigned argReg = getReg (v);
|
unsigned argReg = getReg (v);
|
||||||
switch (getClass (v->getType ()))
|
switch (getClass (v->getType ()))
|
||||||
{
|
{
|
||||||
|
case cByte:
|
||||||
|
case cShort:
|
||||||
|
promote32 (X86::EAX, v);
|
||||||
|
BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX);
|
||||||
|
break;
|
||||||
case cInt:
|
case cInt:
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (BB, X86::PUSHr32, 1).addReg (argReg);
|
BuildMI (BB, X86::PUSHr32, 1).addReg (argReg);
|
||||||
|
@ -107,6 +107,7 @@ namespace {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void promote32 (const unsigned targetReg, Value *v);
|
||||||
|
|
||||||
/// copyConstantToRegister - Output the instructions required to put the
|
/// copyConstantToRegister - Output the instructions required to put the
|
||||||
/// specified constant into the specified register.
|
/// specified constant into the specified register.
|
||||||
@ -272,6 +273,38 @@ void ISel::visitSetCCInst(SetCondInst &I, unsigned OpNum) {
|
|||||||
BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL);
|
BuildMI (BB, X86::MOVrr8, 1, getReg(I)).addReg(X86::AL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide
|
||||||
|
/// operand, in the specified target register.
|
||||||
|
void
|
||||||
|
ISel::promote32 (const unsigned targetReg, Value *v)
|
||||||
|
{
|
||||||
|
unsigned vReg = getReg (v);
|
||||||
|
unsigned Class = getClass (v->getType ());
|
||||||
|
bool isUnsigned = v->getType ()->isUnsigned ();
|
||||||
|
assert (((Class == cByte) || (Class == cShort) || (Class == cInt))
|
||||||
|
&& "Unpromotable operand class in promote32");
|
||||||
|
switch (Class)
|
||||||
|
{
|
||||||
|
case cByte:
|
||||||
|
// Extend value into target register (8->32)
|
||||||
|
if (isUnsigned)
|
||||||
|
BuildMI (BB, X86::MOVZXr32r8, 1, targetReg).addReg (vReg);
|
||||||
|
else
|
||||||
|
BuildMI (BB, X86::MOVSXr32r8, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
case cShort:
|
||||||
|
// Extend value into target register (16->32)
|
||||||
|
if (isUnsigned)
|
||||||
|
BuildMI (BB, X86::MOVZXr32r16, 1, targetReg).addReg (vReg);
|
||||||
|
else
|
||||||
|
BuildMI (BB, X86::MOVSXr32r16, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
case cInt:
|
||||||
|
// Move value into target register (32->32)
|
||||||
|
BuildMI (BB, X86::MOVrr32, 1, targetReg).addReg (vReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
|
/// 'ret' instruction - Here we are interested in meeting the x86 ABI. As such,
|
||||||
/// we have the following possibilities:
|
/// we have the following possibilities:
|
||||||
@ -284,44 +317,32 @@ void ISel::visitSetCCInst(SetCondInst &I, unsigned OpNum) {
|
|||||||
/// 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
|
/// ret float/double : Top of FP stack
|
||||||
///
|
///
|
||||||
void ISel::visitReturnInst (ReturnInst &I) {
|
void
|
||||||
if (I.getNumOperands() == 0) {
|
ISel::visitReturnInst (ReturnInst &I)
|
||||||
|
{
|
||||||
|
if (I.getNumOperands () == 0)
|
||||||
|
{
|
||||||
// Emit a 'ret' instruction
|
// Emit a 'ret' instruction
|
||||||
BuildMI(BB, X86::RET, 0);
|
BuildMI (BB, X86::RET, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Value *rv = I.getOperand (0);
|
||||||
unsigned val = getReg(I.getOperand(0));
|
unsigned Class = getClass (rv->getType ());
|
||||||
unsigned Class = getClass(I.getOperand(0)->getType());
|
switch (Class)
|
||||||
bool isUnsigned = I.getOperand(0)->getType()->isUnsigned();
|
{
|
||||||
switch (Class) {
|
// integral return values: extend or move into EAX and return.
|
||||||
case cByte:
|
case cByte:
|
||||||
// ret sbyte, ubyte: Extend value into EAX and return
|
|
||||||
if (isUnsigned)
|
|
||||||
BuildMI (BB, X86::MOVZXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
else
|
|
||||||
BuildMI (BB, X86::MOVSXr32r8, 1, X86::EAX).addReg (val);
|
|
||||||
break;
|
|
||||||
case cShort:
|
case cShort:
|
||||||
// ret short, ushort: Extend value into EAX and return
|
|
||||||
if (isUnsigned)
|
|
||||||
BuildMI (BB, X86::MOVZXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
else
|
|
||||||
BuildMI (BB, X86::MOVSXr32r16, 1, X86::EAX).addReg (val);
|
|
||||||
break;
|
|
||||||
case cInt:
|
case cInt:
|
||||||
// ret int, uint, ptr: Move value into EAX and return
|
promote32 (X86::EAX, rv);
|
||||||
// MOV EAX, <val>
|
|
||||||
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ret float/double: top of FP stack
|
// ret float/double: top of FP stack
|
||||||
// FLD <val>
|
// FLD <val>
|
||||||
case cFloat: // Floats
|
case cFloat: // Floats
|
||||||
BuildMI(BB, X86::FLDr4, 1).addReg(val);
|
BuildMI (BB, X86::FLDr4, 1).addReg (getReg (rv));
|
||||||
break;
|
break;
|
||||||
case cDouble: // Doubles
|
case cDouble: // Doubles
|
||||||
BuildMI(BB, X86::FLDr8, 1).addReg(val);
|
BuildMI (BB, X86::FLDr8, 1).addReg (getReg (rv));
|
||||||
break;
|
break;
|
||||||
case cLong:
|
case cLong:
|
||||||
// ret long: use EAX(least significant 32 bits)/EDX (most
|
// ret long: use EAX(least significant 32 bits)/EDX (most
|
||||||
@ -329,11 +350,10 @@ void ISel::visitReturnInst (ReturnInst &I) {
|
|||||||
// up the two parts of the value from inside this mouse
|
// up the two parts of the value from inside this mouse
|
||||||
// cage? *zort*
|
// cage? *zort*
|
||||||
default:
|
default:
|
||||||
visitInstruction(I);
|
visitInstruction (I);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit a 'ret' instruction
|
// Emit a 'ret' instruction
|
||||||
BuildMI(BB, X86::RET, 0);
|
BuildMI (BB, X86::RET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
||||||
@ -375,6 +395,11 @@ ISel::visitCallInst (CallInst & CI)
|
|||||||
unsigned argReg = getReg (v);
|
unsigned argReg = getReg (v);
|
||||||
switch (getClass (v->getType ()))
|
switch (getClass (v->getType ()))
|
||||||
{
|
{
|
||||||
|
case cByte:
|
||||||
|
case cShort:
|
||||||
|
promote32 (X86::EAX, v);
|
||||||
|
BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX);
|
||||||
|
break;
|
||||||
case cInt:
|
case cInt:
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (BB, X86::PUSHr32, 1).addReg (argReg);
|
BuildMI (BB, X86::PUSHr32, 1).addReg (argReg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user