1
0
forked from GitHub/gf-core

add x86_64 support to GNU lightning

This commit is contained in:
kr.angelov
2013-06-20 08:27:04 +00:00
parent e7b22ac609
commit 72cd14a5ae
13 changed files with 3395 additions and 1287 deletions

View File

@@ -43,6 +43,8 @@ AC_C_ASCII
case "$target_cpu" in
i?86) cpu=i386; AC_DEFINE(LIGHTNING_I386, 1,
[Define if lightning is targeting the x86 architecture]) ;;
x86_64) cpu=i386; AC_DEFINE(LIGHTNING_I386, 1,
[Define if lightning is targeting the x86 architecture]) ;;
sparc*) cpu=sparc; AC_DEFINE(LIGHTNING_SPARC, 1,
[Define if lightning is targeting the x86 architecture]) ;;
powerpc) cpu=ppc; AC_DEFINE(LIGHTNING_PPC, 1,

View File

@@ -14,7 +14,7 @@
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
@@ -24,8 +24,8 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
@@ -37,21 +37,25 @@
#ifndef _ASM_SAFETY
#define JITFAIL(MSG) 0
#else
#if defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3)
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || (defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3))
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __func__)
#else
#elif defined __GNUC__
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__)
#else
#define JITFAIL(MSG) jit_fail(MSG, __FILE__, __LINE__, "(unknown)")
#endif
#endif
#if defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3)
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || (defined __GNUC__ && (__GNUC__ == 3 ? __GNUC_MINOR__ >= 2 : __GNUC__ > 3))
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __func__)
#else
#elif defined __GNUC__
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, __FUNCTION__)
#else
#define JITSORRY(MSG) jit_fail("sorry, unimplemented: " MSG, __FILE__, __LINE__, "(unknown)")
#endif
#ifdef __GNUC__
#define JIT_UNUSED __attribute__((unused))
#define JIT_UNUSED __attribute__((__unused__))
#else
#define JIT_UNUSED
#endif
@@ -91,11 +95,13 @@ typedef unsigned long _ul;
#define _jit_UC(X) ((_uc )(X))
#define _jit_US(X) ((_us )(X))
#define _jit_UI(X) ((_ui )(X))
#define _jit_SI(X) ((int )(X))
#define _jit_SL(X) ((_sl )(X))
#define _jit_UL(X) ((_ul )(X))
# define _PUC(X) ((_uc *)(X))
# define _PUS(X) ((_us *)(X))
# define _PUI(X) ((_ui *)(X))
# define _PSI(X) ((int *)(X))
# define _PSL(X) ((_sl *)(X))
# define _PUL(X) ((_ul *)(X))
@@ -105,9 +111,9 @@ typedef unsigned long _ul;
#define _jit_L(L) _jit_UL(((*_jit.x.ul_pc++)= _jit_UL((L) )))
#define _jit_I_noinc(I) _jit_UL(((*_jit.x.ui_pc)= _jit_UI((I) )))
#define _MASK(N) ((unsigned)((1<<(N)))-1)
#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N)))
#define _uiP(N,I) (!(((unsigned)(I))&~_MASK(N)))
#define _MASK(N) ((unsigned long)((1L<<(N)))-1L)
#define _siP(N,I) (!((((unsigned long)(I))^(((unsigned long)(I))<<1))&~_MASK(N)))
#define _uiP(N,I) (!(((unsigned long)(I))&~_MASK(N)))
#define _suiP(N,I) (_siP(N,I) | _uiP(N,I))
#ifndef _ASM_SAFETY
@@ -125,8 +131,10 @@ typedef unsigned long _ul;
#define _s0P(I) ((I)==0)
#define _s8P(I) _siP(8,I)
#define _s16P(I) _siP(16,I)
#define _s32P(I) _siP(32,I)
#define _u8P(I) _uiP(8,I)
#define _u16P(I) _uiP(16,I)
#define _u32P(I) _uiP(32,I)
#define _su8(I) _ck_su(8,I)
#define _su16(I) _ck_su(16,I)

View File

@@ -45,12 +45,6 @@ typedef struct {
struct jit_local_state jitl;
} jit_state;
#ifdef jit_init
static jit_state _jit = jit_init ();
#else
static jit_state _jit;
#endif
#define JIT_NOREG (-1)
#define JIT_R0 JIT_R(0)
#define JIT_R1 JIT_R(1)

View File

