forked from OSchip/llvm-project
brg
InstSelectSimple.cpp: Refactor out conversion of byte, short -> int from visitReturnInst() to new method, promote32(). Use it in both visitReturnInst() and visitCallInst(). llvm-svn: 4839
This commit is contained in:
parent
23953e0f8a
commit
2ad3501d3f
|
@ -107,6 +107,7 @@ namespace {
|
|||
abort();
|
||||
}
|
||||
|
||||
void promote32 (const unsigned targetReg, Value *v);
|
||||
|
||||
/// copyConstantToRegister - Output the instructions required to put the
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// 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,
|
||||
/// 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 float/double : Top of FP stack
|
||||
///
|
||||
void ISel::visitReturnInst (ReturnInst &I) {
|
||||
if (I.getNumOperands() == 0) {
|
||||
void
|
||||
ISel::visitReturnInst (ReturnInst &I)
|
||||
{
|
||||
if (I.getNumOperands () == 0)
|
||||
{
|
||||
// Emit a 'ret' instruction
|
||||
BuildMI(BB, X86::RET, 0);
|
||||
BuildMI (BB, X86::RET, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned val = getReg(I.getOperand(0));
|
||||
unsigned Class = getClass(I.getOperand(0)->getType());
|
||||
bool isUnsigned = I.getOperand(0)->getType()->isUnsigned();
|
||||
switch (Class) {
|
||||
Value *rv = I.getOperand (0);
|
||||
unsigned Class = getClass (rv->getType ());
|
||||
switch (Class)
|
||||
{
|
||||
// integral return values: extend or move into EAX and return.
|
||||
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:
|
||||
// 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:
|
||||
// ret int, uint, ptr: Move value into EAX and return
|
||||
// MOV EAX, <val>
|
||||
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(val);
|
||||
promote32 (X86::EAX, rv);
|
||||
break;
|
||||
|
||||
// ret float/double: top of FP stack
|
||||
// FLD <val>
|
||||
case cFloat: // Floats
|
||||
BuildMI(BB, X86::FLDr4, 1).addReg(val);
|
||||
BuildMI (BB, X86::FLDr4, 1).addReg (getReg (rv));
|
||||
break;
|
||||
case cDouble: // Doubles
|
||||
BuildMI(BB, X86::FLDr8, 1).addReg(val);
|
||||
BuildMI (BB, X86::FLDr8, 1).addReg (getReg (rv));
|
||||
break;
|
||||
case cLong:
|
||||
// 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
|
||||
// cage? *zort*
|
||||
default:
|
||||
visitInstruction(I);
|
||||
visitInstruction (I);
|
||||
}
|
||||
|
||||
// Emit a 'ret' instruction
|
||||
BuildMI(BB, X86::RET, 0);
|
||||
BuildMI (BB, X86::RET, 0);
|
||||
}
|
||||
|
||||
/// visitBranchInst - Handle conditional and unconditional branches here. Note
|
||||
|
@ -375,6 +395,11 @@ ISel::visitCallInst (CallInst & CI)
|
|||
unsigned argReg = getReg (v);
|
||||
switch (getClass (v->getType ()))
|
||||
{
|
||||
case cByte:
|
||||
case cShort:
|
||||
promote32 (X86::EAX, v);
|
||||
BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX);
|
||||
break;
|
||||
case cInt:
|
||||
case cFloat:
|
||||
BuildMI (BB, X86::PUSHr32, 1).addReg (argReg);
|
||||
|
|
Loading…
Reference in New Issue