On 5/1/23 22:31, Taylor Simpson wrote:
**** Changes in v3 ****
Fix bugs exposed by dpmpyss_rnd_s0 instruction
     Set correct size/signedness for constants
     Test cases added to tests/tcg/hexagon/misc.c

**** Changes in v2 ****
Fix bug in imm_print identified in clang build

Currently, idef-parser skips all floating point instructions.  However,
there are some floating point instructions that can be handled.

The following instructions are now parsed
     F2_sfimm_p
     F2_sfimm_n
     F2_dfimm_p
     F2_dfimm_n
     F2_dfmpyll
     F2_dfmpylh

To make these instructions work, we fix some bugs in parser-helpers.c
     gen_rvalue_extend
     gen_cast_op
     imm_print
     lexer properly sets size/signedness of constants

Test cases added to tests/tcg/hexagon/fpstuff.c

Signed-off-by: Taylor Simpson<[email protected]>
---
  target/hexagon/idef-parser/parser-helpers.h |  2 +-
  target/hexagon/idef-parser/parser-helpers.c | 41 +++++++++++-----
  tests/tcg/hexagon/fpstuff.c                 | 54 +++++++++++++++++++++
  tests/tcg/hexagon/misc.c                    | 35 +++++++++++++
  target/hexagon/gen_idef_parser_funcs.py     | 10 +++-
  target/hexagon/idef-parser/idef-parser.lex  | 38 +++++++++++++--
  target/hexagon/idef-parser/idef-parser.y    |  2 -
  7 files changed, 162 insertions(+), 20 deletions(-)

diff --git a/target/hexagon/idef-parser/parser-helpers.h 
b/target/hexagon/idef-parser/parser-helpers.h
index 1239d23a6a..7c58087169 100644
--- a/target/hexagon/idef-parser/parser-helpers.h
+++ b/target/hexagon/idef-parser/parser-helpers.h
@@ -80,7 +80,7 @@ void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char 
reg_id[5]);
void reg_print(Context *c, YYLTYPE *locp, HexReg *reg); -void imm_print(Context *c, YYLTYPE *locp, HexImm *imm);
+void imm_print(Context *c, YYLTYPE *locp, HexValue *rvalue);
void var_print(Context *c, YYLTYPE *locp, HexVar *var); diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
index 86511efb62..0ad917f591 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -167,8 +167,9 @@ void reg_print(Context *c, YYLTYPE *locp, HexReg *reg)
      EMIT(c, "hex_gpr[%u]", reg->id);
  }
-void imm_print(Context *c, YYLTYPE *locp, HexImm *imm)
+void imm_print(Context *c, YYLTYPE *locp, HexValue *rvalue)
  {
+    HexImm *imm = &rvalue->imm;
      switch (imm->type) {
      case I:
          EMIT(c, "i");
@@ -177,7 +178,21 @@ void imm_print(Context *c, YYLTYPE *locp, HexImm *imm)
          EMIT(c, "%ciV", imm->id);
          break;
      case VALUE:
-        EMIT(c, "((int64_t) %" PRIu64 "ULL)", (int64_t) imm->value);
+        if (rvalue->bit_width == 32) {
+            if (rvalue->signedness == UNSIGNED) {
+                EMIT(c, "((uint32_t) 0x%" PRIx32 ")", (uint32_t) imm->value);
+            }  else {
+                EMIT(c, "((int32_t) 0x%" PRIx32 ")", (int32_t) imm->value);
+            }
+        } else if (rvalue->bit_width == 64) {
+            if (rvalue->signedness == UNSIGNED) {
+                EMIT(c, "((uint64_t) 0x%" PRIx64 "ULL)", (uint64_t) 
imm->value);
+            } else {
+                EMIT(c, "((int64_t) 0x%" PRIx64 "LL)", (int64_t) imm->value);
+            }
+        } else {
+            g_assert_not_reached();
+        }
          break;
      case QEMU_TMP:
          EMIT(c, "qemu_tmp_%" PRIu64, imm->index);
@@ -213,7 +228,7 @@ void rvalue_print(Context *c, YYLTYPE *locp, void *pointer)
        tmp_print(c, locp, &rvalue->tmp);
        break;
    case IMMEDIATE:
-      imm_print(c, locp, &rvalue->imm);
+      imm_print(c, locp, rvalue);
        break;
    case VARID:
        var_print(c, locp, &rvalue->var);
@@ -386,13 +401,10 @@ HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, 
HexValue *rvalue)
if (rvalue->type == IMMEDIATE) {
          HexValue res = gen_imm_qemu_tmp(c, locp, 64, rvalue->signedness);
-        bool is_unsigned = (rvalue->signedness == UNSIGNED);
-        const char *sign_suffix = is_unsigned ? "u" : "";
          gen_c_int_type(c, locp, 64, rvalue->signedness);
-        OUT(c, locp, " ", &res, " = ");
-        OUT(c, locp, "(", sign_suffix, "int64_t) ");
-        OUT(c, locp, "(", sign_suffix, "int32_t) ");
-        OUT(c, locp, rvalue, ";\n");
+        OUT(c, locp, " ", &res, " = (");
+        gen_c_int_type(c, locp, 64, rvalue->signedness);
+        OUT(c, locp, ")", rvalue, ";\n");
          return res;
      } else {
          HexValue res = gen_tmp(c, locp, 64, rvalue->signedness);
@@ -961,9 +973,16 @@ HexValue gen_cast_op(Context *c,
  {
      assert_signedness(c, locp, src->signedness);
      if (src->bit_width == target_width) {
-        return *src;
-    } else if (src->type == IMMEDIATE) {
          HexValue res = *src;
+        res.signedness = signedness;
+        return res;
+    } else if (src->type == IMMEDIATE) {
+        HexValue res;
+        if (src->bit_width < target_width) {
+            res = gen_rvalue_extend(c, locp, src);
+        } else {
+            res = *src;
+        }
          res.bit_width = target_width;
          res.signedness = signedness;
          return res;

Ah, gen_cast_op() can be simplified a great deal here to

    HexValue gen_cast_op(Context *c,
                         YYLTYPE *locp,
                         HexValue *src,
                         unsigned target_width,
                         HexSignedness signedness)
    {
        HexValue res;
        assert_signedness(c, locp, src->signedness);
        if (src->bit_width == target_width) {
            res = *src;
        } else if (src->bit_width < target_width) {
            res = gen_rvalue_extend(c, locp, src);
        } else {
            res = gen_rvalue_truncate(c, locp, src);
        }
        res.signedness = signedness;
        return res;
    }

Other than that this patch looks good:

Tested-by: Anton Johansson <[email protected]>
Reviewed-by: Anton Johansson <[email protected]>



Reply via email to