Welcome to mirror list, hosted at ThFree Co, Russian Federation.

sync-asm.S « or1k « libgloss - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 911e2552f18fa8fbeb678e804aa595da96d3b72a (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "include/or1k-asm.h"
#include "include/or1k-sprs.h"

	.section .text


	.global	or1k_has_multicore_support
	.type	or1k_has_multicore_support,@function
or1k_has_multicore_support:
#ifdef __OR1K_MULTICORE__
	// Return 1
	OR1K_DELAYED(
		OR1K_INST(l.ori r11,r0,1),
		OR1K_INST(l.jr  r9)
	)
#else
	// Return 0
	OR1K_DELAYED(
		OR1K_INST(l.or r11,r0,r0),
		OR1K_INST(l.jr r9)
	)
#endif

	.global	or1k_coreid
	.type	or1k_coreid,@function
or1k_coreid:
#ifdef __OR1K_MULTICORE__
	// Return SPR with core identifier
	OR1K_DELAYED(
		OR1K_INST(l.mfspr r11,r0,OR1K_SPR_SYS_COREID_ADDR),
		OR1K_INST(l.jr    r9)
	)
#else
	// Return 0
	OR1K_DELAYED(
		OR1K_INST(l.or r11,r0,r0),
		OR1K_INST(l.jr r9)
	)
#endif

	.global	or1k_numcores
	.type	or1k_numcores,@function
or1k_numcores:
#ifdef __OR1K_MULTICORE__
	// Return SPR with number of cores
	OR1K_DELAYED(
		OR1K_INST(l.mfspr r11,r0,OR1K_SPR_SYS_NUMCORES_ADDR),
		OR1K_INST(l.jr    r9)
	)
#else
	// Return 1
	OR1K_DELAYED(
		OR1K_INST(l.ori r11,r0,1),
		OR1K_INST(l.jr r9)
	)
#endif

	.global	or1k_sync_ll
	.type	or1k_sync_ll,@function
or1k_sync_ll:
#ifdef __OR1K_MULTICORE__
	// Load word atomic
	OR1K_DELAYED(
		OR1K_INST(l.lwa r11, 0(r3)),
		OR1K_INST(l.jr  r9)
	)
#else
	// Simply load word, TODO: throw exception? which?
	OR1K_DELAYED(
		OR1K_INST(l.lwz r11, 0(r3)),
		OR1K_INST(l.jr  r9)
	)
#endif

	.global	or1k_sync_sc
	.type	or1k_sync_sc,@function
or1k_sync_sc:
#ifdef __OR1K_MULTICORE__
	// swa sets the flag if it was succesfull
	// Store the value to address and set flag
	l.swa 0(r3),r4
	OR1K_DELAYED(
		// Set return to success speculatively (may go to delay slot)
		OR1K_INST(l.ori r11,r0,1),
		// If the swa was successfull, jump to end
		OR1K_INST(l.bf  .or1k_sync_sc_done)
	)
	// If the swa was not successfull, set
	l.or r11,r0,r0
.or1k_sync_sc_done:
	OR1K_DELAYED_NOP(OR1K_INST(l.jr r9))
#else
	// Simply store word, TODO: throw exception? which?
	OR1K_DELAYED(
		OR1K_INST(l.sw 0(r3),r4),
		OR1K_INST(l.jr r9)
	)
#endif


	.global or1k_sync_cas
	.type	or1k_sync_sc,@function
or1k_sync_cas:
#ifdef __OR1K_MULTICORE__
	/* Load linked address value to return register */
	l.lwa	r11,0(r3)
	/* Compare value to parameter */
	l.sfeq	r11,r4
	/* If not equal: abort and return the read value */
	OR1K_DELAYED_NOP(OR1K_INST(l.bnf .or1k_sync_cas_done))
	/* If compare was successfull: try writing */
	l.swa	0(r3),r5
	/* If writing was not successful: restart */
	OR1K_DELAYED_NOP(OR1K_INST(l.bnf or1k_sync_cas))
.or1k_sync_cas_done:
	/* Return value is the original read value */
	OR1K_DELAYED_NOP(OR1K_INST(l.jr r9))
#else
	// Non-atomic CAS, TODO: throw exception? which?
	l.lwz	r11,0(r3)
	l.sfeq	r11,r4
	OR1K_DELAYED_NOP(OR1K_INST(l.bnf .or1k_sync_cas_done))
	l.sw	0(r3),r5
.or1k_sync_cas_done:
	OR1K_DELAYED_NOP(OR1K_INST(l.jr r9))
#endif

	.global or1k_sync_tsl
	.type	or1k_sync_tsl,@function
or1k_sync_tsl:
	l.or	r4,r0,r0
	OR1K_DELAYED(
		OR1K_INST(l.addi r5,r0,1),
		OR1K_INST(l.j    or1k_sync_cas)
	)