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