mescc: Support 64-bit immediates.

* module/mescc/M1.scm (hex2:address8, hex2:immediate8): New function.
(info->M1): Support 64-bit.
* module/mescc/compile.scm (convert-r0): FIXME!
* module/mescc/x86_64/as.scm (x86_64:value->r, x86_64:r->local,
x86_64:label->arg, x86_64:label->r, x86_64:r+value,
x86_64:r-cmp-value, x86_64:r-long-mem-add, x86_64:r-and): Support
64-bit immediates.
* lib/x86_64-mes/x86_64.M1: Likewise.
* scaffold/tests/17-compare-unsigned-char-le.c: Test it.
* scaffold/tests/17-compare-unsigned-short-le.c: Test it.
* build-aux/check-mescc.sh (tests): Run them.
This commit is contained in:
Jan Nieuwenhuizen 2018-10-06 14:51:57 +02:00
parent d0a1cc5096
commit 51085ba25c
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
10 changed files with 250 additions and 24 deletions

View file

@ -78,6 +78,9 @@ t
17-compare-unsigned-gt
17-compare-unsigned-le
17-compare-unsigned-lt
17-compare-unsigned-char-le
17-compare-unsigned-short-le
17-compare-unsigned-long-le
17-compare-and
17-compare-or
17-compare-and-or
@ -218,9 +221,12 @@ t
99-readdir
a0-call-trunc-char
a0-call-trunc-short
a0-call-trunc-int
"
broken="$broken
17-compare-unsigned-char-le
17-compare-unsigned-short-le
66-local-char-array
"

View file

@ -17,8 +17,8 @@
### along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
# reduced instruction set: rax, rdi (some rcx for shift, rdx for mul, div)
# 184 instructions
# TODO: $i64/$0x64 instructions are missing
# and r10 as i64 immediate helper
# 202 instructions
DEFINE add____$i32,%rax 4805
DEFINE add____$i32,%rbp 4881c5
DEFINE add____$i32,%rdi 4881c7
@ -30,6 +30,8 @@ DEFINE add____$i8,%rsp 4883c4
DEFINE add____$i8,(%rax) 8300
DEFINE add____$i8,(%rdi) 8307
DEFINE add____$i8,0x8(%rbp) 8345
DEFINE add____%r15,(%rax) 4c0138
DEFINE add____%r15,(%rdi) 4c013f
DEFINE add____%rax,%rax 4801c0
DEFINE add____%rbp,%rax 4801e8
DEFINE add____%rdi,%rax 4801f8
@ -43,12 +45,16 @@ DEFINE addl___$i8,(%rdi) 8307
DEFINE addw___$i8,(%rax) 668100
DEFINE addw___$i8,(%rdi) 668107
DEFINE and____$i32,%rdi 4881e7
DEFINE and____%r15,%rax 4c21f8
DEFINE and____%r15,%rdi 4c21ff
DEFINE and____%rdi,%rax 4821f8
DEFINE call32 e8
DEFINE call___*%rax ffd0
DEFINE call___*%rdi ffd7
DEFINE cmp____$i32,%rax 483d
DEFINE cmp____$i8,%rax 4883f8
DEFINE cmp____%r15,%rax 4c39f8
DEFINE cmp____%r15,%rdi 4c39ff
DEFINE hlt f4
DEFINE idiv___%rdi 48f7ff
DEFINE ja32 0f87
@ -68,17 +74,24 @@ DEFINE lahf 9f
DEFINE mov____$i32,%rax 48c7c0
DEFINE mov____$i32,%rdi 48c7c7
DEFINE mov____$i32,0x8(%rbp) c745
DEFINE mov____$i64,%r15 49bf
DEFINE mov____$i64,%rax 48a1
DEFINE mov____$i64,%rax 48b8
DEFINE mov____$i64,%rax 48b8
DEFINE mov____$i64,%rdi 48bf
DEFINE mov____%al,(%rdi) 8807
DEFINE mov____%al,0x32(%rbp) 8885
DEFINE mov____%al,0x8(%rbp) 8845
DEFINE mov____%ax,(%rdi) 668907
DEFINE mov____%ax,0x8(%rbp) 668945
DEFINE mov____%eax,%eax 89c0
DEFINE mov____%eax,%rax 89c0
DEFINE mov____%eax,(%rdi) 8907
DEFINE mov____%eax,0x32(%rbp) 8985
DEFINE mov____%eax,0x8(%rbp) 8945
DEFINE mov____%eax,0x8(%rbp) 8945
DEFINE mov____%edi,%edi 89ff
DEFINE mov____%edi,%rdi 89ff
DEFINE mov____%edi,0x32(%rbp) 89bd
DEFINE mov____%edi,0x8(%rbp) 897d
DEFINE mov____%esi,%eax 89f0
@ -145,8 +158,12 @@ DEFINE movzbq_%al,%rax 480fb6c0
DEFINE movzbq_%dil,%rdi 480fb6ff
DEFINE movzbq_(%rax),%rax 480fb600
DEFINE movzbq_(%rdi),%rdi 480fb63f
DEFINE movzlq_%eax,%rax 89c0
DEFINE movzlq_%edi,%rdi 89ff
DEFINE movzlq_(%rax),%rax 8b00
DEFINE movzlq_(%rdi),%rdi 8b3f
DEFINE movzwq_%ax,%rax 480fb7c0
DEFINE movzwq_%di,%rdi 480fb7ff
DEFINE movzwq_(%rax),%rax 480fb700
DEFINE movzwq_(%rdi),%rdi 480fb73f
DEFINE mul____%rdi 48f7e7
@ -159,6 +176,7 @@ DEFINE pop____%rbp 5d
DEFINE pop____%rdi 5f
DEFINE pop____%rdx 5a
DEFINE push___$i32 68
DEFINE push___%r15 4157
DEFINE push___%rax 50
DEFINE push___%rbp 55
DEFINE push___%rdi 57

