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