Compare commits

...

5 Commits

Author SHA1 Message Date
Abdulaziz Ghuloum 1f2b250ed9 fixed a bug in (not) handling variable-size frames in ikarus-exec. 2010-01-26 07:35:09 +03:00
Abdulaziz Ghuloum 943a72f01f fixed a bug in the register allocator that was rewriting
mov8 mem1 -> mem2
to 
    mov mem1 -> reg
    mov8 reg -> mem2
instead of
    mov8 mem1 reg
    mov reg mem2
which causes unaligned and invalid memory access when the
address mem1 is at a page boundary and the next page is 
unmapped.
2010-01-24 00:13:01 +03:00
Abdulaziz Ghuloum 64aca7c80b one more fix for 64-bit jumps and calls. Some conditional jumps
required cross-code offsets which are now eliminated.
2009-12-31 16:41:13 +03:00
Abdulaziz Ghuloum 820eb7dcb9 Fixed the ``relocation error'' that happens in 64-bit mode. What
used to be a relative jump from one code object to another is now
turned into a pc-relative jump, where the jump targets are stored
somewhere at the bottom of the code that performs the jump:

old code sequence:

        call-relative (Ltarget - L0)
    L0: ...

new code sequence:

        call-pc-relative (L1 - L0)
    L0: ...
        ...
    L1: <8-byte Ltarget>
2009-12-31 03:41:22 +03:00
Abdulaziz Ghuloum 69207de752 fixed a bug in $flonum-sbe that caused a read of 4 bytes past the
end of the flonum object in 64-bit mode (manifesting in a segfault
when running make check on fedora 64-bit).
2009-12-29 05:03:47 +03:00
7 changed files with 179 additions and 87 deletions

Binary file not shown.

View File