@@ -0,0 +1,125 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the i386
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2003 Gwenole Beauchesne
* Copyright 2006 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
#ifndef LIGHTNING_DEBUG
/* OPCODE + i = immediate operand
* + r = register operand
* + m = memory operand (disp,base,index,scale)
* + sr/sm = a star preceding a register or memory
*/
#if !_ASM_SAFETY
# define _r1(R) _rN(R)
# define _r2(R) _rN(R)
# define _r4(R) _rN(R)
# define _r8(R) _rN(R)
# define _rM(R) _rN(R)
# define _rX(R) _rN(R)
#else
/* _r1() used to check only for _AL and _AH but there is
* usage of _CL and _DL when _*AX is already an operand */
# define _r1(R) \
/* Valid 32 bit register? */ \
((!((R) & ~0x77) \
/* 32, 16 or 8 bit register? */ \
&& (((_rC(R) == 0x40 || _rC(R) == 0x30 || _rC(R) == 0x10) \
/* Yes. Register is _AL, _CL or _DL? */ \
&& ( (_rN(R) | 0x10) == _AL \
|| (_rN(R) | 0x10) == _CL \
|| (_rN(R) | 0x10) == _DL)) \
/* No. Register is _AH? */ \
|| ((_rC(R) == 0x20 && (_rN(R) | 0x20) == _AH)))) \
? _rN(R) : JITFAIL("bad 8-bit register " #R))
# define _r2(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 16-bit register " #R))
# 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))
# define _r8(R) \
JITFAIL("bad 64-bit register " #R)
# define _rM(R) \
/* Valid MMX register? */ \
((!((R) & ~0x67) && _rC(R) == 0x60) \
? _rN(R) : JITFAIL("bad MMX register " #R))
# define _rX(R) \
/* Valid SSE register? */ \
((!((R) & ~0x77) && _rC(R) == 0x70) \
? _rN(R) : JITFAIL("bad SSE register " #R))
#endif
#define _rA(R) _r4(R)
#define jit_check8(rs) ((_rN(rs) | _AL) == _AL)
#define jit_reg8(rs) \
((jit_reg16(rs) == _SI || jit_reg16(rs) == _DI) \
? _AL : (_rN(rs) | _AL))
#define jit_reg16(rs) (_rN(rs) | _AX)
/* Use RIP-addressing in 64-bit mode, if possible */
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_ESP,_ESP,1) : \
_r_DB (R,D, B ))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#define _m32only(X) (X)
#define _m64only(X) JITFAIL("invalid instruction in 32-bit mode")
#define _m64(X) ((void)0)
#define _AH 0x24
#define _CH 0x25
#define _DH 0x26
#define _BH 0x27
#define CALLsr(R) CALLLsr(R)
#define JMPsr(R) JMPLsr(R)
#define DECWr(RD) (_d16(), _Or (0x48,_r2(RD) ))
#define DECLr(RD) _Or (0x48,_r4(RD) )
#define INCWr(RD) (_d16(), _Or (0x40,_r2(RD) ))
#define INCLr(RD) _Or (0x40,_r4(RD) )
#endif
#endif /* __lightning_asm_h */

View File

@@ -0,0 +1,430 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler for the x86-64
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2003 Gwenole Beauchesne
* Copyright 2006 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_asm_h
#define __lightning_asm_h
#ifndef LIGHTNING_DEBUG
/* OPCODE + i = immediate operand
* + r = register operand
* + m = memory operand (disp,base,index,scale)
* + sr/sm = a star preceding a register or memory
*/
#if !_ASM_SAFETY
# define _r1(R) _rN(R)
# define _r2(R) _rN(R)
# define _r4(R) _rN(R)
# define _r8(R) _rN(R)
# define _rM(R) _rN(R)
# define _rX(R) _rN(R)
#else
# define _r1(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 8-bit register " #R))
# define _r2(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 16-bit register " #R))
# 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))
# define _r8(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 64-bit register " #R))
# define _rM(R) \
/* Valid MMX* register? */ \
((!((R) & ~0x6f) && _rC(R) == 0x60) \
? _rN(R) : JITFAIL("bad MMX register " #R))
# define _rX(R) \
/* Valid SSE2 register? */ \
((!((R) & ~0x7f) && _rC(R) == 0x70) \
? _rN(R) : JITFAIL("bad SSE2 register " #R))
#endif
#define _rA(R) _r8(R)
#define jit_check8(rs) 1
#define jit_reg8(rs) (_rR(rs) | _AL)
#define jit_reg16(rs) (_rR(rs) | _AX)
/* Use RIP-addressing in 64-bit mode, if possible */
#if 0
#define _x86_RIP_addressing_possible(D,O) (X86_RIP_RELATIVE_ADDR && \
((unsigned long)x86_get_target() + 4 + (O) - (D) <= 0xffffffff))
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? (!X86_TARGET_64BIT ? _r_D(R,D) : \
(_x86_RIP_addressing_possible(D, O) ? \
_r_D(R, (D) - ((unsigned long)x86_get_target() + 4 + (O))) : \
_r_DSIB(R,D))) : \
_r_DSIB(R,D )) : \
(_rIP(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_RSP,_RSP,1) : \
_r_DB (R,D, B )))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#else
#define _r_X( R, D,B,I,S,O) (_r0P(I) ? (_r0P(B) ? _r_DSIB(R,D ) : \
(_rIP(B) ? _r_D (R,D ) : \
(_rsp12P(B) ? _r_DBIS(R,D,_RSP,_RSP,1) : \
_r_DB (R,D, B )))) : \
(_r0P(B) ? _r_4IS (R,D, I,S) : \
(!_rspP(I) ? _r_DBIS(R,D, B, I,S) : \
JITFAIL("illegal index register: %esp"))))
#endif
#define _m32only(X) (JITFAIL("invalid instruction in 64-bit mode"))
#define _m64only(X) (X)
#define _m64(X) (X)
#define _SPL 0x14
#define _BPL 0x15
#define _SIL 0x16
#define _DIL 0x17
#define _R8B 0x18
#define _R9B 0x19
#define _R10B 0x1A
#define _R11B 0x1B
#define _R12B 0x1C
#define _R13B 0x1D
#define _R14B 0x1E
#define _R15B 0x1F
#define _R8W 0x38
#define _R9W 0x39
#define _R10W 0x3A
#define _R11W 0x3B
#define _R12W 0x3C
#define _R13W 0x3D
#define _R14W 0x3E
#define _R15W 0x3F
#define _R8D 0x48
#define _R9D 0x49
#define _R10D 0x4A
#define _R11D 0x4B
#define _R12D 0x4C
#define _R13D 0x4D
#define _R14D 0x4E
#define _R15D 0x4F
#define _RAX 0x50
#define _RCX 0x51
#define _RDX 0x52
#define _RBX 0x53
#define _RSP 0x54
#define _RBP 0x55
#define _RSI 0x56
#define _RDI 0x57
#define _R8 0x58
#define _R9 0x59
#define _R10 0x5A
#define _R11 0x5B
#define _R12 0x5C
#define _R13 0x5D
#define _R14 0x5E
#define _R15 0x5F
#define _RIP -2
#define _r1e8lP(R) ((int)(R) >= _SPL && (int)(R) <= _DIL)
#define DECWr(RD) (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r2(RD) ))
#define DECLr(RD) (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r4(RD) ))
#define INCWr(RD) (_d16(), _REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r2(RD) ))
#define INCLr(RD) (_REXLrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r4(RD) ))
#define ADCQrr(RS, RD) _ALUQrr(X86_ADC, RS, RD)
#define ADCQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADC, MD, MB, MI, MS, RD)
#define ADCQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADC, RS, MD, MB, MI, MS)
#define ADCQir(IM, RD) _ALUQir(X86_ADC, IM, RD)
#define ADCQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADC, IM, MD, MB, MI, MS)
#define ADDQrr(RS, RD) _ALUQrr(X86_ADD, RS, RD)
#define ADDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_ADD, MD, MB, MI, MS, RD)
#define ADDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_ADD, RS, MD, MB, MI, MS)
#define ADDQir(IM, RD) _ALUQir(X86_ADD, IM, RD)
#define ADDQim(IM, MD, MB, MI, MS) _ALUQim(X86_ADD, IM, MD, MB, MI, MS)
#define ANDQrr(RS, RD) _ALUQrr(X86_AND, RS, RD)
#define ANDQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_AND, MD, MB, MI, MS, RD)
#define ANDQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_AND, RS, MD, MB, MI, MS)
#define ANDQir(IM, RD) _ALUQir(X86_AND, IM, RD)
#define ANDQim(IM, MD, MB, MI, MS) _ALUQim(X86_AND, IM, MD, MB, MI, MS)
#define CMPQrr(RS, RD) _ALUQrr(X86_CMP, RS, RD)
#define CMPQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_CMP, MD, MB, MI, MS, RD)
#define CMPQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_CMP, RS, MD, MB, MI, MS)
#define CMPQir(IM, RD) _ALUQir(X86_CMP, IM, RD)
#define CMPQim(IM, MD, MB, MI, MS) _ALUQim(X86_CMP, IM, MD, MB, MI, MS)
#define ORQrr(RS, RD) _ALUQrr(X86_OR, RS, RD)
#define ORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_OR, MD, MB, MI, MS, RD)
#define ORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_OR, RS, MD, MB, MI, MS)
#define ORQir(IM, RD) _ALUQir(X86_OR, IM, RD)
#define ORQim(IM, MD, MB, MI, MS) _ALUQim(X86_OR, IM, MD, MB, MI, MS)
#define SBBQrr(RS, RD) _ALUQrr(X86_SBB, RS, RD)
#define SBBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SBB, MD, MB, MI, MS, RD)
#define SBBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SBB, RS, MD, MB, MI, MS)
#define SBBQir(IM, RD) _ALUQir(X86_SBB, IM, RD)
#define SBBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SBB, IM, MD, MB, MI, MS)
#define SUBQrr(RS, RD) _ALUQrr(X86_SUB, RS, RD)
#define SUBQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_SUB, MD, MB, MI, MS, RD)
#define SUBQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_SUB, RS, MD, MB, MI, MS)
#define SUBQir(IM, RD) _ALUQir(X86_SUB, IM, RD)
#define SUBQim(IM, MD, MB, MI, MS) _ALUQim(X86_SUB, IM, MD, MB, MI, MS)
#define XORQrr(RS, RD) _ALUQrr(X86_XOR, RS, RD)
#define XORQmr(MD, MB, MI, MS, RD) _ALUQmr(X86_XOR, MD, MB, MI, MS, RD)
#define XORQrm(RS, MD, MB, MI, MS) _ALUQrm(X86_XOR, RS, MD, MB, MI, MS)
#define XORQir(IM, RD) _ALUQir(X86_XOR, IM, RD)
#define XORQim(IM, MD, MB, MI, MS) _ALUQim(X86_XOR, IM, MD, MB, MI, MS)
#define ROLQir(IM, RD) _ROTSHIQir(X86_ROL, IM, RD)
#define ROLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROL, IM, MD, MB, MI, MS)
#define ROLQrr(RS, RD) _ROTSHIQrr(X86_ROL, RS, RD)
#define ROLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROL, RS, MD, MB, MI, MS)
#define RORQir(IM, RD) _ROTSHIQir(X86_ROR, IM, RD)
#define RORQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_ROR, IM, MD, MB, MI, MS)
#define RORQrr(RS, RD) _ROTSHIQrr(X86_ROR, RS, RD)
#define RORQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_ROR, RS, MD, MB, MI, MS)
#define RCLQir(IM, RD) _ROTSHIQir(X86_RCL, IM, RD)
#define RCLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCL, IM, MD, MB, MI, MS)
#define RCLQrr(RS, RD) _ROTSHIQrr(X86_RCL, RS, RD)
#define RCLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCL, RS, MD, MB, MI, MS)
#define RCRQir(IM, RD) _ROTSHIQir(X86_RCR, IM, RD)
#define RCRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_RCR, IM, MD, MB, MI, MS)
#define RCRQrr(RS, RD) _ROTSHIQrr(X86_RCR, RS, RD)
#define RCRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_RCR, RS, MD, MB, MI, MS)
#define SHLQir(IM, RD) _ROTSHIQir(X86_SHL, IM, RD)
#define SHLQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHL, IM, MD, MB, MI, MS)
#define SHLQrr(RS, RD) _ROTSHIQrr(X86_SHL, RS, RD)
#define SHLQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHL, RS, MD, MB, MI, MS)
#define SHRQir(IM, RD) _ROTSHIQir(X86_SHR, IM, RD)
#define SHRQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SHR, IM, MD, MB, MI, MS)
#define SHRQrr(RS, RD) _ROTSHIQrr(X86_SHR, RS, RD)
#define SHRQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SHR, RS, MD, MB, MI, MS)
#define SALQir SHLQir
#define SALQim SHLQim
#define SALQrr SHLQrr
#define SALQrm SHLQrm
#define SARQir(IM, RD) _ROTSHIQir(X86_SAR, IM, RD)
#define SARQim(IM, MD, MB, MI, MS) _ROTSHIQim(X86_SAR, IM, MD, MB, MI, MS)
#define SARQrr(RS, RD) _ROTSHIQrr(X86_SAR, RS, RD)
#define SARQrm(RS, MD, MB, MI, MS) _ROTSHIQrm(X86_SAR, RS, MD, MB, MI, MS)
#define BTQir(IM, RD) _BTQir(X86_BT, IM, RD)
#define BTQim(IM, MD, MB, MI, MS) _BTQim(X86_BT, IM, MD, MB, MI, MS)
#define BTQrr(RS, RD) _BTQrr(X86_BT, RS, RD)
#define BTQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BT, RS, MD, MB, MI, MS)
#define BTCQir(IM, RD) _BTQir(X86_BTC, IM, RD)
#define BTCQim(IM, MD, MB, MI, MS) _BTQim(X86_BTC, IM, MD, MB, MI, MS)
#define BTCQrr(RS, RD) _BTQrr(X86_BTC, RS, RD)
#define BTCQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTC, RS, MD, MB, MI, MS)
#define BTRQir(IM, RD) _BTQir(X86_BTR, IM, RD)
#define BTRQim(IM, MD, MB, MI, MS) _BTQim(X86_BTR, IM, MD, MB, MI, MS)
#define BTRQrr(RS, RD) _BTQrr(X86_BTR, RS, RD)
#define BTRQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTR, RS, MD, MB, MI, MS)
#define BTSQir(IM, RD) _BTQir(X86_BTS, IM, RD)
#define BTSQim(IM, MD, MB, MI, MS) _BTQim(X86_BTS, IM, MD, MB, MI, MS)
#define BTSQrr(RS, RD) _BTQrr(X86_BTS, RS, RD)
#define BTSQrm(RS, MD, MB, MI, MS) _BTQrm(X86_BTS, RS, MD, MB, MI, MS)
#define LEAQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8d ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x89 ,_b11,_r8(RS),_r8(RD) ))
#define MOVQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _O_r_X (0x8b ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x89 ,_r8(RS) ,MD,MB,MI,MS ))
#define MOVQir(IM, R) (_REXQrr(0, R), _Or_Q (0xb8,_r8(R) ,IM ))
#define MOVQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_X_L (0xc7 ,MD,MB,MI,MS ,IM ))
#define NOTQr(RS) _UNARYQr(X86_NOT, RS)
#define NOTQm(MD, MB, MI, MS) _UNARYQm(X86_NOT, MD, MB, MI, MS)
#define NEGQr(RS) _UNARYQr(X86_NEG, RS)
#define NEGQm(MD, MB, MI, MS) _UNARYQm(X86_NEG, MD, MB, MI, MS)
#define MULQr(RS) _UNARYQr(X86_MUL, RS)
#define MULQm(MD, MB, MI, MS) _UNARYQm(X86_MUL, MD, MB, MI, MS)
#define IMULQr(RS) _UNARYQr(X86_IMUL, RS)
#define IMULQm(MD, MB, MI, MS) _UNARYQm(X86_IMUL, MD, MB, MI, MS)
#define DIVQr(RS) _UNARYQr(X86_DIV, RS)
#define DIVQm(MD, MB, MI, MS) _UNARYQm(X86_DIV, MD, MB, MI, MS)
#define IDIVQr(RS) _UNARYQr(X86_IDIV, RS)
#define IDIVQm(MD, MB, MI, MS) _UNARYQm(X86_IDIV, MD, MB, MI, MS)
#define IMULQir(IM, RD) IMULQirr(IM, RD, RD)
#define IMULQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0faf ,_b11,_r8(RD),_r8(RS) ))
#define IMULQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0faf ,_r8(RD) ,MD,MB,MI,MS ))
#define IMULQirr(IM,RS,RD) (_REXQrr(RD, RS), _Os_Mrm_sL (0x69 ,_b11,_r8(RS),_r8(RD) ,IM ))
#define IMULQimr(IM,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _Os_r_X_sL (0x69 ,_r8(RD) ,MD,MB,MI,MS ,IM ))
#define CALLQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b010,_r8(R) ))
#define JMPQsr(R) (_REXQrr(0, R), _O_Mrm (0xff ,_b11,_b100,_r8(R) ))
#define CMOVQrr(CC,RS,RD) (_REXQrr(RD, RS), _OO_Mrm (0x0f40|(CC) ,_b11,_r8(RD),_r8(RS) ))
#define CMOVQmr(CC,MD,MB,MI,MS,RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f40|(CC) ,_r8(RD) ,MD,MB,MI,MS ))
#define POPQr(RD) _m64only((_REXQr(RD), _Or (0x58,_r8(RD) )))
#define POPQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )))
#define PUSHQr(RS) _m64only((_REXQr(RS), _Or (0x50,_r8(RS) )))
#define PUSHQm(MD, MB, MI, MS) _m64only((_REXQm(MB, MI), _O_r_X (0xff ,_b110 ,MD,MB,MI,MS )))
#define PUSHQi(IM) _m64only( _Os_sL (0x68 ,IM ))
#define TESTQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x85 ,_b11,_r8(RS),_r8(RD) ))
#define TESTQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x85 ,_r8(RS) ,MD,MB,MI,MS ))
#define TESTQir(IM, RD) \
/* Immediate fits in 32 bits? */ \
(_s32P((long)(IM)) \
/* Yes. Immediate does not fit in 8 bits and reg is %rax? */ \
? (!_s8P(IM) && (RD) == _RAX \
? (_REXQrr(0, RD), _O_L(0xa9, IM)) \
: (_REXQrr(0, RD), _O_Mrm_L(0xf7, _b11, _b000, _r8(RD), IM))) \
/* No. Need immediate in a register */ \
: (MOVQir(IM, JIT_REXTMP), TESTQrr(JIT_REXTMP, RD)))
#define TESTQim(IM, MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X_L (0xf7 ,_b000 ,MD,MB,MI,MS ,IM ))
#define CMPXCHGQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fb1 ,_b11,_r8(RS),_r8(RD) ))
#define CMPXCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fb1 ,_r8(RS) ,MD,MB,MI,MS ))
#define XADDQrr(RS, RD) (_REXQrr(RS, RD), _OO_Mrm (0x0fc1 ,_b11,_r8(RS),_r8(RD) ))
#define XADDQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0fc1 ,_r8(RS) ,MD,MB,MI,MS ))
#define XCHGQrr(RS, RD) (_REXQrr(RS, RD), _O_Mrm (0x87 ,_b11,_r8(RS),_r8(RD) ))
#define XCHGQrm(RS, MD, MB, MI, MS) (_REXQrm(RS, MB, MI), _O_r_X (0x87 ,_r8(RS) ,MD,MB,MI,MS ))
#define DECQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b001 ,MD,MB,MI,MS ))
#define DECQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b001 ,_r8(RD) ))
#define INCQm(MD, MB, MI, MS) (_REXQrm(0, MB, MI), _O_r_X (0xff ,_b000 ,MD,MB,MI,MS ))
#define INCQr(RD) (_REXQrr(0, RD), _O_Mrm (0xff ,_b11,_b000 ,_r8(RD) ))
#define BSFQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbc ,_b11,_r8(RD),_r8(RS) ))
#define BSFQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbc ,_r8(RD) ,MD,MB,MI,MS ))
#define BSRQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbd ,_b11,_r8(RD),_r8(RS) ))
#define BSRQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbd ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbe ,_b11,_r8(RD),_r1(RS) ))
#define MOVSBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbe ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVZBQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb6 ,_b11,_r8(RD),_r1(RS) ))
#define MOVZBQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb6 ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fbf ,_b11,_r8(RD),_r2(RS) ))
#define MOVSWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fbf ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVZWQrr(RS, RD) (_REXQrr(RD, RS), _OO_Mrm (0x0fb7 ,_b11,_r8(RD),_r2(RS) ))
#define MOVZWQmr(MD, MB, MI, MS, RD) (_REXQmr(MB, MI, RD), _OO_r_X (0x0fb7 ,_r8(RD) ,MD,MB,MI,MS ))
#define MOVSLQrr(RS, RD) _m64only((_REXQrr(RD, RS), _O_Mrm (0x63 ,_b11,_r8(RD),_r4(RS) )))
#define MOVSLQmr(MD, MB, MI, MS, RD) _m64only((_REXQmr(MB, MI, RD), _O_r_X (0x63 ,_r8(RD) ,MD,MB,MI,MS )))
#define BSWAPQr(R) (_REXQrr(0, R), _OOr (0x0fc8,_r8(R) ))
#define __SSEQrr(OP,RS,RSA,RD,RDA) (_REXQrr(RD, RS), _OO_Mrm (0x0f00|(OP) ,_b11,RDA(RD),RSA(RS) ))
#define __SSEQmr(OP,MD,MB,MI,MS,RD,RDA) (_REXQmr(MB, MI, RD), _OO_r_X (0x0f00|(OP) ,RDA(RD) ,MD,MB,MI,MS ))
#define __SSEQrm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f00|(OP) ,RSA(RS) ,MD,MB,MI,MS ))
#define __SSEQ1rm(OP,RS,RSA,MD,MB,MI,MS) (_REXQrm(RS, MB, MI), _OO_r_X (0x0f01|(OP) ,RSA(RS) ,MD,MB,MI,MS ))
#define _SSEQrr(PX,OP,RS,RSA,RD,RDA) (_jit_B(PX), __SSEQrr(OP, RS, RSA, RD, RDA))
#define _SSEQmr(PX,OP,MD,MB,MI,MS,RD,RDA) (_jit_B(PX), __SSEQmr(OP, MD, MB, MI, MS, RD, RDA))
#define _SSEQrm(PX,OP,RS,RSA,MD,MB,MI,MS) (_jit_B(PX), __SSEQrm(OP, RS, RSA, MD, MB, MI, MS))
#define _SSEQ1rm(PX,OP,RS,RSA,MD,MB,MI,MS) (_jit_B(PX), __SSEQ1rm(OP, RS, RSA, MD, MB, MI, MS))
#define CVTTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTTSI, RS,_rX, RD,_r8)
#define CVTTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTTSI, MD, MB, MI, MS, RD,_r8)
#define CVTTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTTSI, RS,_rX, RD,_r8)
#define CVTTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSS2SIQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTSI, RS,_rX, RD,_r8)
#define CVTSS2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSD2SIQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTSI, RS,_rX, RD,_r8)
#define CVTSD2SIQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTSI, MD, MB, MI, MS, RD,_r8)
#define CVTSI2SSQrr(RS, RD) _SSEQrr(0xf3, X86_SSE_CVTIS, RS,_r8, RD,_rX)
#define CVTSI2SSQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf3, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX)
#define CVTSI2SDQrr(RS, RD) _SSEQrr(0xf2, X86_SSE_CVTIS, RS,_r8, RD,_rX)
#define CVTSI2SDQmr(MD, MB, MI, MS, RD) _SSEQmr(0xf2, X86_SSE_CVTIS, MD, MB, MI, MS, RD,_rX)
#define MOVDQXrr(RS, RD) _SSEQrr(0x66, 0x6e, RS,_r8, RD,_rX)
#define MOVDQXmr(MD, MB, MI, MS, RD) _SSEQmr(0x66, 0x6e, MD, MB, MI, MS, RD,_rX)
#define MOVDXQrr(RS, RD) _SSEQrr(0x66, 0x7e, RS,_rX, RD,_r8)
#define MOVDXQrm(RS, MD, MB, MI, MS) _SSEQrm(0x66, 0x7e, RS,_rX, MD, MB, MI, MS)
#define MOVDQMrr(RS, RD) __SSEQrr( 0x6e, RS,_r8, RD,_rM)
#define MOVDQMmr(MD, MB, MI, MS, RD) __SSEQmr( 0x6e, MD, MB, MI, MS, RD,_rM)
#define MOVDMQrr(RS, RD) __SSEQrr( 0x7e, RS,_rM, RD,_r8)
#define MOVDMQrm(RS, MD, MB, MI, MS) __SSEQrm( 0x7e, RS,_rM, MD, MB, MI, MS)
#define CALLsr(R) CALLQsr(R)
#define JMPsr(R) JMPQsr(R)
#endif
#endif /* __lightning_asm_h */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (i386 version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
#define JIT_CAN_16 1
#define JIT_AP _EBP
#define JIT_R_NUM 3
#define JIT_R(i) (_EAX + (i))
#define JIT_V_NUM 3
#define JIT_V(i) ((i) == 0 ? _EBX : _ESI + (i) - 1)
struct jit_local_state {
int framesize;
int argssize;
int alloca_offset;
int alloca_slack;
jit_insn *finish_ref;
};
/* Whether a register is used for the user-accessible registers. */
#define jit_save(reg) 1
#define jit_base_prolog() (_jitl.framesize = 20, _jitl.alloca_offset = _jitl.alloca_slack = 0, \
PUSHLr(_EBX), PUSHLr(_ESI), PUSHLr(_EDI), PUSHLr(_EBP), MOVLrr(_ESP, _EBP))
#define jit_base_ret(ofs) \
(((ofs) < 0 ? LEAVE_() : POPLr(_EBP)), \
POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), RET_())
/* Used internally. SLACK is used by the Darwin ABI which keeps the stack
aligned to 16-bytes. */
#define jit_allocai_internal(amount, slack) \
(((amount) < _jitl.alloca_slack \
? (void)0 \
: (void)(_jitl.alloca_slack += (amount) + (slack), \
((amount) + (slack) == sizeof (int) \
? PUSHLr(_EAX) \
: SUBLir((amount) + (slack), _ESP)))), \
_jitl.alloca_slack -= (amount), \
_jitl.alloca_offset -= (amount))
/* Stack */
#define jit_pushr_i(rs) PUSHLr(rs)
#define jit_popr_i(rs) POPLr(rs)
/* The += in argssize allows for stack pollution */
#ifdef __APPLE__
/* Stack must stay 16-byte aligned: */
# define jit_prepare_i(ni) (((ni & 0x3) \
? (void)SUBLir(4 * ((((ni) + 3) & ~(0x3)) - (ni)), JIT_SP) \
: (void)0), \
_jitl.argssize += (((ni) + 3) & ~(0x3)))
#define jit_allocai(n) \
jit_allocai_internal ((n), (_jitl.alloca_slack - (n)) & 15)
#define jit_prolog(n) (jit_base_prolog(), jit_subi_i (JIT_SP, JIT_SP, 12))
#define jit_ret() jit_base_ret (-12)
#else
# define jit_prepare_i(ni) (_jitl.argssize += (ni))
#define jit_allocai(n) \
jit_allocai_internal ((n), 0)
#define jit_prolog(n) jit_base_prolog()
#define jit_ret() jit_base_ret (_jitl.alloca_offset)
#endif
#define jit_calli(label) (CALLm( ((unsigned long) (label))), _jit.x.pc)
#define jit_callr(reg) CALLsr(reg)
#define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (_jitl.finish_ref = jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0, _jitl.finish_ref)
#define jit_finishr(reg) (jit_callr((reg)), )
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_us() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_i() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_ui() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_l() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_ul() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_p() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_movi_p(d, is) (MOVLir (((long)(is)), (d)), _jit.x.pc)
#define jit_patch_long_at(jump_pc,v) (*_PSL((jump_pc) - sizeof(long)) = _jit_SL((jit_insn *)(v) - (jump_pc)))
#define jit_patch_at(jump_pc,v) jit_patch_long_at(jump_pc, v)
/* Memory */
#define jit_replace(s, rep, op) \
(jit_pushr_i(rep), \
MOVLrr((s), (rep)), \
op, jit_popr_i(rep))
#define jit_movbrm(rs, dd, db, di, ds) \
(jit_check8(rs) \
? MOVBrm(jit_reg8(rs), dd, db, di, ds) \
: jit_replace(rs, \
((dd != _EAX && db != _EAX && di != _EAX) ? _EAX : \
((dd != _ECX && db != _ECX && di != _ECX) ? _ECX : _EDX)), \
MOVBrm(((dd != _EAX && db != _EAX && di != _EAX) ? _AL : \
((dd != _ECX && db != _ECX && di != _ECX) ? _CL : _DL)), \
dd, db, di, ds)))
#define jit_ldr_c(d, rs) MOVSBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_c(d, s1, s2) MOVSBLmr(0, (s1), (s2), 1, (d))
#define jit_ldr_s(d, rs) MOVSWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_s(d, s1, s2) MOVSWLmr(0, (s1), (s2), 1, (d))
#define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d))
#define jit_ldxi_c(d, rs, is) MOVSBLmr((is), (rs), 0, 0, (d))
#define jit_ldi_uc(d, is) MOVZBLmr((is), 0, 0, 0, (d))
#define jit_ldxi_uc(d, rs, is) MOVZBLmr((is), (rs), 0, 0, (d))
#define jit_sti_c(id, rs) jit_movbrm((rs), (id), 0, 0, 0)
#define jit_stxi_c(id, rd, rs) jit_movbrm((rs), (id), (rd), 0, 0)
#define jit_ldi_s(d, is) MOVSWLmr((is), 0, 0, 0, (d))
#define jit_ldxi_s(d, rs, is) MOVSWLmr((is), (rs), 0, 0, (d))
#define jit_ldi_us(d, is) MOVZWLmr((is), 0, 0, 0, (d))
#define jit_ldxi_us(d, rs, is) MOVZWLmr((is), (rs), 0, 0, (d))
#define jit_sti_s(id, rs) MOVWrm(jit_reg16(rs), (id), 0, 0, 0)
#define jit_stxi_s(id, rd, rs) MOVWrm(jit_reg16(rs), (id), (rd), 0, 0)
#define jit_ldi_i(d, is) MOVLmr((is), 0, 0, 0, (d))
#define jit_ldxi_i(d, rs, is) MOVLmr((is), (rs), 0, 0, (d))
#define jit_ldr_i(d, rs) MOVLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_i(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
#define jit_sti_i(id, rs) MOVLrm((rs), (id), 0, 0, 0)
#define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0)
#endif /* __lightning_core_h */

