[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.

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 

        /* 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 

Best regards, and thanks in advance,

   Juan Jesús.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]