mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-29 13:24:25 +00:00
Trim whitespace.
Support cast of ints (and narrower) to float and double. Support cast double to double (using load and store). Abort if we see a CallInst or SetCondInst with long/fp args, instead of producing bad code. Support add, sub, mul, div of float and double. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14440 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -86,8 +86,6 @@ namespace {
|
|||||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||||
void visitAllocaInst(AllocaInst &I);
|
void visitAllocaInst(AllocaInst &I);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void visitInstruction(Instruction &I) {
|
void visitInstruction(Instruction &I) {
|
||||||
std::cerr << "Unhandled instruction: " << I;
|
std::cerr << "Unhandled instruction: " << I;
|
||||||
abort();
|
abort();
|
||||||
@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (newTyClass == cFloat) {
|
if (newTyClass == cFloat) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
case cDouble:
|
case cDouble:
|
||||||
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast int to float. Store it to a stack slot and then load
|
||||||
// it using ldf into a floating point register. then do fitos.
|
// it using ldf into a floating point register. then do fitos.
|
||||||
std::cerr << "Casts to float still unsupported: SrcTy = "
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
abort ();
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
} else if (newTyClass == cDouble) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
case cDouble: {
|
||||||
std::cerr << "Casts to double still unsupported: SrcTy = "
|
// go through memory, for now
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
abort ();
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
|
||||||
|
.addSImm (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
std::cerr << "Cast still unsupported: SrcTy = "
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
||||||
@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
|
|||||||
V8::O4, V8::O5 };
|
V8::O4, V8::O5 };
|
||||||
for (unsigned i = 1; i < 7; ++i)
|
for (unsigned i = 1; i < 7; ++i)
|
||||||
if (i < I.getNumOperands ()) {
|
if (i < I.getNumOperands ()) {
|
||||||
|
assert (getClassB (I.getOperand (i)->getType ()) < cLong
|
||||||
|
&& "Can't handle long or fp function call arguments yet");
|
||||||
unsigned ArgReg = getReg (I.getOperand (i));
|
unsigned ArgReg = getReg (I.getOperand (i));
|
||||||
// Schlep it over into the incoming arg register
|
// Schlep it over into the incoming arg register
|
||||||
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
||||||
@ -789,11 +811,30 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
unsigned Op0Reg = getReg (I.getOperand (0));
|
unsigned Op0Reg = getReg (I.getOperand (0));
|
||||||
unsigned Op1Reg = getReg (I.getOperand (1));
|
unsigned Op1Reg = getReg (I.getOperand (1));
|
||||||
|
|
||||||
unsigned ResultReg = DestReg;
|
unsigned Class = getClassB (I.getType());
|
||||||
if (getClassB(I.getType()) != cInt)
|
|
||||||
ResultReg = makeAnotherReg (I.getType ());
|
|
||||||
unsigned OpCase = ~0;
|
unsigned OpCase = ~0;
|
||||||
|
|
||||||
|
if (Class > cLong) {
|
||||||
|
switch (I.getOpcode ()) {
|
||||||
|
case Instruction::Add: OpCase = 0; break;
|
||||||
|
case Instruction::Sub: OpCase = 1; break;
|
||||||
|
case Instruction::Mul: OpCase = 2; break;
|
||||||
|
case Instruction::Div: OpCase = 3; break;
|
||||||
|
default: visitInstruction (I); return;
|
||||||
|
}
|
||||||
|
static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
|
||||||
|
V8::FSUBS, V8::FSUBD,
|
||||||
|
V8::FMULS, V8::FMULD,
|
||||||
|
V8::FDIVS, V8::FDIVD };
|
||||||
|
BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
|
||||||
|
.addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ResultReg = DestReg;
|
||||||
|
if (Class != cInt)
|
||||||
|
ResultReg = makeAnotherReg (I.getType ());
|
||||||
|
|
||||||
// FIXME: support long, ulong, fp.
|
// FIXME: support long, ulong, fp.
|
||||||
switch (I.getOpcode ()) {
|
switch (I.getOpcode ()) {
|
||||||
case Instruction::Add: OpCase = 0; break;
|
case Instruction::Add: OpCase = 0; break;
|
||||||
@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do the other half of the value:
|
// Do the other half of the value:
|
||||||
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
|
||||||
|
.addReg (Op1Reg+1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
visitInstruction (I);
|
visitInstruction (I);
|
||||||
@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
|
|||||||
unsigned DestReg = getReg (I);
|
unsigned DestReg = getReg (I);
|
||||||
const Type *Ty = I.getOperand (0)->getType ();
|
const Type *Ty = I.getOperand (0)->getType ();
|
||||||
|
|
||||||
|
assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
|
||||||
// Compare the two values.
|
// Compare the two values.
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
|
|
||||||
|
@ -86,8 +86,6 @@ namespace {
|
|||||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||||
void visitAllocaInst(AllocaInst &I);
|
void visitAllocaInst(AllocaInst &I);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void visitInstruction(Instruction &I) {
|
void visitInstruction(Instruction &I) {
|
||||||
std::cerr << "Unhandled instruction: " << I;
|
std::cerr << "Unhandled instruction: " << I;
|
||||||
abort();
|
abort();
|
||||||
@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (newTyClass == cFloat) {
|
if (newTyClass == cFloat) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
case cDouble:
|
case cDouble:
|
||||||
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast int to float. Store it to a stack slot and then load
|
||||||
// it using ldf into a floating point register. then do fitos.
|
// it using ldf into a floating point register. then do fitos.
|
||||||
std::cerr << "Casts to float still unsupported: SrcTy = "
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
abort ();
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
} else if (newTyClass == cDouble) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
case cDouble: {
|
||||||
std::cerr << "Casts to double still unsupported: SrcTy = "
|
// go through memory, for now
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
abort ();
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
|
||||||
|
.addSImm (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
std::cerr << "Cast still unsupported: SrcTy = "
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
||||||
@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
|
|||||||
V8::O4, V8::O5 };
|
V8::O4, V8::O5 };
|
||||||
for (unsigned i = 1; i < 7; ++i)
|
for (unsigned i = 1; i < 7; ++i)
|
||||||
if (i < I.getNumOperands ()) {
|
if (i < I.getNumOperands ()) {
|
||||||
|
assert (getClassB (I.getOperand (i)->getType ()) < cLong
|
||||||
|
&& "Can't handle long or fp function call arguments yet");
|
||||||
unsigned ArgReg = getReg (I.getOperand (i));
|
unsigned ArgReg = getReg (I.getOperand (i));
|
||||||
// Schlep it over into the incoming arg register
|
// Schlep it over into the incoming arg register
|
||||||
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
||||||
@ -789,11 +811,30 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
unsigned Op0Reg = getReg (I.getOperand (0));
|
unsigned Op0Reg = getReg (I.getOperand (0));
|
||||||
unsigned Op1Reg = getReg (I.getOperand (1));
|
unsigned Op1Reg = getReg (I.getOperand (1));
|
||||||
|
|
||||||
unsigned ResultReg = DestReg;
|
unsigned Class = getClassB (I.getType());
|
||||||
if (getClassB(I.getType()) != cInt)
|
|
||||||
ResultReg = makeAnotherReg (I.getType ());
|
|
||||||
unsigned OpCase = ~0;
|
unsigned OpCase = ~0;
|
||||||
|
|
||||||
|
if (Class > cLong) {
|
||||||
|
switch (I.getOpcode ()) {
|
||||||
|
case Instruction::Add: OpCase = 0; break;
|
||||||
|
case Instruction::Sub: OpCase = 1; break;
|
||||||
|
case Instruction::Mul: OpCase = 2; break;
|
||||||
|
case Instruction::Div: OpCase = 3; break;
|
||||||
|
default: visitInstruction (I); return;
|
||||||
|
}
|
||||||
|
static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
|
||||||
|
V8::FSUBS, V8::FSUBD,
|
||||||
|
V8::FMULS, V8::FMULD,
|
||||||
|
V8::FDIVS, V8::FDIVD };
|
||||||
|
BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
|
||||||
|
.addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ResultReg = DestReg;
|
||||||
|
if (Class != cInt)
|
||||||
|
ResultReg = makeAnotherReg (I.getType ());
|
||||||
|
|
||||||
// FIXME: support long, ulong, fp.
|
// FIXME: support long, ulong, fp.
|
||||||
switch (I.getOpcode ()) {
|
switch (I.getOpcode ()) {
|
||||||
case Instruction::Add: OpCase = 0; break;
|
case Instruction::Add: OpCase = 0; break;
|
||||||
@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do the other half of the value:
|
// Do the other half of the value:
|
||||||
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
|
||||||
|
.addReg (Op1Reg+1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
visitInstruction (I);
|
visitInstruction (I);
|
||||||
@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
|
|||||||
unsigned DestReg = getReg (I);
|
unsigned DestReg = getReg (I);
|
||||||
const Type *Ty = I.getOperand (0)->getType ();
|
const Type *Ty = I.getOperand (0)->getType ();
|
||||||
|
|
||||||
|
assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
|
||||||
// Compare the two values.
|
// Compare the two values.
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
|
|
||||||
|
@ -86,8 +86,6 @@ namespace {
|
|||||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||||
void visitAllocaInst(AllocaInst &I);
|
void visitAllocaInst(AllocaInst &I);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void visitInstruction(Instruction &I) {
|
void visitInstruction(Instruction &I) {
|
||||||
std::cerr << "Unhandled instruction: " << I;
|
std::cerr << "Unhandled instruction: " << I;
|
||||||
abort();
|
abort();
|
||||||
@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (newTyClass == cFloat) {
|
if (newTyClass == cFloat) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
case cDouble:
|
case cDouble:
|
||||||
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast int to float. Store it to a stack slot and then load
|
||||||
// it using ldf into a floating point register. then do fitos.
|
// it using ldf into a floating point register. then do fitos.
|
||||||
std::cerr << "Casts to float still unsupported: SrcTy = "
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
abort ();
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
} else if (newTyClass == cDouble) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
case cDouble: {
|
||||||
std::cerr << "Casts to double still unsupported: SrcTy = "
|
// go through memory, for now
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
abort ();
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
|
||||||
|
.addSImm (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
std::cerr << "Cast still unsupported: SrcTy = "
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
||||||
@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
|
|||||||
V8::O4, V8::O5 };
|
V8::O4, V8::O5 };
|
||||||
for (unsigned i = 1; i < 7; ++i)
|
for (unsigned i = 1; i < 7; ++i)
|
||||||
if (i < I.getNumOperands ()) {
|
if (i < I.getNumOperands ()) {
|
||||||
|
assert (getClassB (I.getOperand (i)->getType ()) < cLong
|
||||||
|
&& "Can't handle long or fp function call arguments yet");
|
||||||
unsigned ArgReg = getReg (I.getOperand (i));
|
unsigned ArgReg = getReg (I.getOperand (i));
|
||||||
// Schlep it over into the incoming arg register
|
// Schlep it over into the incoming arg register
|
||||||
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
||||||
@ -789,11 +811,30 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
unsigned Op0Reg = getReg (I.getOperand (0));
|
unsigned Op0Reg = getReg (I.getOperand (0));
|
||||||
unsigned Op1Reg = getReg (I.getOperand (1));
|
unsigned Op1Reg = getReg (I.getOperand (1));
|
||||||
|
|
||||||
unsigned ResultReg = DestReg;
|
unsigned Class = getClassB (I.getType());
|
||||||
if (getClassB(I.getType()) != cInt)
|
|
||||||
ResultReg = makeAnotherReg (I.getType ());
|
|
||||||
unsigned OpCase = ~0;
|
unsigned OpCase = ~0;
|
||||||
|
|
||||||
|
if (Class > cLong) {
|
||||||
|
switch (I.getOpcode ()) {
|
||||||
|
case Instruction::Add: OpCase = 0; break;
|
||||||
|
case Instruction::Sub: OpCase = 1; break;
|
||||||
|
case Instruction::Mul: OpCase = 2; break;
|
||||||
|
case Instruction::Div: OpCase = 3; break;
|
||||||
|
default: visitInstruction (I); return;
|
||||||
|
}
|
||||||
|
static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
|
||||||
|
V8::FSUBS, V8::FSUBD,
|
||||||
|
V8::FMULS, V8::FMULD,
|
||||||
|
V8::FDIVS, V8::FDIVD };
|
||||||
|
BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
|
||||||
|
.addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ResultReg = DestReg;
|
||||||
|
if (Class != cInt)
|
||||||
|
ResultReg = makeAnotherReg (I.getType ());
|
||||||
|
|
||||||
// FIXME: support long, ulong, fp.
|
// FIXME: support long, ulong, fp.
|
||||||
switch (I.getOpcode ()) {
|
switch (I.getOpcode ()) {
|
||||||
case Instruction::Add: OpCase = 0; break;
|
case Instruction::Add: OpCase = 0; break;
|
||||||
@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do the other half of the value:
|
// Do the other half of the value:
|
||||||
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
|
||||||
|
.addReg (Op1Reg+1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
visitInstruction (I);
|
visitInstruction (I);
|
||||||
@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
|
|||||||
unsigned DestReg = getReg (I);
|
unsigned DestReg = getReg (I);
|
||||||
const Type *Ty = I.getOperand (0)->getType ();
|
const Type *Ty = I.getOperand (0)->getType ();
|
||||||
|
|
||||||
|
assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
|
||||||
// Compare the two values.
|
// Compare the two values.
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
|
|
||||||
|
@ -86,8 +86,6 @@ namespace {
|
|||||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||||
void visitAllocaInst(AllocaInst &I);
|
void visitAllocaInst(AllocaInst &I);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void visitInstruction(Instruction &I) {
|
void visitInstruction(Instruction &I) {
|
||||||
std::cerr << "Unhandled instruction: " << I;
|
std::cerr << "Unhandled instruction: " << I;
|
||||||
abort();
|
abort();
|
||||||
@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (newTyClass == cFloat) {
|
if (newTyClass == cFloat) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
case cDouble:
|
case cDouble:
|
||||||
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
default: {
|
||||||
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast int to float. Store it to a stack slot and then load
|
||||||
// it using ldf into a floating point register. then do fitos.
|
// it using ldf into a floating point register. then do fitos.
|
||||||
std::cerr << "Casts to float still unsupported: SrcTy = "
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
abort ();
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
} else if (newTyClass == cDouble) {
|
||||||
|
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
default:
|
case cDouble: {
|
||||||
std::cerr << "Casts to double still unsupported: SrcTy = "
|
// go through memory, for now
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
abort ();
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
|
||||||
|
.addSImm (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default: {
|
||||||
|
unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
|
||||||
|
BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (SrcReg);
|
||||||
|
BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
|
||||||
|
BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
std::cerr << "Cast still unsupported: SrcTy = "
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
||||||
@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
|
|||||||
V8::O4, V8::O5 };
|
V8::O4, V8::O5 };
|
||||||
for (unsigned i = 1; i < 7; ++i)
|
for (unsigned i = 1; i < 7; ++i)
|
||||||
if (i < I.getNumOperands ()) {
|
if (i < I.getNumOperands ()) {
|
||||||
|
assert (getClassB (I.getOperand (i)->getType ()) < cLong
|
||||||
|
&& "Can't handle long or fp function call arguments yet");
|
||||||
unsigned ArgReg = getReg (I.getOperand (i));
|
unsigned ArgReg = getReg (I.getOperand (i));
|
||||||
// Schlep it over into the incoming arg register
|
// Schlep it over into the incoming arg register
|
||||||
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
|
||||||
@ -789,11 +811,30 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
unsigned Op0Reg = getReg (I.getOperand (0));
|
unsigned Op0Reg = getReg (I.getOperand (0));
|
||||||
unsigned Op1Reg = getReg (I.getOperand (1));
|
unsigned Op1Reg = getReg (I.getOperand (1));
|
||||||
|
|
||||||
unsigned ResultReg = DestReg;
|
unsigned Class = getClassB (I.getType());
|
||||||
if (getClassB(I.getType()) != cInt)
|
|
||||||
ResultReg = makeAnotherReg (I.getType ());
|
|
||||||
unsigned OpCase = ~0;
|
unsigned OpCase = ~0;
|
||||||
|
|
||||||
|
if (Class > cLong) {
|
||||||
|
switch (I.getOpcode ()) {
|
||||||
|
case Instruction::Add: OpCase = 0; break;
|
||||||
|
case Instruction::Sub: OpCase = 1; break;
|
||||||
|
case Instruction::Mul: OpCase = 2; break;
|
||||||
|
case Instruction::Div: OpCase = 3; break;
|
||||||
|
default: visitInstruction (I); return;
|
||||||
|
}
|
||||||
|
static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
|
||||||
|
V8::FSUBS, V8::FSUBD,
|
||||||
|
V8::FMULS, V8::FMULD,
|
||||||
|
V8::FDIVS, V8::FDIVD };
|
||||||
|
BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
|
||||||
|
.addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned ResultReg = DestReg;
|
||||||
|
if (Class != cInt)
|
||||||
|
ResultReg = makeAnotherReg (I.getType ());
|
||||||
|
|
||||||
// FIXME: support long, ulong, fp.
|
// FIXME: support long, ulong, fp.
|
||||||
switch (I.getOpcode ()) {
|
switch (I.getOpcode ()) {
|
||||||
case Instruction::Add: OpCase = 0; break;
|
case Instruction::Add: OpCase = 0; break;
|
||||||
@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Do the other half of the value:
|
// Do the other half of the value:
|
||||||
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
|
||||||
|
.addReg (Op1Reg+1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
visitInstruction (I);
|
visitInstruction (I);
|
||||||
@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
|
|||||||
unsigned DestReg = getReg (I);
|
unsigned DestReg = getReg (I);
|
||||||
const Type *Ty = I.getOperand (0)->getType ();
|
const Type *Ty = I.getOperand (0)->getType ();
|
||||||
|
|
||||||
|
assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
|
||||||
// Compare the two values.
|
// Compare the two values.
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user