libc: update atomic ops and fp code for arm (from sources)
This commit is contained in:
parent
68c5dc8014
commit
ae116c9446
12 changed files with 52 additions and 22 deletions
|
@ -1,44 +1,47 @@
|
|||
#define CLREX WORD $0xf57ff01f
|
||||
#define LDREX(a,r) WORD $(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
|
||||
/* `The order of operands is from left to right in dataflow order' - asm man */
|
||||
#define STREX(v,a,r) WORD $(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
|
||||
|
||||
/*
|
||||
* int cas(ulong *p, ulong ov, ulong nv);
|
||||
*/
|
||||
|
||||
#define LDREX(a,r) WORD $(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
|
||||
#define STREX(a,v,r) WORD $(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
|
||||
|
||||
TEXT cas+0(SB),0,$12 /* r0 holds p */
|
||||
TEXT casp+0(SB),0,$12 /* r0 holds p */
|
||||
TEXT casl+0(SB),0,$12 /* r0 holds p */
|
||||
TEXT cas+0(SB),0,$0 /* r0 holds p */
|
||||
TEXT casp+0(SB),0,$0 /* r0 holds p */
|
||||
MOVW ov+4(FP), R1
|
||||
MOVW nv+8(FP), R2
|
||||
spincas:
|
||||
LDREX(0,3) /* LDREX 0(R0),R3 */
|
||||
CMP.S R3, R1
|
||||
BNE fail
|
||||
STREX(0,2,4) /* STREX 0(R0),R2,R4 */
|
||||
STREX(2,0,4) /* STREX 0(R0),R2,R4 */
|
||||
CMP.S $0, R4
|
||||
BNE spincas
|
||||
MOVW $1, R0
|
||||
RET
|
||||
fail:
|
||||
CLREX
|
||||
MOVW $0, R0
|
||||
RET
|
||||
|
||||
TEXT _xinc(SB), $0 /* void _xinc(long *); */
|
||||
TEXT ainc(SB), $0 /* long ainc(long *); */
|
||||
spinainc:
|
||||
LDREX(0,3) /* LDREX 0(R0),R3 */
|
||||
ADD $1,R3
|
||||
STREX(0,3,4) /* STREX 0(R0),R2,R4 */
|
||||
STREX(3,0,4) /* STREX 0(R0),R3,R4 */
|
||||
CMP.S $0, R4
|
||||
BNE spinainc
|
||||
MOVW R3, R0
|
||||
RET
|
||||
|
||||
TEXT adec(SB), $0 /* long ainc(long *); */
|
||||
TEXT _xdec(SB), $0 /* long _xdec(long *); */
|
||||
TEXT adec(SB), $0 /* long adec(long *); */
|
||||
spinadec:
|
||||
LDREX(0,3) /* LDREX 0(R0),R3 */
|
||||
SUB $1,R3
|
||||
STREX(0,3,4) /* STREX 0(R0),R3,R4 */
|
||||
STREX(3,0,4) /* STREX 0(R0),R3,R4 */
|
||||
CMP.S $0, R4
|
||||
BNE spinadec
|
||||
MOVW R3, R0
|
||||
|
@ -50,6 +53,6 @@ TEXT loadlinked(SB), $0 /* long loadlinked(long *); */
|
|||
|
||||
TEXT storecond(SB), $0 /* int storecond(long *, long); */
|
||||
MOVW ov+4(FP), R3
|
||||
STREX(0,3,4) /* STREX 0(R0),R3,R0 */
|
||||
STREX(3,0,0) /* STREX 0(R0),R3,R0 */
|
||||
RSB $1, R0
|
||||
RET
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void cycles(uvlong*u)
|
||||
#pragma profile off
|
||||
|
||||
void
|
||||
cycles(uvlong*u)
|
||||
{
|
||||
*u = 0LL;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
TEXT getcallerpc(SB), $-4
|
||||
TEXT getcallerpc(SB), 1, $-4
|
||||
MOVW 0(R13), R0
|
||||
RET
|
||||
|
|
21
sys/src/libc/arm/getfcr.vfp.S
Normal file
21
sys/src/libc/arm/getfcr.vfp.S
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* for VFP */
|
||||
#define VMRS(fp, cpu) WORD $(0xeef00a10 | (fp)<<16 | (cpu)<<12) /* FP → arm */
|
||||
#define VMSR(cpu, fp) WORD $(0xeee00a10 | (fp)<<16 | (cpu)<<12) /* arm → FP */
|
||||
|
||||
#define Fpscr 1
|
||||
|
||||
TEXT setfcr(SB), $0
|
||||
VMSR(0, Fpscr)
|
||||
RET
|
||||
|
||||
TEXT getfcr(SB), $0
|
||||
VMRS(Fpscr, 0)
|
||||
RET
|
||||
|
||||
TEXT getfsr(SB), $0
|
||||
VMSR(0, Fpscr)
|
||||
RET
|
||||
|
||||
TEXT setfsr(SB), $0
|
||||
VMRS(Fpscr, 0)
|
||||
RET
|
|
@ -34,8 +34,8 @@ loop:
|
|||
TEXT _savearg(SB), 1, $0
|
||||
RET
|
||||
|
||||
TEXT _callpc(SB), 1, $0
|
||||
MOVW argp-4(FP), R(arg)
|
||||
TEXT _callpc(SB), 1, $-4
|
||||
MOVW 0(R13), R(arg)
|
||||
RET
|
||||
|
||||
DATA _exitstr<>+0(SB)/4, $"main"
|
||||
|
|
|
@ -5,9 +5,9 @@ N = 3
|
|||
TMP = 3 /* N and TMP don't overlap */
|
||||
TMP1 = 4
|
||||
|
||||
TEXT memcpy(SB), $-4
|
||||
TEXT memcpy(SB), $0
|
||||
B _memmove
|
||||
TEXT memmove(SB), $-4
|
||||
TEXT memmove(SB), $0
|
||||
_memmove:
|
||||
MOVW R(TS), to+0(FP) /* need to save for return value */
|
||||
MOVW from+4(FP), R(FROM)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TEXT strchr(SB), $-4
|
||||
TEXT strchr(SB), $0
|
||||
MOVBU c+4(FP), R1
|
||||
CMP $0, R1
|
||||
BEQ _null
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TEXT strcmp(SB), $-4
|
||||
TEXT strcmp(SB), $0
|
||||
MOVW R0, R1
|
||||
MOVW s2+4(FP), R2
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TEXT strcpy(SB), $-4
|
||||
TEXT strcpy(SB), $0
|
||||
MOVW R0, to+0(FP) /* need to save for return value */
|
||||
MOVW from+4(FP), R1
|
||||
MOVW $0xFF, R2 /* mask */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TEXT _tas(SB), $-4
|
||||
TEXT _tas(SB), 1, $-4
|
||||
MOVW R0,R1
|
||||
MOVW $1,R0
|
||||
SWPW R0,(R1) /* fix: deprecated in armv7 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
TEXT _mulv(SB), $0
|
||||
TEXT _mulv(SB), 1, $0
|
||||
MOVW 4(FP),R8 /* l0 */
|
||||
MOVW 8(FP),R11 /* h0 */
|
||||
MOVW 12(FP),R4 /* l1 */
|
||||
|
|
|
@ -128,6 +128,8 @@ _v2f(Vlong x)
|
|||
return _v2d(x);
|
||||
}
|
||||
|
||||
/* too many of these are also needed by profiler; leave them out */
|
||||
#pragma profile off
|
||||
|
||||
static void
|
||||
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
|
||||
|
@ -503,6 +505,7 @@ _sl2v(Vlong *ret, long sl)
|
|||
ret->hi = t >> 31;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_ul2v(Vlong *ret, ulong ul)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue