; /* @(#)pswmacro.ah	1.1 96/05/23 08:56:58, TEI */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		 macros: Do_install and init_TLB
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  /* $Id$ */

;* File information and includes.

	.file	"macro.ah"
	.ident	"@(#)pswmacro.ah	1.1 96/05/23 08:56:58, TEI"


	.macro	CONST32, RegName, RegValue
		const	RegName, RegValue
		consth	RegName, RegValue
	.endm

	.macro	CONSTX, RegName, RegValue
		.if (RegValue) <= 0x0000ffff
			const	RegName, RegValue
		.else
			const	RegName, RegValue
			consth	RegName, RegValue
		.endif
	.endm

	.macro	PRODEV, RegName
		srl	RegName, RegName, 24
	.endm

;
;* MACRO TO INSTALL VECTOR TABLE ENTRIES
;
 
;* Assumes vector table address in v0
 
        .macro  _setvec, trapnum, trapaddr
                mfsr    v0, vab                 ;
                const   v2, trapnum             ;
                sll     v1, v2, 2               ;
                add     v1, v1, v0              ; v0 has location of vector tab
 
                const   v2, trapaddr            ;
                consth  v2, trapaddr            ;
                store   0, 0, v2, v1            ;
                nop                             ;
        .endm
 
        .macro  syscall, name
                const     tav, HIF_@name        ;
                asneq   V_SYSCALL, gr1, gr1     ;
                nop                             ;
                nop                             ;
        .endm



;* MACRO TO INSTALL VECTOR TABLE ENTRIES 

	.macro	Do_Install, V_Number, V_Address
		const	lr4, V_Address 
		consth	lr4, V_Address
		const	lr3, V_Number * 4
		consth	lr3, V_Number * 4
		call	lr0, V_Install
		nop
	.endm

	.macro	Do_InstallX, V_Number, V_Address
		const	lr4, V_Address 
		consth	lr4, V_Address
		const	lr3, V_Number * 4
		consth	lr3, V_Number * 4
		call	lr0, V_InstallX
		nop
	.endm



; push a register onto the stack
	.macro	pushreg, reg, sp
	sub	sp, sp, 4		; adjust stack pointer
	store	0, 0, reg, sp		; push register
	.endm

	.macro	push, sp, reg
		sub	sp, sp, 4
		store	0, 0, reg, sp
	.endm

; pop the register from stack
	.macro	popreg, reg, sp
	load	0, 0, reg, sp		; pop register
	add	sp, sp, 4		; adjust stack pointer
	.endm
	.macro	pop, reg, sp
		load	0, 0, reg, sp
		add	sp, sp, 4
	.endm

; push a special register onto stack
	.macro	pushspcl, spcl, tmpreg, sp
	sub	sp, sp, 4		; adjust stack pointer
	mfsr	tmpreg, spcl		; get spcl reg
	store	0, 0, tmpreg, sp	; push onto stack
	.endm

	.macro	pushsr, sp, reg, sreg
		mfsr	reg, sreg
		sub	sp, sp, 4
		store	0, 0, reg, sp
	.endm

; pop a special register from stack
	.macro	popspcl, spcl, tmpreg, sp
	load	0, 0, tmpreg, sp	; pop from stack
	add	sp, sp, 4		; adjust stack pointer
	mtsr	spcl, tmpreg		; set spcl reg
	.endm

	.macro	popsr, sreg, reg, sp
		load	0, 0, reg, sp
		add	sp, sp, 4
		mtsr	sreg, reg
	.endm

;
; save freeze mode registers on memory stack.
;

	.macro	SaveFZState,	tmp1, tmp2

		; save freeze mode registers.

		pushspcl pc0, tmp1, msp
		pushspcl pc1, tmp1, msp
		pushspcl alu, tmp1, msp

		pushspcl cha, tmp1, msp
		pushspcl chd, tmp1, msp
		pushspcl chc, tmp1, msp

		pushspcl ops, tmp1, msp

		; turn freeze off

		const	tmp2, FZ
		mfsr	tmp1, cps
		andn	tmp1, tmp1, tmp2
		mtsr	cps, tmp1
	.endm

