206 lines
7.4 KiB
C
206 lines
7.4 KiB
C
|
/******************************** -*- C -*- ****************************
|
||
|
*
|
||
|
* Run-time assembler & support macros for the i386 math coprocessor
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
*
|
||
|
* Copyright 2000, 2001, 2002 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)
|
||
|
* 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_fp_h
|
||
|
#define __lightning_asm_fp_h
|
||
|
|
||
|
#define ESCmi(D,B,I,S,OP) _O_r_X(0xd8|(OP & 7), (OP >> 3), D,B,I,S)
|
||
|
|
||
|
#define FLDSm(D,B,I,S) ESCmi(D,B,I,S,001) /* fld m32real */
|
||
|
#define FILDLm(D,B,I,S) ESCmi(D,B,I,S,003) /* fild m32int */
|
||
|
#define FLDLm(D,B,I,S) ESCmi(D,B,I,S,005) /* fld m64real */
|
||
|
#define FILDWm(D,B,I,S) ESCmi(D,B,I,S,007) /* fild m16int */
|
||
|
#define FSTSm(D,B,I,S) ESCmi(D,B,I,S,021) /* fst m32real */
|
||
|
#define FISTLm(D,B,I,S) ESCmi(D,B,I,S,023) /* fist m32int */
|
||
|
#define FSTLm(D,B,I,S) ESCmi(D,B,I,S,025) /* fst m64real */
|
||
|
#define FISTWm(D,B,I,S) ESCmi(D,B,I,S,027) /* fist m16int */
|
||
|
#define FSTPSm(D,B,I,S) ESCmi(D,B,I,S,031) /* fstp m32real */
|
||
|
#define FISTPLm(D,B,I,S) ESCmi(D,B,I,S,033) /* fistp m32int */
|
||
|
#define FSTPLm(D,B,I,S) ESCmi(D,B,I,S,035) /* fstp m64real */
|
||
|
#define FISTPWm(D,B,I,S) ESCmi(D,B,I,S,037) /* fistp m16int */
|
||
|
#define FLDTm(D,B,I,S) ESCmi(D,B,I,S,053) /* fld m80real */
|
||
|
#define FILDQm(D,B,I,S) ESCmi(D,B,I,S,057) /* fild m64int */
|
||
|
#define FSTPTm(D,B,I,S) ESCmi(D,B,I,S,073) /* fstp m80real */
|
||
|
#define FISTPQm(D,B,I,S) ESCmi(D,B,I,S,077) /* fistp m64int */
|
||
|
|
||
|
|
||
|
#define jit_add_two(reg0) _OO(0xdec1) /* faddp */
|
||
|
#define jit_sub_two(reg0) _OO(0xdee9) /* fsubp */
|
||
|
#define jit_mul_two(reg0) _OO(0xdec9) /* fmulp */
|
||
|
#define jit_div_two(reg0) _OO(0xdef9) /* fdivp */
|
||
|
|
||
|
#define jit_abs(reg0) _OO(0xd9e1) /* fabs */
|
||
|
#define jit_sqr(reg0) _OO(0xdcc8) /* fmul st */
|
||
|
#define jit_sqrt(reg0) _OO(0xd9fa) /* fsqrt */
|
||
|
|
||
|
#define jit_exti_d(reg0, rs) (PUSHLr((rs)), FILDLm(0, _ESP, 0, 0), POPLr((rs)))
|
||
|
|
||
|
#define jit_neg(reg0) _OO(0xd9e0) /* fchs */
|
||
|
|
||
|
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1)
|
||
|
#define jit_ldxi_f(reg0, rs, is) FLDSm((is), (rs), 0, 0)
|
||
|
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1)
|
||
|
#define jit_ldxi_d(reg0, rs, is) FLDLm((is), (rs), 0, 0)
|
||
|
#define jit_ldxr_d(reg0, s1, s2) FLDLm(0, (s1), (s2), 1)
|
||
|
#define jit_ldi_f(reg0, is) FLDSm((is), 0, 0, 0)
|
||
|
#define jit_ldr_f(reg0, rs) FLDSm(0, (rs), 0, 0)
|
||
|
#define jit_ldi_d(reg0, is) FLDLm((is), 0, 0, 0)
|
||
|
#define jit_ldr_d(reg0, rs) FLDLm(0, (rs), 0, 0)
|
||
|
#define jit_stxi_f(id, rd, reg0) FSTPSm((id), (rd), 0, 0)
|
||
|
#define jit_stxr_f(d1, d2, reg0) FSTPSm(0, (d1), (d2), 1)
|
||
|
#define jit_stxi_d(id, rd, reg0) FSTPLm((id), (rd), 0, 0)
|
||
|
#define jit_stxr_d(d1, d2, reg0) FSTPLm(0, (d1), (d2), 1)
|
||
|
#define jit_sti_f(id, reg0) FSTPSm((id), 0, 0, 0)
|
||
|
#define jit_str_f(rd, reg0) FSTPSm(0, (rd), 0, 0)
|
||
|
#define jit_sti_d(id, reg0) FSTPLm((id), 0, 0, 0)
|
||
|
#define jit_str_d(rd, reg0) FSTPLm(0, (rd), 0, 0)
|
||
|
|
||
|
#define jit_fpimm(reg0, first, second) \
|
||
|
(PUSHLi(second), \
|
||
|
PUSHLi(first), \
|
||
|
FLDLm(0, _ESP, 0, 0), \
|
||
|
ADDLir(8, _ESP))
|
||
|
|
||
|
|
||
|
/* Assume round to near mode */
|
||
|
#define jit_floor(rd, reg0) \
|
||
|
jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||
|
|
||
|
#define jit_ceil(rd, reg0) \
|
||
|
jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||
|
|
||
|
#define jit_trunc(rd, reg0) \
|
||
|
jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX))
|
||
|
|
||
|
#define jit_calc_diff(ofs) \
|
||
|
FISTLm(ofs, _ESP, 0, 0), \
|
||
|
FILDLm(ofs, _ESP, 0, 0), \
|
||
|
_OO(0xdee9), /* fsubp */ \
|
||
|
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.pc + 11, 0, 0, 0), \
|
||
|
ADDLir(0x7FFFFFFF, aux), /* 6 */ \
|
||
|
SBBLir(0, rd), /* 3 */ \
|
||
|
JMPSm(_jit.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_round(rd, reg0) \
|
||
|
(PUSHLr(_EAX), \
|
||
|
FISTPLm(0, _ESP, 0, 0), \
|
||
|
POPLr((rd)))
|
||
|
|
||
|
#define jit_cmp(le, ge, reg0) ( \
|
||
|
((le) == _EAX || (ge) == _EAX ? 0 : PUSHLr(_EAX)), \
|
||
|
_OO(0xd8d0), /* fcom st(0) */ \
|
||
|
_d16(), _OO(0xdfe0), /* fnstsw ax */ \
|
||
|
TESTBir(0x40, _AH), \
|
||
|
MOVBir(0, ((le) & 15) | 0x10), \
|
||
|
MOVBir(0, ((ge) & 15) | 0x10), \
|
||
|
JZSm(_jit.pc + 12, 0, 0, 0), \
|
||
|
_OO(0xd9e4), /* ftst */ /* 2 */ \
|
||
|
_d16(), _OO(0xdfe0), /* fnstsw ax */ /* 3 */ \
|
||
|
SAHF(), /* 1 */ \
|
||
|
SETLEr( ((le) & 15) | 0x10), /* 3 */ \
|
||
|
SETGEr( ((ge) & 15) | 0x10), /* 3 */ \
|
||
|
ANDLir( 1, (le)), \
|
||
|
ANDLir( 1, (ge)), \
|
||
|
((le) == _EAX || (ge) == _EAX ? 0 : POPLr(_EAX)) )
|
||
|
|
||
|
#define jitfp_getarg_f(ofs) jitfp_ldxi_f(JIT_FP,(ofs))
|
||
|
#define jitfp_getarg_d(ofs) jitfp_ldxi_d(JIT_FP,(ofs))
|
||
|
#define jitfp_pusharg_d(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jitfp_str_d(JIT_SP,(op1)))
|
||
|
#define jitfp_pusharg_f(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jitfp_str_f(JIT_SP,(op1)))
|
||
|
#define jitfp_retval(op1) _jit_emit(&_jit, (op1), JIT_NULL, 0, 0, 0)
|
||
|
|
||
|
#ifdef JIT_TRANSCENDENTAL
|
||
|
#define jit_sin(reg0) _OO(0xd9fe) /* fsin */
|
||
|
#define jit_cos(reg0) _OO(0xd9ff) /* fcos */
|
||
|
#define jit_tan(reg0) (_OO(0xd9f2), /* fptan */ \
|
||
|
_OO(0xddd8)) /* fstp st */
|
||
|
#define jit_atn(reg0) (_OO(0xd9e8), /* fld1 */ \
|
||
|
_OO(0xd9f3)) /* fpatan */
|
||
|
#define jit_exp(reg0) (_OO(0xd9ea), /* fldl2e */ \
|
||
|
_OO(0xdec9), /* fmulp */ \
|
||
|
_OO(0xd9c0), /* fld st */ \
|
||
|
_OO(0xd9fc), /* frndint */ \
|
||
|
_OO(0xdce9), /* fsubr */ \
|
||
|
_OO(0xd9c9), /* fxch st(1) */ \
|
||
|
_OO(0xd9f0), /* f2xm1 */ \
|
||
|
_OO(0xd9e8), /* fld1 */ \
|
||
|
_OO(0xdec1), /* faddp */ \
|
||
|
_OO(0xd9fd), /* fscale */ \
|
||
|
_OO(0xddd9)) /* fstp st(1) */
|
||
|
#define jit_log(reg0) (_OO(0xd9ed), /* fldln2 */ \
|
||
|
_OO(0xd9c9), /* fxch st(1) */ \
|
||
|
_OO(0xd9f1)) /* fyl2x */
|
||
|
#endif
|
||
|
|
||
|
#endif /* __lightning_asm_h */
|