Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 *      R4000 user-level atomic operations
 */

#define LL(base, rt)    WORD    $((060<<26)|((base)<<21)|((rt)<<16))
#define SC(base, rt)    WORD    $((070<<26)|((base)<<21)|((rt)<<16))
#define NOOP            WORD    $0x27

TEXT ainc(SB), 1, $-4                   /* long ainc(long *); */
TEXT _xinc(SB), 1, $-4                  /* void _xinc(long *); */
        MOVW    R1, R2                  /* address of counter */
loop:   MOVW    $1, R3
        LL(2, 1)
        NOOP
        ADDU    R1, R3
        MOVW    R3, R1                  /* return new value */
        SC(2, 3)
        NOOP
        BEQ     R3,loop
        RET

TEXT adec(SB), 1, $-4                   /* long adec(long*); */
TEXT _xdec(SB), 1, $-4                  /* long _xdec(long *); */
        MOVW    R1, R2                  /* address of counter */
loop1:  MOVW    $-1, R3
        LL(2, 1)
        NOOP
        ADDU    R1, R3
        MOVW    R3, R1                  /* return new value */
        SC(2, 3)
        NOOP
        BEQ     R3,loop1
        RET

/*
 * int cas(uint* p, int ov, int nv);
 */
TEXT cas(SB), 1, $-4
        MOVW    ov+4(FP), R2
        MOVW    nv+8(FP), R3
spincas:
        LL(1, 4)                        /* R4 = *R1 */
        NOOP
        BNE     R2, R4, fail
        SC(1, 3)                        /* *R1 = R3 */
        NOOP
        BEQ     R3, spincas             /* R3 == 0 means store failed */
        MOVW    $1, R1
        RET
fail:
        MOVW    $0, R1
        RET

Generated by GNU Enscript 1.6.6.