poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED 3/3] pkl: support for the 'ref attribute


From: Jose E. Marchesi
Subject: [COMMITTED 3/3] pkl: support for the 'ref attribute
Date: Sun, 23 Apr 2023 15:28:46 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

2023-03-28  Jose E. Marchesi  <jemarch@gnu.org>

        * libpoke/pkl-attrs.def: New attribute 'ref.
        * libpoke/pkl-typify.c (pkl_typify1_ps_attr): Handle 'ref.
        * libpoke/pkl-anal.c (pkl_anal1_ps_op_attr): Likewise.
        * libpoke/pkl-promo.c (pkl_promo_ps_op_attr): Likewise.
        * libpoke/pkl-gen.c (pkl_gen_ps_op_attr): Likewise.
        * libpoke/pkl-gen-attrs.pks (attr_ref): New macro.
        * testsuite/poke.pkl/attr-ref-diag-1.pk: New test.
        * testsuite/poke.pkl/attr-ref-diag-2.pk: Likewise.
        * testsuite/poke.pkl/attr-ref-diag-3.pk: Likewise.
        * testsuite/poke.pkl/attr-ref-1.pk: Likewise.
        * testsuite/poke.pkl/attr-ref-2.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
---
 ChangeLog                             | 20 ++++++++++
 doc/poke.texi                         | 10 ++++-
 libpoke/pkl-anal.c                    |  9 +++++
 libpoke/pkl-attrs.def                 |  1 +
 libpoke/pkl-gen-attrs.pks             | 57 +++++++++++++++++++++++++++
 libpoke/pkl-gen.c                     |  7 ++++
 libpoke/pkl-promo.c                   | 22 ++++++++++-
 libpoke/pkl-typify.c                  | 36 +++++++++++++++++
 testsuite/Makefile.am                 |  9 +++++
 testsuite/poke.pkl/attr-ref-1.pk      |  4 ++
 testsuite/poke.pkl/attr-ref-2.pk      |  6 +++
 testsuite/poke.pkl/attr-ref-3.pk      |  8 ++++
 testsuite/poke.pkl/attr-ref-4.pk      |  8 ++++
 testsuite/poke.pkl/attr-ref-5.pk      |  8 ++++
 testsuite/poke.pkl/attr-ref-diag-1.pk |  3 ++
 testsuite/poke.pkl/attr-ref-diag-2.pk |  3 ++
 testsuite/poke.pkl/attr-ref-diag-3.pk |  3 ++
 testsuite/poke.pkl/attr-ref-diag-4.pk |  6 +++
 18 files changed, 217 insertions(+), 3 deletions(-)
 create mode 100644 testsuite/poke.pkl/attr-ref-1.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-2.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-3.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-4.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-5.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-diag-1.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-diag-2.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-diag-3.pk
 create mode 100644 testsuite/poke.pkl/attr-ref-diag-4.pk

diff --git a/ChangeLog b/ChangeLog
index 2a777004..b212c3ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2023-04-23  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-attrs.def: New attribute 'ref.
+       * libpoke/pkl-typify.c (pkl_typify1_ps_attr): Handle 'ref.
+       * libpoke/pkl-anal.c (pkl_anal1_ps_op_attr): Likewise.
+       * libpoke/pkl-promo.c (pkl_promo_ps_op_attr): Likewise.
+       * libpoke/pkl-gen.c (pkl_gen_ps_op_attr): Likewise.
+       * libpoke/pkl-gen-attrs.pks (attr_ref): New macro.
+       * doc/poke.texi (Offset Attributes): Document the 'ref attribute.
+       * testsuite/poke.pkl/attr-ref-diag-1.pk: New test.
+       * testsuite/poke.pkl/attr-ref-diag-2.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-diag-3.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-diag-4.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-1.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-2.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-3.pk: Likewise.
+       * testsuite/poke.pkl/attr-ref-4.pk: New test.
+       * testsuite/poke.pkl/attr-ref-5.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
 2023-03-05  Jose E. Marchesi  <jemarch@gnu.org>
 
        * libpoke/pkl-ast.h (PKL_AST_STRUCT_REF_INDIRECTION_P): Define.
diff --git a/doc/poke.texi b/doc/poke.texi
index c054bd71..d8918526 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -10146,7 +10146,15 @@ Examples:
 @item mapped
 Always 0 for offsets.  (@pxref{Mapping}).
 @item length