View File

@@ -0,0 +1,498 @@
/******************************** -*- C -*- ****************************
*
* Platform-independent layer (i386 version)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#ifndef __lightning_core_h
#define __lightning_core_h
/* Used to implement ldc, stc, ... */
#define JIT_CAN_16 0
#define JIT_REXTMP _R12
/* Number or integer argument registers */
#define JIT_ARG_MAX 6
/* Number of float argument registers */
#define JIT_FP_ARG_MAX 8
#define JIT_R_NUM 3
#define JIT_R(i) ((i) == 0 ? _EAX : _R9 + (i))
#define JIT_V_NUM 3
#define JIT_V(i) ((i) == 0 ? _EBX : _R12 + (i))
struct jit_local_state {
int long_jumps;
int nextarg_getfp;
int nextarg_putfp;
int nextarg_geti;
int nextarg_puti;
int framesize;
int argssize;
int fprssize;
int alloca_offset;
int alloca_slack;
jit_insn *finish_ref;
};
/* Whether a register in the "low" bank is used for the user-accessible
registers. */
#define jit_save(reg) ((reg) == _EAX || (reg) == _EBX)
/* Keep the stack 16-byte aligned, the SSE hardware prefers it this way. */
#define jit_allocai_internal(amount, slack) \
(((amount) < _jitl.alloca_slack \
? 0 \
: (_jitl.alloca_slack += (amount) + (slack), \
SUBQir((amount) + (slack), _ESP))), \
_jitl.alloca_slack -= (amount), \
_jitl.alloca_offset -= (amount))
#define jit_allocai(n) \
jit_allocai_internal ((n), (_jitl.alloca_slack - (n)) & 15)
/* 3-parameter operation */
#define jit_qopr_(d, s1, s2, op1d, op2d) \
( ((s2) == (d)) ? op1d : \
( (((s1) == (d)) ? (void)0 : (void)MOVQrr((s1), (d))), op2d ) \
)
/* 3-parameter operation, with immediate. TODO: fix the case where mmediate
does not fit! */
#define jit_qop_small(d, s1, op2d) \
(((s1) == (d)) ? op2d : (MOVQrr((s1), (d)), op2d))
#define jit_qop_(d, s1, is, op2d, op2i) \
(_s32P((long)(is)) \
? jit_qop_small ((d), (s1), (op2d)) \
: (MOVQir ((is), JIT_REXTMP), jit_qop_small ((d), (s1), (op2i))))
#define jit_bra_qr(s1, s2, op) (CMPQrr(s2, s1), op, _jit.x.pc)
#define _jit_bra_l(rs, is, op) (CMPQir(is, rs), op, _jit.x.pc)
#define jit_bra_l(rs, is, op) (_s32P((long)(is)) \
? _jit_bra_l(rs, is, op) \
: (MOVQir(is, JIT_REXTMP), jit_bra_qr(rs, JIT_REXTMP, op)))
/* When CMP with 0 can be replaced with TEST */
#define jit_bra_l0(rs, is, op, op0) \
( (is) == 0 ? (TESTQrr(rs, rs), op0, _jit.x.pc) : jit_bra_l(rs, is, op))
#define jit_reduceQ(op, is, rs) \
(_u8P(is) ? jit_reduce_(op##Bir(is, jit_reg8(rs))) : \
jit_reduce_(op##Qir(is, rs)) )
#define jit_addi_l(d, rs, is) \
/* Value is not zero? */ \
((is) \
/* Yes. Value is unsigned and fits in signed 32 bits? */ \
? (_uiP(31, is) \
/* Yes. d == rs? */ \
? jit_opi_((d), (rs), \
/* Yes. Use add opcode */ \
ADDQir((is), (d)), \
/* No. Use lea opcode */ \
LEAQmr((is), (rs), 0, 0, (d))) \
/* No. Need value in a register */ \
: (jit_movi_l(JIT_REXTMP, is), \
jit_addr_l(d, rs, JIT_REXTMP))) \
/* No. Do nothing. */ \
: 0)
#define jit_addr_l(d, s1, s2) jit_opo_((d), (s1), (s2), ADDQrr((s2), (d)), ADDQrr((s1), (d)), LEAQmr(0, (s1), (s2), 1, (d)) )
#define jit_addci_l(d, rs, is) jit_qop_ ((d), (rs), (is), ADCQir((is), (d)), ADCQrr(JIT_REXTMP, (d)))
#define jit_addcr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ADCQrr((s1), (d)), ADCQrr((s2), (d)) )
#define jit_addxi_l(d, rs, is) jit_qop_ ((d), (rs), (is), ADDQir((is), (d)), ADDQrr(JIT_REXTMP, (d)))
#define jit_addxr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ADDQrr((s1), (d)), ADDQrr((s2), (d)) )
#define jit_andi_l(d, rs, is) jit_qop_ ((d), (rs), (is), ANDQir((is), (d)), ANDQrr(JIT_REXTMP, (d)))
#define jit_andr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ANDQrr((s1), (d)), ANDQrr((s2), (d)) )
#define jit_orr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), ORQrr((s1), (d)), ORQrr((s2), (d)) )
#define jit_subr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), (SUBQrr((s1), (d)), NEGQr(d)), SUBQrr((s2), (d)) )
#define jit_xorr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), XORQrr((s1), (d)), XORQrr((s2), (d)) )
/* These can sometimes use byte or word versions! */
#define jit_ori_l(d, rs, is) jit_qop_ ((d), (rs), (is), jit_reduceQ(OR, (is), (d)), ORQrr(JIT_REXTMP, (d)) )
#define jit_xori_l(d, rs, is) jit_qop_ ((d), (rs), (is), jit_reduceQ(XOR, (is), (d)), XORQrr(JIT_REXTMP, (d)) )
#define jit_lshi_l(d, rs, is) ((is) <= 3 ? LEAQmr(0, 0, (rs), 1 << (is), (d)) : jit_qop_small ((d), (rs), SHLQir((is), (d)) ))
#define jit_rshi_l(d, rs, is) jit_qop_small ((d), (rs), SARQir((is), (d)) )
#define jit_rshi_ul(d, rs, is) jit_qop_small ((d), (rs), SHRQir((is), (d)) )
#define jit_lshr_l(d, r1, r2) jit_shift((d), (r1), (r2), SHLQrr)
#define jit_rshr_l(d, r1, r2) jit_shift((d), (r1), (r2), SARQrr)
#define jit_rshr_ul(d, r1, r2) jit_shift((d), (r1), (r2), SHRQrr)
/* Stack */
#define jit_pushr_i(rs) PUSHQr(rs)
#define jit_popr_i(rs) POPQr(rs)
/* A return address is 8 bytes, plus 5 registers = 40 bytes, total = 48 bytes. */
#define jit_prolog(n) (_jitl.framesize = ((n) & 1) ? 56 : 48, _jitl.nextarg_getfp = _jitl.nextarg_geti = 0, _jitl.alloca_offset = 0, \
PUSHQr(_EBX), PUSHQr(_R12), PUSHQr(_R13), PUSHQr(_R14), PUSHQr(_EBP), MOVQrr(_ESP, _EBP))
#define jit_calli(sub) (MOVQir((long) (sub), JIT_REXTMP), CALLsr(JIT_REXTMP))
#define jit_callr(reg) CALLsr((reg))
#define jit_prepare_i(ni) (_jitl.nextarg_puti = (ni), \
_jitl.argssize = _jitl.nextarg_puti > JIT_ARG_MAX \
? _jitl.nextarg_puti - JIT_ARG_MAX : 0)
#define jit_pusharg_i(rs) (--_jitl.nextarg_puti >= JIT_ARG_MAX \
? PUSHQr(rs) : MOVQrr(rs, jit_arg_reg_order[_jitl.nextarg_puti]))
#define jit_finish(sub) (_jitl.fprssize \
? (MOVBir(_jitl.fprssize, _AL), _jitl.fprssize = 0) \
: MOVBir(0, _AL), \
((_jitl.argssize & 1) \
? (PUSHQr(_EAX), ++_jitl.argssize) : 0), \
_jitl.finish_ref = jit_calli(sub), \
(_jitl.argssize \
? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \
: 0), \
_jitl.finish_ref)
#define jit_reg_is_arg(reg) ((reg) == _ECX || (reg) == _EDX)
#define jit_finishr(reg) (_jitl.fprssize \
? (MOVBir(_jitl.fprssize, _AL), _jitl.fprssize = 0) \
: MOVBir(0, _AL), \
((_jitl.argssize & 1) \
? (PUSHQr(_EAX), ++_jitl.argssize) : 0), \
(jit_reg_is_arg((reg)) \
? (MOVQrr(reg, JIT_REXTMP), \
jit_callr(JIT_REXTMP)) \
: jit_callr(reg)), \
(_jitl.argssize \
? (ADDQir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) \
: 0))
#define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX))
#define jit_arg_i() (_jitl.nextarg_geti < JIT_ARG_MAX \
? _jitl.nextarg_geti++ \
: ((_jitl.framesize += sizeof(long)) - sizeof(long)))
#define jit_arg_c() jit_arg_i()
#define jit_arg_uc() jit_arg_i()
#define jit_arg_s() jit_arg_i()
#define jit_arg_us() jit_arg_i()
#define jit_arg_ui() jit_arg_i()
#define jit_arg_l() jit_arg_i()
#define jit_arg_ul() jit_arg_i()
#define jit_arg_p() jit_arg_i()
#define jit_getarg_c(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_c_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_c((reg), JIT_FP, (ofs)))
#define jit_getarg_uc(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_uc_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_uc((reg), JIT_FP, (ofs)))
#define jit_getarg_s(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_s_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_s((reg), JIT_FP, (ofs)))
#define jit_getarg_us(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_extr_us_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_us((reg), JIT_FP, (ofs)))
#define jit_getarg_i(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_i((reg), JIT_FP, (ofs)))
#define jit_getarg_ui(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_ui((reg), JIT_FP, (ofs)))
#define jit_getarg_l(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_l((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_l((reg), JIT_FP, (ofs)))
#define jit_getarg_ul(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_ul((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_ul((reg), JIT_FP, ofs))
#define jit_getarg_p(reg, ofs) ((ofs) < JIT_ARG_MAX \
? jit_movr_p((reg), jit_arg_reg_order[(ofs)]) \
: jit_ldxi_p((reg), JIT_FP, (ofs)))
static int jit_arg_reg_order[] = { _EDI, _ESI, _EDX, _ECX, _R8D, _R9D };
#define jit_negr_l(d, rs) jit_opi_((d), (rs), NEGQr(d), (XORQrr((d), (d)), SUBQrr((rs), (d))) )
#define jit_movr_l(d, rs) ((void)((rs) == (d) ? 0 : MOVQrr((rs), (d))))
#define jit_movi_p(d, is) (MOVQir(((long)(is)), (d)), _jit.x.pc)
#define jit_movi_l(d, is) \
/* Value is not zero? */ \
((is) \
/* Yes. Value is unsigned and fits in signed 32 bits? */ \
? (_uiP(31, is) \
/* Yes. Use 32 bits opcode */ \
? MOVLir(is, (d)) \
/* No. Use 64 bits opcode */ \
: MOVQir(is, (d))) \
/* No. Set register to zero. */ \
: XORQrr ((d), (d)))
#define jit_bmsr_l(label, s1, s2) (TESTQrr((s1), (s2)), JNZm(label), _jit.x.pc)
#define jit_bmcr_l(label, s1, s2) (TESTQrr((s1), (s2)), JZm(label), _jit.x.pc)
#define jit_boaddr_l(label, s1, s2) (ADDQrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_bosubr_l(label, s1, s2) (SUBQrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_boaddr_ul(label, s1, s2) (ADDQrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_bosubr_ul(label, s1, s2) (SUBQrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_boaddi_l(label, rs, is) (ADDQir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_bosubi_l(label, rs, is) (SUBQir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_boaddi_ul(label, rs, is) (ADDQir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bosubi_ul(label, rs, is) (SUBQir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_patch_long_at(jump_pc,v) (*_PSL((jump_pc) - sizeof(long)) = _jit_SL((jit_insn *)(v)))
#define jit_patch_short_at(jump_pc,v) (*_PSI((jump_pc) - sizeof(int)) = _jit_SI((jit_insn *)(v) - (jump_pc)))
#define jit_patch_at(jump_pc,v) (_jitl.long_jumps ? jit_patch_long_at((jump_pc)-3, v) : jit_patch_short_at(jump_pc, v))
#define jit_ret() (LEAVE_(), POPQr(_R14), POPQr(_R13), POPQr(_R12), POPQr(_EBX), RET_())
/* Memory */
/* Used to implement ldc, stc, ... We have SIL and friends which simplify it all. */
#define jit_movbrm(rs, dd, db, di, ds) MOVBrm(jit_reg8(rs), dd, db, di, ds)
#define jit_ldr_c(d, rs) MOVSBQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_c(d, s1, s2) MOVSBQmr(0, (s1), (s2), 1, (d))
#define jit_ldr_s(d, rs) MOVSWQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_s(d, s1, s2) MOVSWQmr(0, (s1), (s2), 1, (d))
#define jit_ldi_c(d, is) (_u32P((long)(is)) ? MOVSBQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_c(d, JIT_REXTMP)))
#define jit_ldxi_c(d, rs, is) (_u32P((long)(is)) ? MOVSBQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_c(d, rs, JIT_REXTMP)))
#define jit_ldi_uc(d, is) (_u32P((long)(is)) ? MOVZBLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_uc(d, JIT_REXTMP)))
#define jit_ldxi_uc(d, rs, is) (_u32P((long)(is)) ? MOVZBLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_uc(d, rs, JIT_REXTMP)))
#define jit_sti_c(id, rs) (_u32P((long)(id)) ? MOVBrm(jit_reg8(rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_c(JIT_REXTMP, rs)))
#define jit_stxi_c(id, rd, rs) (_u32P((long)(id)) ? MOVBrm(jit_reg8(rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_c(JIT_REXTMP, rd, rs)))
#define jit_ldi_s(d, is) (_u32P((long)(is)) ? MOVSWQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_s(d, JIT_REXTMP)))
#define jit_ldxi_s(d, rs, is) (_u32P((long)(is)) ? MOVSWQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_s(d, rs, JIT_REXTMP)))
#define jit_ldi_us(d, is) (_u32P((long)(is)) ? MOVZWLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_us(d, JIT_REXTMP)))
#define jit_ldxi_us(d, rs, is) (_u32P((long)(is)) ? MOVZWLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_us(d, rs, JIT_REXTMP)))
#define jit_sti_s(id, rs) (_u32P((long)(id)) ? MOVWrm(jit_reg16(rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_s(JIT_REXTMP, rs)))
#define jit_stxi_s(id, rd, rs) (_u32P((long)(id)) ? MOVWrm(jit_reg16(rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_s(JIT_REXTMP, rd, rs)))
#define jit_ldi_ui(d, is) (_u32P((long)(is)) ? MOVLmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_ui(d, JIT_REXTMP)))
#define jit_ldxi_ui(d, rs, is) (_u32P((long)(is)) ? MOVLmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_ui(d, rs, JIT_REXTMP)))
#define jit_ldi_i(d, is) (_u32P((long)(is)) ? MOVSLQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_i(d, JIT_REXTMP)))
#define jit_ldxi_i(d, rs, is) (_u32P((long)(is)) ? MOVSLQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_i(d, rs, JIT_REXTMP)))
#define jit_sti_i(id, rs) (_u32P((long)(id)) ? MOVLrm((rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_i(JIT_REXTMP, rs)))
#define jit_stxi_i(id, rd, rs) (_u32P((long)(id)) ? MOVLrm((rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_i(JIT_REXTMP, rd, rs)))
#define jit_ldi_l(d, is) (_u32P((long)(is)) ? MOVQmr((is), 0, 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldr_l(d, JIT_REXTMP)))
#define jit_ldxi_l(d, rs, is) (_u32P((long)(is)) ? MOVQmr((is), (rs), 0, 0, (d)) : (jit_movi_l(JIT_REXTMP, is), jit_ldxr_l(d, rs, JIT_REXTMP)))
#define jit_sti_l(id, rs) (_u32P((long)(id)) ? MOVQrm((rs), (id), 0, 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_str_l(JIT_REXTMP, rs)))
#define jit_stxi_l(id, rd, rs) (_u32P((long)(id)) ? MOVQrm((rs), (id), (rd), 0, 0) : (jit_movi_l(JIT_REXTMP, id), jit_stxr_l(JIT_REXTMP, rd, rs)))
#define jit_ldr_ui(d, rs) MOVLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_ui(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
#define jit_ldr_i(d, rs) MOVSLQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_i(d, s1, s2) MOVSLQmr(0, (s1), (s2), 1, (d))
#define jit_ldr_l(d, rs) MOVQmr(0, (rs), 0, 0, (d))
#define jit_ldxr_l(d, s1, s2) MOVQmr(0, (s1), (s2), 1, (d))
#define jit_str_l(rd, rs) MOVQrm((rs), 0, (rd), 0, 0)
#define jit_stxr_l(d1, d2, rs) MOVQrm((rs), 0, (d1), (d2), 1)
#define jit_blti_l(label, rs, is) jit_bra_l0((rs), (is), JLm(label), JSm(label) )
#define jit_blei_l(label, rs, is) jit_bra_l ((rs), (is), JLEm(label) )
#define jit_bgti_l(label, rs, is) jit_bra_l ((rs), (is), JGm(label) )
#define jit_bgei_l(label, rs, is) jit_bra_l0((rs), (is), JGEm(label), JNSm(label) )
#define jit_beqi_l(label, rs, is) jit_bra_l0((rs), (is), JEm(label), JEm(label) )
#define jit_bnei_l(label, rs, is) jit_bra_l0((rs), (is), JNEm(label), JNEm(label) )
#define jit_blti_ul(label, rs, is) jit_bra_l ((rs), (is), JBm(label) )
#define jit_blei_ul(label, rs, is) jit_bra_l0((rs), (is), JBEm(label), JEm(label) )
#define jit_bgti_ul(label, rs, is) jit_bra_l0((rs), (is), JAm(label), JNEm(label) )
#define jit_bgei_ul(label, rs, is) jit_bra_l ((rs), (is), JAEm(label) )
#define jit_bmsi_l(label, rs, is) (jit_reduceQ(TEST, (is), (rs)), JNZm(label), _jit.x.pc)
#define jit_bmci_l(label, rs, is) (jit_reduceQ(TEST, (is), (rs)), JZm(label), _jit.x.pc)
#define jit_pushr_l(rs) jit_pushr_i(rs)
#define jit_popr_l(rs) jit_popr_i(rs)
#define jit_pusharg_l(rs) jit_pusharg_i(rs)
#define jit_retval_l(rd) ((void)jit_movr_l ((rd), _EAX))
#define jit_bltr_l(label, s1, s2) jit_bra_qr((s1), (s2), JLm(label) )
#define jit_bler_l(label, s1, s2) jit_bra_qr((s1), (s2), JLEm(label) )
#define jit_bgtr_l(label, s1, s2) jit_bra_qr((s1), (s2), JGm(label) )
#define jit_bger_l(label, s1, s2) jit_bra_qr((s1), (s2), JGEm(label) )
#define jit_beqr_l(label, s1, s2) jit_bra_qr((s1), (s2), JEm(label) )
#define jit_bner_l(label, s1, s2) jit_bra_qr((s1), (s2), JNEm(label) )
#define jit_bltr_ul(label, s1, s2) jit_bra_qr((s1), (s2), JBm(label) )
#define jit_bler_ul(label, s1, s2) jit_bra_qr((s1), (s2), JBEm(label) )
#define jit_bgtr_ul(label, s1, s2) jit_bra_qr((s1), (s2), JAm(label) )
#define jit_bger_ul(label, s1, s2) jit_bra_qr((s1), (s2), JAEm(label) )
/* Bool operations. */
#define jit_bool_qr(d, s1, s2, op) \
(jit_replace8(d, CMPQrr(s2, s1), op))
#define jit_bool_qi(d, rs, is, op) \
(jit_replace8(d, CMPQir(is, rs), op))
/* When CMP with 0 can be replaced with TEST */
#define jit_bool_qi0(d, rs, is, op, op0) \
((is) != 0 \
? (jit_replace8(d, CMPQir(is, rs), op)) \
: (jit_replace8(d, TESTQrr(rs, rs), op0)))
#define jit_ltr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETLr )
#define jit_ler_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETLEr )
#define jit_gtr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETGr )
#define jit_ger_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETGEr )
#define jit_eqr_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETEr )
#define jit_ner_l(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETNEr )
#define jit_ltr_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETBr )
#define jit_ler_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETBEr )
#define jit_gtr_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETAr )
#define jit_ger_ul(d, s1, s2) jit_bool_qr((d), (s1), (s2), SETAEr )
#define jit_lti_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETLr, SETSr )
#define jit_lei_l(d, rs, is) jit_bool_qi ((d), (rs), (is), SETLEr )
#define jit_gti_l(d, rs, is) jit_bool_qi ((d), (rs), (is), SETGr )
#define jit_gei_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETGEr, SETNSr )
#define jit_eqi_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETEr, SETEr )
#define jit_nei_l(d, rs, is) jit_bool_qi0((d), (rs), (is), SETNEr, SETNEr )
#define jit_lti_ul(d, rs, is) jit_bool_qi ((d), (rs), (is), SETBr )
#define jit_lei_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETBEr, SETEr )
#define jit_gti_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETAr, SETNEr )
#define jit_gei_ul(d, rs, is) jit_bool_qi0((d), (rs), (is), SETAEr, INCLr )
/* Multiplication/division. */
#define jit_mulr_ul_(s1, s2) \
jit_qopr_(_RAX, s1, s2, MULQr(s1), MULQr(s2))
#define jit_mulr_l_(s1, s2) \
jit_qopr_(_RAX, s1, s2, IMULQr(s1), IMULQr(s2))
#define jit_muli_l_(is, rs) \
(MOVQir(is, rs == _RAX ? _RDX : _RAX), \
IMULQr(rs == _RAX ? _RDX : rs))
#define jit_muli_ul_(is, rs) \
(MOVQir(is, rs == _RAX ? _RDX : _RAX), \
IMULQr(rs == _RAX ? _RDX : rs))
#define jit_divi_l_(result, d, rs, is) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
jit_might (rs, _RAX, MOVQrr(rs, _RAX)), \
jit_might (rs, _RDX, MOVQrr(rs, _RDX)), \
MOVQir(is, _RCX), \
SARQir(63, _RDX), \
IDIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divr_l_(result, d, s1, s2) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
((s1 == _RCX) ? jit_pushr_l(_RCX) : 0), \
jit_might (s2, _RCX, MOVQrr(s2, _RCX)), \
((s1 == _RCX) ? jit_popr_l(_RDX) : \
jit_might (s1, _RDX, MOVQrr(s1, _RDX))), \
MOVQrr(_RDX, _RAX), \
SARQir(63, _RDX), \
IDIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divi_ul_(result, d, rs, is) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
jit_might (rs, _RAX, MOVQrr(rs, _RAX)), \
MOVQir(is, _RCX), \
XORQrr(_RDX, _RDX), \
DIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_divr_ul_(result, d, s1, s2) \
(jit_might (d, _RAX, jit_pushr_l(_RAX)), \
jit_might (d, _RCX, jit_pushr_l(_RCX)), \
jit_might (d, _RDX, jit_pushr_l(_RDX)), \
((s1 == _RCX) ? jit_pushr_l(_RCX) : 0), \
jit_might (s2, _RCX, MOVQrr(s2, _RCX)), \
((s1 == _RCX) ? jit_popr_l(_RAX) : \
jit_might (s1, _RAX, MOVQrr(s1, _RAX))), \
XORQrr(_RDX, _RDX), \
DIVQr(_RCX), \
jit_might(d, result, MOVQrr(result, d)), \
jit_might(d, _RDX, jit_popr_l(_RDX)), \
jit_might(d, _RCX, jit_popr_l(_RCX)), \
jit_might(d, _RAX, jit_popr_l(_RAX)))
#define jit_muli_l(d, rs, is) jit_qop_ ((d), (rs), (is), IMULQir((is), (d)), IMULQrr(JIT_REXTMP, (d)) )
#define jit_mulr_l(d, s1, s2) jit_qopr_((d), (s1), (s2), IMULQrr((s1), (d)), IMULQrr((s2), (d)) )
/* As far as low bits are concerned, signed and unsigned multiplies are
exactly the same. */
#define jit_muli_ul(d, rs, is) jit_qop_ ((d), (rs), (is), IMULQir((is), (d)), IMULQrr(JIT_REXTMP, (d)) )
#define jit_mulr_ul(d, s1, s2) jit_qopr_((d), (s1), (s2), IMULQrr((s1), (d)), IMULQrr((s2), (d)) )
#define jit_hmuli_l(d, rs, is) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_muli_l_((is), (rs)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_muli_l_((is), (rs)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_muli_l_((is), (rs)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmulr_l(d, s1, s2) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_mulr_l_((s1), (s2)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_mulr_l_((s1), (s2)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_mulr_l_((s1), (s2)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmuli_ul(d, rs, is) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_muli_ul_((is), (rs)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_muli_ul_((is), (rs)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_muli_ul_((is), (rs)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_hmulr_ul(d, s1, s2) \
((d) == _RDX ? ( jit_pushr_l(_RAX), jit_mulr_ul_((s1), (s2)), jit_popr_l(_RAX) ) : \
((d) == _RAX ? (jit_pushr_l(_RDX), jit_mulr_ul_((s1), (s2)), MOVQrr(_RDX, _RAX), jit_popr_l(_RDX) ) : \
(jit_pushr_l(_RDX), jit_pushr_l(_RAX), jit_mulr_ul_((s1), (s2)), MOVQrr(_RDX, (d)), jit_popr_l(_RAX), jit_popr_l(_RDX) )))
#define jit_divi_l(d, rs, is) jit_divi_l_(_RAX, (d), (rs), (is))
#define jit_divi_ul(d, rs, is) jit_divi_ul_(_RAX, (d), (rs), (is))
#define jit_modi_l(d, rs, is) jit_divi_l_(_RDX, (d), (rs), (is))
#define jit_modi_ul(d, rs, is) jit_divi_ul_(_RDX, (d), (rs), (is))
#define jit_divr_l(d, s1, s2) jit_divr_l_(_RAX, (d), (s1), (s2))
#define jit_divr_ul(d, s1, s2) jit_divr_ul_(_RAX, (d), (s1), (s2))
#define jit_modr_l(d, s1, s2) jit_divr_l_(_RDX, (d), (s1), (s2))
#define jit_modr_ul(d, s1, s2) jit_divr_ul_(_RDX, (d), (s1), (s2))
#endif /* __lightning_core_h */

