⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips.s

📁 system C源码 一种替代verilog的语言
💻 S
字号:
/* mips.s -- assembly support. *//* * QuickThreads -- Threads-building toolkit. * Copyright (c) 1993 by David Keppel * * Permission to use, copy, modify and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice and this notice * appear in all copies.  This software is provided as a * proof-of-concept and for demonstration purposes; there is no * representation about the suitability of this software for any * purpose. *//* Callee-save $16-$23, $30-$31. * * On startup, restore regs so retpc === call to a function to start. * We're going to call a function ($4) from within this routine. * We're passing 3 args, therefore need to allocate 12 extra bytes on * the stack for a save area.  The start routine needs a like 16-byte * save area.  Must be doubleword aligned (_mips r3000 risc * architecture_, gerry kane, pg d-23). */	.globl qt_block	.globl qt_blocki	.globl qt_abort	.globl qt_start	.globl qt_vstart	/*	** $4: ptr to function to call once curr is suspended	**	and control is on $7's stack.	** $5: 1'th arg to $4.	** $6: 2'th arg to $4	** $7: sp of thread to suspend.	**	** Totally gross hack: The MIPS calling convention reserves	** 4 words on the stack for a0..a3.  This routine "ought" to	** allocate space for callee-save registers plus 4 words for	** the helper function, but instead we use the 4 words	** provided by the function that called us (we don't need to	** save our argument registers).  So what *appears* to be	** allocating only 40 bytes is actually allocating 56, by	** using the caller's 16 bytes.	**	** The helper routine returns a value that is passed on as the	** return value from the blocking routine.  Since we don't	** touch $2 between the helper's return and the end of	** function, we get this behavior for free.	*/qt_blocki:	sub $sp,$sp,40		/* Allocate reg save space. */	sw $16, 0+16($sp)	sw $17, 4+16($sp)	sw $18, 8+16($sp)	sw $19,12+16($sp)	sw $20,16+16($sp)	sw $21,20+16($sp)	sw $22,24+16($sp)	sw $23,28+16($sp)	sw $30,32+16($sp)	sw $31,36+16($sp)	add $2, $sp,$0		/* $2 <= old sp to pass to func@$4. */qt_abort:	add $sp, $7,$0		/* $sp <= new sp. */	.set noreorder	jal $31,$4		/* Call helper func@$4 . */	add $4, $2,$0		/* $a0 <= pass old sp as a parameter. */	.set reorder	lw $31,36+16($sp)	/* Restore callee-save regs... */	lw $30,32+16($sp)	lw $23,28+16($sp)	lw $22,24+16($sp)	lw $21,20+16($sp)	lw $20,16+16($sp)	lw $19,12+16($sp)	lw $18, 8+16($sp)	lw $17, 4+16($sp)	lw $16, 0+16($sp)	/* Restore callee-save */	add $sp,$sp,40		/* Deallocate reg save space. */	j $31			/* Return to caller. */	/*	** Non-varargs thread startup.	** Note: originally, 56 bytes were allocated on the stack.	** The thread restore routine (_blocki/_abort) removed 40	** of them, which means there is still 16 bytes for the	** argument area required by the MIPS calling convention.	*/qt_start:	add $4, $16,$0		/* Load up user function pu. */	add $5, $17,$0		/* ... user function pt. */	add $6, $18,$0		/* ... user function userf. */	jal $31,$19		/* Call `only'. */	j qt_error	/*	** Save calle-save floating-point regs $f20-$f30	** See comment in `qt_block' about calling conventinos and	** reserved space.  Use the same trick here, but here we	** actually have to allocate all the bytes since we have to	** leave 4 words leftover for `qt_blocki'.	**	** Return value from `qt_block' is the same as the return from	** `qt_blocki'.  We get that for free since we don't touch $2	** between the return from `qt_blocki' and the return from	** `qt_block'.	*/qt_block:	sub $sp, $sp,56		/* 6 8-byte regs, saved ret pc, aligned. */	swc1 $f20,  0+16($sp)	swc1 $f22,  8+16($sp)	swc1 $f24, 16+16($sp)	swc1 $f26, 24+16($sp)	swc1 $f28, 32+16($sp)	swc1 $f30, 40+16($sp)	sw $31, 48+16($sp)	jal qt_blocki	lwc1 $f20,  0+16($sp)	lwc1 $f22,  8+16($sp)	lwc1 $f24, 16+16($sp)	lwc1 $f26, 24+16($sp)	lwc1 $f28, 32+16($sp)	lwc1 $f30, 40+16($sp)	lw $31, 48+16($sp)	add $sp, $sp,56	j $31	/*	** First, call `startup' with the `pt' argument.	**	** Next, call the user's function with all arguments.	** Note that we don't know whether args were passed in	** integer regs, fp regs, or on the stack (See Gerry Kane	** "MIPS R2000 RISC Architecture" pg D-22), so we reload	** all the registers, possibly with garbage arguments.	**	** Finally, call `cleanup' with the `pt' argument and with	** the return value from the user's function.  It is an error	** for `cleanup' to return.	*/qt_vstart:	add $4, $17,$0		/* `pt' is arg0 to `startup'. */	jal $31, $18		/* Call `startup'. */	add $sp, $sp,16		/* Free extra save space. */	lw $4,  0($sp)		/* Load up args. */	lw $5,  4($sp)	lw $6,  8($sp)	lw $7, 12($sp)	lwc1 $f12, 0($sp)	/* Load up fp args. */	lwc1 $f14, 8($sp)	jal $31,$19		/* Call `userf'. */	add $4, $17,$0		/* `pt' is arg0 to `cleanup'. */	add $5, $2,$0		/* Ret. val is arg1 to `cleanup'. */	jal $31, $16		/* Call `cleanup'. */	j qt_error

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -