[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-libjit] How to check the value of a boolean variable.
From: |
GARCIA DE SORIA LUCENA, JUAN JESUS |
Subject: |
[Dotgnu-libjit] How to check the value of a boolean variable. |
Date: |
Mon, 11 Aug 2008 09:56:18 +0200 |
Hi everyone.
I've added conditional expression support to the project we are using libjit
for, and I hit several stumbling blocks.
My implementation has several specializations depending on the expression data
type. When a complex type is involved, the compiled code delegates on a native
C++ function to test a condition value (in order to check whether it's true or
false). When the data type is simple enough, it's checked directly by
libjit-generated code.
Just to put everything in context, we're using a MinGW-compiled libjit from
inside a MSVC 2005 project in a Win32 host.
In the first case I originally used a native function that would return a bool
with the condition value. I used a jit_type_sys_bool as the returned type in
the native function signature, and tried to feed it to jit_insn_branch_if
and/or jit_insn_branch_if_not directly.
It didn't work, and when looking at the resulting code, I could see that the
native function was returning the boolean as a ubyte in register AL, while the
generated code was checking its value with (IIRC) an "OR EAX, EAX" opcode,
which would fail since the upper bytes of EAX wouldn't be clean. The generated
code did not extend the value to 32 bits before the test, nor would it use a
byte-sized comparison opcode.
I tried to follow the code a bit to see whether I was using libjit correctly. I
tried an equality comparison with a boolean constant, and it seemed to fail too
(in the same way, IIRC).
I looked at jit_insn_branch_if() in jit-insn.c, and it uses
jit_type_promote_int() of jit-type.c to check for a "standard int type" to feed
to the comparison opcodes (in this case I suppose that jit_type_uint with
JIT_OP_BR_ITRUE ended up being used). I see there that the value should be
converted to the correct type by the line:
value = jit_insn_convert(func, value, type, 0);
However somehow it ended up doing no operand (zero|sign)-extension.
In the end I just changed my test function to return int / sys_int, and it now
works properly, but this is just a dirty hack, and I think the issue should be
investigated properly.
I'm not sure, but I think this piece of code in jit_insn_convert() may be the
culprit:
/* Promote the source type, to reduce the number of cases in
the switch statement below */
vtype = jit_type_promote_int(vtype);
It will promote the type of the source operand, from UBYTE to UINT before the
switch which actually selects the opcodes.
Another case for this issue may be that libjit simply expects UBYTE and SBYTE
values to be stored at a 32 bit register or memory location at all times,
already correctly zero or sign-extended, and it gets confused when a call to a
native function returns the upper bytes in EAX dirty. If the previous
assumption is right and it's a design choice in libjit, then it may be easier
to just sign-extend the result of when a native function call happens to return
an undersized integer.
The second issue came when, for double data types, I just tried to do the same
with a "double" condition value, that is, 0.0 being false and everything else
being true.
Just feeding this to libjit jit_insn_branch_if() in the first try got me this
error (that I suppose is about opcode #89 being not unimplemented yet):
TODO(89) at jit-rules-x86.c, 1471
I just coded around this by explicitly emitting a comparison with a zero
constant.
Best regards, and thanks in advance,
Juan Jesús.
- [Dotgnu-libjit] How to check the value of a boolean variable.,
GARCIA DE SORIA LUCENA, JUAN JESUS <=