.globl add64 .globl mul .text # > When primitive arguments twice the size of a pointer-word are passed on the # > stack, they are naturally aligned. When they are passed in the integer # > registers, they reside in an aligned even-odd register pair, with the even # > register holding the least-significant bits. # 64-bit integer addition # arguments: # a0: x lower 32 bits # a1: x upper 32 bits # a2: y lower 32 bits # a3: y upper 32 bits # return: # a0: x+y lower 32 bits # a1: x+y upper 32 bits # add64: add a0, a0, a2 # add lower 32 bits add t0, a1, a3 # add upper 32 bits sltu t1, a0, a2 # if lower 32-bit sum < a2 then set t1=1 (carry bit) add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit) ret # 32-bit shift-add multiplication # arguments: # a0: multiplicand # a1: multiplier # return: # a0 = a0 × a1 # mul: mv t0, a1 # Save multiplier in t0 li a1, 0 # Initialize product in a1 multiply_loop: beqz t0, done # If multiplier is 0, we're done andi t1, t0, 1 # Check least significant bit beqz t1, shift # If LSB is 0, skip addition add a1, a1, a0 # Add multiplicand to product shift: slli a0, a0, 1 # Shift multiplicand left srli t0, t0, 1 # Shift multiplier right j multiply_loop # Continue loop done: mv a0, a1 # Move product to return register ret