// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include 'src/builtins/builtins-bigint-gen.h'

namespace bigint {

const kPositiveSign: uint32 = 0;
const kNegativeSign: uint32 = 1;

extern macro BigIntBuiltinsAssembler::CppAbsoluteAddAndCanonicalize(
    MutableBigInt, BigIntBase, BigIntBase): void;
extern macro BigIntBuiltinsAssembler::CppAbsoluteSubAndCanonicalize(
    MutableBigInt, BigIntBase, BigIntBase): void;
extern macro BigIntBuiltinsAssembler::CppAbsoluteCompare(
    BigIntBase, BigIntBase): int32;

extern macro BigIntBuiltinsAssembler::ReadBigIntSign(BigIntBase): uint32;
extern macro BigIntBuiltinsAssembler::ReadBigIntLength(BigIntBase): intptr;
extern macro BigIntBuiltinsAssembler::WriteBigIntSignAndLength(
    MutableBigInt, uint32, intptr): void;

extern macro CodeStubAssembler::AllocateBigInt(intptr): MutableBigInt;
extern macro CodeStubAssembler::StoreBigIntDigit(
    MutableBigInt, intptr, uintptr): void;
extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr;

macro IsCanonicalized(bigint: BigIntBase): bool {
  const length = ReadBigIntLength(bigint);

  if (length == 0) {
    return ReadBigIntSign(bigint) == kPositiveSign;
  }

  return LoadBigIntDigit(bigint, length - 1) != 0;
}

macro InvertSign(sign: uint32): uint32 {
  return sign == kPositiveSign ? kNegativeSign : kPositiveSign;
}

macro AllocateEmptyBigIntNoThrow(implicit context: Context)(
    sign: uint32, length: intptr): MutableBigInt labels BigIntTooBig {
  if (length > kBigIntMaxLength) {
    goto BigIntTooBig;
  }
  const result: MutableBigInt = AllocateBigInt(length);

  WriteBigIntSignAndLength(result, sign, length);
  return result;
}

macro AllocateEmptyBigInt(implicit context: Context)(
    sign: uint32, length: intptr): MutableBigInt {
  try {
    return AllocateEmptyBigIntNoThrow(sign, length) otherwise BigIntTooBig;
  } label BigIntTooBig {
    ThrowRangeError(MessageTemplate::kBigIntTooBig);
  }
}

macro MutableBigIntAbsoluteCompare(x: BigIntBase, y: BigIntBase): int32 {
  return CppAbsoluteCompare(x, y);
}

macro MutableBigIntAbsoluteSub(implicit context: Context)(
    x: BigInt, y: BigInt, resultSign: uint32): BigInt {
  const xlength = ReadBigIntLength(x);
  const ylength = ReadBigIntLength(y);
  const xsign = ReadBigIntSign(x);

  assert(MutableBigIntAbsoluteCompare(x, y) >= 0);
  if (xlength == 0) {
    assert(ylength == 0);
    return x;
  }

  if (ylength == 0) {
    return resultSign == xsign ? x : BigIntUnaryMinus(x);
  }

  const result = AllocateEmptyBigInt(resultSign, xlength);
  CppAbsoluteSubAndCanonicalize(result, x, y);
  return Convert<BigInt>(result);
}

macro MutableBigIntAbsoluteAdd(implicit context: Context)(
    xBigint: BigInt, yBigint: BigInt,
    resultSign: uint32): BigInt labels BigIntTooBig {
  let xlength = ReadBigIntLength(xBigint);
  let ylength = ReadBigIntLength(yBigint);

  let x = xBigint;
  let y = yBigint;
  if (xlength < ylength) {
    // Swap x and y so that x is longer.
    x = yBigint;
    y = xBigint;
    const tempLength = xlength;
    xlength = ylength;
    ylength = tempLength;
  }

  // case: 0n + 0n
  if (xlength == 0) {
    assert(ylength == 0);
    return x;
  }

  // case: x + 0n
  if (ylength == 0) {
    return resultSign == ReadBigIntSign(x) ? x : BigIntUnaryMinus(x);
  }

  // case: x + y
  const result = AllocateEmptyBigIntNoThrow(resultSign, xlength + 1)
      otherwise BigIntTooBig;
  CppAbsoluteAddAndCanonicalize(result, x, y);
  return Convert<BigInt>(result);
}

macro BigIntAddImpl(implicit context: Context)(x: BigInt, y: BigInt): BigInt
    labels BigIntTooBig {
  const xsign = ReadBigIntSign(x);
  const ysign = ReadBigIntSign(y);
  if (xsign == ysign) {
    // x + y == x + y
    // -x + -y == -(x + y)
    return MutableBigIntAbsoluteAdd(x, y, xsign) otherwise BigIntTooBig;
  }

  // x + -y == x - y == -(y - x)
  // -x + y == y - x == -(x - y)
  if (MutableBigIntAbsoluteCompare(x, y) >= 0) {
    return MutableBigIntAbsoluteSub(x, y, xsign);
  }
  return MutableBigIntAbsoluteSub(y, x, InvertSign(xsign));
}

builtin BigIntAddNoThrow(implicit context: Context)(
    x: BigInt, y: BigInt): Numeric {
  try {
    return BigIntAddImpl(x, y) otherwise BigIntTooBig;
  } label BigIntTooBig {
    // Smi sentinal is used to signal BigIntTooBig exception.
    return Convert<Smi>(0);
  }
}

builtin BigIntAdd(implicit context: Context)(
    xNum: Numeric, yNum: Numeric): BigInt {
  try {
    const x = Cast<BigInt>(xNum) otherwise MixedTypes;
    const y = Cast<BigInt>(yNum) otherwise MixedTypes;

    return BigIntAddImpl(x, y) otherwise BigIntTooBig;
  } label MixedTypes {
    ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
  } label BigIntTooBig {
    ThrowRangeError(MessageTemplate::kBigIntTooBig);
  }
}

macro BigIntSubtractImpl(implicit context: Context)(
    x: BigInt, y: BigInt): BigInt labels BigIntTooBig {
  const xsign = ReadBigIntSign(x);
  const ysign = ReadBigIntSign(y);
  if (xsign != ysign) {
    // x - (-y) == x + y
    // (-x) - y == -(x + y)
    return MutableBigIntAbsoluteAdd(x, y, xsign) otherwise BigIntTooBig;
  }

  // x - y == -(y - x)
  // (-x) - (-y) == y - x == -(x - y)
  if (MutableBigIntAbsoluteCompare(x, y) >= 0) {
    return MutableBigIntAbsoluteSub(x, y, xsign);
  }
  return MutableBigIntAbsoluteSub(y, x, InvertSign(xsign));
}

builtin BigIntSubtractNoThrow(implicit context: Context)(
    x: BigInt, y: BigInt): Numeric {
  try {
    return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
  } label BigIntTooBig {
    // Smi sentinal is used to signal BigIntTooBig exception.
    return Convert<Smi>(0);
  }
}

builtin BigIntSubtract(implicit context: Context)(
    xNum: Numeric, yNum: Numeric): BigInt {
  try {
    const x = Cast<BigInt>(xNum) otherwise MixedTypes;
    const y = Cast<BigInt>(yNum) otherwise MixedTypes;

    return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
  } label MixedTypes {
    ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
  } label BigIntTooBig {
    ThrowRangeError(MessageTemplate::kBigIntTooBig);
  }
}

builtin BigIntUnaryMinus(implicit context: Context)(bigint: BigInt): BigInt {
  const length = ReadBigIntLength(bigint);

  // There is no -0n.
  if (length == 0) {
    return bigint;
  }

  const result =
      AllocateEmptyBigInt(InvertSign(ReadBigIntSign(bigint)), length);
  for (let i: intptr = 0; i < length; ++i) {
    StoreBigIntDigit(result, i, LoadBigIntDigit(bigint, i));
  }
  return Convert<BigInt>(result);
}

}  // namespace bigint
