136 lines
2.9 KiB
ArmAsm
136 lines
2.9 KiB
ArmAsm
|
#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)
|
||
|
)
|