mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 04:24:00 +00:00
For PR950:
This patch converts the old SHR instruction into two instructions, AShr (Arithmetic) and LShr (Logical). The Shr instructions now are not dependent on the sign of their operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31542 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -606,7 +606,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT:
|
||||
case Instruction::SetGE:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
{
|
||||
Out << '(';
|
||||
bool NeedsClosingParens = printConstExprCast(CE);
|
||||
@ -631,7 +632,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::SetGE: Out << " >= "; break;
|
||||
case Instruction::Shl: Out << " << "; break;
|
||||
case Instruction::Shr: Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: assert(0 && "Illegal opcode here!");
|
||||
}
|
||||
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
|
||||
@ -826,23 +828,23 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
// because their operands were casted to the expected type. This function takes
|
||||
// care of detecting that case and printing the cast for the ConstantExpr.
|
||||
bool CWriter::printConstExprCast(const ConstantExpr* CE) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = CE->getOperand(0)->getType();
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Print a constant assuming that it is the operand for a given Opcode. The
|
||||
@ -863,6 +865,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv/URem get correct type
|
||||
@ -871,6 +874,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
// For SDiv/SRem get correct type
|
||||
@ -927,23 +931,23 @@ void CWriter::writeOperand(Value *Operand) {
|
||||
// This function takes care of detecting that case and printing the cast
|
||||
// for the Instruction.
|
||||
bool CWriter::writeInstructionCast(const Instruction &I) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = I.getOperand(0)->getType();
|
||||
switch (I.getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Write the operand with a cast to another type based on the Opcode being used.
|
||||
@ -964,6 +968,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv to have unsigned operands
|
||||
@ -972,6 +977,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
if (OpTy->isUnsigned()) {
|
||||
@ -1832,7 +1838,8 @@ void CWriter::visitBinaryOperator(Instruction &I) {
|
||||
case Instruction::SetLT: Out << " < "; break;
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::Shl : Out << " << "; break;
|
||||
case Instruction::Shr : Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: std::cerr << "Invalid operator type!" << I; abort();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user