summaryrefslogtreecommitdiff
path: root/emu/Linux/asm-power.S
blob: ff5f97cd090c8191f92b06fb6a6fd1bb6bbf314e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <asm-ppc/reg.h>

	.file	"asm-power.S"
	.section	".text"
	.align 2
	.globl	FPsave
	.type	FPsave, @function
FPsave:
	.set	_framesize,0
	mffs	f0
	stfd	f0,0(r3)
	blr
	.size	FPsave,.-FPsave

	.align 2
	.globl	FPrestore
FPrestore:
	lfd		f0,0(r3)
	mtfsf 	0xff,f0
	blr
	.size	FPrestore, .-FPrestore

	.align 2
	.globl	_tas
_tas:
	sync
	mr	r4,r3
	addi    r5,0,0x1
1:
	lwarx	r3,0,r4
	cmpwi   r3,0x0
	bne-    2f
	stwcx.	r5,0,r4
	bne-    1b		/* Lost reservation, try again */
2:
	sync
	blr
	.size	_tas,.-_tas

/*
 * void executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
 */
	.align	2
	.globl	executeonnewstack:
executeonnewstack:
	mr	r1,r3	/* change stacks */
	stwu 1,-16(r1)	/* save lr to aid the traceback */
	li	r0,0
	stw r0,20(r1)
	mr	r3,r5
	mtctr r4
	bctrl		/* tramp(arg) */
	br	.	/* failed */
	.size executeonnewstack,.-executeonnewstack

/*
 * void unlockandexit(int *key)
 *
 * NB: the return status may be garbaged if the stack is reused
 *	between the unlock and the system call, but this should
 *	not matter since no task is waiting for the result
 */
	.align	2
	.globl	unlockandexit
unlockandexit:
	li	r0,0x0
	stw	r0,0(r3)	/* unlock */
	li	r0,1	/* sys exit; 234 is exit group */
	li	r3,0	/* exit status */
	sc
	br	.	/* not reached */
	.size	unlockandexit,.-unlockandexit