[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED 3/3] pkl: support for the 'ref attribute,
Jose E. Marchesi <=