From 0db7d1d6d045454a773460022d34cbf113e3d18b Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Wed, 2 Jan 2008 05:55:30 -0500 Subject: [PATCH] Identified places where a hard-coded number of null bytes are manually inserted into the code stream to ensure proper offsets. These need to be removed ASAP. Also, abstracted the values of three constants that were hardcoded. --- scheme/ikarus.compiler.altcogen.ss | 9 +- scheme/ikarus.compiler.ss | 12 ++- scheme/last-revision | 2 +- src/ikarus-enter.s | 153 +++++++++++++++++++++++++---- 4 files changed, 149 insertions(+), 27 deletions(-) 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 +