+/// ret long, ulong : Move value into EAX/EDX and return
+/// ret float/double : Top of FP stack
+///
+void
+ISel::visitReturnInst (ReturnInst &I)
+{
+ if (I.getNumOperands () == 0)
+ {
+ // Emit a 'ret' instruction
+ BuildMI (BB, X86::RET, 0);
+ return;
+ }
+ Value *rv = I.getOperand (0);
+ unsigned Class = getClass (rv->getType ());
+ switch (Class)
+ {
+ // integral return values: extend or move into EAX and return.
+ case cByte:
+ case cShort:
+ case cInt:
+ promote32 (X86::EAX, rv);
+ break;
+ // ret float/double: top of FP stack
+ // FLD <val>
+ case cFloat: // Floats
+ BuildMI (BB, X86::FLDr32, 1).addReg (getReg (rv));
+ break;
+ case cDouble: // Doubles
+ BuildMI (BB, X86::FLDr64, 1).addReg (getReg (rv));
+ break;
+ case cLong:
+ // ret long: use EAX(least significant 32 bits)/EDX (most
+ // significant 32)...uh, I think so Brain, but how do i call
+ // up the two parts of the value from inside this mouse
+ // cage? *zort*
+ default:
+ visitInstruction (I);
+ }
+ // Emit a 'ret' instruction
+ BuildMI (BB, X86::RET, 0);
+}
+
+/// visitBranchInst - Handle conditional and unconditional branches here. Note
+/// that since code layout is frozen at this point, that if we are trying to
+/// jump to a block that is the immediate successor of the current block, we can
+/// just make a fall-through. (but we don't currently).
+///
+void
+ISel::visitBranchInst (BranchInst & BI)
+{
+ if (BI.isConditional ())
+ {
+ BasicBlock *ifTrue = BI.getSuccessor (0);
+ BasicBlock *ifFalse = BI.getSuccessor (1); // this is really unobvious
+
+ // simplest thing I can think of: compare condition with zero,
+ // followed by jump-if-equal to ifFalse, and jump-if-nonequal to
+ // ifTrue
+ unsigned int condReg = getReg (BI.getCondition ());
+ BuildMI (BB, X86::CMPri8, 2).addReg (condReg).addZImm (0);
+ BuildMI (BB, X86::JNE, 1).addPCDisp (BI.getSuccessor (0));
+ BuildMI (BB, X86::JE, 1).addPCDisp (BI.getSuccessor (1));
+ }
+ else // unconditional branch
+ {
+ BuildMI (BB, X86::JMP, 1).addPCDisp (BI.getSuccessor (0));
+ }
+}
+
+/// visitCallInst - Push args on stack and do a procedure call instruction.
+void
+ISel::visitCallInst (CallInst & CI)
+{
+ // keep a counter of how many bytes we pushed on the stack
+ unsigned bytesPushed = 0;
+
+ // Push the arguments on the stack in reverse order, as specified by
+ // the ABI.
+ for (unsigned i = CI.getNumOperands()-1; i >= 1; --i)
+ {
+ Value *v = CI.getOperand (i);
+ switch (getClass (v->getType ()))
+ {
+ case cByte:
+ case cShort:
+ // Promote V to 32 bits wide, and move the result into EAX,
+ // then push EAX.
+ promote32 (X86::EAX, v);
+ BuildMI (BB, X86::PUSHr32, 1).addReg (X86::EAX);
+ bytesPushed += 4;
+ break;
+ case cInt:
+ case cFloat: {
+ unsigned Reg = getReg(v);
+ BuildMI (BB, X86::PUSHr32, 1).addReg(Reg);
+ bytesPushed += 4;
+ break;
+ }
+ default:
+ // FIXME: long/ulong/double args not handled.
+ visitInstruction (CI);
+ break;
+ }
+ }
+ // Emit a CALL instruction with PC-relative displacement.
+ BuildMI (BB, X86::CALLpcrel32, 1).addPCDisp (CI.getCalledValue ());
+
+ // Adjust the stack by `bytesPushed' amount if non-zero
+ if (bytesPushed > 0)
+ BuildMI (BB, X86::ADDri32, 2).addReg(X86::ESP).addZImm(bytesPushed);
+
+ // If there is a return value, scavenge the result from the location the call
+ // leaves it in...
+ //
+ if (CI.getType() != Type::VoidTy) {
+ unsigned resultTypeClass = getClass (CI.getType ());
+ switch (resultTypeClass) {
+ case cByte:
+ case cShort:
+ case cInt: {
+ // Integral results are in %eax, or the appropriate portion
+ // thereof.
+ static const unsigned regRegMove[] = {
+ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32
+ };
+ static const unsigned AReg[] = { X86::AL, X86::AX, X86::EAX };
+ BuildMI (BB, regRegMove[resultTypeClass], 1,
+ getReg (CI)).addReg (AReg[resultTypeClass]);
+ break;
+ }
+ case cFloat:
+ // Floating-point return values live in %st(0) (i.e., the top of
+ // the FP stack.) The general way to approach this is to do a
+ // FSTP to save the top of the FP stack on the real stack, then
+ // do a MOV to load the top of the real stack into the target
+ // register.
+ visitInstruction (CI); // FIXME: add the right args for the calls below
+ // BuildMI (BB, X86::FSTPm32, 0);
+ // BuildMI (BB, X86::MOVmr32, 0);
+ break;
+ default:
+ std::cerr << "Cannot get return value for call of type '"
+ << *CI.getType() << "'\n";
+ visitInstruction(CI);
+ }
+ }
+}
+
+/// visitSimpleBinary - Implement simple binary operators for integral types...
+/// OperatorClass is one of: 0 for Add, 1 for Sub, 2 for And, 3 for Or,
+/// 4 for Xor.