View file

@ -53,6 +53,9 @@
(define (hex2:address o)
(string-append "&" o))
(define (hex2:address8 o)
(string-append "&" o " %0")) ;; FIXME: 64bit
(define (hex2:offset o)
(string-append "%" o))
@ -77,6 +80,14 @@
(if hex? (string-append "%0x" (dec->hex o))
(string-append "%" (number->string o))))
(define (hex2:immediate8 o)
(if hex? (string-append "%0x" (dec->hex (modulo o #x100000000))
" %0x" (if (< o 0) "-1"
(dec->hex (quotient o #x100000000))))
(string-append "%" (number->string (dec->hex (modulo o #x100000000)))
" %" (if (< o 0) "-1"
(number->string (dec->hex (quoteint o #x100000000)))))))
(define* (display-join o #:optional (sep ""))
(let loop ((o o))
(when (pair? o)
@ -110,7 +121,8 @@
((and (pair? o) (keyword? (car o)))
(pmatch o
;; FIXME
((#:address (#:string ,string)) (hex2:address (string->label `(#:string ,string))))
((#:address (#:string ,string))
(hex2:address (string->label `(#:string ,string))))
((#:address (#:address ,address)) (guard (string? address))
(hex2:address address))
((#:address (#:address ,global)) (guard (global? global))
@ -119,17 +131,38 @@
(hex2:address (function->string function)))
((#:address ,number) (guard (number? number))
(string-join (map text->M1 (int->bv32 number))))
((#:address8 (#:string ,string))
(hex2:address8 (string->label `(#:string ,string))))
((#:address8 (#:address ,address)) (guard (string? address))
(hex2:address8 address))
((#:address8 (#:address ,global)) (guard (global? global))
(hex2:address8 (global->string global)))
((#:address8 ,function) (guard (function? function))
(hex2:address8 (function->string function)))
((#:address8 ,number) (guard (number? number))
(string-join (map text->M1 (int->bv64 number))))
((#:string ,string)
(hex2:address (string->label o)))
((#:address ,address) (guard (string? address)) (hex2:address address))
((#:address ,address) (guard (string? address))
(hex2:address address))
((#:address ,global) (guard (global? global))
(hex2:address (global->string global)))
((#:address8 ,address) (guard (string? address))
(hex2:address8 address))
((#:address8 ,global) (guard (global? global))
(hex2:address8 (global->string global)))
((#:offset ,offset) (hex2:offset offset))
((#:offset1 ,offset1) (hex2:offset1 offset1))
((#:immediate ,immediate) (hex2:immediate immediate))
((#:immediate1 ,immediate1) (hex2:immediate1 immediate1))
((#:immediate2 ,immediate2) (hex2:immediate2 immediate2))
((#:immediate4 ,immediate4) (hex2:immediate4 immediate4))
((#:immediate8 ,immediate8) (hex2:immediate8 immediate8))
(_ (error "text->M1 no match o" o))))
((pair? o) (string-join (map text->M1 o)))))
(define (write-function o)

View file

@ -1397,15 +1397,23 @@
(cond ((and (= size 1) sign)
(wrap-as (as info 'byte-signed-r)))
((= size 1)
(wrap-as (as info 'byte-r)))
(wrap-as (as info 'byte-r))
;;(wrap-as (as info 'byte-signed-r))
)
((and (= size 2) sign)
(wrap-as (as info 'word-signed-r)))
((= size 2)
(wrap-as (as info 'word-r)))
(wrap-as (as info 'word-r))
;;(wrap-as (as info 'word-signed-r))
)
((and (> reg-size 4) (= size 4) sign)
(wrap-as (as info 'long-signed-r)))
((and (> reg-size 4) (= size 4))
(wrap-as (as info 'long-signed-r)))
;; for 17-unsigned-le
(wrap-as (as info 'long-signed-r)) ; huh, why not long-r?
;; for a0-call-trunc-int
;;(wrap-as (as info 'long-r))
)
(else '())))))
(define (binop->r info)

View file

@ -76,13 +76,17 @@
(define (x86_64:r->local info n)
(let ((r (get-r info))
(n (- 0 (* 8 n))))
`(,(if (< (abs n) #x80) `(,(string-append "mov____%" r ",0x8(%rbp)") (#:immediate1 ,n))
`(,(if (< (abs n) #x80)
`(,(string-append "mov____%" r ",0x8(%rbp)") (#:immediate1 ,n))
`(,(string-append "mov____%" r ",0x32(%rbp)") (#:immediate ,n))))))
(define (x86_64:value->r info v)
(or v (error "invalid value: x86_64:value->r: " v))
(let ((r (get-r info)))
`((,(string-append "mov____$i32,%" r) (#:immediate ,v)))))
(if (and (>= v 0)
(< v #xffffffff))
`((,(string-append "mov____$i32,%" r) (#:immediate ,v)))
`((,(string-append "mov____$i64,%" r) (#:immediate8 ,v))))))
;; AMD
(define (x86_64:ret . rest)
@ -122,7 +126,9 @@
(define (x86_64:label->arg info label i)
(let ((r0 (list-ref x86_64:registers (1+ i))))
`((,(string-append "mov____$i32,%" r0) (#:address ,label))))) ;; FIXME: 64 bits
(if (< (label v) #x80000000)
`((,(string-append "mov____$i32,%" r0) (#:address ,label)))
`((,(string-append "mov____$i64,%" r0) (#:address8 ,label))))))
;; traditional
(define (x86_64:r->arg info i)
@ -132,6 +138,11 @@
(define (x86_64:label->arg info label i)
`(("push___$i32" (#:address ,label))))
;; FIXME?
;; (define (x86_64:label->arg info label i)
;; `((,(string-append "mov____$i64,%r15") (#:address8 ,label))
;; ("push___%r15" (#:address ,label))))
(define (x86_64:r0+r1 info)
(let ((r1 (get-r1 info))
(r0 (get-r0 info)))
@ -168,7 +179,7 @@
(define (x86_64:r-mem-add info v)
(let ((r (get-r info)))
`(,(if (< (abs v) #x80) `(,(string-append "add____$i8,(%" r ")") (#:immediate1 ,v))
`(,(string-append "add____$i32,(%" r ")") (#:immediate ,v))))))
`(,(string-append "add____$i32,(%" r ")") (#:immediate ,v)))))) ;; FIXME 64bit
(define (x86_64:r-byte-mem-add info v)
(let ((r (get-r info)))
@ -183,11 +194,11 @@
(let ((n (- 0 (* 8 n))))
`((,(string-append "mov____%rbp,%" r))
,(if (< (abs n) #x80) `(,(string-append "add____$i8,%" r) (#:immediate1 ,n))
`(,(string-append "add____$i32,%" r) (#:immediate ,n)))))))
`(,(string-append "add____$i32,%" r) (#:immediate ,n))))))) ;; FIXME 64bit
(define (x86_64:label->r info label)
(let ((r (get-r info)))
`((,(string-append "mov____$i32,%" r) (#:address ,label)))))
`((,(string-append "mov____$i64,%" r) (#:address8 ,label)))))
(define (x86_64:r0->r1 info)
(let ((r0 (get-r0 info))
@ -293,11 +304,11 @@
(let ((n (- 0 (* 8 n))))
`(,(if (and (< (abs n) #x80)
(< (abs v) #x80)) `("add____$i8,0x8(%rbp)" (#:immediate1 ,n) (#:immediate1 ,v))
`("add____$i32,0x32(%rbp)" (#:immediate ,n) (#:immediate ,v))))))
`("add____$i32,0x32(%rbp)" (#:immediate ,n) (#:immediate ,v)))))) ;; FIXME: 64b
(define (x86_64:label-mem-add info label v)
`(,(if (< (abs v) #x80) `("add____$i8,0x32" (#:address ,label) (#:immediate1 ,v))
`("add____$i32,0x32" (#:address ,label) (#:immediate ,v)))))
`("add____$i32,0x32" (#:address ,label) (#:immediate ,v))))) ;; FIXME: 64b
(define (x86_64:nop info)
'(("nop")))
@ -460,8 +471,13 @@
(define (x86_64:r+value info v)
(let ((r (get-r info)))
`(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r) (#:immediate1 ,v))
`(,(string-append "add____$i32,%" r) (#:immediate ,v))))))
(cond ((< (abs v) #x80)
`((,(string-append "add____$i8,%" r) (#:immediate1 ,v))))
((< (abs v) #x80000000)
`((,(string-append "add____$i32,%" r) (#:immediate ,v))))
(else
`((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
(,(string-append "add____%r15,%" r)))))))
(define (x86_64:r0->r1-mem info)
(let ((r0 (get-r0 info))
@ -488,8 +504,14 @@
(define (x86_64:r-cmp-value info v)
(let ((r (get-r info)))
`(,(if (< (abs v) #x80) `(,(string-append "cmp____$i8,%" r) (#:immediate1 ,v))
`(,(string-append "cmp____$i32,%" r) (#:immediate ,v))))))
(cond ((< (abs v) #x80)
`((,(string-append "cmp____$i8,%" r) (#:immediate1 ,v))))
((and (>= v 0)
(< v #xffffffff))
`((,(string-append "cmp____$i32,%" r) (#:immediate ,v))))
(else
`(,(string-append "mov____$i64,%r15") (#:immediate8 ,v)
,(string-append "cmp____%r15,%" r))))))
(define (x86_64:push-register info r)
`((,(string-append "push___%" r))))
@ -535,7 +557,7 @@
(define (x86_64:r0+value info v)
(let ((r0 (get-r0 info)))
`(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r0) (#:immediate1 ,v))
`(,(string-append "add____$i32,%" r0) (#:immediate ,v))))))
`(,(string-append "add____$i32,%" r0) (#:immediate ,v)))))) ; FIXME: 64bit
(define (x86_64:value->r0 info v)
(let ((r0 (get-r0 info)))
@ -543,8 +565,14 @@
(define (x86_64:r-long-mem-add info v)
(let ((r (get-r info)))
`(,(if (< (abs v) #x80) `(,(string-append "addl___$i8,(%" r ")") (#:immediate1 ,v))
`(,(string-append "addl___$i32,(%" r ")") (#:immediate ,v))))))
(cond ((< (abs v) #x80)
`((,(string-append "addl___$i8,(%" r ")") (#:immediate1 ,v))))
((and (>= v 0)
(< v #xffffffff))
`((,(string-append "addl___$i32,(%" r ")") (#:immediate ,v))))
(else
`((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
(,(string-append "add____%r15,(%" r ")")))))))
(define (x86_64:byte-r->local+n info id n)
(let* ((n (+ (- 0 (* 8 id)) n))
@ -569,7 +597,11 @@
(define (x86_64:r-and info v)
(let ((r (get-r info)))
`((,(string-append "and____$i32,%" r) (#:immediate ,v)))))
(if (and (>= v 0)
(< v #xffffffff))
`((,(string-append "and____$i32,%" r) (#:immediate ,v)))
`((,(string-append "mov____$i64,%r15") (#:immediate8 ,v))
(,(string-append "and____%r15,%" r))))))
(define (x86_64:push-r0 info)
(let ((r0 (get-r0 info)))

View file

@ -31,7 +31,7 @@
(define (x86_64-info)
(make <info> #:types x86_64:type-alist #:registers x86_64:registers #:instructions x86_64:instructions))
(define x86_64:registers '("rax" "rdi" "rsi" "rdx" "rcx" "r8" "r9"))
(define x86_64:registers '("rax" "rdi" "rsi" "rdx" "rcx" "r8" "r9" "r10" "r11" "r12" "r13" "r14" "r15"))
(define x86_64:type-alist
`(("char" . ,(make-type 'signed 1 #f))
("short" . ,(make-type 'signed 2 #f))

View file

@ -0,0 +1,30 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
* GNU 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.
*
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
*/
int
main ()
{
unsigned char r = -2;
if (r <= -3)
return 1;
if (r <= (unsigned char)-1)
return 0;
return 2;
}

View file

@ -0,0 +1,30 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
* GNU 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.
*
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
*/
int
main ()
{
unsigned long r = -2;
if (r <= -3)
return 1;
if (r <= -1)
return 0;
return 2;
}

View file

@ -0,0 +1,30 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
* GNU 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.
*
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
*/
int
main ()
{
unsigned short r = -2;
if (r <= -3)
return 1;
if (r <= (unsigned short)-1)
return 0;
return 2;
}

View file

@ -0,0 +1,39 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
* GNU 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.
*
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libmes.h>
long
f (unsigned int x)
{
eputs ("x="); eputs (utoa (x)); eputs ("\n");
return x;
}
int
main ()
{
unsigned long x = -1;
x = f (x);
eputs ("x="); eputs (ultoa (x)); eputs ("\n");
if (x != 0xffffffff)
return 1;
return 0;
}