[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::macro

Title:VAX MACRO assembler issues
Moderator:TLE::TROWEL
Created:Mon Mar 30 1987
Last Modified:Wed Jun 04 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:257
Total number of notes:916

251.0. "Stack Switching on ALpha" by GALVIA::FOX_F () Mon Feb 10 1997 17:47

    
    
    I wonder if anyone can help me with the following problem. 
    
    I am porting an application from VAX Macro to Alpha. The VAX
    application was able to store its context ( registers, SP and FP ) in 
    a block of memory. It would subsequently restore the context by simply
    updating the SP and FP and continuing from the point at which the context 
    was saved. 
    
    I am trying to implement this stack switching on ALPHA and I have 
    come up with the following. If anyone has done this kind of thing
    before or come across the problem I would appreciate some help. 
    
    Best regards, 
    John. 
    

; MYTEST.MAR 
; Simple VAX Macro code to call the stack switcher. 
    
	.PSECT DATA 
STATE 	 = 0 
SAVED_FP = 4
SAVED_SP = 8 
INIT 	 = 2 

CTX_BLK::  	.LONG 0 
		.LONG 0 
         	.LONG 0 

	.PSECT 	CODE 
T1:: .CALL_ENTRY       	PRESERVE=<>  
	MOVAL	CTX_BLK,R3
	MOVL	FP,R4
	MOVL	(R4),SAVED_FP(R3)
	MOVL 	SP,R4
	MOVL 	(R4),SAVED_SP(R3)  
	JSB 	T2 
	RET 

T2:: .JSB_ENTRY  	PRESERVE=<>
	
	MOVL 	#INIT,STATE(R3)
	PUSHL 	R3  
	CALLS 	#1,THD$SWITCH_STACK       ; This routine brings execution
	RSB                               ; back to T1 when the epilogue 
.END T1                                   ; completes. 
    
    
; Stack Switcher 
; THD1.M64
; Alpha Code to Switch the stack. 
; 
; Set up the same offsets as before 

STATE=0
SAVED_FP=4 
SAVED_SP=8 
INIT=1 


	$ROUTINE    NAME = THD$SWITCH_STACK,-
		    KIND = STACK,-
		    SAVED_REGS = <R2,R3,R4,R5,R6,R7,R8,R9,-
				  R10,R11,R12,R13,R14,R15,R29>,-
		    STANDARD_PROLOGUE = FALSE

	$LINKAGE_SECTION


	$CODE_SECTION
;+
; Define the stack frame
;-
	.MACRO	sf_start
	sf_pv = 0
	sf_saved_pc = $RSA_OFFSET
	sf_ptr = sf_saved_pc + 8
	.ENDM	sf_start

	.MACRO	sf_save_ireg reg
	sf_saved_'reg = sf_ptr
	sf_ptr = sf_ptr + 8
	.ENDM	sf_save_ireg

	.MACRO	sf_end_ireg
	sf_saved_fp = sf_ptr
	.ENDM	sf_end_ireg

	sf_start
	sf_save_ireg	r2
	sf_save_ireg	r3
	sf_save_ireg	r4
	sf_save_ireg	r5
	sf_save_ireg	r6
	sf_save_ireg	r7
	sf_save_ireg	r8
	sf_save_ireg	r9
	sf_save_ireg	r10
	sf_save_ireg	r11
	sf_save_ireg	r12
	sf_save_ireg	r13
	sf_save_ireg	r14
	sf_save_ireg	r15
	sf_end_ireg

;+
; Procedure prologue
;-
	LDA	SP,-$SIZE(SP)		; Adjust stack pointer for stack frame
	STQ	R27,sf_pv(SP)		; Save our procedure value
	STQ	R26,sf_saved_pc(SP)	; Save registers, starting with ret adr
	STQ	R2,sf_saved_r2(SP)
	STQ	R3,sf_saved_r3(SP)
	STQ	R4,sf_saved_r4(SP)
	STQ	R5,sf_saved_r5(SP)
	STQ	R6,sf_saved_r6(SP)
	STQ	R7,sf_saved_r7(SP)
	STQ	R8,sf_saved_r8(SP)
	STQ	R9,sf_saved_r9(SP)
	STQ	R10,sf_saved_r10(SP)
	STQ	R11,sf_saved_r11(SP)
	STQ	R12,sf_saved_r12(SP)
	STQ	R13,sf_saved_r13(SP)
	STQ	R14,sf_saved_r14(SP)
	STQ	R15,sf_saved_r15(SP)
	STQ	FP,sf_saved_fp(SP)	; Save caller's FP
	MOV	SP,FP			; Make this the current procedure

	$END_PROLOGUE



;+
; First load the state code from the thread block. 
; For now this is always equal to 2 
;-
	LDL	R3,STATE(R16)		; No effect 

	LDL	R2,SAVED_FP(R16)	; R16 contains parameters passed 
	LDL 	R3,sf_saved_fp(SP)      ; Get the new FP and replace the 
	STL 	R2,0(R3)                ; one that was saved in the prolog. 

	LDL	R3,8(R2)                ; New pc entry point is at offset 
	STL	R3,sf_saved_pc(SP)      ; 8 from the new fp i.e. new 
	                                ; procedure function descriptor. 
	STL	R2,sf_pv(SP) 
	MOV 	R2,R27                  ; Set R27 equal to saved Procedure 
					; value 
 
	BR	999$				; Should never return

;+
; Procedure epilogue
;-
999$:	$BEGIN_EPILOGUE

	MOV	FP,SP			; Point SP at our stack frame
	LDQ	R28,sf_saved_pc(SP)	; Retrieve return address
	LDQ	R2,sf_saved_r2(SP)	; Restore all registers
	LDQ	R3,sf_saved_r3(SP)
	LDQ	R4,sf_saved_r4(SP)
	LDQ	R5,sf_saved_r5(SP)
	LDQ	R6,sf_saved_r6(SP)
	LDQ	R7,sf_saved_r7(SP)
	LDQ	R8,sf_saved_r8(SP)
	LDQ	R9,sf_saved_r9(SP)
	LDQ	R10,sf_saved_r10(SP)
	LDQ	R11,sf_saved_r11(SP)
	LDQ	R12,sf_saved_r12(SP)
	LDQ	R13,sf_saved_r13(SP)
	LDQ	R14,sf_saved_r14(SP)
	LDQ	R15,sf_saved_r15(SP)
	LDQ	FP,sf_saved_fp(SP)	; Restore caller's FP
	LDA	SP,$SIZE+64(SP)		; Restore stack pointer
	RET	R28			; And return

	$END_EPILOGUE

	$END_ROUTINE

	.END
    
T.RTitleUserPersonal
Name
DateLines