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

📄 asm_support.s

📁 一个用在mips体系结构中的操作系统
💻 S
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <asm.h>#include <sys/regdef.h>#define CACH_SD         0x3     /* secondary data cache */#define C_HINV          0x10    /* hit invalidate (all) */#define C_HWBINV        0x14    /* hit writeback inv. (d, sd) *//* These labels are made external so that I can set backdoor annotations   on synchronization entry and exit */                .globl _Solo_Barrier_End_1        .globl _Solo_Barrier_End_2        .globl _Solo_Lock_End        .globl _Solo_Unlock_End        /* * This file contains support routines for the solo runtime. It is  * intended to be linked in with the program being run. Note that  * it should be linked after all the application code and before * libc. */        /* *       unsigned long long _SoloLoadDouble(unsigned long long *addr) ;  * *       Perform a load double to the specified address. Assumes a *       "broken" ld instruction. * */LEAF(_LoadDouble)        /* This assumes ld does a laod into v0 and v1 */         ldc2   v0,(a0)	j ra	END(_LoadDouble)/* *       void _StoreDouble(unsigned long long *addr, unsigned long long value) ;  * *       Perform a load double to the specified address. Assumes a *       "broken" ld instruction. * */LEAF(_StoreDouble)        /* This assumes sd does astore from a2 and a3 */         sdc2   a2, (a0)	j ra	END(_StoreDouble)/* *       void _Sync(void) * *       Do a sync instruction * */LEAF(_Sync)        sync	j ra	END(_Sync)/* *       void _Prefetch(char *addr) * *       Prefetch an address */LEAF(_Prefetch)        pref   0,(a0)	j ra	END(_Prefetch)/* *       void _PrefetchX(char *addr) * *       Prefetch exclusive an address */LEAF(_PrefetchX)        pref   1,(a0)	j ra	END(_PrefetchX)/*  * void _FlushLine(char *addr) */LEAF(_FlushLine).set noreorder	cache	CACH_SD|C_HINV, 0(a0).set reorder	j	ra	END(_FlushLine)/* *       void _LockEnter(unsigned int *lockPtr);  * * Acquire a lock. Two different versions are provided.  By default, * the backoff version is used */#if 0LEAF(_LockEnter)		# This version provides no backoff    _Locktry:              ll   a1,(a0)        bne  a1,zero,_Locktry        li   a2,1        sc   a2,(a0)        beq  a2,zero,_Locktry__Lock_End:                        j    ra                     	END(_LockEnter)#endif                #if 1LEAF(_LockEnter)  /* This version is a smarter way to do exponential backoff: I only backoff when     the SC fails, so that I'm spinning with low latency until I really experience      contention *//* a2 is used to track the number of retries -- used for exponential backoff */        move a2,a0        li   a3,0		# The backoff indicator    _Locktry:              ll   a1,(a2)        bne  a1,zero,_Locktry    _Lockgrab:              li   a0,1        sc   a0,(a2)        bne  a0,zero,__Lock_End				# if SC succeeds, finish up /* Hardcode "pause" system call to implement random backoff for LL --   similar to the CheckPlatform implementation below */    _LLBackoff:             li   v0, 1029        move a0, a3		# Copy current backoff time         syscall        add  a3,a3,1		# Bump backoff time        b    _Locktry__Lock_End:                        j    ra                     	END(_LockEnter)#endif         /* *       void _UnLock(unsigned int *lockPtr);  * *  Release a lock. * */LEAF(_Unlock)        sync        sw   zero,(a0)__Unlock_End:        j    ra      	END(_Unlock)/* *	Object: * _Barrier(Barrier *barrier, int num_procs) ;  * *  This provides an effeceint barrier * *     Arguments: *      a0  barrier address (count of processes in the barrier ) *      a0 + 4 Null byte *      a1 Number of waiters at the barrier    *//* * These offset assumes that lock+0 and lock+4 are in the same * cache line while lock+128 is in a difference cache line. */	#define COUNT_OFFSET    0#define PREFETCH_OFFSET 4#define GEN_OFFSET    128   /* On next cache line *//* #define PREFETCH_ON_LL	*//* * _Brrier(Barrier *barrier, int num_procs) */LEAF(_Barrier)	        sync	/*	 *  Read the generation number for this barrier. This memory         *  location will be changed when all have arrived.	 */	lw	t0, GEN_OFFSET(a0)  loop:			/*         * count = LOAD_LINKED(counter);	 * if (count ==  2*num_proc) count = 0;         * STORE_CONDITIONAL(counter, count);         */#ifdef PREFETCH_ON_LL		sb      zero, PREFETCH_OFFSET(a0)#endif		ll	v0, COUNT_OFFSET(a0)	addu	v0, v0, 1	mul	a2, a1, 2	bne	v0, a2, 1f	move	v0, zero1:	move    t1, v0	sc	v0, COUNT_OFFSET(a0)	beq	v0, 0, loop	/*	 * If this is the last process to arrive, release the rest.         * if ((count == 0) || (count == num_proc)) goto release         */	beq     t1, 0, release	beq     t1, a1, release       /*        * while(my_gen == *cur_gen) continue;        */  wait:		 	lw      t1, GEN_OFFSET(a0)	beq     t0, t1, wait__Barrier_End_1:          	j       ra	/*         * cur_gen++;  // Release all waiters         */	  release:		addu    t0, t0, 1	sw      t0, GEN_OFFSET(a0)__Barrier_End_2:  	j       ra        END(_Barrier)/* I've hardcoded "sync" to be the syscall of choice. It's number is   1036, and I hardocde its return value in mipsy. */LEAF(_CheckPlatform)        li      v0, 1036        syscall        j       ra        END(_CheckPlatform)LEAF(_Exit)        li      v0, 1001        syscall        j       ra        END(_SoloExit)/*  * int _FetchAndStore(int *d, int val) * Atomically store val into the memory pointed to by d, and return the value * previously held by d          */LEAF(_FetchAndStore)        .set    noreorder        li      a3,0		# The backoff indicator        move    a2,a0           # Copy argument        pref    1,(a2)		# Prefetch exclusive the lock destination _FASTry:         add     t1, a1, zero    # Set up for loop        ll      t0,(a2)		# Get old value        sc   	t1,(a2)		# Store new value        nop        bne     t1,zero,_FASEnd # Leave if SC succeeded /* Hardcode "pause" system call to implement random backoff for LL --   similar to the CheckPlatform implementation below */       ## Exponential backoff        li      v0, 1029        move    a0, a3		# Copy current backoff time         syscall                 # Back off a random amount         add     a3,a3,1		# Bump backoff time        b      _FASTry             _FASEnd:             add     v0, t0, zero    # return old value        j    ra                             nopEND(FetchAndStore)        .set    reorder/*  * int _CompareAndSwap(int *d, int old, int new) * Atomically perform this operation: * if (*d == old) { *d = new; return 1;} else { return 0; }  */LEAF(_CompareAndSwap)        .set    noreorder        li      a3,0		# The backoff indicator        move    t2,a0           # Copy argument        pref    1,(t2)		# Prefetch exclusive the lock destination_CASTry:         add     t1, a2, zero    # Set up for loop        ll      t0,(t2)		# Get old value        nop        bne     t0, a1, _CASFail					# Check if *d == old        nop        sc   	t1,(t2)		# Store new value        nop        bne     t1,zero,_CASEnd # Leave if SC succeeded /* Hardcode "pause" system call to implement random backoff for LL --   similar to the CheckPlatform implementation below */       ## Exponential backoff        li      v0, 1029        move    a0, a3		# Copy current backoff time         syscall                 # Back off a random amount         add     a3,a3,1		# Bump backoff time        b      _CASTry_CASEnd:        li      v0, 1		# Return success        j       ra        nop	_CASFail:        add     v0, zero, zero	# Return failure        j       ra        nop                                END(CompareAndSwap)        .set    reorder        LEAF(_CountDown)        .set    noreorder        beq     $4, 0, _CD_done        nop_CD:            addu    $4, $4, -1        bgtz    $4, _CD        nop_CD_done:               j       ra        nopEND(_CountDown)        .set    reorder                                /* *      Object: *              LibcStart() * *      Set a marker for the start of the libc functions.  * */LEAF(LibcStart)	j ra	END(LibcStart);/* WARNING - WARNING: LibcStart MUST be the last function in this * file.  If you add a function after this it will cause the * the simulator to acquire the libc mutex when it is called. */

⌨️ 快捷键说明

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