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>