/* LLVM LOCAL begin (ENTIRE FILE!)  */
/* High-level LLVM backend interface 
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by Jim Laskey (jlaskey@apple.com)

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 powerpc ABI.
//===----------------------------------------------------------------------===//

#include "llvm-abi.h"
#include "llvm-internal.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"

extern "C" {
#include "toplev.h"
}

// MergeIntPtrOperand - This merges the int and pointer operands of a GCC
// intrinsic into a single operand for the LLVM intrinsic.  For example, this
// turns LVX(4, p) -> llvm.lvx(gep P, 4).  OPNUM specifies the operand number
// of the integer to contract with its following pointer and NAME specifies the
// name of the resultant intrinsic.
static void MergeIntPtrOperand(TreeToLLVM *TTL,
                               unsigned OpNum, Intrinsic::ID IID,
                               const Type *ResultType,
                               std::vector<Value*> &Ops,
                               LLVMBuilder &Builder, Value *&Result) {
  const Type *VoidPtrTy = PointerType::getUnqual(Type::Int8Ty);
  
  Function *IntFn = Intrinsic::getDeclaration(TheModule, IID);
  
  Value *Offset = Ops[OpNum];
  Value *Ptr = Ops[OpNum + 1];
  Ptr = TTL->CastToType(Instruction::BitCast, Ptr, VoidPtrTy);
  
  if (!isa<Constant>(Offset) || !cast<Constant>(Offset)->isNullValue())
    Ptr = Builder.CreateGEP(Ptr, Offset, "tmp");
    
  Ops.erase(Ops.begin() + OpNum);
  Ops[OpNum] = Ptr;
  Value *V = Builder.CreateCall(IntFn, &Ops[0], &Ops[0]+Ops.size());
  
  if (V->getType() != Type::VoidTy) {
    V->setName("tmp");
    Result = V;
  }
}

// GetAltivecTypeNumFromType - Given an LLVM type, return a unique ID for
// the type in the range 0-3.
static int GetAltivecTypeNumFromType(const Type *Ty) {
  return ((Ty == Type::Int32Ty) ? 0 : \
          ((Ty == Type::Int16Ty) ? 1 : \
           ((Ty == Type::Int8Ty) ? 2 : \
            ((Ty == Type::FloatTy) ? 3 : -1))));
}

// 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,
                                      const Type *ResultType,
                                      std::vector<Value*> &Ops) {
  switch (FnCode) {
  default: break;
  case ALTIVEC_BUILTIN_VADDFP:
  case ALTIVEC_BUILTIN_VADDUBM:
  case ALTIVEC_BUILTIN_VADDUHM:
  case ALTIVEC_BUILTIN_VADDUWM:
    Result = Builder.CreateAdd(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_VSUBFP:
  case ALTIVEC_BUILTIN_VSUBUBM:
  case ALTIVEC_BUILTIN_VSUBUHM:
  case ALTIVEC_BUILTIN_VSUBUWM:
    Result = Builder.CreateSub(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_VAND:
    Result = Builder.CreateAnd(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_VANDC:
    Ops[1] = Builder.CreateNot(Ops[1], "tmp");
    Result = Builder.CreateAnd(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_VOR:
    Result = Builder.CreateOr(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_VNOR:
    Result = Builder.CreateOr(Ops[0], Ops[1], "tmp");
    Result = Builder.CreateNot(Result, "tmp");
    return true;
  case ALTIVEC_BUILTIN_VXOR:
    Result = Builder.CreateXor(Ops[0], Ops[1], "tmp");
    return true;
  case ALTIVEC_BUILTIN_LVSL:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvsl,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVSR:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvsr,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVX:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVXL:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvxl,
                         ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVEBX:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvebx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVEHX:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvehx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_LVEWX:
    MergeIntPtrOperand(this, 0, Intrinsic::ppc_altivec_lvewx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_STVX:
    MergeIntPtrOperand(this, 1, Intrinsic::ppc_altivec_stvx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_STVEBX:
    MergeIntPtrOperand(this, 1, Intrinsic::ppc_altivec_stvebx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_STVEHX:
    MergeIntPtrOperand(this, 1, Intrinsic::ppc_altivec_stvehx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_STVEWX:
    MergeIntPtrOperand(this, 1, Intrinsic::ppc_altivec_stvewx,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_STVXL:
    MergeIntPtrOperand(this, 1, Intrinsic::ppc_altivec_stvxl,
                       ResultType, Ops, Builder, Result);
    return true;
  case ALTIVEC_BUILTIN_VSPLTISB:
    if (Constant *Elt = dyn_cast<ConstantInt>(Ops[0])) {
      Elt = ConstantExpr::getIntegerCast(Elt, Type::Int8Ty, true);
      Result = BuildVector(Elt, Elt, Elt, Elt,  Elt, Elt, Elt, Elt,
                           Elt, Elt, Elt, Elt,  Elt, Elt, Elt, Elt, NULL);
    } else {
      error("%Helement must be an immediate", &EXPR_LOCATION(exp));
      Result = UndefValue::get(VectorType::get(Type::Int8Ty, 16));
    }
    return true;
  case ALTIVEC_BUILTIN_VSPLTISH:
    if (Constant *Elt = dyn_cast<ConstantInt>(Ops[0])) {
      Elt = ConstantExpr::getIntegerCast(Elt, Type::Int16Ty, true);
      Result = BuildVector(Elt, Elt, Elt, Elt,  Elt, Elt, Elt, Elt, NULL);
    } else {
      error("%Helement must be an immediate", &EXPR_LOCATION(exp));
      Result = UndefValue::get(VectorType::get(Type::Int16Ty, 8));
    }
    return true;
  case ALTIVEC_BUILTIN_VSPLTISW:
    if (Constant *Elt = dyn_cast<ConstantInt>(Ops[0])) {
      Elt = ConstantExpr::getIntegerCast(Elt, Type::Int32Ty, true);
      Result = BuildVector(Elt, Elt, Elt, Elt, NULL);
    } else {
      error("%Hmask must be an immediate", &EXPR_LOCATION(exp));
      Result = UndefValue::get(VectorType::get(Type::Int32Ty, 4));
    }
    return true;
  case ALTIVEC_BUILTIN_VSPLTB:
    if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[1])) {
      int EV = Elt->getZExtValue();
      Result = BuildVectorShuffle(Ops[0], Ops[0],
                                  EV, EV, EV, EV, EV, EV, EV, EV,
                                  EV, EV, EV, EV, EV, EV, EV, EV);
    } else {
      error("%Helement number must be an immediate", &EXPR_LOCATION(exp));
      Result = Ops[0];
    }
    return true;
  case ALTIVEC_BUILTIN_VSPLTH:
    if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[1])) {
      int EV = Elt->getZExtValue();
      // gcc accepts anything up to 31, and there is code that tests for it, 
      // although it doesn't seem to make sense.  Hardware behaves as if mod 8.
      if (EV>7 && EV<=31)
        EV = EV%8;
      Result = BuildVectorShuffle(Ops[0], Ops[0],
                                  EV, EV, EV, EV, EV, EV, EV, EV);
    } else {
      error("%Helement number must be an immediate", &EXPR_LOCATION(exp));
      Result = Ops[0];
    }
    return true;
  case ALTIVEC_BUILTIN_VSPLTW:
    if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[1])) {
      int EV = Elt->getZExtValue();
      // gcc accepts anything up to 31, and there is code that tests for it, 
      // although it doesn't seem to make sense.  Hardware behaves as if mod 4.
      if (EV>3 && EV<=31)
        EV = EV%4;
      Result = BuildVectorShuffle(Ops[0], Ops[0], EV, EV, EV, EV);
    } else {
      error("%Helement number must be an immediate", &EXPR_LOCATION(exp));
      Result = Ops[0];
    }
    return true;
  case ALTIVEC_BUILTIN_VSLDOI_16QI:
  case ALTIVEC_BUILTIN_VSLDOI_8HI:
  case ALTIVEC_BUILTIN_VSLDOI_4SI:
  case ALTIVEC_BUILTIN_VSLDOI_4SF:
    if (ConstantInt *Elt = dyn_cast<ConstantInt>(Ops[2])) {
      /* Map all of these to a shuffle. */
      unsigned Amt = Elt->getZExtValue() & 15;
      VectorType *v16i8 = VectorType::get(Type::Int8Ty, 16);
      Ops[0] = Builder.CreateBitCast(Ops[0], v16i8, "tmp");
      Ops[1] = Builder.CreateBitCast(Ops[1], v16i8, "tmp");
      Result = BuildVectorShuffle(Ops[0], Ops[1],
                                  Amt, Amt+1, Amt+2, Amt+3,
                                  Amt+4, Amt+5, Amt+6, Amt+7,
                                  Amt+8, Amt+9, Amt+10, Amt+11,
                                  Amt+12, Amt+13, Amt+14, Amt+15);
    } else {
      error("%Hshift amount must be an immediate", &EXPR_LOCATION(exp));
      Result = Ops[0];
    }
    return true;
  case ALTIVEC_BUILTIN_VPKUHUM:
    Ops[0] = Builder.CreateBitCast(Ops[0], ResultType, "tmp");
    Ops[1] = Builder.CreateBitCast(Ops[1], ResultType, "tmp");
    Result = BuildVectorShuffle(Ops[0], Ops[1], 1, 3, 5, 7, 9, 11, 13, 15,
                                17, 19, 21, 23, 25, 27, 29, 31);
    return true;
  case ALTIVEC_BUILTIN_VPKUWUM:
    Ops[0] = Builder.CreateBitCast(Ops[0], ResultType, "tmp");
    Ops[1] = Builder.CreateBitCast(Ops[1], ResultType, "tmp");
    Result = BuildVectorShuffle(Ops[0], Ops[1], 1, 3, 5, 7, 9, 11, 13, 15);
    return true;
  case ALTIVEC_BUILTIN_VMRGHB:
    Result = BuildVectorShuffle(Ops[0], Ops[1],
                                0, 16, 1, 17, 2, 18, 3, 19,
                                4, 20, 5, 21, 6, 22, 7, 23);
    return true;
  case ALTIVEC_BUILTIN_VMRGHH:
    Result = BuildVectorShuffle(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11);
    return true;
  case ALTIVEC_BUILTIN_VMRGHW:
    Result = BuildVectorShuffle(Ops[0], Ops[1], 0, 4, 1, 5);
    return true;
  case ALTIVEC_BUILTIN_VMRGLB:
    Result = BuildVectorShuffle(Ops[0], Ops[1],
                                 8, 24,  9, 25, 10, 26, 11, 27,
                                12, 28, 13, 29, 14, 30, 15, 31);
    return true;
  case ALTIVEC_BUILTIN_VMRGLH:
    Result = BuildVectorShuffle(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15);
    return true;
  case ALTIVEC_BUILTIN_VMRGLW:
    Result = BuildVectorShuffle(Ops[0], Ops[1], 2, 6, 3, 7);
    return true;
  case ALTIVEC_BUILTIN_ABS_V4SF: {
    // and out sign bits
    VectorType *v4i32 = VectorType::get(Type::Int32Ty, 4);
    Ops[0] = Builder.CreateBitCast(Ops[0], v4i32, "tmp");
    Constant *C = ConstantInt::get(Type::Int32Ty, 0x7FFFFFFF);
    C = ConstantVector::get(std::vector<Constant*>(4, C));
    Result = Builder.CreateAnd(Ops[0], C, "tmp");
    Result = Builder.CreateBitCast(Result, ResultType, "tmp");
    return true;
  }
  case ALTIVEC_BUILTIN_ABS_V4SI:
  case ALTIVEC_BUILTIN_ABS_V8HI:
  case ALTIVEC_BUILTIN_ABS_V16QI: { // iabs(x) -> smax(x, 0-x)
    Result = Builder.CreateNeg(Ops[0], "tmp");
    // get the right smax intrinsic.
    static const Intrinsic::ID smax_iid[3] = {
      Intrinsic::ppc_altivec_vmaxsw,
      Intrinsic::ppc_altivec_vmaxsh,
      Intrinsic::ppc_altivec_vmaxsb
    };
    const VectorType *PTy = cast<VectorType>(ResultType);
    unsigned N = GetAltivecTypeNumFromType(PTy->getElementType());
    Function *smax = Intrinsic::getDeclaration(TheModule, smax_iid[N]);
    Value *ActualOps[] = { Ops[0], Result };
    Result = Builder.CreateCall(smax, ActualOps, ActualOps+2, "tmp");
    return true;
  }
  case ALTIVEC_BUILTIN_ABSS_V4SI:
  case ALTIVEC_BUILTIN_ABSS_V8HI:
  case ALTIVEC_BUILTIN_ABSS_V16QI: { // iabss(x) -> smax(x, satsub(0,x))
    // get the right smax/subs intrinsics.
    static const Intrinsic::ID smax_iid[3] = {
      Intrinsic::ppc_altivec_vmaxsw,
      Intrinsic::ppc_altivec_vmaxsh,
      Intrinsic::ppc_altivec_vmaxsb
    };
    static const Intrinsic::ID subss_iid[3] = {
      Intrinsic::ppc_altivec_vsubsws,
      Intrinsic::ppc_altivec_vsubshs,
      Intrinsic::ppc_altivec_vsubsbs
    };
    
    // get the right satsub intrinsic.
    const VectorType *PTy = cast<VectorType>(ResultType);
    unsigned N = GetAltivecTypeNumFromType(PTy->getElementType());
    Function *smax = Intrinsic::getDeclaration(TheModule, smax_iid[N]);
    Function *subss = Intrinsic::getDeclaration(TheModule, subss_iid[N]);

    Value *ActualOps[] = { Constant::getNullValue(ResultType), Ops[0] };
    Result = Builder.CreateCall(subss, ActualOps, ActualOps+2, "tmp");
    ActualOps[0] = Ops[0];
    ActualOps[1] = Result;
    Result = Builder.CreateCall(smax, ActualOps, ActualOps+2, "tmp");
    return true;
  }
  case ALTIVEC_BUILTIN_VPERM_4SI:
  case ALTIVEC_BUILTIN_VPERM_4SF:
  case ALTIVEC_BUILTIN_VPERM_8HI:
  case ALTIVEC_BUILTIN_VPERM_16QI: {
    // Operation is identical on all types; we have a single intrinsic.
    const Type *VecTy = VectorType::get(Type::Int32Ty, 4);
    Value *Op0 = CastToType(Instruction::BitCast, Ops[0], VecTy);
    Value *Op1 = CastToType(Instruction::BitCast, Ops[1], VecTy);
    Value *ActualOps[] = { Op0, Op1, Ops[2]};
    Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, 
                                          Intrinsic::ppc_altivec_vperm), 
                                ActualOps, ActualOps+3, "tmp");
    Result = CastToType(Instruction::BitCast, Result, Ops[0]->getType());
    return true;
  }
  case ALTIVEC_BUILTIN_VSEL_4SI:
  case ALTIVEC_BUILTIN_VSEL_4SF:
  case ALTIVEC_BUILTIN_VSEL_8HI:
  case ALTIVEC_BUILTIN_VSEL_16QI: {
    // Operation is identical on all types; we have a single intrinsic.
    const Type *VecTy = VectorType::get(Type::Int32Ty, 4);
    Value *Op0 = CastToType(Instruction::BitCast, Ops[0], VecTy);
    Value *Op1 = CastToType(Instruction::BitCast, Ops[1], VecTy);
    Value *Op2 = CastToType(Instruction::BitCast, Ops[2], VecTy);
    Value *ActualOps[] = { Op0, Op1, Op2 };
    Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, 
                                          Intrinsic::ppc_altivec_vsel), 
                                ActualOps, ActualOps+3, "tmp");
    Result = CastToType(Instruction::BitCast, Result, Ops[0]->getType());
    return true;
  }
  }

  return false;
}

