[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