-Always @code{1UL} for integers.
+Always @code{1UL} for offsets.
+@item ref ([IOS])
+If the value is a referring offset, then the application of the
+@code{'ref} attribute implies the mapping of the referred value.
+
+The attribute gets an optional argument which is the IO space to use
+when mapping the referred value.  If this argument is not provided
+then the current IO space is assumed.  The application of this
+attribute may result in a @code{E_no_ios} exception.
 @end table
 
 
diff --git a/libpoke/pkl-anal.c b/libpoke/pkl-anal.c
index 1e54e8a2..781684bf 100644
--- a/libpoke/pkl-anal.c
+++ b/libpoke/pkl-anal.c
@@ -726,6 +726,15 @@ PKL_PHASE_BEGIN_HANDLER (pkl_anal1_ps_op_attr)
           PKL_PASS_ERROR;
         }
       break;
+    case PKL_AST_ATTR_REF:
+      if (PKL_AST_EXP_NUMOPS (exp) > 2)
+        {
+          PKL_ERROR (PKL_AST_LOC (exp),
+                     "too many arguments passed to attribute");
+          PKL_ANAL_PAYLOAD->errors++;
+          PKL_PASS_ERROR;
+        }
+      break;
     default:
       if (PKL_AST_EXP_NUMOPS (exp) != 1)
         {
diff --git a/libpoke/pkl-attrs.def b/libpoke/pkl-attrs.def
index 137a2237..c4de81cc 100644
--- a/libpoke/pkl-attrs.def
+++ b/libpoke/pkl-attrs.def
@@ -36,6 +36,7 @@ PKL_DEF_ATTR (PKL_AST_ATTR_ELEM, "elem")
 PKL_DEF_ATTR (PKL_AST_ATTR_EOFFSET, "eoffset")
 PKL_DEF_ATTR (PKL_AST_ATTR_ESIZE, "esize")
 PKL_DEF_ATTR (PKL_AST_ATTR_ENAME, "ename")
+PKL_DEF_ATTR (PKL_AST_ATTR_REF, "ref")
 
 /*
 Local variables:
diff --git a/libpoke/pkl-gen-attrs.pks b/libpoke/pkl-gen-attrs.pks
index 29b51855..87b00981 100644
--- a/libpoke/pkl-gen-attrs.pks
+++ b/libpoke/pkl-gen-attrs.pks
@@ -365,3 +365,60 @@
 .done:
         nip                     ; ELEM
         .end
+
+;;; RAS_MACRO_ATTR_REF @exp @referred_type
+;;; ( OFF (IOS|null) -- VAL )
+;;;
+;;; Given a referring offset and an IO space identifier on the stack, map
+;;; the value referred by the offset at the given IO space.  The IO space
+;;; may be null, and in that case the IO space to use is the current one.
+;;;
+;;; Macro-arguments:
+;;; @exp
+;;;   AST node with the expression node for the attribute.  The first
+;;;   operand in the expression is the referring offset.  The second
+;;;   operand in the expression may be absent or be an int<32> with
+;;;   the IO space to use.
+
+        .macro attr_ref @exp
+        ;; XXX for the moment, we support only strict mapping here.
+        push int<32>1           ; OFF IOS|null STRICT_P
+        nrot                    ; STRICT_P OFF IOS|null
+        ;; This attribute gets an optional argument which is an int<32>
+        ;; IO space identifier.  If the argument is not provided then it
+        ;; defaults to the current IO space.  If there is no current IO
+        ;; space, E_no_ios is raised.
+    .c if (PKL_AST_EXP_NUMOPS (exp) < 2)
+    .c {
+        drop                    ; STRICT_P OFF
+        pushios                 ; STRICT_P OFF IOS
+        push int<32>0           ; STRICT_P OFF IOS 0
+        lti                     ; STRICT_P OFF IOS 0 (IOS<0)
+        nip                     ; STRICT_P OFF IOS (IOS<0)
+        bzi .got_ios
+        push PVM_E_NO_IOS
+        push "msg"
+        push "evaluating a 'ref attribute"
+        sset
+        raise
+.got_ios:
+        drop                    ; STRICT_P OFF IOS
+    .c }
+        swap                    ; STRICT_P IOS OFF
+        ;; We need a bit-offset.
+        .let @u64t = pkl_ast_make_integral_type (PKL_PASS_AST, 64, 0)
+        .let @offset_type = PKL_AST_TYPE (PKL_AST_EXP_OPERAND (exp, 0))
+        .let @magnitude_type = PKL_AST_TYPE_O_BASE_TYPE (@offset_type)
+        ogetm                   ; ... OFF MAGNITUDE
+        nton @magnitude_type, @u64t
+        nip                     ; ... OFF NMAGNITUDE
+        swap                    ; ... NMAGNITUDE OFF
+        ogetu
+        nip                     ; ... NMAGNITUDE UNIT
+        mullu
+        nip2                    ; STRICT_P IOS (NMAGNITUDE*UNIT)
+        ;; Map the referred value.
+    .c  PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_MAPPER);
+    .c  PKL_PASS_SUBPASS (PKL_AST_TYPE (@exp));
+    .c  PKL_GEN_POP_CONTEXT;
+        .end
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index ac4928af..abe47931 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -4632,6 +4632,13 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_attr)
     case PKL_AST_ATTR_STRICT:
       RAS_MACRO_ATTR_STRICT (operand_type);
       break;
+    case PKL_AST_ATTR_REF:
+      assert (PKL_AST_TYPE_CODE (operand_type) == PKL_TYPE_OFFSET
+              && PKL_AST_TYPE_O_REF_TYPE (operand_type) != NULL);
+      if (PKL_AST_EXP_NUMOPS (exp) == 1)
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, PVM_NULL);
+      RAS_MACRO_ATTR_REF (exp);
+      break;
     case PKL_AST_ATTR_ELEM:
       RAS_MACRO_ATTR_ELEM;
       break;
diff --git a/libpoke/pkl-promo.c b/libpoke/pkl-promo.c
index 113febab..58cceb89 100644
--- a/libpoke/pkl-promo.c
+++ b/libpoke/pkl-promo.c
@@ -1603,11 +1603,29 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_attr)
 
   switch (attr)
     {
+    case PKL_AST_ATTR_REF:
+      /* The argument of the attribute, if any, must be promoted to a
+         signed 32-bit integer.  */
+      if (PKL_AST_EXP_NUMOPS (exp) < 2)
+        break;
+
+      if (!promote_integral (PKL_PASS_AST,
+                             32, 1,
+                             &PKL_AST_EXP_OPERAND (exp, 1),
+                             &restart))
+        {
+          PKL_ICE (PKL_AST_LOC (exp),
+                   "couldn't promote argument of attribute expression #%" 
PRIu64,
+                   PKL_AST_UID (exp));
+          PKL_PASS_ERROR;
+        }
+
+      PKL_PASS_RESTART = restart;
+      break;
     case PKL_AST_ATTR_ELEM:
     case PKL_AST_ATTR_EOFFSET:
     case PKL_AST_ATTR_ESIZE:
     case PKL_AST_ATTR_ENAME:
-
       /* The argument of the attribute must be promoted to an unsigned
          64-bit integer.  */
       if (!promote_integral (PKL_PASS_AST,
@@ -1616,7 +1634,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_attr)
                              &restart))
         {
           PKL_ICE (PKL_AST_LOC (exp),
-                   "couldn't pormote argument of attribute expression #%" 
PRIu64,
+                   "couldn't promote argument of attribute expression #%" 
PRIu64,
                    PKL_AST_UID (exp));
           PKL_PASS_ERROR;
         }
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index 61a45dbf..9c1e036b 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -2662,6 +2662,42 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_attr)
       exp_type = pkl_ast_make_integral_type (PKL_PASS_AST, 32, 1);
       PKL_AST_TYPE (exp) = ASTREF (exp_type);
       break;
