Trim whitespace.
authorBrian Gaeke <gaeke@uiuc.edu>
Sun, 27 Jun 2004 22:47:33 +0000 (22:47 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Sun, 27 Jun 2004 22:47:33 +0000 (22:47 +0000)
Support cast of ints (and narrower) to float and double.
Support cast double to double (using load and store).
Abort if we see a CallInst or SetCondInst with long/fp args, instead
of producing bad code.
Support add, sub, mul, div of float and double.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14440 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/InstSelectSimple.cpp
lib/Target/Sparc/SparcV8ISelSimple.cpp
lib/Target/SparcV8/InstSelectSimple.cpp
lib/Target/SparcV8/SparcV8ISelSimple.cpp

index 12045197b7cee600ed0b0272f46186c14d28611d..91fb2cb09db89ab60f7742f55bb31b4fa1b645a7 100644 (file)
@@ -86,8 +86,6 @@ namespace {
     void visitGetElementPtrInst(GetElementPtrInst &I);
     void visitAllocaInst(AllocaInst &I);
 
-
-
     void visitInstruction(Instruction &I) {
       std::cerr << "Unhandled instruction: " << I;
       abort();
@@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
     }
   } else {
     if (newTyClass == cFloat) {
+      assert (oldTyClass != cLong && "cast long to float not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
@@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
       case cDouble:
         BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
         break;
-      default:
+      default: {
+        unsigned FltAlign = TM.getTargetData().getFloatAlignment();
         // cast int to float.  Store it to a stack slot and then load
         // it using ldf into a floating point register. then do fitos.
-        std::cerr << "Casts to float still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else if (newTyClass == cDouble) {
+      assert (oldTyClass != cLong && "cast long to double not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
         break;
-      default:
-        std::cerr << "Casts to double still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+      case cDouble: {
+        // go through memory, for now
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
+          .addSImm (0);
+        break;
+      }
+      default: {
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else {
       std::cerr << "Cast still unsupported: SrcTy = "
                 << *SrcTy << ", DestTy = " << *DestTy << "\n";
@@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
     V8::O4, V8::O5 };
   for (unsigned i = 1; i < 7; ++i)
     if (i < I.getNumOperands ()) {
+      assert (getClassB (I.getOperand (i)->getType ()) < cLong
+              && "Can't handle long or fp function call arguments yet");
       unsigned ArgReg = getReg (I.getOperand (i));
       // Schlep it over into the incoming arg register
       BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
@@ -789,10 +811,29 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
   unsigned Op0Reg = getReg (I.getOperand (0));
   unsigned Op1Reg = getReg (I.getOperand (1));
 
+  unsigned Class = getClassB (I.getType());
+  unsigned OpCase = ~0;
+
+  if (Class > cLong) {
+    switch (I.getOpcode ()) {
+    case Instruction::Add: OpCase = 0; break;
+    case Instruction::Sub: OpCase = 1; break;
+    case Instruction::Mul: OpCase = 2; break;
+    case Instruction::Div: OpCase = 3; break;
+    default: visitInstruction (I); return;
+    }
+    static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
+                                  V8::FSUBS, V8::FSUBD,
+                                  V8::FMULS, V8::FMULD,
+                                  V8::FDIVS, V8::FDIVD };
+    BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
+      .addReg (Op0Reg).addReg (Op1Reg);
+    return;
+  }
+
   unsigned ResultReg = DestReg;
-  if (getClassB(I.getType()) != cInt)
+  if (Class != cInt)
     ResultReg = makeAnotherReg (I.getType ());
-  unsigned OpCase = ~0;
 
   // FIXME: support long, ulong, fp.
   switch (I.getOpcode ()) {
@@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
         return;
       }
       // Do the other half of the value:
-      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
+      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
+        .addReg (Op1Reg+1);
       break;
     default:
       visitInstruction (I);
@@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
   unsigned DestReg = getReg (I);
   const Type *Ty = I.getOperand (0)->getType ();
   
+  assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
   // Compare the two values.
   BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
 
index 12045197b7cee600ed0b0272f46186c14d28611d..91fb2cb09db89ab60f7742f55bb31b4fa1b645a7 100644 (file)
@@ -86,8 +86,6 @@ namespace {
     void visitGetElementPtrInst(GetElementPtrInst &I);
     void visitAllocaInst(AllocaInst &I);
 
-
-
     void visitInstruction(Instruction &I) {
       std::cerr << "Unhandled instruction: " << I;
       abort();
@@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
     }
   } else {
     if (newTyClass == cFloat) {
+      assert (oldTyClass != cLong && "cast long to float not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
@@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
       case cDouble:
         BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
         break;
-      default:
+      default: {
+        unsigned FltAlign = TM.getTargetData().getFloatAlignment();
         // cast int to float.  Store it to a stack slot and then load
         // it using ldf into a floating point register. then do fitos.
-        std::cerr << "Casts to float still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else if (newTyClass == cDouble) {
+      assert (oldTyClass != cLong && "cast long to double not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
         break;
-      default:
-        std::cerr << "Casts to double still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+      case cDouble: {
+        // go through memory, for now
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
+          .addSImm (0);
+        break;
+      }
+      default: {
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else {
       std::cerr << "Cast still unsupported: SrcTy = "
                 << *SrcTy << ", DestTy = " << *DestTy << "\n";
@@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
     V8::O4, V8::O5 };
   for (unsigned i = 1; i < 7; ++i)
     if (i < I.getNumOperands ()) {
+      assert (getClassB (I.getOperand (i)->getType ()) < cLong
+              && "Can't handle long or fp function call arguments yet");
       unsigned ArgReg = getReg (I.getOperand (i));
       // Schlep it over into the incoming arg register
       BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
@@ -789,10 +811,29 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
   unsigned Op0Reg = getReg (I.getOperand (0));
   unsigned Op1Reg = getReg (I.getOperand (1));
 
+  unsigned Class = getClassB (I.getType());
+  unsigned OpCase = ~0;
+
+  if (Class > cLong) {
+    switch (I.getOpcode ()) {
+    case Instruction::Add: OpCase = 0; break;
+    case Instruction::Sub: OpCase = 1; break;
+    case Instruction::Mul: OpCase = 2; break;
+    case Instruction::Div: OpCase = 3; break;
+    default: visitInstruction (I); return;
+    }
+    static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
+                                  V8::FSUBS, V8::FSUBD,
+                                  V8::FMULS, V8::FMULD,
+                                  V8::FDIVS, V8::FDIVD };
+    BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
+      .addReg (Op0Reg).addReg (Op1Reg);
+    return;
+  }
+
   unsigned ResultReg = DestReg;
-  if (getClassB(I.getType()) != cInt)
+  if (Class != cInt)
     ResultReg = makeAnotherReg (I.getType ());
-  unsigned OpCase = ~0;
 
   // FIXME: support long, ulong, fp.
   switch (I.getOpcode ()) {
@@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
         return;
       }
       // Do the other half of the value:
-      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
+      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
+        .addReg (Op1Reg+1);
       break;
     default:
       visitInstruction (I);
@@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
   unsigned DestReg = getReg (I);
   const Type *Ty = I.getOperand (0)->getType ();
   
+  assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
   // Compare the two values.
   BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
 
index 12045197b7cee600ed0b0272f46186c14d28611d..91fb2cb09db89ab60f7742f55bb31b4fa1b645a7 100644 (file)
@@ -86,8 +86,6 @@ namespace {
     void visitGetElementPtrInst(GetElementPtrInst &I);
     void visitAllocaInst(AllocaInst &I);
 
-
-
     void visitInstruction(Instruction &I) {
       std::cerr << "Unhandled instruction: " << I;
       abort();
@@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
     }
   } else {
     if (newTyClass == cFloat) {
+      assert (oldTyClass != cLong && "cast long to float not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
@@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
       case cDouble:
         BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
         break;
-      default:
+      default: {
+        unsigned FltAlign = TM.getTargetData().getFloatAlignment();
         // cast int to float.  Store it to a stack slot and then load
         // it using ldf into a floating point register. then do fitos.
-        std::cerr << "Casts to float still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else if (newTyClass == cDouble) {
+      assert (oldTyClass != cLong && "cast long to double not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
         break;
-      default:
-        std::cerr << "Casts to double still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+      case cDouble: {
+        // go through memory, for now
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
+          .addSImm (0);
+        break;
+      }
+      default: {
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else {
       std::cerr << "Cast still unsupported: SrcTy = "
                 << *SrcTy << ", DestTy = " << *DestTy << "\n";
@@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
     V8::O4, V8::O5 };
   for (unsigned i = 1; i < 7; ++i)
     if (i < I.getNumOperands ()) {
+      assert (getClassB (I.getOperand (i)->getType ()) < cLong
+              && "Can't handle long or fp function call arguments yet");
       unsigned ArgReg = getReg (I.getOperand (i));
       // Schlep it over into the incoming arg register
       BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
@@ -789,10 +811,29 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
   unsigned Op0Reg = getReg (I.getOperand (0));
   unsigned Op1Reg = getReg (I.getOperand (1));
 
+  unsigned Class = getClassB (I.getType());
+  unsigned OpCase = ~0;
+
+  if (Class > cLong) {
+    switch (I.getOpcode ()) {
+    case Instruction::Add: OpCase = 0; break;
+    case Instruction::Sub: OpCase = 1; break;
+    case Instruction::Mul: OpCase = 2; break;
+    case Instruction::Div: OpCase = 3; break;
+    default: visitInstruction (I); return;
+    }
+    static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
+                                  V8::FSUBS, V8::FSUBD,
+                                  V8::FMULS, V8::FMULD,
+                                  V8::FDIVS, V8::FDIVD };
+    BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
+      .addReg (Op0Reg).addReg (Op1Reg);
+    return;
+  }
+
   unsigned ResultReg = DestReg;
-  if (getClassB(I.getType()) != cInt)
+  if (Class != cInt)
     ResultReg = makeAnotherReg (I.getType ());
-  unsigned OpCase = ~0;
 
   // FIXME: support long, ulong, fp.
   switch (I.getOpcode ()) {
@@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
         return;
       }
       // Do the other half of the value:
-      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
+      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
+        .addReg (Op1Reg+1);
       break;
     default:
       visitInstruction (I);
@@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
   unsigned DestReg = getReg (I);
   const Type *Ty = I.getOperand (0)->getType ();
   
+  assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
   // Compare the two values.
   BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
 
index 12045197b7cee600ed0b0272f46186c14d28611d..91fb2cb09db89ab60f7742f55bb31b4fa1b645a7 100644 (file)
@@ -86,8 +86,6 @@ namespace {
     void visitGetElementPtrInst(GetElementPtrInst &I);
     void visitAllocaInst(AllocaInst &I);
 
-
-
     void visitInstruction(Instruction &I) {
       std::cerr << "Unhandled instruction: " << I;
       abort();
@@ -518,6 +516,7 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
     }
   } else {
     if (newTyClass == cFloat) {
+      assert (oldTyClass != cLong && "cast long to float not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
@@ -525,25 +524,46 @@ void V8ISel::emitCastOperation(MachineBasicBlock *BB,
       case cDouble:
         BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
         break;
-      default:
+      default: {
+        unsigned FltAlign = TM.getTargetData().getFloatAlignment();
         // cast int to float.  Store it to a stack slot and then load
         // it using ldf into a floating point register. then do fitos.
-        std::cerr << "Casts to float still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else if (newTyClass == cDouble) {
+      assert (oldTyClass != cLong && "cast long to double not implemented yet");
       switch (oldTyClass) {
       case cFloat:
         BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
         break;
-      default:
-        std::cerr << "Casts to double still unsupported: SrcTy = "
-                  << *SrcTy << ", DestTy = " << *DestTy << "\n";
-        abort ();
+      case cDouble: {
+        // go through memory, for now
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::STDFri, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, DestReg).addFrameIndex (FI)
+          .addSImm (0);
+        break;
+      }
+      default: {
+        unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
+        unsigned TmpReg = makeAnotherReg (newTy);
+        int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
+        BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
+          .addReg (SrcReg);
+        BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
+        BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
         break;
       }
+      }
     } else {
       std::cerr << "Cast still unsupported: SrcTy = "
                 << *SrcTy << ", DestTy = " << *DestTy << "\n";
@@ -636,6 +656,8 @@ void V8ISel::visitCallInst(CallInst &I) {
     V8::O4, V8::O5 };
   for (unsigned i = 1; i < 7; ++i)
     if (i < I.getNumOperands ()) {
+      assert (getClassB (I.getOperand (i)->getType ()) < cLong
+              && "Can't handle long or fp function call arguments yet");
       unsigned ArgReg = getReg (I.getOperand (i));
       // Schlep it over into the incoming arg register
       BuildMI (BB, V8::ORrr, 2, OutgoingArgRegs[i - 1]).addReg (V8::G0)
@@ -789,10 +811,29 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
   unsigned Op0Reg = getReg (I.getOperand (0));
   unsigned Op1Reg = getReg (I.getOperand (1));
 
+  unsigned Class = getClassB (I.getType());
+  unsigned OpCase = ~0;
+
+  if (Class > cLong) {
+    switch (I.getOpcode ()) {
+    case Instruction::Add: OpCase = 0; break;
+    case Instruction::Sub: OpCase = 1; break;
+    case Instruction::Mul: OpCase = 2; break;
+    case Instruction::Div: OpCase = 3; break;
+    default: visitInstruction (I); return;
+    }
+    static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
+                                  V8::FSUBS, V8::FSUBD,
+                                  V8::FMULS, V8::FMULD,
+                                  V8::FDIVS, V8::FDIVD };
+    BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
+      .addReg (Op0Reg).addReg (Op1Reg);
+    return;
+  }
+
   unsigned ResultReg = DestReg;
-  if (getClassB(I.getType()) != cInt)
+  if (Class != cInt)
     ResultReg = makeAnotherReg (I.getType ());
-  unsigned OpCase = ~0;
 
   // FIXME: support long, ulong, fp.
   switch (I.getOpcode ()) {
@@ -875,7 +916,8 @@ void V8ISel::visitBinaryOperator (Instruction &I) {
         return;
       }
       // Do the other half of the value:
-      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1).addReg (Op1Reg+1);
+      BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
+        .addReg (Op1Reg+1);
       break;
     default:
       visitInstruction (I);
@@ -888,6 +930,7 @@ void V8ISel::visitSetCondInst(Instruction &I) {
   unsigned DestReg = getReg (I);
   const Type *Ty = I.getOperand (0)->getType ();
   
+  assert (getClass (Ty) < cLong && "can't setcc on longs or fp yet");
   // Compare the two values.
   BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);