Frage

I feel like I'm going crazy. I'm attempting to write a function which simulates hardware floating point addition in ARM assembly. I have a function float simulate_fp_add(float, float) which currently looks like this:

    .global simulated_fp_add
    .type simulated_fp_add, %function
simulated_fp_add:
    push {r3, r4, r5, r6, lr}

    mov r0, r0, lsr #1

    pop {r3, r4, r5, r6, pc}

My main file (simplified) currently just calls my ARM function with two arbitrary floats and outputs the result in decimal and binary:

#include <stdio.h>

float simulated_fp_add(float, float);
void prt_bin(unsigned int, unsigned int);

int main() {
    float x,y,z;
    unsigned int a,b,c;

    union
    {
       float f;
       unsigned int i;
    } u;

    x = 125;
    y = 0.5;

    u.f = x; 
    a = u.i;

    u.f = y;
    b = u.i;

    c = simulated_fp_add( a, b );
    u.f = c;

    printf("simulated_fp_add(%d, %d) = %f\n", a, b, u.f);

    printf("result in binary: ");
    prt_bin(c, 32);
    putchar('\n');

    return 0;
}

void prt_bin(unsigned int value, unsigned int length) {
    int i;
    for (i=(length-1); i>=0; i--) {
       if ((value >> i) & 1)
          putchar('1');
       else
          putchar('0');
    }
}

Output with shift line removed:

simulated_fp_add(1123680256, 1056964608) = 125.000000
result in binary: 01000010111110100000000000000000

Output WITH shifting:

simulated_fp_add(1123680256, 1056964608) = 0.000000
result in binary: 00000000000000000000000000000000

All my simulated_fp_add function does is shift the float in r0 right 1, but the result is zero? Am I missing something?

War es hilfreich?

Lösung

You have a combination of things that are acting against you.

float simulated_fp_add(float, float);

c = simulated_fp_add( a, b );
u.f = c;

You are calling a function that takes floats with integer values of floating point bit patterns. These are being converted to (garbage) floating point values before the call is made, which is probably not what you intended.

You are converting the return value of simulated_fp_add() to an unsigned int (c) and then converting that back to a float (u.f).

Finally, simulated_fp_add() does a logical shift right on a value that will be interpreted as float. The effect of this is unpredictable, but is likely to give you a subnormal floating point value that will be rounded down to zero in the above integer conversion.

You should start by writing an extremely small piece of code, testing it, and then building on it. Start with something like this:

unsigned int shift(unsigned int a);

int main() {
    unsigned int a, c;

    a = 5;
    printf("a = %0x\n", a);
    c = shift(a);
    printf("c = %0x\n", c);
    return 0;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top