+    case PKL_AST_ATTR_REF:
+      /* 'ref is defined for offset values whose type has a
+         referred type.  */
+      if (PKL_AST_TYPE_CODE (operand_type) != PKL_TYPE_OFFSET
+          || PKL_AST_TYPE_O_REF_TYPE (operand_type) == NULL)
+        goto invalid_attribute;
+      /* If 'ref is binary then it requires an integral argument
+         encoding an IO space.  */
+      if (PKL_AST_EXP_NUMOPS (exp) == 2)
+      {
+        pkl_ast_node argument = PKL_AST_EXP_OPERAND (exp, 1);
+        pkl_ast_node argument_type = PKL_AST_TYPE (argument);
+
+        /* Integral structs shall be considered as integers in this
+           context.  */
+        if (PKL_AST_TYPE_CODE (argument_type) == PKL_TYPE_STRUCT
+            && PKL_AST_TYPE_S_ITYPE (argument_type))
+          argument_type = PKL_AST_TYPE_S_ITYPE (argument_type);
+
+        if (PKL_AST_TYPE_CODE (argument_type) != PKL_TYPE_INTEGRAL)
+          {
+            char *argument_type_str = pkl_type_str (argument_type, 1);
+
+            PKL_ERROR (PKL_AST_LOC (argument),
+                       "invalid argument to attribute\n"
+                       "expected integral, got %s",
+                       argument_type_str);
+            free (argument_type_str);
+            PKL_TYPIFY_PAYLOAD->errors++;
+            PKL_PASS_ERROR;
+          }
+      }
+      /* The type of 'ref is the referred type of the offset.  */
+      exp_type = PKL_AST_TYPE_O_REF_TYPE (operand_type);
+      PKL_AST_TYPE (exp) = ASTREF (exp_type);
+      break;
     case PKL_AST_ATTR_IOS:
       /* The type of 'mapped is an IOS descriptor, int<32>  */
       exp_type = pkl_ast_make_integral_type (PKL_PASS_AST, 32, 1);
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 2b1b8bcd..a4ce5a71 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -968,6 +968,15 @@ EXTRA_DIST = \
   poke.pkl/attr-offset-diag-2.pk \
   poke.pkl/attr-offset-diag-3.pk \
   poke.pkl/attr-offset-diag-4.pk \
