Add support for fixed-point type comparison operators
authorJoel Brobecker <brobecker@adacore.com>
Sun, 15 Nov 2020 08:18:35 +0000 (03:18 -0500)
committerJoel Brobecker <brobecker@adacore.com>
Sun, 15 Nov 2020 08:18:35 +0000 (03:18 -0500)
This patch adds support for binary comparison operators with
fixed-point type values.

gdb/ChangeLog:

        * valarith.c (fixed_point_binop): Add BINOP_EQUAL and BINOP_LESS
        handling.
        (value_less): Add fixed-point handling.

gdb/testsuite/ChangeLog:

        * gdb.ada/fixed_cmp.exp: Add -fgnat-encodings=minimal testing.
        * gdb.dwarf2/dw2-fixed-point.c (pck__fp1_var2): New global.
        (main): Add reference to pck__fp1_var2.
        * gdb.dwarf2/dw2-fixed-point.exp: Add comparison operator testing.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/fixed_cmp.exp
gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c
gdb/testsuite/gdb.dwarf2/dw2-fixed-point.exp
gdb/valarith.c

index e9f0afd9192bd16b865dbcd815ab65bcb142bdd2..6d0a0c649100434a7dfdeb8aff61ecbbf2459921 100644 (file)
@@ -1,3 +1,9 @@
+2020-11-15  Joel Brobecker  <brobecker@adacore.com>
+
+       * valarith.c (fixed_point_binop): Add BINOP_EQUAL and BINOP_LESS
+       handling.
+       (value_less): Add fixed-point handling.
+
 2020-11-15  Joel Brobecker  <brobecker@adacore.com>
 
        * eval.c (binop_promote): Add fixed-point type handling.
index 3c53f6c666a406c8c0543f9dd5ce9ae48ded62b8..6ecb04cf0ad18f090d11d8e6546a27220d93dd01 100644 (file)
@@ -1,3 +1,10 @@
+2020-11-15  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdb.ada/fixed_cmp.exp: Add -fgnat-encodings=minimal testing.
+       * gdb.dwarf2/dw2-fixed-point.c (pck__fp1_var2): New global.
+       (main): Add reference to pck__fp1_var2.
+       * gdb.dwarf2/dw2-fixed-point.exp: Add comparison operator testing.
+
 2020-11-15  Joel Brobecker  <brobecker@adacore.com>
 
        * gdb.dwarf2/dw2-fixed-point.exp: Add arithmetic tests.
index cfdbb1cfd1eb05b4f21c208875bc5c94499bdb19..e2c88b8c902d913c782d1d85ef4acc2a6973b281 100644 (file)
@@ -19,7 +19,7 @@ if { [skip_ada_tests] } { return -1 }
 
 standard_ada_testfile fixed
 
