binOp :: (RegOrImm a,  RegOrImm b) => String 
      -> a -> b -> CodeGen Env ()
binOp op a b
  | isAtSP a && isAtSP b = do sp <- getStackPointer
                              binOp' (Ref sp) (Ref sp)
  | isAtSP a             = do sp <- getStackPointer
                              binOp' (Ref sp) b
  | isAtSP b             = do sp <- getStackPointer
                              binOp' a (Ref sp)
  | otherwise            = binOp' a b
  where 
  binOp' x y = emit $ "\t"++op++"\t"++showRegOrImm x++", "++showRegOrImm y
binOp :: (RegOrImm a,  RegOrImm b) => String 
      -> a -> b -> CodeGen Env ()
binOp op a b
  | isAtSP a && isAtSP b = do sp <- getStackPointer
                              binOp' (Ref sp) (Ref sp)
  | isAtSP a             = do sp <- getStackPointer
                              binOp' (Ref sp) b
  | isAtSP b             = do sp <- getStackPointer
                              binOp' a (Ref sp)
  | otherwise            = binOp' a b
  where 
  binOp' x y = emit $ "\t"++op++"\t"++showRegOrImm x++", "++showRegOrImm y
binOp op a b
  | isAtSP a && isAtSP b = do sp <- getStackPointer
                              binOp' (Ref sp) (Ref sp)
  | isAtSP a             = do sp <- getStackPointer
                              binOp' (Ref sp) b
  | isAtSP b             = do sp <- getStackPointer
                              binOp' a (Ref sp)
  | otherwise            = binOp' a b
  where 
  binOp' x y = emit $ "\t"++op++"\t"++showRegOrImm x++", "++showRegOrImm y