/* LLVM LOCAL begin (ENTIRE FILE!)  */
/* High-level LLVM backend interface
Copyright (C) 2008, 2009 Apple Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

//===----------------------------------------------------------------------===//
// This is a C++ source file that implements specific llvm ARM ABI.
//===----------------------------------------------------------------------===//

#include "llvm-abi.h"
#include "llvm-internal.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm-arm-target.h"

extern "C" {
#include "insn-codes.h"
#include "toplev.h"
#include "rtl.h"
#include "insn-config.h"
#include "recog.h"

static LLVMContext &Context = getGlobalContext();

enum neon_itype { neon_itype_dummy };
extern enum insn_code locate_neon_builtin_icode
  (int fcode, neon_itype *itype, enum neon_builtins *neon_code);
}

static ConstantInt *getInt32Const(int c) {
  return ConstantInt::get(Type::getInt32Ty(Context), c);
}

/// UnexpectedError - Report errors about unexpected uses of builtins.  The
/// msg argument should begin with a "%H" so that the location of the
/// expression is printed in the error message.
static bool UnexpectedError(const char *msg, tree exp, Value *&Result) {
  error(msg, &EXPR_LOCATION(exp));

  // Set the Result to an undefined value.
  Type *ResTy = ConvertType(TREE_TYPE(exp));
  if (ResTy->isSingleValueType())
    Result = UndefValue::get(ResTy);

  // Return true, which can be propagated as the return value of
  // TargetIntrinsicLower, to indicate that no further error message
  // is needed.
  return true;
}

static bool NonImmediateError(tree exp, Value *&Result) {
  return UnexpectedError("%Hlast builtin argument must be an immediate",
                         exp, Result);
}

static bool BadImmediateError(tree exp, Value *&Result) {
  return UnexpectedError("%Hunexpected immediate argument for builtin",
                         exp, Result);
}

static bool BadModeError(tree exp, Value *&Result) {
  return UnexpectedError("%Hunexpected mode for builtin argument",
                         exp, Result);
}

enum neon_datatype {
  neon_datatype_unspecified,
  neon_datatype_signed,
  neon_datatype_unsigned,
  neon_datatype_float,
  neon_datatype_polynomial
};

/// GetBuiltinExtraInfo - Decipher the extra integer immediate argument
/// used with many of GCC's builtins for NEON to distinguish variants of an
/// operation.  The following values for that argument are used:
///   - bit0: For integer types (i.e., bit2 == 0), 0 = unsigned, 1 = signed;
///           otherwise, 0 = polynomial, 1 = float.
///   - bit1: The operation rounds its results.
///   - bit2: 0 = integer datatypes, 1 = floating-point or polynomial.
///   .
/// Returns false if the extra argument is not an integer immediate.
static bool GetBuiltinExtraInfo(const Value *extra_arg,
                                neon_datatype &datatype, bool &isRounded) {
  const ConstantInt *arg = dyn_cast<ConstantInt>(extra_arg);
  if (!arg)
    return false;

  int argval = arg->getZExtValue();
  isRounded = ((argval & 2) != 0);
  if ((argval & 4) == 0) {
    if ((argval & 1) == 0)
      datatype = neon_datatype_unsigned;
    else
      datatype = neon_datatype_signed;
  } else {
    if ((argval & 1) == 0)
      datatype = neon_datatype_polynomial;
    else
      datatype = neon_datatype_float;
  }
  return true;
}

/// BuildConstantSplatVector - Create a ConstantVector with the same value
/// replicated in each element.
static Value *BuildConstantSplatVector(unsigned NumElements, ConstantInt *Val) {
  std::vector<Constant*> CstOps;
  for (unsigned i = 0; i != NumElements; ++i)
    CstOps.push_back(Val);
  return ConstantVector::get(CstOps);
}

/// BuildDup - Build a splat operation to duplicate a value into every
/// element of a vector.
static Value *BuildDup(Type *ResultType, Value *Val,
                       LLVMBuilder &Builder) {
  // GCC may promote the scalar argument; cast it back.
  VectorType *VTy = dyn_cast<VectorType>(ResultType);
  assert(VTy && "expected a vector type");
  Type *ElTy = VTy->getElementType();
  if (Val->getType() != ElTy) {
    assert(!ElTy->isFloatingPointTy() &&
           "only integer types expected to be promoted");
    Val = Builder.CreateTrunc(Val, ElTy);
  }

  // Insert the value into lane 0 of an undef vector.
  Value *Undef = UndefValue::get(ResultType);
  Value *Result = Builder.CreateInsertElement(Undef, Val, getInt32Const(0));

  // Use a shuffle to move the value into the other lanes.
  unsigned NUnits = VTy->getNumElements();
  if (NUnits > 1) {
    std::vector<Constant*> Idxs;
    for (unsigned i = 0; i != NUnits; ++i)
      Idxs.push_back(getInt32Const(0));
    Result = Builder.CreateShuffleVector(Result, Undef,
                                         ConstantVector::get(Idxs));
  }
  return Result;
}

/// BuildDupLane - Build a splat operation to take a value from one element
/// of a vector and splat it into another vector.
static Value *BuildDupLane(Value *Vec, unsigned LaneVal, unsigned NUnits,
                           LLVMBuilder &Builder) {
  // Translate this to a vector shuffle.
  std::vector<Constant*> Idxs;
  for (unsigned i = 0; i != NUnits; ++i)
    Idxs.push_back(getInt32Const(LaneVal));
  return Builder.CreateShuffleVector(Vec, UndefValue::get(Vec->getType()),
                                     ConstantVector::get(Idxs));
}

// NEON vector shift counts must be in the range 0..ElemBits-1 for left shifts
// or 1..ElemBits for right shifts.  For narrowing shifts, compare against the
// destination element size.  For widening shifts, the upper bound can be
// equal to the element size.  Define separate functions to check these
// constraints, so that the rest of the code for handling vector shift counts
// can be shared.

typedef bool (*ShiftCountChecker)(int Cnt, int ElemBits);

static bool CheckLeftShiftCount(int Cnt, int ElemBits) {
  return (Cnt >= 0 && Cnt < ElemBits);
}

static bool CheckLongLeftShiftCount(int Cnt, int ElemBits) {
  return (Cnt >= 0 && Cnt <= ElemBits);
}

static bool CheckRightShiftCount(int Cnt, int ElemBits) {
  return (Cnt >= 1 && Cnt <= ElemBits);
}

static bool CheckNarrowRightShiftCount(int Cnt, int ElemBits) {
  return (Cnt >= 1 && Cnt <= ElemBits / 2);
}

/// BuildShiftCountVector - Check that the shift count argument to a constant
/// shift builtin is a constant in the appropriate range for the shift
/// operation.  It expands the shift count into a vector, optionally with the
/// count negated for right shifts.  Returns true on success.
static bool BuildShiftCountVector(Value *&Op, enum machine_mode Mode,
                                  ShiftCountChecker CheckCount,
                                  bool NegateRightShift) {
  ConstantInt *Cnt = dyn_cast<ConstantInt>(Op);
  if (!Cnt)
    return false;
  int CntVal = Cnt->getSExtValue();

  assert (VECTOR_MODE_P (Mode) && "expected vector mode for shift");
  unsigned ElemBits = GET_MODE_BITSIZE (GET_MODE_INNER (Mode));
  if (!CheckCount(CntVal, ElemBits))
    return false;

  // Right shifts are represented in NEON intrinsics by a negative shift count.
  Cnt = ConstantInt::get(IntegerType::get(Context, ElemBits),
                         NegateRightShift ? -CntVal : CntVal);
  Op = BuildConstantSplatVector(GET_MODE_NUNITS(Mode), Cnt);
  return true;
}

/// isValidLane - Check if the lane operand for a vector intrinsic is a
/// ConstantInt in the range 0..NUnits.  If pLaneVal is not null, store
/// the lane value to it.
static bool isValidLane(Value *LnOp, int NUnits, unsigned *pLaneVal = 0) {
  ConstantInt *Lane = dyn_cast<ConstantInt>(LnOp);
  if (!Lane)
    return false;

  int LaneVal = Lane->getSExtValue();
  if (LaneVal < 0 || LaneVal >= NUnits)
    return false;

  if (pLaneVal)
    *pLaneVal = LaneVal;
  return true;
}

/// TargetIntrinsicLower - To handle builtins, we want to expand the
/// invocation into normal LLVM code.  If the target can handle the builtin,
/// this function should emit the expanded code and return true.
bool TreeToLLVM::TargetIntrinsicLower(tree exp,
                                      unsigned FnCode,
                                      const MemRef *DestLoc,
                                      Value *&Result,
                                      Type *ResultType,
                                      std::vector<Value*> &Ops) {
  neon_datatype datatype = neon_datatype_unspecified;
  bool isRounded = false;
  Intrinsic::ID intID = Intrinsic::not_intrinsic;
  Function *intFn;
  Type* intOpTypes[2];

  if (FnCode < ARM_BUILTIN_NEON_BASE)
    return false;

  neon_builtins neon_code;
  enum insn_code icode = locate_neon_builtin_icode (FnCode, 0, &neon_code);

  // Read the extra immediate argument to the builtin.
  switch (neon_code) {
  default:
    return false;
  case NEON_BUILTIN_vpaddl:
  case NEON_BUILTIN_vneg:
  case NEON_BUILTIN_vqneg:
  case NEON_BUILTIN_vabs:
  case NEON_BUILTIN_vqabs:
  case NEON_BUILTIN_vcls:
  case NEON_BUILTIN_vclz:
  case NEON_BUILTIN_vcnt:
  case NEON_BUILTIN_vrecpe:
  case NEON_BUILTIN_vrsqrte:
  case NEON_BUILTIN_vmvn:
  case NEON_BUILTIN_vcvt:
  case NEON_BUILTIN_vmovn:
  case NEON_BUILTIN_vqmovn:
  case NEON_BUILTIN_vqmovun:
  case NEON_BUILTIN_vmovl:
  case NEON_BUILTIN_vrev64:
  case NEON_BUILTIN_vrev32:
  case NEON_BUILTIN_vrev16:
    if (!GetBuiltinExtraInfo(Ops[1], datatype, isRounded))
      return NonImmediateError(exp, Result);
    break;
  case NEON_BUILTIN_vadd:
  case NEON_BUILTIN_vaddl:
  case NEON_BUILTIN_vaddw:
  case NEON_BUILTIN_vhadd:
  case NEON_BUILTIN_vqadd:
  case NEON_BUILTIN_vaddhn:
  case NEON_BUILTIN_vmul:
  case NEON_BUILTIN_vqdmulh:
  case NEON_BUILTIN_vmull:
  case NEON_BUILTIN_vqdmull:
  case NEON_BUILTIN_vsub:
  case NEON_BUILTIN_vsubl:
  case NEON_BUILTIN_vsubw:
  case NEON_BUILTIN_vqsub:
  case NEON_BUILTIN_vhsub:
  case NEON_BUILTIN_vsubhn:
  case NEON_BUILTIN_vceq:
  case NEON_BUILTIN_vcge:
  case NEON_BUILTIN_vcgt:
  case NEON_BUILTIN_vcage:
  case NEON_BUILTIN_vcagt:
  case NEON_BUILTIN_vtst:
  case NEON_BUILTIN_vabd:
  case NEON_BUILTIN_vabdl:
  case NEON_BUILTIN_vmax:
  case NEON_BUILTIN_vmin:
  case NEON_BUILTIN_vpadd:
  case NEON_BUILTIN_vpadal:
  case NEON_BUILTIN_vpmax:
  case NEON_BUILTIN_vpmin:
  case NEON_BUILTIN_vrecps:
  case NEON_BUILTIN_vrsqrts:
  case NEON_BUILTIN_vshl:
  case NEON_BUILTIN_vqshl:
  case NEON_BUILTIN_vshr_n:
  case NEON_BUILTIN_vshrn_n:
  case NEON_BUILTIN_vqshrn_n:
  case NEON_BUILTIN_vqshrun_n:
  case NEON_BUILTIN_vshl_n:
  case NEON_BUILTIN_vqshl_n:
  case NEON_BUILTIN_vqshlu_n:
  case NEON_BUILTIN_vshll_n:
  case NEON_BUILTIN_vget_lane:
  case NEON_BUILTIN_vcvt_n:
  case NEON_BUILTIN_vmul_n:
  case NEON_BUILTIN_vmull_n:
  case NEON_BUILTIN_vqdmull_n:
  case NEON_BUILTIN_vqdmulh_n:
  case NEON_BUILTIN_vand:
  case NEON_BUILTIN_vorr:
  case NEON_BUILTIN_veor:
  case NEON_BUILTIN_vbic:
  case NEON_BUILTIN_vorn:
    if (!GetBuiltinExtraInfo(Ops[2], datatype, isRounded))
      return NonImmediateError(exp, Result);
    break;
  case NEON_BUILTIN_vmla:
  case NEON_BUILTIN_vmls:
  case NEON_BUILTIN_vmlal:
  case NEON_BUILTIN_vmlsl:
  case NEON_BUILTIN_vqdmlal:
  case NEON_BUILTIN_vqdmlsl:
  case NEON_BUILTIN_vaba:
  case NEON_BUILTIN_vabal:
  case NEON_BUILTIN_vsra_n:
  case NEON_BUILTIN_vmul_lane:
  case NEON_BUILTIN_vmull_lane:
  case NEON_BUILTIN_vqdmull_lane:
  case NEON_BUILTIN_vqdmulh_lane:
  case NEON_BUILTIN_vmla_n:
  case NEON_BUILTIN_vmlal_n:
  case NEON_BUILTIN_vqdmlal_n:
  case NEON_BUILTIN_vmls_n:
  case NEON_BUILTIN_vmlsl_n:
  case NEON_BUILTIN_vqdmlsl_n:
    if (!GetBuiltinExtraInfo(Ops[3], datatype, isRounded))
      return NonImmediateError(exp, Result);
    break;
  case NEON_BUILTIN_vmla_lane:
  case NEON_BUILTIN_vmlal_lane:
  case NEON_BUILTIN_vqdmlal_lane:
  case NEON_BUILTIN_vmls_lane:
  case NEON_BUILTIN_vmlsl_lane:
  case NEON_BUILTIN_vqdmlsl_lane:
    if (!GetBuiltinExtraInfo(Ops[4], datatype, isRounded))
      return NonImmediateError(exp, Result);
    break;
  case NEON_BUILTIN_vsri_n:
  case NEON_BUILTIN_vsli_n:
  case NEON_BUILTIN_vset_lane:
  case NEON_BUILTIN_vcreate:
  case NEON_BUILTIN_vdup_n:
  case NEON_BUILTIN_vdup_lane:
  case NEON_BUILTIN_vcombine:
  case NEON_BUILTIN_vget_high:
  case NEON_BUILTIN_vget_low:
  case NEON_BUILTIN_vtbl1:
  case NEON_BUILTIN_vtbl2:
  case NEON_BUILTIN_vtbl3:
  case NEON_BUILTIN_vtbl4:
  case NEON_BUILTIN_vtbx1:
  case NEON_BUILTIN_vtbx2:
  case NEON_BUILTIN_vtbx3:
  case NEON_BUILTIN_vtbx4:
  case NEON_BUILTIN_vext:
  case NEON_BUILTIN_vbsl:
  case NEON_BUILTIN_vtrn:
  case NEON_BUILTIN_vzip:
  case NEON_BUILTIN_vuzp:
  case NEON_BUILTIN_vld1:
  case NEON_BUILTIN_vld2:
  case NEON_BUILTIN_vld3:
  case NEON_BUILTIN_vld4:
  case NEON_BUILTIN_vld1_lane:
  case NEON_BUILTIN_vld2_lane:
  case NEON_BUILTIN_vld3_lane:
  case NEON_BUILTIN_vld4_lane:
  case NEON_BUILTIN_vld1_dup:
  case NEON_BUILTIN_vld2_dup:
  case NEON_BUILTIN_vld3_dup:
  case NEON_BUILTIN_vld4_dup:
  case NEON_BUILTIN_vst1:
  case NEON_BUILTIN_vst2:
  case NEON_BUILTIN_vst3:
  case NEON_BUILTIN_vst4:
  case NEON_BUILTIN_vst1_lane:
  case NEON_BUILTIN_vst2_lane:
  case NEON_BUILTIN_vst3_lane:
  case NEON_BUILTIN_vst4_lane:
  case NEON_BUILTIN_vreinterpretv8qi:
  case NEON_BUILTIN_vreinterpretv4hi:
  case NEON_BUILTIN_vreinterpretv2si:
  case NEON_BUILTIN_vreinterpretv2sf:
  case NEON_BUILTIN_vreinterpretv1di:
  case NEON_BUILTIN_vreinterpretv16qi:
  case NEON_BUILTIN_vreinterpretv8hi:
  case NEON_BUILTIN_vreinterpretv4si:
  case NEON_BUILTIN_vreinterpretv4sf:
  case NEON_BUILTIN_vreinterpretv2di:
    // No extra argument used here.
    break;
  }

  // Check that the isRounded flag is only set when it is supported.
  if (isRounded) {
    switch (neon_code) {
    case NEON_BUILTIN_vhadd:
    case NEON_BUILTIN_vaddhn:
    case NEON_BUILTIN_vqdmulh:
    case NEON_BUILTIN_vsubhn:
    case NEON_BUILTIN_vshl:
    case NEON_BUILTIN_vqshl:
    case NEON_BUILTIN_vshr_n:
    case NEON_BUILTIN_vshrn_n:
    case NEON_BUILTIN_vqshrn_n:
    case NEON_BUILTIN_vqshrun_n:
    case NEON_BUILTIN_vsra_n:
    case NEON_BUILTIN_vqdmulh_lane:
    case NEON_BUILTIN_vqdmulh_n:
      // These all support a rounded variant.
      break;
    default:
      return BadImmediateError(exp, Result);
    }
  }

  // Check for supported vector modes.

  // Set defaults for mode checking.
  int modeCheckOpnd = 1;
  bool allow_64bit_modes = true;
  bool allow_128bit_modes = true;
  bool allow_8bit_elements = true;
  bool allow_16bit_elements = true;
  bool allow_32bit_elements = true;
  bool allow_64bit_elements = false;
  bool allow_16bit_polynomials = false;

  switch (neon_code) {
  default:
    assert(0 && "unexpected builtin");
    break;

  case NEON_BUILTIN_vadd:
  case NEON_BUILTIN_vsub:
  case NEON_BUILTIN_vqadd:
  case NEON_BUILTIN_vqsub:
  case NEON_BUILTIN_vshl:
  case NEON_BUILTIN_vqshl:
  case NEON_BUILTIN_vshr_n:
  case NEON_BUILTIN_vshl_n:
  case NEON_BUILTIN_vqshl_n:
  case NEON_BUILTIN_vqshlu_n:
  case NEON_BUILTIN_vsra_n:
  case NEON_BUILTIN_vsri_n:
  case NEON_BUILTIN_vsli_n:
  case NEON_BUILTIN_vmvn:
  case NEON_BUILTIN_vext:
  case NEON_BUILTIN_vbsl:
  case NEON_BUILTIN_vand:
  case NEON_BUILTIN_vorr:
  case NEON_BUILTIN_veor:
  case NEON_BUILTIN_vbic:
  case NEON_BUILTIN_vorn:
  case NEON_BUILTIN_vdup_lane:
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vhadd:
  case NEON_BUILTIN_vhsub:
  case NEON_BUILTIN_vmul:
  case NEON_BUILTIN_vceq:
  case NEON_BUILTIN_vcge:
  case NEON_BUILTIN_vcgt:
  case NEON_BUILTIN_vcage:
  case NEON_BUILTIN_vcagt:
  case NEON_BUILTIN_vtst:
  case NEON_BUILTIN_vabd:
  case NEON_BUILTIN_vabdl:
  case NEON_BUILTIN_vaba:
  case NEON_BUILTIN_vmax:
  case NEON_BUILTIN_vmin:
  case NEON_BUILTIN_vpaddl:
  case NEON_BUILTIN_vrecps:
  case NEON_BUILTIN_vrsqrts:
  case NEON_BUILTIN_vneg:
  case NEON_BUILTIN_vqneg:
  case NEON_BUILTIN_vabs:
  case NEON_BUILTIN_vqabs:
  case NEON_BUILTIN_vcls:
  case NEON_BUILTIN_vclz:
  case NEON_BUILTIN_vtrn:
  case NEON_BUILTIN_vzip:
  case NEON_BUILTIN_vuzp:
    break;

  case NEON_BUILTIN_vabal:
  case NEON_BUILTIN_vmla:
  case NEON_BUILTIN_vmls:
  case NEON_BUILTIN_vpadal:
    modeCheckOpnd = 2;
    break;

  case NEON_BUILTIN_vaddhn:
  case NEON_BUILTIN_vsubhn:
  case NEON_BUILTIN_vshrn_n:
  case NEON_BUILTIN_vqshrn_n:
  case NEON_BUILTIN_vqshrun_n:
  case NEON_BUILTIN_vmovn:
  case NEON_BUILTIN_vqmovn:
  case NEON_BUILTIN_vqmovun:
    allow_64bit_modes = false;
    allow_8bit_elements = false;
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vqdmulh:
  case NEON_BUILTIN_vqdmulh_lane:
  case NEON_BUILTIN_vqdmulh_n:
  case NEON_BUILTIN_vmul_lane:
  case NEON_BUILTIN_vmul_n:
  case NEON_BUILTIN_vmla_lane:
  case NEON_BUILTIN_vmla_n:
  case NEON_BUILTIN_vmls_lane:
  case NEON_BUILTIN_vmls_n:
    allow_8bit_elements = false;
    break;

  case NEON_BUILTIN_vqdmull:
  case NEON_BUILTIN_vqdmull_lane:
  case NEON_BUILTIN_vqdmull_n:
  case NEON_BUILTIN_vmull_lane:
  case NEON_BUILTIN_vmull_n:
    allow_128bit_modes = false;
    allow_8bit_elements = false;
    break;

  case NEON_BUILTIN_vqdmlal:
  case NEON_BUILTIN_vqdmlal_lane:
  case NEON_BUILTIN_vqdmlal_n:
  case NEON_BUILTIN_vqdmlsl:
  case NEON_BUILTIN_vmlal_lane:
  case NEON_BUILTIN_vmlal_n:
  case NEON_BUILTIN_vmlsl_lane:
  case NEON_BUILTIN_vmlsl_n:
  case NEON_BUILTIN_vqdmlsl_lane:
  case NEON_BUILTIN_vqdmlsl_n:
    modeCheckOpnd = 2;
    allow_128bit_modes = false;
    allow_8bit_elements = false;
    break;

  case NEON_BUILTIN_vaddw:
  case NEON_BUILTIN_vmlal:
  case NEON_BUILTIN_vmlsl:
  case NEON_BUILTIN_vsubw:
    modeCheckOpnd = 2;
    allow_128bit_modes = false;
    break;

  case NEON_BUILTIN_vaddl:
  case NEON_BUILTIN_vmull:
  case NEON_BUILTIN_vsubl:
  case NEON_BUILTIN_vpadd:
  case NEON_BUILTIN_vpmax:
  case NEON_BUILTIN_vpmin:
  case NEON_BUILTIN_vshll_n:
  case NEON_BUILTIN_vmovl:
    allow_128bit_modes = false;
    break;

  case NEON_BUILTIN_vcnt:
    allow_16bit_elements = false;
    allow_32bit_elements = false;
    break;

  case NEON_BUILTIN_vtbl1:
  case NEON_BUILTIN_vtbl2:
  case NEON_BUILTIN_vtbl3:
  case NEON_BUILTIN_vtbl4:
  case NEON_BUILTIN_vtbx1:
  case NEON_BUILTIN_vtbx2:
  case NEON_BUILTIN_vtbx3:
  case NEON_BUILTIN_vtbx4:
    allow_16bit_elements = false;
    allow_32bit_elements = false;
    allow_128bit_modes = false;
    modeCheckOpnd = 0;
    break;

  case NEON_BUILTIN_vrecpe:
  case NEON_BUILTIN_vrsqrte:
  case NEON_BUILTIN_vcvt:
  case NEON_BUILTIN_vcvt_n:
    allow_8bit_elements = false;
    allow_16bit_elements = false;
    break;

  case NEON_BUILTIN_vget_lane:
    allow_64bit_elements = true;
    allow_16bit_polynomials = true;
    break;

  case NEON_BUILTIN_vset_lane:
    allow_64bit_elements = true;
    allow_16bit_polynomials = true;
    modeCheckOpnd = 2;
    break;

  case NEON_BUILTIN_vrev64:
    allow_16bit_polynomials = true;
    break;

  case NEON_BUILTIN_vrev32:
    allow_16bit_polynomials = true;
    allow_32bit_elements = false;
    break;

  case NEON_BUILTIN_vrev16:
    allow_16bit_elements = false;
    allow_32bit_elements = false;
    break;

  case NEON_BUILTIN_vcreate:
    modeCheckOpnd = 0;
    allow_128bit_modes = false;
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vdup_n:
    modeCheckOpnd = 0;
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vcombine:
  case NEON_BUILTIN_vreinterpretv8qi:
  case NEON_BUILTIN_vreinterpretv4hi:
  case NEON_BUILTIN_vreinterpretv2si:
  case NEON_BUILTIN_vreinterpretv2sf:
  case NEON_BUILTIN_vreinterpretv1di:
    allow_128bit_modes = false;
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vget_high:
  case NEON_BUILTIN_vget_low:
  case NEON_BUILTIN_vreinterpretv16qi:
  case NEON_BUILTIN_vreinterpretv8hi:
  case NEON_BUILTIN_vreinterpretv4si:
  case NEON_BUILTIN_vreinterpretv4sf:
  case NEON_BUILTIN_vreinterpretv2di:
    allow_64bit_modes = false;
    allow_64bit_elements = true;
    break;

  case NEON_BUILTIN_vld1:
  case NEON_BUILTIN_vld2:
  case NEON_BUILTIN_vld3:
  case NEON_BUILTIN_vld4:
  case NEON_BUILTIN_vld1_lane:
  case NEON_BUILTIN_vld2_lane:
  case NEON_BUILTIN_vld3_lane:
  case NEON_BUILTIN_vld4_lane:
  case NEON_BUILTIN_vld1_dup:
  case NEON_BUILTIN_vld2_dup:
  case NEON_BUILTIN_vld3_dup:
  case NEON_BUILTIN_vld4_dup:
  case NEON_BUILTIN_vst1:
  case NEON_BUILTIN_vst2:
  case NEON_BUILTIN_vst3:
  case NEON_BUILTIN_vst4:
  case NEON_BUILTIN_vst1_lane:
  case NEON_BUILTIN_vst2_lane:
  case NEON_BUILTIN_vst3_lane:
  case NEON_BUILTIN_vst4_lane:
    // Most of the load/store builtins do not have operands with the mode of
    // the operation.  Skip the mode check, since there is no extra operand
    // to check against the mode anyway.
    modeCheckOpnd = -1;
    break;
  }

  if (modeCheckOpnd >= 0) {

    switch (insn_data[icode].operand[modeCheckOpnd].mode) {
    case V8QImode: case V4HImode: case V2SImode: case V1DImode: case V2SFmode:
      if (!allow_64bit_modes)
        return BadModeError(exp, Result);
      break;
    case V16QImode: case V8HImode: case V4SImode: case V2DImode: case V4SFmode:
      if (!allow_128bit_modes)
        return BadModeError(exp, Result);
      break;
    default:
      return BadModeError(exp, Result);
    }

    if (datatype == neon_datatype_polynomial) {

      switch (insn_data[icode].operand[modeCheckOpnd].mode) {
      case V8QImode: case V16QImode:
        break;
      case V4HImode: case V8HImode:
        if (!allow_16bit_polynomials)
          return BadModeError(exp, Result);
        break;
      default:
        return BadModeError(exp, Result);
      }

    } else if (datatype == neon_datatype_float) {

      switch (insn_data[icode].operand[modeCheckOpnd].mode) {
      case V2SFmode: case V4SFmode:
        break;
      default:
        return BadModeError(exp, Result);
      }

    } else {

      switch (insn_data[icode].operand[modeCheckOpnd].mode) {
      case V8QImode: case V16QImode:
        if (!allow_8bit_elements)
          return BadModeError(exp, Result);
        break;
      case V4HImode: case V8HImode:
        if (!allow_16bit_elements)
          return BadModeError(exp, Result);
        break;
      case V2SImode: case V4SImode:
      case V2SFmode: case V4SFmode:
        if (!allow_32bit_elements)
          return BadModeError(exp, Result);
        break;
      case V1DImode: case V2DImode:
        if (!allow_64bit_elements)
          return BadModeError(exp, Result);
        break;
      default:
        return BadModeError(exp, Result);
      }
    }
  }

  // Now translate the builtin to LLVM.

  switch (neon_code) {
  default:
    assert(0 && "unimplemented builtin");
    break;

  case NEON_BUILTIN_vadd:
    if (datatype == neon_datatype_polynomial)
      return BadImmediateError(exp, Result);
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFAdd(Ops[0], Ops[1]);
    else
      Result = Builder.CreateAdd(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vaddl:
    if (datatype == neon_datatype_signed) {
      Ops[0] = Builder.CreateSExt(Ops[0], ResultType);
      Ops[1] = Builder.CreateSExt(Ops[1], ResultType);
    } else if (datatype == neon_datatype_unsigned) {
      Ops[0] = Builder.CreateZExt(Ops[0], ResultType);
      Ops[1] = Builder.CreateZExt(Ops[1], ResultType);
    } else
      return BadImmediateError(exp, Result);

    Result = Builder.CreateAdd(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vaddw:
    if (datatype == neon_datatype_signed)
      Ops[1] = Builder.CreateSExt(Ops[1], ResultType);
    else if (datatype == neon_datatype_unsigned)
      Ops[1] = Builder.CreateZExt(Ops[1], ResultType);
    else
      return BadImmediateError(exp, Result);

    Result = Builder.CreateAdd(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vhadd:
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrhadds :
               Intrinsic::arm_neon_vhadds);
    else if (datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrhaddu :
               Intrinsic::arm_neon_vhaddu);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqadd:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqadds;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vqaddu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vaddhn:
    if (datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vraddhn :
               Intrinsic::arm_neon_vaddhn);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vmul_lane:
  case NEON_BUILTIN_vmul_n:
    if (datatype == neon_datatype_polynomial)
      return BadImmediateError(exp, Result);
    // fall through....
  case NEON_BUILTIN_vmul:
    if (neon_code == NEON_BUILTIN_vmul_n) {
      Ops[1] = BuildDup(Ops[0]->getType(), Ops[1], Builder);
    } else if (neon_code == NEON_BUILTIN_vmul_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
      if (!isValidLane(Ops[2], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[1] = BuildDupLane(Ops[1], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_polynomial) {
      intID = Intrinsic::arm_neon_vmulp;
      intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
      Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    } else if (datatype == neon_datatype_float)
      Result = Builder.CreateFMul(Ops[0], Ops[1]);
    else
      Result = Builder.CreateMul(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vmla_lane:
  case NEON_BUILTIN_vmla_n:
  case NEON_BUILTIN_vmla:
    if (neon_code == NEON_BUILTIN_vmla_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vmla_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_polynomial)
      return BadImmediateError(exp, Result);
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFAdd(Ops[0], Builder.CreateFMul(Ops[1], Ops[2]));
    else
      Result = Builder.CreateAdd(Ops[0], Builder.CreateMul(Ops[1], Ops[2]));
    break;

  case NEON_BUILTIN_vmls_lane:
  case NEON_BUILTIN_vmls_n:
  case NEON_BUILTIN_vmls:
    if (neon_code == NEON_BUILTIN_vmls_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vmls_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_polynomial)
      return BadImmediateError(exp, Result);
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFSub(Ops[0], Builder.CreateFMul(Ops[1], Ops[2]));
    else
      Result = Builder.CreateSub(Ops[0], Builder.CreateMul(Ops[1], Ops[2]));
    break;

  case NEON_BUILTIN_vmlal_lane:
  case NEON_BUILTIN_vmlal_n:
  case NEON_BUILTIN_vmlal:
    if (neon_code == NEON_BUILTIN_vmlal_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vmlal_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vmulls;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vmullu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[1], Ops[2]);
    Result = Builder.CreateAdd(Ops[0], Result);
    break;

  case NEON_BUILTIN_vmlsl_lane:
  case NEON_BUILTIN_vmlsl_n:
  case NEON_BUILTIN_vmlsl:
    if (neon_code == NEON_BUILTIN_vmlsl_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vmlsl_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vmulls;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vmullu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[1], Ops[2]);
    Result = Builder.CreateSub(Ops[0], Result);
    break;

  case NEON_BUILTIN_vqdmulh_lane:
  case NEON_BUILTIN_vqdmulh_n:
  case NEON_BUILTIN_vqdmulh:
    if (neon_code == NEON_BUILTIN_vqdmulh_n) {
      Ops[1] = BuildDup(Ops[0]->getType(), Ops[1], Builder);
    } else if (neon_code == NEON_BUILTIN_vqdmulh_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
      if (!isValidLane(Ops[2], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[1] = BuildDupLane(Ops[1], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrdmulh :
               Intrinsic::arm_neon_vqdmulh);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqdmlal_lane:
  case NEON_BUILTIN_vqdmlal_n:
  case NEON_BUILTIN_vqdmlal:
    if (neon_code == NEON_BUILTIN_vqdmlal_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vqdmlal_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqdmlal;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall3(intFn, Ops[0], Ops[1], Ops[2]);
    break;

  case NEON_BUILTIN_vqdmlsl_lane:
  case NEON_BUILTIN_vqdmlsl_n:
  case NEON_BUILTIN_vqdmlsl:
    if (neon_code == NEON_BUILTIN_vqdmlsl_n) {
      Ops[2] = BuildDup(Ops[1]->getType(), Ops[2], Builder);
    } else if (neon_code == NEON_BUILTIN_vqdmlsl_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
      if (!isValidLane(Ops[3], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[2] = BuildDupLane(Ops[2], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqdmlsl;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall3(intFn, Ops[0], Ops[1], Ops[2]);
    break;

  case NEON_BUILTIN_vmull_lane:
  case NEON_BUILTIN_vmull_n:
  case NEON_BUILTIN_vmull:
    if (neon_code == NEON_BUILTIN_vmull_n) {
      Ops[1] = BuildDup(Ops[0]->getType(), Ops[1], Builder);
    } else if (neon_code == NEON_BUILTIN_vmull_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
      if (!isValidLane(Ops[2], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[1] = BuildDupLane(Ops[1], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_polynomial)
      intID = Intrinsic::arm_neon_vmullp;
    else if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vmulls;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vmullu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqdmull_n:
  case NEON_BUILTIN_vqdmull_lane:
  case NEON_BUILTIN_vqdmull:
    if (neon_code == NEON_BUILTIN_vqdmull_n) {
      Ops[1] = BuildDup(Ops[0]->getType(), Ops[1], Builder);
    } else if (neon_code == NEON_BUILTIN_vqdmull_lane) {
      unsigned LaneVal;
      unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
      if (!isValidLane(Ops[2], NUnits, &LaneVal))
        return UnexpectedError("%Hinvalid lane number", exp, Result);
      Ops[1] = BuildDupLane(Ops[1], LaneVal, NUnits, Builder);
    }
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqdmull;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vshl_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckLeftShiftCount, false))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      Result = Builder.CreateShl(Ops[0], Ops[1]);
    else
      return BadImmediateError(exp, Result);
    break;

  case NEON_BUILTIN_vshr_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckRightShiftCount, isRounded))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (!isRounded) {
      if (datatype == neon_datatype_signed)
        Result = Builder.CreateAShr(Ops[0], Ops[1]);
      else if (datatype == neon_datatype_unsigned)
        Result = Builder.CreateLShr(Ops[0], Ops[1]);
      else
        return BadImmediateError(exp, Result);
      break;
    }
    // fall through....
  case NEON_BUILTIN_vshl:
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrshifts :
               Intrinsic::arm_neon_vshifts);
    else if (datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrshiftu :
               Intrinsic::arm_neon_vshiftu);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vshrn_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckNarrowRightShiftCount, true))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrshiftn :
               Intrinsic::arm_neon_vshiftn);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqshl_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckLeftShiftCount, false))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    // fall through....
  case NEON_BUILTIN_vqshl:
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrshifts :
               Intrinsic::arm_neon_vqshifts);
    else if (datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrshiftu :
               Intrinsic::arm_neon_vqshiftu);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqshlu_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckLeftShiftCount, false))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype != neon_datatype_signed)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vqshiftsu;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqshrn_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckNarrowRightShiftCount, true))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrshiftns :
               Intrinsic::arm_neon_vqshiftns);
    else if (datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrshiftnu :
               Intrinsic::arm_neon_vqshiftnu);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqshrun_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckNarrowRightShiftCount, true))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype == neon_datatype_signed)
      intID = (isRounded ?
               Intrinsic::arm_neon_vqrshiftnsu :
               Intrinsic::arm_neon_vqshiftnsu);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vshll_n:
    if (!BuildShiftCountVector(Ops[1], insn_data[icode].operand[1].mode,
                               CheckLongLeftShiftCount, false))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vshiftls;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vshiftlu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vsra_n:
    if (!BuildShiftCountVector(Ops[2], insn_data[icode].operand[1].mode,
                               CheckRightShiftCount, isRounded))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    if (!isRounded) {
      if (datatype == neon_datatype_signed)
        Result = Builder.CreateAShr(Ops[1], Ops[2]);
      else if (datatype == neon_datatype_unsigned)
        Result = Builder.CreateLShr(Ops[1], Ops[2]);
      else
        return BadImmediateError(exp, Result);
    } else {
      if (datatype == neon_datatype_signed)
        intID = (isRounded ?
                 Intrinsic::arm_neon_vrshifts :
                 Intrinsic::arm_neon_vshifts);
      else if (datatype == neon_datatype_unsigned)
        intID = (isRounded ?
                 Intrinsic::arm_neon_vrshiftu :
                 Intrinsic::arm_neon_vshiftu);
      else
        return BadImmediateError(exp, Result);

      intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
      Result = Builder.CreateCall2(intFn, Ops[1], Ops[2]);
    }
    Result = Builder.CreateAdd(Ops[0], Result);
    break;

  case NEON_BUILTIN_vsub:
    if (datatype == neon_datatype_polynomial)
      return BadImmediateError(exp, Result);
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFSub(Ops[0], Ops[1]);
    else
      Result = Builder.CreateSub(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vsubl:
    if (datatype == neon_datatype_signed) {
      Ops[0] = Builder.CreateSExt(Ops[0], ResultType);
      Ops[1] = Builder.CreateSExt(Ops[1], ResultType);
    } else if (datatype == neon_datatype_unsigned) {
      Ops[0] = Builder.CreateZExt(Ops[0], ResultType);
      Ops[1] = Builder.CreateZExt(Ops[1], ResultType);
    } else
      return BadImmediateError(exp, Result);

    Result = Builder.CreateSub(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vsubw:
    if (datatype == neon_datatype_signed)
      Ops[1] = Builder.CreateSExt(Ops[1], ResultType);
    else if (datatype == neon_datatype_unsigned)
      Ops[1] = Builder.CreateZExt(Ops[1], ResultType);
    else
      return BadImmediateError(exp, Result);

    Result = Builder.CreateSub(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vqsub:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqsubs;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vqsubu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vhsub:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vhsubs;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vhsubu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vsubhn:
    if (datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      intID = (isRounded ?
               Intrinsic::arm_neon_vrsubhn :
               Intrinsic::arm_neon_vsubhn);
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vceq:
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFCmp(FCmpInst::FCMP_OEQ, Ops[0], Ops[1]);
    else
      Result = Builder.CreateICmp(ICmpInst::ICMP_EQ, Ops[0], Ops[1]);
    Result = Builder.CreateSExt(Result, ResultType);
    break;

  case NEON_BUILTIN_vcge:
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFCmp(FCmpInst::FCMP_OGE, Ops[0], Ops[1]);
    else if (datatype == neon_datatype_signed)
      Result = Builder.CreateICmp(ICmpInst::ICMP_SGE, Ops[0], Ops[1]);
    else if (datatype == neon_datatype_unsigned)
      Result = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[0], Ops[1]);
    else
      return BadImmediateError(exp, Result);
    Result = Builder.CreateSExt(Result, ResultType);
    break;

  case NEON_BUILTIN_vcgt:
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFCmp(FCmpInst::FCMP_OGT, Ops[0], Ops[1]);
    else if (datatype == neon_datatype_signed)
      Result = Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Ops[1]);
    else if (datatype == neon_datatype_unsigned)
      Result = Builder.CreateICmp(ICmpInst::ICMP_UGT, Ops[0], Ops[1]);
    else
      return BadImmediateError(exp, Result);
    Result = Builder.CreateSExt(Result, ResultType);
    break;

  case NEON_BUILTIN_vcage:
    if (datatype != neon_datatype_float)
      return BadImmediateError(exp, Result);

    switch (insn_data[icode].operand[1].mode) {
    case V2SFmode:
      intID = Intrinsic::arm_neon_vacged;
      break;
    case V4SFmode:
      intID = Intrinsic::arm_neon_vacgeq;
      break;
    default:
      return BadModeError(exp, Result);
    }

    intFn = Intrinsic::getDeclaration(TheModule, intID);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vcagt:
    if (datatype != neon_datatype_float)
      return BadImmediateError(exp, Result);

    switch (insn_data[icode].operand[1].mode) {
    case V2SFmode:
      intID = Intrinsic::arm_neon_vacgtd;
      break;
    case V4SFmode:
      intID = Intrinsic::arm_neon_vacgtq;
      break;
    default:
      return BadModeError(exp, Result);
    }

    intFn = Intrinsic::getDeclaration(TheModule, intID);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vtst:
    if (datatype == neon_datatype_float)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateICmp(ICmpInst::ICMP_NE,
                                Builder.CreateAnd(Ops[0], Ops[1]),
                                ConstantAggregateZero::get(ResultType));
    Result = Builder.CreateSExt(Result, ResultType);
    break;

  case NEON_BUILTIN_vabd:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vabds;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vabdu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vabdl: {
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vabds;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vabdu;
    else
      return BadImmediateError(exp, Result);

    VectorType *VTy = dyn_cast<VectorType>(ResultType);
    assert(VTy && "expected a vector type for vabdl result");
    llvm::Type *DTy = VectorType::getTruncatedElementVectorType(VTy);
    intFn = Intrinsic::getDeclaration(TheModule, intID, DTy);
    Ops[0] = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    Result = Builder.CreateZExt(Ops[0], ResultType);
    break;
  }

  case NEON_BUILTIN_vaba:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vabds;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vabdu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Ops[1] = Builder.CreateCall2(intFn, Ops[1], Ops[2]);
    Result = Builder.CreateAdd(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vabal: {
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vabds;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vabdu;
    else
      return BadImmediateError(exp, Result);

    VectorType *VTy = dyn_cast<VectorType>(ResultType);
    assert(VTy && "expected a vector type for vabal result");
    llvm::Type *DTy = VectorType::getTruncatedElementVectorType(VTy);
    intFn = Intrinsic::getDeclaration(TheModule, intID, DTy);
    Ops[1] = Builder.CreateCall2(intFn, Ops[1], Ops[2]);
    Ops[1] = Builder.CreateZExt(Ops[1], ResultType);
    Result = Builder.CreateAdd(Ops[0], Ops[1]);
    break;
  }

  case NEON_BUILTIN_vmax:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vmaxs;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vmaxu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vmin:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vmins;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vminu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vpadd:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vpadd;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vpaddl:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vpaddls;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vpaddlu;
    else
      return BadImmediateError(exp, Result);

    intOpTypes[0] = ResultType;
    intOpTypes[1] = Ops[0]->getType();
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vpadal:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vpadals;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vpadalu;
    else
      return BadImmediateError(exp, Result);

    intOpTypes[0] = ResultType;
    intOpTypes[1] = Ops[1]->getType();
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vpmax:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vpmaxs;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vpmaxu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vpmin:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vpmins;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vpminu;
    else
      return BadImmediateError(exp, Result);

    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vrecps:
    if (datatype != neon_datatype_float)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vrecps;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vrsqrts:
    if (datatype != neon_datatype_float)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vrsqrts;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vsri_n:
    if (!BuildShiftCountVector(Ops[2], insn_data[icode].operand[1].mode,
                               CheckRightShiftCount, true))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    intID = Intrinsic::arm_neon_vshiftins;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall3(intFn, Ops[0], Ops[1], Ops[2]);
    break;

  case NEON_BUILTIN_vsli_n:
    if (!BuildShiftCountVector(Ops[2], insn_data[icode].operand[1].mode,
                               CheckLeftShiftCount, false))
      return UnexpectedError("%Hinvalid shift count", exp, Result);
    intID = Intrinsic::arm_neon_vshiftins;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall3(intFn, Ops[0], Ops[1], Ops[2]);
    break;

  case NEON_BUILTIN_vabs:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vabs;
    else
      return BadImmediateError(exp, Result);
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vqabs:
    if (datatype != neon_datatype_signed)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vqabs;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vneg:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_float)
      return BadImmediateError(exp, Result);
    if (datatype == neon_datatype_float)
      Result = Builder.CreateFNeg(Ops[0]);
    else
      Result = Builder.CreateNeg(Ops[0]);
    break;

  case NEON_BUILTIN_vqneg:
    if (datatype != neon_datatype_signed)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vqneg;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vcls:
    if (datatype != neon_datatype_signed)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vcls;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vclz:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vclz;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vcnt:
    if (datatype == neon_datatype_float)
      return BadImmediateError(exp, Result);
    intID = Intrinsic::arm_neon_vcnt;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vrecpe:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vrecpe;
    else
      return BadImmediateError(exp, Result);
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vrsqrte:
    if (datatype == neon_datatype_float ||
        datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vrsqrte;
    else
      return BadImmediateError(exp, Result);
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vmvn:
    if (datatype == neon_datatype_float)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateNot(Ops[0]);
    break;

  case NEON_BUILTIN_vget_lane: {
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    if (!isValidLane(Ops[1], NUnits))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    Result = Builder.CreateExtractElement(Ops[0], Ops[1]);
    break;
  }

  case NEON_BUILTIN_vset_lane: {
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[2].mode);
    if (!isValidLane(Ops[2], NUnits))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    // GCC may promote the scalar argument; cast it back.
    const VectorType *VTy = dyn_cast<const VectorType>(Ops[1]->getType());
    assert(VTy && "expected a vector type for vset_lane vector operand");
    Type *ElTy = VTy->getElementType();
    if (Ops[0]->getType() != ElTy) {
      assert(!ElTy->isFloatingPointTy() &&
             "only integer types expected to be promoted");
      Ops[0] = Builder.CreateTrunc(Ops[0], ElTy);
    }
    Result = Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2]);
    break;
  }

  case NEON_BUILTIN_vcreate:
    Result = Builder.CreateBitCast(Ops[0], ResultType);
    break;

  case NEON_BUILTIN_vdup_n:
    Result = BuildDup(ResultType, Ops[0], Builder);
    break;

  case NEON_BUILTIN_vdup_lane: {
    unsigned LaneVal;
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    if (!isValidLane(Ops[1], NUnits, &LaneVal))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    unsigned DstUnits = GET_MODE_NUNITS(insn_data[icode].operand[0].mode);
    Result = BuildDupLane(Ops[0], LaneVal, DstUnits, Builder);
    break;
  }

  case NEON_BUILTIN_vcombine: {
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[0].mode);
    std::vector<Constant*> Idxs;
    for (unsigned i = 0; i != NUnits; ++i)
      Idxs.push_back(getInt32Const(i));
    Result = Builder.CreateShuffleVector(Ops[0], Ops[1],
                                         ConstantVector::get(Idxs));
    break;
  }

  case NEON_BUILTIN_vget_high:
  case NEON_BUILTIN_vget_low: {
    Type *v2f64Ty = VectorType::get(Type::getDoubleTy(Context), 2);
    unsigned Idx = (neon_code == NEON_BUILTIN_vget_low ? 0 : 1);
    Result = Builder.CreateBitCast(Ops[0], v2f64Ty);
    Result = Builder.CreateExtractElement(Result, getInt32Const(Idx));
    Result = Builder.CreateBitCast(Result, ResultType);
    break;
  }

  case NEON_BUILTIN_vmovn:
    if (datatype == neon_datatype_signed ||
        datatype == neon_datatype_unsigned)
      Result = Builder.CreateTrunc(Ops[0], ResultType);
    else
      return BadImmediateError(exp, Result);
    break;

  case NEON_BUILTIN_vqmovn:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqmovns;
    else if (datatype == neon_datatype_unsigned)
      intID = Intrinsic::arm_neon_vqmovnu;
    else
      return BadImmediateError(exp, Result);
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vqmovun:
    if (datatype == neon_datatype_signed)
      intID = Intrinsic::arm_neon_vqmovnsu;
    else
      return BadImmediateError(exp, Result);
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Result = Builder.CreateCall(intFn, Ops[0]);
    break;

  case NEON_BUILTIN_vmovl:
    if (datatype == neon_datatype_signed)
      Result = Builder.CreateSExt(Ops[0], ResultType);
    else if (datatype == neon_datatype_unsigned)
      Result = Builder.CreateZExt(Ops[0], ResultType);
    else
      return BadImmediateError(exp, Result);
    break;

  case NEON_BUILTIN_vext: {
    // Check if immediate operand is valid.
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    ConstantInt *Imm = dyn_cast<ConstantInt>(Ops[2]);
    if (!Imm)
      return UnexpectedError("%Hinvalid immediate for vext", exp, Result);
    int ImmVal = Imm->getSExtValue();
    if (ImmVal < 0 || ImmVal >= (int)NUnits)
      return UnexpectedError("%Hout of range immediate for vext", exp, Result);
    if (ImmVal == 0) {
      Result = Ops[0];
      break;
    }
    // Translate to a vector shuffle.
    std::vector<Constant*> Idxs;
    for (unsigned i = 0; i != NUnits; ++i)
      Idxs.push_back(getInt32Const(i + ImmVal));
    Result = Builder.CreateShuffleVector(Ops[0], Ops[1],
                                         ConstantVector::get(Idxs));
    break;
  }

  case NEON_BUILTIN_vrev64:
  case NEON_BUILTIN_vrev32:
  case NEON_BUILTIN_vrev16: {
    unsigned ChunkBits = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vrev64: ChunkBits = 64; break;
    case NEON_BUILTIN_vrev32: ChunkBits = 32; break;
    case NEON_BUILTIN_vrev16: ChunkBits = 16; break;
    default: assert(false);
    }
    const VectorType *VTy = dyn_cast<const VectorType>(ResultType);
    assert(VTy && "expected a vector type");
    Type *ElTy = VTy->getElementType();
    unsigned ChunkElts = ChunkBits / ElTy->getPrimitiveSizeInBits();

    // Translate to a vector shuffle.
    std::vector<Constant*> Idxs;
    unsigned NUnits = VTy->getNumElements();
    for (unsigned c = ChunkElts; c <= NUnits; c += ChunkElts) {
      for (unsigned i = 0; i != ChunkElts; ++i) {
        Idxs.push_back(getInt32Const(c - i - 1));
      }
    }
    Result = Builder.CreateShuffleVector(Ops[0], UndefValue::get(ResultType),
                                         ConstantVector::get(Idxs));
    break;
  }

  case NEON_BUILTIN_vcvt:
    if (FLOAT_MODE_P(insn_data[icode].operand[1].mode)) {
      if (datatype == neon_datatype_unsigned)
        Result = Builder.CreateFPToUI(Ops[0], ResultType);
      else if (datatype == neon_datatype_signed)
        Result = Builder.CreateFPToSI(Ops[0], ResultType);
      else
        return BadImmediateError(exp, Result);
    } else {
      if (datatype == neon_datatype_unsigned)
        Result = Builder.CreateUIToFP(Ops[0], ResultType);
      else if (datatype == neon_datatype_signed)
        Result = Builder.CreateSIToFP(Ops[0], ResultType);
      else
        return BadImmediateError(exp, Result);
    }
    break;

  case NEON_BUILTIN_vcvt_n: {
    // Check if the fractional bits argument is between 1 and 32.
    ConstantInt *FBits = dyn_cast<ConstantInt>(Ops[1]);
    if (!FBits)
      return UnexpectedError("%Hinvalid fractional bit count", exp, Result);
    int FBitsVal = FBits->getSExtValue();
    if (FBitsVal < 1 || FBitsVal > 32)
      return UnexpectedError("%Hinvalid fractional bit count", exp, Result);
    if (FLOAT_MODE_P(insn_data[icode].operand[1].mode)) {
      if (datatype == neon_datatype_unsigned)
        intID = Intrinsic::arm_neon_vcvtfp2fxu;
      else if (datatype == neon_datatype_signed)
        intID = Intrinsic::arm_neon_vcvtfp2fxs;
      else
        return BadImmediateError(exp, Result);
    } else {
      if (datatype == neon_datatype_unsigned)
        intID = Intrinsic::arm_neon_vcvtfxu2fp;
      else if (datatype == neon_datatype_signed)
        intID = Intrinsic::arm_neon_vcvtfxs2fp;
      else
        return BadImmediateError(exp, Result);
    }
    intOpTypes[0] = ResultType;
    intOpTypes[1] = Ops[0]->getType();
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    Result = Builder.CreateCall2(intFn, Ops[0], Ops[1]);
    break;
  }

  case NEON_BUILTIN_vbsl:
    Ops[1] = BitCastToType(Ops[1], Ops[0]->getType());
    Ops[2] = BitCastToType(Ops[2], Ops[0]->getType());
    Result = Builder.CreateOr(Builder.CreateAnd(Ops[1], Ops[0]),
                              Builder.CreateAnd(Ops[2],
                                                Builder.CreateNot(Ops[0])));
    break;

  case NEON_BUILTIN_vtbl1:
  case NEON_BUILTIN_vtbl2:
  case NEON_BUILTIN_vtbl3:
  case NEON_BUILTIN_vtbl4: {
    unsigned TblVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vtbl1:
      intID = Intrinsic::arm_neon_vtbl1;
      TblVecs = 1;
      break;
    case NEON_BUILTIN_vtbl2:
      intID = Intrinsic::arm_neon_vtbl2;
      TblVecs = 2;
      break;
    case NEON_BUILTIN_vtbl3:
      intID = Intrinsic::arm_neon_vtbl3;
      TblVecs = 3;
      break;
    case NEON_BUILTIN_vtbl4:
      intID = Intrinsic::arm_neon_vtbl4;
      TblVecs = 4;
      break;
    default:
      assert(false);
    }
    intFn = Intrinsic::getDeclaration(TheModule, intID);
    std::vector<Value*> Args;
    if (TblVecs == 1) {
      Args.push_back(Ops[0]);
    } else {
      for (unsigned n = 0; n < TblVecs; ++n) {
        Args.push_back(Builder.CreateExtractValue(Ops[0], n));
      }
    }
    Args.push_back(Ops[1]);
    Result = Builder.CreateCall(intFn, Args);
    break;
  }

  case NEON_BUILTIN_vtbx1:
  case NEON_BUILTIN_vtbx2:
  case NEON_BUILTIN_vtbx3:
  case NEON_BUILTIN_vtbx4: {
    unsigned TblVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vtbx1:
      intID = Intrinsic::arm_neon_vtbx1;
      TblVecs = 1;
      break;
    case NEON_BUILTIN_vtbx2:
      intID = Intrinsic::arm_neon_vtbx2;
      TblVecs = 2;
      break;
    case NEON_BUILTIN_vtbx3:
      intID = Intrinsic::arm_neon_vtbx3;
      TblVecs = 3;
      break;
    case NEON_BUILTIN_vtbx4:
      intID = Intrinsic::arm_neon_vtbx4;
      TblVecs = 4;
      break;
    default:
      assert(false);
    }
    intFn = Intrinsic::getDeclaration(TheModule, intID);
    std::vector<Value*> Args;
    Args.push_back(Ops[0]);
    if (TblVecs == 1) {
      Args.push_back(Ops[1]);
    } else {
      for (unsigned n = 0; n < TblVecs; ++n) {
        Args.push_back(Builder.CreateExtractValue(Ops[1], n));
      }
    }
    Args.push_back(Ops[2]);
    Result = Builder.CreateCall(intFn, Args);
    break;
  }

  case NEON_BUILTIN_vtrn: {
    // Translate this to a pair of vector shuffles.
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    for (unsigned Elt = 0; Elt != 2; ++Elt) {
      std::vector<Constant*> Idxs;
      for (unsigned i = 0; i < NUnits; i += 2) {
        Idxs.push_back(getInt32Const(i + Elt));
        Idxs.push_back(getInt32Const(i + NUnits + Elt));
      }
      Result = Builder.CreateShuffleVector(Ops[0], Ops[1],
                                           ConstantVector::get(Idxs));
      Value *Addr = Builder.CreateConstInBoundsGEP2_32(DestLoc->Ptr, 0, Elt);
      Builder.CreateStore(Result, Addr);
    }
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vzip: {
    // Translate this to a pair of vector shuffles.
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    unsigned Idx = 0;
    for (unsigned Elt = 0; Elt != 2; ++Elt) {
      std::vector<Constant*> Idxs;
      for (unsigned i = 0; i != NUnits; i += 2) {
        Idxs.push_back(getInt32Const(Idx));
        Idxs.push_back(getInt32Const(Idx + NUnits));
        Idx += 1;
      }
      Result = Builder.CreateShuffleVector(Ops[0], Ops[1],
                                           ConstantVector::get(Idxs));
      Value *Addr = Builder.CreateConstInBoundsGEP2_32(DestLoc->Ptr, 0, Elt);
      Builder.CreateStore(Result, Addr);
    }
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vuzp: {
    // Translate this to a pair of vector shuffles.
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    for (unsigned Elt = 0; Elt != 2; ++Elt) {
      std::vector<Constant*> Idxs;
      for (unsigned i = 0; i != NUnits; ++i)
        Idxs.push_back(getInt32Const(2 * i + Elt));
      Result = Builder.CreateShuffleVector(Ops[0], Ops[1],
                                           ConstantVector::get(Idxs));
      Value *Addr = Builder.CreateConstInBoundsGEP2_32(DestLoc->Ptr, 0, Elt);
      Builder.CreateStore(Result, Addr);
    }
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vreinterpretv8qi:
  case NEON_BUILTIN_vreinterpretv4hi:
  case NEON_BUILTIN_vreinterpretv2si:
  case NEON_BUILTIN_vreinterpretv2sf:
  case NEON_BUILTIN_vreinterpretv1di:
  case NEON_BUILTIN_vreinterpretv16qi:
  case NEON_BUILTIN_vreinterpretv8hi:
  case NEON_BUILTIN_vreinterpretv4si:
  case NEON_BUILTIN_vreinterpretv4sf:
  case NEON_BUILTIN_vreinterpretv2di:
    Result = Builder.CreateBitCast(Ops[0], ResultType);
    break;

  case NEON_BUILTIN_vld1: {
    intID = Intrinsic::arm_neon_vld1;
    intFn = Intrinsic::getDeclaration(TheModule, intID, ResultType);
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Result = Builder.CreateCall2(intFn, BitCastToType(Ops[0], VPTy),
                                 getInt32Const(Align));
    break;
  }

  case NEON_BUILTIN_vld2:
  case NEON_BUILTIN_vld3:
  case NEON_BUILTIN_vld4: {
    const StructType *STy = dyn_cast<const StructType>(ResultType);
    assert(STy && "expected a struct type");
    Type *VTy = STy->getElementType(0);
    switch (neon_code) {
    case NEON_BUILTIN_vld2: intID = Intrinsic::arm_neon_vld2; break;
    case NEON_BUILTIN_vld3: intID = Intrinsic::arm_neon_vld3; break;
    case NEON_BUILTIN_vld4: intID = Intrinsic::arm_neon_vld4; break;
    default: assert(false);
    }
    intFn = Intrinsic::getDeclaration(TheModule, intID, VTy);
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Result = Builder.CreateCall2(intFn, BitCastToType(Ops[0], VPTy),
                                 getInt32Const(Align));
    Builder.CreateStore(Result, DestLoc->Ptr);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vld1_lane: {
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[0].mode);
    if (!isValidLane(Ops[2], NUnits))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    Value *Elt = Builder.CreateLoad(Ops[0]);
    Result = Builder.CreateInsertElement(Ops[1], Elt, Ops[2]);
    break;
  }

  case NEON_BUILTIN_vld2_lane:
  case NEON_BUILTIN_vld3_lane:
  case NEON_BUILTIN_vld4_lane: {
    StructType *STy = dyn_cast<StructType>(ResultType);
    assert(STy && "expected a struct type");
    VectorType *VTy = dyn_cast<VectorType>(STy->getElementType(0));
    assert(VTy && "expected a vector type");
    if (!isValidLane(Ops[2], VTy->getNumElements()))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    switch (neon_code) {
    case NEON_BUILTIN_vld2_lane: intID = Intrinsic::arm_neon_vld2lane; break;
    case NEON_BUILTIN_vld3_lane: intID = Intrinsic::arm_neon_vld3lane; break;
    case NEON_BUILTIN_vld4_lane: intID = Intrinsic::arm_neon_vld4lane; break;
    default: assert(false);
    }
    intOpTypes[0] = VTy;
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    unsigned NumVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vld2_lane: NumVecs = 2; break;
    case NEON_BUILTIN_vld3_lane: NumVecs = 3; break;
    case NEON_BUILTIN_vld4_lane: NumVecs = 4; break;
    default: assert(false);
    }
    std::vector<Value*> Args;
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    Args.push_back(BitCastToType(Ops[0], VPTy));
    for (unsigned n = 0; n != NumVecs; ++n) {
      Args.push_back(Builder.CreateExtractValue(Ops[1], n));
    }
    Args.push_back(Ops[2]); // lane number
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Args.push_back(getInt32Const(Align));
    Result = Builder.CreateCall(intFn, Args);
    Builder.CreateStore(Result, DestLoc->Ptr);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vld1_dup:
    Result = BuildDup(ResultType, Builder.CreateLoad(Ops[0]), Builder);
    break;

  case NEON_BUILTIN_vld2_dup:
  case NEON_BUILTIN_vld3_dup:
  case NEON_BUILTIN_vld4_dup: {
    StructType *STy = dyn_cast<StructType>(ResultType);
    assert(STy && "expected a struct type");
    VectorType *VTy = dyn_cast<VectorType>(STy->getElementType(0));
    assert(VTy && "expected a vector type");
    intOpTypes[0] = VTy;

    // Handle 64-bit elements as a special-case.  There is no "dup" needed.
    if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
      switch (neon_code) {
      case NEON_BUILTIN_vld2_dup: intID = Intrinsic::arm_neon_vld2; break;
      case NEON_BUILTIN_vld3_dup: intID = Intrinsic::arm_neon_vld3; break;
      case NEON_BUILTIN_vld4_dup: intID = Intrinsic::arm_neon_vld4; break;
      default: assert(false);
      }
      intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
      Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
      unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
      Result = Builder.CreateCall2(intFn, BitCastToType(Ops[0], VPTy),
                                   getInt32Const(Align));
      Builder.CreateStore(Result, DestLoc->Ptr);
      Result = 0;
      break;
    }

    // First use a vldN_lane intrinsic to load into lane 0 of undef vectors.
    switch (neon_code) {
    case NEON_BUILTIN_vld2_dup: intID = Intrinsic::arm_neon_vld2lane; break;
    case NEON_BUILTIN_vld3_dup: intID = Intrinsic::arm_neon_vld3lane; break;
    case NEON_BUILTIN_vld4_dup: intID = Intrinsic::arm_neon_vld4lane; break;
    default: assert(false);
    }
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    unsigned NumVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vld2_dup: NumVecs = 2; break;
    case NEON_BUILTIN_vld3_dup: NumVecs = 3; break;
    case NEON_BUILTIN_vld4_dup: NumVecs = 4; break;
    default: assert(false);
    }
    std::vector<Value*> Args;
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    Args.push_back(BitCastToType(Ops[0], VPTy));
    for (unsigned n = 0; n != NumVecs; ++n) {
      Args.push_back(UndefValue::get(VTy));
    }
    Args.push_back(getInt32Const(0));
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Args.push_back(getInt32Const(Align));
    Result = Builder.CreateCall(intFn, Args);

    // Now splat the values in lane 0 to the rest of the elements.
    for (unsigned n = 0; n != NumVecs; ++n) {
      Value *Vec = Builder.CreateExtractValue(Result, n);
      Vec = BuildDupLane(Vec, 0, VTy->getNumElements(), Builder);
      Result = Builder.CreateInsertValue(Result, Vec, n);
    }

    Builder.CreateStore(Result, DestLoc->Ptr);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vst1: {
    Type *VTy = Ops[1]->getType();
    intID = Intrinsic::arm_neon_vst1;
    intFn = Intrinsic::getDeclaration(TheModule, intID, VTy);
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Builder.CreateCall3(intFn, BitCastToType(Ops[0], VPTy), Ops[1],
                        getInt32Const(Align));
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vst2:
  case NEON_BUILTIN_vst3:
  case NEON_BUILTIN_vst4: {
    const StructType *STy = dyn_cast<const StructType>(Ops[1]->getType());
    assert(STy && "expected a struct type");
    Type *VTy = STy->getElementType(0);
    switch (neon_code) {
    case NEON_BUILTIN_vst2: intID = Intrinsic::arm_neon_vst2; break;
    case NEON_BUILTIN_vst3: intID = Intrinsic::arm_neon_vst3; break;
    case NEON_BUILTIN_vst4: intID = Intrinsic::arm_neon_vst4; break;
    default: assert(false);
    }
    intFn = Intrinsic::getDeclaration(TheModule, intID, VTy);
    unsigned NumVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vst2: NumVecs = 2; break;
    case NEON_BUILTIN_vst3: NumVecs = 3; break;
    case NEON_BUILTIN_vst4: NumVecs = 4; break;
    default: assert(false);
    }
    std::vector<Value*> Args;
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    Args.push_back(BitCastToType(Ops[0], VPTy));
    for (unsigned n = 0; n != NumVecs; ++n) {
      Args.push_back(Builder.CreateExtractValue(Ops[1], n));
    }
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Args.push_back(getInt32Const(Align));
    Builder.CreateCall(intFn, Args);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vst1_lane: {
    unsigned NUnits = GET_MODE_NUNITS(insn_data[icode].operand[1].mode);
    if (!isValidLane(Ops[2], NUnits))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    Builder.CreateStore(Builder.CreateExtractElement(Ops[1], Ops[2]), Ops[0]);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vst2_lane:
  case NEON_BUILTIN_vst3_lane:
  case NEON_BUILTIN_vst4_lane: {
    StructType *STy = dyn_cast<StructType>(Ops[1]->getType());
    assert(STy && "expected a struct type");
    VectorType *VTy = dyn_cast<VectorType>(STy->getElementType(0));
    assert(VTy && "expected a vector type");
    if (!isValidLane(Ops[2], VTy->getNumElements()))
      return UnexpectedError("%Hinvalid lane number", exp, Result);
    switch (neon_code) {
    case NEON_BUILTIN_vst2_lane: intID = Intrinsic::arm_neon_vst2lane; break;
    case NEON_BUILTIN_vst3_lane: intID = Intrinsic::arm_neon_vst3lane; break;
    case NEON_BUILTIN_vst4_lane: intID = Intrinsic::arm_neon_vst4lane; break;
    default: assert(false);
    }
    intOpTypes[0] = VTy;
    intFn = Intrinsic::getDeclaration(TheModule, intID, intOpTypes);
    unsigned NumVecs = 0;
    switch (neon_code) {
    case NEON_BUILTIN_vst2_lane: NumVecs = 2; break;
    case NEON_BUILTIN_vst3_lane: NumVecs = 3; break;
    case NEON_BUILTIN_vst4_lane: NumVecs = 4; break;
    default: assert(false);
    }
    std::vector<Value*> Args;
    Type *VPTy = PointerType::getUnqual(Type::getInt8Ty(Context));
    Args.push_back(BitCastToType(Ops[0], VPTy));
    for (unsigned n = 0; n != NumVecs; ++n) {
      Args.push_back(Builder.CreateExtractValue(Ops[1], n));
    }
    Args.push_back(Ops[2]); // lane number
    unsigned Align = getPointerAlignment(TREE_VALUE(TREE_OPERAND(exp, 1)));
    Args.push_back(getInt32Const(Align));
    Builder.CreateCall(intFn, Args);
    Result = 0;
    break;
  }

  case NEON_BUILTIN_vand:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateAnd(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vorr:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateOr(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_veor:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateXor(Ops[0], Ops[1]);
    break;

  case NEON_BUILTIN_vbic:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateAnd(Ops[0], Builder.CreateNot(Ops[1]));
    break;

  case NEON_BUILTIN_vorn:
    if (datatype != neon_datatype_signed &&
        datatype != neon_datatype_unsigned)
      return BadImmediateError(exp, Result);
    Result = Builder.CreateOr(Ops[0], Builder.CreateNot(Ops[1]));
    break;
  }

  return true;
}

// "Fundamental Data Types" according to the AAPCS spec.  These are used
// to check that a given aggregate meets the criteria for a "homogeneous
// aggregate."
enum arm_fdts {
  ARM_FDT_INVALID,

  ARM_FDT_HALF_FLOAT,
  ARM_FDT_FLOAT,
  ARM_FDT_DOUBLE,

  ARM_FDT_VECTOR_64,
  ARM_FDT_VECTOR_128,

  ARM_FDT_MAX
};

// Classify type according to the number of fundamental data types contained
// among its members.  Returns true if type is a homogeneous aggregate.
static bool
vfp_arg_homogeneous_aggregate_p(enum machine_mode mode, tree type,
                                int *fdt_counts)
{
  bool result = false;
  HOST_WIDE_INT bytes =
    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);

  if (type && AGGREGATE_TYPE_P (type))
  {
    int i;
    int cnt = 0;
    tree field;

    // Zero sized arrays or structures are not homogeneous aggregates.
    if (!bytes)
      return 0;

    // Classify each field of records.
    switch (TREE_CODE (type))
    {
      case RECORD_TYPE:
      // For classes first merge in the field of the subclasses.
      if (TYPE_BINFO (type)) {
        tree binfo, base_binfo;
        int basenum;

        for (binfo = TYPE_BINFO (type), basenum = 0;
             BINFO_BASE_ITERATE (binfo, basenum, base_binfo); basenum++) {
          int offset = tree_low_cst (BINFO_OFFSET (base_binfo), 0) * 4;
          tree type = BINFO_TYPE (base_binfo);

          result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE (type), type,
                                                   fdt_counts);
          if (!result)
            return false;
        }
      }
      // And now merge the fields of structure.
      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) {
        if (TREE_CODE (field) == FIELD_DECL) {
          if (TREE_TYPE (field) == error_mark_node)
            continue;

          result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE(TREE_TYPE(field)),
                                                   TREE_TYPE(field),
                                                   fdt_counts);
          if (!result)
            return false;
        }
      }
      break;

      case ARRAY_TYPE:
        // Arrays are handled as small records.
        {
          int array_fdt_counts[ARM_FDT_MAX] = { 0 };

          result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE(TREE_TYPE(type)),
                                                   TREE_TYPE(type),
                                                   array_fdt_counts);

          cnt = bytes / int_size_in_bytes(TREE_TYPE(type));
          for (i = 0; i < ARM_FDT_MAX; ++i)
            fdt_counts[i] += array_fdt_counts[i] * cnt;

          if (!result)
            return false;
        }
      break;

      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        {
          // Unions are similar to RECORD_TYPE.
          int union_fdt_counts[ARM_FDT_MAX] = { 0 };

          // Unions are not derived.
          gcc_assert (!TYPE_BINFO (type)
                      || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
          for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) {
            int union_field_fdt_counts[ARM_FDT_MAX] = { 0 };

            if (TREE_CODE (field) == FIELD_DECL) {
              if (TREE_TYPE (field) == error_mark_node)
                continue;

              result = vfp_arg_homogeneous_aggregate_p(
                          TYPE_MODE(TREE_TYPE(field)),
                          TREE_TYPE(field),
                          union_field_fdt_counts);
              if (!result)
                return false;

              // track largest union field
              for (i = 0; i < ARM_FDT_MAX; ++i) {
                if (union_field_fdt_counts[i] > 4)  // bail early if we can
                  return false;

                union_fdt_counts[i] = MAX(union_fdt_counts[i],
                                          union_field_fdt_counts[i]);
                union_field_fdt_counts[i] = 0;  // clear it out for next iter
              }
            }
          }

          // check for only one type across all union fields
          cnt = 0;
          for (i = 0; i < ARM_FDT_MAX; ++i) {
            if (union_fdt_counts[i])
              ++cnt;

            if (cnt > 1)
              return false;

            fdt_counts[i] += union_fdt_counts[i];
          }
        }
      break;

      default:
      assert(0 && "What type is this?");
    }

    // Walk through fdt_counts.  This is a homogeneous aggregate if
    // only one FDT is used.
    cnt = 0;
    for (i = 0; i < ARM_FDT_MAX; ++i) {
      if (fdt_counts[i]) {
        // Make sure that one FDT is 4 or less elements in size.
        if (fdt_counts[i] > 4)
          return false;
        ++cnt;
      }

      if (cnt > 1)
        return false;
    }

    if (cnt == 0)
      return false;

    return true;
  }

  if (type)
  {
    int idx = 0;
    int cnt = 0;

    switch (TREE_CODE(type))
    {
    case REAL_TYPE:
      idx = (TYPE_PRECISION(type) == 32) ?
              ARM_FDT_FLOAT :
              ((TYPE_PRECISION(type) == 64) ?
                ARM_FDT_DOUBLE :
                ARM_FDT_INVALID);
      cnt = 1;
      break;

    case COMPLEX_TYPE:
      {
        tree subtype = TREE_TYPE(type);
        idx = (TYPE_PRECISION(subtype) == 32) ?
                ARM_FDT_FLOAT :
                ((TYPE_PRECISION(subtype) == 64) ?
                  ARM_FDT_DOUBLE :
                  ARM_FDT_INVALID);
        cnt = 2;
      }
      break;

    case VECTOR_TYPE:
      idx = (bytes == 8) ?
              ARM_FDT_VECTOR_64 :
              (bytes == 16) ?
                ARM_FDT_VECTOR_128 :
                ARM_FDT_INVALID;
      cnt = 1;
      break;

    case INTEGER_TYPE:
    case POINTER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case REFERENCE_TYPE:
    case FUNCTION_TYPE:
    case METHOD_TYPE:
    default:
      return false;     // All of these disqualify.
    }

    fdt_counts[idx] += cnt;
    return true;
  }
  else
    assert(0 && "what type was this?");

  return false;
}

// Walk over an LLVM Type that we know is a homogeneous aggregate and
// push the proper LLVM Types that represent the register types to pass
// that struct member in.
static void push_elts(Type *Ty, std::vector<Type*> &Elts)
{
  for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
       I != E; ++I) {
    Type *STy = *I;
    if (const VectorType *VTy = dyn_cast<VectorType>(STy)) {
      switch (VTy->getBitWidth())
      {
        case 64:  // v2f32
          Elts.push_back(VectorType::get(Type::getFloatTy(Context), 2));
          break;
        case 128: // v2f64
          Elts.push_back(VectorType::get(Type::getDoubleTy(Context), 2));
          break;
        default:
          assert (0 && "invalid vector type");
      }
    } else if (ArrayType *ATy = dyn_cast<ArrayType>(STy)) {
      Type *ETy = ATy->getElementType();

      for (uint64_t i = ATy->getNumElements(); i > 0; --i)
        Elts.push_back(ETy);
    } else if (STy->getNumContainedTypes())
      push_elts(STy, Elts);
    else
      Elts.push_back(STy);
  }
}

static unsigned count_num_words(std::vector<Type*> &ScalarElts) {
  unsigned NumWords = 0;
  for (unsigned i = 0, e = ScalarElts.size(); i != e; ++i) {
    Type *Ty = ScalarElts[i];
    if (Ty->isPointerTy()) {
      NumWords++;
    } else if (Ty->isIntegerTy()) {
      const unsigned TypeSize = Ty->getPrimitiveSizeInBits();
      const unsigned NumWordsForType = (TypeSize + 31) / 32;

      NumWords += NumWordsForType;
    } else {
      assert (0 && "Unexpected type.");
    }
  }
  return NumWords;
}

// This function is used only on AAPCS. The difference from the generic
// handling of arguments is that arguments larger than 32 bits are split
// and padding arguments are added as necessary for alignment. This makes
// the IL a bit more explicit about how arguments are handled.
extern bool
llvm_arm_try_pass_aggregate_custom(tree type,
                                   std::vector<Type*>& ScalarElts,
				   CallingConv::ID& CC,
				   struct DefaultABIClient* C) {
  if (CC != CallingConv::ARM_AAPCS && CC != CallingConv::C)
    return false;

  if (CC == CallingConv::C && !TARGET_AAPCS_BASED)
    return false;

  if (TARGET_HARD_FLOAT_ABI)
    return false;
  Type *Ty = ConvertType(type);
  if (Ty->isPointerTy())
    return false;

  const unsigned Size = TREE_INT_CST_LOW(TYPE_SIZE(type))/8;
  const unsigned Alignment = TYPE_ALIGN(type)/8;
  const unsigned NumWords = count_num_words(ScalarElts);
  const bool AddPad = Alignment >= 8 && (NumWords % 2);

  // First, build a type that will be bitcast to the original one and
  // from where elements will be extracted.
  std::vector<Type*> Elts;
  Type* Int32Ty = Type::getInt32Ty(getGlobalContext());
  const unsigned NumRegularArgs = Size / 4;
  for (unsigned i = 0; i < NumRegularArgs; ++i) {
    Elts.push_back(Int32Ty);
  }
  const unsigned RestSize = Size % 4;
  llvm::Type *RestType = NULL;
  if (RestSize> 2) {
    RestType = Type::getInt32Ty(getGlobalContext());
  } else if (RestSize > 1) {
    RestType = Type::getInt16Ty(getGlobalContext());
  } else if (RestSize > 0) {
    RestType = Type::getInt8Ty(getGlobalContext());
  }
  if (RestType)
    Elts.push_back(RestType);
  StructType *STy = StructType::get(getGlobalContext(), Elts, false);

  if (AddPad) {
    ScalarElts.push_back(Int32Ty);
    C->HandlePad(Int32Ty);
  }

  for (unsigned i = 0; i < NumRegularArgs; ++i) {
    C->EnterField(i, STy);
    C->HandleScalarArgument(Int32Ty, 0);
    ScalarElts.push_back(Int32Ty);
    C->ExitField();
  }
  if (RestType) {
    C->EnterField(NumRegularArgs, STy);
    C->HandleScalarArgument(RestType, 0, RestSize);
    ScalarElts.push_back(RestType);
    C->ExitField();
  }
  return true;
}

// Target hook for llvm-abi.h. It returns true if an aggregate of the
// specified type should be passed in a number of registers of mixed types.
// It also returns a vector of types that correspond to the registers used
// for parameter passing. This only applies to AAPCS-VFP "homogeneous
// aggregates" as specified in 4.3.5 of the AAPCS spec.
bool
llvm_arm_should_pass_aggregate_in_mixed_regs(tree TreeType, Type *Ty,
                                             CallingConv::ID &CC,
                                             std::vector<Type*> &Elts) {
  if (!llvm_arm_should_pass_or_return_aggregate_in_regs(TreeType, CC))
    return false;

  // Walk Ty and push LLVM types corresponding to register types onto
  // Elts.
  push_elts(Ty, Elts);

  return true;
}

static bool alloc_next_spr(bool *SPRs)
{
  for (int i = 0; i < 16; ++i)
    if (!SPRs[i]) {
      SPRs[i] = true;
      return true;
    }
  return false;
}

static bool alloc_next_dpr(bool *SPRs)
{
  for (int i = 0; i < 16; i += 2)
    if (!SPRs[i]) {
      SPRs[i] = SPRs[i+1] = true;
      return true;
    }
  return false;
}

static bool alloc_next_qpr(bool *SPRs) {
  for (int i = 0; i < 16; i += 4)
    if (!SPRs[i]) {
      SPRs[i] = SPRs[i+1] = SPRs[i+2] = SPRs[i+3] = true;
      return true;
    }
  return false;
}

// count_num_registers_uses - Simulate argument passing reg allocation in SPRs.
// Caller is expected to zero out SPRs.  Returns true if all of ScalarElts fit
// in registers.
static bool count_num_registers_uses(std::vector<Type*> &ScalarElts,
                                     bool *SPRs) {
  for (unsigned i = 0, e = ScalarElts.size(); i != e; ++i) {
    Type *Ty = ScalarElts[i];
    if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
      switch (VTy->getBitWidth())
      {
        case 64:
          if (!alloc_next_dpr(SPRs))
            return false;
          break;
        case 128:
          if (!alloc_next_qpr(SPRs))
            return false;
          break;
        default:
          assert(0);
      }
    } else if (Ty->isIntegerTy() || Ty->isPointerTy() ||
               Ty==Type::getVoidTy(Context)) {
      ;
    } else {
      // Floating point scalar argument.
      assert(Ty->isFloatingPointTy() && Ty->isPrimitiveType() &&
             "Expecting a floating point primitive type!");
      switch (Ty->getTypeID())
      {
        case Type::FloatTyID:
          if (!alloc_next_spr(SPRs))
            return false;
          break;
        case Type::DoubleTyID:
          if (!alloc_next_spr(SPRs))
            return false;
          break;
        default:
          assert(0);
      }
    }
  }
  return true;
}

// Target hook for llvm-abi.h. This is called when an aggregate is being passed
// in registers. If there are only enough available parameter registers to pass
// part of the aggregate, return true. That means the aggregate should instead
// be passed in memory.
bool
llvm_arm_aggregate_partially_passed_in_regs(std::vector<Type*> &Elts,
                                            std::vector<Type*> &ScalarElts,
                                            CallingConv::ID &CC) {
  // Homogeneous aggregates are an AAPCS-VFP feature.
  if ((CC != CallingConv::ARM_AAPCS_VFP) ||
      !(TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT_ABI))
    return true;

  bool SPRs[16] = { 0 };                    // represents S0-S16

  // Figure out which SPRs are available.
  if (!count_num_registers_uses(ScalarElts, SPRs))
    return true;

  if (!count_num_registers_uses(Elts, SPRs))
    return true;

  return false;                            // it all fit in registers!
}

// Return LLVM Type if TYPE can be returned as an aggregate,
// otherwise return NULL.
Type *llvm_arm_aggr_type_for_struct_return(tree TreeType,
                                           CallingConv::ID &CC) {
  if (!llvm_arm_should_pass_or_return_aggregate_in_regs(TreeType, CC))
    return NULL;

  // Walk Ty and push LLVM types corresponding to register types onto
  // Elts.
  std::vector<Type*> Elts;
  Type *Ty = ConvertType(TreeType);
  push_elts(Ty, Elts);

  return StructType::get(Context, Elts, false);
}

// llvm_arm_extract_mrv_array_element - Helper function that helps extract
// an array element from multiple return value.
//
// Here, SRC is returning multiple values. DEST's DESTFIELDNO field is an array.
// Extract SRCFIELDNO's ELEMENO value and store it in DEST's FIELDNO field's
// ELEMENTNO.
//
static void llvm_arm_extract_mrv_array_element(Value *Src, Value *Dest,
                                               unsigned SrcFieldNo,
                                               unsigned SrcElemNo,
                                               unsigned DestFieldNo,
                                               unsigned DestElemNo,
                                               LLVMBuilder &Builder,
                                               bool isVolatile) {
  Value *EVI = Builder.CreateExtractValue(Src, SrcFieldNo, "mrv_gr");
  const StructType *STy = cast<StructType>(Src->getType());
  llvm::Value *Idxs[3];
  Idxs[0] = ConstantInt::get(llvm::Type::getInt32Ty(Context), 0);
  Idxs[1] = ConstantInt::get(llvm::Type::getInt32Ty(Context), DestFieldNo);
  Idxs[2] = ConstantInt::get(llvm::Type::getInt32Ty(Context), DestElemNo);
  Value *GEP = Builder.CreateGEP(Dest, Idxs, "mrv_gep");
  if (STy->getElementType(SrcFieldNo)->isVectorTy()) {
    Value *ElemIndex = ConstantInt::get(Type::getInt32Ty(Context), SrcElemNo);
    Value *EVIElem = Builder.CreateExtractElement(EVI, ElemIndex, "mrv");
    Builder.CreateStore(EVIElem, GEP, isVolatile);
  } else {
    Builder.CreateStore(EVI, GEP, isVolatile);
  }
}

// llvm_arm_extract_multiple_return_value - Extract multiple values returned
// by SRC and store them in DEST. It is expected that SRC and
// DEST types are StructType, but they may not match.
void llvm_arm_extract_multiple_return_value(Value *Src, Value *Dest,
                                            bool isVolatile,
                                            LLVMBuilder &Builder) {
  const StructType *STy = cast<StructType>(Src->getType());
  unsigned NumElements = STy->getNumElements();

  const PointerType *PTy = cast<PointerType>(Dest->getType());
  const StructType *DestTy = cast<StructType>(PTy->getElementType());

  unsigned SNO = 0;
  unsigned DNO = 0;

  while (SNO < NumElements) {

    Type *DestElemType = DestTy->getElementType(DNO);

    // Directly access first class values.
    if (DestElemType->isSingleValueType()) {
      Value *GEP = Builder.CreateStructGEP(Dest, DNO, "mrv_gep");
      Value *EVI = Builder.CreateExtractValue(Src, SNO, "mrv_gr");
      Builder.CreateStore(EVI, GEP, isVolatile);
      ++DNO; ++SNO;
      continue;
    }

    // Access array elements individually. Note, Src and Dest type may
    // not match. For example { <2 x float>, float } and { float[3]; }
    const ArrayType *ATy = cast<ArrayType>(DestElemType);
    unsigned ArraySize = ATy->getNumElements();
    unsigned DElemNo = 0; // DestTy's DNO field's element number
    while (DElemNo < ArraySize) {
      unsigned i = 0;
      unsigned Size = 1;

      if (const VectorType *SElemTy =
          dyn_cast<VectorType>(STy->getElementType(SNO))) {
        Size = SElemTy->getNumElements();
      }
      while (i < Size) {
        llvm_arm_extract_mrv_array_element(Src, Dest, SNO, i++,
                                           DNO, DElemNo++,
                                           Builder, isVolatile);
      }
      // Consumed this src field. Try next one.
      ++SNO;
    }
    // Finished building current dest field.
    ++DNO;
  }
}

// Target hook for llvm-abi.h for LLVM_SHOULD_NOT_USE_SHADOW_RETURN and is
// also a utility function used for other target hooks in this file. Returns
// true if the aggregate should be passed or returned in registers.
bool llvm_arm_should_pass_or_return_aggregate_in_regs(tree TreeType,
                                                      CallingConv::ID &CC) {
  // Homogeneous aggregates are an AAPCS-VFP feature.
  if ((CC != CallingConv::ARM_AAPCS_VFP) ||
      !(TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT_ABI))
    return false;

  // Alas, we can't use LLVM Types to figure this out because we need to
  // examine unions closely.  We'll have to walk the GCC TreeType.
  int fdt_counts[ARM_FDT_MAX] = { 0 };
  bool result = false;
  result = vfp_arg_homogeneous_aggregate_p(TYPE_MODE(TreeType), TreeType,
                                           fdt_counts);
  return result && !TREE_ADDRESSABLE(TreeType);
}

/* LLVM LOCAL end (ENTIRE FILE!)  */
