; penter_shx.s
;
; Time-stamp: <04/11/01 09:07:08 keuchel@netwave.de>
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Detecting which function called __penter is not as easy as on ARM.
; We have to walk the instructions up until we find sts.l pr,@-15.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        .export  __penter
        .export  __pexit
        .import  ___handle_penter
        .import  ___handle_return

        .section .text, code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; can be missing
;  1A010400   2FE6 mov.l   r14,@-r15            ; frame
; always there!
;  1A010402   4F22 sts.l   pr,@-r15             ; save return addr (pr)
; this is variable...
;  1A010404   1F.. mov.l   r7,@(0x00000014,r15) ; arg
;  1A010406   1F.. mov.l   r6,@(0x00000010,r15) ; arg
;  1A010408   1F.. mov.l   r5,@(0x0000000C,r15) ; arg
;  1A01040A   1F.. mov.l   r4,@(0x00000008,r15) ; arg
;  1A01040C   7F.. add     #0xFFFFFFE8,r15
;  1A01040E   6EF3 mov     r15,r14
; frame increment can be here
;  1A010410   7F.. add     #0xFFFFFFE4,r15
;  1A010412   D0.. mov.l   @(0x00000314,pc),r0  ; __penter
;  1A010414   400B jsr     @r0
;  1A010416   0009 nop                          ; delay slot

__penter .ENTRY
        sts.l pr, @-r15                 ; save return
        .PROLOG                         ; what's this for????
        mov.l r0, @-r15
        mov.l r4, @-r15                 ; save arg1
        mov.l r5, @-r15                 ; save arg2

        ; use pr for the caller's address -- it's in the caller's method;
        ; so we can just scan the map file for the largest address, smaller
        ; than pr.

        sts.l pr, r4
        mov.l #0, r5

l2:
        mov.l #___handle_penter, r0
        jsr @r0
        nop     ; delay slot

        mov.l @r15+, r5
        mov.l @r15+, r4
        mov.l @r15+, r0
        lds.l @r15+, pr
        rts

        nop     ; delay slot

        .ENDF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  The SH3 compiler also generates __pexit() calls...
;
;  1A010840   mov     #0x00000000,r0                 ; retcode
;
;  1A010842   mov.l   @(0x00000098,pc),r2            ; __pexit
;  1A010844   jsr     @r2
;  1A010846   nop                                    ; delay slot
;  1A010848   add     #0x00000018,r15
;  1A01084A   lds.l   @r15+,pr                       ; return address
;  1A01084C   rts
;  1A01084E   nop                                    ; delay slot

__pexit .ENTRY
  .aif PROFILE_TIMING eq 1
        sts.l pr, @-r15
        .PROLOG
        mov.l r0, @-r15

        ; this uses the last address pushed on the virtual stack
        mov.l #___handle_return, r0
        jsr @r0
        nop     ; delay slot

        mov.l @r15+, r0
        lds.l @r15+, pr
  .aelse
        .PROLOG
  .aendi

        rts
        nop     ; delay slot

        .ENDF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        .end
