libc: update atomic ops and fp code for arm (from sources)

This commit is contained in:
cinap_lenrek 2013-01-26 17:00:38 +01:00
parent 68c5dc8014
commit ae116c9446
12 changed files with 52 additions and 22 deletions

View file

@ -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

View file

@ -1,7 +1,10 @@
#include <u.h>
#include <libc.h>
void cycles(uvlong*u)
#pragma profile off
void
cycles(uvlong*u)
{
*u = 0LL;
}

View file

@ -1,3 +1,3 @@
TEXT getcallerpc(SB), $-4
TEXT getcallerpc(SB), 1, $-4
MOVW 0(R13), R0
RET

View 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

View file

@ -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"

View file

@ -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)

View file

@ -1,4 +1,4 @@
TEXT strchr(SB), $-4
TEXT strchr(SB), $0
MOVBU c+4(FP), R1
CMP $0, R1
BEQ _null

View file

@ -1,4 +1,4 @@
TEXT strcmp(SB), $-4
TEXT strcmp(SB), $0
MOVW R0, R1
MOVW s2+4(FP), R2

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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)
{