//===--- SwiftTargetInfo.cpp ----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the SwiftTargetInfo abstract base class. This class
// provides an interface to target-dependent attributes of interest to Swift.
//
//===----------------------------------------------------------------------===//

#include "SwiftTargetInfo.h"
#include "IRGenModule.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
#include "swift/ABI/System.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/Basic/Platform.h"

using namespace swift;
using namespace irgen;

/// Initialize a bit vector to be equal to the given bit-mask.
static void setToMask(SpareBitVector &bits, unsigned size, uint64_t mask) {
  bits.clear();
  bits.add(size, mask);
}

/// Configures target-specific information for arm64 platforms.
static void configureARM64(IRGenModule &IGM, const llvm::Triple &triple,
                           SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 64,
            SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK);
  setToMask(target.ObjCPointerReservedBits, 64,
            SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK);
  setToMask(target.IsObjCPointerBit, 64, SWIFT_ABI_ARM64_IS_OBJC_BIT);

  if (triple.isOSDarwin()) {
    target.LeastValidPointerValue =
      SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER;
  }

  // arm64 has no special objc_msgSend variants, not even stret.
  target.ObjCUseStret = false;

  // arm64 requires marker assembly for objc_retainAutoreleasedReturnValue.
  target.ObjCRetainAutoreleasedReturnValueMarker =
    "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";

  // arm64 requires ISA-masking.
  target.ObjCUseISAMask = true;

  // arm64 tops out at 56 effective bits of address space and reserves the high
  // half for the kernel.
  target.SwiftRetainIgnoresNegativeValues = true;
}

/// Configures target-specific information for x86-64 platforms.
static void configureX86_64(IRGenModule &IGM, const llvm::Triple &triple,
                            SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 64,
            SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK);
  setToMask(target.IsObjCPointerBit, 64, SWIFT_ABI_X86_64_IS_OBJC_BIT);

  if (tripleIsAnySimulator(triple)) {
    setToMask(target.ObjCPointerReservedBits, 64,
              SWIFT_ABI_X86_64_SIMULATOR_OBJC_RESERVED_BITS_MASK);
  } else {
    setToMask(target.ObjCPointerReservedBits, 64,
              SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK);
  }

  if (triple.isOSDarwin()) {
    target.LeastValidPointerValue =
      SWIFT_ABI_DARWIN_X86_64_LEAST_VALID_POINTER;
  }

  // x86-64 has every objc_msgSend variant known to humankind.
  target.ObjCUseFPRet = true;
  target.ObjCUseFP2Ret = true;

  // x86-64 requires ISA-masking.
  target.ObjCUseISAMask = true;
  
  // x86-64 only has 48 effective bits of address space and reserves the high
  // half for the kernel.
  target.SwiftRetainIgnoresNegativeValues = true;
}

/// Configures target-specific information for 32-bit x86 platforms.
static void configureX86(IRGenModule &IGM, const llvm::Triple &triple,
                         SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 32,
            SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK);

  // x86 uses objc_msgSend_fpret but not objc_msgSend_fp2ret.
  target.ObjCUseFPRet = true;
  setToMask(target.IsObjCPointerBit, 32, SWIFT_ABI_I386_IS_OBJC_BIT);
}

/// Configures target-specific information for 32-bit arm platforms.
static void configureARM(IRGenModule &IGM, const llvm::Triple &triple,
                         SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 32,
            SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK);

  // ARM requires marker assembly for objc_retainAutoreleasedReturnValue.
  target.ObjCRetainAutoreleasedReturnValueMarker =
    "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";

  // armv7k has opaque ISAs which must go through the ObjC runtime.
  if (triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v7k)
    target.ObjCHasOpaqueISAs = true;

  setToMask(target.IsObjCPointerBit, 32, SWIFT_ABI_ARM_IS_OBJC_BIT);
}

/// Configures target-specific information for powerpc64 platforms.
static void configurePowerPC64(IRGenModule &IGM, const llvm::Triple &triple,
                               SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 64,
            SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK);
}

/// Configures target-specific information for SystemZ platforms.
static void configureSystemZ(IRGenModule &IGM, const llvm::Triple &triple,
                             SwiftTargetInfo &target) {
  setToMask(target.PointerSpareBits, 64,
            SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK);
}

/// Configure a default target.
SwiftTargetInfo::SwiftTargetInfo(
  llvm::Triple::ObjectFormatType outputObjectFormat,
  unsigned numPointerBits)
  : OutputObjectFormat(outputObjectFormat),
    HeapObjectAlignment(numPointerBits / 8),
    LeastValidPointerValue(SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER)
{
  setToMask(PointerSpareBits, numPointerBits,
            SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK);
  setToMask(ObjCPointerReservedBits, numPointerBits,
            SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK);
  setToMask(FunctionPointerSpareBits, numPointerBits,
            SWIFT_ABI_DEFAULT_FUNCTION_SPARE_BITS_MASK);
}

SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) {
  const llvm::Triple &triple = IGM.Context.LangOpts.Target;
  auto pointerSize = IGM.DataLayout.getPointerSizeInBits();

  // Prepare generic target information.
  SwiftTargetInfo target(triple.getObjectFormat(), pointerSize);
  
  // On Apple platforms, we implement "once" using dispatch_once,
  // which exposes a barrier-free inline path with -1 as the "done" value.
  if (triple.isOSDarwin())
    target.OnceDonePredicateValue = -1L;
  // Other platforms use std::call_once() and we don't
  // assume that they have a barrier-free inline fast path.
  
  switch (triple.getArch()) {
  case llvm::Triple::x86_64:
    configureX86_64(IGM, triple, target);
    break;

  case llvm::Triple::x86:
    configureX86(IGM, triple, target);
    break;

  case llvm::Triple::arm:
  case llvm::Triple::thumb:
    configureARM(IGM, triple, target);
    break;

  case llvm::Triple::aarch64:
    configureARM64(IGM, triple, target);
    break;

  case llvm::Triple::ppc64:
  case llvm::Triple::ppc64le:
    configurePowerPC64(IGM, triple, target);
    break;

  case llvm::Triple::systemz:
    configureSystemZ(IGM, triple, target);
    break;

  default:
    // FIXME: Complain here? Default target info is unlikely to be correct.
    break;
  }

  return target;
}

bool SwiftTargetInfo::hasObjCTaggedPointers() const {
  return ObjCPointerReservedBits.any();
}
