From 8b6c1ff677fbd47f8d09d3bae37a388a6ae527c2 Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Thu, 14 Oct 2004 19:39:34 +0000 Subject: [PATCH] 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 --- lib/Target/Sparc/SparcV8ISelSimple.cpp | 146 +++++++++++++++++++------------ lib/Target/SparcV8/SparcV8ISelSimple.cpp | 146 +++++++++++++++++++------------ 2 files changed, 184 insertions(+), 108 deletions(-) diff --git a/lib/Target/Sparc/SparcV8ISelSimple.cpp b/lib/Target/Sparc/SparcV8ISelSimple.cpp index ce91a37958b..93711eaeeb4 100644 --- a/lib/Target/Sparc/SparcV8ISelSimple.cpp +++ b/lib/Target/Sparc/SparcV8ISelSimple.cpp @@ -64,6 +64,17 @@ namespace { void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP, 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 /// block. This simply creates a new MachineBasicBlock to emit code into /// 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); } + +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 /// expression cast support. /// void V8ISel::emitCastOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator IP, - Value *Src, const Type *DestTy, - unsigned DestReg) { + MachineBasicBlock::iterator IP, Value *Src, + const Type *DestTy, unsigned DestReg) { const Type *SrcTy = Src->getType(); unsigned SrcClass = getClassB(SrcTy); unsigned DestClass = getClassB(DestTy); @@ -552,45 +606,23 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, unsigned newTyClass = DestClass; if (oldTyClass < cLong && newTyClass < cLong) { - if (oldTyClass >= newTyClass) { - // Emit a reg->reg copy to do a equal-size or narrowing cast, - // and do sign/zero extension (necessary if we change signedness). - unsigned TmpReg1 = makeAnotherReg (newTy); - unsigned TmpReg2 = makeAnotherReg (newTy); - 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); + emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg); + } else switch (newTyClass) { + case cByte: + case cShort: + case cInt: + switch (oldTyClass) { + case cFloat: + case cDouble: + emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg); + break; + default: goto not_yet; } - } - } else { - if (newTyClass == cFloat) { - assert (oldTyClass != cLong && "cast long to float not implemented yet"); + return; + + case cFloat: switch (oldTyClass) { + case cLong: goto not_yet; case cFloat: BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg); break; @@ -599,7 +631,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; default: { 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. unsigned TmpReg = makeAnotherReg (newTy); int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign); @@ -610,9 +642,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; } } - } else if (newTyClass == cDouble) { - assert (oldTyClass != cLong && "cast long to double not implemented yet"); + return; + + case cDouble: switch (oldTyClass) { + case cLong: goto not_yet; case cFloat: BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg); break; @@ -630,23 +664,27 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; } } - } else if (newTyClass == cLong) { - if (oldTyClass == cLong) { + return; + + case cLong: + switch (oldTyClass) { + case cLong: // Just copy it BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0) .addReg (SrcReg+1); - } else { - std::cerr << "Cast still unsupported: SrcTy = " - << *SrcTy << ", DestTy = " << *DestTy << "\n"; - abort (); + break; + default: goto not_yet; } - } else { - std::cerr << "Cast still unsupported: SrcTy = " - << *SrcTy << ", DestTy = " << *DestTy << "\n"; - abort (); - } + return; + + default: goto not_yet; } + return; +not_yet: + std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy + << ", DestTy = " << *DestTy << "\n"; + abort (); } void V8ISel::visitLoadInst(LoadInst &I) { diff --git a/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/lib/Target/SparcV8/SparcV8ISelSimple.cpp index ce91a37958b..93711eaeeb4 100644 --- a/lib/Target/SparcV8/SparcV8ISelSimple.cpp +++ b/lib/Target/SparcV8/SparcV8ISelSimple.cpp @@ -64,6 +64,17 @@ namespace { void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP, 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 /// block. This simply creates a new MachineBasicBlock to emit code into /// 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); } + +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 /// expression cast support. /// void V8ISel::emitCastOperation(MachineBasicBlock *BB, - MachineBasicBlock::iterator IP, - Value *Src, const Type *DestTy, - unsigned DestReg) { + MachineBasicBlock::iterator IP, Value *Src, + const Type *DestTy, unsigned DestReg) { const Type *SrcTy = Src->getType(); unsigned SrcClass = getClassB(SrcTy); unsigned DestClass = getClassB(DestTy); @@ -552,45 +606,23 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, unsigned newTyClass = DestClass; if (oldTyClass < cLong && newTyClass < cLong) { - if (oldTyClass >= newTyClass) { - // Emit a reg->reg copy to do a equal-size or narrowing cast, - // and do sign/zero extension (necessary if we change signedness). - unsigned TmpReg1 = makeAnotherReg (newTy); - unsigned TmpReg2 = makeAnotherReg (newTy); - 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); + emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg); + } else switch (newTyClass) { + case cByte: + case cShort: + case cInt: + switch (oldTyClass) { + case cFloat: + case cDouble: + emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg); + break; + default: goto not_yet; } - } - } else { - if (newTyClass == cFloat) { - assert (oldTyClass != cLong && "cast long to float not implemented yet"); + return; + + case cFloat: switch (oldTyClass) { + case cLong: goto not_yet; case cFloat: BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg); break; @@ -599,7 +631,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; default: { 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. unsigned TmpReg = makeAnotherReg (newTy); int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign); @@ -610,9 +642,11 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; } } - } else if (newTyClass == cDouble) { - assert (oldTyClass != cLong && "cast long to double not implemented yet"); + return; + + case cDouble: switch (oldTyClass) { + case cLong: goto not_yet; case cFloat: BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg); break; @@ -630,23 +664,27 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB, break; } } - } else if (newTyClass == cLong) { - if (oldTyClass == cLong) { + return; + + case cLong: + switch (oldTyClass) { + case cLong: // Just copy it BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0) .addReg (SrcReg+1); - } else { - std::cerr << "Cast still unsupported: SrcTy = " - << *SrcTy << ", DestTy = " << *DestTy << "\n"; - abort (); + break; + default: goto not_yet; } - } else { - std::cerr << "Cast still unsupported: SrcTy = " - << *SrcTy << ", DestTy = " << *DestTy << "\n"; - abort (); - } + return; + + default: goto not_yet; } + return; +not_yet: + std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy + << ", DestTy = " << *DestTy << "\n"; + abort (); } void V8ISel::visitLoadInst(LoadInst &I) { -- 2.11.0