mescc: Tinycc support: Char and short sign extend.

* module/mes/as-i386.mes (i386:accu*n->local, i386:byte-accu->local+n,
  i386:word-accu->local+n): Remove.
  (i386:byte-accu, i386:signed-byte-accu, i386:word-accu,
  i386:signed-word-accu): New function.
* module/mes/as-i386.scm: Export them.
* module/language/c99/compiler.mes (accu->local+n-text): Simplify.
  (mem->accu, convert-accu): New function.
  (expr->accu): Use them.
* stage0/x86.M1 (mov____%al,0x32(%ebp), mov____%al,0x8(%ebp),
  mov____%ax,0x32(%ebp), mov____%ax,0x8(%ebp), movzbl_0x32(%ebp),%eax,
  movzbl_0x8(%ebp),%eax, movzwl_0x32(%ebp),%eax,
  movzwl_0x8(%ebp),%eax): Deprecate.
* scaffold/tests/7r-sign-extend.c: Test it.
* build-aux/check-mescc.sh (tests): Run it.
This commit is contained in:
Jan Nieuwenhuizen 2018-05-18 23:58:10 +02:00
parent 7f712e4555
commit 4faeece057
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
7 changed files with 214 additions and 109 deletions

View file

@ -115,6 +115,7 @@ t
7o-struct-pre-post
7p-struct-cast
7q-bit-field
7r-sign-extend
80-setjmp
81-qsort
82-define

View file

