atom.s 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * int cas(ulong *p, ulong ov, ulong nv);
  3. */
  4. #define CLREX WORD $0xf57ff01f
  5. #define LDREX(a,r) WORD $(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
  6. /* `The order of operands is from left to right in dataflow order' - asm man */
  7. #define STREX(v,a,r) WORD $(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
  8. TEXT cas+0(SB),0,$0 /* r0 holds p */
  9. TEXT casp+0(SB),0,$0 /* r0 holds p */
  10. MOVW ov+4(FP), R1
  11. MOVW nv+8(FP), R2
  12. spincas:
  13. LDREX(0,3) /* LDREX 0(R0),R3 */
  14. CMP.S R3, R1
  15. BNE fail
  16. STREX(2,0,4) /* STREX 0(R0),R2,R4 */
  17. CMP.S $0, R4
  18. BNE spincas
  19. MOVW $1, R0
  20. RET
  21. fail:
  22. // CLREX /* fpiarm in pre-v7 ports needs to emulate this */
  23. MOVW $0, R0
  24. RET
  25. TEXT _xinc(SB), $0 /* void _xinc(long *); */
  26. TEXT ainc(SB), $0 /* long ainc(long *); */
  27. spinainc:
  28. LDREX(0,3) /* LDREX 0(R0),R3 */
  29. ADD $1,R3
  30. STREX(3,0,4) /* STREX 0(R0),R3,R4 */
  31. CMP.S $0, R4
  32. BNE spinainc
  33. MOVW R3, R0
  34. RET
  35. TEXT _xdec(SB), $0 /* long _xdec(long *); */
  36. TEXT adec(SB), $0 /* long adec(long *); */
  37. spinadec:
  38. LDREX(0,3) /* LDREX 0(R0),R3 */
  39. SUB $1,R3
  40. STREX(3,0,4) /* STREX 0(R0),R3,R4 */
  41. CMP.S $0, R4
  42. BNE spinadec
  43. MOVW R3, R0
  44. RET
  45. TEXT loadlinked(SB), $0 /* long loadlinked(long *); */
  46. LDREX(0,0) /* LDREX 0(R0),R0 */
  47. RET
  48. TEXT storecond(SB), $0 /* int storecond(long *, long); */
  49. MOVW ov+4(FP), R3
  50. STREX(3,0,0) /* STREX 0(R0),R3,R0 */
  51. RSB $1, R0
  52. RET