@ -2227,6 +2227,23 @@
[else (error 'small-operand? "huh?")])) [else (error 'small-operand? "huh?")]))
(define (mem? x) (define (mem? x)
(or (disp? x) (fvar? x))) (or (disp? x) (fvar? x)))
(define (fix-address x k)
(cond
[(disp? x)
(let ([s0 (disp-s0 x)] [s1 (disp-s1 x)])
(cond
[(not (small-operand? s0))
(let ([u (mku)])
(make-seq
(E (make-asm-instr 'move u s0))
(fix-address (make-disp u s1) k)))]
[(not (small-operand? s1))
(let ([u (mku)])
(make-seq
(E (make-asm-instr 'move u s1))
(fix-address (make-disp s0 u) k)))]
[else (k x)]))]
[else (k x)]))
;;; unspillable effect ;;; unspillable effect
(define (E x) (define (E x)
(struct-case x (struct-case x
@ -2235,9 +2252,19 @@
(make-conditional (P e0) (E e1) (E e2))] (make-conditional (P e0) (E e1) (E e2))]
[(asm-instr op a b) [(asm-instr op a b)
(case op (case op
[(load8 load32)
(fix-address b
(lambda (b)
(cond
[(or (register? a) (var? a))
(make-asm-instr op a b)]
[else
(let ([u (mku)])
(make-seq
(make-asm-instr op u b)
(E (make-asm-instr 'move a u))))])))]
[(logor logxor logand int+ int- int* move [(logor logxor logand int+ int- int* move
load8 load32 int-/overflow int+/overflow int*/overflow)
int-/overflow int+/overflow int*/overflow)
(cond (cond
[(and (eq? op 'move) (eq? a b)) [(and (eq? op 'move) (eq? a b))
(make-primcall 'nop '())] (make-primcall 'nop '())]
@ -2256,17 +2283,10 @@
(E (make-asm-instr op u b))) (E (make-asm-instr op u b)))
(E (make-asm-instr 'move a u))))] (E (make-asm-instr 'move a u))))]
[(and (mem? a) (not (small-operand? b))) [(and (mem? a) (not (small-operand? b)))
(case op (let ([u (mku)])
[(load32) (make-seq
(let ([u (mku)]) (E (make-asm-instr 'move u b))
(make-seq (E (make-asm-instr op a u))))]
(E (make-asm-instr 'load32 u b))
(E (make-asm-instr 'move a u))))]
[else
(let ([u (mku)])
(make-seq
(E (make-asm-instr 'move u b))
(E (make-asm-instr op a u))))])]
[(disp? a) [(disp? a)
(let ([s0 (disp-s0 a)] [s1 (disp-s1 a)]) (let ([s0 (disp-s0 a)] [s1 (disp-s1 a)])
(cond (cond
@ -2480,12 +2500,7 @@
(define (compile-call-frame framesize livemask-vec multiarg-rp call-sequence) (define (compile-call-frame framesize livemask-vec multiarg-rp call-sequence)
(let ([L_CALL (label (gensym))] (let ([L_CALL (label (gensym))])
[padding
(- call-instruction-size
(instruction-size call-sequence))])
(when (< padding 0)
(error 'compile-call-frame "call sequence too long" call-sequence))
(list 'seq (list 'seq
(if (or (= framesize 0) (= framesize 1)) (if (or (= framesize 0) (= framesize 1))
'(seq) '(seq)
@ -2495,9 +2510,9 @@
`(int ,(* framesize wordsize)) `(int ,(* framesize wordsize))
'(current-frame-offset) '(current-frame-offset)
multiarg-rp multiarg-rp
`(byte-vector ,(make-vector padding 0)) `(pad ,call-instruction-size
L_CALL ,L_CALL
call-sequence ,call-sequence)
(if (or (= framesize 0) (= framesize 1)) (if (or (= framesize 0) (= framesize 1))
'(seq) '(seq)
`(addl ,(* (fxsub1 framesize) wordsize) ,fpr))))) `(addl ,(* (fxsub1 framesize) wordsize) ,fpr)))))

View File

@ -2084,19 +2084,6 @@
(movl (mem (fx- 0 wordsize) fpr) eax) (movl (mem (fx- 0 wordsize) fpr) eax)
(ret))))) (ret)))))
SL_values] SL_values]
[(sl-nonprocedure-error-label)
(define SL_nonprocedure (gensym "SL_nonprocedure"))
(assemble-sources (lambda (x) #f)
(list
(list 0
(label SL_nonprocedure)
(movl cpr (mem (fx- 0 wordsize) fpr)) ; first arg
(movl (obj (primref->symbol '$apply-nonprocedure-error-handler)) cpr)
(movl (mem (- disp-symbol-record-proc record-tag) cpr) cpr)
;(movl (primref-loc '$apply-nonprocedure-error-handler) cpr)
(movl (int (argc-convention 1)) eax)
(tail-indirect-cpr-call))))
SL_nonprocedure]
[(sl-cwv-label) [(sl-cwv-label)
(define SL_call_with_values (gensym "SL_call_with_values")) (define SL_call_with_values (gensym "SL_call_with_values"))
(assemble-sources (lambda (x) #f) (assemble-sources (lambda (x) #f)
@ -2104,18 +2091,20 @@
(let ([L_cwv_done (gensym)] (let ([L_cwv_done (gensym)]
[L_cwv_loop (gensym)] [L_cwv_loop (gensym)]
[L_cwv_multi_rp (gensym)] [L_cwv_multi_rp (gensym)]
[L_cwv_call (gensym)]) [L_cwv_call (gensym)]
[SL_nonprocedure (gensym "SL_nonprocedure")]
[SL_invalid_args (gensym "SL_invalid_args")])
(list (list
0 ; no free vars 0 ; no free vars
'(name call-with-values) '(name call-with-values)
(label SL_call_with_values) (label SL_call_with_values)
(cmpl (int (argc-convention 2)) eax) (cmpl (int (argc-convention 2)) eax)
(jne (label (sl-invalid-args-label))) (jne (label SL_invalid_args))
(movl (mem (fx- 0 wordsize) fpr) ebx) ; producer (movl (mem (fx- 0 wordsize) fpr) ebx) ; producer
(movl ebx cpr) (movl ebx cpr)
(andl (int closure-mask) ebx) (andl (int closure-mask) ebx)
(cmpl (int closure-tag) ebx) (cmpl (int closure-tag) ebx)
(jne (label (sl-nonprocedure-error-label))) (jne (label SL_nonprocedure))
(movl (int (argc-convention 0)) eax) (movl (int (argc-convention 0)) eax)
(compile-call-frame (compile-call-frame
3 3
@ -2129,7 +2118,7 @@
(movl (int (argc-convention 1)) eax) (movl (int (argc-convention 1)) eax)
(andl (int closure-mask) ebx) (andl (int closure-mask) ebx)
(cmpl (int closure-tag) ebx) (cmpl (int closure-tag) ebx)
(jne (label (sl-nonprocedure-error-label))) (jne (label SL_nonprocedure))
(tail-indirect-cpr-call) (tail-indirect-cpr-call)
;;; multiple values returned ;;; multiple values returned
(label L_cwv_multi_rp) (label L_cwv_multi_rp)
@ -2153,8 +2142,27 @@
(movl cpr ebx) (movl cpr ebx)
(andl (int closure-mask) ebx) (andl (int closure-mask) ebx)
(cmpl (int closure-tag) ebx) (cmpl (int closure-tag) ebx)
(jne (label (sl-nonprocedure-error-label))) (jne (label SL_nonprocedure))
(tail-indirect-cpr-call))))) (tail-indirect-cpr-call)
(label SL_nonprocedure)
(movl cpr (mem (fx- 0 wordsize) fpr)) ; first arg
(movl (obj (primref->symbol '$apply-nonprocedure-error-handler)) cpr)
(movl (mem (- disp-symbol-record-proc record-tag) cpr) cpr)
(movl (int (argc-convention 1)) eax)
(tail-indirect-cpr-call)
(label SL_invalid_args)
;;;
(movl cpr (mem (fx- 0 wordsize) fpr)) ; first arg
(negl eax)
(movl eax (mem (fx- 0 (fx* 2 wordsize)) fpr))
(movl (obj (primref->symbol '$incorrect-args-error-handler)) cpr)
(movl (mem (- disp-symbol-record-proc record-tag) cpr) cpr)
(movl (int (argc-convention 2)) eax)
(tail-indirect-cpr-call)
))))
SL_call_with_values] SL_call_with_values]
)) ))

View File

@ -16,7 +16,7 @@
(library (ikarus.intel-assembler) (library (ikarus.intel-assembler)
(export instruction-size assemble-sources code-entry-adjustment) (export assemble-sources code-entry-adjustment)
(import (import
(ikarus) (ikarus)
(rnrs bytevectors) (rnrs bytevectors)
@ -35,9 +35,11 @@
[else [else
(f (car ls) (fold f init (cdr ls)))]))) (f (car ls) (fold f init (cdr ls)))])))
(define convert-instructions (define convert-instructions
(lambda (ls) (lambda (ls)
(fold convert-instruction '() ls))) (parameterize ([local-labels (uncover-local-labels ls)])
(fold convert-instruction '() ls))))
(define register-mapping (define register-mapping
;;; reg cls idx REX.R ;;; reg cls idx REX.R
@ -216,7 +218,11 @@
(byte (sra n 24)) (byte (sra n 24))
ac)] ac)]
[(label? n) [(label? n)
(cons (cons 'relative (label-name n)) ac)] (cond
[(local-label? (label-name n))
(cons (cons 'local-relative (label-name n)) ac)]
[else
(cons (cons 'relative (label-name n)) ac)])]
[else (die 'IMM32 "invalid" n)]))) [else (die 'IMM32 "invalid" n)])))
(define IMM (define IMM
@ -255,7 +261,12 @@
[(foreign? n) [(foreign? n)
(cons (cons 'foreign-label (label-name n)) ac)] (cons (cons 'foreign-label (label-name n)) ac)]
[(label? n) [(label? n)
(cons (cons 'relative (label-name n)) ac)] (cond
[(local-label? (label-name n))
(cons (cons 'local-relative (label-name n)) ac)]
[else
(cons (cons 'relative (label-name n)) ac)])]
;(cons (cons 'relative (label-name n)) ac)]
[else (die 'IMM "invalid" n)]))) [else (die 'IMM "invalid" n)])))
@ -376,6 +387,7 @@
(begin (begin
(add-instruction (name* instr ac arg** ...) b* b** ...) ...)])) (add-instruction (name* instr ac arg** ...) b* b** ...) ...)]))
(define (convert-instruction a ac) (define (convert-instruction a ac)
(cond (cond
[(getprop (car a) *cogen*) => [(getprop (car a) *cogen*) =>
@ -400,6 +412,21 @@
(die 'convert-instruction "incorrect args" a))])))] (die 'convert-instruction "incorrect args" a))])))]
[(eq? (car a) 'seq) [(eq? (car a) 'seq)
(fold convert-instruction ac (cdr a))] (fold convert-instruction ac (cdr a))]
[(eq? (car a) 'pad)
(let ()
(define (find-prefix x ls)
(let f ([ls ls])
(cond
[(eq? ls x) '()]
[else
(let ([a (car ls)])
(if (and (pair? a) (eq? (car a) 'bottom-code))
(f (cdr ls))
(cons a (f (cdr ls)))))])))
(let ([n (cadr a)] [code (cddr a)])
(let ([ls (fold convert-instruction ac code)])
(let ([m (compute-code-size (find-prefix ac ls))])
(append (make-list (- n m) 0) ls)))))]
[else (die 'convert-instruction "unknown instruction" a)])) [else (die 'convert-instruction "unknown instruction" a)]))
(define (RM /d dst ac) (define (RM /d dst ac)
@ -562,6 +589,19 @@
(cons (car ls) (f (cdr ls)))))) (cons (car ls) (f (cdr ls))))))
ls) ls)
(define (jmp-pc-relative code0 code1 dst ac)
(when (= wordsize 4)
(error 'intel-assembler "no pc-relative jumps in 32-bit mode"))
(let ([g (gensym)])
(CODE code0
(CODE code1
(cons*
`(local-relative . ,g)
`(bottom-code
(label . ,g)
(label-addr . ,(label-name dst)))
ac)))))
(add-instructions instr ac (add-instructions instr ac
[(ret) (CODE #xC3 ac)] [(ret) (CODE #xC3 ac)]
[(cltd) (C #x99 ac)] [(cltd) (C #x99 ac)]
@ -721,12 +761,22 @@
[else (die who "invalid" instr)])] [else (die who "invalid" instr)])]
[(jmp dst) [(jmp dst)
(cond (cond
[(imm? dst) (CODE #xE9 (IMM32 dst ac))] [(and (label? dst) (local-label? (label-name dst)))
(CODE #xE9 (cons `(local-relative . ,(label-name dst)) ac))]
[(imm? dst)
(if (= wordsize 4)
(CODE #xE9 (IMM32 dst ac))
(jmp-pc-relative #xFF #x25 dst ac))]
[(mem? dst) (CR* #xFF '/4 dst ac)] [(mem? dst) (CR* #xFF '/4 dst ac)]
[else (die who "invalid jmp target" dst)])] [else (die who "invalid jmp target" dst)])]
[(call dst) [(call dst)
(cond (cond
[(imm? dst) (CODE #xE8 (IMM32 dst ac))] [(and (label? dst) (local-label? (label-name dst)))
(CODE #xE8 (cons `(local-relative . ,(label-name dst)) ac))]
[(imm? dst)
(if (= wordsize 4)
(CODE #xE8 (IMM32 dst ac))
(jmp-pc-relative #xFF #x15 dst ac))]
[(mem? dst) (CR* #xFF '/2 dst ac)] [(mem? dst) (CR* #xFF '/2 dst ac)]
[(reg? dst) (CR* #xFF '/2 dst ac)] [(reg? dst) (CR* #xFF '/2 dst ac)]
[else (die who "invalid jmp target" dst)])] [else (die who "invalid jmp target" dst)])]
@ -812,7 +862,7 @@
)) ))
(define compute-code-size (define compute-code-size
(lambda (ls) (lambda (ls)
(fold (lambda (x ac) (fold (lambda (x ac)
(if (fixnum? x) (if (fixnum? x)
@ -824,12 +874,13 @@
[(label) ac] [(label) ac]
[(word reloc-word reloc-word+ label-addr [(word reloc-word reloc-word+ label-addr
current-frame-offset foreign-label) current-frame-offset foreign-label)
(+ ac wordsize)] (fx+ ac wordsize)]
[(bottom-code)
(fx+ ac (compute-code-size (cdr x)))]
[else (die 'compute-code-size "unknown instr" x)]))) [else (die 'compute-code-size "unknown instr" x)])))
0 0
ls))) ls)))
(define set-label-loc! (define set-label-loc!
(lambda (x loc) (lambda (x loc)
(when (getprop x '*label-loc*) (when (getprop x '*label-loc*)
@ -841,7 +892,6 @@
(or (getprop x '*label-loc*) (or (getprop x '*label-loc*)
(die 'compile "undefined label" x)))) (die 'compile "undefined label" x))))
(define unset-label-loc! (define unset-label-loc!
(lambda (x) (lambda (x)
(remprop x '*label-loc*))) (remprop x '*label-loc*)))
@ -868,22 +918,41 @@
(code-set! code (fx+ idx 7) (fxlogand (fxsra x 53) #xFF))])] (code-set! code (fx+ idx 7) (fxlogand (fxsra x 53) #xFF))])]
[else (die 'set-code-word! "unhandled" x)]))) [else (die 'set-code-word! "unhandled" x)])))
(define local-labels (make-parameter '()))
(define (local-label? x) (and (memq x (local-labels)) #t))
(define (uncover-local-labels ls)
(define locals '())
(define find
(lambda (x)
(when (pair? x)
(case (car x)
[(label)
(set! locals (cons (label-name x) locals))]
[(seq pad)
(for-each find (cdr x))]))))
(for-each find ls)
locals)
(define (optimize-local-jumps ls) (define (optimize-local-jumps ls)
(define locals '()) (define locals '())
(define g (gensym)) (define g (gensym))
(for-each (define (mark x)
(lambda (x) (when (pair? x)
(when (and (pair? x) (eq? (car x) 'label)) (case (car x)
(putprop (cdr x) g 'local) [(label)
(set! locals (cons (cdr x) locals)))) (putprop (cdr x) g 'local)
ls) (set! locals (cons (cdr x) locals))]
(for-each [(bottom-code) (for-each mark (cdr x))])))
(lambda (x) (define (opt x)
(when (and (pair? x) (when (pair? x)
(eq? (car x) 'relative) (case (car x)
(eq? (getprop (cdr x) g) 'local)) [(relative)
(set-car! x 'local-relative))) (when (eq? (getprop (cdr x) g) 'local)
ls) (set-car! x 'local-relative))]
[(bottom-code) (for-each opt (cdr x))])))
(for-each mark ls)
(for-each opt ls)
(for-each (lambda (x) (remprop x g)) locals) (for-each (lambda (x) (remprop x g)) locals)
ls) ls)
@ -892,47 +961,52 @@
(define whack-instructions (define whack-instructions
(lambda (x ls) (lambda (x ls)
(define f (define f
(lambda (ls idx reloc) (lambda (ls idx reloc bot*)
(cond (cond
[(null? ls) reloc] [(null? ls)
(if (null? bot*)
reloc
(f (car bot*) idx reloc (cdr bot*)))]
[else [else
(let ([a (car ls)]) (let ([a (car ls)])
(if (fixnum? a) (if (fixnum? a)
(begin (begin
(code-set! x idx a) (code-set! x idx a)
(f (cdr ls) (fxadd1 idx) reloc)) (f (cdr ls) (fxadd1 idx) reloc bot*))
(case (car a) (case (car a)
[(byte) [(byte)
(code-set! x idx (cdr a)) (code-set! x idx (cdr a))
(f (cdr ls) (fx+ idx 1) reloc)] (f (cdr ls) (fx+ idx 1) reloc bot*)]
[(relative local-relative) [(relative local-relative)
(f (cdr ls) (fx+ idx 4) (cons (cons idx a) reloc))] (f (cdr ls) (fx+ idx 4) (cons (cons idx a) reloc) bot*)]
[(reloc-word reloc-word+ label-addr foreign-label) [(reloc-word reloc-word+ label-addr foreign-label)
(f (cdr ls) (fx+ idx wordsize) (cons (cons idx a) reloc))] (f (cdr ls) (fx+ idx wordsize) (cons (cons idx a) reloc) bot*)]
[(word) [(word)
(let ([v (cdr a)]) (let ([v (cdr a)])
(set-code-word! x idx v) (set-code-word! x idx v)
(f (cdr ls) (fx+ idx wordsize) reloc))] (f (cdr ls) (fx+ idx wordsize) reloc bot*))]
[(current-frame-offset) [(current-frame-offset)
(set-code-word! x idx idx) ;;; FIXME 64bit (set-code-word! x idx idx) ;;; FIXME 64bit
(f (cdr ls) (fx+ idx wordsize) reloc)] (f (cdr ls) (fx+ idx wordsize) reloc bot*)]
[(label) [(label)
(set-label-loc! (cdr a) (list x idx)) (set-label-loc! (cdr a) (list x idx))
(f (cdr ls) idx reloc)] (f (cdr ls) idx reloc bot*)]
[(bottom-code)
(f (cdr ls) idx reloc (cons (cdr a) bot*))]
[else [else
(die 'whack-instructions "unknown instr" a)])))]))) (die 'whack-instructions "unknown instr" a)])))])))
(f ls 0 '()))) (f ls 0 '() '())))
(define compute-reloc-size
(define compute-reloc-size
(lambda (ls) (lambda (ls)
(fold (lambda (x ac) (fold (lambda (x ac)
(if (fixnum? x) (if (fixnum? x)
ac ac
(case (car x) (case (car x)
[(word byte label current-frame-offset local-relative) ac]
[(reloc-word foreign-label) (fx+ ac 2)] [(reloc-word foreign-label) (fx+ ac 2)]
[(relative reloc-word+ label-addr) (fx+ ac 3)] [(relative reloc-word+ label-addr) (fx+ ac 3)]
[(word byte label current-frame-offset local-relative) ac] [(bottom-code) (fx+ ac (compute-reloc-size (cdr x)))]
[else (die 'compute-reloc-size "unknown instr" x)]))) [else (die 'compute-reloc-size "unknown instr" x)])))
0 0
ls))) ls)))
@ -1031,14 +1105,6 @@
[else (die 'whack-reloc "invalid reloc type" type)])) [else (die 'whack-reloc "invalid reloc type" type)]))
))) )))
(define (instruction-size x)
(unless (and (pair? x) (getprop (car x) *cogen*))
(die 'instruction-size "not an instruction" x))
;;; limitations: does not work if the instruction contains
;;; a jump to a local label, and the jump is later optimized
;;; to a short jump.
(compute-code-size
(convert-instruction x '())))
(define assemble-sources (define assemble-sources

View File

@ -1 +1 @@
1864 1869

View File

@ -1226,7 +1226,7 @@
[(V x) [(V x)
(prm 'sll (prm 'sll
(prm 'srl (prm 'srl
(prm 'mref (T x) (prm 'mref32 (T x)
(K (- (+ disp-flonum-data 4) vector-tag))) (K (- (+ disp-flonum-data 4) vector-tag)))
(K 20)) (K 20))
(K fx-shift))]) (K fx-shift))])

View File

@ -40,6 +40,9 @@ ikptr ik_exec_code(ikpcb* pcb, ikptr code_ptr, ikptr argcount, ikptr cp){
fprintf(stderr, "exec framesize=0x%016lx ksize=%ld rp=0x%016lx\n", fprintf(stderr, "exec framesize=0x%016lx ksize=%ld rp=0x%016lx\n",
framesize, k->size, rp); framesize, k->size, rp);
#endif #endif
if(framesize == 0){
framesize = ref(top, wordsize);
}
if(framesize <= 0){ if(framesize <= 0){
fprintf(stderr, "invalid framesize %ld\n", framesize); fprintf(stderr, "invalid framesize %ld\n", framesize);
exit(-10); exit(-10);