diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-01-18 14:44:48 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2019-03-06 18:11:31 +0000 |
commit | 0841c79a3dc1cfa382164a6bb2c1ee41af3ab0a9 (patch) | |
tree | 91f447c2bbfe0f87c46e7a42205ca8d63ca86ec8 | |
parent | 4a270568d93263e4970099456b4efb58466134a6 (diff) | |
download | gdb-0841c79a3dc1cfa382164a6bb2c1ee41af3ab0a9.zip gdb-0841c79a3dc1cfa382164a6bb2c1ee41af3ab0a9.tar.gz gdb-0841c79a3dc1cfa382164a6bb2c1ee41af3ab0a9.tar.bz2 |
gdb/fortran: Add support for the ABS intrinsic function
Adds support for the abs intrinsic function, this requires adding a
new pattern to the Fortran parser. Currently only float and integer
argument types are supported to ABS, complex is still not supported,
this can be added later if needed.
gdb/ChangeLog:
* f-exp.y: New token, UNOP_INTRINSIC.
(exp): New pattern using UNOP_INTRINSIC token.
(f77_keywords): Add 'abs' keyword.
* f-lang.c: Add 'target-float.h' and 'math.h' includes.
(value_from_host_double): New function.
(evaluate_subexp_f): Support UNOP_ABS.
gdb/testsuite/ChangeLog:
* gdb.fortran/intrinsics.exp: Extend to cover ABS.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/f-exp.y | 8 | ||||
-rw-r--r-- | gdb/f-lang.c | 39 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.fortran/intrinsics.exp | 9 |
5 files changed, 70 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e1fdda0..1dbec5a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,4 +1,15 @@ 2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com> + Chris January <chris.january@arm.com> + David Lecomber <david.lecomber@arm.com> + + * f-exp.y: New token, UNOP_INTRINSIC. + (exp): New pattern using UNOP_INTRINSIC token. + (f77_keywords): Add 'abs' keyword. + * f-lang.c: Add 'target-float.h' and 'math.h' includes. + (value_from_host_double): New function. + (evaluate_subexp_f): Support UNOP_ABS. + +2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com> * f-lang.c (build_fortran_types): Use TYPE_CODE_CHAR for character types. diff --git a/gdb/f-exp.y b/gdb/f-exp.y index d256ff1..88c685a 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -168,6 +168,7 @@ static int parse_number (struct parser_state *, const char *, int, %token <voidval> DOLLAR_VARIABLE %token <opcode> ASSIGN_MODIFY +%token <opcode> UNOP_INTRINSIC %left ',' %left ABOVE_COMMA @@ -252,6 +253,10 @@ exp : exp '(' OP_F77_UNDETERMINED_ARGLIST); } ; +exp : UNOP_INTRINSIC '(' exp ')' + { write_exp_elt_opcode (pstate, $1); } + ; + arglist : ; @@ -945,7 +950,8 @@ static const struct token f77_keywords[] = { "real", REAL_KEYWORD, BINOP_END, true }, /* The following correspond to actual functions in Fortran and are case insensitive. */ - { "kind", KIND, BINOP_END, false } + { "kind", KIND, BINOP_END, false }, + { "abs", UNOP_INTRINSIC, UNOP_ABS, false } }; /* Implementation of a dynamically expandable buffer for processing input diff --git a/gdb/f-lang.c b/gdb/f-lang.c index c329d60..24f0e61 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -34,7 +34,9 @@ #include "cp-support.h" #include "charset.h" #include "c-lang.h" +#include "target-float.h" +#include <math.h> /* Local functions */ @@ -239,6 +241,20 @@ f_collect_symbol_completion_matches (completion_tracker &tracker, text, word, ":", code); } +/* Create and return a value object of TYPE containing the value D. The + TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once + it is converted to target format. */ + +static struct value * +value_from_host_double (struct type *type, double d) +{ + struct value *value = allocate_value (type); + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT); + target_float_from_host_double (value_contents_raw (value), + value_type (value), d); + return value; +} + /* Special expression evaluation cases for Fortran. */ struct value * evaluate_subexp_f (struct type *expect_type, struct expression *exp, @@ -259,6 +275,29 @@ evaluate_subexp_f (struct type *expect_type, struct expression *exp, *pos -= 1; return evaluate_subexp_standard (expect_type, exp, pos, noside); + case UNOP_ABS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FLT: + { + double d + = fabs (target_float_to_host_double (value_contents (arg1), + value_type (arg1))); + return value_from_host_double (type, d); + } + case TYPE_CODE_INT: + { + LONGEST l = value_as_long (arg1); + l = llabs (l); + return value_from_longest (type, l); + } + } + error (_("ABS of type %s not supported"), TYPE_SAFE_NAME (type)); + case UNOP_KIND: arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); type = value_type (arg1); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 87c491f..7f70b48 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.fortran/intrinsics.exp: Extend to cover ABS. + +2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.fortran/type-kinds.exp: Update expected results. 2019-03-06 Andrew Burgess <andrew.burgess@embecosm.com> diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp index 674f299..00396c7 100644 --- a/gdb/testsuite/gdb.fortran/intrinsics.exp +++ b/gdb/testsuite/gdb.fortran/intrinsics.exp @@ -40,3 +40,12 @@ gdb_test "p kind (l2)" " = 2" gdb_test "p kind (l4)" " = 4" gdb_test "p kind (l8)" " = 8" gdb_test "p kind (s1)" "argument to kind must be an intrinsic type" + +# Test ABS + +gdb_test "p abs (-11)" " = 11" +gdb_test "p abs (11)" " = 11" +# Use `$decimal` to match here as we depend on host floating point +# rounding, which can vary. +gdb_test "p abs (-9.1)" " = 9.$decimal" +gdb_test "p abs (9.1)" " = 9.$decimal" |