[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