I am compiling the following code for the MIPS architecture: <br><br>unsigned char trunc(float f) {<br> return (unsigned char) f;<br>}<br><br>and it produces the following assembly (directives removed for convenience: <br>
trunc:<br> trunc.w.s $f0, $f12<br> mfc1 $2, $f0<br> jr $ra<br> nop<br><br>However, this does not seem to produce the correct output for negative numbers. When I run the following code, I get -1 instead of 255 (which is produced by compiling natively with gcc).<br>
int trunc(float c);<br>int main() {<br> printf("%d\n", trunc(-1.0));<br>}<br><br>I am running the mips code on a PISA simulator (SimpleScalar's Simple-Sim 3.0) instead of a MIPS IV simulator, so there is a little bit of translation occurring before I can simulate it; here is the revised code:<br>
trunc:<br> cvt.w.s $f0, $f12<br>
mfc1 $2, $f0<br>
jr $ra<br>
nop<br>the cvt.w.s function in PISA MIPS is rounding towards zero, so it should meet the specification for trunc.w.s in MIPS IV.<br><br>Here are the commands I used to compile test.c (with the trunc function in it):<br>
clang -emit-llvm -mfloat-abi=hard -ccc-host-triple mipsel-unknown-linux -ccc-clang-archs mipsel -O3 -S -o test_unopt.ll test.c<br>opt -std-compile-opts test_unopt.ll -o test.ll<br>llc -march=mipsel -mcpu=mips32 -float-abi=hard -relocation-model=static test.ll -o test.s<br>
<br>Here is the llvm intermediate representation:<br>; ModuleID = 'test_unopt.ll'<br>target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"<br>target triple = "mipsel-unknown-linux"<br>
<br>define zeroext i8 @trunc(float %f) nounwind readnone {<br>entry:<br> %conv = fptoui float %f to i8<br> ret i8 %conv<br>}<br><br>This is the assembly produced by another compiler; it is more complex, but it produces the expected output, matching with GCC: (directives removed for convenience)<br>
trunc:<br> mov.s $f4,$f12<br> la $2,L6<br> l.s $f6,($2)<br> c.lt.s $f12,$f6<br> bc1t .L3<br> sub.s $f0,$f12,$f6<br> cvt.w.s $f0,$f0<br> mfc1 $2,$f0<br>
lui $3,32768<br> addu $3,$2,$3<br> j .L4<br>.L3:<br> cvt.w.s $f4,$f4<br> mfc1 $3,$f4<br>.L4:<br> sll $2,$3,24<br> srl $2,$2,24<br> sll $2,$2,24 <br>
srl $2,$2,24 <br> j $31<br>.data<br>.align 4<br>L6:<br>.word 1325400064<br><br>Am I correct in my analysis that LLVM's assembly output is wrong? Is there a way for me to get the correct output?<br>
<br>