; restore freeze mode registers from memory stack.

	.macro	RestoreFZState, tmp1, tmp2

		; turn freeze on

		const	tmp2, (FZ|DI|DA)
		mfsr	tmp1, cps
		or	tmp1, tmp1, tmp2
		mtsr	cps, tmp1

		; restore freeze mode registers.

		popspcl	ops, tmp1, msp
		popspcl	chc, tmp1, msp
		popspcl	chd, tmp1, msp
		popspcl	cha, tmp1, msp
		popspcl	alu, tmp1, msp
		popspcl	pc1, tmp1, msp
		popspcl	pc0, tmp1, msp
	.endm

;
;*
;
	.equ	WS,	512				; window size
	.equ	RALLOC,	4 * 4				; stack alloc for C
	.equ	SIGCTX_UM_SIZE,	40 * 4			; 
	.equ	SIGCTX_RFB, (38) * 4			; user mode saved
	.equ	SIGCTX_SM_SIZE, 12 * 4			;
	.equ	SIGCTX_SIG, (11)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_GR1, (10)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_RAB, (9)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_PC0, (8)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_PC1, (7)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_PC2, (6)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_CHC, (3)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_OPS, (1)*4 + SIGCTX_UM_SIZE	;
	.equ	SIGCTX_TAV, (0)*4 + SIGCTX_UM_SIZE	;

	.macro	sup_sv
		add	it2, trapreg, 0			; transfer signal #
		sub	msp, msp, 4			;
		store	0, 0, it2, msp			; save signal number
		sub	msp, msp, 4			; push gr1

		store	0, 0, gr1, msp			; 
		sub	msp, msp, 4			; push rab
		store	0, 0, rab, msp			; 
		const	it0, WS				; Window size	

		sub	rab, rfb, it0			; set rab = rfb-512
		pushsr	msp, it0, PC0			; save program counter0
		pushsr	msp, it0, PC1			; save program counter1
		pushsr	msp, it0, PC2			; save program counter2

		pushsr	msp, it0, CHA			; save channel address
		pushsr	msp, it0, CHD			; save channel data
		pushsr	msp, it0, CHC			; save channel control
		pushsr	msp, it0, ALU			; save alu

		pushsr	msp, it0, OPS			; save ops
		sub	msp, msp, 4			; 
		store	0, 0, tav, msp			; push tav
		mtsrim	chc, 0				; no loadm/storem

		mfsr	it0, ops			; get ops value
		const	it1, (TD | DI)			; disable interrupts
		consth	it1, (TD | DI)			; disable interrupts
		or	it0, it0, it1			; set bits

		mtsr	ops, it0			; set new ops
		const	it0, sigcode			; signal handler
		consth	it0, sigcode			; signal handler
		mtsr	pc1, it0			; store pc1

		add	it1, it0, 4			; next addr
		mtsr	pc0, it1			; store pc1 location
		iret					; return
		nop					; ALIGN
	.endm

	.macro	sig_return
		mfsr	it0, cps			; get processor status
		const	it1, FZ|DA			; Freeze + traps disable
		or	it0, it0, it1			; to set FZ+DA
		mtsr	cps, it0			; in freeze mode

		load	0, 0, tav, msp			; restore tav
		add	msp, msp, 4			;
		
		popsr	OPS,it0, msp			;
		popsr	ALU,it0, msp			;
		popsr	CHC,it0, msp			;
		popsr	CHD,it0, msp			;

		popsr	CHA,it0, msp			;
		popsr	PC2,it0, msp			;
		popsr	PC1,it0, msp			;
		popsr	PC0,it0, msp			;

		load	0, 0, rab, msp			;
		add	msp, msp, 4			;
		load	0, 0, it0, msp			;
		add	gr1, it0, 0			; pop rsp

		add	msp, msp, 8			; discount signal #
		iret
	.endm

	.macro	repair_R_stack
		add	v0, msp, SIGCTX_GR1		; interrupted gr1
		load 	0, 0, v2, v0			;
		add	v0, msp, SIGCTX_RFB		;
		load	0, 0, v3, v0			; interupted rfb

		const	v1, WS				;	
		sub	v1, v3, v1			; rfb-512
		cpltu	v0, v2, v1			; test gr1 < rfb-512
		jmpf	v0, $1				; 

		add	gr1, rab, 0			;
		add	v2, v1, 0			; set LB = rfb-512
