mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Rewrite emitCastOperation, refactoring parts of it into emitIntegerCast, and
adding emitFPToIntegerCast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16995 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
941833a37c
commit
8b6c1ff677
@ -64,6 +64,17 @@ namespace {
|
|||||||
void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
|
void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
|
||||||
Value *Src, const Type *DestTy, unsigned TargetReg);
|
Value *Src, const Type *DestTy, unsigned TargetReg);
|
||||||
|
|
||||||
|
/// emitIntegerCast, emitFPToIntegerCast - Helper methods for
|
||||||
|
/// emitCastOperation.
|
||||||
|
///
|
||||||
|
void emitIntegerCast (MachineBasicBlock *BB, MachineBasicBlock::iterator IP,
|
||||||
|
const Type *oldTy, unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg);
|
||||||
|
void emitFPToIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP, const Type *oldTy,
|
||||||
|
unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg);
|
||||||
|
|
||||||
/// visitBasicBlock - This method is called when we are visiting a new basic
|
/// visitBasicBlock - This method is called when we are visiting a new basic
|
||||||
/// block. This simply creates a new MachineBasicBlock to emit code into
|
/// block. This simply creates a new MachineBasicBlock to emit code into
|
||||||
/// and adds it to the current MachineFunction. Subsequent visit* for
|
/// and adds it to the current MachineFunction. Subsequent visit* for
|
||||||
@ -534,13 +545,56 @@ void V8ISel::visitCastInst(CastInst &I) {
|
|||||||
emitCastOperation(BB, MI, Op, I.getType(), DestReg);
|
emitCastOperation(BB, MI, Op, I.getType(), DestReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void V8ISel::emitIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP, const Type *oldTy,
|
||||||
|
unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg) {
|
||||||
|
if (oldTy == newTy) {
|
||||||
|
// No-op cast - just emit a copy; assume the reg. allocator will zap it.
|
||||||
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg(SrcReg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Emit left-shift, then right-shift to sign- or zero-extend.
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
||||||
|
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg).addZImm (shiftWidth).addReg(SrcReg);
|
||||||
|
if (newTy->isSigned ()) { // sign-extend with SRA
|
||||||
|
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
|
||||||
|
} else { // zero-extend with SRL
|
||||||
|
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP,
|
||||||
|
const Type *oldTy, unsigned SrcReg,
|
||||||
|
const Type *newTy, unsigned DestReg) {
|
||||||
|
unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
|
||||||
|
unsigned oldTyClass = getClassB(oldTy);
|
||||||
|
if (oldTyClass == cFloat) {
|
||||||
|
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
|
||||||
|
FPAlign = TM.getTargetData().getFloatAlignment();
|
||||||
|
} else { // it's a double
|
||||||
|
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
|
||||||
|
FPAlign = TM.getTargetData().getDoubleAlignment();
|
||||||
|
}
|
||||||
|
unsigned TempReg = makeAnotherReg (oldTy);
|
||||||
|
BuildMI (*BB, IP, FPCastOpcode, 1, TempReg).addReg (SrcReg);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(FPSize, FPAlign);
|
||||||
|
BuildMI (*BB, IP, FPStoreOpcode, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (TempReg);
|
||||||
|
unsigned TempReg2 = makeAnotherReg (newTy);
|
||||||
|
BuildMI (*BB, IP, V8::LD, 3, TempReg2).addFrameIndex (FI).addSImm (0);
|
||||||
|
emitIntegerCast (BB, IP, Type::IntTy, TempReg2, newTy, DestReg);
|
||||||
|
}
|
||||||
|
|
||||||
/// emitCastOperation - Common code shared between visitCastInst and constant
|
/// emitCastOperation - Common code shared between visitCastInst and constant
|
||||||
/// expression cast support.
|
/// expression cast support.
|
||||||
///
|
///
|
||||||
void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
||||||
MachineBasicBlock::iterator IP,
|
MachineBasicBlock::iterator IP, Value *Src,
|
||||||
Value *Src, const Type *DestTy,
|
const Type *DestTy, unsigned DestReg) {
|
||||||
unsigned DestReg) {
|
|
||||||
const Type *SrcTy = Src->getType();
|
const Type *SrcTy = Src->getType();
|
||||||
unsigned SrcClass = getClassB(SrcTy);
|
unsigned SrcClass = getClassB(SrcTy);
|
||||||
unsigned DestClass = getClassB(DestTy);
|
unsigned DestClass = getClassB(DestTy);
|
||||||
@ -552,45 +606,23 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
unsigned newTyClass = DestClass;
|
unsigned newTyClass = DestClass;
|
||||||
|
|
||||||
if (oldTyClass < cLong && newTyClass < cLong) {
|
if (oldTyClass < cLong && newTyClass < cLong) {
|
||||||
if (oldTyClass >= newTyClass) {
|
emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
|
||||||
// Emit a reg->reg copy to do a equal-size or narrowing cast,
|
} else switch (newTyClass) {
|
||||||
// and do sign/zero extension (necessary if we change signedness).
|
case cByte:
|
||||||
unsigned TmpReg1 = makeAnotherReg (newTy);
|
case cShort:
|
||||||
unsigned TmpReg2 = makeAnotherReg (newTy);
|
case cInt:
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, TmpReg1).addReg (V8::G0).addReg (SrcReg);
|
|
||||||
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
if (newTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned TmpReg1 = makeAnotherReg (oldTy);
|
|
||||||
unsigned TmpReg2 = makeAnotherReg (newTy);
|
|
||||||
unsigned TmpReg3 = makeAnotherReg (newTy);
|
|
||||||
// Widening integer cast. Make sure it's fully sign/zero-extended
|
|
||||||
// wrt the input type, then make sure it's fully sign/zero-extended wrt
|
|
||||||
// the output type. Kind of stupid, but simple...
|
|
||||||
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (oldTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg1).addZImm (shiftWidth).addReg(SrcReg);
|
|
||||||
if (oldTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
}
|
|
||||||
shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg3).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
if (newTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg3);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (newTyClass == cFloat) {
|
|
||||||
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
|
case cFloat:
|
||||||
|
case cDouble:
|
||||||
|
emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
|
||||||
|
break;
|
||||||
|
default: goto not_yet;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case cFloat:
|
||||||
|
switch (oldTyClass) {
|
||||||
|
case cLong: goto not_yet;
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
@ -599,7 +631,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast integer type 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.
|
||||||
unsigned TmpReg = makeAnotherReg (newTy);
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
@ -610,9 +642,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
return;
|
||||||
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
|
||||||
|
case cDouble:
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
|
case cLong: goto not_yet;
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
@ -630,23 +664,27 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (newTyClass == cLong) {
|
return;
|
||||||
if (oldTyClass == cLong) {
|
|
||||||
|
case cLong:
|
||||||
|
switch (oldTyClass) {
|
||||||
|
case cLong:
|
||||||
// Just copy it
|
// Just copy it
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
|
||||||
.addReg (SrcReg+1);
|
.addReg (SrcReg+1);
|
||||||
} else {
|
break;
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
default: goto not_yet;
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
|
||||||
abort ();
|
|
||||||
}
|
}
|
||||||
} else {
|
return;
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
default: goto not_yet;
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
not_yet:
|
||||||
|
std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy
|
||||||
|
<< ", DestTy = " << *DestTy << "\n";
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void V8ISel::visitLoadInst(LoadInst &I) {
|
void V8ISel::visitLoadInst(LoadInst &I) {
|
||||||
|
@ -64,6 +64,17 @@ namespace {
|
|||||||
void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
|
void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
|
||||||
Value *Src, const Type *DestTy, unsigned TargetReg);
|
Value *Src, const Type *DestTy, unsigned TargetReg);
|
||||||
|
|
||||||
|
/// emitIntegerCast, emitFPToIntegerCast - Helper methods for
|
||||||
|
/// emitCastOperation.
|
||||||
|
///
|
||||||
|
void emitIntegerCast (MachineBasicBlock *BB, MachineBasicBlock::iterator IP,
|
||||||
|
const Type *oldTy, unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg);
|
||||||
|
void emitFPToIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP, const Type *oldTy,
|
||||||
|
unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg);
|
||||||
|
|
||||||
/// visitBasicBlock - This method is called when we are visiting a new basic
|
/// visitBasicBlock - This method is called when we are visiting a new basic
|
||||||
/// block. This simply creates a new MachineBasicBlock to emit code into
|
/// block. This simply creates a new MachineBasicBlock to emit code into
|
||||||
/// and adds it to the current MachineFunction. Subsequent visit* for
|
/// and adds it to the current MachineFunction. Subsequent visit* for
|
||||||
@ -534,13 +545,56 @@ void V8ISel::visitCastInst(CastInst &I) {
|
|||||||
emitCastOperation(BB, MI, Op, I.getType(), DestReg);
|
emitCastOperation(BB, MI, Op, I.getType(), DestReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void V8ISel::emitIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP, const Type *oldTy,
|
||||||
|
unsigned SrcReg, const Type *newTy,
|
||||||
|
unsigned DestReg) {
|
||||||
|
if (oldTy == newTy) {
|
||||||
|
// No-op cast - just emit a copy; assume the reg. allocator will zap it.
|
||||||
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg(SrcReg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Emit left-shift, then right-shift to sign- or zero-extend.
|
||||||
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
|
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
||||||
|
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg).addZImm (shiftWidth).addReg(SrcReg);
|
||||||
|
if (newTy->isSigned ()) { // sign-extend with SRA
|
||||||
|
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
|
||||||
|
} else { // zero-extend with SRL
|
||||||
|
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
|
||||||
|
MachineBasicBlock::iterator IP,
|
||||||
|
const Type *oldTy, unsigned SrcReg,
|
||||||
|
const Type *newTy, unsigned DestReg) {
|
||||||
|
unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
|
||||||
|
unsigned oldTyClass = getClassB(oldTy);
|
||||||
|
if (oldTyClass == cFloat) {
|
||||||
|
FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
|
||||||
|
FPAlign = TM.getTargetData().getFloatAlignment();
|
||||||
|
} else { // it's a double
|
||||||
|
FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
|
||||||
|
FPAlign = TM.getTargetData().getDoubleAlignment();
|
||||||
|
}
|
||||||
|
unsigned TempReg = makeAnotherReg (oldTy);
|
||||||
|
BuildMI (*BB, IP, FPCastOpcode, 1, TempReg).addReg (SrcReg);
|
||||||
|
int FI = F->getFrameInfo()->CreateStackObject(FPSize, FPAlign);
|
||||||
|
BuildMI (*BB, IP, FPStoreOpcode, 3).addFrameIndex (FI).addSImm (0)
|
||||||
|
.addReg (TempReg);
|
||||||
|
unsigned TempReg2 = makeAnotherReg (newTy);
|
||||||
|
BuildMI (*BB, IP, V8::LD, 3, TempReg2).addFrameIndex (FI).addSImm (0);
|
||||||
|
emitIntegerCast (BB, IP, Type::IntTy, TempReg2, newTy, DestReg);
|
||||||
|
}
|
||||||
|
|
||||||
/// emitCastOperation - Common code shared between visitCastInst and constant
|
/// emitCastOperation - Common code shared between visitCastInst and constant
|
||||||
/// expression cast support.
|
/// expression cast support.
|
||||||
///
|
///
|
||||||
void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
||||||
MachineBasicBlock::iterator IP,
|
MachineBasicBlock::iterator IP, Value *Src,
|
||||||
Value *Src, const Type *DestTy,
|
const Type *DestTy, unsigned DestReg) {
|
||||||
unsigned DestReg) {
|
|
||||||
const Type *SrcTy = Src->getType();
|
const Type *SrcTy = Src->getType();
|
||||||
unsigned SrcClass = getClassB(SrcTy);
|
unsigned SrcClass = getClassB(SrcTy);
|
||||||
unsigned DestClass = getClassB(DestTy);
|
unsigned DestClass = getClassB(DestTy);
|
||||||
@ -552,45 +606,23 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
unsigned newTyClass = DestClass;
|
unsigned newTyClass = DestClass;
|
||||||
|
|
||||||
if (oldTyClass < cLong && newTyClass < cLong) {
|
if (oldTyClass < cLong && newTyClass < cLong) {
|
||||||
if (oldTyClass >= newTyClass) {
|
emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
|
||||||
// Emit a reg->reg copy to do a equal-size or narrowing cast,
|
} else switch (newTyClass) {
|
||||||
// and do sign/zero extension (necessary if we change signedness).
|
case cByte:
|
||||||
unsigned TmpReg1 = makeAnotherReg (newTy);
|
case cShort:
|
||||||
unsigned TmpReg2 = makeAnotherReg (newTy);
|
case cInt:
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, TmpReg1).addReg (V8::G0).addReg (SrcReg);
|
|
||||||
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
if (newTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned TmpReg1 = makeAnotherReg (oldTy);
|
|
||||||
unsigned TmpReg2 = makeAnotherReg (newTy);
|
|
||||||
unsigned TmpReg3 = makeAnotherReg (newTy);
|
|
||||||
// Widening integer cast. Make sure it's fully sign/zero-extended
|
|
||||||
// wrt the input type, then make sure it's fully sign/zero-extended wrt
|
|
||||||
// the output type. Kind of stupid, but simple...
|
|
||||||
unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (oldTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg1).addZImm (shiftWidth).addReg(SrcReg);
|
|
||||||
if (oldTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, TmpReg2).addZImm (shiftWidth).addReg(TmpReg1);
|
|
||||||
}
|
|
||||||
shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
|
|
||||||
BuildMI (*BB, IP, V8::SLLri, 2, TmpReg3).addZImm (shiftWidth).addReg(TmpReg2);
|
|
||||||
if (newTy->isSigned ()) { // sign-extend with SRA
|
|
||||||
BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg3);
|
|
||||||
} else { // zero-extend with SRL
|
|
||||||
BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (newTyClass == cFloat) {
|
|
||||||
assert (oldTyClass != cLong && "cast long to float not implemented yet");
|
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
|
case cFloat:
|
||||||
|
case cDouble:
|
||||||
|
emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
|
||||||
|
break;
|
||||||
|
default: goto not_yet;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case cFloat:
|
||||||
|
switch (oldTyClass) {
|
||||||
|
case cLong: goto not_yet;
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
@ -599,7 +631,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
unsigned FltAlign = TM.getTargetData().getFloatAlignment();
|
||||||
// cast int to float. Store it to a stack slot and then load
|
// cast integer type 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.
|
||||||
unsigned TmpReg = makeAnotherReg (newTy);
|
unsigned TmpReg = makeAnotherReg (newTy);
|
||||||
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
|
||||||
@ -610,9 +642,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (newTyClass == cDouble) {
|
return;
|
||||||
assert (oldTyClass != cLong && "cast long to double not implemented yet");
|
|
||||||
|
case cDouble:
|
||||||
switch (oldTyClass) {
|
switch (oldTyClass) {
|
||||||
|
case cLong: goto not_yet;
|
||||||
case cFloat:
|
case cFloat:
|
||||||
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
|
||||||
break;
|
break;
|
||||||
@ -630,23 +664,27 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (newTyClass == cLong) {
|
return;
|
||||||
if (oldTyClass == cLong) {
|
|
||||||
|
case cLong:
|
||||||
|
switch (oldTyClass) {
|
||||||
|
case cLong:
|
||||||
// Just copy it
|
// Just copy it
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
|
||||||
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
|
BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
|
||||||
.addReg (SrcReg+1);
|
.addReg (SrcReg+1);
|
||||||
} else {
|
break;
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
default: goto not_yet;
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
|
||||||
abort ();
|
|
||||||
}
|
}
|
||||||
} else {
|
return;
|
||||||
std::cerr << "Cast still unsupported: SrcTy = "
|
|
||||||
<< *SrcTy << ", DestTy = " << *DestTy << "\n";
|
default: goto not_yet;
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
not_yet:
|
||||||
|
std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy
|
||||||
|
<< ", DestTy = " << *DestTy << "\n";
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void V8ISel::visitLoadInst(LoadInst &I) {
|
void V8ISel::visitLoadInst(LoadInst &I) {
|
||||||
|
Loading…
Reference in New Issue
Block a user