mescc: Mescc-tools support: char foo[BAR] = {'a', 'b', 'c'}.
authorJan Nieuwenhuizen <janneke@gnu.org>
Mon, 27 Nov 2017 18:51:18 +0000 (19:51 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 27 Nov 2017 18:51:18 +0000 (19:51 +0100)
* stage0/x86.M1 (mov____%al,0x8(%ebp), mov____%al,0x32(%ebp),
  mov____%ax,0x8(%ebp), mov____%ax,0x32(%ebp)): New define.
* module/mes/as-i386.mes (i386:accu->local+n,i386:byte-accu->local+n,
  i386:word-accu->local+n): New function.
* module/language/c99/compiler.mes (accu->local+n): New function.
  (initzer->data): Return char as single byte.
  (decl->info): Support char foo[BAR] = {'a', 'b', 'c'}.
* scaffold/tests/66-local-char-array.c: Test it.
* make.scm (add-scaffold-test): Build it.

make.scm
module/language/c99/compiler.mes
module/mes/as-i386.mes
module/mes/as-i386.scm
scaffold/tests/66-local-char-array.c [new file with mode: 0644]
stage0/x86.M1

index e8419c529d7d4dbc66e2fe6b9e585aba498fe148..841fbec5d2da43478b0b1b2bb9796d72c6a57709 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -218,7 +218,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "61-array"
    "63-struct-cell"
    "64-make-cell"
-   "65-read"))
+   "65-read"
+   "66-local-char-array"))
 
 (add-target (group "check-scaffold-tests/6" #:dependencies (filter (target-prefix? "check-scaffold/tests/6") %targets)))
 
index e11e99ad4380c72a21f450a07aef201c5b8ef00b..54df5a56ddb31519c42aa75d2b32e9d2b81e1d7c 100644 (file)
 (define (accu->base-mem*n info n)
   (append-text info (accu->base-mem*n- info n)))
 
+(define (accu->local+n info local)
+  (lambda (n)
+    (let* ((type (local:type local))
+           (ptr (local:pointer local))
+           (size (if (= ptr -2) (ast-type->size info type)
+                     4))
+           (id (local:id local)))
+      (append-text info (wrap-as (case size
+                                   ((1) (i386:byte-accu->local+n id n))
+                                   ((2) (i386:word-accu->local+n id n))
+                                   (else (i386:accu->local+n id n))))))))
+
 (define (expr->accu* info)
   (lambda (o)
     (pmatch o
                 (info (append-text info (ast->comment o)))
                 (globals (append globals initzer-globals))
                 (info (clone info #:globals globals))
-                (size 4)
+                (type-size (if (<= pointer 0) (ast-type->size info type)
+                               4))
                 (count (expr->number info count))
-                (size (* count size)))
+                (size (* count type-size)))
            (if (.function info)
                (let* ((local (car (add-local locals name type 1)))
                       (local (pke "3local: " (make-local-entry name type pointer (+ (local:id (cdr local)) -1 (quotient (+ size 3) 4)))))
                       (locals (cons local locals))
+                      (local (cdr local))
                       (info (clone info #:locals locals))
-                      (info (let loop ((info info) (initzers initzers) (id (local:id (cdr local))))
+                      (info (let loop ((info info) (initzers initzers) (n 0))
                               (if (null? initzers) info
                                   (let* ((info ((initzer->accu info) (car initzers)))
-                                         (info (append-text info (wrap-as (i386:accu->local id)))))
-                                    (loop info (cdr initzers) (1- id)))))))
+                                         (info ((accu->local+n info local) n)))
+                                    (loop info (cdr initzers) (+ n type-size)))))))
                  info)
                (let* ((global (pke "3global:" (make-global-entry name type pointer (append-map (initzer->data info) initzers))))
                       (globals (append globals (list global))))
 (define (initzer->data info)
   (lambda (o)
     (pmatch o
-      ((initzer (p-expr (char ,char)))  (int->bv32 (char->integer (string-ref char 0))))
+      ((initzer (p-expr (char ,char))) (int->bv32 (char->integer (string-ref char 0))))
+      ((initzer (p-expr (char ,char))) (list (char->integer (string-ref char 0))))
       ((initzer (p-expr (string ,string))) `((#:string ,string) #f #f #f))
       ((initzer (p-expr (string . ,strings))) `((#:string ,(string-join strings "")) #f #f #f))
       ((initzer (initzer-list . ,initzers)) (append-map (initzer->data info) initzers))
index 30baed2321f9089459d14726e880ba7cc42ef7ed..c280fdd8a83275b298f1c9899a10120eb6de62b9 100644 (file)
     `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
            `("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
 
+(define (i386:accu->local+n id n)
+  (let ((n (+ (- 0 (* 4 id)) n)))
+    `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%ebp)" (#:immediate1 ,n))
+           `("mov____%eax,0x32(%ebp)" (#:immediate ,n))))))
+
+(define (i386:byte-accu->local+n id n)
+  (let ((n (+ (- 0 (* 4 id)) n)))
+    `(,(if (< (abs n) #x80) `("mov____%al,0x8(%ebp)" (#:immediate1 ,n))
+           `("mov____%al,0x32(%ebp)" (#:immediate ,n))))))
+
+(define (i386:word-accu->local+n id n)
+  (let ((n (+ (- 0 (* 4 id)) n)))
+    `(,(if (< (abs n) #x80) `("mov____%ax,0x8(%ebp)" (#:immediate1 ,n))
+           `("mov____%ax,0x32(%ebp)" (#:immediate ,n))))))
+
 (define (i386:accu*n->local i n)
   (or n (error "invalid value: accu->local: " n))
   (let ((o (- 0 (* 4 i))))
index 9649194bcf52f092dcf458c77da6f80bdd34db25..ea6dd7e8ff809147206c01758292800fdafbbb4b 100644 (file)
@@ -44,6 +44,9 @@
             i386:word-accu->base-mem+n
             i386:accu->label
             i386:accu->local
+            i386:accu->local+n
+            i386:byte-accu->local+n
+            i386:word-accu->local+n
             i386:accu-and-base
             i386:accu-base
             i386:accu-cmp-value
diff --git a/scaffold/tests/66-local-char-array.c b/scaffold/tests/66-local-char-array.c
new file mode 100644 (file)
index 0000000..958a7db
--- /dev/null
@@ -0,0 +1,100 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "30-test.i"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+void *
+memset (void *s, int c, size_t n)
+{
+  char *p = s;
+  while (n--) *p++ = c;
+  return s;
+}
+
+void *
+calloc (size_t nmemb, size_t size)
+{
+  size_t count = nmemb * size;
+  void *p = malloc (count);
+  memset (p, 0, count);
+  return p;
+}
+
+/* {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'} */
+char LittleEndian_table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
+
+char* LittleEndian(unsigned value, char* c, int Number_of_bytes)
+{
+  char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
+  
+  switch(Number_of_bytes)
+    {
+    case 4:
+      {
+        c[6] = table[value >> 28];
+        c[7] = table[(value >> 24)% 16];
+      }
+    case 3:
+      {
+        c[4] = table[(value >> 20)% 16];
+        c[5] = table[(value >> 16)% 16];
+      }
+    case 2:
+      {
+        c[2] = table[(value >> 12)% 16];
+        c[3] = table[(value >> 8)% 16];
+      }
+    case 1:
+      {
+        c[0] = table[(value >> 4)% 16];
+        c[1] = table[value % 16];
+        break;
+      }
+    default:
+      {
+        //fprintf(stderr, "Recieved invalid number of bytes in LittleEndian %d\n", Number_of_bytes);
+        exit(EXIT_FAILURE);
+      }
+    }
+  return c;
+}
+
+int
+test ()
+{
+  char table[3] = {'0', '1', '2'};
+
+  char *s;
+  s = calloc (10, sizeof (char));
+  eputs ("2="); eputs (LittleEndian (2, s, 1)); eputs ("\n");
+  if (strcmp (s, "02")) return 1;
+
+  eputs ("8="); eputs (LittleEndian (8, s, 2)); eputs ("\n");
+  if (strcmp (s, "0800")) return 1;
+  
+  eputs ("16="); eputs (LittleEndian (16, s, 4)); eputs ("\n");
+  if (strcmp (s, "10000000")) return 1;
+
+  return 0;
+}
index f1554a2297f08b800af07eb39ed3161aa0d36e45..c6f74522f479a6d05649978b9d92b987b99dfee0 100644 (file)
@@ -77,9 +77,13 @@ DEFINE mov____$i32,0x32 c705
 DEFINE mov____$i32,0x8(%eax) c740
 DEFINE mov____$i32,0x8(%ebp) c745
 DEFINE mov____%al,(%edx) 8802
+DEFINE mov____%al,0x32(%ebp) 8885
+DEFINE mov____%al,0x8(%ebp) 8845
 DEFINE mov____%al,0x8(%edx) 8842
 DEFINE mov____%ax,(%edx) 668902
+DEFINE mov____%ax,0x32(%ebp) 668985
 DEFINE mov____%ax,0x32(%edx) 668982
+DEFINE mov____%ax,0x8(%ebp) 668945
 DEFINE mov____%ax,0x8(%edx) 668942
 DEFINE mov____%dl,(%eax) 8810
 DEFINE mov____%dl,0x8(%eax) 8850