[Vm-dev] Primitive 40 (asFloat) fails for me
Tobias Pape
Das.Linux at gmx.de
Fri Feb 22 07:35:50 UTC 2019
Hi Levente.
> On 22.02.2019, at 00:43, Levente Uzonyi <leves at caesar.elte.hu> wrote:
>
> I had a look at the generated code and I think the generated code for primitiveAsFloat has no issues. The machine code is simple and looks correct with gcc 8, thought the pxor operation is unnecessary (and not generated by gcc 4) as cvtsi2sd will zero fill the higher 64 bits of xmm0.
>
> GCC 4.8:
>
> 0000000000432ff0 <primitiveAsFloat>:
> { DECL_MAYBE_SQ_GLOBAL_STRUCT
> 432ff0: 53 push %rbx
> rcvr = longAt(GIV(stackPointer));
> 432ff1: 48 8b 1d 20 24 36 00 mov 0x362420(%rip),%rbx # 795418 <stackPointer>
> longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), floatObjectOf(((double) ((rcvr >> 3)) )));
> 432ff8: 48 8b 03 mov (%rbx),%rax
> 432ffb: 48 c1 f8 03 sar $0x3,%rax
> 432fff: f2 48 0f 2a c0 cvtsi2sd %rax,%xmm0
> 433004: e8 37 ee ff ff callq 431e40 <floatObjectOf>
> 433009: 48 89 03 mov %rax,(%rbx)
> GIV(stackPointer) = sp;
> 43300c: 48 89 1d 05 24 36 00 mov %rbx,0x362405(%rip) # 795418 <stackPointer>
> }
> 433013: 5b pop %rbx
> 433014: c3 retq
> 433015: 90 nop
> 433016: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
> 43301d: 00 00 00
>
> GCC 8.2:
>
> 000000000004a1f0 <primitiveAsFloat>:
> { DECL_MAYBE_SQ_GLOBAL_STRUCT
> 4a1f0: 53 push %rbx
> rcvr = longAt(GIV(stackPointer));
> 4a1f1: 48 8b 1d 80 32 36 00 mov 0x363280(%rip),%rbx # 3ad478 <stackPointer>
> longAtput((sp = GIV(stackPointer) + ((1 - 1) * BytesPerWord)), floatObjectOf(((double) ((rcvr >> 3)) )));
> 4a1f8: 66 0f ef c0 pxor %xmm0,%xmm0
> 4a1fc: 48 8b 03 mov (%rbx),%rax
> 4a1ff: 48 c1 f8 03 sar $0x3,%rax
> 4a203: f2 48 0f 2a c0 cvtsi2sd %rax,%xmm0
> 4a208: e8 b3 eb ff ff callq 48dc0 <floatObjectOf>
> 4a20d: 48 89 03 mov %rax,(%rbx)
> GIV(stackPointer) = sp;
> 4a210: 48 89 1d 61 32 36 00 mov %rbx,0x363261(%rip) # 3ad478 <stackPointer>
> }
> 4a217: 5b pop %rbx
> 4a218: c3 retq
> 4a219: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
>
>
> Actually the returned float object is -100.0 (-100 asFloat < 0.0 returns true), but the code used for printing doesn't work properly, because #basicAt: returns 0 (when the argument is 1 or 2), and the method used to print the number uses #signBit to print the negative sign, and #signBit relies on #basicAt: returning a non-zero value when the number is negative.
>
> So, we're back to the original issue I found: #basicAt: (primitive 38) doesn't work with newer gcc versions.
>
Wow. Great analysis! Thank you :)
Best regards
-Tobias
More information about the Vm-dev
mailing list