From dc4b7f3a3719bfaa7fd45ff3593e5dbcb829b742 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 6 Oct 2018 20:23:43 +0200 Subject: [PATCH] mescc: Fix clobbering of struct by value assign. * module/mescc/x86_64/as.scm (long-r0->r1-mem): New instruction. * module/mescc/i386/as.scm: Likewise. * lib/x86_64-mes/x86_64.M1: Support it. * module/mescc/compile.scm (r0->r1-mem*n-): Fix clobbering. --- lib/x86-mes/x86.M1 | 8 ++++- lib/x86_64-mes/x86_64.M1 | 6 +++- module/mescc/compile.scm | 61 ++++++++++++++++++-------------------- module/mescc/i386/as.scm | 21 +++++++++++++ module/mescc/x86_64/as.scm | 31 ++++++++++++++++++- 5 files changed, 92 insertions(+), 35 deletions(-) diff --git a/lib/x86-mes/x86.M1 b/lib/x86-mes/x86.M1 index 6c5bdad0..4e850b34 100644 --- a/lib/x86-mes/x86.M1 +++ b/lib/x86-mes/x86.M1 @@ -17,7 +17,7 @@ ### along with GNU Mes. If not, see . # reduced instruction set: eax, ebx (some ecx for shift, edx for mul, div) -# 185 instructions +# 191 instructions DEFINE add____$i32,%eax 05 DEFINE add____$i32,%ebx 81c3 @@ -84,6 +84,9 @@ DEFINE mov____%al,(%ebx) 8803 DEFINE mov____%al,0x8(%ebp) 8845 DEFINE mov____%ax,(%ebx) 668903 DEFINE mov____%ax,0x8(%ebp) 668945 +DEFINE mov____%bx,%bx 6689db +DEFINE mov____%cl,(%ebx) 8a08 +DEFINE mov____%cx,(%ebx) 668b08 DEFINE mov____%dl,(%eax) 8810 DEFINE mov____%dl,0x8(%eax) 8850 DEFINE mov____%eax,%ebx 89c3 @@ -103,6 +106,8 @@ DEFINE mov____%ecx,(%ebx) 890b DEFINE mov____%edx,%eax 89d0 DEFINE mov____%edx,%ebx 89d3 DEFINE mov____%esp,%ebp 89e5 +DEFINE mov____(%eax),%cl 8a08 +DEFINE mov____(%eax),%cx 668b08 DEFINE mov____(%eax),%eax 8b00 DEFINE mov____(%eax),%ecx 8b08 DEFINE mov____(%ebx),%ebx 8b1b @@ -138,6 +143,7 @@ DEFINE movzbl_0x8(%eax),%eax 0fb640 DEFINE movzbl_0x8(%ebp),%eax 0fb645 DEFINE movzwl_%ax,%eax 0fb7c0 DEFINE movzwl_%bx,%ebx 0fb7db +DEFINE movzwl_%bx,%ebx 6689db DEFINE movzwl_(%eax),%eax 0fb700 DEFINE movzwl_(%ebx),%ebx 0fb71b DEFINE movzwl_0x32(%eax),%eax 0fb780 diff --git a/lib/x86_64-mes/x86_64.M1 b/lib/x86_64-mes/x86_64.M1 index 760fef3d..a7b26bcc 100644 --- a/lib/x86_64-mes/x86_64.M1 +++ b/lib/x86_64-mes/x86_64.M1 @@ -18,7 +18,7 @@ # reduced instruction set: rax, rdi (some rcx for shift, rdx for mul, div) # and r10 as i64 immediate helper -# 206 instructions +# 211 instructions DEFINE add____$i32,%rax 4805 DEFINE add____$i32,%rbp 4881c5 @@ -97,6 +97,7 @@ DEFINE mov____%edi,%rdi 89ff DEFINE mov____%edi,0x32(%rbp) 89bd DEFINE mov____%edi,0x8(%rbp) 897d DEFINE mov____%esi,%eax 89f0 +DEFINE mov____%esi,(%rdi) 8937 DEFINE mov____%r8,%rdi 4c89c7 DEFINE mov____%rax,%rax 4889c0 DEFINE mov____%rax,%rdi 4889c7 @@ -121,6 +122,7 @@ DEFINE mov____%rdx,%rdi 4889d7 DEFINE mov____%rsi,(%rdi) 488937 DEFINE mov____%rsp,%rbp 4889e5 DEFINE mov____(%rax),%eax 8b00 +DEFINE mov____(%rax),%esi 8b30 DEFINE mov____(%rax),%rax 488b00 DEFINE mov____(%rax),%rsi 488b30 DEFINE mov____(%rdi),%edi 8b3f @@ -145,6 +147,8 @@ DEFINE mov____0x8(%rdi),%rbp 488b6f DEFINE mov____0x8(%rdi),%rsp 488b67 DEFINE movl___%eax,0x32 890425 DEFINE movl___%edi,0x32 893c25 +DEFINE movl___%esi,(%rdi) 8937 +DEFINE movl___(%rax),%esi 8b30 DEFINE movsbq_%al,%rax 480fbec0 DEFINE movsbq_%dil,%rdi 480fbeff DEFINE movsbq_(%rax),%rax 480fbe00 diff --git a/module/mescc/compile.scm b/module/mescc/compile.scm index 7d32a56c..d82724de 100644 --- a/module/mescc/compile.scm +++ b/module/mescc/compile.scm @@ -678,38 +678,35 @@ (let ((reg-size (->size "*" info))) (wrap-as (cond - ((= n 1) (as info 'byte-r0->r1-mem)) - ((= n 2) (cond ((= size 1) (append (as info 'byte-r0->r1-mem) - (as info 'r+value 1) - (as info 'value->r0 0) - (as info 'byte-r0->r1-mem))) - (else (as info 'word-r0->r1-mem)))) - ((= n 4) (as info 'long-r0->r1-mem)) - ((and (= n 8) (or (= reg-size 8) - (= size 4))) - (cond ((= size 4) (append (as info 'long-r0->r1-mem) - (as info 'r+value 4) - (as info 'value->r0 0) - (as info 'long-r0->r1-mem))) - ((and (= size 8) (= reg-size 8)) (as info 'quad-r0->r1-mem)) - (else (error "r0->r1-mem*n-: not supported")))) - (else (append (let loop ((i 0)) - (if (>= i n) '() - (append (if (= i 0) '() - (append (as info 'r+value reg-size) - (as info 'r0+value reg-size))) - (case (- n i) - ((1) (append (as info 'r+value -3) - (as info 'r0+value -3) - (as info 'r0-mem->r1-mem))) - ((2) (append (as info 'r+value -2) - (as info 'r0+value -2) - (as info 'r0-mem->r1-mem))) - ((3) (append (as info 'r+value -1) - (as info 'r0+value -1) - (as info 'r0-mem->r1-mem))) - (else (as info 'r0-mem->r1-mem))) - (loop (+ i reg-size))))))))))) + ((= n 1) (as info 'byte-r0->r1-mem)) + ((= n 2) (cond ((= size 1) (append (as info 'byte-r0->r1-mem) + (as info 'r+value 1) + (as info 'value->r0 0) + (as info 'byte-r0->r1-mem))) + (else (as info 'word-r0->r1-mem)))) + ((= n 4) (as info 'long-r0->r1-mem)) + ((and (= n 8) (or (= reg-size 8) + (= size 4))) + (cond ((= size 4) (append (as info 'long-r0->r1-mem) + (as info 'r+value 4) + (as info 'value->r0 0) + (as info 'long-r0->r1-mem))) + ((and (= size 8) (= reg-size 8)) (as info 'quad-r0->r1-mem)) + (else (error "r0->r1-mem*n-: not supported")))) + (else (let loop ((i 0)) + (if (>= i n) '() + (case (- n i) + ((1) (as info 'byte-r0-mem->r1-mem)) + ((2) (as info 'word-r0-mem->r1-mem)) + ((3) (append (as info 'word-r0-mem->r1-mem) + (as info 'r+value 2) + (as info 'r0+value 2) + (loop (+ i 2)))) + ((4) (append (as info 'long-r0-mem->r1-mem))) + (else (append (as info 'r0-mem->r1-mem) + (as info 'r+value reg-size) + (as info 'r0+value reg-size) + (loop (+ i reg-size)))))))))))) (define (r0->r1-mem*n info n size) (append-text info (r0->r1-mem*n- info n size))) diff --git a/module/mescc/i386/as.scm b/module/mescc/i386/as.scm index d3092e3a..178ab98e 100644 --- a/module/mescc/i386/as.scm +++ b/module/mescc/i386/as.scm @@ -470,6 +470,24 @@ `((,(string-append "mov____(%" r0 "),%" r2)) (,(string-append "mov____%" r2 ",(%" r1 ")"))))) +(define (i386:byte-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers)) + (l2 (e->l r2))) + `((,(string-append "mov____(%" r0 "),%" l2)) + (,(string-append "mov____%" l2 ",(%" r1 ")"))))) + +(define (i386:word-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers)) + (x2 (e->x r2))) + `((,(string-append "mov____(%" r0 "),%" x2)) + (,(string-append "mov____%" x2 ",(%" r1 ")"))))) + (define (i386:r0+value info v) (let ((r0 (get-r0 info))) `(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r0) (#:immediate1 ,v)) @@ -538,6 +556,7 @@ (byte-r->local+n . ,i386:byte-r->local+n) (byte-r0->r1-mem . ,i386:byte-r0->r1-mem) (byte-r0->r1-mem . ,i386:byte-r0->r1-mem) + (byte-r0-mem->r1-mem . ,i386:byte-r0-mem->r1-mem) (byte-signed-r . ,i386:byte-signed-r) (call-label . ,i386:call-label) (call-r . ,i386:call-r) @@ -567,6 +586,7 @@ (local-add . ,i386:local-add) (local-ptr->r . ,i386:local-ptr->r) (long-r0->r1-mem . ,i386:r0->r1-mem) + (long-r0-mem->r1-mem . ,i386:r0-mem->r1-mem) (mem->r . ,i386:mem->r) (nop . ,i386:nop) (not-r . ,i386:not-r) @@ -618,6 +638,7 @@ (word-r . ,i386:word-r) (word-r->local+n . ,i386:word-r->local+n) (word-r0->r1-mem . ,i386:word-r0->r1-mem) + (word-r0-mem->r1-mem . ,i386:word-r0-mem->r1-mem) (word-signed-r . ,i386:word-signed-r) (xor-zf . ,i386:xor-zf) (zf->r . ,i386:zf->r) diff --git a/module/mescc/x86_64/as.scm b/module/mescc/x86_64/as.scm index 0b11af00..968d7c4b 100644 --- a/module/mescc/x86_64/as.scm +++ b/module/mescc/x86_64/as.scm @@ -567,6 +567,33 @@ `((,(string-append "mov____(%" r0 "),%" r2)) (,(string-append "mov____%" r2 ",(%" r1 ")"))))) +(define (x86_64:byte-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers)) + (l2 (r->l r2))) + `((,(string-append "mov____(%" r0 "),%" l2)) + (,(string-append "mov____%" l2 ",(%" r1 ")"))))) + +(define (x86_64:word-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers)) + (x2 (r->x r2))) + `((,(string-append "mov____(%" r0 "),%" x2)) + (,(string-append "mov____%" x2 ",(%" r1 ")"))))) + +(define (x86_64:long-r0-mem->r1-mem info) + (let* ((registers (.registers info)) + (r0 (get-r0 info)) + (r1 (get-r1 info)) + (r2 (car registers)) + (e2 (r->e r2))) + `((,(string-append "mov____(%" r0 "),%" e2)) + (,(string-append "mov____%" e2 ",(%" r1 ")"))))) + (define (x86_64:r0+value info v) (let ((r0 (get-r0 info))) `(,(if (< (abs v) #x80) `(,(string-append "add____$i8,%" r0) (#:immediate1 ,v)) @@ -656,7 +683,7 @@ (byte-r . ,x86_64:byte-r) (byte-r->local+n . ,x86_64:byte-r->local+n) (byte-r0->r1-mem . ,x86_64:byte-r0->r1-mem) - (byte-r0->r1-mem . ,x86_64:byte-r0->r1-mem) + (byte-r0-mem->r1-mem . ,x86_64:byte-r0-mem->r1-mem) (byte-signed-r . ,x86_64:byte-signed-r) (call-label . ,x86_64:call-label) (call-r . ,x86_64:call-r) @@ -689,6 +716,7 @@ (long-r . ,x86_64:long-r) (long-r->local+n . ,x86_64:long-r->local+n) (long-r0->r1-mem . ,x86_64:long-r0->r1-mem) + (long-r0-mem->r1-mem . ,x86_64:long-r0-mem->r1-mem) (long-signed-r . ,x86_64:long-signed-r) (mem->r . ,x86_64:mem->r) (nop . ,x86_64:nop) @@ -744,6 +772,7 @@ (word-r . ,x86_64:word-r) (word-r->local+n . ,x86_64:word-r->local+n) (word-r0->r1-mem . ,x86_64:word-r0->r1-mem) + (word-r0-mem->r1-mem . ,x86_64:word-r0-mem->r1-mem) (word-signed-r . ,x86_64:word-signed-r) (xor-zf . ,x86_64:xor-zf) (zf->r . ,x86_64:zf->r)