From: Aaron [aaron.d.mullens@lmco.com] Sent: Tuesday, December 10, 2002 9:01 AM To: Info-VAX@Mvb.Saic.Com Subject: Re: Another Porting Problem VAXman- @SendSpamHere.ORG wrote in message > > Perhaps a larger snippet of the code would help. > OK, I'll give you a large code segment. I in no way expect you to go over it all, but you may be interested in seeing it. I have been struggling with this section of code for weeks now. If you believe I need to learn Macro64 after reviewing it, then break it to me gently, and again thanks for your time. I listed two .sbttl here, the first function gets the Initial_FP and I have been able to do this in C and Ada and pass it into a assembly routine on an Alpha. The functions are called by Ada units. .sbttl Initialize Tasking Routine ; This routine searches back through stack frames for the second to last FP. ; This FP is needed for task stack initialization to keep Ada & the debugger ; happy. ; ; INPUTS: Offset of the stack top pointer for the currently running ; VMS version ; ; OUTPUTS: None STACK_TOP = ^X4 ; stack lower limit (VAX stacks grow down.) ; We change this to be the bottom of P0 space ; instead of P1 space. The offset is different ; between 4.x and 5.x. .psect $DATA,long,noexe,pic,rel,noshr,wrt Initial_FP: .long 0 .psect $CODE,long,exe,pic,rel,shr,nowrt .entry $Initialize_Tasking,^m movl FP,R11 ; start with the current FP 0$: movl SF$L_SAVE_FP(R11),R10 ; Get the previous FP tstl SF$L_SAVE_FP(R10) ; is the FP before that = 0 ? beql 1$ ; if so, remember this FP movl R10,R11 ; else keep looking brb 0$ 1$: movl R11,Initial_FP ; record the last FP with ; a nonzero previous FP ; Initialize Ada stack limit to prevent errors tstl -(SP) ; make room for a longword on the stack pushab (SP) ; record the address of the argument calls #1,G^Ada$Current_Task ; get the main task's Ada TCB addl3 (sp)+,STACK_TOP(ap),r0 clrl (R0) ; change the lower task stack bound to 0 ; (bottom of P0) to prevent Ada errors 4$: ret .sbttl Initialize Task Stack Routine ; This routine initializes the new task stack for ease of switching .entry $INITIALIZE_STACK,^m movl 4(AP),R10 ; get the TCB passed as an argument .if equal Debug_Stats #3,#0,r10 .endc ; Create an initial stack frame on the new stack: pushl FP ; save the creator task's Frame Pointer movl SP,R11 ; save the creator task's Stack Pointer movl Initial_SP(R10),SP ; get the initial SP for the new task movl Initial_FP,FP ; set the initial FP for the new task calls #0,1$ ; create a stack frame on the new stack, 1$: .word 0 ; ...filling in FP with the current SP ; Initial condition handler is passed in the Saved_SP field of the TCB movl Saved_SP(R10),(FP) ; put Condition Handler on top of stack clrl SF$L_SAVE_PC(FP) ; clear the return PC for the new task ; Create a second stack frame with AST arguments: subl #ArgsLen,SP ; make room for the argument list. movc3 #ArgsLen,@SF$L_SAVE_AP(FP), - (SP) ; copy creator's arg list onto the stack movl Initial_PC(R10), - Return_PC(SP) ; make the AST return to the new task addl #2,Return_PC(SP) ; adjust the PC for the entry mask subl #SF$L_SAVE_REGS,SP ; adjust the SP for remaining frame movc3 #SF$L_SAVE_REGS,4(R11),- ; copy the rest of the creator's (SP) ; current stack frame insv #0,#SF$V_SAVE_MASK, - ; indicate no registers were saved #SF$S_SAVE_MASK,SF$W_SAVE_MASK(SP) movl FP,SF$L_SAVE_FP(SP) ; update the saved FP to indicate ; the initial frame on the new stack pushl SP ; record the current SP as the FP movl SP,Saved_SP(R10) ; for when we get rescheduled moval $SCHED_DATA + PQLen,R0 ; get the address of scheduling data movl Priority(R10),R2 ; get the priority of the current task bbss R2,Queue_Info(R0),2$ ; mark queue non-empty 2$: insqhi (R10),PQueue(R0)[R2] ; put current task at head of Queue movl R11,SP ; restore creator's SP popl FP ; restore creator's FP movl TCB(R0),R1 ; get current task cmpl Priority(R1),Priority(R10) ; if current task higher priority, blss Return ; that's all - we're done $CANTIM_S - ; if new task is higher priority, REQIDT=#-1 ; cancel any time-slicing calls #0,$SCHEDULE ; and reschedule Return: ret ; & return to creator ; $Initialize_Stack yields new task stack contents: ; The address of Frame 1 is saved as the SP for the task to use when it is ; first scheduled. ; ; Task Frame 1 (AST Frame) : ; Condition_Handler = (Copied & Ignored) ; Frame Flags = Copied PSL & no saved regs ; Saved AP = (Copied & Ignored) ; Saved FP = Address of Frame 0 ; Saved PC = (Copied & Ignored) ; Args: Arg Count = 5 (Copied) ; AST Arg = (Copied & Ignored) ; Saved R0 = (Copied & Ignored) ; Saved R1 = (Copied & Ignored) ; Return PC = Task address+2 (passed in TCB) ; Saved PSL = (Copied) ; ; Task Frame 0 (Initial Task Frame) : ; Condition_Handler = Passed in TCB's saved FP field ; Frame Flags = Created by CALLS ; Saved AP = Created by CALLS & Ignored ; Saved FP = Initial FP for Ada & Debugger ;Initial_SP: Saved PC = 0