diff --git a/scheme/ikarus.compiler.altcogen.ss b/scheme/ikarus.compiler.altcogen.ss index 168671a..33b3920 100644 --- a/scheme/ikarus.compiler.altcogen.ss +++ b/scheme/ikarus.compiler.altcogen.ss @@ -2453,6 +2453,7 @@ `(int ,(* size wordsize)) `(current-frame-offset) (rp-label value) + ;;; FIXME: hardcoded number of bytes '(byte 0) '(byte 0) '(byte 0) @@ -2467,6 +2468,7 @@ `(int ,(* size wordsize)) `(current-frame-offset) (rp-label value) + ;;; FIXME: hardcoded number of bytes LCALL `(call (label ,target)) `(addl ,(* (fxsub1 size) wordsize) ,fpr) @@ -2478,6 +2480,7 @@ `(int ,(* size wordsize)) `(current-frame-offset) (rp-label value) + ;;; FIXME: hardcoded number of bytes '(byte 0) '(byte 0) LCALL @@ -2577,11 +2580,6 @@ (set-cdr! tc (append hand (cdr tc))))) (parameterize ([exception-label L]) (E body (cons L2 ac))))] - ;[(shortcut body handler) - ; (let ([L (unique-label)] [L2 (unique-label)]) - ; (let ([ac (cons L (E handler (cons L2 ac)))]) - ; (parameterize ([exception-label L]) - ; (E body (cons `(jmp ,L2) ac)))))] [else (error who "invalid effect" (unparse x))])) ;;; (define (unique-interrupt-label) @@ -2756,6 +2754,7 @@ '(int 0) ; if the framesize=0, then the framesize is dynamic '(current-frame-offset) '(int 0) ; multiarg rp + ;;; FIXME: hardcoded number of bytes (byte 0) (byte 0) L_CALL diff --git a/scheme/ikarus.compiler.ss b/scheme/ikarus.compiler.ss index de58a01..ea65faa 100644 --- a/scheme/ikarus.compiler.ss +++ b/scheme/ikarus.compiler.ss @@ -1987,9 +1987,14 @@ (define record-pmask 7) (define disp-struct-rtd 0) (define disp-struct-data wordsize) - (define disp-frame-size -17) ;; OUCH - (define disp-frame-offset -13) ;; OUCH - (define disp-multivalue-rp -9) ;; OUCH + + ;;; refer to the picture in src/ikarus-collect.c for details + ;;; on how call-frames are laid out. (search for livemask) + (define call-instruction-size 5) + (define disp-frame-size (- (+ call-instruction-size (* 3 wordsize)))) + (define disp-frame-offset (- (+ call-instruction-size (* 2 wordsize)))) + (define disp-multivalue-rp (- (+ call-instruction-size (* 1 wordsize)))) + (define dirty-word -1)) ;(define pcb-allocation-pointer (* 0 wordsize)) NOT USED @@ -2324,6 +2329,7 @@ `(int ,(fx* wordsize 3)) '(current-frame-offset) (label-address L_cwv_multi_rp) + ;;; FIXME: hardcoded number of bytes (byte 0) (byte 0) (label L_cwv_call) diff --git a/scheme/last-revision b/scheme/last-revision index a3285fb..07f7d5f 100644 --- a/scheme/last-revision +++ b/scheme/last-revision @@ -1 +1 @@ -1308 +1309 diff --git a/src/ikarus-enter.s b/src/ikarus-enter.s index 6509785..3afda16 100644 --- a/src/ikarus-enter.s +++ b/src/ikarus-enter.s @@ -22,6 +22,13 @@ .globl _ik_foreign_call .globl ik_asm_reenter .globl _ik_asm_reenter + + +#if __x86_64__ + +#################################################################### +# 64-bit + .align 8 ik_asm_enter: _ik_asm_enter: @@ -35,7 +42,6 @@ _ik_asm_enter: movl 0(%esi), %ebp # allocation pointer is at 0(pcb) movl %esp, %eax subl $16, %esp # 24 for alignment -# set_stack: movl %esp, 24(%esi) # save esp in pcb->system_stack movl 8(%esi), %esp # load scheme stack from pcb->frame_pinter jmp L_call @@ -47,11 +53,9 @@ _ik_asm_enter: .byte 0 .byte 0 .byte 0 -#ifdef __x86_64__ - .long 0 # FIXME -#else - .long L_multivalue_underflow -#endif +L_multivalue_label: # FIXME + .long 0 # 2 longs + .long 0 # for return address .byte 0 .byte 0 L_call: @@ -72,6 +76,7 @@ L_multivalue_underflow: addl $4, %esp jmp L_do_underflow + .align 8 ik_asm_reenter: _ik_asm_reenter: @@ -127,29 +132,141 @@ L_two: L_one: push $0 L_zero: -#if __x86_64__ push %rsi # (pushl pcr) -#else - push %esi # (pushl pcr) -#endif cmpl $0, %eax # (cmpl (int 0) eax) je L_set # (je (label Lset)) L_loop: # (label Lloop) movl (%ebx,%eax), %ecx # (movl (mem ebx eax) ecx) -#if __x86_64__ push %rcx # (pushl ecx) -#else - push %ecx # (pushl ecx) -#endif addl $4, %eax # (addl (int 4) eax) cmpl $0, %eax # (cmpl (int 0) eax) jne L_loop # (jne (label Lloop)) L_set: # (label Lset) -#if __x86_64__ call *%rdi # (call cpr) -#else - call *%edi # (call cpr) -#endif movl 8(%esi), %esp # (movl (pcb-ref 'frame-pointer) fpr) movl 0(%esi), %ebp # (movl (pcb-ref 'allocation-pointer) apr) ret # (ret))) + +#else + +#################################################################### +# 32-bit + +.align 8 +ik_asm_enter: +_ik_asm_enter: + # ignored value is the third arg 12(%esp) + # code is the second arg 8(%esp) + # pcb is the first arg 4(%esp) + # return point is at 0(%esp) + movl %esi, -4(%esp) # preserve + movl %ebp, -8(%esp) # preserve + movl 4(%esp), %esi + movl 0(%esi), %ebp # allocation pointer is at 0(pcb) + movl %esp, %eax + subl $16, %esp # 24 for alignment + movl %esp, 24(%esi) # save esp in pcb->system_stack + movl 8(%esi), %esp # load scheme stack from pcb->frame_pinter + jmp L_call + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .long L_multivalue_underflow + .byte 0 + .byte 0 +L_call: + call *8(%eax) # goooooooo + # now we're back +ik_underflow_handler: + movl %eax, -8(%esp) # store the return value + movl $-4, %eax # set rvcount = 1 +L_do_underflow: + movl %esp, 8(%esi) # store scheme stack in pcb->frame_pointer + movl %ebp, 0(%esi) # store allocation pointer + movl 24(%esi), %esp # restore system stack + addl $16, %esp # 24 for alignment (>= 16) + movl -4(%esp), %esi # restore callee-save registers + movl -8(%esp), %ebp # + ret # back to C, which handled the underflow +L_multivalue_underflow: + addl $4, %esp + jmp L_do_underflow + + +.align 8 +ik_asm_reenter: +_ik_asm_reenter: + # argc is at 12(%esp) + # scheme stack is third arg 8(%esp) + # pcb is the first arg 4(%esp) + # return point is at 0(%esp) + movl 12(%esp), %eax + movl 8(%esp), %ebx + movl %esi, -4(%esp) + movl %ebp, -8(%esp) + movl 4(%esp), %esi + movl 0(%esi), %ebp # allocation pointer is at 0(pcb) + subl $16, %esp # 24 for alignment + movl %esp, 24(%esi) # save esp in pcb->system_stack + movl %ebx, %esp # load scheme stack from second arg + cmpl $-4, %eax + jne L_multi_reentry + movl -4(%esp), %eax + ret +L_multi_reentry: + movl 0(%esp), %ebx + jmp *-9(%ebx) + + +.align 8 +ik_foreign_call: +_ik_foreign_call: + movl %esp, 8(%esi) # (movl fpr (pcb-ref 'frame-pointer)) + movl %ebp, 0(%esi) # (movl apr (pcb-ref 'allocation-pointer)) + movl %esp, %ebx # (movl fpr ebx) + movl 24(%esi), %esp # (movl (pcb-ref 'system-stack) esp) + # %esp is the system stack, %eax is the index to the last arg, + # %esi is the pcb. + # Now, the value of %esp is 16-byte aligned + # we always push %esi (4 bytes) and do a call (4 bytes), + # 0 args require 6 (2) pushes => argc= 0 (0000): %esp += -8 + # 1 args require 5 (1) pushes => argc= -4 (1100): %esp += -4 + # 2 args require 4 (0) pushes => argc= -8 (1000): %esp += 0 + # 3 args require 3 (3) pushes => argc= -12 (0100): %esp += -12 + movl %eax, %ecx + andl $15, %ecx +check_ecx: + cmpl $8, %ecx + je L_zero + cmpl $12, %ecx + je L_one + cmpl $0, %ecx + je L_two + push $0 +L_two: + push $0 +L_one: + push $0 +L_zero: + push %esi # (pushl pcr) + cmpl $0, %eax # (cmpl (int 0) eax) + je L_set # (je (label Lset)) +L_loop: # (label Lloop) + movl (%ebx,%eax), %ecx # (movl (mem ebx eax) ecx) + push %ecx # (pushl ecx) + addl $4, %eax # (addl (int 4) eax) + cmpl $0, %eax # (cmpl (int 0) eax) + jne L_loop # (jne (label Lloop)) +L_set: # (label Lset) + call *%edi # (call cpr) + movl 8(%esi), %esp # (movl (pcb-ref 'frame-pointer) fpr) + movl 0(%esi), %ebp # (movl (pcb-ref 'allocation-pointer) apr) + ret # (ret))) + +#endif +