poke-devel
[Top][All Lists]
Advanced

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

[COMMITTED] pkl,pvm,testsuite,doc: support for the pow operator **


From: Jose E. Marchesi
Subject: [COMMITTED] pkl,pvm,testsuite,doc: support for the pow operator **
Date: Sun, 01 Mar 2020 18:15:29 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

Author: Jose E. Marchesi <address@hidden>
Date:   Sun Mar 1 18:11:16 2020 +0100

    pkl,pvm,testsuite,doc: support for the pow operator **
    
    2020-03-01  Jose E. Marchesi  <address@hidden>
    
            * src/pkl-ops.def (PKL_AST_OP_POW): New operator.
            * src/pkl-tab.y (POW): New token.
            (expression): New rule alternative for exponentiation.
            * src/pkl-lex.l: Handle POW.
            * src/pkl-typify.c: Handle the exponent operator.
            * src/pkl-fold.c: Likewise.
            * src/pkl-promo.c: Likewise.
            (pkl_promo_ps_op_bshiftpow): Renamed from pkl_promo_ps_op_bshift.
            * src/pvm.jitter (PVM_POWOP): Define.
            (powi): New instruction.
            (powiu): Likewise.
            (powl): Likewise.
            (powlu): Likewise.
            * src/pkl-insn.def (PKL_INSN_POWI): Define
            (PKL_INSN_POWIU): Likewise.
            (PKL_INSN_POWL): Likewise.
            (PKL_INSN_POWLU): Likewise.
            (PKL_INSN_POW): Likewise.
            * src/pkl-asm.c (pkl_asm_insn_intop): Implement the pow
            macro-instruction.
            (pkl_asm_insn): Handle PKL_INSN_POW.
            * src/pkl-gen.c (pkl_gen_ps_op_pow): New handler.
            * src/pk-utils.h: Prototypes for pk_ipow and pk_upow.
            * src/pk-utils.c (pk_ipow): New function.
            (pk_upow): Likewise.
            * testsuite/poke.pkl/pow-1.pk: New test.
            * testsuite/poke.pkl/pow-2.pk: Likewise.
            * testsuite/poke.pkl/pow-3.pk: Likewise.
            * doc/poke.texi (Arithmetic Operators): Mention the exponentiation
            operator.

diff --git a/ChangeLog b/ChangeLog
index 5477bdc..7cefb9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2020-03-01  Jose E. Marchesi  <address@hidden>
+
+       * src/pkl-ops.def (PKL_AST_OP_POW): New operator.
+       * src/pkl-tab.y (POW): New token.
+       (expression): New rule alternative for exponentiation.
+       * src/pkl-lex.l: Handle POW.
+       * src/pkl-typify.c: Handle the exponent operator.
+       * src/pkl-fold.c: Likewise.
+       * src/pkl-promo.c: Likewise.
+       (pkl_promo_ps_op_bshiftpow): Renamed from pkl_promo_ps_op_bshift.
+       * src/pvm.jitter (PVM_POWOP): Define.
+       (powi): New instruction.
+       (powiu): Likewise.
+       (powl): Likewise.
+       (powlu): Likewise.
+       * src/pkl-insn.def (PKL_INSN_POWI): Define
+       (PKL_INSN_POWIU): Likewise.
+       (PKL_INSN_POWL): Likewise.
+       (PKL_INSN_POWLU): Likewise.
+       (PKL_INSN_POW): Likewise.
+       * src/pkl-asm.c (pkl_asm_insn_intop): Implement the pow
+       macro-instruction.
+       (pkl_asm_insn): Handle PKL_INSN_POW.
+       * src/pkl-gen.c (pkl_gen_ps_op_pow): New handler.
+       * src/pk-utils.h: Prototypes for pk_ipow and pk_upow.
+       * src/pk-utils.c (pk_ipow): New function.
+       (pk_upow): Likewise.
+       * testsuite/poke.pkl/pow-1.pk: New test.
+       * testsuite/poke.pkl/pow-2.pk: Likewise.
+       * testsuite/poke.pkl/pow-3.pk: Likewise.
+       * doc/poke.texi (Arithmetic Operators): Mention the exponentiation
+       operator.
+
 2020-02-29  John Darrington <address@hidden>
 
        * src/pk-editor.c (pk_cmd_editor):  Correctly test
diff --git a/doc/poke.texi b/doc/poke.texi
index 69548d0..0c2314a 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -1264,7 +1264,7 @@ The following left-associative binary arithmetic 
operators are
 supported, in descending precedence order:
 
 @itemize
