From 7ad2023c81e22bc2bf932007698154fe8856b438 Mon Sep 17 00:00:00 2001 From: Klaus Treichel Date: Fri, 6 Aug 2010 11:30:02 +0200 Subject: [PATCH] Add new trunc insn for rounding float values towards zero. --- ChangeLog | 14 ++++++++++++++ config/jit-opcodes.ops | 3 +++ dpas/dpas-builtin.c | 17 ++++++++++------- include/jit/jit-insn.h | 2 ++ jit/jit-insn.c | 18 ++++++++++++++++++ jit/jit-interp.c | 24 ++++++++++++++++++++++++ tests/math.pas | 9 +++++++++ 7 files changed, 80 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index d882184..55fac5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,9 +3,21 @@ * configure.ac: Add checks for the rint, round and trunc c library functions. + * config/jit-opcodes.ops: (ftrunc, dtrunc, nftrunc): Add opcode + definitions for the new trunc instruction. + + * dpas/dpas-builtin.c: Add new Trunc builtin. + + * include/jit/jit-insn.c (jit_insn_trunc): Add prototype. + * include/jit/jit-intrinsic.h (jit_float32_trunc, jit_float64_trunc, jit_nfloat_trunc): Add prototypes. + * jit/jit-insn.c (jit_insn_trunc): Add new float rounding function. + + * jit/jit-interp.c (_jit_run_function): Add support for the new + trunc opcodes. + * jit/jit-intrinsic.c: Nove float rounding intrinsics to one block and refine conmments. (jit_float32_rint): Use rintf or rint if available. @@ -20,6 +32,8 @@ * jit/jit-symbol.c: Add the new intrinsics jit_float32_trunc, jit_float64_trunc and jit_nfloat_trunc to the symbol table. + * tests/math.pas: Add tests for the new trunc insn. + 2010-08-04 Klaus Treichel * include/jit/Makefile.am: Don't include jit-arch.h in the diff --git a/config/jit-opcodes.ops b/config/jit-opcodes.ops index c156443..4cec16f 100644 --- a/config/jit-opcodes.ops +++ b/config/jit-opcodes.ops @@ -342,6 +342,7 @@ opcodes(JIT_OP_, "jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES]") op_def("fsqrt") { op_values(float32, float32) } op_def("ftan") { op_values(float32, float32) } op_def("ftanh") { op_values(float32, float32) } + op_def("ftrunc") { op_values(float32, float32) } op_def("dacos") { op_values(float64, float64) } op_def("dasin") { op_values(float64, float64) } op_def("datan") { op_values(float64, float64) } @@ -361,6 +362,7 @@ opcodes(JIT_OP_, "jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES]") op_def("dsqrt") { op_values(float64, float64) } op_def("dtan") { op_values(float64, float64) } op_def("dtanh") { op_values(float64, float64) } + op_def("dtrunc") { op_values(float64, float64) } op_def("nfacos") { op_values(nfloat, nfloat) } op_def("nfasin") { op_values(nfloat, nfloat) } op_def("nfatan") { op_values(nfloat, nfloat) } @@ -380,6 +382,7 @@ opcodes(JIT_OP_, "jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES]") op_def("nfsqrt") { op_values(nfloat, nfloat) } op_def("nftan") { op_values(nfloat, nfloat) } op_def("nftanh") { op_values(nfloat, nfloat) } + op_def("nftrunc") { op_values(nfloat, nfloat) } /* * Absolute, minimum, maximum, and sign. */ diff --git a/dpas/dpas-builtin.c b/dpas/dpas-builtin.c index e43414d..0a03c52 100644 --- a/dpas/dpas-builtin.c +++ b/dpas/dpas-builtin.c @@ -498,6 +498,7 @@ dpas_math_unary(sinh, jit_insn_sinh) dpas_math_unary(sqrt, jit_insn_sqrt) dpas_math_unary(tan, jit_insn_tan) dpas_math_unary(tanh, jit_insn_tanh) +dpas_math_unary(trunc, jit_insn_trunc) dpas_math_unary(abs, jit_insn_abs) dpas_math_binary(min, jit_insn_min) dpas_math_binary(max, jit_insn_max) @@ -535,13 +536,14 @@ dpas_math_test(finite, jit_insn_is_finite) #define DPAS_BUILTIN_SQRT 24 #define DPAS_BUILTIN_TAN 25 #define DPAS_BUILTIN_TANH 26 -#define DPAS_BUILTIN_ABS 27 -#define DPAS_BUILTIN_MIN 28 -#define DPAS_BUILTIN_MAX 29 -#define DPAS_BUILTIN_SIGN 30 -#define DPAS_BUILTIN_ISNAN 31 -#define DPAS_BUILTIN_ISINF 32 -#define DPAS_BUILTIN_FINITE 33 +#define DPAS_BUILTIN_TRUNC 27 +#define DPAS_BUILTIN_ABS 28 +#define DPAS_BUILTIN_MIN 29 +#define DPAS_BUILTIN_MAX 30 +#define DPAS_BUILTIN_SIGN 31 +#define DPAS_BUILTIN_ISNAN 32 +#define DPAS_BUILTIN_ISINF 33 +#define DPAS_BUILTIN_FINITE 34 /* * Table that defines the builtins. @@ -581,6 +583,7 @@ static dpas_builtin const builtins[] = { {"Sqrt", DPAS_BUILTIN_SQRT, dpas_sqrt, 1}, {"Tan", DPAS_BUILTIN_TAN, dpas_tan, 1}, {"Tanh", DPAS_BUILTIN_TANH, dpas_tanh, 1}, + {"Trunc", DPAS_BUILTIN_TRUNC, dpas_trunc, 1}, {"Abs", DPAS_BUILTIN_ABS, dpas_abs, 1}, {"Min", DPAS_BUILTIN_MIN, dpas_min, 2}, {"Max", DPAS_BUILTIN_MAX, dpas_max, 2}, diff --git a/include/jit/jit-insn.h b/include/jit/jit-insn.h index e2631eb..f342747 100644 --- a/include/jit/jit-insn.h +++ b/include/jit/jit-insn.h @@ -189,6 +189,8 @@ jit_value_t jit_insn_tan (jit_function_t func, jit_value_t value1) JIT_NOTHROW; jit_value_t jit_insn_tanh (jit_function_t func, jit_value_t value1) JIT_NOTHROW; +jit_value_t jit_insn_trunc + (jit_function_t func, jit_value_t value1) JIT_NOTHROW; jit_value_t jit_insn_is_nan (jit_function_t func, jit_value_t value1) JIT_NOTHROW; jit_value_t jit_insn_is_finite diff --git a/jit/jit-insn.c b/jit/jit-insn.c index b1dd2e2..5780d7b 100644 --- a/jit/jit-insn.c +++ b/jit/jit-insn.c @@ -3249,6 +3249,24 @@ jit_value_t jit_insn_tanh(jit_function_t func, jit_value_t value1) return apply_unary_arith(func, &tanh_descr, value1, 0, 1, 0); } +jit_value_t jit_insn_trunc(jit_function_t func, jit_value_t value1) +{ + static jit_opcode_descr const trunc_descr = { + 0, 0, 0, 0, + JIT_OP_FTRUNC, + JIT_OP_DTRUNC, + JIT_OP_NFTRUNC, + jit_no_intrinsic, + jit_no_intrinsic, + jit_no_intrinsic, + jit_no_intrinsic, + jit_intrinsic(jit_float32_trunc, descr_f_f), + jit_intrinsic(jit_float64_trunc, descr_d_d), + jit_intrinsic(jit_nfloat_trunc, descr_D_D) + }; + return apply_unary_arith(func, &trunc_descr, value1, 0, 1, 0); +} + /*@ * @deftypefun jit_value_t jit_insn_is_nan (jit_function_t @var{func}, jit_value_t @var{value1}) * @deftypefunx jit_value_t jit_insn_is_finite (jit_function_t @var{func}, jit_value_t @var{value1}) diff --git a/jit/jit-interp.c b/jit/jit-interp.c index 16f5267..bf484e4 100644 --- a/jit/jit-interp.c +++ b/jit/jit-interp.c @@ -2786,6 +2786,14 @@ restart_tail: } VMBREAK; + VMCASE(JIT_OP_FTRUNC): + { + /* Compute 32-bit float "trunc" */ + VM_R0_FLOAT32 = jit_float32_trunc(VM_R1_FLOAT32); + VM_MODIFY_PC(1); + } + VMBREAK; + VMCASE(JIT_OP_DACOS): { /* Compute 64-bit float "acos" */ @@ -2938,6 +2946,14 @@ restart_tail: } VMBREAK; + VMCASE(JIT_OP_DTRUNC): + { + /* Compute 64-bit float "trunc" */ + VM_R0_FLOAT64 = jit_float64_trunc(VM_R1_FLOAT64); + VM_MODIFY_PC(1); + } + VMBREAK; + VMCASE(JIT_OP_NFACOS): { /* Compute native float "acos" */ @@ -3090,6 +3106,14 @@ restart_tail: } VMBREAK; + VMCASE(JIT_OP_NFTRUNC): + { + /* Compute native float "trunc" */ + VM_R0_NFLOAT = jit_nfloat_trunc(VM_R1_NFLOAT); + VM_MODIFY_PC(1); + } + VMBREAK; + /****************************************************************** * Absolute, minimum, maximum, and sign. ******************************************************************/ diff --git a/tests/math.pas b/tests/math.pas index 135e810..8f4fcee 100644 --- a/tests/math.pas +++ b/tests/math.pas @@ -300,6 +300,9 @@ begin runf("math_f_rint_2.5", Rint(ShortReal(2.5)), ShortReal(2.0), 0.00001); runf("math_f_round_1.5", Round(ShortReal(1.5)), ShortReal(2.0), 0.00001); runf("math_f_round_2.5", Round(ShortReal(2.5)), ShortReal(3.0), 0.00001); + runf("math_f_trunc_1.5", Trunc(ShortReal(1.5)), ShortReal(1.0), 0.00001); + runf("math_f_trunc_2.5", Trunc(ShortReal(2.5)), ShortReal(2.0), 0.00001); + runf("math_f_trunc_m1.5", Trunc(ShortReal(-1.5)), ShortReal(-1.0), 0.00001); { real versions } rund("math_d_abs_1.5", Abs(Real(1.5)), Real(1.5), 0.00001); @@ -325,6 +328,9 @@ begin rund("math_d_rint_2.5", Rint(Real(2.5)), Real(2.0), 0.00001); rund("math_d_round_1.5", Round(Real(1.5)), Real(2.0), 0.00001); rund("math_d_round_2.5", Round(Real(2.5)), Real(3.0), 0.00001); + rund("math_d_trunc_1.5", Trunc(Real(1.5)), Real(1.0), 0.00001); + rund("math_d_trunc_2.5", Trunc(Real(2.5)), Real(2.0), 0.00001); + rund("math_d_trunc_m1.5", Trunc(Real(-1.5)), Real(-1.0), 0.00001); { long real versions } runn("math_n_abs_1.5", Abs(LongReal(1.5)), LongReal(1.5), 0.00001); @@ -350,6 +356,9 @@ begin runn("math_n_rint_2.5", Rint(LongReal(2.5)), LongReal(2.0), 0.00001); runn("math_n_round_1.5", Round(LongReal(1.5)), LongReal(2.0), 0.00001); runn("math_n_round_2.5", Round(LongReal(2.5)), LongReal(3.0), 0.00001); + runn("math_n_trunc_1.5", Trunc(LongReal(1.5)), LongReal(1.0), 0.00001); + runn("math_n_trunc_2.5", Trunc(LongReal(2.5)), LongReal(2.0), 0.00001); + runn("math_n_trunc_m1.5", Trunc(LongReal(-1.5)), LongReal(-1.0), 0.00001); end; -- 2.47.3