View File

@@ -7,21 +7,21 @@
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
* Copyright 2000, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Matthew Flatt.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
@@ -31,22 +31,13 @@
#ifndef __lightning_core_h
#define __lightning_core_h
#ifndef __lightning_core_i386_h
#define __lightning_core_i386_h
#define JIT_FP _EBP
#define JIT_SP _ESP
#define JIT_RET _EAX
#define JIT_R_NUM 3
#define JIT_V_NUM 3
#define JIT_R(i) (_EAX + (i))
#define JIT_V(i) ((i) == 0 ? _EBX : _ESI + (i) - 1)
struct jit_local_state {
int framesize;
int argssize;
};
/* 3-parameter operation */
#define jit_opr_(d, s1, s2, op1d, op2d) \
@@ -56,7 +47,7 @@ struct jit_local_state {
/* 3-parameter operation, with immediate */
#define jit_op_(d, s1, op2d) \
((s1 == d) ? op2d : (MOVLrr(s1, d), op2d)) \
((s1 == d) ? op2d : (MOVLrr(s1, d), op2d))
/* 3-parameter operation, optimizable */
#define jit_opo_(d, s1, s2, op1d, op2d, op12d) \
@@ -67,28 +58,27 @@ struct jit_local_state {
#define jit_opi_(d, rs, opdi, opdri) \
((rs == d) ? opdi : opdri)
/* An operand is forced into a register */
#define jit_replace(rd, rs, forced, op) \
((rd == forced) ? JITSORRY("Register conflict for " # op) : \
(rs == forced) ? op : (PUSHLr(forced), MOVLrr(rs, forced), op, POPLr(forced)))
/* For LT, LE, ... */
#define jit_replace8(d, op) \
(jit_check8(d) \
? (MOVLir(0, d), op(d)) \
: (PUSHLr(_EAX), MOVLir(0, _EAX), op(_EAX), MOVLrr(_EAX, (d)), POPLr(_EAX)))
#define jit_replace8(d, cmp, op) \
(jit_check8(d) \
? ((cmp), \
MOVLir(0, (d)), \
op(_rR(d) | _AL)) \
: (jit_pushr_i(_EAX), (cmp), \
MOVLir(0, _EAX), \
op(_AL), MOVLrr(_EAX, (d)), jit_popr_i(_EAX)))
#define jit_bool_r(d, s1, s2, op) \
(CMPLrr(s2, s1), jit_replace8(d, op))
(jit_replace8(d, CMPLrr(s2, s1), op))
#define jit_bool_i(d, rs, is, op) \
(CMPLir(is, rs), jit_replace8(d, op))
(jit_replace8(d, CMPLir(is, rs), op))
/* When CMP with 0 can be replaced with TEST */
#define jit_bool_i0(d, rs, is, op, op0) \
((is) != 0 \
? (CMPLir(is, rs), jit_replace8(d, op)) \
: (TESTLrr(rs, rs), jit_replace8(d, op0)))
? (jit_replace8(d, CMPLir(is, rs), op)) \
: (jit_replace8(d, TESTLrr(rs, rs), op0)))
/* For BLT, BLE, ... */
#define jit_bra_r(s1, s2, op) (CMPLrr(s2, s1), op, _jit.x.pc)
@@ -98,22 +88,11 @@ struct jit_local_state {
#define jit_bra_i0(rs, is, op, op0) \
( (is) == 0 ? (TESTLrr(rs, rs), op0, _jit.x.pc) : (CMPLir(is, rs), op, _jit.x.pc))
/* Used to implement ldc, stc, ... */
#define jit_check8(rs) ( (rs) <= _EBX )
#define jit_reg8(rs) ( ((rs) == _SI || (rs) == _DI) ? _AL : ((rs) & _BH) | _AL )
#define jit_reg16(rs) ( ((rs) & _BH) | _AX )
/* In jit_replace below, _EBX is dummy */
#define jit_movbrm(rs, dd, db, di, ds) \
(jit_check8(rs) \
? MOVBrm(jit_reg8(rs), dd, db, di, ds) \
: jit_replace(_EBX, rs, _EAX, MOVBrm(_AL, dd, db, di, ds)))
/* Reduce arguments of XOR/OR/TEST */
#define jit_reduce_(op) op
#define jit_reduce(op, is, rs) \
(_u8P(is) && jit_check8(rs) ? jit_reduce_(op##Bir(is, jit_reg8(rs))) : \
(_u16P(is) ? jit_reduce_(op##Wir(is, jit_reg16(rs))) : \
(_u16P(is) && JIT_CAN_16 ? jit_reduce_(op##Wir(is, jit_reg16(rs))) : \
jit_reduce_(op##Lir(is, rs)) ))
/* Helper macros for MUL/DIV/IDIV */
@@ -133,62 +112,62 @@ struct jit_local_state {
IMULLr(rs == _EAX ? _EDX : rs))
#define jit_divi_i_(result, d, rs, is) \
(jit_might (d, _EAX, PUSHLr(_EAX)), \
jit_might (d, _ECX, PUSHLr(_ECX)), \
jit_might (d, _EDX, PUSHLr(_EDX)), \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
jit_might (rs, _EDX, MOVLrr(rs, _EDX)), \
MOVLir(is, _ECX), \
SARLir(31, _EDX), \
IDIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, POPLr(_EDX)), \
jit_might(d, _ECX, POPLr(_ECX)), \
jit_might(d, _EAX, POPLr(_EAX)))
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divr_i_(result, d, s1, s2) \
(jit_might (d, _EAX, PUSHLr(_EAX)), \
jit_might (d, _ECX, PUSHLr(_ECX)), \
jit_might (d, _EDX, PUSHLr(_EDX)), \
((s1 == _ECX) ? PUSHLr(_ECX) : 0), \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
((s1 == _ECX) ? jit_pushr_i(_ECX) : 0), \
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
((s1 == _ECX) ? POPLr(_EDX) : \
((s1 == _ECX) ? jit_popr_i(_EDX) : \
jit_might (s1, _EDX, MOVLrr(s1, _EDX))), \
MOVLrr(_EDX, _EAX), \
SARLir(31, _EDX), \
IDIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, POPLr(_EDX)), \
jit_might(d, _ECX, POPLr(_ECX)), \
jit_might(d, _EAX, POPLr(_EAX)))
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divi_ui_(result, d, rs, is) \
(jit_might (d, _EAX, PUSHLr(_EAX)), \
jit_might (d, _ECX, PUSHLr(_ECX)), \
jit_might (d, _EDX, PUSHLr(_EDX)), \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
jit_might (rs, _EAX, MOVLrr(rs, _EAX)), \
MOVLir(is, _ECX), \
XORLrr(_EDX, _EDX), \
DIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, POPLr(_EDX)), \
jit_might(d, _ECX, POPLr(_ECX)), \
jit_might(d, _EAX, POPLr(_EAX)))
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
#define jit_divr_ui_(result, d, s1, s2) \
(jit_might (d, _EAX, PUSHLr(_EAX)), \
jit_might (d, _ECX, PUSHLr(_ECX)), \
jit_might (d, _EDX, PUSHLr(_EDX)), \
((s1 == _ECX) ? PUSHLr(_ECX) : 0), \
(jit_might (d, _EAX, jit_pushr_i(_EAX)), \
jit_might (d, _ECX, jit_pushr_i(_ECX)), \
jit_might (d, _EDX, jit_pushr_i(_EDX)), \
((s1 == _ECX) ? jit_pushr_i(_ECX) : 0), \
jit_might (s2, _ECX, MOVLrr(s2, _ECX)), \
((s1 == _ECX) ? POPLr(_EAX) : \
((s1 == _ECX) ? jit_popr_i(_EAX) : \
jit_might (s1, _EAX, MOVLrr(s1, _EAX))), \
XORLrr(_EDX, _EDX), \
DIVLr(_ECX), \
jit_might(d, result, MOVLrr(result, d)), \
jit_might(d, _EDX, POPLr(_EDX)), \
jit_might(d, _ECX, POPLr(_ECX)), \
jit_might(d, _EAX, POPLr(_EAX)))
jit_might(d, _EDX, jit_popr_i(_EDX)), \
jit_might(d, _ECX, jit_popr_i(_ECX)), \
jit_might(d, _EAX, jit_popr_i(_EAX)))
/* ALU */
@@ -207,6 +186,7 @@ struct jit_local_state {
#define jit_subxi_i(d, rs, is) jit_op_ ((d), (rs), SBBLir((is), (d)) )
#define jit_xorr_i(d, s1, s2) jit_opr_((d), (s1), (s2), XORLrr((s1), (d)), XORLrr((s2), (d)) )
/* These can sometimes use byte or word versions! */
#define jit_ori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(OR, (is), (d)) )
#define jit_xori_i(d, rs, is) jit_op_ ((d), (rs), jit_reduce(XOR, (is), (d)) )
@@ -220,24 +200,24 @@ struct jit_local_state {
#define jit_mulr_ui(d, s1, s2) jit_opr_((d), (s1), (s2), IMULLrr((s1), (d)), IMULLrr((s2), (d)) )
#define jit_hmuli_i(d, rs, is) \
((d) == _EDX ? ( PUSHLr(_EAX), jit_muli_i_((is), (rs)), POPLr(_EAX) ) : \
((d) == _EAX ? (PUSHLr(_EDX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
(PUSHLr(_EDX), PUSHLr(_EAX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_muli_i_((is), (rs)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_muli_i_((is), (rs)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmulr_i(d, s1, s2) \
((d) == _EDX ? ( PUSHLr(_EAX), jit_mulr_i_((s1), (s2)), POPLr(_EAX) ) : \
((d) == _EAX ? (PUSHLr(_EDX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
(PUSHLr(_EDX), PUSHLr(_EAX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_mulr_i_((s1), (s2)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_mulr_i_((s1), (s2)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmuli_ui(d, rs, is) \
((d) == _EDX ? ( PUSHLr(_EAX), jit_muli_ui_((is), (rs)), POPLr(_EAX) ) : \
((d) == _EAX ? (PUSHLr(_EDX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
(PUSHLr(_EDX), PUSHLr(_EAX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_muli_ui_((is), (rs)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_muli_ui_((is), (rs)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_hmulr_ui(d, s1, s2) \
((d) == _EDX ? ( PUSHLr(_EAX), jit_mulr_ui_((s1), (s2)), POPLr(_EAX) ) : \
((d) == _EAX ? (PUSHLr(_EDX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, _EAX), POPLr(_EDX) ) : \
(PUSHLr(_EDX), PUSHLr(_EAX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, (d)), POPLr(_EAX), POPLr(_EDX) )))
((d) == _EDX ? ( jit_pushr_i(_EAX), jit_mulr_ui_((s1), (s2)), jit_popr_i(_EAX) ) : \
((d) == _EAX ? (jit_pushr_i(_EDX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, _EAX), jit_popr_i(_EDX) ) : \
(jit_pushr_i(_EDX), jit_pushr_i(_EAX), jit_mulr_ui_((s1), (s2)), MOVLrr(_EDX, (d)), jit_popr_i(_EAX), jit_popr_i(_EDX) )))
#define jit_divi_i(d, rs, is) jit_divi_i_(_EAX, (d), (rs), (is))
#define jit_divi_ui(d, rs, is) jit_divi_ui_(_EAX, (d), (rs), (is))
@@ -250,49 +230,42 @@ struct jit_local_state {
/* Shifts */
#define jit_shift(d, s1, s2, m) \
((d) == _ECX || (d) == (s2) \
? ((s2) == _EAX \
? jit_fixd(d, _EDX, jit_shift2(_EDX, s1, s2, m)) \
: jit_fixd(d, _EAX, jit_shift2(_EAX, s1, s2, m))) \
: jit_shift2(d, s1, s2, m))
/* Shift operation, assuming d != s2 or ECX */
#define jit_shift2(d, s1, s2, m) \
jit_op_(d, s1, jit_cfixs(s2, _ECX, m(_CL, d)))
/* Substitute x for destination register d */
#define jit_fixd(d, x, op) \
(jit_pushr_i(x), op, jit_movr_i(d, x), jit_popr_i(x))
/* Conditionally substitute y for source register s */
#define jit_cfixs(s, y, op) \
((s) == (y) ? op : \
(jit_pushr_i(y), jit_movr_i(y, s), op, jit_popr_i(y)))
#define jit_lshi_i(d, rs, is) ((is) <= 3 ? LEALmr(0, 0, (rs), 1 << (is), (d)) : jit_op_ ((d), (rs), SHLLir((is), (d)) ))
#define jit_rshi_i(d, rs, is) jit_op_ ((d), (rs), SARLir((is), (d)) )
#define jit_rshi_ui(d, rs, is) jit_op_ ((d), (rs), SHRLir((is), (d)) )
#define jit_lshr_i(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SHLLrr(_CL, (d)) ))
#define jit_rshr_i(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SARLrr(_CL, (d)) ))
#define jit_rshr_ui(d, r1, r2) jit_replace((r1), (r2), _ECX, jit_op_ ((d), (r1), SHRLrr(_CL, (d)) ))
#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)
/* Stack */
#define jit_pushr_i(rs) PUSHLr(rs)
#define jit_popr_i(rs) POPLr(rs)
#define jit_prolog(n) (_jitl.framesize = 8, PUSHLr(_EBP), MOVLrr(_ESP, _EBP), PUSHLr(_EBX), PUSHLr(_ESI), PUSHLr(_EDI))
/* The += allows for stack pollution */
#define jit_prepare_i(ni) (_jitl.argssize += (ni))
#define jit_prepare_f(nf) (_jitl.argssize += (nf))
#define jit_prepare_d(nd) (_jitl.argssize += 2 * (nd))
#define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (jit_calli((sub)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_finishr(reg) (jit_callr((reg)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_retval_i(rd) jit_movr_i ((rd), _EAX)
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_s() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_us() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_i() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_ui() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_l() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_ul() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_p() ((_jitl.framesize += sizeof(long)) - sizeof(long))
#define jit_arg_f() ((_jitl.framesize += sizeof(float)) - sizeof(float))
#define jit_arg_d() ((_jitl.framesize += sizeof(double)) - sizeof(double))
#define jit_retval_i(rd) ((void)jit_movr_i ((rd), _EAX))
/* Unary */
#define jit_negr_i(d, rs) jit_opi_((d), (rs), NEGLr(d), (XORLrr((d), (d)), SUBLrr((rs), (d))) )
#define jit_negr_l(d, rs) jit_opi_((d), (rs), NEGLr(d), (XORLrr((d), (d)), SUBLrr((rs), (d))) )
#define jit_movr_i(d, rs) ((rs) == (d) ? 0 : MOVLrr((rs), (d)))
#define jit_movr_i(d, rs) ((void)((rs) == (d) ? 0 : MOVLrr((rs), (d))))
#define jit_movi_i(d, is) ((is) ? MOVLir((is), (d)) : XORLrr ((d), (d)) )
#define jit_movi_p(d, is) (MOVLir((is), (d)), _jit.x.pc)
#define jit_patch_movi(pa,pv) (*_PSL((pa) - 4) = _jit_SL((pv)))
#define jit_patch_movi(pa,pv) (*_PSL((pa) - sizeof(long)) = _jit_SL((pv)))
#define jit_ntoh_ui(d, rs) jit_op_((d), (rs), BSWAPLr(d))
#define jit_ntoh_us(d, rs) jit_op_((d), (rs), RORWir(8, d))
@@ -321,93 +294,73 @@ struct jit_local_state {
#define jit_gei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAEr, INCLr )
/* Jump */
#define jit_bltr_i(label, s1, s2) jit_bra_r((s1), (s2), JLm(label, 0,0,0) )
#define jit_bler_i(label, s1, s2) jit_bra_r((s1), (s2), JLEm(label,0,0,0) )
#define jit_bgtr_i(label, s1, s2) jit_bra_r((s1), (s2), JGm(label, 0,0,0) )
#define jit_bger_i(label, s1, s2) jit_bra_r((s1), (s2), JGEm(label,0,0,0) )
#define jit_beqr_i(label, s1, s2) jit_bra_r((s1), (s2), JEm(label, 0,0,0) )
#define jit_bner_i(label, s1, s2) jit_bra_r((s1), (s2), JNEm(label,0,0,0) )
#define jit_bltr_ui(label, s1, s2) jit_bra_r((s1), (s2), JBm(label, 0,0,0) )
#define jit_bler_ui(label, s1, s2) jit_bra_r((s1), (s2), JBEm(label,0,0,0) )
#define jit_bgtr_ui(label, s1, s2) jit_bra_r((s1), (s2), JAm(label, 0,0,0) )
#define jit_bger_ui(label, s1, s2) jit_bra_r((s1), (s2), JAEm(label,0,0,0) )
#define jit_bmsr_i(label, s1, s2) (TESTLrr((s1), (s2)), JNZm(label,0,0,0), _jit.x.pc)
#define jit_bmcr_i(label, s1, s2) (TESTLrr((s1), (s2)), JZm(label,0,0,0), _jit.x.pc)
#define jit_boaddr_i(label, s1, s2) (ADDLrr((s2), (s1)), JOm(label,0,0,0), _jit.x.pc)
#define jit_bosubr_i(label, s1, s2) (SUBLrr((s2), (s1)), JOm(label,0,0,0), _jit.x.pc)
#define jit_boaddr_ui(label, s1, s2) (ADDLrr((s2), (s1)), JCm(label,0,0,0), _jit.x.pc)
#define jit_bosubr_ui(label, s1, s2) (SUBLrr((s2), (s1)), JCm(label,0,0,0), _jit.x.pc)
#define jit_bltr_i(label, s1, s2) jit_bra_r((s1), (s2), JLm(label) )
#define jit_bler_i(label, s1, s2) jit_bra_r((s1), (s2), JLEm(label) )
#define jit_bgtr_i(label, s1, s2) jit_bra_r((s1), (s2), JGm(label) )
#define jit_bger_i(label, s1, s2) jit_bra_r((s1), (s2), JGEm(label) )
#define jit_beqr_i(label, s1, s2) jit_bra_r((s1), (s2), JEm(label) )
#define jit_bner_i(label, s1, s2) jit_bra_r((s1), (s2), JNEm(label) )
#define jit_bltr_ui(label, s1, s2) jit_bra_r((s1), (s2), JBm(label) )
#define jit_bler_ui(label, s1, s2) jit_bra_r((s1), (s2), JBEm(label) )
#define jit_bgtr_ui(label, s1, s2) jit_bra_r((s1), (s2), JAm(label) )
#define jit_bger_ui(label, s1, s2) jit_bra_r((s1), (s2), JAEm(label) )
#define jit_bmsr_i(label, s1, s2) (TESTLrr((s1), (s2)), JNZm(label), _jit.x.pc)
#define jit_bmcr_i(label, s1, s2) (TESTLrr((s1), (s2)), JZm(label), _jit.x.pc)
#define jit_boaddr_i(label, s1, s2) (ADDLrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_bosubr_i(label, s1, s2) (SUBLrr((s2), (s1)), JOm(label), _jit.x.pc)
#define jit_boaddr_ui(label, s1, s2) (ADDLrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_bosubr_ui(label, s1, s2) (SUBLrr((s2), (s1)), JCm(label), _jit.x.pc)
#define jit_blti_i(label, rs, is) jit_bra_i0((rs), (is), JLm(label, 0,0,0), JSm(label, 0,0,0) )
#define jit_blei_i(label, rs, is) jit_bra_i ((rs), (is), JLEm(label,0,0,0) )
#define jit_bgti_i(label, rs, is) jit_bra_i ((rs), (is), JGm(label, 0,0,0) )
#define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label,0,0,0), JNSm(label,0,0,0) )
#define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label, 0,0,0), JEm(label, 0,0,0) )
#define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label,0,0,0), JNEm(label,0,0,0) )
#define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JBm(label, 0,0,0) )
#define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JBEm(label,0,0,0), JEm(label, 0,0,0) )
#define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JAm(label, 0,0,0), JNEm(label,0,0,0) )
#define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JAEm(label,0,0,0) )
#define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
#define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
#define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc)
#define jit_bosubi_ui(label, rs, is) (SUBLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc)
#define jit_blti_i(label, rs, is) jit_bra_i0((rs), (is), JLm(label), JSm(label) )
#define jit_blei_i(label, rs, is) jit_bra_i ((rs), (is), JLEm(label) )
#define jit_bgti_i(label, rs, is) jit_bra_i ((rs), (is), JGm(label) )
#define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label), JNSm(label) )
#define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label), JEm(label) )
#define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label), JNEm(label) )
#define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JBm(label) )
#define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JBEm(label), JEm(label) )
#define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JAm(label), JNEm(label) )
#define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JAEm(label) )
#define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label), _jit.x.pc)
#define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bosubi_ui(label, rs, is) (SUBLir((is), (rs)), JCm(label), _jit.x.pc)
#define jit_bmsi_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JNZm(label,0,0,0), _jit.x.pc)
#define jit_bmci_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JZm(label,0,0,0), _jit.x.pc)
#define jit_bmsi_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JNZm(label), _jit.x.pc)
#define jit_bmci_i(label, rs, is) (jit_reduce(TEST, (is), (rs)), JZm(label), _jit.x.pc)
#define jit_jmpi(label) (JMPm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
#define jit_calli(label) (CALLm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
#define jit_callr(reg) (CALLsr(reg))
#define jit_jmpr(reg) JMPsr(reg)
#define jit_patch_at(jump_pc,v) (*_PSL((jump_pc) - 4) = _jit_SL((v) - (jump_pc)))
#define jit_ret() (POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), POPLr(_EBP), RET_())
#define jit_jmpi(label) (JMPm( ((unsigned long) (label))), _jit.x.pc)
#define jit_jmpr(reg) JMPsr(reg)
/* Memory */
#define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d))
#define jit_ldr_c(d, rs) MOVSBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_c(d, s1, s2) MOVSBLmr(0, (s1), (s2), 1, (d))
#define jit_ldxi_c(d, rs, is) MOVSBLmr((is), (rs), 0, 0, (d))
#define jit_ldi_uc(d, is) MOVZBLmr((is), 0, 0, 0, (d))
#define jit_ldr_uc(d, rs) MOVZBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_uc(d, s1, s2) MOVZBLmr(0, (s1), (s2), 1, (d))
#define jit_ldxi_uc(d, rs, is) MOVZBLmr((is), (rs), 0, 0, (d))
#define jit_sti_c(id, rs) jit_movbrm((rs), (id), 0, 0, 0)
#define jit_ldr_uc(d, rs) MOVZBLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_uc(d, s1, s2) MOVZBLmr(0, (s1), (s2), 1, (d))
#define jit_str_c(rd, rs) jit_movbrm((rs), 0, (rd), 0, 0)
#define jit_stxr_c(d1, d2, rs) jit_movbrm((rs), 0, (d1), (d2), 1)
#define jit_stxi_c(id, rd, rs) jit_movbrm((rs), (id), (rd), 0, 0)
#define jit_ldi_s(d, is) MOVSWLmr((is), 0, 0, 0, (d))
#define jit_ldr_s(d, rs) MOVSWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_s(d, s1, s2) MOVSWLmr(0, (s1), (s2), 1, (d))
#define jit_ldxi_s(d, rs, is) MOVSWLmr((is), (rs), 0, 0, (d))
#define jit_ldi_us(d, is) MOVZWLmr((is), 0, 0, 0, (d))
#define jit_ldr_us(d, rs) MOVZWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_us(d, s1, s2) MOVZWLmr(0, (s1), (s2), 1, (d))
#define jit_ldxi_us(d, rs, is) MOVZWLmr((is), (rs), 0, 0, (d))
#define jit_sti_s(id, rs) MOVWrm(jit_reg16(rs), (id), 0, 0, 0)
#define jit_str_s(rd, rs) MOVWrm(jit_reg16(rs), 0, (rd), 0, 0)
#define jit_stxr_s(d1, d2, rs) MOVWrm(jit_reg16(rs), 0, (d1), (d2), 1)
#define jit_stxi_s(id, rd, rs) MOVWrm(jit_reg16(rs), (id), (rd), 0, 0)
#define jit_ldi_i(d, is) MOVLmr((is), 0, 0, 0, (d))
#define jit_ldr_i(d, rs) MOVLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_i(d, s1, s2) MOVLmr(0, (s1), (s2), 1, (d))
#define jit_ldxi_i(d, rs, is) MOVLmr((is), (rs), 0, 0, (d))
#define jit_sti_i(id, rs) MOVLrm((rs), (id), 0, 0, 0)
#define jit_str_i(rd, rs) MOVLrm((rs), 0, (rd), 0, 0)
#define jit_stxr_i(d1, d2, rs) MOVLrm((rs), 0, (d1), (d2), 1)
#define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0)
#define jit_ldr_us(d, rs) MOVZWLmr(0, (rs), 0, 0, (d))
#define jit_ldxr_us(d, s1, s2) MOVZWLmr(0, (s1), (s2), 1, (d))
#define jit_str_s(rd, rs) MOVWrm(jit_reg16(rs), 0, (rd), 0, 0)
#define jit_stxr_s(d1, d2, rs) MOVWrm(jit_reg16(rs), 0, (d1), (d2), 1)
#define jit_str_i(rd, rs) MOVLrm((rs), 0, (rd), 0, 0)
#define jit_stxr_i(d1, d2, rs) MOVLrm((rs), 0, (d1), (d2), 1)
/* Extra */
#define jit_nop() NOP_()
#define _jit_alignment(pc, n) (((pc ^ _MASK(4)) + 1) & _MASK(n))
#define jit_align(n) NOPi(_jit_alignment(_jit_UL(_jit.x.pc), (n)))
#endif /* __lightning_core_h */
#if LIGHTNING_CROSS \
? LIGHTNING_TARGET == LIGHTNING_X86_64 \
: defined (__x86_64__)
#include "i386/core-64.h"
#else
#include "i386/core-32.h"
#endif
#endif /* __lightning_core_i386_h */

View File

@@ -0,0 +1,356 @@
/******************************** -*- C -*- ****************************
*
* Support macros for the i386 math coprocessor
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2004, 2008 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_fp_h
#define __lightning_fp_h
/* We really must map the x87 stack onto a flat register file. In practice,
we can provide something sensible and make it work on the x86 using the
stack like a file of eight registers.
We use six or seven registers so as to have some freedom
for floor, ceil, round, (and log, tan, atn and exp).
Not hard at all, basically play with FXCH. FXCH is mostly free,
so the generated code is not bad. Of course we special case when one
of the operands turns out to be ST0.
Here are the macros that actually do the trick. */
#define JIT_FPR_NUM 6
#define JIT_FPRET 0
#define JIT_FPR(i) (i)
#define jit_fxch(rs, op) (((rs) != 0 ? FXCHr(rs) : 0), \
op, ((rs) != 0 ? FXCHr(rs) : 0))
#define jit_fp_unary(rd, s1, op) \
((rd) == (s1) ? jit_fxch ((rd), op) \
: (rd) == 0 ? (FSTPr (0), FLDr ((s1)-1), op) \
: (FLDr ((s1)), op, FSTPr ((rd) + 1)))
#define jit_fp_binary(rd, s1, s2, op, opr) \
((rd) == (s1) ? \
((s2) == 0 ? opr(0, (rd)) \
: (s2) == (s1) ? jit_fxch((rd), op(0, 0)) \
: jit_fxch((rd), op((s2), 0))) \
: (rd) == (s2) ? \
((s1) == 0 ? op(0, (rd)) \
: jit_fxch((rd), opr((s1), 0))) \
: (FLDr (s1), op((s2)+1, 0), FSTPr((rd)+1)))
#define jit_addr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FADDrr,FADDrr)
#define jit_subr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FSUBrr,FSUBRrr)
#define jit_mulr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FMULrr,FMULrr)
#define jit_divr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FDIVrr,FDIVRrr)
#define jit_abs_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e1))
#define jit_negr_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e0))
#define jit_sqrt_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9fa))
/* - moves:
move FPR0 to FPR3
FST ST3
move FPR3 to FPR0
FXCH ST3
FST ST3
move FPR3 to FPR1
FLD ST3
FSTP ST2 Stack is rotated, so FPRn becomes STn+1 */
#define jit_movr_d(rd,s1) \
((s1) == (rd) ? 0 \
: (s1) == 0 ? FSTr ((rd)) \
: (rd) == 0 ? (FXCHr ((s1)), FSTr ((s1))) \
: (FLDr ((s1)), FSTPr ((rd)+1)))
/* - loads:
load into FPR0
FSTP ST0
FLD [FUBAR]
load into FPR3
FSTP ST3 Save old st0 into destination register
FLD [FUBAR]
FXCH ST3 Get back old st0
(and similarly for immediates, using the stack) */
#define jit_movi_f(rd,immf) \
(_O (0x68), \
*((float *) _jit.x.pc) = (float) immf, \
_jit.x.uc_pc += sizeof (float), \
jit_ldr_f((rd), _ESP), \
ADDLir(4, _ESP))
union jit_double_imm {
double d;
int i[2];
};
#define jit_movi_d(rd,immd) \
(_O (0x68), \
_jit.x.uc_pc[4] = 0x68, \
((union jit_double_imm *) (_jit.x.uc_pc + 5))->d = (double) immd, \
*((int *) _jit.x.uc_pc) = ((union jit_double_imm *) (_jit.x.uc_pc + 5))->i[1], \
_jit.x.uc_pc += 9, \
jit_ldr_d((rd), _ESP), \
ADDLir(8, _ESP))
#define jit_ldi_f(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0)) \
: (FLDSm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldi_d(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), 0, 0, 0)) \
: (FLDLm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_f(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (rs), 0, 0)) \
: (FLDSm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_d(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (rs), 0, 0)) \
: (FLDLm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_f(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), (rs), 0, 0)) \
: (FLDSm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_d(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), (rs), 0, 0)) \
: (FLDLm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxr_f(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (s1), (s2), 1)) \
: (FLDSm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_ldxr_d(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (s1), (s2), 1)) \
: (FLDLm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_extr_i_d(rd, rs) (PUSHLr((rs)), \
((rd) == 0 ? (FSTPr (0), FILDLm(0, _ESP, 0, 0)) \
: (FILDLm(0, _ESP, 0, 0), FSTPr ((rd) + 1))), \
POPLr((rs)))
#define jit_stxi_f(id, rd, rs) jit_fxch ((rs), FSTSm((id), (rd), 0, 0))
#define jit_stxr_f(d1, d2, rs) jit_fxch ((rs), FSTSm(0, (d1), (d2), 1))
#define jit_stxi_d(id, rd, rs) jit_fxch ((rs), FSTLm((id), (rd), 0, 0))
#define jit_stxr_d(d1, d2, rs) jit_fxch ((rs), FSTLm(0, (d1), (d2), 1))
#define jit_sti_f(id, rs) jit_fxch ((rs), FSTSm((id), 0, 0, 0))
#define jit_str_f(rd, rs) jit_fxch ((rs), FSTSm(0, (rd), 0, 0))
#define jit_sti_d(id, rs) jit_fxch ((rs), FSTLm((id), 0, 0, 0))
#define jit_str_d(rd, rs) jit_fxch ((rs), FSTLm(0, (rd), 0, 0))
/* ABI */
#define jit_retval_d(rd) FSTPr((rd) + 1)
/* Assume round to near mode */
#define jit_floorr_d_i(rd, rs) \
(FLDr (rs), jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_ceilr_d_i(rd, rs) \
(FLDr (rs), jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_truncr_d_i(rd, rs) \
(FLDr (rs), jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_calc_diff(ofs) \
FISTLm(ofs, _ESP, 0, 0), \
FILDLm(ofs, _ESP, 0, 0), \
FSUBRPr(1), \
FSTPSm(4+ofs, _ESP, 0, 0) \
/* The real meat */
#define jit_floor2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
ADDLir(0x7FFFFFFF, aux), /* carry if x-round(x) < -0 */ \
SBBLir(0, rd), /* subtract 1 if carry */ \
POPLr(aux))
#define jit_ceil2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
TESTLrr(aux, aux), \
SETGr(jit_reg8(aux)), \
SHRLir(1, aux), \
ADCLir(0, rd), \
POPLr(aux))
/* a mingling of the two above */
#define jit_trunc2(rd, aux) \
(PUSHLr(aux), \
SUBLir(12, _ESP), \
FSTSm(0, _ESP, 0, 0), \
jit_calc_diff(4), \
POPLr(aux), \
POPLr(rd), \
TESTLrr(aux, aux), \
POPLr(aux), \
JSSm(_jit.x.pc + 11), \
ADDLir(0x7FFFFFFF, aux), /* 6 */ \
SBBLir(0, rd), /* 3 */ \
JMPSm(_jit.x.pc + 10), /* 2 */ \
TESTLrr(aux, aux), /* 2 */ \
SETGr(jit_reg8(aux)), /* 3 */ \
SHRLir(1, aux), /* 2 */ \
ADCLir(0, rd), /* 3 */ \
POPLr(aux))
/* the easy one */
#define jit_roundr_d_i(rd, rs) \
(PUSHLr(_EAX), \
jit_fxch ((rs), FISTLm(0, _ESP, 0, 0)), \
POPLr((rd)))
#define jit_fp_test(d, s1, s2, n, _and, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
((d) != _EAX ? MOVLrr(_EAX, (d)) : 0), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)), \
res, \
((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0)) /* xchg */
#define jit_fp_btest(d, s1, s2, n, _and, cmp, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
PUSHLr(_EAX), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir ((_and), _EAX) : 0), \
((cmp) ? CMPLir ((cmp), _EAX) : 0), \
POPLr(_EAX), \
res ((d)), \
_jit.x.pc)
#define jit_nothing_needed(x)
/* After FNSTSW we have 1 if <, 40 if =, 0 if >, 45 if unordered. Here
is how to map the values of the status word's high byte to the
conditions.
< = > unord valid values condition
gt no no yes no 0 STSW & 45 == 0
lt yes no no no 1 STSW & 45 == 1
eq no yes no no 40 STSW & 45 == 40
unord no no no yes 45 bit 2 == 1
ge no yes no no 0, 40 bit 0 == 0
unlt yes no no yes 1, 45 bit 0 == 1
ltgt yes no yes no 0, 1 bit 6 == 0
uneq no yes no yes 40, 45 bit 6 == 1
le yes yes no no 1, 40 odd parity for STSW & 41
ungt no no yes yes 0, 45 even parity for STSW & 41
unle yes yes no yes 1, 40, 45 STSW & 45 != 0
unge no yes yes yes 0, 40, 45 STSW & 45 != 1
ne yes no yes yes 0, 1, 45 STSW & 45 != 40
ord yes yes yes no 0, 1, 40 bit 2 == 0
lt, le, ungt, unge are actually computed as gt, ge, unlt, unle with
the operands swapped; it is more efficient this way. */
#define jit_gtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETZr (_AL))
#define jit_ger_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, SBBBir (-1, _AL))
#define jit_unler_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETNZr (_AL))
#define jit_unltr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, ADCBir (0, _AL))
#define jit_ltr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETZr (_AL))
#define jit_ler_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, SBBBir (-1, _AL))
#define jit_unger_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETNZr (_AL))
#define jit_ungtr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, ADCBir (0, _AL))
#define jit_eqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETEr (_AL)))
#define jit_ner_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETNEr (_AL)))
#define jit_ltgtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, SBBBir (-1, _AL))
#define jit_uneqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, ADCBir (0, _AL))
#define jit_ordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, SBBBir (-1, _AL))
#define jit_unordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, ADCBir (0, _AL))
#define jit_bgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JZm)
#define jit_bger_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JNCm)
#define jit_bunler_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
#define jit_bunltr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
#define jit_bltr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JZm)
#define jit_bler_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JNCm)
#define jit_bunger_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
#define jit_bungtr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
#define jit_beqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JZm)
#define jit_bner_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
#define jit_bltgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JNCm)
#define jit_buneqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JCm)
#define jit_bordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JNCm)
#define jit_bunordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JCm)
#define jit_pusharg_d(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jit_str_d(JIT_SP,(rs)))
#define jit_pusharg_f(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jit_str_f(JIT_SP,(rs)))
#if 0
#define jit_sin() _OO(0xd9fe) /* fsin */
#define jit_cos() _OO(0xd9ff) /* fcos */
#define jit_tan() (_OO(0xd9f2), /* fptan */ \
FSTPr(0)) /* fstp st */
#define jit_atn() (_OO(0xd9e8), /* fld1 */ \
_OO(0xd9f3)) /* fpatan */
#define jit_exp() (_OO(0xd9ea), /* fldl2e */ \
FMULPr(1), /* fmulp */ \
_OO(0xd9c0), /* fld st */ \
_OO(0xd9fc), /* frndint */ \
_OO(0xdce9), /* fsubr */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f0), /* f2xm1 */ \
_OO(0xd9e8), /* fld1 */ \
_OO(0xdec1), /* faddp */ \
_OO(0xd9fd), /* fscale */ \
FSTPr(1)) /* fstp st(1) */
#define jit_log() (_OO(0xd9ed), /* fldln2 */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f1)) /* fyl2x */
#endif
#define jit_prepare_f(nf) (_jitl.argssize += (nf))
#define jit_prepare_d(nd) (_jitl.argssize += 2 * (nd))
#define jit_arg_f() ((_jitl.framesize += sizeof(float)) - sizeof(float))
#define jit_arg_d() ((_jitl.framesize += sizeof(double)) - sizeof(double))
#endif /* __lightning_fp_h */

View File

@@ -0,0 +1,325 @@
/******************************** -*- C -*- ****************************
*
* Support macros for SSE floating-point math
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_fp_h
#define __lightning_fp_h
#include <float.h>
#define JIT_FPR_NUM 7
#define JIT_FPRET _XMM0
#define JIT_FPR(i) (_XMM8 + (i))
#define JIT_FPTMP _XMM15
/* Either use a temporary register that is finally AND/OR/XORed with RS = RD,
or use RD as the temporary register and to the AND/OR/XOR with RS. */
#define jit_unop_tmp(rd, rs, op) \
( (rs) == (rd) \
? op((rd), JIT_FPTMP, JIT_FPTMP)) \
: op((rd), (rd), (rs)))
#define jit_unop_f(rd, rs, op) \
((rs) == (rd) ? op((rd)) : (MOVSSrr ((rs), (rd)), op((rd))))
#define jit_unop_d(rd, rs, op) \
((rs) == (rd) ? op((rd)) : (MOVSDrr ((rs), (rd)), op((rd))))
#define jit_3opc_f(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) ? op((s1), (rd)) \
: (MOVSSrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3opc_d(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) ? op((s1), (rd)) \
: (MOVSDrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3op_f(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) \
? (MOVSSrr ((rd), JIT_FPTMP), MOVSSrr ((s1), (rd)), op(JIT_FPTMP, (rd))) \
: (MOVSSrr ((s1), (rd)), op((s2), (rd)))))
#define jit_3op_d(rd, s1, s2, op) \
( (s1) == (rd) ? op((s2), (rd)) \
: ((s2) == (rd) \
? (MOVSDrr ((rd), JIT_FPTMP), MOVSDrr ((s1), (rd)), op(JIT_FPTMP, (rd))) \
: (MOVSDrr ((s1), (rd)), op((s2), (rd)))))
#define jit_addr_f(rd,s1,s2) jit_3opc_f((rd), (s1), (s2), ADDSSrr)
#define jit_subr_f(rd,s1,s2) jit_3op_f((rd), (s1), (s2), SUBSSrr)
#define jit_mulr_f(rd,s1,s2) jit_3opc_f((rd), (s1), (s2), MULSSrr)
#define jit_divr_f(rd,s1,s2) jit_3op_f((rd), (s1), (s2), DIVSSrr)
#define jit_addr_d(rd,s1,s2) jit_3opc_d((rd), (s1), (s2), ADDSDrr)
#define jit_subr_d(rd,s1,s2) jit_3op_d((rd), (s1), (s2), SUBSDrr)
#define jit_mulr_d(rd,s1,s2) jit_3opc_d((rd), (s1), (s2), MULSDrr)
#define jit_divr_d(rd,s1,s2) jit_3op_d((rd), (s1), (s2), DIVSDrr)
#define jit_movr_f(rd,rs) MOVSSrr((rs), (rd))
#define jit_movr_d(rd,rs) MOVSDrr((rs), (rd))
/* either pcmpeqd %xmm7, %xmm7 / psrld $1, %xmm7 / andps %xmm7, %RD (if RS = RD)
or pcmpeqd %RD, %RD / psrld $1, %RD / andps %RS, %RD (if RS != RD) */
#define _jit_abs_f(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSRLDir (1, (cnst)), ANDPSrr ((rs), (rd)))
#define _jit_neg_f(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSLLDir (31, (cnst)), XORPSrr ((rs), (rd)))
#define jit_abs_f(rd,rs) jit_unop_tmp ((rd), (rs), _jit_abs_f)
#define jit_neg_f(rd,rs) jit_unop_tmp ((rd), (rs), _jit_neg_f)
#define _jit_abs_d(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSRLQir (1, (cnst)), ANDPDrr ((rs), (rd)))
#define _jit_neg_d(rd,cnst,rs) \
(PCMPEQDrr((cnst), (cnst)), PSLLQir (63, (cnst)), XORPDrr ((rs), (rd)))
#define jit_abs_d(rd,rs) jit_unop_tmp ((rd), (rs), _jit_abs_d)
#define jit_neg_d(rd,rs) jit_unop_tmp ((rd), (rs), _jit_neg_d)
#define jit_sqrt_d(rd,rs) SQRTSSrr((rs), (rd))
#define jit_sqrt_f(rd,rs) SQRTSDrr((rs), (rd))
#define _jit_ldi_f(d, is) MOVSSmr((is), 0, 0, 0, (d))
#define _jit_ldxi_f(d, rs, is) MOVSSmr((is), (rs), 0, 0, (d))
#define jit_ldr_f(d, rs) MOVSSmr(0, (rs), 0, 0, (d))
#define jit_ldxr_f(d, s1, s2) MOVSSmr(0, (s1), (s2), 1, (d))
#define _jit_sti_f(id, rs) MOVSSrm((rs), (id), 0, 0, 0)
#define _jit_stxi_f(id, rd, rs) MOVSSrm((rs), (id), (rd), 0, 0)
#define jit_str_f(rd, rs) MOVSSrm((rs), 0, (rd), 0, 0)
#define jit_stxr_f(d1, d2, rs) MOVSSrm((rs), 0, (d1), (d2), 1)
#define jit_ldi_f(d, is) (_u32P((long)(is)) ? _jit_ldi_f((d), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldr_f((d), JIT_REXTMP)))
#define jit_sti_f(id, rs) (_u32P((long)(id)) ? _jit_sti_f((id), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_str_f (JIT_REXTMP, (rs))))
#define jit_ldxi_f(d, rs, is) (_u32P((long)(is)) ? _jit_ldxi_f((d), (rs), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldxr_f((d), (rs), JIT_REXTMP)))
#define jit_stxi_f(id, rd, rs) (_u32P((long)(id)) ? _jit_stxi_f((id), (rd), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_stxr_f (JIT_REXTMP, (rd), (rs))))
#define _jit_ldi_d(d, is) MOVSDmr((is), 0, 0, 0, (d))
#define _jit_ldxi_d(d, rs, is) MOVSDmr((is), (rs), 0, 0, (d))
#define jit_ldr_d(d, rs) MOVSDmr(0, (rs), 0, 0, (d))
#define jit_ldxr_d(d, s1, s2) MOVSDmr(0, (s1), (s2), 1, (d))
#define _jit_sti_d(id, rs) MOVSDrm((rs), (id), 0, 0, 0)
#define _jit_stxi_d(id, rd, rs) MOVSDrm((rs), (id), (rd), 0, 0)
#define jit_str_d(rd, rs) MOVSDrm((rs), 0, (rd), 0, 0)
#define jit_stxr_d(d1, d2, rs) MOVSDrm((rs), 0, (d1), (d2), 1)
#define jit_ldi_d(d, is) (_u32P((long)(is)) ? _jit_ldi_d((d), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldr_d((d), JIT_REXTMP)))
#define jit_sti_d(id, rs) (_u32P((long)(id)) ? _jit_sti_d((id), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_str_d (JIT_REXTMP, (rs))))
#define jit_ldxi_d(d, rs, is) (_u32P((long)(is)) ? _jit_ldxi_d((d), (rs), (is)) : (jit_movi_l(JIT_REXTMP, (is)), jit_ldxr_d((d), (rs), JIT_REXTMP)))
#define jit_stxi_d(id, rd, rs) (_u32P((long)(id)) ? _jit_stxi_d((id), (rd), (rs)) : (jit_movi_l(JIT_REXTMP, (id)), jit_stxr_d (JIT_REXTMP, (rd), (rs))))
#define jit_movi_f(rd,immf) \
((immf) == 0.0 ? XORSSrr ((rd), (rd)) : \
(PUSHQi (0x12345678L), \
*((float *) (_jit.x.uc_pc - 4)) = (float) immf, \
jit_ldr_f((rd), _ESP), \
ADDQir(8, _ESP)))
union jit_double_imm {
double d;
long l;
};
#define jit_movi_d(rd,immd) \
((immd) == 0.0 ? XORSDrr ((rd), (rd)) : \
(_O (0x50), \
MOVQir (0x123456789abcdef0L, _EAX), \
((union jit_double_imm *) (_jit.x.uc_pc - 8))->d = (double) immd, \
_O (0x50), jit_ldr_d((rd), _ESP), \
_O (0x58), _O (0x58)))
#define jit_extr_i_d(rd, rs) CVTSI2SDLrr((rs), (rd))
#define jit_extr_i_f(rd, rs) CVTSI2SSLrr((rs), (rd))
#define jit_extr_l_d(rd, rs) CVTSI2SDQrr((rs), (rd))
#define jit_extr_l_f(rd, rs) CVTSI2SSQrr((rs), (rd))
#define jit_extr_f_d(rd, rs) CVTSS2SDrr((rs), (rd))
#define jit_extr_d_f(rd, rs) CVTSD2SSrr((rs), (rd))
#define jit_roundr_d_i(rd, rs) CVTSD2SILrr((rs), (rd))
#define jit_roundr_f_i(rd, rs) CVTSS2SILrr((rs), (rd))
#define jit_roundr_d_l(rd, rs) CVTSD2SIQrr((rs), (rd))
#define jit_roundr_f_l(rd, rs) CVTSS2SIQrr((rs), (rd))
#define jit_truncr_d_i(rd, rs) CVTTSD2SILrr((rs), (rd))
#define jit_truncr_f_i(rd, rs) CVTTSS2SILrr((rs), (rd))
#define jit_truncr_d_l(rd, rs) CVTTSD2SIQrr((rs), (rd))
#define jit_truncr_f_l(rd, rs) CVTTSS2SIQrr((rs), (rd))
#define jit_ceilr_f_i(rd, rs) do { \
jit_roundr_f_i ((rd), (rs)); \
jit_extr_i_f (JIT_FPTMP, (rd)); \
UCOMISSrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_d_i(rd, rs) do { \
jit_roundr_d_i ((rd), (rs)); \
jit_extr_i_d (JIT_FPTMP, (rd)); \
UCOMISDrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_f_l(rd, rs) do { \
jit_roundr_f_l ((rd), (rs)); \
jit_extr_l_f (JIT_FPTMP, (rd)); \
UCOMISSrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_ceilr_d_l(rd, rs) do { \
jit_roundr_d_l ((rd), (rs)); \
jit_extr_l_d (JIT_FPTMP, (rd)); \
UCOMISDrr ((rs), JIT_FPTMP); \
ADCLir (0, (rd)); \
} while (0)
#define jit_floorr_f_i(rd, rs) do { \
jit_roundr_f_i ((rd), (rs)); \
jit_extr_i_f (JIT_FPTMP, (rd)); \
UCOMISSrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_d_i(rd, rs) do { \
jit_roundr_d_i ((rd), (rs)); \
jit_extr_i_d (JIT_FPTMP, (rd)); \
UCOMISDrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_f_l(rd, rs) do { \
jit_roundr_f_l ((rd), (rs)); \
jit_extr_l_f (JIT_FPTMP, (rd)); \
UCOMISSrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_floorr_d_l(rd, rs) do { \
jit_roundr_d_l ((rd), (rs)); \
jit_extr_l_d (JIT_FPTMP, (rd)); \
UCOMISDrr (JIT_FPTMP, (rs)); \
SBBLir (0, (rd)); \
} while (0)
#define jit_bltr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JAm ((d)), _jit.x.pc)
#define jit_bler_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JAEm ((d)), _jit.x.pc)
#define jit_beqr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), _OO (0x7a06), JEm ((d)), _jit.x.pc)
#define jit_bner_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), _OO (0x7a02), _OO (0x7405), JMPm (((d))), _jit.x.pc) /* JP to JMP, JZ past JMP */
#define jit_bger_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JAEm ((d)), _jit.x.pc)
#define jit_bgtr_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JAm ((d)), _jit.x.pc)
#define jit_bunltr_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JNAEm ((d)), _jit.x.pc)
#define jit_bunler_f(d, s1, s2) (UCOMISSrr ((s2), (s1)), JNAm ((d)), _jit.x.pc)
#define jit_buneqr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JEm ((d)), _jit.x.pc)
#define jit_bltgtr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNEm ((d)), _jit.x.pc)
#define jit_bunger_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNAm ((d)), _jit.x.pc)
#define jit_bungtr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNAEm ((d)), _jit.x.pc)
#define jit_bordr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JNPm ((d)), _jit.x.pc)
#define jit_bunordr_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), JPm ((d)), _jit.x.pc)
#define jit_bltr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JAm ((d)), _jit.x.pc)
#define jit_bler_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JAEm ((d)), _jit.x.pc)
#define jit_beqr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), _OO (0x7a06), JEm ((d)), _jit.x.pc)
#define jit_bner_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), _OO (0x7a02), _OO (0x7405), JMPm (((d))), _jit.x.pc) /* JP to JMP, JZ past JMP */
#define jit_bger_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JAEm ((d)), _jit.x.pc)
#define jit_bgtr_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JAm ((d)), _jit.x.pc)
#define jit_bunltr_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JNAEm ((d)), _jit.x.pc, _jit.x.pc)
#define jit_bunler_d(d, s1, s2) (UCOMISDrr ((s2), (s1)), JNAm ((d)), _jit.x.pc)
#define jit_buneqr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JEm ((d)), _jit.x.pc)
#define jit_bltgtr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNEm ((d)), _jit.x.pc)
#define jit_bunger_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNAm ((d)), _jit.x.pc)
#define jit_bungtr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNAEm ((d)), _jit.x.pc)
#define jit_bordr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JNPm ((d)), _jit.x.pc)
#define jit_bunordr_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), JPm ((d)), _jit.x.pc)
#define jit_ltr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETAr (jit_reg8((d))))
#define jit_ler_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETAEr (jit_reg8((d))))
#define jit_eqr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), _OO(0x7a03), SETEr (jit_reg8((d))))
#define jit_ner_f(d, s1, s2) (UCOMISSrr ((s1), (s2)), MOVLir (1, (d)), _OO(0x7a03), SETNEr (jit_reg8((d))))
#define jit_ger_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETAEr (jit_reg8((d))))
#define jit_gtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETAr (jit_reg8((d))))
#define jit_unltr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETNAEr (jit_reg8((d))))
#define jit_unler_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s2), (s1)), SETNAr (jit_reg8((d))))
#define jit_uneqr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETEr (jit_reg8((d))))
#define jit_ltgtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNEr (jit_reg8((d))))
#define jit_unger_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNAr (jit_reg8((d))))
#define jit_ungtr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNAEr (jit_reg8((d))))
#define jit_ordr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETNPr (jit_reg8((d))))
#define jit_unordr_f(d, s1, s2) (XORLrr ((d), (d)), UCOMISSrr ((s1), (s2)), SETPr (jit_reg8((d))))
#define jit_ltr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETAr (jit_reg8((d))))
#define jit_ler_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETAEr (jit_reg8((d))))
#define jit_eqr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), _OO(0x7a03), SETEr (jit_reg8((d))))
#define jit_ner_d(d, s1, s2) (UCOMISDrr ((s1), (s2)), MOVLir (1, (d)), _OO(0x7a03), SETNEr (jit_reg8((d))))
#define jit_ger_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETAEr (jit_reg8((d))))
#define jit_gtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETAr (jit_reg8((d))))
#define jit_unltr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETNAEr (jit_reg8((d))))
#define jit_unler_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s2), (s1)), SETNAr (jit_reg8((d))))
#define jit_uneqr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETEr (jit_reg8((d))))
#define jit_ltgtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNEr (jit_reg8((d))))
#define jit_unger_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNAr (jit_reg8((d))))
#define jit_ungtr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNAEr (jit_reg8((d))))
#define jit_ordr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETNPr (jit_reg8((d))))
#define jit_unordr_d(d, s1, s2) (XORLrr ((d), (d)), UCOMISDrr ((s1), (s2)), SETPr (jit_reg8((d))))
#define jit_prepare_f(num) ((_jitl.nextarg_putfp + (num) > JIT_FP_ARG_MAX \
? (_jitl.argssize += _jitl.nextarg_putfp + (num) - JIT_FP_ARG_MAX, \
_jitl.fprssize = JIT_FP_ARG_MAX) \
: (_jitl.fprssize += (num))), \
_jitl.nextarg_putfp += (num))
#define jit_prepare_d(num) ((_jitl.nextarg_putfp + (num) > JIT_FP_ARG_MAX \
? (_jitl.argssize += _jitl.nextarg_putfp + (num) - JIT_FP_ARG_MAX, \
_jitl.fprssize = JIT_FP_ARG_MAX) \
: (_jitl.fprssize += (num))), \
_jitl.nextarg_putfp += (num))
#define jit_arg_f() (_jitl.nextarg_getfp < JIT_FP_ARG_MAX \
? _jitl.nextarg_getfp++ \
: ((_jitl.framesize += sizeof(double)) - sizeof(double)))
#define jit_arg_d() (_jitl.nextarg_getfp < JIT_FP_ARG_MAX \
? _jitl.nextarg_getfp++ \
: ((_jitl.framesize += sizeof(double)) - sizeof(double)))
#define jit_getarg_f(reg, ofs) ((ofs) < JIT_FP_ARG_MAX \
? jit_movr_f((reg), _XMM0 + (ofs)) \
: jit_ldxi_f((reg), JIT_FP, (ofs)))
#define jit_getarg_d(reg, ofs) ((ofs) < JIT_FP_ARG_MAX \
? jit_movr_d((reg), _XMM0 + (ofs)) \
: jit_ldxi_d((reg), JIT_FP, (ofs)))
#define jit_pusharg_f(rs) (--_jitl.nextarg_putfp >= JIT_FP_ARG_MAX \
? (SUBQir(sizeof(double), JIT_SP), jit_str_f(JIT_SP,(rs))) \
: jit_movr_f(_XMM0 + _jitl.nextarg_putfp, (rs)))
#define jit_pusharg_d(rs) (--_jitl.nextarg_putfp >= JIT_FP_ARG_MAX \
? (SUBQir(sizeof(double), JIT_SP), jit_str_d(JIT_SP,(rs))) \
: jit_movr_d(_XMM0 + _jitl.nextarg_putfp, (rs)))
#endif /* __lightning_fp_h */

View File

@@ -1,20 +1,20 @@
/******************************** -*- C -*- ****************************
*
* Run-time assembler & support macros for the i386 math coprocessor
* Floating-point support (i386)
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
* Copyright 2008 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
@@ -24,324 +24,22 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
#ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h
/* We really must map the x87 stack onto a flat register file. In practice,
we can provide something sensible and make it work on the x86 using the
stack like a file of eight registers.
#ifndef __lightning_fp_i386_h
#define __lightning_fp_i386_h
We use six or seven registers so as to have some freedom
for floor, ceil, round, (and log, tan, atn and exp).
Not hard at all, basically play with FXCH. FXCH is mostly free,
so the generated code is not bad. Of course we special case when one
of the operands turns out to be ST0.
Here are the macros that actually do the trick. */
#define JIT_FPR_NUM 6
#define JIT_FPR(i) (i)
#define jit_fxch(rs, op) (((rs) != 0 ? FXCHr(rs) : 0), \
op, ((rs) != 0 ? FXCHr(rs) : 0))
#define jit_fp_unary(rd, s1, op) \
((rd) == (s1) ? jit_fxch ((rd), op) \
: (rd) == 0 ? (FSTPr (0), FLDr ((s1)-1), op) \
: (FLDr ((s1)), op, FSTPr ((rd))))
#define jit_fp_binary(rd, s1, s2, op, opr) \
((rd) == (s1) ? \
((s2) == 0 ? opr(0, (rd)) \
: (s2) == (s1) ? jit_fxch((rd), op(0, 0)) \
: jit_fxch((rd), op((s2), 0))) \
: (rd) == (s2) ? jit_fxch((s1), opr(0, (rd) == 0 ? (s1) : (rd))) \
: (FLDr (s1), op(0, (s2)+1), FSTPr((rd)+1)))
#define jit_addr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FADDrr,FADDrr)
#define jit_subr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FSUBrr,FSUBRrr)
#define jit_mulr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FMULrr,FMULrr)
#define jit_divr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FDIVrr,FDIVRrr)
#define jit_abs_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e1))
#define jit_negr_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e0))
#define jit_sqrt_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9fa))
/* - moves:
move FPR0 to FPR3
FST ST3
move FPR3 to FPR0
FXCH ST3
FST ST3
move FPR3 to FPR1
FLD ST1
FST ST4 Stack is rotated, so FPRn becomes STn+1 */
#define jit_movr_d(rd,s1) \
((s1) == (rd) ? 0 \
: (s1) == 0 ? FSTr ((rd)) \
: (rd) == 0 ? (FXCHr ((s1)), FSTr ((s1))) \
: (FLDr ((s1)), FSTr ((rd)+1)))
/* - loads:
load into FPR0
FSTP ST0
FLD [FUBAR]
load into FPR3
FSTP ST3 Save old st0 into destination register
FLD [FUBAR]
FXCH ST3 Get back old st0
(and similarly for immediates, using the stack) */
#define jit_movi_f(rd,immf) \
(_O (0x68), \
*((float *) _jit.x.pc) = (float) immf, \
_jit.x.uc_pc += sizeof (float), \
jit_ldr_f((rd), _ESP), \
ADDLir(4, _ESP))
union jit_double_imm {
double d;
int i[2];
};
#define jit_movi_d(rd,immd) \
(_O (0x68), \
_jit.x.uc_pc[4] = 0x68, \
((union jit_double_imm *) (_jit.x.uc_pc + 5))->d = (double) immd, \
*((int *) _jit.x.uc_pc) = ((union jit_double_imm *) (_jit.x.uc_pc + 5))->i[1], \
_jit.x.uc_pc += 9, \
jit_ldr_d((rd), _ESP), \
ADDLir(8, _ESP))
#define jit_ldi_f(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0)) \
: (FLDSm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldi_d(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), 0, 0, 0)) \
: (FLDLm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_f(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (rs), 0, 0)) \
: (FLDSm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_d(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (rs), 0, 0)) \
: (FLDLm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_f(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), (rs), 0, 0)) \
: (FLDSm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_d(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), (rs), 0, 0)) \
: (FLDLm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxr_f(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (s1), (s2), 1)) \
: (FLDSm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_ldxr_d(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (s1), (s2), 1)) \
: (FLDLm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_extr_i_d(rd, rs) (PUSHLr((rs)), \
((rd) == 0 ? (FSTPr (0), FILDLm(0, _ESP, 0, 0)) \
: (FILDLm(0, _ESP, 0, 0), FSTPr ((rd) + 1))), \
POPLr((rs)))
#define jit_stxi_f(id, rd, rs) jit_fxch ((rs), FSTSm((id), (rd), 0, 0))
#define jit_stxr_f(d1, d2, rs) jit_fxch ((rs), FSTSm(0, (d1), (d2), 1))
#define jit_stxi_d(id, rd, rs) jit_fxch ((rs), FSTLm((id), (rd), 0, 0))
#define jit_stxr_d(d1, d2, rs) jit_fxch ((rs), FSTLm(0, (d1), (d2), 1))
#define jit_sti_f(id, rs) jit_fxch ((rs), FSTSm((id), 0, 0, 0))
#define jit_str_f(rd, rs) jit_fxch ((rs), FSTSm(0, (rd), 0, 0))
#define jit_sti_d(id, rs) jit_fxch ((rs), FSTLm((id), 0, 0, 0))
#define jit_str_d(rd, rs) jit_fxch ((rs), FSTLm(0, (rd), 0, 0))
/* Assume round to near mode */
#define jit_floorr_d_i(rd, rs) \
(FLDr (rs), jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_ceilr_d_i(rd, rs) \
(FLDr (rs), jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_truncr_d_i(rd, rs) \
(FLDr (rs), jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_calc_diff(ofs) \
FISTLm(ofs, _ESP, 0, 0), \
FILDLm(ofs, _ESP, 0, 0), \
FSUBRPr(1), \
FSTPSm(4+ofs, _ESP, 0, 0) \
/* The real meat */
#define jit_floor2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
ADDLir(0x7FFFFFFF, aux), /* carry if x-round(x) < -0 */ \
SBBLir(0, rd), /* subtract 1 if carry */ \
POPLr(aux))
#define jit_ceil2(rd, aux) \
(PUSHLr(aux), \
SUBLir(8, _ESP), \
jit_calc_diff(0), \
POPLr(rd), /* floor in rd */ \
POPLr(aux), /* x-round(x) in aux */ \
TESTLrr(aux, aux), \
SETGr(jit_reg8(aux)), \
SHRLir(1, aux), \
ADCLir(0, rd), \
POPLr(aux))
/* a mingling of the two above */
#define jit_trunc2(rd, aux) \
(PUSHLr(aux), \
SUBLir(12, _ESP), \
FSTSm(0, _ESP, 0, 0), \
jit_calc_diff(4), \
POPLr(aux), \
POPLr(rd), \
TESTLrr(aux, aux), \
POPLr(aux), \
JSSm(_jit.x.pc + 11, 0, 0, 0), \
ADDLir(0x7FFFFFFF, aux), /* 6 */ \
SBBLir(0, rd), /* 3 */ \
JMPSm(_jit.x.pc + 10, 0, 0, 0), /* 2 */ \
TESTLrr(aux, aux), /* 2 */ \
SETGr(jit_reg8(aux)), /* 3 */ \
SHRLir(1, aux), /* 2 */ \
ADCLir(0, rd), /* 3 */ \
POPLr(aux))
/* the easy one */
#define jit_roundr_d_i(rd, rs) \
(PUSHLr(_EAX), \
jit_fxch ((rs), FISTPLm(0, _ESP, 0, 0)), \
POPLr((rd)))
#define jit_fp_test(d, s1, s2, n, _and, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
((d) != _EAX ? MOVLrr(_EAX, (d)) : 0), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)), \
res, \
((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0)) /* xchg */
#define jit_fp_btest(d, s1, s2, n, _and, cmp, res) \
(((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
PUSHLr(_EAX), \
FNSTSWr(_EAX), \
SHRLir(n, _EAX), \
((_and) ? ANDLir ((_and), _EAX) : 0), \
((cmp) ? CMPLir ((cmp), _AL) : 0), \
POPLr(_EAX), \
res ((d), 0, 0, 0))
#define jit_nothing_needed(x)
/* After FNSTSW we have 1 if <, 40 if =, 0 if >, 45 if unordered. Here
is how to map the values of the status word's high byte to the
conditions.
< = > unord valid values condition
gt no no yes no 0 STSW & 45 == 0
lt yes no no no 1 STSW & 45 == 1
eq no yes no no 40 STSW & 45 == 40
unord no no no yes 45 bit 2 == 1
ge no yes no no 0, 40 bit 0 == 0
unlt yes no no yes 1, 45 bit 0 == 1
ltgt yes no yes no 0, 1 bit 6 == 0
uneq no yes no yes 40, 45 bit 6 == 1
le yes yes no no 1, 40 odd parity for STSW & 41
ungt no no yes yes 0, 45 even parity for STSW & 41
unle yes yes no yes 1, 40, 45 STSW & 45 != 0
unge no yes yes yes 0, 40, 45 STSW & 45 != 1
ne yes no yes yes 0, 1, 45 STSW & 45 != 40
ord yes yes yes no 0, 1, 40 bit 2 == 0
lt, le, ungt, unge are actually computed as gt, ge, unlt, unle with
the operands swapped; it is more efficient this way. */
#define jit_gtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETZr (_AL))
#define jit_ger_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, SBBBir (-1, _AL))
#define jit_unler_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETNZr (_AL))
#define jit_unltr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, ADCBir (0, _AL))
#define jit_ltr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETZr (_AL))
#define jit_ler_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, SBBBir (-1, _AL))
#define jit_unger_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETNZr (_AL))
#define jit_ungtr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, ADCBir (0, _AL))
#define jit_eqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETEr (_AL)))
#define jit_ner_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETNEr (_AL)))
#define jit_ltgtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, SBBBir (-1, _AL))
#define jit_uneqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, ADCBir (0, _AL))
#define jit_ordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, SBBBir (-1, _AL))
#define jit_unordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, ADCBir (0, _AL))
#define jit_bgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JZm)
#define jit_bger_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JNCm)
#define jit_bunler_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
#define jit_bunltr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
#define jit_bltr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JZm)
#define jit_bler_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JNCm)
#define jit_bunger_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
#define jit_bungtr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
#define jit_beqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JZm)
#define jit_bner_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
#define jit_bltgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JNCm)
#define jit_buneqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JCm)
#define jit_bordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JNCm)
#define jit_bunordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JCm)
#define jit_getarg_f(rd, ofs) jit_ldxi_f((rd), JIT_FP,(ofs))
#define jit_getarg_d(rd, ofs) jit_ldxi_d((rd), JIT_FP,(ofs))
#define jit_pusharg_d(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jit_str_d(JIT_SP,(rs)))
#define jit_pusharg_f(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jit_str_f(JIT_SP,(rs)))
#define jit_retval_d(op1) jit_movr_d(0, (op1))
#if 0
#define jit_sin() _OO(0xd9fe) /* fsin */
#define jit_cos() _OO(0xd9ff) /* fcos */
#define jit_tan() (_OO(0xd9f2), /* fptan */ \
FSTPr(0)) /* fstp st */
#define jit_atn() (_OO(0xd9e8), /* fld1 */ \
_OO(0xd9f3)) /* fpatan */
#define jit_exp() (_OO(0xd9ea), /* fldl2e */ \
FMULPr(1), /* fmulp */ \
_OO(0xd9c0), /* fld st */ \
_OO(0xd9fc), /* frndint */ \
_OO(0xdce9), /* fsubr */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f0), /* f2xm1 */ \
_OO(0xd9e8), /* fld1 */ \
_OO(0xdec1), /* faddp */ \
_OO(0xd9fd), /* fscale */ \
FSTPr(1)) /* fstp st(1) */
#define jit_log() (_OO(0xd9ed), /* fldln2 */ \
FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f1)) /* fyl2x */
#if LIGHTNING_CROSS \
? LIGHTNING_TARGET == LIGHTNING_X86_64 \
: defined (__x86_64__)
#include "i386/fp-64.h"
#else
#include "i386/fp-32.h"
#endif
#endif /* __lightning_asm_h */
#endif /* __lightning_fp_i386_h */

View File

@@ -7,14 +7,14 @@
/***********************************************************************
*
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
* Copyright 2000, 2001, 2002, 2006 Free Software Foundation, Inc.
* Written by Paolo Bonzini.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* by the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU lightning is distributed in the hope that it will be useful, but
@@ -24,8 +24,8 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
* Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
***********************************************************************/
@@ -62,7 +62,7 @@ jit_flush_code(void *dest, void *end)
page_size = sysconf (_SC_PAGESIZE);
#endif
page = (unsigned long) dest & ~(page_size - 1);
page = (long) dest & ~(page_size - 1);
length = ((char *) end - (char *) page + page_size - 1) & ~(page_size - 1);
/* Simple-minded attempt at optimizing the common case where a single
@@ -79,7 +79,8 @@ jit_flush_code(void *dest, void *end)
/* See if we can extend the previously mprotect'ed memory area towards
lower addresses: the highest address remains the same as before. */
else if (page < prev_page && page + length <= prev_page + prev_length)
else if (page < prev_page && page + length >= prev_page
&& page + length <= prev_page + prev_length)
prev_length += prev_page - page, prev_page = page;
/* Nothing to do, replace the area. */