-@item Multiplication @code{*}, integer division @code{/}, integer
+@item Exponentiation @code{**}, multiplication @code{*}, integer division 
@code{/}, integer
 ceil-division @code{/^} and modulus @code{%}.
 @item Addition @code{+} and subtraction @code{-}.
 @end itemize
diff --git a/src/pk-utils.c b/src/pk-utils.c
index 09eb9fb..237dd22 100644
--- a/src/pk-utils.c
+++ b/src/pk-utils.c
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <sys/stat.h>
 #include <gettext.h>
 #define _(str) dgettext (PACKAGE, str)
@@ -55,3 +56,25 @@ pk_file_readable (const char *filename)
 
   return 0;
 }
+
+#define PK_POW(NAME,TYPE)                       \
+  TYPE                                          \
+  NAME (TYPE base, uint32_t exp)                \
+  {                                             \
+    TYPE result = 1;                            \
+    while (1)                                   \
+      {                                         \
+        if (exp & 1)                            \
+          result *= base;                       \
+        exp >>= 1;                              \
+        if (!exp)                               \
+          break;                                \
+        base *= base;                           \
+      }                                         \
+    return result;                              \
+  }
+
+PK_POW (pk_ipow, int64_t)
+PK_POW (pk_upow, uint64_t)
+
+#undef PK_POW
diff --git a/src/pk-utils.h b/src/pk-utils.h
index 5b0abf7..a04963c 100644
--- a/src/pk-utils.h
+++ b/src/pk-utils.h
@@ -31,4 +31,10 @@
 
 char *pk_file_readable (const char *filename);
 
+/* Integer exponentiation by squaring, for both signed and unsigned
+   integers.  */
+
+int64_t pk_ipow (int64_t base, uint32_t exp);
+uint64_t pk_upow (uint64_t base, uint32_t exp);
+
 #endif /* ! PK_UTILS_H */
diff --git a/src/pkl-asm.c b/src/pkl-asm.c
index 7a03c14..bebdf49 100644
--- a/src/pkl-asm.c
+++ b/src/pkl-asm.c
@@ -620,10 +620,14 @@ pkl_asm_insn_poked (pkl_asm pasm, pkl_ast_node type)
    Macro-instruction: SR type
    ( VAL VAL -- VAL VAL VAL )
 
+   Macro-instruction: POW type
+   ( VAL VAL -- VAL VAL VAL )
+
    Generate code for performing negation, addition, subtraction,
    multiplication, division, remainder and bit shift to integral and
