mescc: Support negative divide.
* module/mescc/i386/as.scm (i386:r0/r1, i386:r0%r1): Support negative divide. * module/mescc/x86_64/as.scm (x86_64:r0/r1, x86_64:r0%r1): Likewise. * lib/x86-mes/x86.M1: Likewise. * lib/x86_64-mes/x86_64.M1: Likewise. * scaffold/tests/a0-math-divide-signed-negative.c: Test it. * build-aux/check-mescc.sh (tests): Run it.
This commit is contained in:
parent
d862f1eceb
commit
3dd4da895f
|
@ -222,6 +222,7 @@ t
|
||||||
a0-call-trunc-char
|
a0-call-trunc-char
|
||||||
a0-call-trunc-short
|
a0-call-trunc-short
|
||||||
a0-call-trunc-int
|
a0-call-trunc-int
|
||||||
|
a0-math-divide-signed-negative
|
||||||
a1-global-no-align
|
a1-global-no-align
|
||||||
a1-global-no-clobber
|
a1-global-no-clobber
|
||||||
"
|
"
|
||||||
|
@ -231,6 +232,7 @@ broken="$broken
|
||||||
17-compare-unsigned-short-le
|
17-compare-unsigned-short-le
|
||||||
66-local-char-array
|
66-local-char-array
|
||||||
a0-call-trunc-int
|
a0-call-trunc-int
|
||||||
|
a0-math-divide-signed-negative
|
||||||
"
|
"
|
||||||
|
|
||||||
# gcc not supported
|
# gcc not supported
|
||||||
|
|
|
@ -49,6 +49,7 @@ DEFINE and____%ebx,%eax 21d8
|
||||||
DEFINE call32 e8
|
DEFINE call32 e8
|
||||||
DEFINE call___*%eax ffd0
|
DEFINE call___*%eax ffd0
|
||||||
DEFINE call___*%ebx ffd3
|
DEFINE call___*%ebx ffd3
|
||||||
|
DEFINE cltd 99
|
||||||
DEFINE cmp____$0x32,%eax 3d
|
DEFINE cmp____$0x32,%eax 3d
|
||||||
DEFINE cmp____$i32,%eax 3d
|
DEFINE cmp____$i32,%eax 3d
|
||||||
DEFINE cmp____$i8,%eax 83f8
|
DEFINE cmp____$i8,%eax 83f8
|
||||||
|
|
|
@ -56,6 +56,7 @@ DEFINE cmp____$i32,%rax 483d
|
||||||
DEFINE cmp____$i8,%rax 4883f8
|
DEFINE cmp____$i8,%rax 4883f8
|
||||||
DEFINE cmp____%r15,%rax 4c39f8
|
DEFINE cmp____%r15,%rax 4c39f8
|
||||||
DEFINE cmp____%r15,%rdi 4c39ff
|
DEFINE cmp____%r15,%rdi 4c39ff
|
||||||
|
DEFINE cqto 4899
|
||||||
DEFINE hlt f4
|
DEFINE hlt f4
|
||||||
DEFINE idiv___%rdi 48f7ff
|
DEFINE idiv___%rdi 48f7ff
|
||||||
DEFINE ja32 0f87
|
DEFINE ja32 0f87
|
||||||
|
|
|
@ -79,10 +79,14 @@
|
||||||
(cons `(tag ,name) (make-type 'union size fields))))
|
(cons `(tag ,name) (make-type 'union size fields))))
|
||||||
|
|
||||||
(define (signed? o)
|
(define (signed? o)
|
||||||
(eq? ((compose type:type ->type) o) 'signed))
|
(let ((type (->type o)))
|
||||||
|
(cond ((type? type) (eq? (type:type type) 'signed))
|
||||||
|
(else #f))))
|
||||||
|
|
||||||
(define (unsigned? o)
|
(define (unsigned? o)
|
||||||
(eq? ((compose type:type ->type) o) 'unsigned))
|
(let ((type (->type o)))
|
||||||
|
(cond ((type? type) (eq? (type:type type) 'unsigned))
|
||||||
|
(else #t))))
|
||||||
|
|
||||||
(define (->size o info)
|
(define (->size o info)
|
||||||
(cond ((and (type? o) (eq? (type:type o) 'union))
|
(cond ((and (type? o) (eq? (type:type o) 'union))
|
||||||
|
@ -792,7 +796,7 @@
|
||||||
(info (append-text info (wrap-as (append
|
(info (append-text info (wrap-as (append
|
||||||
(as info 'value->r size)
|
(as info 'value->r size)
|
||||||
(as info 'swap-r0-r1)
|
(as info 'swap-r0-r1)
|
||||||
(as info 'r0/r1)))))
|
(as info 'r0/r1 #f)))))
|
||||||
(info (append-text info (wrap-as (append (as info 'swap-r0-r1)))))
|
(info (append-text info (wrap-as (append (as info 'swap-r0-r1)))))
|
||||||
(free-register info))
|
(free-register info))
|
||||||
info)))
|
info)))
|
||||||
|
@ -1177,7 +1181,7 @@
|
||||||
;; FIXME: c&p 792
|
;; FIXME: c&p 792
|
||||||
(let* ((info (allocate-register info))
|
(let* ((info (allocate-register info))
|
||||||
(info (append-text info (wrap-as (append (as info 'value->r size)
|
(info (append-text info (wrap-as (append (as info 'value->r size)
|
||||||
(as info 'r0/r1)))))
|
(as info 'r0/r1 #f)))))
|
||||||
(info (free-register info)))
|
(info (free-register info)))
|
||||||
info)))
|
info)))
|
||||||
(let* ((info (expr->register b info))
|
(let* ((info (expr->register b info))
|
||||||
|
@ -1199,8 +1203,11 @@
|
||||||
((bitwise-xor ,a ,b) ((binop->r info) a b 'r0-xor-r1))
|
((bitwise-xor ,a ,b) ((binop->r info) a b 'r0-xor-r1))
|
||||||
((lshift ,a ,b) ((binop->r info) a b 'r0<<r1))
|
((lshift ,a ,b) ((binop->r info) a b 'r0<<r1))
|
||||||
((rshift ,a ,b) ((binop->r info) a b 'r0>>r1))
|
((rshift ,a ,b) ((binop->r info) a b 'r0>>r1))
|
||||||
((div ,a ,b) ((binop->r info) a b 'r0/r1))
|
((div ,a ,b)
|
||||||
((mod ,a ,b) ((binop->r info) a b 'r0%r1))
|
((binop->r info) a b 'r0/r1
|
||||||
|
(or (signed? (ast->type a info)) (signed? (ast->type b info)))))
|
||||||
|
((mod ,a ,b) ((binop->r info) a b 'r0%r1
|
||||||
|
(or (signed? (ast->type a info)) (signed? (ast->type b info)))))
|
||||||
((mul ,a ,b) ((binop->r info) a b 'r0*r1))
|
((mul ,a ,b) ((binop->r info) a b 'r0*r1))
|
||||||
|
|
||||||
((not ,expr)
|
((not ,expr)
|
||||||
|
@ -1334,11 +1341,12 @@
|
||||||
info)))
|
info)))
|
||||||
(info (expr->register a info))
|
(info (expr->register a info))
|
||||||
(info (append-text info (wrap-as (as info 'swap-r0-r1))))
|
(info (append-text info (wrap-as (as info 'swap-r0-r1))))
|
||||||
|
(signed? (or (signed? type) (signed? type-b)))
|
||||||
(info (append-text info (cond ((equal? op "+=") (wrap-as (as info 'r0+r1)))
|
(info (append-text info (cond ((equal? op "+=") (wrap-as (as info 'r0+r1)))
|
||||||
((equal? op "-=") (wrap-as (as info 'r0-r1)))
|
((equal? op "-=") (wrap-as (as info 'r0-r1)))
|
||||||
((equal? op "*=") (wrap-as (as info 'r0*r1)))
|
((equal? op "*=") (wrap-as (as info 'r0*r1)))
|
||||||
((equal? op "/=") (wrap-as (as info 'r0/r1)))
|
((equal? op "/=") (wrap-as (as info 'r0/r1 signed?)))
|
||||||
((equal? op "%=") (wrap-as (as info 'r0%r1)))
|
((equal? op "%=") (wrap-as (as info 'r0%r1 signed?)))
|
||||||
((equal? op "&=") (wrap-as (as info 'r0-and-r1)))
|
((equal? op "&=") (wrap-as (as info 'r0-and-r1)))
|
||||||
((equal? op "|=") (wrap-as (as info 'r0-or-r1)))
|
((equal? op "|=") (wrap-as (as info 'r0-or-r1)))
|
||||||
((equal? op "^=") (wrap-as (as info 'r0-xor-r1)))
|
((equal? op "^=") (wrap-as (as info 'r0-xor-r1)))
|
||||||
|
@ -1349,7 +1357,7 @@
|
||||||
(cond ((not (and (= rank 1) (= rank-b 1))) info)
|
(cond ((not (and (= rank 1) (= rank-b 1))) info)
|
||||||
((equal? op "-=") (let* ((info (allocate-register info))
|
((equal? op "-=") (let* ((info (allocate-register info))
|
||||||
(info (append-text info (wrap-as (append (as info 'value->r size)
|
(info (append-text info (wrap-as (append (as info 'value->r size)
|
||||||
(as info 'r0/r1)))))
|
(as info 'r0/r1 signed?)))))
|
||||||
(info (free-register info)))
|
(info (free-register info)))
|
||||||
info))
|
info))
|
||||||
(else (error (format #f "invalid operands to binary ~s (have ~s* and ~s*)" op type (ast->basic-type b info)))))))))
|
(else (error (format #f "invalid operands to binary ~s (have ~s* and ~s*)" op type (ast->basic-type b info)))))))))
|
||||||
|
@ -1446,10 +1454,10 @@
|
||||||
(else '())))))
|
(else '())))))
|
||||||
|
|
||||||
(define (binop->r info)
|
(define (binop->r info)
|
||||||
(lambda (a b c)
|
(lambda (a b c . rest)
|
||||||
(let* ((info (expr->register a info))
|
(let* ((info (expr->register a info))
|
||||||
(info (expr->register b info))
|
(info (expr->register b info))
|
||||||
(info (append-text info (wrap-as (as info c)))))
|
(info (append-text info (wrap-as (apply as info (cons c rest))))))
|
||||||
(free-register info))))
|
(free-register info))))
|
||||||
|
|
||||||
(define (binop->r* info)
|
(define (binop->r* info)
|
||||||
|
|
|
@ -354,7 +354,7 @@
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
`((,(string-append "and____%" r1 ",%" r0)))))
|
`((,(string-append "and____%" r1 ",%" r0)))))
|
||||||
|
|
||||||
(define (i386:r0/r1 info)
|
(define (i386:r0/r1 info signed?)
|
||||||
(let ((allocated (.allocated info))
|
(let ((allocated (.allocated info))
|
||||||
(r0 (get-r0 info))
|
(r0 (get-r0 info))
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
|
@ -362,7 +362,7 @@
|
||||||
`(,@(if (equal? r0 "eax") '()
|
`(,@(if (equal? r0 "eax") '()
|
||||||
`(("push___%eax")
|
`(("push___%eax")
|
||||||
(,(string-append "mov____%" r0 ",%eax"))))
|
(,(string-append "mov____%" r0 ",%eax"))))
|
||||||
("xor____%edx,%edx")
|
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||||
(,(string-append "idiv___%" r1))
|
(,(string-append "idiv___%" r1))
|
||||||
,@(if (equal? r0 "eax") '()
|
,@(if (equal? r0 "eax") '()
|
||||||
`((,(string-append "mov____%eax,%" r0))
|
`((,(string-append "mov____%eax,%" r0))
|
||||||
|
@ -372,14 +372,14 @@
|
||||||
("push___%edx")
|
("push___%edx")
|
||||||
(,(string-append "mov____%" r1 ",%ebx"))
|
(,(string-append "mov____%" r1 ",%ebx"))
|
||||||
(,(string-append "mov____%" r0 ",%eax"))
|
(,(string-append "mov____%" r0 ",%eax"))
|
||||||
("xor____%edx,%edx")
|
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||||
(,(string-append "idiv___%ebx"))
|
(,(string-append "idiv___%ebx"))
|
||||||
("pop____%edx")
|
("pop____%edx")
|
||||||
("pop____%ebx")
|
("pop____%ebx")
|
||||||
(,(string-append "mov____%eax,%" r0))
|
(,(string-append "mov____%eax,%" r0))
|
||||||
("pop____%eax")))))
|
("pop____%eax")))))
|
||||||
|
|
||||||
(define (i386:r0%r1 info)
|
(define (i386:r0%r1 info signed?)
|
||||||
(let ((allocated (.allocated info))
|
(let ((allocated (.allocated info))
|
||||||
(r0 (get-r0 info))
|
(r0 (get-r0 info))
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
`(,@(if (equal? r0 "eax") '()
|
`(,@(if (equal? r0 "eax") '()
|
||||||
`(("push___%eax")
|
`(("push___%eax")
|
||||||
(,(string-append "mov____%" r0 ",%eax"))))
|
(,(string-append "mov____%" r0 ",%eax"))))
|
||||||
("xor____%edx,%edx")
|
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||||
(,(string-append "idiv___%" r1))
|
(,(string-append "idiv___%" r1))
|
||||||
(,(string-append "mov____%edx,%" r0)))
|
(,(string-append "mov____%edx,%" r0)))
|
||||||
`(("push___%eax")
|
`(("push___%eax")
|
||||||
|
@ -395,7 +395,7 @@
|
||||||
("push___%edx")
|
("push___%edx")
|
||||||
(,(string-append "mov____%" r1 ",%ebx"))
|
(,(string-append "mov____%" r1 ",%ebx"))
|
||||||
(,(string-append "mov____%" r0 ",%eax"))
|
(,(string-append "mov____%" r0 ",%eax"))
|
||||||
("xor____%edx,%edx")
|
,(if signed? '("cltd") '("xor____%edx,%edx"))
|
||||||
(,(string-append "idiv___%ebx"))
|
(,(string-append "idiv___%ebx"))
|
||||||
("pop____%edx")
|
("pop____%edx")
|
||||||
("pop____%ebx")
|
("pop____%ebx")
|
||||||
|
|
|
@ -436,7 +436,7 @@
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
`((,(string-append "and____%" r1 ",%" r0)))))
|
`((,(string-append "and____%" r1 ",%" r0)))))
|
||||||
|
|
||||||
(define (x86_64:r0/r1 info)
|
(define (x86_64:r0/r1 info signed?)
|
||||||
(let ((allocated (.allocated info))
|
(let ((allocated (.allocated info))
|
||||||
(r0 (get-r0 info))
|
(r0 (get-r0 info))
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
|
@ -444,7 +444,7 @@
|
||||||
`(,@(if (equal? r0 "rax") '()
|
`(,@(if (equal? r0 "rax") '()
|
||||||
`(("push___%rax")
|
`(("push___%rax")
|
||||||
(,(string-append "mov____%" r0 ",%rax"))))
|
(,(string-append "mov____%" r0 ",%rax"))))
|
||||||
("xor____%rdx,%rdx")
|
,(if signed? '("cqto") '("xor____%rdx,%rdx"))
|
||||||
(,(string-append "idiv___%" r1))
|
(,(string-append "idiv___%" r1))
|
||||||
,@(if (equal? r0 "rax") '()
|
,@(if (equal? r0 "rax") '()
|
||||||
`((,(string-append "mov____%rax,%" r0))
|
`((,(string-append "mov____%rax,%" r0))
|
||||||
|
@ -454,14 +454,14 @@
|
||||||
("push___%rdx")
|
("push___%rdx")
|
||||||
(,(string-append "mov____%" r1 ",%rdi"))
|
(,(string-append "mov____%" r1 ",%rdi"))
|
||||||
(,(string-append "mov____%" r0 ",%rax"))
|
(,(string-append "mov____%" r0 ",%rax"))
|
||||||
("xor____%rdx,%rdx")
|
,(if signed? '("cqto") '("xor____%rdx,%rdx"))
|
||||||
(,(string-append "idiv___%rdi"))
|
(,(string-append "idiv___%rdi"))
|
||||||
("pop____%rdx")
|
("pop____%rdx")
|
||||||
("pop____%rdi")
|
("pop____%rdi")
|
||||||
(,(string-append "mov____%rax,%" r0))
|
(,(string-append "mov____%rax,%" r0))
|
||||||
("pop____%rax")))))
|
("pop____%rax")))))
|
||||||
|
|
||||||
(define (x86_64:r0%r1 info)
|
(define (x86_64:r0%r1 info signed?)
|
||||||
(let ((allocated (.allocated info))
|
(let ((allocated (.allocated info))
|
||||||
(r0 (get-r0 info))
|
(r0 (get-r0 info))
|
||||||
(r1 (get-r1 info)))
|
(r1 (get-r1 info)))
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
`(,@(if (equal? r0 "rax") '()
|
`(,@(if (equal? r0 "rax") '()
|
||||||
`(("push___%rax")
|
`(("push___%rax")
|
||||||
(,(string-append "mov____%" r0 ",%rax"))))
|
(,(string-append "mov____%" r0 ",%rax"))))
|
||||||
("xor____%rdx,%rdx")
|
,(if signed? '("cqto") '("xor____%rdx,%rdx"))
|
||||||
(,(string-append "idiv___%" r1))
|
(,(string-append "idiv___%" r1))
|
||||||
(,(string-append "mov____%rdx,%" r0)))
|
(,(string-append "mov____%rdx,%" r0)))
|
||||||
`(("push___%rax")
|
`(("push___%rax")
|
||||||
|
@ -477,7 +477,7 @@
|
||||||
("push___%rdx")
|
("push___%rdx")
|
||||||
(,(string-append "mov____%" r1 ",%rdi"))
|
(,(string-append "mov____%" r1 ",%rdi"))
|
||||||
(,(string-append "mov____%" r0 ",%rax"))
|
(,(string-append "mov____%" r0 ",%rax"))
|
||||||
("xor____%rdx,%rdx")
|
,(if signed? '("cqto") '("xor____%rdx,%rdx"))
|
||||||
(,(string-append "idiv___%rdi"))
|
(,(string-append "idiv___%rdi"))
|
||||||
("pop____%rdx")
|
("pop____%rdx")
|
||||||
("pop____%rdi")
|
("pop____%rdi")
|
||||||
|
|
28
scaffold/tests/a0-math-divide-signed-negative.c
Normal file
28
scaffold/tests/a0-math-divide-signed-negative.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/* -*-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 ()
|
||||||
|
{
|
||||||
|
int i = -2 / 1;
|
||||||
|
if (i != -2)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue