[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] pkl, testsuite: generalize bit-wise operators, shifts and po
From: |
Jose E. Marchesi |
Subject: |
[COMMITTED] pkl, testsuite: generalize bit-wise operators, shifts and pow to offsets |
Date: |
Sun, 01 Mar 2020 22:11:05 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) |
Author: Jose E. Marchesi <address@hidden>
Date: Sun Mar 1 22:07:19 2020 +0100
pkl,testsuite: generalize bit-wise operators, shifts and pow to offsets
This patch generalizes the operators ^, &, |, **, <<. and .>> so they
can be applied to offset operands.
2020-03-01 Jose E. Marchesi <address@hidden>
* src/pkl-promo.c (pkl_promo_ps_op_binary_intoffstr): Renamed from
pkl_promo_ps_op_add_sub_mod.
(pkl_promo_ps_op_bshiftpow): Promote offset operand.
* src/pkl-typify.c: ior, xor and band accept both integers and
offsets as arguments.
* src/pkl-gen.c (pkl_gen_ps_op_binexp): Renamed from
pkl_gen_ps_op_intexp, and allow offsets for all operations.
(pkl_gen_ps_op_pow): Remove.
* src/pkl-asm.c (pkl_asm_insn_binop): Renamed from
pkl_asm_insn_binop, and expanded to support binary offset
macro-instructions.
* src/pkl-typify.c (pkl_typify1_ps_bshift_pow): New handler.
* testsuite/poke.pkl/pow-integers-1.pk: Renamed from pow-1.pk.
* testsuite/poke.pkl/pow-integers-2.pk: Renamed from pow-2.pk.
* testsuite/poke.pkl/pow-integers-3.pk: Renamed from pow-3.pk.
* testsuite/poke.pkl/xor-integers-1.pk: Renamed from xor-1.pk
* testsuite/poke.pkl/xor-integers-2.pk: Renamed from xor-2.pk
* testsuite/poke.pkl/ior-integers-1.pk: Renamed from ior-1.pk.
* testsuite/poke.pkl/ior-integers-2.pk: Renamed from ior-2.pk.
* testsuite/poke.pkl/band-integers-1.pk: Renamed from band-1.pk.
* testsuite/poke.pkl/band-integers-2.pk: Renamed from band-2.pk.
* testsuite/poke.pkl/band-offsets-1.pk: New test.
* testsuite/poke.pkl/band-offsets-2.pk: Likewise.
* testsuite/poke.pkl/ior-offsets-1.pk: Likewise.
* testsuite/poke.pkl/ior-offsets-2.pk: Likewise.
* testsuite/poke.pkl/xor-offsets-1.pk: Likewise.
* testsuite/poke.pkl/xor-offsets-2.pk: Likewise.
* testsuite/poke.pkl/pow-diag-1.pk: Likewise.
* testsuite/poke.pkl/sr-diag-1.pk: Likewise.
* testsuite/poke.pkl/sl-diag-4.pk: Likewise.
* testsuite/poke.pkl/sr-diag-2.pk: Likewise.
* testsuite/poke.pkl/sl-diag-5.pk: Likewise.
* testsuite/poke.pkl/pow-diag-2.pk: Likewise.
* testsuite/poke.pkl/pow-offsets-1.pk: Likewise.
* testsuite/poke.pkl/pow-offsets-2.pk: Likewise.
* testsuite/poke.pkl/pow-offsets-3.pk: Likewise.
* TODO: Update.
diff --git a/ChangeLog b/ChangeLog
index 7b21416..eddc0f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2020-03-01 Jose E. Marchesi <address@hidden>
+
+ * src/pkl-promo.c (pkl_promo_ps_op_binary_intoffstr): Renamed from
+ pkl_promo_ps_op_add_sub_mod.
+ (pkl_promo_ps_op_bshiftpow): Promote offset operand.
+ * src/pkl-typify.c: ior, xor and band accept both integers and
+ offsets as arguments.
+ * src/pkl-gen.c (pkl_gen_ps_op_binexp): Renamed from
+ pkl_gen_ps_op_intexp, and allow offsets for all operations.
+ (pkl_gen_ps_op_pow): Remove.
+ * src/pkl-asm.c (pkl_asm_insn_binop): Renamed from
+ pkl_asm_insn_binop, and expanded to support binary offset
+ macro-instructions.
+ * src/pkl-typify.c (pkl_typify1_ps_bshift_pow): New handler.
+ * testsuite/poke.pkl/pow-integers-1.pk: Renamed from pow-1.pk.
+ * testsuite/poke.pkl/pow-integers-2.pk: Renamed from pow-2.pk.
+ * testsuite/poke.pkl/pow-integers-3.pk: Renamed from pow-3.pk.
+ * testsuite/poke.pkl/xor-integers-1.pk: Renamed from xor-1.pk
+ * testsuite/poke.pkl/xor-integers-2.pk: Renamed from xor-2.pk
+ * testsuite/poke.pkl/ior-integers-1.pk: Renamed from ior-1.pk.
+ * testsuite/poke.pkl/ior-integers-2.pk: Renamed from ior-2.pk.
+ * testsuite/poke.pkl/band-integers-1.pk: Renamed from band-1.pk.
+ * testsuite/poke.pkl/band-integers-2.pk: Renamed from band-2.pk.
+ * testsuite/poke.pkl/band-offsets-1.pk: New test.
+ * testsuite/poke.pkl/band-offsets-2.pk: Likewise.
+ * testsuite/poke.pkl/ior-offsets-1.pk: Likewise.
+ * testsuite/poke.pkl/ior-offsets-2.pk: Likewise.
+ * testsuite/poke.pkl/xor-offsets-1.pk: Likewise.
+ * testsuite/poke.pkl/xor-offsets-2.pk: Likewise.
+ * testsuite/poke.pkl/pow-diag-1.pk: Likewise.
+ * testsuite/poke.pkl/sr-diag-1.pk: Likewise.
+ * testsuite/poke.pkl/sl-diag-4.pk: Likewise.
+ * testsuite/poke.pkl/sr-diag-2.pk: Likewise.
+ * testsuite/poke.pkl/sl-diag-5.pk: Likewise.
+ * testsuite/poke.pkl/pow-diag-2.pk: Likewise.
+ * testsuite/poke.pkl/pow-offsets-1.pk: Likewise.
+ * testsuite/poke.pkl/pow-offsets-2.pk: Likewise.
+ * testsuite/poke.pkl/pow-offsets-3.pk: Likewise.
+ * TODO: Update.
+
2020-03-01 Jose E. Marchesi <address@hidden>
* src/pvm.jitter: Remove trailing whitespaces.
diff --git a/TODO b/TODO
index abefdeb..9a99b44 100644
--- a/TODO
+++ b/TODO
@@ -197,23 +197,6 @@ For example, this is passed as valid::
RAS should emit an error in that case.
-#L2 Support bitwise operators for offsets
------------------------------------------
-
-Offset values should support bitwise operations, in exactly the same
-way than integer values::
-
- OFF1 ^ OFF2
- OFF1 & OFF2
- OFF1 | OFF2
- OFF1 <<. INT
- OFF1 .>> INT
-
-This task involves modifying the relevant typify1 handlers to allow
-offsets in these operators, promotion rules in promo and updates to
-the code generator. I suggest to implement the operations as
-macro-instructions in ``src/pkl-asm.c``.
-
#L2 Support casts from/to integrals to strings
----------------------------------------------
diff --git a/src/pkl-asm.c b/src/pkl-asm.c
index bebdf49..52be910 100644
--- a/src/pkl-asm.c
+++ b/src/pkl-asm.c
@@ -630,7 +630,7 @@ pkl_asm_insn_poked (pkl_asm pasm, pkl_ast_node type)
result. */
static void
-pkl_asm_insn_intop (pkl_asm pasm,
+pkl_asm_insn_binop (pkl_asm pasm,
enum pkl_asm_insn insn,
pkl_ast_node type)
{
@@ -730,17 +730,51 @@ pkl_asm_insn_intop (pkl_asm pasm,
else if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_OFFSET)
{
pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (type);
+ pkl_ast_node unit = PKL_AST_TYPE_O_UNIT (type);
- /* Only certain operations are valid on offsets. */
- assert (insn == PKL_INSN_NEG || insn == PKL_INSN_BNOT);
-
- /* Get the magnitude of the offset, operate on it, and set it
- back in the offset value. The offset is in the stack. */
- pkl_asm_insn (pasm, PKL_INSN_DUP); /* OFF OFF */
- pkl_asm_insn (pasm, PKL_INSN_OGETM); /* OFF OFF OMAG */
- pkl_asm_insn_intop (pasm, insn, base_type); /* OFF OFF OMAG NOMAG */
- pkl_asm_insn (pasm, PKL_INSN_NIP); /* OFF OFF NOMAG */
- pkl_asm_insn (pasm, PKL_INSN_OSETM); /* OFF NOFF */
+ if (insn == PKL_INSN_NEG || insn == PKL_INSN_BNOT)
+ {
+ pkl_asm_insn (pasm, PKL_INSN_OGETM); /* OFF OMAG */
+ pkl_asm_insn_binop (pasm, insn, base_type); /* OFF OMAG NOMAG */
+ pkl_asm_insn (pasm, PKL_INSN_NIP); /* OFF NOMAG */
+ pkl_asm_insn (pasm, PKL_INSN_PUSH,
+ pvm_make_ulong (PKL_AST_INTEGER_VALUE (unit), 64));
+ /* OFF NOMAG RUNIT */
+ pkl_asm_insn (pasm, PKL_INSN_MKO); /* OFF ROFF */
+ }
+ else if (insn == PKL_INSN_SL
+ || insn == PKL_INSN_SR
+ || insn == PKL_INSN_POW)
+ {
+ pkl_asm_insn (pasm, PKL_INSN_OVER); /* OFF UINT OFF */
+ pkl_asm_insn (pasm, PKL_INSN_OGETM); /* OFF UINT OFF OMAG */
+ pkl_asm_insn (pasm, PKL_INSN_NIP); /* OFF UINT OMAG */
+ pkl_asm_insn (pasm, PKL_INSN_SWAP); /* OFF OMAG UINT */
+ pkl_asm_insn_binop (pasm, insn, base_type); /* OFF OMAG UINT NOMAG */
+ pkl_asm_insn (pasm, PKL_INSN_ROT); /* OFF UINT NOMAG OMAG */
+ pkl_asm_insn (pasm, PKL_INSN_DROP); /* OFF UINT NOMAG */
+ pkl_asm_insn (pasm, PKL_INSN_PUSH,
+ pvm_make_ulong (PKL_AST_INTEGER_VALUE (unit), 64));
+ /* OFF UINT NOMAG RUNIT
*/
+ pkl_asm_insn (pasm, PKL_INSN_MKO); /* OFF1 OFF2 ROFF */
+ }
+ else
+ {
+ pkl_asm_insn (pasm, PKL_INSN_OVER); /* OFF1 OFF2 OFF1 */
+ pkl_asm_insn (pasm, PKL_INSN_OVER); /* OFF1 OFF2 OFF1 OFF2 */
+ pkl_asm_insn (pasm, PKL_INSN_OGETM); /* ... OFF1 OFF2 OMAG2 */
+ pkl_asm_insn (pasm, PKL_INSN_NIP); /* ... OFF1 OMAG2 */
+ pkl_asm_insn (pasm, PKL_INSN_SWAP); /* ... OMAG2 OFF1 */
+ pkl_asm_insn (pasm, PKL_INSN_OGETM); /* ... OMAG2 OFF1 OMAG1
*/
+ pkl_asm_insn (pasm, PKL_INSN_NIP); /* ... OMAG2 OMAG1 */
+ pkl_asm_insn (pasm, PKL_INSN_SWAP); /* ... OMAG1 OMAG2 */
+ pkl_asm_insn_binop (pasm, insn, base_type); /* ... OMAG1 OMAG2 RMAG
*/
+ pkl_asm_insn (pasm, PKL_INSN_NIP2); /* OFF1 OFF2 RMAG */
+ pkl_asm_insn (pasm, PKL_INSN_PUSH,
+ pvm_make_ulong (PKL_AST_INTEGER_VALUE (unit), 64));
+ /* OFF1 OFF2 RMAG RUNIT
*/
+ pkl_asm_insn (pasm, PKL_INSN_MKO); /* OFF1 OFF2 ROFF */
+ }
}
else
assert (0);
@@ -1426,7 +1460,7 @@ pkl_asm_insn (pkl_asm pasm, enum pkl_asm_insn insn, ...)
type = va_arg (valist, pkl_ast_node);
va_end (valist);
- pkl_asm_insn_intop (pasm, insn, type);
+ pkl_asm_insn_binop (pasm, insn, type);
break;
}
case PKL_INSN_CDIV:
diff --git a/src/pkl-gen.c b/src/pkl-gen.c
index 661b9a3..3d6b8d8 100644
--- a/src/pkl-gen.c
+++ b/src/pkl-gen.c
@@ -2551,22 +2551,6 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_ceildiv)
}
PKL_PHASE_END_HANDLER
-/*
- * | OP1
- * | OP2
- * EXP
- */
-
-PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_pow)
-{
- pkl_ast_node type = PKL_AST_TYPE (PKL_PASS_NODE);
-
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_POW, type);
- pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP2);
-}
-PKL_PHASE_END_HANDLER
-
-
PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_mod)
{
pkl_ast_node node = PKL_PASS_NODE;
@@ -2596,7 +2580,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_mod)
}
PKL_PHASE_END_HANDLER
-PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_intexp)
+PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_binexp)
{
pkl_asm pasm = PKL_GEN_ASM;
@@ -2618,6 +2602,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_intexp)
case PKL_AST_OP_XOR: insn = PKL_INSN_BXOR; break;
case PKL_AST_OP_SL: insn = PKL_INSN_SL; break;
case PKL_AST_OP_SR: insn = PKL_INSN_SR; break;
+ case PKL_AST_OP_POW: insn = PKL_INSN_POW; break;
default:
assert (0);
break;
@@ -2626,7 +2611,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_intexp)
switch (PKL_AST_TYPE_CODE (type))
{
case PKL_TYPE_OFFSET:
- assert (insn == PKL_INSN_NEG || insn == PKL_INSN_BNOT);
+ /* Fallthrough. */
case PKL_TYPE_INTEGRAL:
pkl_asm_insn (pasm, insn, type);
pkl_asm_insn (pasm, PKL_INSN_NIP);
@@ -3028,17 +3013,17 @@ struct pkl_phase pkl_phase_gen =
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SUB, pkl_gen_ps_op_sub),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MUL, pkl_gen_ps_op_mul),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MOD, pkl_gen_ps_op_mod),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BAND, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BNOT, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_NEG, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POS, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IOR, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_XOR, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SL, pkl_gen_ps_op_intexp),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_gen_ps_op_intexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BAND, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BNOT, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_NEG, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POS, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IOR, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_XOR, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SL, pkl_gen_ps_op_binexp),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_gen_ps_op_binexp),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_DIV, pkl_gen_ps_op_div),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_CEILDIV, pkl_gen_ps_op_ceildiv),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POW, pkl_gen_ps_op_pow),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POW, pkl_gen_ps_op_binexp),
PKL_PHASE_PR_OP_HANDLER (PKL_AST_OP_AND, pkl_gen_pr_op_and),
PKL_PHASE_PR_OP_HANDLER (PKL_AST_OP_OR, pkl_gen_pr_op_or),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_NOT, pkl_gen_ps_op_not),
diff --git a/src/pkl-promo.c b/src/pkl-promo.c
index 6f2d7db..e143a4f 100644
--- a/src/pkl-promo.c
+++ b/src/pkl-promo.c
@@ -282,8 +282,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_div)
}
PKL_PHASE_END_HANDLER
-/* Addition, subtraction and modulus are defined on the following
- configurations of operand and result types:
+/* Addition, subtraction, modulus, and the bitwise binary operators
+ are defined on the following configurations of operand and result
+ types:
INTEGRAL x INTEGRAL -> INTEGRAL
OFFSET x OFFSET -> OFFSET
@@ -301,7 +302,7 @@ PKL_PHASE_END_HANDLER
In this configuration no promotions are done. */
-PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_add_sub_mod)
+PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_binary_intoffstr)
{
pkl_ast_node exp = PKL_PASS_NODE;
pkl_ast_node type = PKL_AST_TYPE (exp);
@@ -564,6 +565,7 @@ PKL_PHASE_END_HANDLER
the following configurations of operand and result types:
INTEGRAL x INTEGRAL(32,0) -> INTEGRAL
+ OFFSET x INTEGRAL(32,0) -> OFFSET
In this configuration, the type of the first operand is promoted to
match the type of the result. The type of the second operand is
@@ -576,25 +578,51 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_bshiftpow)
pkl_ast_node exp = PKL_PASS_NODE;
pkl_ast_node type = PKL_AST_TYPE (exp);
- if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_INTEGRAL)
+ switch (PKL_AST_TYPE_CODE (type))
{
- size_t size = PKL_AST_TYPE_I_SIZE (type);
- int sign = PKL_AST_TYPE_I_SIGNED (type);
+ case PKL_TYPE_INTEGRAL:
+ {
+ size_t size = PKL_AST_TYPE_I_SIZE (type);
+ int sign = PKL_AST_TYPE_I_SIGNED (type);
- if (!promote_integral (PKL_PASS_AST, size, sign,
+ if (!promote_integral (PKL_PASS_AST, size, sign,
+ &PKL_AST_EXP_OPERAND (exp, 0), &restart1)
+ || !promote_integral (PKL_PASS_AST, 32, 0,
+ &PKL_AST_EXP_OPERAND (exp, 1), &restart2))
+ goto error;
+
+ PKL_PASS_RESTART = restart1 || restart2;
+ break;
+ }
+ case PKL_TYPE_OFFSET:
+ {
+ pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (type);
+ pkl_ast_node unit = PKL_AST_TYPE_O_UNIT (type);
+
+ size_t size = PKL_AST_TYPE_I_SIZE (base_type);
+ int sign = PKL_AST_TYPE_I_SIGNED (base_type);
+
+ if (!promote_offset (PKL_PASS_AST,
+ size, sign, unit,
&PKL_AST_EXP_OPERAND (exp, 0), &restart1)
- || !promote_integral (PKL_PASS_AST, 32, 0,
- &PKL_AST_EXP_OPERAND (exp, 1), &restart2))
- {
- pkl_ice (PKL_PASS_AST, PKL_AST_LOC (exp),
- "couldn't promote operands of expression #%" PRIu64,
- PKL_AST_UID (exp));
- PKL_PASS_ERROR;
- }
+ || !promote_integral (PKL_PASS_AST, 32, 0,
+ &PKL_AST_EXP_OPERAND (exp, 1), &restart2))
+ goto error;
- PKL_PASS_RESTART = restart1 || restart2;
+ PKL_PASS_RESTART = restart1 || restart2;
+ break;
+ }
+ default:
+ assert (0);
}
+ PKL_PASS_DONE;
+
+ error:
+ pkl_ice (PKL_PASS_AST, PKL_AST_LOC (exp),
+ "couldn't promote operands of expression #%" PRIu64,
+ PKL_AST_UID (exp));
+ PKL_PASS_ERROR;
}
PKL_PHASE_END_HANDLER
@@ -1474,15 +1502,15 @@ struct pkl_phase pkl_phase_promo =
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_GE, pkl_promo_ps_op_rela),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SL, pkl_promo_ps_op_bshiftpow),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_promo_ps_op_bshiftpow),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IOR, pkl_promo_ps_op_binary),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_XOR, pkl_promo_ps_op_binary),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BAND, pkl_promo_ps_op_binary),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IOR, pkl_promo_ps_op_binary_intoffstr),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_XOR, pkl_promo_ps_op_binary_intoffstr),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BAND, pkl_promo_ps_op_binary_intoffstr),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_AND, pkl_promo_ps_op_binary),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_OR, pkl_promo_ps_op_binary),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_NOT, pkl_promo_ps_op_unary),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_ADD, pkl_promo_ps_op_add_sub_mod),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SUB, pkl_promo_ps_op_add_sub_mod),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MOD, pkl_promo_ps_op_add_sub_mod),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_ADD, pkl_promo_ps_op_binary_intoffstr),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SUB, pkl_promo_ps_op_binary_intoffstr),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MOD, pkl_promo_ps_op_binary_intoffstr),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MUL, pkl_promo_ps_op_mul),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POW, pkl_promo_ps_op_bshiftpow),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_DIV, pkl_promo_ps_op_div),
diff --git a/src/pkl-typify.c b/src/pkl-typify.c
index 85c2e41..ac2125d 100644
--- a/src/pkl-typify.c
+++ b/src/pkl-typify.c
@@ -489,25 +489,11 @@ PKL_PHASE_END_HANDLER
} \
PKL_PHASE_END_HANDLER
-/* The following operations only accept integers. */
+/* DIV, MOD and SUB accept integral and offset operands. */
#define CASE_STR
#define CASE_OFFSET
-#define CASE_INTEGRAL \
- case PKL_TYPE_INTEGRAL: \
- { \
- int signed_p = PKL_AST_TYPE_I_SIGNED (t1); \
- int size = PKL_AST_TYPE_I_SIZE (t1); \
- \
- type = pkl_ast_make_integral_type (PKL_PASS_AST, size, signed_p); \
- break; \
- }
-
-TYPIFY_BIN (sl);
-TYPIFY_BIN (sr);
-TYPIFY_BIN (pow);
-
#undef CASE_INTEGRAL
#define CASE_INTEGRAL \
case PKL_TYPE_INTEGRAL: \
@@ -521,12 +507,6 @@ TYPIFY_BIN (pow);
break; \
}
-TYPIFY_BIN (ior);
-TYPIFY_BIN (xor);
-TYPIFY_BIN (band);
-
-/* DIV, MOD and SUB accept integral and offset operands. */
-
#undef CASE_OFFSET
#define CASE_OFFSET \
case PKL_TYPE_OFFSET: \
@@ -587,7 +567,7 @@ TYPIFY_BIN (div);
TYPIFY_BIN (ceildiv);
TYPIFY_BIN (mod);
-/* SUB accepts integrals and offsets. */
+/* IOR, XOR, BAND and SUB accept integrals and offsets. */
#undef CASE_OFFSET
#define CASE_OFFSET \
@@ -638,6 +618,9 @@ TYPIFY_BIN (mod);
break; \
}
+TYPIFY_BIN (ior);
+TYPIFY_BIN (xor);
+TYPIFY_BIN (band);
TYPIFY_BIN (sub);
/* ADD accepts integral, string and offset operands. */
@@ -650,6 +633,62 @@ TYPIFY_BIN (sub);
TYPIFY_BIN (add);
+/* The bit-shift operators and the pow operator can't be handled with
+ TYPIFY_BIN. */
+
+PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_bshift_pow)
+{
+ pkl_ast_node exp = PKL_PASS_NODE;
+ pkl_ast_node op1 = PKL_AST_EXP_OPERAND (exp, 0);
+ pkl_ast_node op2 = PKL_AST_EXP_OPERAND (exp, 1);
+ pkl_ast_node t1 = PKL_AST_TYPE (op1);
+ pkl_ast_node t2 = PKL_AST_TYPE (op2);
+
+ pkl_ast_node type;
+
+ /* The second argument should be an integral. */
+ if (PKL_AST_TYPE_CODE (t2) != PKL_TYPE_INTEGRAL)
+ {
+ PKL_ERROR (PKL_AST_LOC (op2), "expected an integer");
+ PKL_TYPIFY_PAYLOAD->errors++;
+ PKL_PASS_ERROR;
+ }
+
+ /* The first argument can be either an integral or an offset. */
+
+ switch (PKL_AST_TYPE_CODE (t1))
+ {
+ case PKL_TYPE_INTEGRAL:
+ {
+ int signed_p = PKL_AST_TYPE_I_SIGNED (t1);
+ int size = PKL_AST_TYPE_I_SIZE (t1);
+
+ type = pkl_ast_make_integral_type (PKL_PASS_AST,
+ size, signed_p);
+ break;
+ }
+ case PKL_TYPE_OFFSET:
+ {
+ pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (t1);
+ pkl_ast_node unit = PKL_AST_TYPE_O_UNIT (t1);
+
+ type = pkl_ast_make_offset_type (PKL_PASS_AST,
+ base_type, unit);
+ break;
+ }
+ default:
+ PKL_ERROR (PKL_AST_LOC (op1), "expected integral or offset");
+ PKL_TYPIFY_PAYLOAD->errors++;
+ PKL_PASS_ERROR;
+ break;
+ }
+
+ PKL_AST_LOC (type) = PKL_AST_LOC (exp);
+ PKL_AST_TYPE (exp) = ASTREF (type);
+ PKL_PASS_DONE;
+}
+PKL_PHASE_END_HANDLER
+
/* MUL accepts integral, offset and string operands. We can't use
TYPIFY_BIN here because it relies on a different logic to determine
the result type. */
@@ -2412,10 +2451,10 @@ struct pkl_phase pkl_phase_typify1 =
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MUL, pkl_typify1_ps_mul),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_DIV, pkl_typify1_ps_div),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_CEILDIV, pkl_typify1_ps_ceildiv),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POW, pkl_typify1_ps_pow),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_POW, pkl_typify1_ps_bshift_pow),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_MOD, pkl_typify1_ps_mod),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SL, pkl_typify1_ps_sl),
- PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_typify1_ps_sr),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SL, pkl_typify1_ps_bshift_pow),
+ PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_typify1_ps_bshift_pow),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IOR, pkl_typify1_ps_ior),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_XOR, pkl_typify1_ps_xor),
PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_BAND, pkl_typify1_ps_band),
diff --git a/testsuite/poke.pkl/band-1.pk
b/testsuite/poke.pkl/band-integers-1.pk
similarity index 100%
rename from testsuite/poke.pkl/band-1.pk
rename to testsuite/poke.pkl/band-integers-1.pk
diff --git a/testsuite/poke.pkl/band-2.pk
b/testsuite/poke.pkl/band-integers-2.pk
similarity index 100%
rename from testsuite/poke.pkl/band-2.pk
rename to testsuite/poke.pkl/band-integers-2.pk
diff --git a/testsuite/poke.pkl/band-offsets-1.pk
b/testsuite/poke.pkl/band-offsets-1.pk
new file mode 100644
index 0000000..a15d612
--- /dev/null
+++ b/testsuite/poke.pkl/band-offsets-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x & 0xeadbeef#B } } */
+/* { dg-output "0x0#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0#B & 0x0eadbeef#B } } */
+/* { dg-output "\n0x0#B" } */
diff --git a/testsuite/poke.pkl/band-offsets-2.pk
b/testsuite/poke.pkl/band-offsets-2.pk
new file mode 100644
index 0000000..b25a6d5
--- /dev/null
+++ b/testsuite/poke.pkl/band-offsets-2.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0xffffffffU#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x & 0xdeadbeefU#B } } */
+/* { dg-output "0xdeadbeefU#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0xffffffffU#B & 0xdeadbeefU#B } } */
+/* { dg-output "\n0xdeadbeefU#B" } */
diff --git a/testsuite/poke.pkl/ior-1.pk b/testsuite/poke.pkl/ior-integers-1.pk
similarity index 100%
rename from testsuite/poke.pkl/ior-1.pk
rename to testsuite/poke.pkl/ior-integers-1.pk
diff --git a/testsuite/poke.pkl/ior-2.pk b/testsuite/poke.pkl/ior-integers-2.pk
similarity index 100%
rename from testsuite/poke.pkl/ior-2.pk
rename to testsuite/poke.pkl/ior-integers-2.pk
diff --git a/testsuite/poke.pkl/ior-offsets-1.pk
b/testsuite/poke.pkl/ior-offsets-1.pk
new file mode 100644
index 0000000..55d4b6a
--- /dev/null
+++ b/testsuite/poke.pkl/ior-offsets-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x | 0xeadbeef#B } } */
+/* { dg-output "0xeadbeef#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0#B | 0x0eadbeef#B } } */
+/* { dg-output "\n0xeadbeef#B" } */
diff --git a/testsuite/poke.pkl/ior-offsets-2.pk
b/testsuite/poke.pkl/ior-offsets-2.pk
new file mode 100644
index 0000000..4886994
--- /dev/null
+++ b/testsuite/poke.pkl/ior-offsets-2.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0U#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x | 0xdeadbeefU#B } } */
+/* { dg-output "0xdeadbeefU#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0U#B | 0xdeadbeefU#B } } */
+/* { dg-output "\n0xdeadbeefU#B" } */
diff --git a/testsuite/poke.pkl/pow-diag-1.pk b/testsuite/poke.pkl/pow-diag-1.pk
new file mode 100644
index 0000000..6277906
--- /dev/null
+++ b/testsuite/poke.pkl/pow-diag-1.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = 20 ** "foo"; /* { dg-error "expected an integer" } */
diff --git a/testsuite/poke.pkl/pow-diag-2.pk b/testsuite/poke.pkl/pow-diag-2.pk
new file mode 100644
index 0000000..378adf0
--- /dev/null
+++ b/testsuite/poke.pkl/pow-diag-2.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = "foo" ** 2; /* { dg-error "expected integral or offset" } */
diff --git a/testsuite/poke.pkl/pow-1.pk b/testsuite/poke.pkl/pow-integers-1.pk
similarity index 100%
rename from testsuite/poke.pkl/pow-1.pk
rename to testsuite/poke.pkl/pow-integers-1.pk
diff --git a/testsuite/poke.pkl/pow-2.pk b/testsuite/poke.pkl/pow-integers-2.pk
similarity index 100%
rename from testsuite/poke.pkl/pow-2.pk
rename to testsuite/poke.pkl/pow-integers-2.pk
diff --git a/testsuite/poke.pkl/pow-3.pk b/testsuite/poke.pkl/pow-integers-3.pk
similarity index 100%
rename from testsuite/poke.pkl/pow-3.pk
rename to testsuite/poke.pkl/pow-integers-3.pk
diff --git a/testsuite/poke.pkl/pow-offsets-1.pk
b/testsuite/poke.pkl/pow-offsets-1.pk
new file mode 100644
index 0000000..cb2fe6b
--- /dev/null
+++ b/testsuite/poke.pkl/pow-offsets-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+/* { dg-command { .set obase 16 } } */
+
+defvar x = 2#B;
+
+/* { dg-command { x ** 10 } } */
+/* { dg-output "0x400#B" } */
+
+/* For constant folding: */
+/* { dg-command { 2#B ** 10 } } */
+/* { dg-output "\n0x400#B" } */
diff --git a/testsuite/poke.pkl/pow-offsets-2.pk
b/testsuite/poke.pkl/pow-offsets-2.pk
new file mode 100644
index 0000000..ea06c1f
--- /dev/null
+++ b/testsuite/poke.pkl/pow-offsets-2.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+defvar x = 1#B;
+
+/* { dg-command { x ** 0 } } */
+/* { dg-output "1#B" } */
+
+/* For constant folding: */
+/* { dg-command { 2#B ** 0 } } */
+/* { dg-output "\n1#B" } */
diff --git a/testsuite/poke.pkl/pow-offsets-3.pk
b/testsuite/poke.pkl/pow-offsets-3.pk
new file mode 100644
index 0000000..b6f9ed8
--- /dev/null
+++ b/testsuite/poke.pkl/pow-offsets-3.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+defvar x = 2#B;
+
+/* { dg-command { x ** -1 } } */
+/* { dg-output "0#B" } */
+
+/* For constant folding: */
+/* { dg-command { 2#B ** -1 } } */
+/* { dg-output "\n0#B" } */
diff --git a/testsuite/poke.pkl/sl-diag-4.pk b/testsuite/poke.pkl/sl-diag-4.pk
new file mode 100644
index 0000000..863557b
--- /dev/null
+++ b/testsuite/poke.pkl/sl-diag-4.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = 20 <<. [1,2,3]; /* { dg-error "expected an integer" } */
diff --git a/testsuite/poke.pkl/sl-diag-5.pk b/testsuite/poke.pkl/sl-diag-5.pk
new file mode 100644
index 0000000..6e3a2d9
--- /dev/null
+++ b/testsuite/poke.pkl/sl-diag-5.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = [1,2,3] <<. 20; /* { dg-error "expected integral or offset" } */
diff --git a/testsuite/poke.pkl/sr-diag-1.pk b/testsuite/poke.pkl/sr-diag-1.pk
new file mode 100644
index 0000000..bd24aa5
--- /dev/null
+++ b/testsuite/poke.pkl/sr-diag-1.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = 20 .>> 3#B; /* { dg-error "expected an integer" } */
diff --git a/testsuite/poke.pkl/sr-diag-2.pk b/testsuite/poke.pkl/sr-diag-2.pk
new file mode 100644
index 0000000..5108bd3
--- /dev/null
+++ b/testsuite/poke.pkl/sr-diag-2.pk
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+defvar a = [1,2,3] .>> 2; /* { dg-error "expected integral or offset" } */
diff --git a/testsuite/poke.pkl/xor-1.pk b/testsuite/poke.pkl/xor-integers-1.pk
similarity index 100%
rename from testsuite/poke.pkl/xor-1.pk
rename to testsuite/poke.pkl/xor-integers-1.pk
diff --git a/testsuite/poke.pkl/xor-2.pk b/testsuite/poke.pkl/xor-integers-2.pk
similarity index 100%
rename from testsuite/poke.pkl/xor-2.pk
rename to testsuite/poke.pkl/xor-integers-2.pk
diff --git a/testsuite/poke.pkl/xor-offsets-1.pk
b/testsuite/poke.pkl/xor-offsets-1.pk
new file mode 100644
index 0000000..b98128f
--- /dev/null
+++ b/testsuite/poke.pkl/xor-offsets-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0x0000ffffU#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x ^ 0xffff0000U#B } } */
+/* { dg-output "0xffffffffU#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0x0000ffffU#B ^ 0xffff0000U#B } } */
+/* { dg-output "\n0xffffffffU#B" } */
diff --git a/testsuite/poke.pkl/xor-offsets-2.pk
b/testsuite/poke.pkl/xor-offsets-2.pk
new file mode 100644
index 0000000..74575c5
--- /dev/null
+++ b/testsuite/poke.pkl/xor-offsets-2.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+defvar x = 0x0000ffff#B;
+
+/* { dg-command { .set obase 16 } } */
+
+/* { dg-command { x ^ 0xfff0000#B } } */
+/* { dg-output "0xfffffff#B" } */
+
+/* For constant folding: */
+/* { dg-command { 0x0000ffff#B ^ 0xfff0000#B } } */
+/* { dg-output "\n0xfffffff#B" } */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED] pkl, testsuite: generalize bit-wise operators, shifts and pow to offsets,
Jose E. Marchesi <=