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:
Brian Gaeke 2002-11-30 11:57:28 +00:00
parent 18a20212d9
commit c2505985ce
2 changed files with 148 additions and 98 deletions

View File

@ -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);

View File

@ -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);