directory_asm.s 1.84 KB
/*
 * 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 <regdef.h>
#include "embra.h"
#include "mem_control.h"
#include "directory.h"

#define PENDING_MASK 0x80000000
#define PENDING_SHIFT 31

LEAF( Dir_Lock_Line )
    /* Try to aquire directory entry */
 	li  t0, PENDING_MASK
.set noreorder
1:	
    ll   t1,   0(a0)
    srl  t2,   t1, PENDING_SHIFT #if pending bit is set, spin
    bnez t2,   1b
    or   t1,   t0                #set pending bit
    move t3,   t1
    sc   t1,   0(a0)
    beqz t1,   1b                #if sc fails, try again
    nop
.set reorder
    move v0,   t3
    j    ra
END( Dir_Lock_Line )


/* XXX In addition to the directory stuff, I am also placing
 * other synchronization primitives here until we can hide
 * them in the vcode implementation -BL
 */	
    /* compare_and_swap( void* addr, unsigned old_val , unsigned new_val )*/
    /* { ATOMIC( if( *addr == old_val ) */
    /* { *addr == new_val;  return 1; } */
    /* else { return 0; } )*/
    /* XXX - ONLY use t0-t2, t7-t9, a0-a3, v0-v1 */

/* ***************************************************************
 * compare_and_swap
 *
 * (MPinMP only)
 * !! registers have been renamed!!!! something will break here.
 * ***************************************************************/
        
LEAF( compare_and_swap)
    /* int v0 = new_val */
    move   v0,    a2
.set noreorder
    ll     t1,    0(a0)
    /* if( LL(  *addr) != old_val ) return 0; */
    bne    t1,    a1, 2f
    nop
    sc     v0,    0(a0)
    /* return( SC(*addr = new_val));  */
    /* } */
    j      ra
.set reorder
2:
    /* return 0 ;  */
    move v0, zero
    j ra
END( compare_and_swap )

LEAF(SyncInstr)
        sync
        j ra
END(SyncInstr)