+/// visitStoreInst - Implement LLVM store instructions in terms of the x86 'mov'
+/// instruction.
+///
+void ISel::visitStoreInst(StoreInst &I) {
+ unsigned Class = getClass(I.getOperand(0)->getType());
+ if (Class > 2) // FIXME: Handle longs and others...
+ visitInstruction(I);
+
+ static const unsigned Opcode[] = { X86::MOVrm8, X86::MOVrm16, X86::MOVrm32 };
+
+ unsigned ValReg = getReg(I.getOperand(0));
+ unsigned AddressReg = getReg(I.getOperand(1));
+ addDirectMem(BuildMI(BB, Opcode[Class], 1+4), AddressReg).addReg(ValReg);
+}
+
+
+/// visitPHINode - Turn an LLVM PHI node into an X86 PHI node...
+///
+void ISel::visitPHINode(PHINode &PN) {
+ MachineInstr *MI = BuildMI(BB, X86::PHI, PN.getNumOperands(), getReg(PN));
+
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+ // FIXME: This will put constants after the PHI nodes in the block, which
+ // is invalid. They should be put inline into the PHI node eventually.
+ //
+ MI->addRegOperand(getReg(PN.getIncomingValue(i)));
+ MI->addPCDispOperand(PN.getIncomingBlock(i));
+ }
+}
+
+/// visitCastInst - Here we have various kinds of copying with or without
+/// sign extension going on.
+void
+ISel::visitCastInst (CastInst &CI)
+{
+ 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);
+ //
+ // 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);
+}