[Vm-dev] Primitive 40 (asFloat) fails for me

Levente Uzonyi leves at caesar.elte.hu
Thu Feb 21 23:43:06 UTC 2019


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.

Levente




More information about the Vm-dev mailing list