[llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Dec 6 04:50:00 PST 2002
Changes in directory llvm/lib/Target/X86:
InstSelectSimple.cpp updated: 1.52 -> 1.53
---
Log message:
Implement a lot of cast functionality (no FP or 64)
---
Diffs of the changes:
Index: llvm/lib/Target/X86/InstSelectSimple.cpp
diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.52 llvm/lib/Target/X86/InstSelectSimple.cpp:1.53
--- llvm/lib/Target/X86/InstSelectSimple.cpp:1.52 Wed Dec 4 17:50:28 2002
+++ llvm/lib/Target/X86/InstSelectSimple.cpp Fri Dec 6 04:49:33 2002
@@ -665,45 +665,73 @@
void
ISel::visitCastInst (CastInst &CI)
{
-//> cast larger int to smaller int --> copy least significant byte/word w/ mov?
-//
-//I'm not really sure what to do with this. We could insert a pseudo-op
-//that says take the low X bits of a Y bit register, but for now we can just
-//force the value into, say, EAX, then rip out AL or AX. The advantage of
-//the former is that the register allocator could use any register it wants,
-//but for now this obviously doesn't matter. :)
-
const Type *targetType = CI.getType ();
Value *operand = CI.getOperand (0);
unsigned int operandReg = getReg (operand);
const Type *sourceType = operand->getType ();
unsigned int destReg = getReg (CI);
-
- // cast to bool:
- if (targetType == Type::BoolTy) {
- // Emit Compare
- BuildMI (BB, X86::CMPri8, 2).addReg (operandReg).addZImm (0);
- // Emit Set-if-not-zero
- BuildMI (BB, X86::SETNEr, 1, destReg);
- return;
- }
-
-// if size of target type == size of source type
-// Emit Mov reg(target) <- reg(source)
-
-// if size of target type > size of source type
-// if both types are integer types
-// if source type is signed
-// sbyte to short, ushort: Emit movsx 8->16
-// sbyte to int, uint: Emit movsx 8->32
-// short to int, uint: Emit movsx 16->32
-// else if source type is unsigned
-// ubyte to short, ushort: Emit movzx 8->16
-// ubyte to int, uint: Emit movzx 8->32
-// ushort to int, uint: Emit movzx 16->32
-// if both types are fp types
-// float to double: Emit fstp, fld (???)
-
+ //
+ // Currently we handle:
+ //
+ // 1) cast * to bool
+ //
+ // 2) cast {sbyte, ubyte} to {sbyte, ubyte}
+ // cast {short, ushort} to {ushort, short}
+ // cast {int, uint, ptr} to {int, uint, ptr}
+ //
+ // 3) cast {sbyte, ubyte} to {ushort, short}
+ // cast {sbyte, ubyte} to {int, uint, ptr}
+ // cast {short, ushort} to {int, uint, ptr}
+ //
+ // 4) cast {int, uint, ptr} to {short, ushort}
+ // cast {int, uint, ptr} to {sbyte, ubyte}
+ // cast {short, ushort} to {sbyte, ubyte}
+ //
+ // 1) Implement casts to bool by using compare on the operand followed
+ // by set if not zero on the result.
+ if (targetType == Type::BoolTy)
+ {
+ BuildMI (BB, X86::CMPri8, 2).addReg (operandReg).addZImm (0);
+ BuildMI (BB, X86::SETNEr, 1, destReg);
+ return;
+ }
+ // 2) Implement casts between values of the same type class (as determined
+ // by getClass) by using a register-to-register move.
+ unsigned int srcClass = getClass (sourceType);
+ unsigned int targClass = getClass (targetType);
+ static const unsigned regRegMove[] = {
+ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32
+ };
+ if ((srcClass < 3) && (targClass < 3) && (srcClass == targClass))
+ {
+ BuildMI (BB, regRegMove[srcClass], 1, destReg).addReg (operandReg);
+ return;
+ }
+ // 3) Handle cast of SMALLER int to LARGER int using a move with sign
+ // extension or zero extension, depending on whether the source type
+ // was signed.
+ if ((srcClass < 3) && (targClass < 3) && (srcClass < targClass))
+ {
+ static const unsigned ops[] = {
+ X86::MOVSXr16r8, X86::MOVSXr32r8, X86::MOVSXr32r16,
+ X86::MOVZXr16r8, X86::MOVZXr32r8, X86::MOVZXr32r16
+ };
+ unsigned srcSigned = sourceType->isSigned ();
+ BuildMI (BB, ops[3 * srcSigned + srcClass + targClass - 1], 1,
+ destReg).addReg (operandReg);
+ return;
+ }
+ // 4) Handle cast of LARGER int to SMALLER int using a move to EAX
+ // followed by a move out of AX or AL.
+ if ((srcClass < 3) && (targClass < 3) && (srcClass > targClass))
+ {
+ static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX };
+ BuildMI (BB, regRegMove[srcClass], 1,
+ AReg[srcClass]).addReg (operandReg);
+ BuildMI (BB, regRegMove[targClass], 1, destReg).addReg (AReg[srcClass]);
+ return;
+ }
+ // Anything we haven't handled already, we can't (yet) handle at all.
visitInstruction (CI);
}
More information about the llvm-commits
mailing list