lightning
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lightning] Let's shift again


From: Mike Spivey
Subject: [Lightning] Let's shift again
Date: Fri, 20 Feb 2009 21:57:24 +0000
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

Dear Paolo and all,

I'm sorry to say it, but the shift instructions still aren't working on i386.  
In
particular, "lshr_i V0 R1 V2" results in a message saying that the instruction 
is
unimplemented, but in fact "lshr_i R1 V1 V2" gives the wrong answers. (The 
problem
arises because i386 insists on having the *third* operand in ECX aka R1, so some
moves must be inserted if any other register is used.)

I've attached a test case that can be compiled with -DUNFIXED or -DFIX1 or 
-DFIX2.
 With FIX1, the instruction "lshr_i V0 R1 V2" works correctly, and "lshr_i R1 V1
V2" is unimplemented.  The fix is a simple matter of nesting calls to jit_op_ 
and
jit_replace in the opposite order with a couple of adjustments.

A better fix is provided with FIX2, because there R1 can be used as any of the
registers, but of course with varying penalties in pushes and pops and moves.

Best wishes,

-- Mike

#include <stdio.h>
#include "lightning.h"
     
#ifdef UNFIXED
/* Existing version of lightning gives wrong results for the PART3 tests,
   and wrongly claims that the PART2 tests are not supported */
#define PART3
#endif


#ifdef FIX1
/* This simple fix makes the PART2 tests work, but does not support the 
   PART3 tests */
#define PART2

#undef jit_lshr_i
#undef jit_rshr_i
#undef jit_rshr_ui

#define jit_lshr_i(d, r1, r2) \
     jit_op_((d), (r1), jit_replace((d), (r2), _ECX, SHLLrr(_CL, (d))))
#define jit_rshr_i(d, r1, r2) \
     jit_op_((d), (r1), jit_replace((d), (r2), _ECX, SARLrr(_CL, (d))))
#define jit_rshr_ui(d, r1, r2) \
     jit_op_((d), (r1), jit_replace((d), (r2), _ECX, SHRLrr(_CL, (d))))

#endif


#ifdef FIX2
/* A better fix that additionally supports having R1 = ECX as the 
   destination register, passing all tests. */
#define PART2
#define PART3

#undef jit_lshr_i
#undef jit_rshr_i
#undef jit_rshr_ui

#define jit_lshr_i(d, r1, r2) jit_shift(d, r1, r2, SHLLrr)
#define jit_rshr_i(d, r1, r2) jit_shift(d, r1, r2, SARLrr)
#define jit_rshr_ui(d, r1, r2) jit_shift(d, r1, r2, SHRLrr)

#define jit_shift(d, r1, r2, m)                                 \
     (((d) == _ECX)                                             \
      ? (jit_pushr_i(_EAX), jit_shiftop(_EAX, r1, r2, m),       \
         MOVLrr(_EAX, d), jit_popr_i(_EAX))                     \
      : jit_shiftop(d, r1, r2, m))

#define jit_shiftop(d, r1, r2, m) \
     jit_op_((d), (r1), jit_replace((d), (r2), _ECX, m(_CL, (d))))

#endif

static jit_insn codeBuffer[1024];
     
typedef int (*pifi)(int);    /* Pointer to Int Function of Int */
     
void test(int n, int r1, int r2, int r3, int res, int exp) {
     pifi fun = (pifi) (jit_set_ip(codeBuffer).iptr);
     int in, out;
     
     jit_prolog(1);
     in = jit_arg_i();
     jit_getarg_i(r2, in);

     jit_movi_i(r3, 2);
     jit_lshr_i(r1, r2, r3);
     jit_movr_i(JIT_RET, res);
     jit_ret();
     
     jit_flush_code(codeBuffer, jit_get_ip().ptr);
     
     out = fun(-16);
     printf("test %d: %d / %d\n", n, out, exp);
}

int main() {
     test(11, JIT_V0, JIT_V1, JIT_V2, JIT_V0, -64);
     test(12, JIT_V0, JIT_V1, JIT_V2, JIT_V1, -16);
     test(13, JIT_V0, JIT_V1, JIT_V2, JIT_V2, 2);

#ifdef PART2
     test(21, JIT_V0, JIT_R1, JIT_V2, JIT_V0, -64);
     test(22, JIT_V0, JIT_R1, JIT_V2, JIT_R1, -16);
     test(23, JIT_V0, JIT_R1, JIT_V2, JIT_V2, 2);
#endif

#ifdef PART3
     test(31, JIT_R1, JIT_V1, JIT_V2, JIT_R1, -64);
     test(32, JIT_R1, JIT_V1, JIT_V2, JIT_V1, -16);
     test(33, JIT_R1, JIT_V1, JIT_V2, JIT_V2, 2);
#endif

     test(41, JIT_V0, JIT_V1, JIT_R1, JIT_V0, -64);
     test(42, JIT_V0, JIT_V1, JIT_R1, JIT_V1, -16);
     test(43, JIT_V0, JIT_V1, JIT_R1, JIT_R1, 2);

     return 0;
}     

reply via email to

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