+  poke.pkl/attr-ref-1.pk \
+  poke.pkl/attr-ref-2.pk \
+  poke.pkl/attr-ref-3.pk \
+  poke.pkl/attr-ref-4.pk \
+  poke.pkl/attr-ref-5.pk \
+  poke.pkl/attr-ref-diag-1.pk \
+  poke.pkl/attr-ref-diag-2.pk \
+  poke.pkl/attr-ref-diag-3.pk \
+  poke.pkl/attr-ref-diag-4.pk \
   poke.pkl/attr-signed-1.pk \
   poke.pkl/attr-signed-2.pk \
   poke.pkl/attr-size-1.pk \
diff --git a/testsuite/poke.pkl/attr-ref-1.pk b/testsuite/poke.pkl/attr-ref-1.pk
new file mode 100644
index 00000000..b56aaa10
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-1.pk
@@ -0,0 +1,4 @@
+/* { dg-do run } */
+
+/* { dg-command {try (23#B as offset<int<32>,B,string>)'ref; catch if E_no_ios 
{ print "caught\n"; } } } */
+/* { dg-output "caught" } */
diff --git a/testsuite/poke.pkl/attr-ref-2.pk b/testsuite/poke.pkl/attr-ref-2.pk
new file mode 100644
index 00000000..9b121eb8
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-2.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+/* { dg-command {string @ 3#B = "foo"} } */
+/* { dg-command {(3#B as offset<int<32>,B,string>)'ref + "bar"} } */
+/* { dg-output "foobar" } */
diff --git a/testsuite/poke.pkl/attr-ref-3.pk b/testsuite/poke.pkl/attr-ref-3.pk
new file mode 100644
index 00000000..d689db64
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-3.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Pointer = offset<int<32>,B,string>;
+
+/* { dg-command {string @ 3#B = "foo"} } */
+/* { dg-command {(3#B as Pointer)'ref + "bar"} } */
+/* { dg-output "foobar" } */
diff --git a/testsuite/poke.pkl/attr-ref-4.pk b/testsuite/poke.pkl/attr-ref-4.pk
new file mode 100644
index 00000000..e571836f
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-4.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Pointer = offset<int<32>,B,string>;
+
+/* { dg-command {string @ 3#B = "foo"} } */
+/* { dg-command {(3#B as Pointer)'ref (0) + "bar"} } */
+/* { dg-output "foobar" } */
diff --git a/testsuite/poke.pkl/attr-ref-5.pk b/testsuite/poke.pkl/attr-ref-5.pk
new file mode 100644
index 00000000..aaff1cb2
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-5.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Pointer = offset<int<32>,B,string>;
+
+/* { dg-command {string @ 3#B = "foo"} } */
+/* { dg-command {try (3#B as Pointer)'ref (1) + "bar"; catch if E_no_ios { 
print "caught\n"; } } } */
+/* { dg-output "caught" } */
diff --git a/testsuite/poke.pkl/attr-ref-diag-1.pk 
b/testsuite/poke.pkl/attr-ref-diag-1.pk
new file mode 100644
index 00000000..b6ba5457
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-diag-1.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+var a = 23#B'ref; /* { dg-error "not defined" } */
diff --git a/testsuite/poke.pkl/attr-ref-diag-2.pk 
b/testsuite/poke.pkl/attr-ref-diag-2.pk
new file mode 100644
index 00000000..cf333291
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-diag-2.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+var a = (23#B as offset<int<32>,B,string>)'ref ("foo"); /* { dg-error "invalid 
argument.*\n.*expected integral" } */
diff --git a/testsuite/poke.pkl/attr-ref-diag-3.pk 
b/testsuite/poke.pkl/attr-ref-diag-3.pk
new file mode 100644
index 00000000..af7688f2
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-diag-3.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+var a = (23#B as offset<int<32>,B,string>)'ref ("foo", 2); /* { dg-error 
"unexpected" } */
diff --git a/testsuite/poke.pkl/attr-ref-diag-4.pk 
b/testsuite/poke.pkl/attr-ref-diag-4.pk
new file mode 100644
index 00000000..619babc1
--- /dev/null
+++ b/testsuite/poke.pkl/attr-ref-diag-4.pk
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+type Pointer = offset<int<32>,B,string>;
+
+var a =
+  (2#B as Pointer + 3#B as Pointer)'ref; /* { dg-error "" } */
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]