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