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