System info
- zig version 0.12.0-dev.15+1c7798a3c
- zig flags: -O ReleaseFast -target mips-linux-gnu
Background
New to MIPS, trying to figure out some simple examples!
I have the following zig code:
export fn mul_add(num: f32) f32 {
const result = 2e-3 * num + 1;
return result;
}
that generates the assembly:
$CPI0_0:
.4byte 0x3b03126f
$CPI0_1:
.4byte 0x3f800000
mul_add:
lui $1, %hi($CPI0_0)
lwc1 $f0, %lo($CPI0_0)($1)
lui $1, %hi($CPI0_1)
lwc1 $f1, %lo($CPI0_1)($1)
mul.s $f0, $f12, $f0 # <- here's the multiply!
jr $ra
add.s $f0, $f0, $f1 # <- here's the add!
If I change that zig code to use the builtin function @mulAdd
:
export fn mul_add(num: f32) f32 {
const result = @mulAdd(f32, 2e-3, num, 1);
return result;
}
it will instead generate this assembly:
$CPI0_0:
.4byte 0x3b03126f
mul_add:
addiu $sp, $sp, -24 # <- ...what is this add doing?
sw $ra, 20($sp)
lui $1, %hi($CPI0_0)
lwc1 $f14, %lo($CPI0_0)($1)
jal fmaf # <- multiply-then-add instruction?
lui $6, 16256
lw $ra, 20($sp)
jr $ra
addiu $sp, $sp, 24 # <- ...is this add undoing the first add?
This version is 9 instructions total, compared to the 7 total instructions of the original version.
Questions
- where's the multiply instruction in the
@mulAdd
version? - what's the gist of the second version's assembly? why does it need the additional two instructions compared to the first version?
- [EDIT] it seems that
jal
is used to jump to thefmaf
routine. But I don't seefmaf
anywhere else in the assembly. Where is that defined? (e.g., is that a MIPS builtin routine?) Do docs exist for that function?