|
|
| version 1.4, 2003/07/20 03:55:25 | version 1.5, 2004/02/13 18:44:42 |
|---|---|
| Line 80 | Line 80 |
| * atomic instructions are MP safe, the nonlocked instructions are | * atomic instructions are MP safe, the nonlocked instructions are |
| * local-interrupt-safe (so we don't depend on C 'X |= Y' generating an | * local-interrupt-safe (so we don't depend on C 'X |= Y' generating an |
| * atomic instruction). | * atomic instruction). |
| * | |
| * +m - memory is read and written (=m - memory is only written) | |
| * iq - integer constant or %ax/%bx/%cx/%dx (ir = int constant or any reg) | |
| * (Note: byte instructions only work on %ax,%bx,%cx, or %dx). iq | |
| * is good enough for our needs so don't get fancy. | |
| */ | */ |
| #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 9) | |
| /* egcs 1.1.2+ version */ | /* egcs 1.1.2+ version */ |
| #define ATOMIC_ASM(NAME, TYPE, OP, V) \ | #define ATOMIC_ASM(NAME, TYPE, OP, V) \ |
| Line 89 static __inline void \ | Line 93 static __inline void \ |
| atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ |
| { \ | { \ |
| __asm __volatile(MPLOCKED OP \ | __asm __volatile(MPLOCKED OP \ |
| : "=m" (*p) \ | : "+m" (*p) \ |
| : "0" (*p), "ir" (V)); \ | : "iq" (V)); \ |
| } \ | } \ |
| static __inline void \ | static __inline void \ |
| atomic_##NAME##_##TYPE##_nonlocked(volatile u_##TYPE *p, u_##TYPE v)\ | atomic_##NAME##_##TYPE##_nonlocked(volatile u_##TYPE *p, u_##TYPE v)\ |
| { \ | { \ |
| __asm __volatile(MPLOCKED OP \ | __asm __volatile(MPLOCKED OP \ |
| : "=m" (*p) \ | : "+m" (*p) \ |
| : "0" (*p), "ir" (V)); \ | : "iq" (V)); \ |
| } | } |
| #else | |
| /* gcc <= 2.8 version */ | |
| #define ATOMIC_ASM(NAME, TYPE, OP, V) \ | |
| static __inline void \ | |
| atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | |
| { \ | |
| __asm __volatile(MPLOCKED OP \ | |
| : "=m" (*p) \ | |
| : "ir" (V)); \ | |
| } \ | |
| static __inline void \ | |
| atomic_##NAME##_##TYPE##_nonlocked(volatile u_##TYPE *p, u_##TYPE v)\ | |
| { \ | |
| __asm __volatile(OP \ | |
| : "=m" (*p) \ | |
| : "ir" (V)); \ | |
| } | |
| #endif | |
| #endif /* KLD_MODULE */ | #endif /* KLD_MODULE */ |
| #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 9) | |
| /* egcs 1.1.2+ version */ | /* egcs 1.1.2+ version */ |
| ATOMIC_ASM(set, char, "orb %b2,%0", v) | ATOMIC_ASM(set, char, "orb %b2,%0", v) |
| ATOMIC_ASM(clear, char, "andb %b2,%0", ~v) | ATOMIC_ASM(clear, char, "andb %b2,%0", ~v) |
| Line 144 ATOMIC_ASM(clear, long, "andl %2,%0" | Line 127 ATOMIC_ASM(clear, long, "andl %2,%0" |
| ATOMIC_ASM(add, long, "addl %2,%0", v) | ATOMIC_ASM(add, long, "addl %2,%0", v) |
| ATOMIC_ASM(subtract, long, "subl %2,%0", v) | ATOMIC_ASM(subtract, long, "subl %2,%0", v) |
| #else | |
| /* gcc <= 2.8 version */ | |
| ATOMIC_ASM(set, char, "orb %1,%0", v) | |
| ATOMIC_ASM(clear, char, "andb %1,%0", ~v) | |
| ATOMIC_ASM(add, char, "addb %1,%0", v) | |
| ATOMIC_ASM(subtract, char, "subb %1,%0", v) | |
| ATOMIC_ASM(set, short, "orw %1,%0", v) | |
| ATOMIC_ASM(clear, short, "andw %1,%0", ~v) | |
| ATOMIC_ASM(add, short, "addw %1,%0", v) | |
| ATOMIC_ASM(subtract, short, "subw %1,%0", v) | |
| ATOMIC_ASM(set, int, "orl %1,%0", v) | |
| ATOMIC_ASM(clear, int, "andl %1,%0", ~v) | |
| ATOMIC_ASM(add, int, "addl %1,%0", v) | |
| ATOMIC_ASM(subtract, int, "subl %1,%0", v) | |
| ATOMIC_ASM(set, long, "orl %1,%0", v) | |
| ATOMIC_ASM(clear, long, "andl %1,%0", ~v) | |
| ATOMIC_ASM(add, long, "addl %1,%0", v) | |
| ATOMIC_ASM(subtract, long, "subl %1,%0", v) | |
| #endif | |
| #endif /* ! _MACHINE_ATOMIC_H_ */ | #endif /* ! _MACHINE_ATOMIC_H_ */ |