:#define data_base_reg %l3
:#define global_cnt_reg %l5
:#define prot_area_reg %l6
: wr %g0, 0x4, %fprs ! make sure fef is 1 for FP ops
:th_fork(th_main,test_reg1)
for ( $c = 0; $c < $proc_num; $c++ ){
$offs = 4 * $c; # threads own offset
: setx addrA, test_reg1, addrA_reg
: setx alive, test_reg1, alive_reg
: setx turn, test_reg1, turn_reg
: setx prot_area, test_reg1, prot_area_reg
: set ITERATIONS, global_cnt_reg
: set ${c}, my_id_reg ! my ID
: prefetch [addrA_reg], #n_writes
: prefetch [prot_area_reg], #n_writes
: prefetch [turn_reg], #n_writes
: set 1, test_reg1 ! store 1 in lock area
: st test_reg1, [alive_reg + ${offs}] !
: st test_reg1, [addrA_reg + ${offs}] !
: membar 0x40 ! IMPORTANT
for ( $k = 0; $k < ${proc_num} * 4; $k = $k + 4) {
: ld [addrA_reg + ${k}], test_reg1 ! accumulate flags
: add test_reg1, test_reg2, test_reg2 ! in test_reg2
: subcc test_reg2, 0x1, %g0 ! if 1 -> gotlock
: st %g0, [addrA_reg + ${offs}] ! else release.
:wait_turn${c}: ! while turn not mine.
: ld [turn_reg], test_reg3 ! read the turn reg.
: subcc my_id_reg, test_reg3, %g0 ! and wait
:gotlock${c}: ! do something
: set 1, test_reg1 ! store 1 in lock area
: st test_reg1, [addrA_reg + ${offs}]
: ld [prot_area_reg], test_reg1
: st test_reg1, [prot_area_reg]
: ldd [prot_area_reg], %f0 ! FP noise.
: std %f0, [prot_area_reg]
: ld [prot_area_reg + 0xc], test_reg1
: st test_reg1, [prot_area_reg + 0xc]
: ldd [prot_area_reg], %f0 ! FP noise.
: std %f0, [prot_area_reg]
: ld [prot_area_reg + 0x10], test_reg1
: st test_reg1, [prot_area_reg + 0x10]
: ldd [prot_area_reg], %f0 ! FP noise.
: std %f0, [prot_area_reg]
: ld [prot_area_reg + 0x1c], test_reg1
: st test_reg1, [prot_area_reg + 0x1c]
: ldd [prot_area_reg], %f0 ! FP noise.
: std %f0, [prot_area_reg]
: ld [prot_area_reg + 0x20], test_reg1
: st test_reg1, [prot_area_reg + 0x20]
: ldd [prot_area_reg], %f0 ! FP noise.
: std %f0, [prot_area_reg]
:clearlock${c}: ! requires some work
for($next = ($c+1) % ${proc_num}; $next != $c; $next = ($next+1) % ${proc_num}){
: mov ${next}, test_reg2 ! find next living
: ld [alive_reg + ${tempoffs}], test_reg1 ! process
: brnz test_reg1, foundnext${c}
:foundnext${c}: ! give it the turn
: st test_reg2, [turn_reg]
:check_done${c}: ! check if I am done
: st %g0, [addrA_reg + ${offs}] ! release...
: ba getlock${c} ! iterate
: st %g0, [alive_reg + ${offs}] ! I am out of the game
: st %g0, [addrA_reg + ${offs}] ! release...
:!---------------------------------------------------------------------
:!==========================
:SECTION .MY_DATA0 TEXT_VA=0xf0100000, DATA_VA=0xd0100000
: PA= ra2pa(0x1d0100000,0),
: part_0_ctx_nonzero_tsb_config_0,
: TTE_G=1, TTE_Context=0x44, TTE_V=1, TTE_Size=0, TTE_NFO=0,
: TTE_IE=0, TTE_Soft2=0, TTE_Diag=0, TTE_Soft=0,
: TTE_L=0, TTE_CP=1, TTE_CV=1, TTE_E=0, TTE_P=0, TTE_W=1
: PA= ra2pa(0x1f0100000,0),
: part_0_ctx_nonzero_tsb_config_0,
: TTE_G=1, TTE_Context=0x44, TTE_V=1, TTE_Size=0, TTE_NFO=0,
: TTE_IE=0, TTE_Soft2=0, TTE_Diag=0, TTE_Soft=0,
: TTE_L=0, TTE_CP=1, TTE_CV=1, TTE_E=0, TTE_P=0, TTE_W=1
for ( $k = 0; $k < 32; $k++) {
:SECTION .MY_DATA1 TEXT_VA=0xf1110000, DATA_VA=0xd1110000
: PA= ra2pa(0x1d1110000,0),
: part_0_ctx_nonzero_tsb_config_0,
: TTE_G=1, TTE_Context=0x44, TTE_V=1, TTE_Size=0, TTE_NFO=0,
: TTE_IE=0, TTE_Soft2=0, TTE_Diag=0, TTE_Soft=0,
: TTE_L=0, TTE_CP=1, TTE_CV=1, TTE_E=0, TTE_P=0, TTE_W=1
: PA= ra2pa(0x1f1110000,0),
: part_0_ctx_nonzero_tsb_config_0,
: TTE_G=1, TTE_Context=0x44, TTE_V=1, TTE_Size=0, TTE_NFO=0,
: TTE_IE=0, TTE_Soft2=0, TTE_Diag=0, TTE_Soft=0,
: TTE_L=0, TTE_CP=1, TTE_CV=1, TTE_E=0, TTE_P=0, TTE_W=1