-   offset operands.  INSN identifies the operation to perform, and
-   TYPE the type of the operands and the result.  */
+   offset operands.  Also exponentiation.  INSN identifies the
+   operation to perform, and TYPE the type of the operands and the
+   result.  */
 
 static void
 pkl_asm_insn_intop (pkl_asm pasm,
@@ -668,6 +672,9 @@ pkl_asm_insn_intop (pkl_asm pasm,
       static int sr_table[2][2] = {{ PKL_INSN_SRIU, PKL_INSN_SRI },
                                    { PKL_INSN_SRLU, PKL_INSN_SRL }};
 
+      static int pow_table[2][2] = {{ PKL_INSN_POWIU, PKL_INSN_POWI },
+                                    { PKL_INSN_POWLU, PKL_INSN_POWL }};
+
       uint64_t size = PKL_AST_TYPE_I_SIZE (type);
       int signed_p = PKL_AST_TYPE_I_SIGNED (type);
       int tl = !!((size - 1) & ~0x1f);
@@ -713,6 +720,9 @@ pkl_asm_insn_intop (pkl_asm pasm,
         case PKL_INSN_SR:
           pkl_asm_insn (pasm, sr_table[tl][signed_p]);
           break;
+        case PKL_INSN_POW:
+          pkl_asm_insn (pasm, pow_table[tl][signed_p]);
+          break;
         default:
           assert (0);
         }
@@ -1408,6 +1418,7 @@ pkl_asm_insn (pkl_asm pasm, enum pkl_asm_insn insn, ...)
         case PKL_INSN_BXOR:
         case PKL_INSN_SL:
         case PKL_INSN_SR:
+        case PKL_INSN_POW:
           {
             pkl_ast_node type;
 
diff --git a/src/pkl-fold.c b/src/pkl-fold.c
index 4b8271d..a7868e5 100644
--- a/src/pkl-fold.c
+++ b/src/pkl-fold.c
@@ -115,6 +115,8 @@ EMUL_UUU (cdiv) { return (op1 - 1 + op2) / op2; }
 EMUL_III (cdiv) { return (op1 - 1 + op2) / op2; }
 EMUL_UUU (mod) { return op1 % op2; }
 EMUL_III (mod) { return op1 % op2; }
+EMUL_III (pow) { return pk_ipow (op1, op2); }
+EMUL_UUU (pow) { return pk_upow (op1, op2); }
 EMUL_UUU (lt) { return op1 < op2; }
 EMUL_III (lt) { return op1 < op2; }
 EMUL_UUU (gt) { return op1 > op2; }
@@ -593,6 +595,7 @@ PKL_PHASE_HANDLER_BIN_INT (and);
 PKL_PHASE_HANDLER_BIN_INT (band);
 PKL_PHASE_HANDLER_BIN_INT (sr);
 PKL_PHASE_HANDLER_BIN_INT (sl);
+PKL_PHASE_HANDLER_BIN_INT (pow);
 
 #define PKL_PHASE_HANDLER_BIN_RELA(OP)               \
   PKL_PHASE_BEGIN_HANDLER (pkl_fold_##OP)            \
@@ -968,6 +971,28 @@ PKL_PHASE_BEGIN_HANDLER (pkl_fold_ps_indexer)
 }
 PKL_PHASE_END_HANDLER
 
+#if 0
+PKL_PHASE_BEGIN_HANDLER (pkl_fold_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);
+
+  if (PKL_AST_CODE (op1) == PKL_AST_INTEGER
+      && PKL_AST_CODE (op2) == PKL_AST_INTEGER)
+    {
+      pkl_ast_node op1_type = PKL_AST_TYPE (op1);
+      
+      if (PKL_AST_TYPE_I_SIGNED (op1_type))
+        {
+          
+
+        }
+    }
+}
+PKL_PHASE_END_HANDLER
+#endif
+
 struct pkl_phase pkl_phase_fold =
   {
    PKL_PHASE_PR_HANDLER (PKL_AST_TYPE, pkl_fold_pr_type),
@@ -987,6 +1012,6 @@ struct pkl_phase pkl_phase_fold =
    ENTRY (GE, ge),
    ENTRY (BCONC, bconc),
    ENTRY (POS, pos), ENTRY (NEG, neg), ENTRY (BNOT, bnot),
-   ENTRY (NOT, not),
+   ENTRY (NOT, not), ENTRY (POW, pow),
 #undef ENTRY
   };
diff --git a/src/pkl-gen.c b/src/pkl-gen.c
index 08d5cc5..661b9a3 100644
--- a/src/pkl-gen.c
+++ b/src/pkl-gen.c
@@ -2551,6 +2551,21 @@ 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)
 {
@@ -3023,6 +3038,7 @@ struct pkl_phase pkl_phase_gen =
    PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_gen_ps_op_intexp),
    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_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-insn.def b/src/pkl-insn.def
index 8fb5ac4..ccee3bd 100644
--- a/src/pkl-insn.def
+++ b/src/pkl-insn.def
@@ -121,6 +121,11 @@ PKL_DEF_INSN (PKL_INSN_MODIU, "", "modiu")
 PKL_DEF_INSN (PKL_INSN_MODL, "", "modl")
 PKL_DEF_INSN (PKL_INSN_MODLU, "", "modlu")
 
+PKL_DEF_INSN (PKL_INSN_POWI, "", "powi")
+PKL_DEF_INSN (PKL_INSN_POWIU, "", "powiu")
+PKL_DEF_INSN (PKL_INSN_POWL, "", "powl")
+PKL_DEF_INSN (PKL_INSN_POWLU, "", "powlu")
+
 /* Compare-and-swap instructions.  */
 
 PKL_DEF_INSN (PKL_INSN_SWAPGTI, "", "swapgti")
@@ -406,6 +411,7 @@ PKL_DEF_INSN (PKL_INSN_MUL, "a", "mul")
 PKL_DEF_INSN (PKL_INSN_DIV, "a", "div")
 PKL_DEF_INSN (PKL_INSN_CDIV, "a", "cdiv")
 PKL_DEF_INSN (PKL_INSN_MOD, "a", "mod")
+PKL_DEF_INSN (PKL_INSN_POW, "a", "pow")
 PKL_DEF_INSN (PKL_INSN_PEEK, "ann", "peek")
 PKL_DEF_INSN (PKL_INSN_POKE, "ann", "poke")
 PKL_DEF_INSN (PKL_INSN_PEEKD, "a", "peekd")
diff --git a/src/pkl-lex.l b/src/pkl-lex.l
index 6451630..2eb925b 100644
--- a/src/pkl-lex.l
+++ b/src/pkl-lex.l
@@ -276,6 +276,7 @@ D [0-9]
 ">"            { return '>'; }
 "+"            { return '+'; }
 "-"            { return '-'; }
+"**"           { return POW; }
 "*"            { return '*'; }
 "/^"           { return CEILDIV; }
 "/"            { return '/'; }
diff --git a/src/pkl-ops.def b/src/pkl-ops.def
index c8c9b89..6cf3c7c 100644
--- a/src/pkl-ops.def
+++ b/src/pkl-ops.def
@@ -34,6 +34,7 @@ PKL_DEF_OP (PKL_AST_OP_SUB, "SUB")
 PKL_DEF_OP (PKL_AST_OP_MUL, "MUL")
 PKL_DEF_OP (PKL_AST_OP_DIV, "DIV")
 PKL_DEF_OP (PKL_AST_OP_CEILDIV, "CEILDIV")
+PKL_DEF_OP (PKL_AST_OP_POW, "POW")
 PKL_DEF_OP (PKL_AST_OP_MOD, "MOD")
 PKL_DEF_OP (PKL_AST_OP_LT, "LT")
 PKL_DEF_OP (PKL_AST_OP_GT, "GT")
diff --git a/src/pkl-promo.c b/src/pkl-promo.c
index ef32d4c..6f2d7db 100644
--- a/src/pkl-promo.c
+++ b/src/pkl-promo.c
@@ -560,8 +560,8 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_rela)
 }
 PKL_PHASE_END_HANDLER
 
