+ unsigned Class = getClass(B.getType());
+ if (Class > 2) // FIXME: Handle longs
+ visitInstruction(B);
+
+ static const unsigned OpcodeTab[][4] = {
+ // Arithmetic operators
+ { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32, 0 }, // ADD
+ { X86::SUBrr8, X86::SUBrr16, X86::SUBrr32, 0 }, // SUB
+
+ // Bitwise operators
+ { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 }, // AND
+ { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 }, // OR
+ { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 }, // XOR
+ };
+
+ unsigned Opcode = OpcodeTab[OperatorClass][Class];
+ unsigned Op0r = getReg(B.getOperand(0));
+ unsigned Op1r = getReg(B.getOperand(1));
+ BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r);
+}
+
+/// visitMul - Multiplies are not simple binary operators because they must deal
+/// with the EAX register explicitly.
+///
+void ISel::visitMul(BinaryOperator &I) {
+ unsigned Class = getClass(I.getType());
+ if (Class > 2) // FIXME: Handle longs
+ visitInstruction(I);
+
+ static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX };
+ static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 };
+ static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
+
+ unsigned Reg = Regs[Class];
+ unsigned Op0Reg = getReg(I.getOperand(0));
+ unsigned Op1Reg = getReg(I.getOperand(1));
+
+ // Put the first operand into one of the A registers...
+ BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
+
+ // Emit the appropriate multiply instruction...
+ BuildMI(BB, MulOpcode[Class], 1).addReg(Op1Reg);
+
+ // Put the result into the destination register...
+ BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg);
+}
+
+
+/// visitDivRem - Handle division and remainder instructions... these
+/// instruction both require the same instructions to be generated, they just
+/// select the result from a different register. Note that both of these
+/// instructions work differently for signed and unsigned operands.
+///
+void ISel::visitDivRem(BinaryOperator &I) {
+ unsigned Class = getClass(I.getType());
+ if (Class > 2) // FIXME: Handle longs
+ visitInstruction(I);
+
+ static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX };
+ static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
+ static const unsigned ExtOpcode[]={ X86::CBW , X86::CWD , X86::CDQ };
+ static const unsigned ClrOpcode[]={ X86::XORrr8, X86::XORrr16, X86::XORrr32 };
+ static const unsigned ExtRegs[] ={ X86::AH , X86::DX , X86::EDX };
+
+ static const unsigned DivOpcode[][4] = {
+ { X86::DIVrr8 , X86::DIVrr16 , X86::DIVrr32 , 0 }, // Unsigned division
+ { X86::IDIVrr8, X86::IDIVrr16, X86::IDIVrr32, 0 }, // Signed division
+ };
+
+ bool isSigned = I.getType()->isSigned();
+ unsigned Reg = Regs[Class];
+ unsigned ExtReg = ExtRegs[Class];
+ unsigned Op0Reg = getReg(I.getOperand(0));
+ unsigned Op1Reg = getReg(I.getOperand(1));
+
+ // Put the first operand into one of the A registers...
+ BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg);
+
+ if (isSigned) {
+ // Emit a sign extension instruction...
+ BuildMI(BB, ExtOpcode[Class], 0);
+ } else {
+ // If unsigned, emit a zeroing instruction... (reg = xor reg, reg)
+ BuildMI(BB, ClrOpcode[Class], 2, ExtReg).addReg(ExtReg).addReg(ExtReg);
+ }
+
+ // Emit the appropriate divide or remainder instruction...
+ BuildMI(BB, DivOpcode[isSigned][Class], 1).addReg(Op1Reg);
+
+ // Figure out which register we want to pick the result out of...
+ unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg;
+
+ // Put the result into the destination register...
+ BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(DestReg);