1.28. 64-BIT VALUES IN 32-BIT ENVIRONMENT
; $v1 - low part of result
f_sub:
; $a0 - high part of a
; $a1 - low part of a
; $a2 - high part of b
; $a3 - low part of b
subu $v1, $a1, $a3 ; subtract low parts
subu $v0, $a0, $a2 ; subtract high parts
; will carry generated while subtracting low parts?
; if yes, set $a0 to 1
sltu $a1, $v1
jr $ra
; subtract 1 from high part of result if carry should be generated:
subu $v0, $a1 ; branch delay slot
; $v0 - high part of result
; $v1 - low part of result
f_add_test:
var_10 = -0x10
var_4 = -4
lui $gp, (__gnu_local_gp >> 16)
addiu $sp, -0x20
la $gp, (__gnu_local_gp & 0xFFFF)
sw $ra, 0x20+var_4($sp)
sw $gp, 0x20+var_10($sp)
lui $a1, 0x73CE
lui $a3, 0x7593
li $a0, 0xB3A
li $a3, 0x75939F79
li $a2, 0x1555
jal f_add
li $a1, 0x73CE2FF2
lw $gp, 0x20+var_10($sp)
lui $a0, ($LC0 >> 16) # "%lld\n"
lw $t9, (printf & 0xFFFF)($gp)
lw $ra, 0x20+var_4($sp)
la $a0, ($LC0 & 0xFFFF) # "%lld\n"
move $a3, $v1
move $a2, $v0
jr $t9
addiu $sp, 0x20
$LC0: .ascii "%lld\n"<0>
MIPS has no flags register, so there is no such information present after the execution of arithmetic op-
erations. So there are no instructions like x86’sADCandSBB. To know if the carry flag would be set, a
comparison (usingSLTUinstruction) also occurs, which sets the destination register to 1 or 0. This 1 or 0
is then added or subtracted to/from the final result.
1.28.3 Multiplication, division
#include <stdint.h>
uint64_t f_mul (uint64_t a, uint64_t b)
{
return a*b;
};
uint64_t f_div (uint64_t a, uint64_t b)
{
return a/b;
};
uint64_t f_rem (uint64_t a, uint64_t b)
{