/* Target hook for llvm-abi.h. It returns true if an aggregate of the
   specified type should be passed using the byval mechanism. */
bool llvm_rs6000_should_pass_aggregate_byval(tree TreeType, const Type *Ty) {

  /* FIXME byval not implemented for ppc64. */
  if (TARGET_64BIT)
    return false;

  HOST_WIDE_INT Bytes = (TYPE_MODE(TreeType) == BLKmode) ? 
                        int_size_in_bytes(TreeType) : 
                        (int) GET_MODE_SIZE(TYPE_MODE(TreeType));

  // Zero sized array, struct, or class, ignored.
  if (Bytes == 0)
    return false;

  // Large types always use byval.  If this is a small fixed size type, 
  // investigate it.
  if (Bytes <= 0 || Bytes > 16)
    return true;

  // ppc32 passes aggregates by copying, either in int registers or on the 
  // stack.
  const StructType *STy = dyn_cast<StructType>(Ty);
  if (!STy) return true;

  // A struct containing only a float, double or vector field, possibly with
  // some zero-length fields as well, must be passed as the field type.
  // Note this does not apply to long double.
  // This is required for ABI correctness.  
  tree tType = isSingleElementStructOrArray(TreeType, true, false);
  if (tType && int_size_in_bytes(tType)==Bytes && TYPE_MODE(tType)!=TFmode &&
      (TREE_CODE(tType)!=VECTOR_TYPE || Bytes==16))
    return false;

  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. */
bool 
llvm_rs6000_should_pass_aggregate_in_mixed_regs(tree TreeType, const Type* Ty,
                                              std::vector<const Type*>&Elts) {
  // FIXME there are plenty of ppc64 cases that need this.
  if (TARGET_64BIT)
    return false;

  // If this is a small fixed size type, investigate it.
  HOST_WIDE_INT SrcSize = int_size_in_bytes(TreeType);
  if (SrcSize <= 0 || SrcSize > 16)
    return false;

  const StructType *STy = dyn_cast<StructType>(Ty);
  if (!STy) return false;

  // A struct containing only a float, double or Altivec field, possibly with
  // some zero-length fields as well, must be passed as the field type.
  // Note this does not apply to long double, nor generic vectors.
  // Other single-element structs may be passed this way as well, but
  // only if the type size matches the element's type size (structs that
  // violate this can be created with __aligned__).
  tree tType = isSingleElementStructOrArray(TreeType, true, false);
  if (tType && int_size_in_bytes(tType)==SrcSize && TYPE_MODE(tType)!=TFmode &&
      (TREE_CODE(tType)!=VECTOR_TYPE || SrcSize==16)) {
    Elts.push_back(ConvertType(tType));
    return true;
  }

  Elts.clear();
  return false;
}

/* Non-Altivec vectors are passed in integer regs. */
bool llvm_rs6000_should_pass_vector_in_integer_regs(tree type) {
  if (!TARGET_64BIT &&
    TREE_CODE(type) == VECTOR_TYPE &&
    TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
    TREE_INT_CST_LOW(TYPE_SIZE(type)) != 128)
    return true;
  return false;
}

/* (Generic) vectors 4 bytes long are returned as an int.
   Vectors 8 bytes long are returned as 2 ints. */
tree llvm_rs6000_should_return_vector_as_scalar(tree type, 
                                    bool isBuiltin ATTRIBUTE_UNUSED) {
  if (!TARGET_64BIT &&
      TREE_CODE(type) == VECTOR_TYPE &&
      TYPE_SIZE(type) &&
      TREE_CODE(TYPE_SIZE(type))==INTEGER_CST) {
    if (TREE_INT_CST_LOW(TYPE_SIZE(type))==32)
      return uint32_type_node;
    else if (TREE_INT_CST_LOW(TYPE_SIZE(type))==64)
      return uint64_type_node;
  }
  return 0;
}

/* Non-altivec vectors bigger than 8 bytes are returned by sret. */
bool llvm_rs6000_should_return_vector_as_shadow(tree type, 
                                      bool isBuiltin ATTRIBUTE_UNUSED) {
  if (!TARGET_64BIT &&
      TREE_CODE(type) == VECTOR_TYPE &&
      TYPE_SIZE(type) &&
      TREE_CODE(TYPE_SIZE(type))==INTEGER_CST &&
      TREE_INT_CST_LOW(TYPE_SIZE(type))>64 &&
      TREE_INT_CST_LOW(TYPE_SIZE(type))!=128)
    return true;
  return false;
}

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