$1:
;* if gr1 < rfb-512 yes LB = rfb-512 signalled during spill
;* if no, LB=gr1 interrupted cache < 126 registers
		cpleu	v0, v2, rfb			; test LB<=rfb
		jmpf	v0, $2				;
		nop					;
		add	v2, rfb, 0			;
$2:
		cpeq	v0, v3, rfb			; fill rfb->'rfb
		jmpt	v0, $3				; if rfb==rfb'
		const	tav, (0x80<<2)			; prepare for fill
		or	tav, tav, v2			; 

		mtsr	IPA, tav			; IPA=LA<<2
		sub	tav, v3, gr98			; cache fill LA->rfb
		srl	tav, tav, 2			; convert to words
		sub	tav, tav, 1			; 

		mtsr	cr, tav				;
		loadm	0, 0, gr0, v2			; fill from LA->rfb
$3:
		add	rfb, v3, 0			; move rfb upto 'rfb
		sub	rab, v1, 0			; assign rab to rfb-512

		add	v0, msp, SIGCTX_GR1		;
		load	0, 0, v2, v0			; v0 = interrupted gr1
		add	gr1, v2, 0			; move gr1 upto 'gr1
		nop					;
	.endm	
		
	.macro	repair_regs
		mtsrim	cr, 29 - 1			; to restore locals
		loadm	0, 0, v0, msp			;
		add	msp, msp, 29*4			; 
		popsr	Q, tav, msp			; 

		popsr	IPC, tav, msp			; 
		popsr	IPB, tav, msp			; 
		popsr	IPA, tav, msp			; 
		pop	FPStat3, msp			; floating point regs

		pop	FPStat2, msp			; floating point regs
		pop	FPStat1, msp			; floating point regs
		pop	FPStat0, msp			; floating point regs

		add	msp, msp, 3*4			; R-stack repaired
	.endm

;
;*HIF related...
;




; send the message in bufaddr to Montip.
	.macro	SendMessageToMontip,	bufaddr
	const	lr2, bufaddr
$1:
	call	lr0, _msg_send
	consth	lr2, bufaddr
	cpeq	gr96, gr96, 0
	jmpf	gr96, $1
	const	lr2, bufaddr
	.endm

; build a HIF_CALL message in bufaddr to send to montip.
	.macro	BuildHIFCALLMsg,	bufaddr, tmp1, tmp2
	const	tmp1, bufaddr
	consth	tmp1, bufaddr
	const	tmp2, HIF_CALL_MSGCODE
	store	0, 0, tmp2, tmp1	; msg code
	add	tmp1, tmp1, 4
	const	tmp2, HIF_CALL_MSGLEN	
	store	0, 0, tmp2, tmp1	; msg len
	add	tmp1, tmp1, 4
	store	0, 0, gr121, tmp1	; service number
	add	tmp1, tmp1, 4
	store	0, 0, lr2, tmp1		; lr2
	add	tmp1, tmp1, 4
	store	0, 0, lr3, tmp1		; lr3
	add	tmp1, tmp1, 4
	store	0, 0, lr4, tmp1		; lr4
	.endm

;
;* 
;* All the funky AMD style macros go in here...simply for 
;* compatility
;
;
  .macro        IMPORT, symbol
        .extern symbol
  .endm

  .macro        GLOBAL, symbol
        .global symbol
  .endm

  .macro        USESECT, name, type
        .sect   name, type
        .use    name
  .endm

  .macro        SECTION, name, type
        .sect   name, type
  .endm

 .macro FUNC, fname, lineno
        .global fname
fname:
 .endm

 .macro ENDFUNC, fname, lineno
 .endm

;*************************************LONG
 .macro LONG, varname
varname:
        .block  4
 .endm

;*************************************UNSIGNED LONG
 .macro ULONG, varname
varname:
        .block  4
 .endm

;*************************************SHORT
 .macro SHORT, varname
varname:
        .block  2
 .endm

;*************************************CHAR
 .macro CHAR, varname
varname:
        .block  1
 .endm 

;*************************************LONGARRAY
 .macro LONGARRAY, name, count
name:
        .block  count*4
 .endm

;*************************************SHORTARRAY

 .macro SHORTARRAY, name, count
name:
        .block  count*2
 .endm

;*************************************CHARARRAY

 .macro CHARARRAY, name, count
name:
        .block  count
 .endm


;*************************************VOID_FPTR

 .macro VOID_FPTR, name
name:
        .block  4
 .endm
