0

My OS is in Windows and a Raspberry Pi emulator is used in QEMU and with "GCC" is used to exercise a code

I have a code with arm and I am trying to transcribe it with VFP intrusions, but it does not show me the result and convert result of integer operation to decimal in assembler.

It should show, for example: 3.3 ^ 5 = 391.35393

At the moment I have it with integers and the result is correct 3 ^ 5 = 243 and i need with VFP: 3.0 ^ 5 = 243.000 but is result 0.00000

     .data

fmt:    .ascii "%f\n \000"

    .text
    .global main

main:
     push {fp, lr}

     MOV r1, #3
     VMOV s0, r1
     MOV r2, #5
     VMOV s2, r1
     
     BL X_POWER_Y   
     B loop

X_POWER_Y:

  CMP r2, #0        
  BEQ ZERO_COND

  CMP r2,#1         
  BEQ POWER_1

  MOV r3, #1

  while:
    CMP r3, r2 
        
        BGT BREAK

        ADD r3, r3, #1
        //MUL r0, r0, r1  //This line is commented

        //VFP
        vmul.f32 s4, s4, s0
        
        vcvt.f64.f32 d0, s4

        B while

        vmov    r2, r3, d0

POWER_1:
   MOV r0, r1
   B BREAK

ZERO_COND:
   MOV r0, #1
   B BREAK

BREAK:
   MOV r1, r0

loop:
    ldr r0, =fmt
    bl printf
    B _exit
    
    pop {fp, pc}

.end
JEMV
  • 1
  • 3
  • `pow(3.3, 5)` isn't an integer operation. The correct format string for printing a `double` is `.asciz "%f\n"` or `%g` - see the manual for printf conversions. You can't print a `float` because C variadic functions like printf can't take a `float` arg. See [How to print a single-precision float with printf](https://stackoverflow.com/q/37082784) – Peter Cordes Jul 05 '20 at 07:13
  • @PeterCordes The result when putting`%f` is 0.000000 – JEMV Jul 05 '20 at 07:16
  • Then the `double` you passed was `0.00000`, or rounded to that. Use a debugger to check your register values. https://godbolt.org/z/V_EqY2 shows what a C compiler does, which is generally a good first step in finding a working example. Check the calling convention docs to see where to pass a `double`; it appears that the two halves get passed in integer regs on GNU/Linux with the `softfp` float ABI. – Peter Cordes Jul 05 '20 at 07:45
  • If you have a [mcve] of actually trying to pass FP args to printf, then include that. Also include what OS you're running this on. – Peter Cordes Jul 05 '20 at 07:50
  • Thanks for the recommendations that you have given me, I have updated the code and I have tried with the VFP instructions for example `vcvt` `vmul`` vmov` but I do not handle these instructions correctly and I was a little confused because it does not show me the value, I understand that for To show the value I need to have `vmov r2, r3, d0` to have the same value for the 8 bytes that you need in precision double and it is sure that I am wrong or something is missing. – JEMV Jul 05 '20 at 08:14
  • `VMOV s0, r1` doesn't convert, it just uses that small integer *as* an FP bit-pattern. (It represents a very tiny subnormal value; squaring it will underflow to 0.0) https://www.h-schmidt.net/FloatConverter/IEEE754.html. BTW, your title still doesn't match what you're trying to do. – Peter Cordes Jul 05 '20 at 08:23
  • I understand what you recommend modifying the code for the result I want, am I new to this FP topic? Thanks for the information – JEMV Jul 05 '20 at 08:37
  • Replace your code with what GCC or clang emit for a C version of your code: https://godbolt.org/z/ZXkJ5U Splitting it up into caller that passes constants vs. function that takes args lets you see asm for putting constants in regs without optimizing it down to just printing the answer. (I used `-O1` instead of a more normal optimization level to not do inlining). Usually that means loading FP constants from memory, although for simple constants I think ARM has some instructions that take an immediate operand and put it in an FP register. – Peter Cordes Jul 05 '20 at 08:50

0 Answers0