// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2015, Linaro Limited
 */

#include <compiler.h>
#include "platform.h"
#include <softfloat.h>

/*
 * On ARM32 EABI defines both a soft-float ABI and a hard-float ABI,
 * hard-float is basically a super set of soft-float. Hard-float requires
 * all the support routines provided for soft-float, but the compiler may
 * choose to optimize to not use some of them.
 *
 * The AEABI functions uses soft-float calling convention even if the
 * functions are compiled for hard-float. So where float and double would
 * have been expected we use aeabi_float_t and aeabi_double_t respectively
 * instead.
 */
typedef unsigned aeabi_float_t;
typedef unsigned long long aeabi_double_t;

/*
 * Helpers to convert between float32 and aeabi_float_t, and float64 and
 * aeabi_double_t used by the AEABI functions below.
 */
static aeabi_float_t f32_to_f(float32_t val)
{
	union {
		float32_t from;
		aeabi_float_t to;
	} res = { .from = val };

	return res.to;
}

static float32_t f32_from_f(aeabi_float_t val)
{
	union {
		aeabi_float_t from;
		float32_t to;
	} res = { .from = val };

	return res.to;
}

static aeabi_double_t f64_to_d(float64_t val)
{
	union {
		float64_t from;
		aeabi_double_t to;
	} res = { .from = val };

	return res.to;
}

static float64_t f64_from_d(aeabi_double_t val)
{
	union {
		aeabi_double_t from;
		float64_t to;
	} res = { .from = val };

	return res.to;
}

/*
 * From ARM Run-time ABI for ARM Architecture
 * ARM IHI 0043D, current through ABI release 2.09
 *
 * 4.1.2 The floating-point helper functions
 */

/*
 * Table 2, Standard aeabi_double_t precision floating-point arithmetic helper
 * functions
 */

aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
{
	return f64_to_d(f64_add(f64_from_d(a), f64_from_d(b)));
}

aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
{
	return f64_to_d(f64_div(f64_from_d(a), f64_from_d(b)));
}

aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
{
	return f64_to_d(f64_mul(f64_from_d(a), f64_from_d(b)));
}


aeabi_double_t __aeabi_drsub(aeabi_double_t a, aeabi_double_t b)
{
	return f64_to_d(f64_sub(f64_from_d(b), f64_from_d(a)));
}

aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
{
	return f64_to_d(f64_sub(f64_from_d(a), f64_from_d(b)));
}

/*
 * Table 3, double precision floating-point comparison helper functions
 */

int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
{
	return f64_eq(f64_from_d(a), f64_from_d(b));
}

int __aeabi_dcmplt(aeabi_double_t a, aeabi_double_t b)
{
	return f64_lt(f64_from_d(a), f64_from_d(b));
}

int __aeabi_dcmple(aeabi_double_t a, aeabi_double_t b)
{
	return f64_le(f64_from_d(a), f64_from_d(b));
}

int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
{
	return f64_le(f64_from_d(b), f64_from_d(a));
}

int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
{
	return f64_lt(f64_from_d(b), f64_from_d(a));
}

/*
 * Table 4, Standard single precision floating-point arithmetic helper
 * functions
 */

aeabi_float_t __aeabi_fadd(aeabi_float_t a, aeabi_float_t b)
{
	return f32_to_f(f32_add(f32_from_f(a), f32_from_f(b)));
}

aeabi_float_t __aeabi_fdiv(aeabi_float_t a, aeabi_float_t b)
{
	return f32_to_f(f32_div(f32_from_f(a), f32_from_f(b)));
}

aeabi_float_t __aeabi_fmul(aeabi_float_t a, aeabi_float_t b)
{
	return f32_to_f(f32_mul(f32_from_f(a), f32_from_f(b)));
}

aeabi_float_t __aeabi_frsub(aeabi_float_t a, aeabi_float_t b)
{
	return f32_to_f(f32_sub(f32_from_f(b), f32_from_f(a)));
}

aeabi_float_t __aeabi_fsub(aeabi_float_t a, aeabi_float_t b)
{
	return f32_to_f(f32_sub(f32_from_f(a), f32_from_f(b)));
}

/*
 * Table 5, Standard single precision floating-point comparison helper
 * functions
 */

int __aeabi_fcmpeq(aeabi_float_t a, aeabi_float_t b)
{
	return f32_eq(f32_from_f(a), f32_from_f(b));
}

int __aeabi_fcmplt(aeabi_float_t a, aeabi_float_t b)
{
	return f32_lt(f32_from_f(a), f32_from_f(b));
}

int __aeabi_fcmple(aeabi_float_t a, aeabi_float_t b)
{
	return f32_le(f32_from_f(a), f32_from_f(b));
}

int __aeabi_fcmpge(aeabi_float_t a, aeabi_float_t b)
{
	return f32_le(f32_from_f(b), f32_from_f(a));
}

int __aeabi_fcmpgt(aeabi_float_t a, aeabi_float_t b)
{
	return f32_lt(f32_from_f(b), f32_from_f(a));
}

/*
 * Table 6, Standard floating-point to integer conversions
 */

int __aeabi_d2iz(aeabi_double_t a)
{
	return f64_to_i32_r_minMag(f64_from_d(a), false);
}

unsigned __aeabi_d2uiz(aeabi_double_t a)
{
	return f64_to_ui32_r_minMag(f64_from_d(a), false);
}

long long __aeabi_d2lz(aeabi_double_t a)
{
	return f64_to_i64_r_minMag(f64_from_d(a), false);
}

unsigned long long __aeabi_d2ulz(aeabi_double_t a)
{
	return f64_to_ui64_r_minMag(f64_from_d(a), false);
}

int __aeabi_f2iz(aeabi_float_t a)
{
	return f32_to_i32_r_minMag(f32_from_f(a), false);
}

unsigned __aeabi_f2uiz(aeabi_float_t a)
{
	return f32_to_ui32_r_minMag(f32_from_f(a), false);
}

long long __aeabi_f2lz(aeabi_float_t a)
{
	return f32_to_i64_r_minMag(f32_from_f(a), false);
}

unsigned long long __aeabi_f2ulz(aeabi_float_t a)
{
	return f32_to_ui64_r_minMag(f32_from_f(a), false);
}

/*
 * Table 7, Standard conversions between floating types
 */

aeabi_float_t __aeabi_d2f(aeabi_double_t a)
{
	return f32_to_f(f64_to_f32(f64_from_d(a)));
}

aeabi_double_t __aeabi_f2d(aeabi_float_t a)
{
	return f64_to_d(f32_to_f64(f32_from_f(a)));
}

/*
 * Table 8, Standard integer to floating-point conversions
 */

aeabi_double_t __aeabi_i2d(int a)
{
	return f64_to_d(i32_to_f64(a));
}

aeabi_double_t __aeabi_ui2d(unsigned a)
{
	return f64_to_d(ui32_to_f64(a));
}

aeabi_double_t __aeabi_l2d(long long a)
{
	return f64_to_d(i64_to_f64(a));
}

aeabi_double_t __aeabi_ul2d(unsigned long long a)
{
	return f64_to_d(ui64_to_f64(a));
}

aeabi_float_t __aeabi_i2f(int a)
{
	return f32_to_f(i32_to_f32(a));
}

aeabi_float_t __aeabi_ui2f(unsigned a)
{
	return f32_to_f(ui32_to_f32(a));
}

aeabi_float_t __aeabi_l2f(long long a)
{
	return f32_to_f(i64_to_f32(a));
}

aeabi_float_t __aeabi_ul2f(unsigned long long a)
{
	return f32_to_f(ui64_to_f32(a));
}
