Guest User

Untitled

a guest
Aug 3rd, 2018
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
4CS 10.88 KB | None | 0 0
  1. .data
  2. board: .space 324 # 9x9 sudoku board. 9*9*4 bytes
  3.  
  4. .text
  5. main:
  6.     li      $t0, 0x4001 # flag for sudoku interrupt set, and global interrupt enable
  7.     mtc0    $t0, $12    # Enable interrupt mask (Status register)
  8.  
  9.     li $s0, 0           # 0 = no board
  10.                         # 1 = waiting for board
  11.                         # 2 = unsolved board
  12. loop:
  13.     beq $s0, $zero, get_board
  14.     li $t0, 1
  15.     beq $s0, $t0, loop
  16.  
  17. solve_board:
  18.     move  $s1, $ra
  19.     la    $a0, board
  20.     jal solve             # solve sudoku board
  21.     move  $ra, $s1
  22.     la $t0, board
  23.     sw $t0, 0xffff00ec($zero)    # get credit for solution
  24.  
  25.     li $s0, 0                    # mark as no board now we are done with it
  26.     j loop
  27.  
  28. get_board:
  29.     la $t0, board
  30.     sw $t0, 0xffff00e8($zero)    # ask for sudoku board
  31.  
  32.     li $s0, 1                    # mark as waiting for board
  33.     j loop
  34.  
  35.     jr $ra
  36.  
  37.  
  38. ################
  39. # SOLVING LOOP #
  40. ################
  41. solve:
  42.     sub     $sp, $sp, 12
  43.     sw      $ra, 0($sp) # save $ra on stack
  44.     sw      $s0, 4($sp)     # save $s0 on stack <--- check out use of $s register!!
  45.     sw      $s1, 8($sp) # save $s1 on stack
  46.     move    $s0, $a0
  47. solve_loop:
  48.     move    $a0, $s0
  49.     jal rule1
  50.     move $s1, $v0       # save changed
  51.  
  52.     move    $a0, $s0
  53.     jal rule2
  54.     #or  $v0, $s1, $v0   # changed = rule1() or rule2()
  55.     move $v0, $s1
  56.  
  57.     bne $v0, 0, solve_loop   # keep running rule1 until no more changes
  58.    
  59.     lw      $ra, 0($sp)     # restore $ra
  60.     lw      $s0, 4($sp)     # restore $s0
  61.     lw      $s1, 8($sp)     # restore $s1
  62.     add     $sp, $sp, 12
  63.     jr $ra
  64.  
  65. .data
  66. atsave: .word 0
  67. a0save: .word 0
  68. a1save: .word 0
  69.  
  70. non_intrpt_str:   .asciiz "Non-interrupt exception\n"
  71. unhandled_str:    .asciiz "Unhandled interrupt type\n"
  72.  
  73. .ktext 0x80000080
  74. interrupt_handler:
  75.     .set noat
  76.     sw  $at, atsave
  77.     .set at
  78.     sw  $a0, a0save     # Get some free registers
  79.     sw  $a1, a1save     # by storing them to a global variable
  80.  
  81.     mfc0    $k0, $13        # Get Cause register
  82.     srl     $a0, $k0, 2    
  83.     and     $a0, $a0, 0xf       # ExcCode field
  84.     bne     $a0, 0, non_intrpt
  85.  
  86. interrupt_dispatch:         # Interrupt:
  87.     mfc0    $k0, $13        # Get Cause register, again
  88.     beq $k0, $zero, done    # handled all outstanding interrupts
  89.  
  90.     and     $a0, $k0, 0x4000    # is there a bonk interrupt?
  91.     bne     $a0, 0, sudoku_interrupt   
  92.  
  93.                     # add dispatch for other interrupt types here.
  94.  
  95.     #li $v0, 4          # Unhandled interrupt types
  96.     #la $a0, unhandled_str
  97.     #syscall
  98.     j done
  99.    
  100. sudoku_interrupt:
  101.     li  $s0, 2                  # mark a sudoku puzzle
  102.     sw  $k0, 0xffff0068($zero)  # acknowledge interrupt
  103.     j   interrupt_dispatch      # see if other interrupts are waiting
  104.  
  105. non_intrpt:             # was some non-interrupt
  106.     #li $v0, 4         
  107.     #la $a0, non_intrpt_str
  108.     #syscall                # print out an error message
  109.     j done
  110.  
  111. done:
  112.     lw  $a0, a0save
  113.     lw  $a1, a1save
  114.     mfc0    $k0 $14         # EPC
  115.  
  116.     .set noat
  117.     lw  $at, atsave
  118.     .set at
  119.  
  120.     rfe             # Return from exception handler
  121.     jr  $k0
  122.  
  123.  
  124. ########################
  125. #  SUDOKU RULE SOLVERS #
  126. ########################
  127. .text
  128. ###
  129. # Rule 1
  130. ###
  131. board_address:
  132.     mul $v0, $a1, 9     # i*9
  133.     add $v0, $v0, $a2       # (i*9)+j
  134.     sll $v0, $v0, 2     # ((i*9)+j)*4
  135.     add $v0, $a0, $v0
  136.     jr  $ra
  137.  
  138. rule1:
  139.     sub $sp, $sp, 32        
  140.     sw  $ra, 0($sp)     # save $ra and free up 7 $s registers for
  141.     sw  $s0, 4($sp)     # i
  142.     sw  $s1, 8($sp)     # j
  143.     sw  $s2, 12($sp)        # board
  144.     sw  $s3, 16($sp)        # value
  145.     sw  $s4, 20($sp)        # k
  146.     sw  $s5, 24($sp)        # changed
  147.     sw  $s6, 28($sp)        # temp
  148.     move    $s2, $a0
  149.     li  $s5, 0          # changed = false
  150.  
  151.     li  $s0, 0          # i = 0
  152. r1_loop1:
  153.     li  $s1, 0          # j = 0
  154. r1_loop2:
  155.     move    $a0, $s2        # board
  156.     move    $a1, $s0        # i
  157.     move    $a2, $s1        # j
  158.     jal board_address
  159.     lw  $s3, 0($v0)     # value = board[i][j]
  160.     move    $a0, $s3        
  161.     jal is_singleton
  162.     beq $v0, 0, r1_loop2_bot    # if not a singleton, we can go onto the next iteration
  163.  
  164.     li  $s4, 0          # k = 0
  165. r1_loop3:
  166.     beq $s4, $s1, r1_skip_row   # skip if (k == j)
  167.     move    $a0, $s2        # board
  168.     move    $a1, $s0        # i
  169.     move    $a2, $s4        # k
  170.     jal board_address
  171.     lw  $t0, 0($v0)     # board[i][k]
  172.     and $t1, $t0, $s3      
  173.     beq $t1, 0, r1_skip_row
  174.     not $t1, $s3
  175.     and $t1, $t0, $t1      
  176.     sw  $t1, 0($v0)     # board[i][k] = board[i][k] & ~value
  177.     li  $s5, 1          # changed = true
  178.    
  179. r1_skip_row:
  180.     beq $s4, $s0, r1_skip_col   # skip if (k == i)
  181.     move    $a0, $s2        # board
  182.     move    $a1, $s4        # k
  183.     move    $a2, $s1        # j
  184.     jal board_address
  185.     lw  $t0, 0($v0)     # board[k][j]
  186.     and $t1, $t0, $s3      
  187.     beq $t1, 0, r1_skip_col
  188.     not $t1, $s3
  189.     and $t1, $t0, $t1      
  190.     sw  $t1, 0($v0)     # board[k][j] = board[k][j] & ~value
  191.     li  $s5, 1          # changed = true
  192.  
  193. r1_skip_col:    
  194.     add $s4, $s4, 1     # k++
  195.     blt $s4, 9, r1_loop3
  196.  
  197. ## doubly nested loop
  198.     move    $a0, $s0        # i
  199.     jal get_square_begin
  200.     move    $s6, $v0        # ii
  201.     move    $a0, $s1        # j
  202.     jal get_square_begin    # jj
  203.     move    $t0, $s6        # k = ii
  204.     add     $s6, $v0, 3     # jj + GRIDSIZE
  205.     add $t1, $t0, 3     # ii + GRIDSIZE
  206.  
  207. r1_loop4_outer:
  208.     sub $t2, $s6, 3     # l = jj
  209.  
  210. r1_loop4_inner:
  211.     bne $t0, $s0, r1_loop4_1
  212.     beq $t2, $s1, r1_loop4_bot
  213.  
  214. r1_loop4_1:
  215.     mul $v0, $t0, 9     # k*9
  216.     add $v0, $v0, $t2       # (k*9)+l
  217.     sll $v0, $v0, 2     # ((k*9)+l)*4
  218.     add $v0, $s2, $v0       # &board[k][l]
  219.     lw  $v1, 0($v0)     # board[k][l]
  220.     and $t3, $v1, $s3       # board[k][l] & value
  221.     beq $t3, 0, r1_loop4_bot
  222.  
  223.     not $t3, $s3
  224.     and $v1, $v1, $t3      
  225.     sw  $v1, 0($v0)     # board[k][l] = board[k][l] & ~value
  226.     li  $s5, 1          # changed = true
  227.  
  228. r1_loop4_bot:  
  229.     add $t2, $t2, 1     # l++
  230.     blt $t2, $s6, r1_loop4_inner
  231.  
  232.     add $t0, $t0, 1     # k++
  233.     blt $t0, $t1, r1_loop4_outer
  234.    
  235.  
  236. r1_loop2_bot:  
  237.     add $s1, $s1, 1     # j++
  238.     blt $s1, 9, r1_loop2
  239.  
  240.     add $s0, $s0, 1     # i++
  241.     blt $s0, 9, r1_loop1
  242.  
  243.     move    $v0, $s5        # return changed
  244.     lw  $ra, 0($sp)     # restore registers and return
  245.     lw  $s0, 4($sp)
  246.     lw  $s1, 8($sp)
  247.     lw  $s2, 12($sp)
  248.     lw  $s3, 16($sp)
  249.     lw  $s4, 20($sp)
  250.     lw  $s5, 24($sp)
  251.     lw  $s6, 28($sp)
  252.     add $sp, $sp, 32
  253.     jr  $ra
  254.  
  255.  
  256. ###
  257. # Rule 2
  258. ###
  259.  
  260. rule2:
  261.     sub $sp,$sp,36
  262.     sw  $ra,0($sp)
  263.     sw  $s0,4($sp)
  264.     sw  $s1,8($sp)
  265.     sw  $s2,12($sp)
  266.     sw  $s3,16($sp)
  267.     sw  $s4,20($sp)
  268.     sw  $s5,24($sp)
  269.     sw  $s6,28($sp)
  270.     sw  $s7,32($sp)
  271.  
  272.     li  $s7, 0  #s7 = returning boolean
  273.     move    $s6, $a0 #$s6 = board[0][0]
  274.     li  $s1,0   #i=0
  275.    
  276. i_loop:
  277.     beq $s1,9,return_rule#i==9
  278.  
  279.     li  $s2,0       #j=0
  280.  
  281. j_loop:
  282.     beq $s2,9,i_loop_increment  #j==9
  283.     j   ignore_i_inc
  284.  
  285. i_loop_increment:       #increments i
  286.     add $s1,$s1,1   #i++
  287.     j   i_loop
  288.  
  289. ignore_i_inc:
  290.  
  291.     move    $a0,$s1
  292.     move    $a1,$s2
  293.  
  294.  
  295.     jal board_val
  296.  
  297.     move    $s3,$v0     #value at [i][j]
  298.     move    $a0,$s3
  299.  
  300.     jal is_singleton
  301.  
  302.     bne $v0,$zero, j_loop_end  #THIS IS DIFFERENT FOR RULE2
  303.  
  304.     li  $t1,0       #isum = 0
  305.     li  $t2,0       #jsum = 0  
  306.  
  307.     li  $s4,0       #k=0
  308.  
  309. k_loop:
  310.     beq $s4,9,k_loop_end #k==9
  311.  
  312. check_row:
  313.     beq $s4,$s2,check_column #if(k!=j)
  314.    
  315.     move    $a0,$s1
  316.     move    $a1,$s4
  317.  
  318.     jal board_val   #value at board[i][k]
  319.  
  320.     or  $t2,$t2,$v0 #j_sum |= board[i][k]
  321.  
  322. check_column:
  323.     beq $s4,$s1,k_inc    #if(k!=i)
  324.    
  325.     move    $a0,$s4
  326.     move    $a1,$s2
  327.  
  328.     jal board_val   #value at board[k][j]
  329.  
  330. k_inc:
  331.     add $s4,$s4,1   #k++
  332.     j   k_loop
  333.  
  334. k_loop_end:
  335.  
  336.     beq $t2,1023,skip_j_sum;    #if ALLVALUES == j_sum
  337.     li  $s7,1           #changed = true
  338.    
  339.     move    $a0,$s1
  340.     move    $a1,$s2
  341.  
  342.     jal board_loc
  343.  
  344.     not $t2,$t2         #j_sum = ~jsum
  345.     and $t2,$t2,1023        #ALL_VALUES & ~j_sum
  346.     lw  $t2,0($v0)      #board[i][j]
  347.     j   j_loop_end
  348.  
  349. skip_j_sum:
  350.     beq $t1,1023,skip_i_sum #if ALLVALUES == i_sum (same as above :P)
  351.     li  $s7,1  
  352.  
  353.     move    $a0,$s1
  354.     move    $a1,$s2
  355.  
  356.     jal board_loc
  357.  
  358.     not $t1,$t1
  359.     and $t1,$t1,1023
  360.     lw  $t1,0($v0)
  361.     j   j_loop_end
  362.  
  363. skip_i_sum:
  364.  
  365. #dont need t1/t2 anymore, can be reused
  366.     li  $t0,0       #sq_sum = 0
  367.     move    $a0,$s1
  368.    
  369.     jal get_square_begin
  370.  
  371.     move    $t1,$v0     #ii
  372.  
  373.     move    $a0,$s2
  374.  
  375.     jal get_square_begin
  376.  
  377.     move    $t2,$v0     #jj
  378.     move    $t3,$t2     #extra copy of jj
  379.  
  380.     add $t4,$t1,3    #ii+3
  381.     add $t5,$t2,3    #jj+3
  382.  
  383. ii_loop:
  384.     beq $t1,$t4,after_square #k == ii+3
  385.     move    $t2,$t3         #set l = jj
  386.  
  387. jj_loop:
  388.     beq $t2,$t5,ii_inc  #l = jj+3
  389.     j   ignore_ii_inc
  390.    
  391. ii_inc:
  392.     add $t1,$t1,1       #k++
  393.     j   ii_loop
  394.  
  395. ignore_ii_inc:
  396.     bne $s1,$t1,skip_wierd_part     #k!=i
  397.     bne $s2,$t2,skip_wierd_part     #l!=j
  398.  
  399.     j   jj_loop_end
  400.  
  401. skip_wierd_part:
  402.  
  403.     move    $a0,$t1
  404.     move    $a1,$t2
  405.  
  406.     jal board_value
  407.    
  408.     or  $t0,$t0,$v0 #sum |= board[k][j]
  409.  
  410. jj_loop_end:
  411.     add $t2,$t2,1       #l++
  412.     j   jj_loop
  413.  
  414. after_square:
  415.  
  416.     beq $t0,1023,j_loop_end #ALLVALUES !=sq_sum
  417.     li  $s7,1           #changed = true
  418.    
  419.     move    $a0,$s1
  420.     move    $a1,$s2
  421.  
  422.     jal board_loc
  423.  
  424.     not $t0,$t0         #sq_sum = ~sq_sum
  425.     and $t0,$t0,1023        #ALL_VALUES & ~sq_sum
  426.     lw  $t0,0($v0)      #board[i][j]
  427.  
  428.  
  429. j_loop_end:
  430.     add $s2,$s2,1   #j++
  431.     j   j_loop
  432.  
  433. return_rule:
  434.  
  435.     move    $v0,$s7 #set return value
  436.     lw  $ra,0($sp)
  437.     lw  $s0, 4($sp)
  438.     lw  $s1, 8($sp)
  439.     lw  $s2, 12($sp)
  440.     lw  $s3, 16($sp)
  441.     lw  $s4, 20($sp)
  442.     lw  $s5, 24($sp)
  443.     lw  $s6, 28($sp)
  444.     lw  $s7, 32($sp)
  445.     add $sp, $sp, 36
  446.     jr  $ra
  447.  
  448.  
  449.  
  450.  
  451.  
  452. board_loc:
  453.     sub $sp,$sp,4
  454.     sw  $ra,0($sp)
  455.  
  456.     mul $a3,$a0,9
  457.     add $v0,$a3,$a1
  458.     mul $v0,$v0,4
  459.     add $v0,$v0,$s6 #board[i][j] = (i*9 + j)*4 + starting add.
  460.                
  461.  
  462.     lw  $ra,0($sp)
  463.     add $sp,$sp,4
  464.     jr  $ra
  465.  
  466.  
  467. board_val:      #returns value of of cell[a0][a1]
  468.             #$a0 = i, $a1 = j
  469.  
  470.     sub $sp,$sp,4
  471.     sw  $ra,0($sp)
  472.  
  473.     mul $a3,$a0,9
  474.     add $v0,$a3,$a1
  475.     mul $v0,$v0,4
  476.     add $a3,$v0,$s6
  477.     lw  $v0,0($a3)  #board[i][j] loc.
  478.                
  479.  
  480.     lw  $ra,0($sp)
  481.     add $sp,$sp,4
  482.     jr  $ra
  483.  
  484.    
  485. #################### SINGLETON ####################    
  486. is_singleton:
  487.     li  $v0, 0
  488.     beq $a0, 0, is_singleton_done       # return 0 if value == 0
  489.     sub $a1, $a0, 1
  490.     and $a1, $a0, $a1
  491.     bne $a1, 0, is_singleton_done       # return 0 if (value & (value - 1)) == 0
  492.     li  $v0, 1
  493. is_singleton_done:
  494.     jr  $ra
  495.  
  496.    
  497. ## int get_square_begin(int index) {
  498. ##   return (index/GRIDSIZE) * GRIDSIZE;
  499. ## }
  500.  
  501. get_square_begin:
  502.     div $v0, $a0, 3
  503.     mul $v0, $v0, 3
  504.     jr  $ra
Add Comment
Please, Sign In to add comment