lightning
[Top][All Lists]
Advanced

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

[Lightning] About _ASM_SAFETY


From: Paulo César Pereira de Andrade
Subject: [Lightning] About _ASM_SAFETY
Date: Sat, 28 Aug 2010 14:06:06 -0300

 Hi,

 I made a somewhat experimental commit yesterday,
what should be ok for a "playground" repository :-), but
I would like to comment about it.

 The patch pattern is basically:

*** lightning/i386/asm.h
- -#define _r4(R)  ( (_rC(R) == 0x40) ? _rN(R) : JITFAIL("32-bit
register required"))

*** lightning/i386/asm-32.h
+#  define _r4(R)  \
+    /* Valid 32 bit register? */ \
+    ((!((R) & ~0x77) \
+       /* 32, 16 or 8 bit register? */ \
+       && (_rC(R) == 0x40 || _rC(R) == 0x30 || _rC(R) == 0x10)) \
+       ? _rN(R) : JITFAIL("bad 32-bit register " #R))

*** lightning/i386/asm-64.h
+#  define _r4(R) \
+    /* Valid 64 bit register? */ \
+    ((!((R) & ~0xff) \
+       /* 64, 32, 16 or 8 bit register? */ \
+       && (_rC(R) == 0x50 || _rC(R) == 0x40 \
+               || _rC(R) == 0x30 || _rC(R) == 0x10)) \
+       ? _rN(R) : JITFAIL("bad 32-bit register " #R))

 This has the advantage over the previous macro checks that
it also checks if register specification is out of range, i.e. before
it would allow the common mistake of writing something like
jit_XYZr_i <register> <immediate>
and get it to pass because _rC(<immediate>) would match
the proper bit pattern by accident.

 But the major problem is that it now accepts things like
MOVQrr(_AL, _DL)
so, it may require some rework. The main reason of the patch
actually is the fact that x86_64 uses i386 macros, and these
macros fail because of receiving a 64 bits register argument,
for example:

#define jit_movi_l(d, is) ((is) \
? (_u32P((long)(is)) \
  ? MOVLir((is), (d)) \
  : MOVQir((is), (d))) \
: XORQrr ((d), (d)) )

is a case where a jit_reg32 would help, but there are way
too many "shared" jit_*{r,i}_i, and casting arguments on
all of them, or copying them to core-64.h would just cause
more problems.

 But, I believe this could be greatly simplified. Reason is
that If one uses static register names as macro arguments,
the C compiler should be able to remove most redundancy,
but, if one uses values that cannot be known to be constant
at compile time, gcc may actually generate a significantly
slower jit generator.

Possible way to simplify:
1. Define registers with only a class modifier, example:
   #define _RA    0x10
   ...
   #define _R15   0x1f
   ...
   #define _RAH  0x20  /* %ah and other top 8 bits of a 16 bit register */
   ...
   #define _RX0   0x40  /* mmx, sse, sse2 first register */

   after, that, do not use names like _AL, _AH, _AX, _EAX, and _RAX,
but just the _RA, and let the _ASM_SAFETY check ensure it is a valid
argument.

2. Add support for inline functions, to have compiler support
   for strict type checking, and use enums. This is tricky as
   it requires maintaining two implementations. But should
   allow the compiler to generate significantly better code for
   macro/inline function invocations with values not known at
   compile time.

 Other options include something like:
#if !_ASM_SAFETY
...
#elif _ASM_SAFETY == 1
/* my current patch */
#else
/* more strict patch, possibly only accepting 64 bit registers where
32 bit ones are required
* (explaining better :-) 64 bit registers actually mean an abstract
type/value check, and
* is a bitmask removed before generating code, so, effectively a 32
bit and a 64 bit register
* specification in lightning macros generate the same jit code) */
#endif

Thanks,
Paulo



reply via email to

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