Back to index

plt-scheme  4.2.1
fp.h
Go to the documentation of this file.
00001 /******************************** -*- C -*- ****************************
00002  *
00003  *     Run-time assembler & support macros for the i386 math coprocessor
00004  *
00005  ***********************************************************************/
00006 
00007 
00008 /***********************************************************************
00009  *
00010  * Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
00011  * Written by Paolo Bonzini.
00012  *
00013  * This file is part of GNU lightning.
00014  *
00015  * GNU lightning is free software; you can redistribute it and/or modify it
00016  * under the terms of the GNU Lesser General Public License as published
00017  * by the Free Software Foundation; either version 2.1, or (at your option)
00018  * any later version.
00019  * 
00020  * GNU lightning is distributed in the hope that it will be useful, but 
00021  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00022  * or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00023  * License for more details.
00024  * 
00025  * You should have received a copy of the GNU Lesser General Public License
00026  * along with GNU lightning; see the file COPYING.LESSER; if not, write to the
00027  * Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00028  * MA 02111-1307, USA.
00029  *
00030  ***********************************************************************/
00031 
00032 
00033 #ifndef __lightning_asm_fp_h
00034 #define __lightning_asm_fp_h
00035 
00036 /* We really must map the x87 stack onto a flat register file.  In practice,
00037    we can provide something sensible and make it work on the x86 using the
00038    stack like a file of eight registers.
00039 
00040    We use six or seven registers so as to have some freedom
00041    for floor, ceil, round, (and log, tan, atn and exp).
00042 
00043    Not hard at all, basically play with FXCH.  FXCH is mostly free,
00044    so the generated code is not bad.  Of course we special case when one
00045    of the operands turns out to be ST0.
00046 
00047    Here are the macros that actually do the trick.  */
00048 
00049 #define JIT_FPR_NUM         6
00050 #define JIT_FPR(i)          (i)
00051 
00052 #define jit_fxch(rs, op)       (((rs) != 0 ? FXCHr(rs) : (void)0),      \
00053                                 op, ((rs) != 0 ? FXCHr(rs) : (void)0))
00054 
00055 #define jit_fp_unary(rd, s1, op)                       \
00056        ((rd) == (s1) ? jit_fxch ((rd), op)             \
00057         : (rd) == 0 ? (FSTPr (0), FLDr ((s1)-1), op)   \
00058         : (FLDr ((s1)), op, FSTPr ((rd))))
00059 
00060 #define jit_fp_binary(rd, s1, s2, op, opr)             \
00061        ((rd) == (s1) ?                                 \
00062           ((s2) == 0 ? opr(0, (rd))                    \
00063            : (s2) == (s1) ? jit_fxch((rd), op(0, 0))   \
00064            : jit_fxch((rd), op((s2), 0)))              \
00065         : (rd) == (s2) ? ((s1) == 0 ? op((s1), (s2)) : jit_fxch((s2), opr((s1), 0))) \
00066         : (FLDr (s1), op(0, (s2)+1), FSTPr((rd)+1)))
00067 
00068 #define jit_addr_d(rd,s1,s2)    jit_fp_binary((rd),(s1),(s2),FADDrr,FADDrr)
00069 #define jit_subr_d(rd,s1,s2)    jit_fp_binary((rd),(s1),(s2),FSUBrr,FSUBRrr)
00070 #define jit_subrr_d(rd,s1,s2)   jit_fp_binary((rd),(s1),(s2),FSUBRrr,FSUBrr)
00071 #define jit_mulr_d(rd,s1,s2)    jit_fp_binary((rd),(s1),(s2),FMULrr,FMULrr)
00072 #define jit_divr_d(rd,s1,s2)    jit_fp_binary((rd),(s1),(s2),FDIVrr,FDIVRrr)
00073 #define jit_divrr_d(rd,s1,s2)   jit_fp_binary((rd),(s1),(s2),FDIVRrr,FDIVrr)
00074 
00075 #define jit_abs_d(rd,rs)       jit_fp_unary ((rd), (rs), _OO (0xd9e1))
00076 #define jit_negr_d(rd,rs)      jit_fp_unary ((rd), (rs), _OO (0xd9e0))
00077 #define jit_sqrt_d(rd,rs)      jit_fp_unary ((rd), (rs), _OO (0xd9fa))
00078 
00079 #define jit_addr_d_fppop(rd,s1,s2)  (FADDPr(1))
00080 #define jit_subr_d_fppop(rd,s1,s2)  (FSUBPr(1))
00081 #define jit_subrr_d_fppop(rd,s1,s2) (FSUBRPr(1))
00082 #define jit_mulr_d_fppop(rd,s1,s2)  (FMULPr(1))
00083 #define jit_divr_d_fppop(rd,s1,s2)  (FDIVPr(1))
00084 #define jit_divrr_d_fppop(rd,s1,s2) (FDIVRPr(1))
00085 #define jit_negr_d_fppop(rd,rs)     ( _OO (0xd9e0))
00086 #define jit_abs_d_fppop(rd,rs)      ( _OO (0xd9e1))
00087 
00088 /* - moves:
00089 
00090        move FPR0 to FPR3
00091               FST  ST3
00092 
00093        move FPR3 to FPR0
00094               FXCH ST3
00095               FST  ST3
00096 
00097        move FPR3 to FPR1
00098                 FLD  ST1
00099                 FST  ST4   Stack is rotated, so FPRn becomes STn+1 */
00100 
00101 #define jit_movr_d(rd,s1)                              \
00102        ((s1) == (rd) ? 0                               \
00103         : (s1) == 0 ? FSTr ((rd))                      \
00104         : (rd) == 0 ? (FXCHr ((s1)), FSTr ((s1)))      \
00105         : (FLDr ((s1)), FSTr ((rd)+1)))
00106 
00107 /* - loads:
00108 
00109        load into FPR0
00110               FSTP ST0
00111               FLD  [FUBAR]
00112 
00113        load into FPR3
00114               FSTP ST3     Save old st0 into destination register
00115               FLD  [FUBAR]
00116               FXCH ST3     Get back old st0
00117 
00118    (and similarly for immediates, using the stack) */
00119 
00120 #define jit_movi_f(rd,immf)                     \
00121         (_O (0x68),                            \
00122          *((float *) _jit.x.pc) = (float) immf, \
00123          _jit.x.uc_pc += sizeof (float),       \
00124         jit_ldr_f((rd), _ESP),                 \
00125         ADDQir(4, _ESP))
00126 
00127 union jit_double_imm {
00128   double d;
00129   int i[2];
00130 };
00131 
00132 #ifdef JIT_X86_64
00133 # define jit_double_as_long(v) (*(double *)(_jit.x.uc_pc) = v, *(long *)(_jit.x.uc_pc))
00134 # define _jit_push_d(immd) \
00135   (MOVQir(jit_double_as_long(immd), JIT_REXTMP),        \
00136    PUSHQr(JIT_REXTMP))
00137 # define FPX() (void)0 /* don't need _REX(0,0,0), apparently */
00138 #else
00139 # define _jit_push_d(immd)                                                              \
00140         (_O (0x68),                                                                    \
00141          _jit.x.uc_pc[4] = 0x68,                                                       \
00142          ((union jit_double_imm *) (_jit.x.uc_pc + 5))->d = (double) immd,             \
00143          *((int *) _jit.x.uc_pc) = ((union jit_double_imm *) (_jit.x.uc_pc + 5))->i[1],        \
00144          _jit.x.uc_pc += 9)
00145 # define FPX() ((void) 0)
00146 #endif
00147 
00148 #define jit_movi_d(rd,immd)                                                            \
00149         (_jit_push_d(immd),                                                            \
00150         jit_ldr_d((rd), _ESP),                                                         \
00151         ADDQir(8, _ESP))
00152 
00153 #define jit_movi_d_fppush(rd,immd)                                                            \
00154         (_jit_push_d(immd),                                                            \
00155         jit_ldr_d_fppush((rd), _ESP),                                                         \
00156         ADDQir(8, _ESP))
00157 
00158 #ifdef JIT_X86_64
00159 #define jit_ldi_d_fppush(rd, is)   \
00160   (MOVQrr(JIT_R0, JIT_REXTMP), \
00161    MOVQir(((long)is), JIT_R0),  \
00162    jit_ldr_d_fppush(rd, JIT_R0), \
00163    MOVQrr(JIT_REXTMP, JIT_R0))
00164 #else
00165 #define jit_ldi_f(rd, is)                              \
00166   ((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0))       \
00167    : (FLDSm((is), 0, 0, 0), FSTPr ((rd) + 1)))
00168 
00169 #define jit_ldi_d(rd, is)                              \
00170   ((rd) == 0 ? (FSTPr (0), FPX(), FLDLm((is), 0, 0, 0)) \
00171    : (FPX(), FLDLm((is), 0, 0, 0), FSTPr ((rd) + 1)))
00172 
00173 #define jit_ldi_d_fppush(rd, is) (FPX(), FLDLm((is), 0, 0, 0))
00174 #endif
00175 
00176 #define jit_ldr_f(rd, rs)                              \
00177   ((rd) == 0 ? (FSTPr (0), FPX(), FLDSm(0, (rs), 0, 0)) \
00178    : (FPX(), FLDSm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
00179 
00180 #define jit_ldr_d(rd, rs)                              \
00181   ((rd) == 0 ? (FSTPr (0), FPX(), FLDLm(0, (rs), 0, 0)) \
00182    : (FPX(), FLDLm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
00183 
00184 #define jit_ldr_d_fppush(rd, rs) (FPX(), FLDLm(0, (rs), 0, 0))
00185 
00186 #define jit_ldxi_f(rd, rs, is)                         \
00187   ((rd) == 0 ? (FSTPr (0), FPX(), FLDSm((is), (rs), 0, 0))     \
00188    : (FPX(), FLDSm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
00189 
00190 #define jit_ldxi_d(rd, rs, is)                         \
00191   ((rd) == 0 ? (FSTPr (0), FPX(), FLDLm((is), (rs), 0, 0))     \
00192    : (FPX(), FLDLm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
00193 
00194 #define jit_ldxi_d_fppush(rd, rs, is) (FPX(), FLDLm((is), (rs), 0, 0))
00195 
00196 #define jit_ldxr_f(rd, s1, s2)                         \
00197   ((rd) == 0 ? (FSTPr (0), FPX(), FLDSm(0, (s1), (s2), 1))     \
00198    : (FPX(), FLDSm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
00199 
00200 #define jit_ldxr_d(rd, s1, s2)                         \
00201   ((rd) == 0 ? (FSTPr (0), FPX(), FLDLm(0, (s1), (s2), 1))     \
00202    : (FPX(), FLDLm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
00203 
00204 #define jit_extr_i_d(rd, rs)   (PUSHLr((rs)),          \
00205   ((rd) == 0 ? (FSTPr (0), FILDLm(0, _ESP, 0, 0))      \
00206    : (FILDLm(0, _ESP, 0, 0), FSTPr ((rd) + 1))),       \
00207   POPLr((rs)))
00208 
00209 #define jit_stxi_f(id, rd, rs) jit_fxch ((rs), FPX(), FSTSm((id), (rd), 0, 0))
00210 #define jit_stxr_f(d1, d2, rs) jit_fxch ((rs), FPX(), FSTSm(0, (d1), (d2), 1))
00211 #define jit_stxi_d(id, rd, rs) jit_fxch ((rs), FPX(), FSTLm((id), (rd), 0, 0))
00212 #define jit_stxr_d(d1, d2, rs) jit_fxch ((rs), FPX(), FSTLm(0, (d1), (d2), 1))
00213 
00214 #ifdef JIT_X86_64
00215 #define jit_sti_d_fppop(is, rd)   \
00216   (MOVQrr(JIT_R0, JIT_REXTMP), \
00217    MOVQir(((long)is), JIT_R0),  \
00218    jit_str_d_fppop(JIT_R0, rd), \
00219    MOVQrr(JIT_REXTMP, JIT_R0))
00220 #else
00221 #define jit_sti_f(id, rs)      jit_fxch ((rs), FPX(), FSTSm((id), 0,    0, 0))
00222 #define jit_str_f(rd, rs)      jit_fxch ((rs), FPX(), FSTSm(0,    (rd), 0, 0))
00223 #define jit_sti_d(id, rs)      jit_fxch ((rs), FPX(), FSTLm((id), 0,    0, 0))
00224 #define jit_str_d(rd, rs)      jit_fxch ((rs), FPX(), FSTLm(0,    (rd), 0, 0))
00225 
00226 #define jit_sti_d_fppop(id, rs)      (FPX(), FSTPLm((id), 0,    0, 0))
00227 #endif
00228 #define jit_stxi_d_fppop(id, rd, rs) (FPX(), FSTPLm((id), (rd), 0, 0))
00229 
00230 #define jit_str_d_fppop(rd, rs)      (FPX(), FSTPLm(0,    (rd), 0, 0))
00231 
00232 /* Assume round to near mode */
00233 #define jit_floorr_d_i(rd, rs) \
00234        (FLDr (rs), jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)))
00235 
00236 #define jit_ceilr_d_i(rd, rs)  \
00237        (FLDr (rs), jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)))
00238 
00239 #define jit_truncr_d_i(rd, rs) \
00240        (FLDr (rs), jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)))
00241 
00242 #define jit_calc_diff(ofs)         \
00243        FISTLm(ofs, _ESP, 0, 0),    \
00244        FILDLm(ofs, _ESP, 0, 0),    \
00245        FSUBRPr(1),                 \
00246        FSTPSm(4+ofs, _ESP, 0, 0)   \
00247 
00248 /* The real meat */
00249 #define jit_floor2(rd, aux)        \
00250        (PUSHLr(aux),               \
00251        SUBLir(8, _ESP),            \
00252        jit_calc_diff(0),           \
00253        POPLr(rd),                  /* floor in rd */ \
00254        POPLr(aux),                 /* x-round(x) in aux */ \
00255        ADDLir(0x7FFFFFFF, aux),    /* carry if x-round(x) < -0 */ \
00256        SBBLir(0, rd),                     /* subtract 1 if carry */ \
00257        POPLr(aux))
00258 
00259 #define jit_ceil2(rd, aux)         \
00260        (PUSHLr(aux),               \
00261        SUBLir(8, _ESP),            \
00262        jit_calc_diff(0),           \
00263        POPLr(rd),                  /* floor in rd */ \
00264        POPLr(aux),                 /* x-round(x) in aux */ \
00265        TESTLrr(aux, aux),          \
00266        SETGr(jit_reg8(aux)),              \
00267        SHRLir(1, aux),                    \
00268        ADCLir(0, rd),                     \
00269        POPLr(aux))
00270 
00271 /* a mingling of the two above */
00272 #define jit_trunc2(rd, aux)               \
00273        (PUSHLr(aux),                      \
00274        SUBLir(12, _ESP),                  \
00275        FSTSm(0, _ESP, 0, 0),                     \
00276        jit_calc_diff(4),                  \
00277        POPLr(aux),                        \
00278        POPLr(rd),                         \
00279        TESTLrr(aux, aux),                 \
00280        POPLr(aux),                        \
00281        JSSm(_jit.x.pc + 11, 0, 0, 0),            \
00282        ADDLir(0x7FFFFFFF, aux),    /* 6 */       \
00283        SBBLir(0, rd),                     /* 3 */ \
00284        JMPSm(_jit.x.pc + 10, 0, 0, 0),    /* 2 */ \
00285        TESTLrr(aux, aux),          /* 2 */ \
00286        SETGr(jit_reg8(aux)),              /* 3 */ \
00287        SHRLir(1, aux),                    /* 2 */ \
00288        ADCLir(0, rd),                     /* 3 */ \
00289        POPLr(aux))
00290 
00291 /* the easy one */
00292 #define jit_roundr_d_i(rd, rs)                         \
00293         (PUSHLr(_EAX),                                 \
00294         jit_fxch ((rs), FISTPLm(0, _ESP, 0, 0)),       \
00295        POPLr((rd)))
00296 
00297 #define jit_fp_test(d, s1, s2, n, _and, res)           \
00298        (((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))),     \
00299         ((d) != _EAX ? MOVLrr(_EAX, (d)) : 0),                 \
00300         FNSTSWr(_EAX),                                         \
00301         SHRLir(n, _EAX),                                       \
00302         ((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)),     \
00303         res,                                                   \
00304         ((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0))     /* xchg */
00305 
00306 #define jit_fp_btest(d, s1, s2, n, _and, cmp, res)             \
00307        (((s1) == 0 ? FCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))),    \
00308         PUSHQr(_EAX),                                          \
00309         FNSTSWr(_EAX),                                         \
00310         SHRLir(n, _EAX),                                       \
00311         (void)((_and) ? ANDLir ((_and), _EAX) : 0),            \
00312         ((cmp) ? CMPLir ((cmp), _AL) : 0),                     \
00313         (void) POPQr(_EAX),                                     \
00314         res ((d), 0, 0, 0), _jit.x.pc)
00315 
00316 #define jit_fp_test_fppop(d, n, _and, res)                       \
00317        (FUCOMPPr(1),                                           \
00318         ((d) != _EAX ? MOVLrr(_EAX, (d)) : 0),                 \
00319         FNSTSWr(_EAX),                                         \
00320         SHRLir(n, _EAX),                                       \
00321         ((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)),     \
00322         res,                                                   \
00323         ((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0))     /* xchg */
00324 
00325 #define jit_fp_btest_fppop(d, n, _and, cmp, res)               \
00326        (FUCOMPPr(1),                                           \
00327         PUSHQr(_EAX),                                          \
00328         FNSTSWr(_EAX),                                         \
00329         SHRLir(n, _EAX),                                       \
00330         (void)((_and) ? ANDLir ((_and), _EAX) : 0),            \
00331         (void)((cmp) ? CMPLir ((cmp), _AL) : 0),               \
00332         POPQr(_EAX),                                           \
00333         res ((d), 0, 0, 0), _jit.x.pc)
00334 
00335 #define jit_nothing_needed(x)
00336 
00337 /* After FNSTSW we have 1 if <, 40 if =, 0 if >, 45 if unordered.  Here
00338    is how to map the values of the status word's high byte to the
00339    conditions.
00340 
00341          <     =     >     unord    valid values    condition
00342   gt     no    no    yes   no       0               STSW & 45 == 0
00343   lt     yes   no    no    no       1               STSW & 45 == 1
00344   eq     no    yes   no    no       40              STSW & 45 == 40
00345   unord  no    no    no    yes      45              bit 2 == 1
00346 
00347   ge     no    yes   no    no       0, 40           bit 0 == 0
00348   unlt   yes   no    no    yes      1, 45           bit 0 == 1
00349   ltgt   yes   no    yes   no       0, 1            bit 6 == 0
00350   uneq   no    yes   no    yes      40, 45          bit 6 == 1
00351   le     yes   yes   no    no       1, 40           odd parity for STSW & 41
00352   ungt   no    no    yes   yes      0, 45           even parity for STSW & 41
00353 
00354   unle   yes   yes   no    yes      1, 40, 45       STSW & 45 != 0
00355   unge   no    yes   yes   yes      0, 40, 45       STSW & 45 != 1
00356   ne     yes   no    yes   yes      0, 1, 45        STSW & 45 != 40
00357   ord    yes   yes   yes   no       0, 1, 40        bit 2 == 0
00358 
00359   lt, le, ungt, unge are actually computed as gt, ge, unlt, unle with
00360   the operands swapped; it is more efficient this way.  */
00361 
00362 #define jit_gtr_d(d, s1, s2)            jit_fp_test((d), (s1), (s2), 8, 0x45, SETZr (_AL))
00363 #define jit_ger_d(d, s1, s2)            jit_fp_test((d), (s1), (s2), 9, 0, SBBBir (-1, _AL))
00364 #define jit_unler_d(d, s1, s2)          jit_fp_test((d), (s1), (s2), 8, 0x45, SETNZr (_AL))
00365 #define jit_unltr_d(d, s1, s2)          jit_fp_test((d), (s1), (s2), 9, 0, ADCBir (0, _AL))
00366 #define jit_ltr_d(d, s1, s2)            jit_fp_test((d), (s2), (s1), 8, 0x45, SETZr (_AL))
00367 #define jit_ler_d(d, s1, s2)            jit_fp_test((d), (s2), (s1), 9, 0, SBBBir (-1, _AL))
00368 #define jit_unger_d(d, s1, s2)          jit_fp_test((d), (s2), (s1), 8, 0x45, SETNZr (_AL))
00369 #define jit_ungtr_d(d, s1, s2)          jit_fp_test((d), (s2), (s1), 9, 0, ADCBir (0, _AL))
00370 #define jit_eqr_d(d, s1, s2)            jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETEr (_AL)))
00371 #define jit_ner_d(d, s1, s2)            jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETNEr (_AL)))
00372 #define jit_ltgtr_d(d, s1, s2)          jit_fp_test((d), (s1), (s2), 15, 0, SBBBir (-1, _AL))
00373 #define jit_uneqr_d(d, s1, s2)          jit_fp_test((d), (s1), (s2), 15, 0, ADCBir (0, _AL))
00374 #define jit_ordr_d(d, s1, s2)           jit_fp_test((d), (s1), (s2), 11, 0, SBBBir (-1, _AL))
00375 #define jit_unordr_d(d, s1, s2)         jit_fp_test((d), (s1), (s2), 11, 0, ADCBir (0, _AL))
00376 #define jit_bgtr_d(d, s1, s2)           jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JZm)
00377 #define jit_bger_d(d, s1, s2)           jit_fp_btest((d), (s1), (s2), 9, 0, 0, JNCm)
00378 #define jit_bantigtr_d(d, s1, s2)       jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
00379 #define jit_bantiger_d(d, s1, s2)       jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
00380 #define jit_bunler_d(d, s1, s2)         jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
00381 #define jit_bunltr_d(d, s1, s2)         jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
00382 #define jit_bltr_d(d, s1, s2)           jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JZm)
00383 #define jit_bler_d(d, s1, s2)           jit_fp_btest((d), (s2), (s1), 9, 0, 0, JNCm)
00384 #define jit_bantiltr_d(d, s1, s2)       jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
00385 #define jit_bantiler_d(d, s1, s2)       jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
00386 #define jit_bunger_d(d, s1, s2)         jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
00387 #define jit_bungtr_d(d, s1, s2)         jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
00388 #define jit_beqr_d(d, s1, s2)           jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JZm)
00389 #define jit_bantieqr_d(d, s1, s2)       jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
00390 #define jit_bner_d(d, s1, s2)           jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
00391 #define jit_bltgtr_d(d, s1, s2)         jit_fp_btest((d), (s1), (s2), 15, 0, 0, JNCm)
00392 #define jit_buneqr_d(d, s1, s2)         jit_fp_btest((d), (s1), (s2), 15, 0, 0, JCm)
00393 #define jit_bordr_d(d, s1, s2)          jit_fp_btest((d), (s1), (s2), 11, 0, 0, JNCm)
00394 #define jit_bunordr_d(d, s1, s2)        jit_fp_btest((d), (s1), (s2), 11, 0, 0, JCm)
00395 
00396 #define jit_bger_d_fppop(d, s1, s2)       jit_fp_btest_fppop((d), 9, 0, 0, JNCm)
00397 #define jit_bantiger_d_fppop(d, s1, s2)   jit_fp_btest_fppop((d), 9, 0, 0, JCm)
00398 #define jit_bler_d_fppop(d, s1, s2)       (FXCHr(1), jit_bger_d_fppop(d, s1, s2))
00399 #define jit_bantiler_d_fppop(d, s1, s2)   (FXCHr(1), jit_bantiger_d_fppop(d, s1, s2))
00400 
00401 #define jit_bgtr_d_fppop(d, s1, s2)       jit_fp_btest_fppop((d), 8, 0x45, 0, JZm)
00402 #define jit_bantigtr_d_fppop(d, s1, s2)   jit_fp_btest_fppop((d), 8, 0x45, 0, JNZm)
00403 #define jit_bltr_d_fppop(d, s1, s2)       (FXCHr(1), jit_bgtr_d_fppop(d, s1, s2))
00404 #define jit_bantiltr_d_fppop(d, s1, s2)   (FXCHr(1), jit_bantigtr_d_fppop(d, s1, s2))
00405 
00406 #define jit_beqr_d_fppop(d, s1, s2)       jit_fp_btest_fppop((d), 8, 0x45, 0x40, JZm)
00407 #define jit_bantieqr_d_fppop(d, s1, s2)   jit_fp_btest_fppop((d), 8, 0x45, 0x40, JNZm)
00408 
00409 #define jit_getarg_f(rd, ofs)        jit_ldxi_f((rd), JIT_FP,(ofs))
00410 #define jit_getarg_d(rd, ofs)        jit_ldxi_d((rd), JIT_FP,(ofs))
00411 #define jit_pusharg_d(rs)            (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jit_str_d(JIT_SP,(rs)))
00412 #define jit_pusharg_f(rs)            (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jit_str_f(JIT_SP,(rs)))
00413 #define jit_retval_d(op1)            jit_movr_d(0, (op1))
00414 
00415 
00416 #if 0
00417 #define jit_sin()    _OO(0xd9fe)                 /* fsin */
00418 #define jit_cos()    _OO(0xd9ff)                 /* fcos */
00419 #define jit_tan()    (_OO(0xd9f2),                      /* fptan */ \
00420                       FSTPr(0))                  /* fstp st */
00421 #define jit_atn()    (_OO(0xd9e8),                      /* fld1 */ \
00422                       _OO(0xd9f3))               /* fpatan */
00423 #define jit_exp()    (_OO(0xd9ea),                      /* fldl2e */ \
00424                       FMULPr(1),                 /* fmulp */ \
00425                       _OO(0xd9c0),               /* fld st */ \
00426                       _OO(0xd9fc),               /* frndint */ \
00427                       _OO(0xdce9),                      /* fsubr */ \
00428                       FXCHr(1),                  /* fxch st(1) */ \
00429                       _OO(0xd9f0),                      /* f2xm1 */ \
00430                       _OO(0xd9e8),                      /* fld1 */ \
00431                       _OO(0xdec1),                      /* faddp */ \
00432                       _OO(0xd9fd),                      /* fscale */ \
00433                       FSTPr(1))                  /* fstp st(1) */
00434 #define jit_log()    (_OO(0xd9ed),                      /* fldln2 */ \
00435                       FXCHr(1),                  /* fxch st(1) */ \
00436                       _OO(0xd9f1))               /* fyl2x */
00437 #endif
00438 
00439 #endif /* __lightning_asm_h */