Index: lib/builtins/CMakeLists.txt =================================================================== --- lib/builtins/CMakeLists.txt +++ lib/builtins/CMakeLists.txt @@ -247,10 +247,28 @@ arm/unordsf2vfp.S ${GENERIC_SOURCES}) +set(mips16_SOURCES + mips/mips16_cmpdf2.c + mips/mips16_cmpsf2.c + mips/mips16_extendsfdf2.c + mips/mips16_fix_truncdfsi.c + mips/mips16_fix_truncsfsi.c + mips/mips16_floatdf.c + mips/mips16_floatsf.c + mips/mips16_opdf3.c + mips/mips16_opsf3.c + mips/mips16_truncdfsf2.c) + +set(mips_SOURCES ${mips16_SOURCES} ${GENERIC_SOURCES}) + +set_source_files_properties(${mips16_SOURCES} + PROPERTIES + COMPILE_FLAGS "-Os") + add_custom_target(builtins) if (NOT WIN32) - foreach (arch x86_64 i386 arm) + foreach (arch x86_64 i386 arm mips) if (CAN_TARGET_${arch}) # Filter out generic versions of routines that are re-implemented in # architecture specific manner. This prevents multiple definitions of the Index: lib/builtins/mips/mips16_cmpdf2.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_cmpdf2.c @@ -0,0 +1,44 @@ +/* ===-- mips16_cmpdf2.c - mips16 wrappers for double comparison -----------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Wrappers for comparison of double precision values + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) + +#define DOUBLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENOP2(eqdf2, ==, 0, 1); + +GENOP2(nedf2, !=, 1, 0); + +GENOP2(gtdf2, >, 1, 0); + +GENOP2(gedf2, >=, 0, -1); + +GENOP2(ltdf2, <, -1, 0); + +GENOP2(ledf2, <=, 0, 1); + +GENUNORDOP2(unorddf2); + +#endif /* _MIPS16_COMPAT */ + +#endif /* __mips_single_float */ Index: lib/builtins/mips/mips16_cmpsf2.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_cmpsf2.c @@ -0,0 +1,40 @@ +/* ===-- mips16_cmpsf2.c - mips16 wrappers for float comparison ------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Wrappers for comparison of single precision values + * + * ===----------------------------------------------------------------------=== + */ + +#define SINGLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENOP2(eqsf2, ==, 0, 1); + +GENOP2(nesf2, !=, 1, 0); + +GENOP2(gtsf2, >, 1, 0); + +GENOP2(gesf2, >=, 0, -1); + +GENOP2(ltsf2, <, -1, 0); + +GENOP2(lesf2, <=, 0, 1); + +GENUNORDOP2(unordsf2); + +#endif /* _MIPS16_COMPAT */ Index: lib/builtins/mips/mips16_extendsfdf2.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_extendsfdf2.c @@ -0,0 +1,32 @@ +/* ===-- mips16_extenddfsf2.c - mips16 wrappers for double precision -------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Function to convert representations from single to double precision + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) + +#define DOUBLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENCVTFOP1(extendsfdf2, su_int, float, .u); + +#endif /* _MIPS16_COMPAT */ + +#endif /* __mips_single_float */ Index: lib/builtins/mips/mips16_fix_truncdfsi.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_fix_truncdfsi.c @@ -0,0 +1,33 @@ +/* ===-- mips16_fix_truncdfsi.c - wrapper __mips16_fix_truncdfsi -----------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Function to convert double precision to signed integer with truncation of + * fractional part + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) + +#define DOUBLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENFIXOP1(fix_truncdfsi, si_int); + +#endif /* _MIPS16_COMPAT */ + +#endif /* __mips_single_float */ Index: lib/builtins/mips/mips16_fix_truncsfsi.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_fix_truncsfsi.c @@ -0,0 +1,28 @@ +/* ===-- mips16_fix_truncsfsi.c - wrappers for __mips16_fix_truncsfsi ------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Function to convert from single-precision float to signed integer + * + * ===----------------------------------------------------------------------=== + */ + +#define SINGLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENFIXOP1(fix_truncsfsi, si_int); + +#endif /* _MIPS16_COMPAT */ Index: lib/builtins/mips/mips16_floatdf.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_floatdf.c @@ -0,0 +1,34 @@ +/* ===-- mips16_floatdf.c - wrappers for __mips16_float[un]sidf ----------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Functions to convert signed/unsigned integers to double precision + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) + +#define DOUBLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENCVTOP1(floatsidf, si_int); + +GENCVTOP1(floatunsidf, su_int); + +#endif /* _MIPS16_COMPAT */ + +#endif /* __mips_single_float */ Index: lib/builtins/mips/mips16_floatsf.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_floatsf.c @@ -0,0 +1,30 @@ +/* ===-- mips16_floatsf.c - wrappers for __mips16_float[un]sisf ------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Functions to convert signed/unsigned integers to single-precision float + * + * ===----------------------------------------------------------------------=== + */ + +#define SINGLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENCVTOP1(floatsisf,si_int); + +GENCVTOP1(floatunsisf,su_int); + +#endif /* _MIPS16_COMPAT */ Index: lib/builtins/mips/mips16_gen.h =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_gen.h @@ -0,0 +1,80 @@ +/* ===-- mips16_gen.h - macros to generate mips16 wrappers ----------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file is not part of the interface of this library. + * + * This file contains generator macros for soft-fp wrappers to make hardware + * floating point available to MIPS16 code by temporarily switching the + * instruction set. These wrappers accept arguments and produce results in + * GP registers, but may perform the underlying operation using floating point + * instructions and registers. + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_micromips) && __mips_isa_rev < 6 +#if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64) + +#define _MIPS16_COMPAT + +#include "../fp_lib.h" +#include "../int_types.h" + +#define GENOP3(name,op) \ + rep_t __mips16_##name(rep_t, rep_t) __attribute__((nomips16)); \ + rep_t __mips16_##name(rep_t op1, rep_t op2) \ + { \ + return toRep(fromRep(op1) op fromRep(op2)); \ + } + +#define GENOP2(name,op,ret1,ret2) \ + int __mips16_##name(rep_t, rep_t) __attribute__((nomips16)); \ + int __mips16_##name(rep_t op1, rep_t op2) \ + { \ + if (fromRep(op1) op fromRep(op2)) \ + return ret1; \ + else \ + return ret2; \ + } + +#define GENUNORDOP2(name) \ + int __mips16_##name(rep_t, rep_t) __attribute__((nomips16)); \ + int __mips16_##name(rep_t op1, rep_t op2) \ + { \ + fp_t op1fp = fromRep(op1), op2fp = fromRep(op2); \ + if (!(op1fp >= op2fp) && !(op1fp < op2fp)) \ + return 1; \ + else \ + return 0; \ + } + +#define GENCVTOP1(name,type) \ + rep_t __mips16_##name(type) __attribute__((nomips16)); \ + rep_t __mips16_##name(type op1) \ + { \ + return (toRep((fp_t)op1)); \ + } + +#define GENCVTFOP1(name,type1,type2,acc) \ + rep_t __mips16_##name(type1) __attribute__((nomips16)); \ + rep_t __mips16_##name(type1 op1) \ + { \ + const type2##_bits __tmp = {acc = op1}; \ + return (toRep((fp_t)__tmp.f)); \ + } + +#define GENFIXOP1(name,type) \ + type __mips16_##name(rep_t) __attribute__((nomips16)); \ + type __mips16_##name(rep_t op1) \ + { \ + return ((type)fromRep(op1)); \ + } + +#endif /* _MIPS_SIM */ +#endif /* micromips */ Index: lib/builtins/mips/mips16_opdf3.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_opdf3.c @@ -0,0 +1,38 @@ +/* ===-- mips16_opdf3.c - mips16 wrappers for double precision arithmetic --=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Functions for double precision arithmetic operations + * + * ===----------------------------------------------------------------------=== + */ + +#if !defined(__mips_single_float) && !defined(__SINGLE_FLOAT) + +#define DOUBLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENOP3(adddf3, +); + +GENOP3(subdf3, -); + +GENOP3(muldf3, *); + +GENOP3(divdf3, /); + +#endif /* _MIPS16_COMPAT */ + +#endif /* __mips_single_float */ Index: lib/builtins/mips/mips16_opsf3.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_opsf3.c @@ -0,0 +1,34 @@ +/* ===-- mips16_opsf3.c - mips16 wrappers for single precision arithmetic --=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Single-precision arithmetic operations: add, sub, mul, div + * + * ===----------------------------------------------------------------------=== + */ + +#define SINGLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENOP3(addsf3, +); + +GENOP3(subsf3, -); + +GENOP3(mulsf3, *); + +GENOP3(divsf3, /); + +#endif /* _MIPS16_COMPAT */ Index: lib/builtins/mips/mips16_truncdfsf2.c =================================================================== --- /dev/null +++ lib/builtins/mips/mips16_truncdfsf2.c @@ -0,0 +1,28 @@ +/* ===-- mips16_truncdfsf2.c - mips16 wrappers for double precision -------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===----------------------------------------------------------------------=== + * + * This file defines soft-fp wrappers to make hardware floating point + * available to MIPS16 code by temporarily switching the instruction + * set. These wrappers accept arguments and produce results in GP registers, + * but may perform the underlying operation using floating point instructions + * and registers. + * Function to convert representations double to single precision + * + * ===----------------------------------------------------------------------=== + */ + +#define SINGLE_PRECISION + +#include "mips16_gen.h" + +#if defined(_MIPS16_COMPAT) + +GENCVTFOP1(truncdfsf2, du_int, double, .u.all); + +#endif /* _MIPS16_COMPAT */