mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
This implements folding of constant operands into floating point operations
for mul and div. Instead of generating this: test_divr: fld QWORD PTR [%ESP + 4] fld QWORD PTR [.CPItest_divr_0] fdivrp %ST(1) ret We now generate this: test_divr: fld QWORD PTR [%ESP + 4] fdivr QWORD PTR [.CPItest_divr_0] ret This code desperately needs refactoring, which will come in the next patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12841 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
462fa82270
commit
8ebf1c35a1
@ -2129,23 +2129,37 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
|
|||||||
TypeClass Class = getClass(Op0->getType());
|
TypeClass Class = getClass(Op0->getType());
|
||||||
|
|
||||||
// Simple scalar multiply?
|
// Simple scalar multiply?
|
||||||
|
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cByte:
|
case cByte:
|
||||||
case cShort:
|
case cShort:
|
||||||
case cInt:
|
case cInt:
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Val = (unsigned)CI->getRawValue(); // Isn't a 64-bit constant
|
unsigned Val = (unsigned)CI->getRawValue(); // Isn't a 64-bit constant
|
||||||
doMultiplyConst(&BB, IP, DestReg, Op0->getType(), Op0Reg, Val);
|
doMultiplyConst(&BB, IP, DestReg, Op0->getType(), Op0Reg, Val);
|
||||||
} else {
|
} else {
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
||||||
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case cFP:
|
case cFP:
|
||||||
|
if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1))
|
||||||
|
if (!Op1C->isExactlyValue(+0.0) && !Op1C->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(Op1C);
|
||||||
|
const Type *Ty = Op1C->getType();
|
||||||
|
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FMUL32m, X86::FMUL64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
addConstantPoolReference(BuildMI(*MBB, IP, Opcode, 5,
|
||||||
|
DestReg).addReg(Op0Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
||||||
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
||||||
return;
|
return;
|
||||||
@ -2154,8 +2168,6 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
|
|
||||||
// Long value. We have to do things the hard way...
|
// Long value. We have to do things the hard way...
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||||
unsigned CLow = CI->getRawValue();
|
unsigned CLow = CI->getRawValue();
|
||||||
@ -2248,17 +2260,48 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
MachineBasicBlock::iterator IP = BB->end();
|
MachineBasicBlock::iterator IP = BB->end();
|
||||||
emitDivRemOperation(BB, IP, I.getOperand(0), I.getOperand(1),
|
emitDivRemOperation(BB, IP, I.getOperand(0), I.getOperand(1),
|
||||||
I.getOpcode() == Instruction::Div, ResultReg);
|
I.getOpcode() == Instruction::Div, ResultReg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
MachineBasicBlock::iterator IP,
|
MachineBasicBlock::iterator IP,
|
||||||
Value *Op0, Value *Op1, bool isDiv,
|
Value *Op0, Value *Op1, bool isDiv,
|
||||||
unsigned ResultReg) {
|
unsigned ResultReg) {
|
||||||
unsigned Class = getClass(Op0->getType());
|
const Type *Ty = Op0->getType();
|
||||||
|
unsigned Class = getClass(Ty);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cFP: // Floating point divide
|
case cFP: // Floating point divide
|
||||||
if (isDiv) {
|
if (isDiv) {
|
||||||
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op0))
|
||||||
|
if (!CFP->isExactlyValue(+0.0) && !CFP->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(CFP);
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FDIVR32m, X86::FDIVR64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
|
addConstantPoolReference(BuildMI(*BB, IP, Opcode, 5,
|
||||||
|
ResultReg).addReg(Op1Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))
|
||||||
|
if (!CFP->isExactlyValue(+0.0) && !CFP->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(CFP);
|
||||||
|
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FDIV32m, X86::FDIV64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
|
addConstantPoolReference(BuildMI(*BB, IP, Opcode, 5,
|
||||||
|
ResultReg).addReg(Op0Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned Op0Reg = getReg(Op0, BB, IP);
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
unsigned Op1Reg = getReg(Op1, BB, IP);
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
BuildMI(*BB, IP, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(*BB, IP, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
@ -2278,7 +2321,7 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
|||||||
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
||||||
unsigned Op0Reg = getReg(Op0, BB, IP);
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
unsigned Op1Reg = getReg(Op1, BB, IP);
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
unsigned NameIdx = Op0->getType()->isUnsigned()*2 + isDiv;
|
unsigned NameIdx = Ty->isUnsigned()*2 + isDiv;
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
||||||
|
|
||||||
@ -2304,7 +2347,7 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
|||||||
{ X86::IDIV8r, X86::IDIV16r, X86::IDIV32r, 0 }, // Signed division
|
{ X86::IDIV8r, X86::IDIV16r, X86::IDIV32r, 0 }, // Signed division
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isSigned = Op0->getType()->isSigned();
|
bool isSigned = Ty->isSigned();
|
||||||
unsigned Reg = Regs[Class];
|
unsigned Reg = Regs[Class];
|
||||||
unsigned ExtReg = ExtRegs[Class];
|
unsigned ExtReg = ExtRegs[Class];
|
||||||
|
|
||||||
|
@ -2129,23 +2129,37 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
|
|||||||
TypeClass Class = getClass(Op0->getType());
|
TypeClass Class = getClass(Op0->getType());
|
||||||
|
|
||||||
// Simple scalar multiply?
|
// Simple scalar multiply?
|
||||||
|
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cByte:
|
case cByte:
|
||||||
case cShort:
|
case cShort:
|
||||||
case cInt:
|
case cInt:
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Val = (unsigned)CI->getRawValue(); // Isn't a 64-bit constant
|
unsigned Val = (unsigned)CI->getRawValue(); // Isn't a 64-bit constant
|
||||||
doMultiplyConst(&BB, IP, DestReg, Op0->getType(), Op0Reg, Val);
|
doMultiplyConst(&BB, IP, DestReg, Op0->getType(), Op0Reg, Val);
|
||||||
} else {
|
} else {
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
||||||
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case cFP:
|
case cFP:
|
||||||
|
if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1))
|
||||||
|
if (!Op1C->isExactlyValue(+0.0) && !Op1C->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(Op1C);
|
||||||
|
const Type *Ty = Op1C->getType();
|
||||||
|
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FMUL32m, X86::FMUL64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
addConstantPoolReference(BuildMI(*MBB, IP, Opcode, 5,
|
||||||
|
DestReg).addReg(Op0Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
unsigned Op1Reg = getReg(Op1, &BB, IP);
|
||||||
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
doMultiply(&BB, IP, DestReg, Op1->getType(), Op0Reg, Op1Reg);
|
||||||
return;
|
return;
|
||||||
@ -2154,8 +2168,6 @@ void ISel::emitMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Op0Reg = getReg(Op0, &BB, IP);
|
|
||||||
|
|
||||||
// Long value. We have to do things the hard way...
|
// Long value. We have to do things the hard way...
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
|
||||||
unsigned CLow = CI->getRawValue();
|
unsigned CLow = CI->getRawValue();
|
||||||
@ -2248,17 +2260,48 @@ void ISel::visitDivRem(BinaryOperator &I) {
|
|||||||
MachineBasicBlock::iterator IP = BB->end();
|
MachineBasicBlock::iterator IP = BB->end();
|
||||||
emitDivRemOperation(BB, IP, I.getOperand(0), I.getOperand(1),
|
emitDivRemOperation(BB, IP, I.getOperand(0), I.getOperand(1),
|
||||||
I.getOpcode() == Instruction::Div, ResultReg);
|
I.getOpcode() == Instruction::Div, ResultReg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
||||||
MachineBasicBlock::iterator IP,
|
MachineBasicBlock::iterator IP,
|
||||||
Value *Op0, Value *Op1, bool isDiv,
|
Value *Op0, Value *Op1, bool isDiv,
|
||||||
unsigned ResultReg) {
|
unsigned ResultReg) {
|
||||||
unsigned Class = getClass(Op0->getType());
|
const Type *Ty = Op0->getType();
|
||||||
|
unsigned Class = getClass(Ty);
|
||||||
switch (Class) {
|
switch (Class) {
|
||||||
case cFP: // Floating point divide
|
case cFP: // Floating point divide
|
||||||
if (isDiv) {
|
if (isDiv) {
|
||||||
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op0))
|
||||||
|
if (!CFP->isExactlyValue(+0.0) && !CFP->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(CFP);
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FDIVR32m, X86::FDIVR64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
|
addConstantPoolReference(BuildMI(*BB, IP, Opcode, 5,
|
||||||
|
ResultReg).addReg(Op1Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))
|
||||||
|
if (!CFP->isExactlyValue(+0.0) && !CFP->isExactlyValue(+1.0)) {
|
||||||
|
// Create a constant pool entry for this constant.
|
||||||
|
MachineConstantPool *CP = F->getConstantPool();
|
||||||
|
unsigned CPI = CP->getConstantPoolIndex(CFP);
|
||||||
|
|
||||||
|
static const unsigned OpcodeTab[2] = { X86::FDIV32m, X86::FDIV64m };
|
||||||
|
|
||||||
|
assert(Ty == Type::FloatTy||Ty == Type::DoubleTy&&"Unknown FP type!");
|
||||||
|
unsigned Opcode = OpcodeTab[Ty != Type::FloatTy];
|
||||||
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
|
addConstantPoolReference(BuildMI(*BB, IP, Opcode, 5,
|
||||||
|
ResultReg).addReg(Op0Reg), CPI);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned Op0Reg = getReg(Op0, BB, IP);
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
unsigned Op1Reg = getReg(Op1, BB, IP);
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
BuildMI(*BB, IP, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(*BB, IP, X86::FpDIV, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
@ -2278,7 +2321,7 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
|||||||
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
{ "__moddi3", "__divdi3", "__umoddi3", "__udivdi3" };
|
||||||
unsigned Op0Reg = getReg(Op0, BB, IP);
|
unsigned Op0Reg = getReg(Op0, BB, IP);
|
||||||
unsigned Op1Reg = getReg(Op1, BB, IP);
|
unsigned Op1Reg = getReg(Op1, BB, IP);
|
||||||
unsigned NameIdx = Op0->getType()->isUnsigned()*2 + isDiv;
|
unsigned NameIdx = Ty->isUnsigned()*2 + isDiv;
|
||||||
MachineInstr *TheCall =
|
MachineInstr *TheCall =
|
||||||
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
BuildMI(X86::CALLpcrel32, 1).addExternalSymbol(FnName[NameIdx], true);
|
||||||
|
|
||||||
@ -2304,7 +2347,7 @@ void ISel::emitDivRemOperation(MachineBasicBlock *BB,
|
|||||||
{ X86::IDIV8r, X86::IDIV16r, X86::IDIV32r, 0 }, // Signed division
|
{ X86::IDIV8r, X86::IDIV16r, X86::IDIV32r, 0 }, // Signed division
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isSigned = Op0->getType()->isSigned();
|
bool isSigned = Ty->isSigned();
|
||||||
unsigned Reg = Regs[Class];
|
unsigned Reg = Regs[Class];
|
||||||
unsigned ExtReg = ExtRegs[Class];
|
unsigned ExtReg = ExtRegs[Class];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user