@ -148,33 +148,56 @@
(cons `(tag ,name) (make-type 'union size fields))))
(define i386:type-alist
`(("char" . ,(make-type 'builtin 1 #f))
("short" . ,(make-type 'builtin 2 #f))
("int" . ,(make-type 'builtin 4 #f))
("long" . ,(make-type 'builtin 4 #f))
;;("long long" . ,(make-type 'builtin 8 #f))
;;("long long int" . ,(make-type 'builtin 8 #f))
`(("char" . ,(make-type 'signed 1 #f))
("short" . ,(make-type 'signed 2 #f))
("int" . ,(make-type 'signed 4 #f))
("long" . ,(make-type 'signed 4 #f))
;;("long long" . ,(make-type 'signed 8 #f))
;;("long long int" . ,(make-type 'signed 8 #f))
("long long" . ,(make-type 'builtin 4 #f)) ;; FIXME
("long long int" . ,(make-type 'builtin 4 #f))
("long long" . ,(make-type 'signed 4 #f)) ;; FIXME
("long long int" . ,(make-type 'signed 4 #f))
("void" . ,(make-type 'builtin 1 #f))
("void" . ,(make-type 'void 1 #f))
;; FIXME sign
("unsigned char" . ,(make-type 'builtin 1 #f))
("unsigned short" . ,(make-type 'builtin 2 #f))
("unsigned short int" . ,(make-type 'builtin 2 #f))
("unsigned" . ,(make-type 'builtin 4 #f))
("unsigned int" . ,(make-type 'builtin 4 #f))
("unsigned long" . ,(make-type 'builtin 4 #f))
("unsigned char" . ,(make-type 'unsigned 1 #f))
("unsigned short" . ,(make-type 'unsigned 2 #f))
("unsigned short int" . ,(make-type 'unsigned 2 #f))
("unsigned" . ,(make-type 'unsigned 4 #f))
("unsigned int" . ,(make-type 'unsigned 4 #f))
("unsigned long" . ,(make-type 'unsigned 4 #f))
;; ("unsigned long long" . ,(make-type 'builtin 8 #f))
;; ("unsigned long long int" . ,(make-type 'builtin 8 #f))
("unsigned long long" . ,(make-type 'builtin 4 #f)) ;; FIXME
("unsigned long long int" . ,(make-type 'builtin 4 #f))
("unsigned long long" . ,(make-type 'unsigned 4 #f)) ;; FIXME
("unsigned long long int" . ,(make-type 'unsigned 4 #f))
("float" . ,(make-type 'builtin 4 #f))
("double" . ,(make-type 'builtin 8 #f))
("long double" . ,(make-type 'builtin 16 #f))))
("float" . ,(make-type 'float 4 #f))
("double" . ,(make-type 'float 8 #f))
("long double" . ,(make-type 'float 16 #f))))
(define (signed? o)
(eq? ((compose type:type ->type) o) 'signed))
(define (unsigned? o)
(eq? ((compose type:type ->type) o) 'unsigned))
(define (->size o)
(cond ((and (type? o) (eq? (type:type o) 'union))
(apply max (map (compose ->size cdr) (struct->fields o))))
((type? o) (type:size o))
((pointer? o) %pointer-size)
((c-array? o) (* (c-array:count o) ((compose ->size c-array:type) o)))
((local? o) ((compose ->size local:type) o))
((global? o) ((compose ->size global:type) o))
((bit-field? o) ((compose ->size bit-field:type) o))
((and (pair? o) (pair? (car o)) (bit-field? (cdar o))) ((compose ->size cdar) o))
;; FIXME
;; (#t
;; (stderr "o=~s\n" o)
;; (format (current-error-port) "->size: not a <type>: ~s\n" o)
;; 4)
(else (error "->size>: not a <type>:" o))))
(define (ast->type o info)
(define (type-helper o info)
@ -617,11 +640,8 @@
(let* ((type (local:type o)))
(cond ((or (c-array? type)
(structured-type? type)) (wrap-as (i386:local-ptr->accu (local:id o))))
(else (let ((size (->size o)))
(wrap-as (case size
((1) (i386:byte-local->accu (local:id o)))
((2) (i386:word-local->accu (local:id o)))
(else (i386:local->accu (local:id o))))))))))
(else (append (wrap-as (i386:local->accu (local:id o)))
(convert-accu type))))))
(define (global->accu o)
(let ((type (global:type o)))
@ -663,15 +683,7 @@
(wrap-as (i386:value->accu v)))
(define (accu->local+n-text local n)
(let* ((type (local:type local))
(ptr (->rank local))
(size (if (= ptr -1) ((compose type:size local:type) local)
4))
(id (local:id local)))
(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))))))
(let ((id (local:id local))) (wrap-as (i386:accu->local+n id n))))
(define (accu->ident info)
(lambda (o)
@ -1002,12 +1014,8 @@
((array-ref ,index ,array)
(let* ((info (expr->accu* o info))
(size (ast->size o info)))
(append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
((2) (i386:word-mem->accu))
((4) (i386:mem->accu))
(else '()))))))
(type (ast->type o info)))
(append-text info (mem->accu type))))
((d-sel ,field ,struct)
(let* ((info (expr->accu* o info))
@ -1016,11 +1024,7 @@
(size (->size type))
(array? (c-array? type)))
(if array? info
(append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
((2) (i386:word-mem->accu))
((4) (i386:mem->accu))
(else '())))))))
(append-text info (mem->accu type)))))
((i-sel ,field ,struct)
(let* ((info (expr->accu* o info))
@ -1029,20 +1033,12 @@
(size (->size type))
(array? (c-array? type)))
(if array? info
(append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
((2) (i386:word-mem->accu))
((4) (i386:mem->accu))
(else '())))))))
(append-text info (mem->accu type)))))
((de-ref ,expr)
(let* ((info (expr->accu expr info))
(size (ast->size o info)))
(append-text info (wrap-as (case size
((1) (i386:byte-mem->accu))
((2) (i386:word-mem->accu))
((4) (i386:mem->accu))
(else '()))))))
(type (ast->type o info)))
(append-text info (mem->accu type))))
((fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list))
(if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list)))) ;; FIXME
@ -1252,7 +1248,9 @@
info))
((cast ,type ,expr)
(expr->accu expr info))
(let ((info (expr->accu expr info))
(type (ast->type o info)))
(append-text info (convert-accu type))))
((assn-expr (de-ref (post-inc (p-expr (ident ,name)))) (op ,op) ,b)
(let* ((info (expr->accu `(assn-expr (de-ref (p-expr (ident ,name))) (op ,op) ,b) info))
@ -1349,6 +1347,28 @@
(if (null? (.post info)) info
(append-text (clone info #:post '()) (.post info))))))
(define (mem->accu type)
(let ((size (->size type)))
(case size
((1) (append (wrap-as (i386:byte-mem->accu)) (convert-accu type)))
((2) (append (wrap-as (i386:word-mem->accu)) (convert-accu type)))
((4) (wrap-as (i386:mem->accu)))
(else '()))))
(define (convert-accu type)
(if (not (type? type)) '()
(let ((sign (signed? type))
(size (->size type)))
(cond ((and (= size 1) sign)
(wrap-as (i386:signed-byte-accu)))
((= size 1)
(wrap-as (i386:byte-accu)))
((and (= size 2) sign)
(wrap-as (i386:signed-word-accu)))
((= size 1)
(wrap-as (i386:word-accu)))
(else '())))))
(define (expr->base o info)
(let* ((info (append-text info (wrap-as (i386:push-accu))))
(info (expr->accu o info))
@ -1548,23 +1568,6 @@
decls))
(_ (error "struct-field: not supported: " o)))))
(define (->size o)
(cond ((and (type? o) (eq? (type:type o) 'union))
(apply max (map (compose ->size cdr) (struct->fields o))))
((type? o) (type:size o))
((pointer? o) %pointer-size)
((c-array? o) (* (c-array:count o) ((compose ->size c-array:type) o)))
((local? o) ((compose ->size local:type) o))
((global? o) ((compose ->size global:type) o))
((bit-field? o) ((compose ->size bit-field:type) o))
((and (pair? o) (pair? (car o)) (bit-field? (cdar o))) ((compose ->size cdar) o))
;; FIXME
;; (#t
;; (stderr "o=~s\n" o)
;; (format (current-error-port) "->size: not a <type>: ~s\n" o)
;; 4)
(else (error "->size>: not a <type>:" o))))
(define (local-var? o) ;; formals < 0, locals > 0
(positive? (local:id o)))

View file

@ -226,8 +226,8 @@
(define (->type o)
(cond ((type? o) o)
((bit-field? o) o)
((pointer? o) (pointer:type o))
((c-array? o) (c-array:type o))
((pointer? o) ((compose ->type pointer:type) o))
((c-array? o) ((compose ->type c-array:type) o))
((and (pair? o) (eq? (car o) 'tag)) o)
;; FIXME
(#t

View file

@ -114,16 +114,6 @@
`(,(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))))
@ -156,18 +146,6 @@
,(if (< (abs n) #x80) `("add____$i8,%eax" (#:immediate1 ,n))
`("add____$i32,%eax" (#:immediate ,n))))))
(define (i386:byte-local->accu n)
(or n (error "invalid value: byte-local->accu: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("movzbl_0x8(%ebp),%eax" (#:immediate1 ,n))
`("movzbl_0x32(%ebp),%eax" (#:immediate ,n))))))
(define (i386:word-local->accu n)
(or n (error "invalid value: word-local->accu: " n))
(let ((n (- 0 (* 4 n))))
`(,(if (< (abs n) #x80) `("movzwl_0x8(%ebp),%eax" (#:immediate1 ,n))
`("movzwl_0x32(%ebp),%eax" (#:immediate ,n))))))
(define (i386:byte-local->base n)
(or n (error "invalid value: byte-local->base: " n))
(let ((n (- 0 (* 4 n))))
@ -542,3 +520,15 @@
(define (i386:accu<->stack)
'(("xchg___%eax,(%esp)"))) ; xchg %eax,(%esp)
(define (i386:byte-accu)
'(("movzbl_%al,%eax")))
(define (i386:signed-byte-accu)
'(("movsbl_%al,%eax")))
(define (i386:word-accu)
'(("movzwl_%ax,%eax")))
(define (i386:signed-word-accu)
'(("movswl_%ax,%eax")))

View file

@ -45,8 +45,6 @@
i386:accu->label
i386:accu->local
i386:accu->local+n
i386:byte-accu->local+n
i386:word-accu->local+n
i386:accu->local+n
i386:accu-and
i386:accu-and-base
@ -81,8 +79,6 @@
i386:byte-base->accu-mem+n
i386:byte-base-mem->accu
i386:byte-base-sub
i386:byte-local->accu
i386:word-local->accu
i386:byte-local->base
i386:byte-mem->accu
i386:word-mem->accu
@ -153,6 +149,10 @@
i386:l?->accu
i386:le?->accu
i386:z->accu
i386:byte-accu
i386:signed-byte-accu
i386:word-accu
i386:signed-word-accu
))
(cond-expand

View file

@ -0,0 +1,104 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) 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/>.
*/
char global_c = -1;
struct foo {char type;};
int
main ()
{
{
char c = -1;
int i = c;
if (i != -1)
return 1;
}
{
int i = global_c;
if (i != -1)
return 2;
}
{
char c = -1;
int ints[2] = {c, 0};
if (ints[0] != -1)
return 3;
}
{
char c = -1;
int i = c;
if (i != -1)
return 4;
}
{
char c = -1;
int i = c;
if (i != -1)
return 5;
}
{
char a[2] = {-1, -129};
int i = a[0];
if (i != -1)
return 6;
if (a[0] != -1)
return 7;
}
{
struct foo f = {-1};
int i = f.type;
if (i != -1)
return 8;
struct foo *g = &f;
i = g->type;
if (i != -1)
return 9;
}
{
char c = -1;
char *p = &c;
int i = *p;
if (i != -1)
return 10;
}
{
int i = -129;
i = (char)i;
if (i != 127)
return 11;
}
{
unsigned char b = -129;
int i = b;
if (i != 127)
return 12;
}
return 0;
}

View file

@ -79,13 +79,9 @@ 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
@ -141,21 +137,22 @@ DEFINE mov____0x8(%ebp),%ebx 8b5d
DEFINE mov____0x8(%ebp),%ecx 8b4d
DEFINE mov____0x8(%ebp),%edx 8b55
DEFINE mov____0x8(%ebp),%esp 8b65
DEFINE movsbl_%al,%eax 0fbec0
DEFINE movswl_%ax,%eax 0fbfc0
DEFINE movzbl_%al,%eax 0fb6c0
DEFINE movzbl_%al,%eax 0fb6c0
DEFINE movzbl_%dl,%edx 0fb6d2
DEFINE movzbl_(%eax),%eax 0fb600
DEFINE movzbl_(%eax),%edx 0fb610
DEFINE movzbl_(%edx),%edx 0fb612
DEFINE movzbl_0x32(%eax),%eax 0fb680
DEFINE movzbl_0x32(%ebp),%eax 0fb685
DEFINE movzbl_0x8(%eax),%eax 0fb640
DEFINE movzbl_0x8(%ebp),%eax 0fb645
DEFINE movzbl_0x8(%ebp),%edx 0fb655
DEFINE movzwl_%ax,%eax 0fb7c0
DEFINE movzwl_(%eax),%eax 0fb700
DEFINE movzwl_0x32(%eax),%eax 0fb780
DEFINE movzwl_0x32(%ebp),%eax 0fb785
DEFINE movzwl_0x8(%eax),%eax 0fb740
DEFINE movzwl_0x8(%ebp),%eax 0fb745
DEFINE mul____%edx f7e2
DEFINE nop 90
DEFINE not____%eax f7d0
@ -199,6 +196,16 @@ DEFINE xor____%ecx,%ecx 31c9
DEFINE xor____%edx,%eax 31d0
DEFINE xor____%edx,%edx 31d2
# Deprecated. Remove after 0.14 release.
DEFINE mov____%al,0x32(%ebp) 8885
DEFINE mov____%al,0x8(%ebp) 8845
DEFINE mov____%ax,0x32(%ebp) 668985
DEFINE mov____%ax,0x8(%ebp) 668945
DEFINE movzbl_0x32(%ebp),%eax 0fb685
DEFINE movzbl_0x8(%ebp),%edx 0fb655
DEFINE movzwl_0x8(%ebp),%eax 0fb745
DEFINE movzwl_0x8(%ebp),%eax 0fb745
DEFINE SYS_exit 01000000
DEFINE SYS_read 03000000
DEFINE SYS_write 04000000