;;; This subroutine computes the maximum processor ID in each region (or ;;; cluster) in an image. It propagates that ID to all processors in ;;; that region. ;;; ;;; To try out this subroutine in traffic.spa, insert it in traffic.spa ;;; and replace the "s_call DISPLAY_ARRAY" at the beginning of the file with ;;; s_call FIND_REGIONS ;;; s_call DISPLAY_REGIONS FIND_REGIONS OS_LOAD_ID R15 ; Processor ID goes into R15 as initial cluster ID (CID). snei R2, 0x01 ; Put nodes with threshold flag set to sleep. sub R15, R15, R15 ; Set CID in nodes w/ null threshold flag subi R15, R15, 1 ; to -1 (default). wakeupi 0x01 ; Wake everyone up. seqi R2, 0x01 ; Put nodes with threshold flag clear to sleep. Loop ;; Find maximum CID of node and its neighbors and store it in R15 (new CID). ;; R14 is a temporary register that receives neighbors' CIDs. ;; R12 is a temporary flag that is set if the node's CID changes. sub R14, R14, R14 ; Initialize R14 to 0. sub R12, R12, R12 ; Clear R12. xfer R14, R15, 0 ; Send node's CID to NORTH neighbor. sub R13, R15, R14 ; If current CID is higher than neighbor CID sgei R13, 0x02 ; then sleep. addi R15, R14, 0 ; Otherwise, update CID with neighbor CID. ori R12, R12, 1 ; Set the change flag to 1. wakeupi 0x02 xfer R14, R15, 1 ; Send node's CID to EAST neighbor. sub R13, R15, R14 ; If current CID is higher than neighbor CID sgei R13, 0x02 ; then sleep. addi R15, R14, 0 ; Otherwise, update CID with neighbor CID. ori R12, R12, 1 ; Set the change flag to 1. wakeupi 0x02 xfer R14, R15, 2 ; Send node's CID to WEST neighbor. sub R13, R15, R14 ; If current CID is higher than neighbor CID sgei R13, 0x02 ; then sleep. addi R15, R14, 0 ; Otherwise, update CID with neighbor CID. ori R12, R12, 1 ; Set the change flag to 1. wakeupi 0x02 xfer R14, R15, 3 ; Send node's CID to SOUTH neighbor. sub R13, R15, R14 ; If current CID is higher than neighbor CID sgei R13, 0x02 ; then sleep. addi R15, R14, 0 ; Otherwise, update CID with neighbor CID. ori R12, R12, 1 ; Set the change flag to 1. wakeupi 0x02 seqi R12, 0x02 ; Put to sleep all nodes that did not change. s_raisehand SR1 ; If any nodes have changed, loop again. wakeupi 0x02 ; (but wake up nodes first). s_bne SR1, Loop wakeupi 0xff s_return