-3

I defined an assembly function which takes three parameters (int, double, double) which should add two putted double value and return the result of this addition. And I don't know why the below code doesn't work:

extern double ftaylor(unsigned int n, double x, double y);
int main()
{
    double z  = 14;
    z = ftaylor(30, 13.45, 7);


    printf("%f", z);
    return 0;
}

And the assembly function:

.globl ftaylor

ftaylor:
    .lcomm state, 8
    .lcomm state2, 8
    push %rbp
    mov %rsp, %rbp
    push %rax

    mov %rdi, %rax
    movsd %xmm0, state
    movsd %xmm1, state2

    finit

    fld state
    fld state2

    fadd %st(1), %st(0)

    fstp state
    fstp state2

    movsd state, %xmm0

    pop %rax
    mov %rbp, %rsp
    pop %rbp
    ret

The result printed on the terminal is 13.45. It looks like the processor doesn't perform the addition. I don't know why.

fingolfin
  • 77
  • 5
  • 4
    What is the argument `unsigned int n` for? And what do you expect the sum of the two double values `13.45` + `0` to be if it is not `13.45`? – Weather Vane May 18 '15 at 19:46
  • Is there any particular reason you don't move the arguments from `%xmm`-registers to the FPU via the stack? Using a static variable seems odd. – EOF May 18 '15 at 20:09
  • 3
    What is this blasphemous mix of SSE and x87?? And, as written, you simply overwrite `state`. – void_ptr May 18 '15 at 20:23
  • In the future this function should compute the specific taylor function, and the unsigned int is one of nedeed parameter. But now i only try to run the any floating point functionality. – fingolfin May 18 '15 at 20:33
  • The mix of SSE and x87 must be done, because in c the double and float parameter are passed to the function by xmm0 registers, and i wan't to use this function in c. – fingolfin May 18 '15 at 20:35
  • 1
    Never mind the overwrite part - AT&T syntax tricked me! Still, why don't you calculate everything using SSE? And, as noted, your output is correct given the inputs. – void_ptr May 18 '15 at 20:36
  • @Weather Vane for the 13.45 and 7 it don't work too. – fingolfin May 18 '15 at 20:37
  • 1
    Why not `addsd %xmm1, %xmm0`? No need to use x87 to add floating-point numbers. – EOF May 18 '15 at 20:37
  • Yes, but i must use x87. – fingolfin May 18 '15 at 20:38

2 Answers2

2

The main issue is that fld/fstp without a suffix defaults to s(hort) which is otherwise known as single precision float. But you have double precision values, so you should use fldl/fstpl. As others pointed out, do not use x87 unless absolutely necessary. Also, learn to use a debugger.

Jester
  • 56,577
  • 4
  • 81
  • 125
1

state, as calculated by the x87 code fragment, gets overwritten by value stored in xmm0:

...
movsd %xmm0, state
...
... x87 calculation of state ...
...
movsd state, %xmm0
...

After some back-and-forth, it does seem like the AT&T syntax may use the reversed arguments order, that is, mov a, b moves from b to a, which would explain the overwriting of the input argument, and the output observed by the OP. What exactly syntax his assembler is using remains unclear though, so I am a bit tentative about this answer.

Other possible reasons have been pointed out in other answers and comments.

void_ptr
  • 618
  • 5
  • 15
  • Err, no. The result of the x87-computation is saved into `state`, but whatever ABI the OP is using probably demands floating-point `return` to be in a `%xmm`-register, so that is what `movsd state, %xmm0` is doing. – EOF May 18 '15 at 20:30
  • You mean, this assembly notation uses `mov from, to`, not `mov to, from`? – void_ptr May 18 '15 at 20:32