mips-irix5.s revision 12027:1eb7dc7aa10b
111666Stushar@ece.gatech.edu/* mips.s -- assembly support. */
211666Stushar@ece.gatech.edu
311666Stushar@ece.gatech.edu/*
411666Stushar@ece.gatech.edu * QuickThreads -- Threads-building toolkit.
511666Stushar@ece.gatech.edu * Copyright (c) 1993 by David Keppel
611666Stushar@ece.gatech.edu *
711666Stushar@ece.gatech.edu * Permission to use, copy, modify and distribute this software and
811666Stushar@ece.gatech.edu * its documentation for any purpose and without fee is hereby
911666Stushar@ece.gatech.edu * granted, provided that the above copyright notice and this notice
1011666Stushar@ece.gatech.edu * appear in all copies.  This software is provided as a
1111666Stushar@ece.gatech.edu * proof-of-concept and for demonstration purposes; there is no
1211666Stushar@ece.gatech.edu * representation about the suitability of this software for any
1311666Stushar@ece.gatech.edu * purpose.
1411666Stushar@ece.gatech.edu */
1511666Stushar@ece.gatech.edu
1611666Stushar@ece.gatech.edu/* Callee-save $16-$23, $30-$31.
1711666Stushar@ece.gatech.edu *
1811666Stushar@ece.gatech.edu * $25 is used as a procedure value pointer, used to discover constants
1911666Stushar@ece.gatech.edu * in a callee.  Thus, each caller here sets $25 before the call.
2011666Stushar@ece.gatech.edu *
2111666Stushar@ece.gatech.edu * On startup, restore regs so retpc === call to a function to start.
2211666Stushar@ece.gatech.edu * We're going to call a function ($4) from within this routine.
2311666Stushar@ece.gatech.edu * We're passing 3 args, therefore need to allocate 12 extra bytes on
2411666Stushar@ece.gatech.edu * the stack for a save area.  The start routine needs a like 16-byte
2511666Stushar@ece.gatech.edu * save area.  Must be doubleword aligned (_mips r3000 risc
2611666Stushar@ece.gatech.edu * architecture_, gerry kane, pg d-23).
2711666Stushar@ece.gatech.edu */
2811666Stushar@ece.gatech.edu
2911666Stushar@ece.gatech.edu/*
3011666Stushar@ece.gatech.edu * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x
3111666Stushar@ece.gatech.edu * calling conventions for dynamically-linked code.
3211666Stushar@ece.gatech.edu */
3311666Stushar@ece.gatech.edu
3412492Sodanrc@yahoo.com.br	/* Make this position-independent code. */
3512492Sodanrc@yahoo.com.br	.option pic2
3611666Stushar@ece.gatech.edu
3711666Stushar@ece.gatech.edu	.globl qt_block
3811666Stushar@ece.gatech.edu	.globl qt_blocki
3911666Stushar@ece.gatech.edu	.globl qt_abort
4011666Stushar@ece.gatech.edu	.globl qt_start
4111666Stushar@ece.gatech.edu	.globl qt_vstart
4211666Stushar@ece.gatech.edu
4311666Stushar@ece.gatech.edu	/*
4411666Stushar@ece.gatech.edu	** $4: ptr to function to call once curr is suspended
4511666Stushar@ece.gatech.edu	**	and control is on $7's stack.
4611666Stushar@ece.gatech.edu	** $5: 1'th arg to $4.
4711666Stushar@ece.gatech.edu	** $6: 2'th arg to $4
4811666Stushar@ece.gatech.edu	** $7: sp of thread to suspend.
4911666Stushar@ece.gatech.edu	**
5011666Stushar@ece.gatech.edu	** Totally gross hack: The MIPS calling convention reserves
5111666Stushar@ece.gatech.edu	** 4 words on the stack for a0..a3.  This routine "ought" to
5211666Stushar@ece.gatech.edu	** allocate space for callee-save registers plus 4 words for
5311666Stushar@ece.gatech.edu	** the helper function, but instead we use the 4 words
5411666Stushar@ece.gatech.edu	** provided by the function that called us (we don't need to
5511666Stushar@ece.gatech.edu	** save our argument registers).  So what *appears* to be
5611666Stushar@ece.gatech.edu	** allocating only 40 bytes is actually allocating 56, by
5711666Stushar@ece.gatech.edu	** using the caller's 16 bytes.
5811666Stushar@ece.gatech.edu	**
5911666Stushar@ece.gatech.edu	** The helper routine returns a value that is passed on as the
6011666Stushar@ece.gatech.edu	** return value from the blocking routine.  Since we don't
6111666Stushar@ece.gatech.edu	** touch $2 between the helper's return and the end of
6211666Stushar@ece.gatech.edu	** function, we get this behavior for free.
6311666Stushar@ece.gatech.edu	*/
6411666Stushar@ece.gatech.eduqt_blocki:
6511666Stushar@ece.gatech.edu	sub $sp,$sp,40		/* Allocate reg save space. */
6611666Stushar@ece.gatech.edu	sw $16, 0+16($sp)
6711666Stushar@ece.gatech.edu	sw $17, 4+16($sp)
6811666Stushar@ece.gatech.edu	sw $18, 8+16($sp)
6911666Stushar@ece.gatech.edu	sw $19,12+16($sp)
7011666Stushar@ece.gatech.edu	sw $20,16+16($sp)
7111666Stushar@ece.gatech.edu	sw $21,20+16($sp)
7211666Stushar@ece.gatech.edu	sw $22,24+16($sp)
7311666Stushar@ece.gatech.edu	sw $23,28+16($sp)
7411666Stushar@ece.gatech.edu	sw $30,32+16($sp)
7511666Stushar@ece.gatech.edu	sw $31,36+16($sp)
7611666Stushar@ece.gatech.edu	add $2, $sp,$0		/* $2 <= old sp to pass to func@$4. */
7711666Stushar@ece.gatech.eduqt_abort:
7811666Stushar@ece.gatech.edu	add $sp, $7,$0		/* $sp <= new sp. */
7911666Stushar@ece.gatech.edu	.set noreorder
8011666Stushar@ece.gatech.edu	add $25, $4,$0		/* Set helper function procedure value. */
8111666Stushar@ece.gatech.edu	jal $31,$25		/* Call helper func@$4 . */
8211666Stushar@ece.gatech.edu	add $4, $2,$0		/* $a0 <= pass old sp as a parameter. */
8311666Stushar@ece.gatech.edu	.set reorder
8411666Stushar@ece.gatech.edu	lw $31,36+16($sp)	/* Restore callee-save regs... */
8511666Stushar@ece.gatech.edu	lw $30,32+16($sp)
8611666Stushar@ece.gatech.edu	lw $23,28+16($sp)
8711666Stushar@ece.gatech.edu	lw $22,24+16($sp)
8811666Stushar@ece.gatech.edu	lw $21,20+16($sp)
8911666Stushar@ece.gatech.edu	lw $20,16+16($sp)
9011666Stushar@ece.gatech.edu	lw $19,12+16($sp)
9111666Stushar@ece.gatech.edu	lw $18, 8+16($sp)
9211666Stushar@ece.gatech.edu	lw $17, 4+16($sp)
9311666Stushar@ece.gatech.edu	lw $16, 0+16($sp)	/* Restore callee-save */
9411666Stushar@ece.gatech.edu
9511666Stushar@ece.gatech.edu	add $sp,$sp,40		/* Deallocate reg save space. */
9611666Stushar@ece.gatech.edu	j $31			/* Return to caller. */
9711666Stushar@ece.gatech.edu
9811666Stushar@ece.gatech.edu	/*
9911666Stushar@ece.gatech.edu	** Non-varargs thread startup.
10011666Stushar@ece.gatech.edu	** Note: originally, 56 bytes were allocated on the stack.
10111666Stushar@ece.gatech.edu	** The thread restore routine (_blocki/_abort) removed 40
10211666Stushar@ece.gatech.edu	** of them, which means there is still 16 bytes for the
10311666Stushar@ece.gatech.edu	** argument area required by the MIPS calling convention.
10411666Stushar@ece.gatech.edu	*/
10511666Stushar@ece.gatech.eduqt_start:
10611666Stushar@ece.gatech.edu	add $4, $16,$0		/* Load up user function pu. */
10711666Stushar@ece.gatech.edu	add $5, $17,$0		/* ... user function pt. */
10811666Stushar@ece.gatech.edu	add $6, $18,$0		/* ... user function userf. */
10911666Stushar@ece.gatech.edu	add $25, $19,$0		/* Set `only' procedure value. */
11011666Stushar@ece.gatech.edu	jal $31,$25		/* Call `only'. */
11111666Stushar@ece.gatech.edu	la $25,qt_error		/* Set `qt_error' procedure value. */
11211666Stushar@ece.gatech.edu	j $25
11312492Sodanrc@yahoo.com.br
114
115	/*
116	** Save calle-save floating-point regs $f20-$f30
117	** See comment in `qt_block' about calling conventinos and
118	** reserved space.  Use the same trick here, but here we
119	** actually have to allocate all the bytes since we have to
120	** leave 4 words leftover for `qt_blocki'.
121	**
122	** Return value from `qt_block' is the same as the return from
123	** `qt_blocki'.  We get that for free since we don't touch $2
124	** between the return from `qt_blocki' and the return from
125	** `qt_block'.
126	*/
127qt_block:
128	sub $sp, $sp,56		/* 6 8-byte regs, saved ret pc, aligned. */
129	swc1 $f20,  0+16($sp)
130	swc1 $f22,  8+16($sp)
131	swc1 $f24, 16+16($sp)
132	swc1 $f26, 24+16($sp)
133	swc1 $f28, 32+16($sp)
134	swc1 $f30, 40+16($sp)
135	sw $31, 48+16($sp)
136	jal qt_blocki
137	lwc1 $f20,  0+16($sp)
138	lwc1 $f22,  8+16($sp)
139	lwc1 $f24, 16+16($sp)
140	lwc1 $f26, 24+16($sp)
141	lwc1 $f28, 32+16($sp)
142	lwc1 $f30, 40+16($sp)
143	lw $31, 48+16($sp)
144	add $sp, $sp,56
145	j $31
146
147
148	/*
149	** First, call `startup' with the `pt' argument.
150	**
151	** Next, call the user's function with all arguments.
152	** Note that we don't know whether args were passed in
153	** integer regs, fp regs, or on the stack (See Gerry Kane
154	** "MIPS R2000 RISC Architecture" pg D-22), so we reload
155	** all the registers, possibly with garbage arguments.
156	**
157	** Finally, call `cleanup' with the `pt' argument and with
158	** the return value from the user's function.  It is an error
159	** for `cleanup' to return.
160	*/
161qt_vstart:
162	add $4, $17,$0		/* `pt' is arg0 to `startup'. */
163	add $25, $18,$0		/* Set `startup' procedure value. */
164	jal $31, $25		/* Call `startup'. */
165
166	add $sp, $sp,16		/* Free extra save space. */
167	lw $4,  0($sp)		/* Load up args. */
168	lw $5,  4($sp)
169	lw $6,  8($sp)
170	lw $7, 12($sp)
171	lwc1 $f12, 0($sp)	/* Load up fp args. */
172	lwc1 $f14, 8($sp)
173	add $25, $19,$0		/* Set `userf' procedure value. */
174	jal $31,$25		/* Call `userf'. */
175
176	add $4, $17,$0		/* `pt' is arg0 to `cleanup'. */
177	add $5, $2,$0		/* Ret. val is arg1 to `cleanup'. */
178	add $25, $16,$0		/* Set `cleanup' procedure value. */
179	jal $31, $25		/* Call `cleanup'. */
180
181	la $25,qt_error		/* Set `qt_error' procedure value. */
182	j $25
183