Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .text
- # short count_odd_nodes(TreeNode* head) {
- # // Base case
- # if (head == NULL) {
- # return 0;
- # }
- # // Recurse once for each child
- # short count_left = count_odd_nodes(head->left);
- # short count_right = count_odd_nodes(head->right);
- # short count = count_left + count_right;
- # // Determine if this current node is odd
- # if (head->value%2 != 0) {
- # count += 1;
- # }
- # return count;
- # }
- .globl count_odd_nodes
- count_odd_nodes:
- li $v0, 0
- beq $a0, $zero, count_odd_nodes_end # branch if (head == NULL)
- sub $sp, $sp, 16
- sw $ra, 0($sp)
- sw $v0, 4($sp)
- sw $a0, 8 ($sp)
- lw $a0, 0($a0); # load head->left into $a0
- jal count_odd_nodes # count_odd_nodes(head->left)
- move $t0, $v0 # x = count_odd_nodes(head->left)
- sw $t0, 12($sp)
- lw $t1, 8($sp) # load head->right into $a0
- lw $a0, 4($t1)
- jal count_odd_nodes # count_odd_nodes(head->right)
- move $t1, $v0 # y = count_odd_nodes(head->right)
- lw $t0, 12($sp)
- lw $a0, 8($sp)
- lw $v0, 4($sp)
- lw $ra, 0($sp)
- add $sp, $sp, 16
- add $v0, $t1, $t0 # count = count_left + count_right
- lh $t3, 8($a0) # load head->value
- div $t4, $t3, 2 # divide by 2
- mfhi $t4 # load remainder into $t4
- beq $t4, $zero, count_odd_nodes_end # branch if !(head->value%2 != 0))
- add $v0, $v0, 1 # count += 1
- count_odd_nodes_end:
- jr $ra
- .text
- # bool rule1(unsigned short* board) {
- # bool changed = false;
- # for (int y = 0 ; y < GRIDSIZE ; y++) {
- # for (int x = 0 ; x < GRIDSIZE ; x++) {
- # unsigned value = board[y*GRIDSIZE + x];
- # if (has_single_bit_set(value)) {
- # for (int k = 0 ; k < GRIDSIZE ; k++) {
- # // eliminate from row
- # if (k != x) {
- # if (board[y*GRIDSIZE + k] & value) {
- # board[y*GRIDSIZE + k] &= ~value;
- # changed = true;
- # }
- # }
- # // eliminate from column
- # if (k != y) {
- # if (board[k*GRIDSIZE + x] & value) {
- # board[k*GRIDSIZE + x] &= ~value;
- # changed = true;
- # }
- # }
- # }
- # }
- # }
- # }
- # return changed;
- # }
- #a0: board
- .globl rule1
- rule1:
- li $v0, 0 # bool changed = false
- li $t1, 0 # int y = 0
- li $t0, GRIDSIZE # GRIDSIZE = 4
- y_for_loop:
- bge $t1, $t0, y_end # branch if !(y < GRIDSIZE)
- li $t2, 0 # int x = 0
- x_for_loop:
- bge $t2, $t0, x_end # branch if !(x < GRIDSIZE)
- mul $t3, $t1, $t0 # y * GRIDSIZE
- add $t3, $t3, $t2 # y * GRIDSIZE + x
- sll $t3, $t3, 1 # 2 bit append
- add $t3, $a0, $t3 # load &board[y * GRIDSIZE + x]
- lh $t3, 0($t3) # value = board[y * GRIDSIZE + x]
- sub $sp, $sp, 28
- sw $ra, 0($sp)
- sw $v0, 4($sp)
- sw $a0, 8($sp)
- sw $t0, 12($sp)
- sw $t1, 16($sp)
- sw $t2, 20($sp)
- sw $t3, 24($sp)
- move $a0, $t3 # move value into argument 0
- jal has_single_bit_set
- move $t4, $v0 # output = has_single_bit_set(value)
- lw $t3, 24($sp)
- lw $t2, 20($sp)
- lw $t1, 16($sp)
- lw $t0, 12($sp)
- lw $a0, 8($sp)
- lw $v0, 4($sp)
- lw $ra, 0($sp)
- add $sp, $sp, 28
- beq $t4, $zero, x_next # branch if !(has_single_bit_set(value))
- li $t5, 0 # k = 0
- k_for_loop:
- bge $t5, $t0, k_end # branch if !(k < GRIDSIZE)
- beq $t5, $t2, ky_if # branch if !(k != x)
- mul $t6, $t1, $t0 # y * GRIDSIZE
- add $t6, $t6, $t5 # y * GRIDSIZE + k
- sll $t6, $t6, 1 # 2 bit append
- add $t6, $a0, $t6 # load &board[y * GRIDSIZE + k]
- lh $t9, 0($t6) # get board[y * GRIDSIZE + k]
- and $t7, $t9, $t3 # board[y * GRIDSIZE + k] & value
- beq $t7, $zero, ky_if # branch if !(board[y * GRIDSIZE + k] & value)
- not $t8, $t3 # $t8 = ~value
- and $t9, $t9, $t8 # board[y * GRIDSIZE + k] & ~value
- sh $t9, 0($t6) # board[y * GRIDSIZE + k] = board[y * GRIDSIZE + k] & ~value
- li $v0, 1 # changed = true
- ky_if:
- beq $t5, $t1, k_next # branch if !(k != y)
- mul $t6, $t5, $t0 # k * GRIDSIZE
- add $t6, $t6, $t2 # k * GRIDSIZE + x
- sll $t6, $t6, 1 # 2 bit append
- add $t6, $a0, $t6 # load &board[k * GRIDSIZE + x]
- lh $t9, 0($t6) # get board[k * GRIDSIZE + x]
- and $t7, $t9, $t3 # board[k * GRIDSIZE + x] & value
- beq $t7, $zero, k_next # branch if !(board[k * GRIDSIZE + x] & value)
- not $t8, $t3 # $t8 = ~value
- and $t9, $t9, $t8 # board[k * GRIDSIZE + x] & ~value
- sh $t9, 0($t6) # board[k * GRIDSIZE + x] = board[k * GRIDSIZE + x] & ~value
- li $v0, 1 # changed = true
- k_next:
- add $t5, $t5, 1 # k++
- j k_for_loop
- k_end:
- j x_next
- x_next:
- add $t2, $t2, 1 # x++
- j x_for_loop
- x_end:
- j y_next
- y_next:
- add $t1, $t1, 1 # y++
- j y_for_loop
- y_end:
- jr $ra
- # bool solve(unsigned short *current_board, unsigned row, unsigned col, Puzzle* puzzle) {
- # if (row >= GRIDSIZE || col >= GRIDSIZE) {
- # bool done = board_done(current_board, puzzle);
- # if (done) {
- # copy_board(current_board, puzzle->board);
- # }
- # return done;
- # }
- # current_board = increment_heap(current_board);
- # bool changed;
- # do {
- # changed = rule1(current_board);
- # changed |= rule2(current_board);
- # } while (changed);
- # short possibles = current_board[row*GRIDSIZE + col];
- # for(char number = 0; number < GRIDSIZE; ++number) {
- # // Remember & is a bitwise operator
- # if ((1 << number) & possibles) {
- # current_board[row*GRIDSIZE + col] = 1 << number;
- # unsigned next_row = ((col == GRIDSIZE-1) ? row + 1 : row);
- # if (solve(current_board, next_row, (col + 1) % GRIDSIZE, puzzle)) {
- # return true;
- # }
- # current_board[row*GRIDSIZE + col] = possibles;
- # }
- # }
- # return false;
- # }
- .globl solve
- solve:
- li $t0, GRIDSIZE # GRIDSIZE = 4
- sge $t1, $a1, $t0 # row >= GRIDSIZE
- sge $t2, $a2, $t0 # col >= GRIDSIZE
- or $t1, $t1, $t2 # row >= GRIDSIZE || col >= GRIDSIZE
- beq $t1, $zero, set_current_board # branch if !(row >= GRIDSIZE || col >= GRIDSIZE)
- sub $sp, $sp, 24
- sw $ra, 0($sp)
- sw $a0, 4($sp)
- sw $a1, 8($sp)
- sw $a2, 12($sp)
- sw $a3, 16($sp)
- sw $t0, 20($sp)
- move $a1, $a3 # set the second argument to puzzle
- jal board_done
- lw $ra, 0($sp)
- lw $a0, 4($sp)
- lw $a1, 8($sp)
- lw $a2, 12($sp)
- lw $a3, 16($sp)
- lw $t0, 20($sp)
- add $sp, $sp, 24
- beq $v0, $zero, solve_end # branch if !(done)
- sub $sp, $sp, 28
- sw $ra, 0($sp)
- sw $a0, 4($sp)
- sw $a1, 8($sp)
- sw $a2, 12($sp)
- sw $a3, 16($sp)
- sw $t0, 20($sp)
- sw $v0, 24($sp)
- la $a1, 0($a3) # set the second argument to puzzle->board
- jal copy_board
- lw $ra, 0($sp)
- lw $a0, 4($sp)
- lw $a1, 8($sp)
- lw $a2, 12($sp)
- lw $a3, 16($sp)
- lw $t0, 20($sp)
- lw $v0, 24($sp)
- add $sp, $sp, 28
- j solve_end
- set_current_board:
- sub $sp, $sp, 24
- sw $ra, 0($sp)
- sw $a0, 4($sp)
- sw $a1, 8($sp)
- sw $a2, 12($sp)
- sw $a3, 16($sp)
- sw $t0, 20($sp)
- jal increment_heap
- lw $ra, 0($sp)
- lw $a0, 4($sp)
- lw $a1, 8($sp)
- lw $a2, 12($sp)
- lw $a3, 16($sp)
- lw $t0, 20($sp)
- add $sp, $sp, 24
- move $a0, $v0 # current_board = increment_heap(current_board)
- do_while:
- sub $sp, $sp, 28
- sw $ra, 0($sp)
- sw $a0, 4($sp)
- sw $a1, 8($sp)
- sw $a2, 12($sp)
- sw $a3, 16($sp)
- sw $t0, 20($sp)
- jal rule1
- move $t1, $v0 # changed = rule1(current_board)
- sw $t1, 24($sp)
- jal rule2
- move $t2, $v0 # $t2 = rule2(current_board)
- lw $t1, 24($sp)
- or $t1, $t1, $t2 # changed = changed | rule2(current_board)
- lw $ra, 0($sp)
- lw $a0, 4($sp)
- lw $a1, 8($sp)
- lw $a2, 12($sp)
- lw $a3, 16($sp)
- lw $t0, 20($sp)
- add $sp, $sp, 28
- beq $t1, $zero, set_possibles # branch if !(changed)
- j do_while
- set_possibles:
- mul $t1, $t0, $a1 # row * GRIDSIZE
- add $t1, $t1, $a2 # row * GRIDSIZE + col
- sll $t1, $t1, 1 # 2 bit append
- add $t1, $a0, $t1 # load ¤t_board[row * GRIDSIZE + col]
- lh $t2, 0($t1) # short possibles = current_board[row * GRIDSIZE + col]
- li $t3, 0 # char number = 0
- solve_for_loop:
- bgt $t3, $t0, solve_for_loop_end # branch if !(number < GRIDSIZE)
- li $t8, 1 # $t8 = 1
- sll $t4, $t8, $t3 # 1 << number
- and $t4, $t4, $t2 # 1 << number & possibles
- beq $t4, $zero, solve_for_loop_next # branch if !(1 << number & possibles)
- sll $t4, $t8, $t3 # 1 << number
- sh $t4, 0($t1) # current_board[row * GRIDSIZE + col] = 1 << number
- sub $t6, $t0, 1 # GRIDSIZE - 1
- bne $a2, $t6, set_row # branch if !(col == GRIDSIZE - 1)
- add $t5, $a1, 1 # next_row = row + 1
- j if_solve
- set_row:
- move $t5, $a1 # next_row = row
- if_solve:
- sub $sp, $sp, 52
- sw $ra, 0($sp)
- sw $a0, 4($sp)
- sw $a1, 8($sp)
- sw $a2, 12($sp)
- sw $a3, 16($sp)
- sw $t0, 20($sp)
- sw $t1, 24($sp)
- sw $t2, 28($sp)
- sw $t3, 32($sp)
- sw $t4, 36($sp)
- sw $t5, 40($sp)
- sw $t6, 44($sp)
- sw $v0, 48($sp)
- move $a1, $t5 # move next_row into argument 1
- add $t1, $a2, 1 # col + 1
- div $t1, $t1, $t0 # col + 1 / GRIDSIZE
- mfhi $t2 # col + 1 % GRIDSIZE
- move $a2, $t2 # move col + 1 & GRIDSIZE into argument 2
- jal solve
- move $t7, $v0 # x = solve(current_board, next_row, (col + 1) % GRIDSIZE, puzzle)
- lw $ra, 0($sp)
- lw $a0, 4($sp)
- lw $a1, 8($sp)
- lw $a2, 12($sp)
- lw $a3, 16($sp)
- lw $t0, 20($sp)
- lw $t1, 24($sp)
- lw $t2, 28($sp)
- lw $t3, 32($sp)
- lw $t4, 36($sp)
- lw $t5, 40($sp)
- lw $t6, 44($sp)
- lw $v0, 48($sp)
- add $sp, $sp, 52
- beq $t7, $zero, final_set # branch if !(solve(current_board, next_row, (col + 1) % GRIDSIZE, puzzle))
- li $v0, 1 # return true
- j solve_end
- final_set:
- sh $t2, 0($t1) # current_board[row * GRIDSIZE + col] = possibles
- solve_for_loop_next:
- add $t3, $t3, 1 # ++number
- j solve_for_loop
- solve_for_loop_end:
- li $v0, 0 # return false
- j solve_end;
- solve_end:
- jr $ra
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement