[PATCH] cgen: partial support for 64-bit wide fields in 32-bit hosts

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] cgen: partial support for 64-bit wide fields in 32-bit hosts

Jose E. Marchesi-2
Hi people!

This patch adds support for having 64-bit wide fields working in
32-bit hosts.  This is not a complete solution, but it is enough for
supporting:

- Defining a 64-bit h-sint in your .cpu file.
- Using that hardware to define an operand featuring as index a
  64-bit wide multi-ifield.

Note that the current CGEN support in binutils provides
cgen_{extract,insert}_normal functions that get `long' values, hence
the need for the operand to be indexed by a multi-ifield.

This is used by an eBPF binutils port which I will be upstreaming this
week.  All other CGEN-based ports currently in binutils are not
impacted by this change.

Eventually, we shall make the "portable" INT/UINT modes (and
associated hardwares s-int/s-uint) to work properly in 32-bit hosts
when holding 64-bit values.

I have a tentative large patch attempting that, including changes in
binutils's opcodes CGEN support, that I will send for comments soon,
but in the meanwhile I would really appreciate if this gets into cgen.
(Without this patch applied, the eBPF assembler doesn't work properly
in 32-bit hosts.)

Thanks!

2019-05-14  Jose E. Marchesi  <[hidden email]>

        * opcodes.scm (gen-ifield-default-type): Use int64_t for fields
        wider than 32-bits.
        (/gen-parse-number): Use u?int64_t for > 32-bit modes.
        (gen-ifield-value-decl): Fix call to gen-ifield-default-type.
        (<ifield>, gen-insert): Likewise.
        (<ifield>, gen-extract): Likewise.
        * opc-asmdis.scm (char): Likewise.
---
 ChangeLog      | 10 ++++++++++
 opc-asmdis.scm |  2 +-
 opcodes.scm    | 21 +++++++++++++--------
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9add333..058fc6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-14  Jose E. Marchesi  <[hidden email]>
+
+ * opcodes.scm (gen-ifield-default-type): Use int64_t for fields
+ wider than 32-bits.
+ (/gen-parse-number): Use u?int64_t for > 32-bit modes.
+ (gen-ifield-value-decl): Fix call to gen-ifield-default-type.
+ (<ifield>, gen-insert): Likewise.
+ (<ifield>, gen-extract): Likewise.
+ * opc-asmdis.scm (char): Likewise.
+
 2019-01-01  Alan Modra  <[hidden email]>
 
  * utils.scm: Update emitted copyright dates.
diff --git a/opc-asmdis.scm b/opc-asmdis.scm
index 6bdd44c..b268bf5 100644
--- a/opc-asmdis.scm
+++ b/opc-asmdis.scm
@@ -32,7 +32,7 @@ const char *
 {
   const char * errmsg = NULL;
   /* Used by scalar operands that still need to be parsed.  */
-  " (gen-ifield-default-type) " junk ATTRIBUTE_UNUSED;
+  " (gen-ifield-default-type #f) " junk ATTRIBUTE_UNUSED;
 
   switch (opindex)
     {
diff --git a/opcodes.scm b/opcodes.scm
index f24b368..66ce9dd 100644
--- a/opcodes.scm
+++ b/opcodes.scm
@@ -73,9 +73,10 @@
 
 ; Default type of variable to use to hold ifield value.
 
-(define (gen-ifield-default-type)
-  ; FIXME: Use long for now.
-  "long"
+(define (gen-ifield-default-type f)
+  (if (and f (> (mode:bits (ifld-mode f)) 32))
+      "int64_t"
+      "long")
 )
 
 ; Given field F, return a C definition of a variable big enough to hold
@@ -83,7 +84,7 @@
 
 (define (gen-ifield-value-decl f)
   (gen-obj-sanitize f (string-append "  "
-     (gen-ifield-default-type)
+     (gen-ifield-default-type f)
      " " (gen-sym f) ";\n"))
 )
 
@@ -113,7 +114,7 @@
       (if need-extra?
   (string-append "      {\n"
  "        "
- (gen-ifield-default-type)
+ (gen-ifield-default-type self)
  " value = " varname ";\n")
   "")
       (if encode
@@ -175,7 +176,7 @@
      (string-append
       (if need-extra?
   (string-append "      {\n        "
- (gen-ifield-default-type)
+ (gen-ifield-default-type self)
  " value;\n  ")
   "")
       "      length = "
@@ -372,8 +373,12 @@
    ; This is to pacify gcc 4.x which will complain about
    ; incorrect signed-ness of pointers passed to functions.
    (case (obj:name mode)
- ((QI HI SI INT) "(long *)")
- ((BI UQI UHI USI UINT) "(unsigned long *)")
+     ((QI HI SI DI INT)
+      (if (> (mode:bits mode) 32) "(int64_t *)" "(long *)"))
+     ((BI UQI UHI USI UDI UINT)
+      (if (> (mode:bits mode) 32) "(uint64_t *)" "(unsigned long *)"))
+     (else (error "unsupported (as yet) mode for parsing"
+                  (obj:name mode)))
    )
    " (& " result-var-name
    "));\n"
--
2.11.0