mescc: Mescc-tools support: char foo[BAR] = {'a', 'b', 'c'}.

* 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.
This commit is contained in:
Jan Nieuwenhuizen 2017-11-27 19:51:18 +01:00
parent 49d01a46fa
commit 74c4197467
6 changed files with 145 additions and 7 deletions

View file

@ -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)))

View file

@ -818,6 +818,18 @@
(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
@ -1976,19 +1988,21 @@
(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))))
@ -2291,7 +2305,8 @@
(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))

View file

@ -101,6 +101,21 @@
`(,(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))))

View 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

View file

@ -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;
}

View 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