-foreach_with_prefix gnat_encodings {all} {
+foreach_with_prefix gnat_encodings {all minimal} {
     set flags [list debug additional_flags=-fgnat-encodings=$gnat_encodings]
 
     if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $flags] != "" } {
index d9c811c08837af73e35a97a6ca441c4325101fa8..971a7a89b9de870de2f715449d7b5ffc81442a8c 100644 (file)
       FP1_Var : FP1_Type := 0.25;  */
 int8_t pck__fp1_var = 4;
 
+/* Simulate an Ada variable declared inside package Pck as follow:
+      type FP1_Type is delta 0.1 range -1.0 .. +1.0;
+      FP1_Var2 : FP1_Type := 0.50;
+   Basically, the same as FP1_Var, but with a different value.  */
+int8_t pck__fp1_var2 = 8;
+
 /* Simulate an Ada variable declared inside package Pck as follow:
       type FP2_Type is delta 0.01 digits 14;
       FP2_Var : FP2_Type := -0.01;  */
@@ -41,6 +47,7 @@ int
 main (void)
 {
   pck__fp1_var++;
+  pck__fp1_var2++;
   pck__fp2_var++;
   pck__fp3_var++;
   pck__fp1_range_var++;
index 0252195e1d4806a63bc70f5b09f924c45baab023..a82a9af32392d2c8e877e1e8580fe727f1155c05 100644 (file)
@@ -49,6 +49,15 @@ Dwarf::assemble $asm_file {
                 {external 1 flag}
             }
 
+            DW_TAG_variable {
+                {DW_AT_name pck__fp1_var2}
+                {DW_AT_type :$fp1_base_type}
+                {DW_AT_location {
+                    DW_OP_addr [gdb_target_symbol pck__fp1_var2]
+                } SPECIAL_expr}
+                {external 1 flag}
+            }
+
             fp2_base_type: DW_TAG_base_type {
                 {DW_AT_byte_size     1 DW_FORM_sdata}
                 {DW_AT_encoding      @DW_ATE_signed_fixed}
@@ -161,6 +170,99 @@ gdb_test "print pck.fp1_range_var - 0.5" \
 gdb_test "print -pck.fp1_var" \
          " = -0.25"
 
+gdb_test "print pck.fp1_var = pck.fp1_var" \
+         " = true"
+
+gdb_test "print pck.fp1_var = pck.fp1_var2" \
+         " = false"
+
+gdb_test "print pck.fp1_var /= pck.fp1_var" \
+         " = false"
+
+gdb_test "print pck.fp1_var /= pck.fp1_var2" \
+         " = true"
+
+gdb_test "print pck.fp1_var < pck.fp1_var" \
+         " = false"
+
+gdb_test "print pck.fp1_var < pck.fp1_var2" \
+         " = true"
+
+gdb_test "print pck.fp1_var <= pck.fp1_var2" \
+         " = true"
+
+gdb_test "print pck.fp1_var <= pck.fp1_var" \
+         " = true"
+
+gdb_test "print pck.fp1_var > pck.fp1_var2" \
+         " = false"
+
+gdb_test "print pck.fp1_var2 > pck.fp1_var" \
+         " = true"
+
+gdb_test "print pck.fp1_var >= pck.fp1_var" \
+         " = true"
+
+gdb_test "print pck.fp1_var >= pck.fp1_var2" \
+         " = false"
+
+# Same as above, but with litterals...
+
+gdb_test "print pck.fp1_var = 0.25" \
+         " = true"
+
+gdb_test "print pck.fp1_var = 0.5" \
+         " = false"
+
+gdb_test "print pck.fp1_var = 1" \
+         " = false"
+
+gdb_test "print pck.fp1_var /= 0.25" \
+         " = false"
+
+gdb_test "print pck.fp1_var /= 0.5" \
+         " = true"
+
+gdb_test "print pck.fp1_var /= 1" \
+         " = true"
+
+gdb_test "print pck.fp1_var < 0.25" \
+         " = false"
+
+gdb_test "print pck.fp1_var <  0.5" \
+         " = true"
+
+gdb_test "print pck.fp1_var <  1" \
+         " = true"
+
+gdb_test "print pck.fp1_var <= 0.25" \
+         " = true"
+
+gdb_test "print pck.fp1_var <= 0.5" \
+         " = true"
+
+gdb_test "print pck.fp1_var <= 1" \
+         " = true"
+
+gdb_test "print pck.fp1_var > 0.25" \
+         " = false"
+
+gdb_test "print pck.fp1_var > 0.5" \
+         " = false"
+
+gdb_test "print pck.fp1_var > 1" \
+         " = false"
+
+gdb_test "print pck.fp1_var >= 0.25" \
+         " = true"
+
+gdb_test "print pck.fp1_var >= 0.5" \
+         " = false"
+
+gdb_test "print pck.fp1_var >= 1" \
+         " = false"
+
+
 # Set the language to LANG and do a ptype test on pck__fp1_var,
 # pck__fp2_var and pck__fp3_var, verifying that the output matches
 # FP1_RE, FP2_RE, FP2_RE (resp.).
index 65a6f13db5e18718ae8b68a404b0622321a4cb6a..f4497cd223f42ced6b0556d1d7517136cf67bda2 100644 (file)
@@ -890,7 +890,9 @@ fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 {
   struct type *type1 = check_typedef (value_type (arg1));
   struct type *type2 = check_typedef (value_type (arg2));
+  const struct language_defn *language = current_language;
 
+  struct gdbarch *gdbarch = get_type_arch (type1);
   struct value *val;
 
   gdb_assert (is_fixed_point_type (type1) || is_fixed_point_type (type2));
@@ -952,6 +954,16 @@ fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
       INIT_VAL_WITH_FIXED_POINT_VAL (res);
       break;
 
+    case BINOP_EQUAL:
+      val = value_from_ulongest (language_bool_type (language, gdbarch),
+                                mpq_cmp (v1.val, v2.val) == 0 ? 1 : 0);
+      break;
+
+    case BINOP_LESS:
+      val = value_from_ulongest (language_bool_type (language, gdbarch),
+                                mpq_cmp (v1.val, v2.val) < 0 ? 1 : 0);
+      break;
+
     default:
       error (_("Integer-only operation on fixed point number."));
     }
@@ -1774,7 +1786,8 @@ value_less (struct value *arg1, struct value *arg2)
   is_int1 = is_integral_type (type1);
   is_int2 = is_integral_type (type2);
 
-  if (is_int1 && is_int2)
+  if ((is_int1 && is_int2)
+      || (is_fixed_point_type (type1) && is_fixed_point_type (type2)))
     return longest_to_int (value_as_long (value_binop (arg1, arg2,
                                                       BINOP_LESS)));
   else if ((is_floating_value (arg1) || is_int1)