poke-devel
[Top][All Lists]
Advanced

[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" } */



reply via email to

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