-/* The bit shift operations are defined on the following
-   configurations of operand and result types:
+/* The bit shift operations, and also exponentiation, are defined on
+   the following configurations of operand and result types:
 
            INTEGRAL x INTEGRAL(32,0) -> INTEGRAL
 
@@ -569,7 +569,7 @@ PKL_PHASE_END_HANDLER
    match the type of the result.  The type of the second operand is
    promoted to an unsigned 32-bit integral type.  */
 
-PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_bshift)
+PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_bshiftpow)
 {
   int restart1, restart2;
 
@@ -1472,8 +1472,8 @@ struct pkl_phase pkl_phase_promo =
    PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_GT, pkl_promo_ps_op_rela),
    PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_LE, pkl_promo_ps_op_rela),
    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_bshift),
-   PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SR, pkl_promo_ps_op_bshift),
+   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),
@@ -1484,6 +1484,7 @@ struct pkl_phase pkl_phase_promo =
    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_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),
    PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_CEILDIV, pkl_promo_ps_op_div),
    PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_IN, pkl_promo_ps_op_in),
diff --git a/src/pkl-tab.y b/src/pkl-tab.y
index da47cbb..e7f7563 100644
--- a/src/pkl-tab.y
+++ b/src/pkl-tab.y
@@ -377,6 +377,7 @@ load_module (struct pkl_parser *parser,
 %left SL SR
 %left '+' '-'
 %left '*' '/' CEILDIV '%'
+%left POW
 %left BCONC
 %right '@'
 %nonassoc UNIT
@@ -623,6 +624,11 @@ expression:
                   $$ = pkl_ast_make_binary_exp (pkl_parser->ast, 
PKL_AST_OP_CEILDIV, $1, $3);
                   PKL_AST_LOC ($$) = @$;
                 }
+       | expression POW expression
+               {
+                  $$ = pkl_ast_make_binary_exp (pkl_parser->ast, 
PKL_AST_OP_POW, $1, $3);
+                  PKL_AST_LOC ($$) = @$;
+                }
         | expression '%' expression
                {
                   $$ = pkl_ast_make_binary_exp (pkl_parser->ast, 
PKL_AST_OP_MOD,
diff --git a/src/pkl-typify.c b/src/pkl-typify.c
index be8ea5e..85c2e41 100644
--- a/src/pkl-typify.c
+++ b/src/pkl-typify.c
@@ -506,6 +506,7 @@ PKL_PHASE_END_HANDLER
 
 TYPIFY_BIN (sl);
 TYPIFY_BIN (sr);
+TYPIFY_BIN (pow);
 
 #undef CASE_INTEGRAL
 #define CASE_INTEGRAL                                                   \
@@ -2411,6 +2412,7 @@ 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_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),
diff --git a/src/pvm.jitter b/src/pvm.jitter
index aed38b7..2ddc44e 100644
--- a/src/pvm.jitter
+++ b/src/pvm.jitter
@@ -81,9 +81,11 @@ end
 
 early-header-c
   code
+#   include <config.h>
 #   include "pvm.h"
 #   include "ios.h"
 #   include "pk-term.h"
+#   include "pk-utils.h"
 
 #   define STREQ(a, b) (strcmp (a, b) == 0)
 #   define STRNEQ(a, b) (strcmp (a, b) != 0)
@@ -224,6 +226,19 @@ late-header-c
      }                                                                       \
    }
 
