On Sat, 26 Apr 2008 19:18:21 -0700
Geoffrey Broadwell (via RT) <[EMAIL PROTECTED]> wrote:

> # New Ticket Created by  Geoffrey Broadwell 
> # Please include the string:  [perl #53406]
> # in the subject line of all future correspondence about this issue. 
> # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=53406 >

> (I wish we could just insist that INTVAL be 64 bits everywhere, but
> alas that doesn't make a lot of sense for very memory-constrained
> environments.  Though those do get rarer by the day ....)

In the future, INTVAL will probably be 128 bits for some platforms.
I'd really like to see a set of fixed-width types (similar to what p5
has for pack and unpack), so you have the option of "native int" or
"exactly 32 bits" or whatever you need.

HUGEINTVAL is 64 bits on both linux-x86 and linux-amd64, so it
seems like a good start.  Here's an ugly patch that attempts to add it.

Problems with this patch:

1.  It probably won't work on win32-x64... I seem to recall someone
mentioning HUGEINTVAL is just 32 bits there.
2.  The patch adds a HUGEINTVAL to the PObj union, and would probably
require additional fixups all over parrot to be able to access the
resulting object.

The above makes me think we might be better off using a BigInt object
for this data.  But anyway, here's what I got.

Mark
Index: src/call_list.txt
===================================================================
--- src/call_list.txt   (revision 27216)
+++ src/call_list.txt   (working copy)
@@ -13,6 +13,7 @@
 # s - short
 # i - int
 # l - long
+# L - long long
 
 # NUM register stuff
 # N - FLOATVAL
@@ -34,6 +35,7 @@
 # 2 - pointer to short
 # 3 - pointer to int
 # 4 - pointer to long
+# 5 - pointer to long long
 
 # void stuff
 # v - void
Index: tools/build/nativecall.pl
===================================================================
--- tools/build/nativecall.pl   (revision 27216)
+++ tools/build/nativecall.pl   (working copy)
@@ -43,6 +43,8 @@
     3 => "int *",
     l => "long",
     4 => "long *",
+    L => "long long",
+    5 => "long long *",
     c => "char",
     s => "short",
     2 => "short *",
@@ -65,6 +67,8 @@
     3   => "int *",
     l   => "long",
     4   => "long *",
+    L   => "long long",
+    5   => "long long *",
     c   => "char",
     s   => "short",
     2   => "short *",
@@ -105,6 +109,8 @@
     3 => "int *",
     l => "long",
     4 => "long *",
+    L => "long long",
+    5 => "long long *",
     c => "char",
     s => "short",
     2 => "short *",
@@ -126,8 +132,10 @@
     i => "set_nci_I(interp, &st, return_data);",
     I => "set_nci_I(interp, &st, return_data);",
     l => "set_nci_I(interp, &st, return_data);",
+    L => "set_nci_L(interp, &st, return_data);",
     s => "set_nci_I(interp, &st, return_data);",
     c => "set_nci_I(interp, &st, return_data);",
+    5 => "set_nci_L(interp, &st, *return_data);",
     4 => "set_nci_I(interp, &st, *return_data);",
     3 => "set_nci_I(interp, &st, *return_data);",
     2 => "set_nci_I(interp, &st, *return_data);",
@@ -147,10 +155,12 @@
 my %func_call_assign = (
     p => "return_data = ",
     i => "return_data = ",
+    2 => "return_data = ",
     3 => "return_data = ",
-    2 => "return_data = ",
     4 => "return_data = ",
+    5 => "return_data = ",
     l => "return_data = ",
+    L => "return_data = ",
     c => "return_data = ",
     s => "return_data = ",
     f => "return_data = ",
@@ -173,6 +183,7 @@
     2   => "P",
     4   => "P",
     l   => "I",
+    L   => "L",
     c   => "I",
     s   => "I",
     f   => "N",
@@ -320,6 +331,18 @@
     return UVal_int(st->val);
 }
 
+static HUGEINTVAL
+get_nci_L(PARROT_INTERP, ARGMOD(call_state *st), int n)
+{
+    if (n >= st->src.n) {
+        real_exception(interp, NULL, E_ValueError,
+                    "too few arguments passed to NCI function");
+    }
+    Parrot_fetch_arg_nci(interp, st);
+
+    return UVal_hugeint(st->val);
+}
+
 static FLOATVAL
 get_nci_N(PARROT_INTERP, ARGMOD(call_state *st), int n)
 {
@@ -367,6 +390,7 @@
 #define GET_NCI_I(n) get_nci_I(interp, &st, n)
 #define GET_NCI_S(n) get_nci_S(interp, &st, n)
 #define GET_NCI_N(n) get_nci_N(interp, &st, n)
+#define GET_NCI_L(n) get_nci_L(interp, &st, n)
 #define GET_NCI_P(n) get_nci_P(interp, &st, n)
 
 /*
@@ -384,6 +408,17 @@
 }
 
 static void
+set_nci_L(PARROT_INTERP, ARGOUT(call_state *st), HUGEINTVAL val)
+{
+    Parrot_init_ret_nci(interp, st, "L");
+    if (st->dest.i < st->dest.n) {
+        UVal_hugeint(st->val) = val;
+        Parrot_convert_arg(interp, st);
+        Parrot_store_arg(interp, st);
+    }
+}
+
+static void
 set_nci_N(PARROT_INTERP, ARGOUT(call_state *st), FLOATVAL val)
 {
     Parrot_init_ret_nci(interp, st, "N");
@@ -454,6 +489,11 @@
         push @{$extra_preamble_ref}, "t_$temp_num = 
(long)GET_NCI_I($reg_num);";
         return "t_$temp_num";
     };
+    /L/ && do {
+        push @{$temps_ref},          "long long t_$temp_num;";
+        push @{$extra_preamble_ref}, "t_$temp_num = (long 
long)GET_NCI_I($reg_num);";
+        return "t_$temp_num";
+    };
     /I/ && do {
         push @{$temps_ref},          "INTVAL t_$temp_num;";
         push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_I($reg_num);";
@@ -464,6 +504,11 @@
         push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);";
         return "(long*)&PMC_int_val(t_$temp_num)";
     };
+    /5/ && do {
+        push @{$temps_ref},          "PMC *t_$temp_num;";
+        push @{$extra_preamble_ref}, "t_$temp_num = GET_NCI_P($reg_num);";
+        return "(long long*)&PMC_hugeint_val(t_$temp_num)";
+    };
     /s/ && do {
         push @{$temps_ref},          "short t_$temp_num;";
         push @{$extra_preamble_ref}, "t_$temp_num = 
(short)GET_NCI_I($reg_num);";
Index: include/parrot/pobj.h
===================================================================
--- include/parrot/pobj.h       (revision 27216)
+++ include/parrot/pobj.h       (working copy)
@@ -28,6 +28,7 @@
         INTVAL _int_val;                      /* or 2 intvals */
         INTVAL _int_val2;
     } _i;
+    HUGEINTVAL _hugeint_val;                 /* or one hugeintval */
     FLOATVAL _num_val;                       /* or one float */
     struct parrot_string_t * _string_val;    /* or a pointer to a string */
 } UnionVal;
@@ -37,6 +38,7 @@
 #define UVal_int(u)       (u)._i._int_val
 #define UVal_int2(u)      (u)._i._int_val2
 #define UVal_num(u)       (u)._num_val
+#define UVal_hugeint(u)   (u)._hugeint_val
 #define UVal_str(u)       (u)._string_val
 
 /* Parrot Object - base class for all others */

Reply via email to