+/* Exponentiation instructions.  */
+# define PVM_POWOP(TYPE,TYPEC,TYPELC,POWF)                                  \
+  do                                                                        \
+  {                                                                         \
+     uint64_t size = PVM_VAL_##TYPE##_SIZE (JITTER_UNDER_TOP_STACK ());     \
+     TYPEC res                                                              \
+      = (TYPEC) POWF (PVM_VAL_##TYPE (JITTER_UNDER_TOP_STACK ()),           \
+                      PVM_VAL_UINT (JITTER_TOP_STACK ()));                  \
+                                                                            \
+     JITTER_PUSH_STACK (pvm_make_##TYPELC (res, size));                     \
+  }                                                                         \
+  while (0)
+  
 /* Conversion instructions.
    ( TYPE -- TYPE RTYPE )  */
 #define PVM_CONVOP(TYPE, TYPEC, RTYPELC, RTYPEC)                             \
@@ -1876,6 +1891,62 @@ instruction neglu ()
   end
 end
 
+# Instruction: powi
+#
+# Perform the exponentiation of the integer at the under top of the
+# main stack.  The exponent is the unsigned integer at the top of the
+# stack.  If the exponent is 0, the result is 1.
+#
+# Stack: ( INT UINT -- INT UINT INT )
+
+instruction powi ()
+  code
+    PVM_POWOP (INT,int64_t,int,pk_ipow);
+  end
+end
+
+# Instruction: powiu
+#
+# Perform the exponentiation of the unsigned integer at the under top
+# of the main stack.  The exponent is the unsigned integer at the top
+# of the stack.  If the exponent is 0, the result is 1.
+#
+# Stack: ( UINT UINT -- UINT UINT UINT )
+
+instruction powiu ()
+  code
+    PVM_POWOP (UINT,uint64_t,uint,pk_upow);
+  end
+end
+
+# Instruction: powl
+#
+# Perform the exponentiation of the long at the under top of the
+# main stack.  The exponent is the unsigned integer at the top of the
+# stack.  If the exponent is 0, the result is 1.
+#
+# Stack: ( LONG UINT -- LONG UINT LONG )
+
+instruction powl ()
+  code
+    PVM_POWOP (LONG,int64_t,long,pk_ipow);
+  end
+end
+
+# Instruction: powlu
+#
+# Perform the exponentiation of the unsigned long at the under top
+# of the main stack.  The exponent is the unsigned integer at the top
+# of the stack.  If the exponent is 0, the result is 1.
+#
+# Stack: ( ULONG UINT -- ULONG UINT ULONG )
+
+instruction powlu ()
+  code
+    PVM_POWOP (ULONG,uint64_t,ulong,pk_upow);
+  end
+end
+
 
 ## Relational instructions
 
diff --git a/testsuite/poke.pkl/pow-1.pk b/testsuite/poke.pkl/pow-1.pk
new file mode 100644
index 0000000..30b11b2
--- /dev/null
+++ b/testsuite/poke.pkl/pow-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+/* { dg-command { .set obase 16 } } */
+
+defvar x = 2;
+
+/* { dg-command { x ** 10 } } */
+/* { dg-output "0x400" } */
+
+/* For constant folding:  */
+/* { dg-command { 2 ** 10 } } */
+/* { dg-output "\n0x400" } */
diff --git a/testsuite/poke.pkl/pow-2.pk b/testsuite/poke.pkl/pow-2.pk
new file mode 100644
index 0000000..a645af7
--- /dev/null
+++ b/testsuite/poke.pkl/pow-2.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+defvar x = 1;
+
+/* { dg-command { x ** 0 } } */
+/* { dg-output "1" } */
+
+/* For constant folding:  */
+/* { dg-command { 2 ** 0 } } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/pow-3.pk b/testsuite/poke.pkl/pow-3.pk
new file mode 100644
index 0000000..2a4b416
--- /dev/null
+++ b/testsuite/poke.pkl/pow-3.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+
+defvar x = 2;
+
+/* { dg-command { x ** -1 } } */
+/* { dg-output "0" } */
+
+/* For constant folding:  */
+/* { dg-command { 2 ** -1 } } */
+/* { dg-output "\n0" } */



reply via email to

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