1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-05 06:50:21 +02:00
guile/lib/jit_x86-x87.c
pcpa 33ee2337c7 Implement the new jit_set_data interface.
* include/lightning.h, include/lightning/jit_private.h,
	lib/lightning.c: Implement the new jit_set_data() interface,
	and the new jit_get_data() helper. Like jit_set_code(),
	jit_realize() should be called before jit_set_data().
	The most common usage should be jit_set_data(JIT_DISABLE_DATA
	| JIT_DISABLE_NOTE), to force synthesize any float/double
	constant in the stack and not generate any debug information.

	* lib/jit_note.c: Minor change to debug note generation as
	now it uses an alternate temporary data buffer during constants
	and debug generation to accommodate the possibility of the user
	setting an alternate data buffer.

	* lib/jit_hppa-fpu.c, lib/jit_s390x.c, lib/jit_s390x-cpu.c,
	lib/jit_s390x-fpu.c, lib/jit_sparc.c, lib/jit_sparc-fpu.c,
	lib/jit_x86-sse.c, lib/jit_x86-x87.c: Implement jit_set_data.

	* lib/jit_hppa-sz.c, lib/jit_sparc-sz.c, lib/jit_x86-sz.c,
	lib/jit_s390x-sz.c: Update for several instructions that now
	have a different maximum length due to jit_set_data.

	* lib/jit_mips-fpu.c: Implement jit_set_data, but missing
	validation on n32 and n64 abis (and/or big endian).

	* lib/jit_mips-sz.c: Update for changes in o32.

	* lib/jit_ppc-fpu.c: Implement jit_set_data, but missing
	validation on Darwin PPC.

	* lib/jit_ppc-sz.c: Update for changes in powerpc 32 and
	64 bit.

	* lib/jit_ia64-fpu.c: Implement untested jit_set_data.

	* TODO: Add note to list ports that were not tested for the
	new jit_set_data() feature, due to no longer having access
	to them.

	* check/nodata.c: New file implementing a simple test exercising
	several different conditions created by jit_set_data().

	* check/check.nodata.sh: New file implementing a wrapper
	over the existing *.tst files, that runs all tests without
	using a data buffer for constants; only meaningful (and
	enabled) on architectures that used to store float/double
	constants on a read only data buffer.

	* configure.ac, check/Makefile.am: Update for the new test
	cases.

	* check/lightning.c: Implement the new "-d" option that
	sets an internal flag to call jit_set_data() disable
	constants and debug, that is, using only a pure code
	buffer.
2014-03-12 14:50:31 -03:00

1274 lines
38 KiB
C

/*
* Copyright (C) 2012, 2013 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.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#if PROTO
# define _ST0_REGNO 0
# define _ST1_REGNO 1
# define _ST2_REGNO 2
# define _ST3_REGNO 3
# define _ST4_REGNO 4
# define _ST5_REGNO 5
# define _ST6_REGNO 6
# define _ST7_REGNO 7
# define x87rx(code, md, rb, ri, ms) _x87rx(_jit, code, md, rb, ri, ms)
# define fldcwm(md, rb, ri, ms) x87rx(015, md, rb, ri, ms)
# define fstcwm(md, rb, ri, ms) _fstcwm(_jit, md, rb, ri, ms)
static void
_fstcwm(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
# define fldsm(md, rb, ri, ms) x87rx(010, md, rb, ri, ms)
# define fstsm(md, rb, ri, ms) x87rx(012, md, rb, ri, ms)
# define fldlm(md, rb, ri, ms) x87rx(050, md, rb, ri, ms)
# define fstlm(md, rb, ri, ms) x87rx(052, md, rb, ri, ms)
# define fisttplm(md, rb, ri, ms) x87rx(031, md, rb, ri, ms)
# define fistlm(md, rb, ri, ms) x87rx(032, md, rb, ri, ms)
# define fisttpqm(md, rb, ri, ms) x87rx(071, md, rb, ri, ms)
# define fildlm(md, rb, ri, ms) x87rx(030, md, rb,ri, ms)
# define fildqm(md, rb, ri, ms) x87rx(075, md, rb,ri, ms)
static void
_x87rx(jit_state_t*, jit_int32_t, jit_int32_t,
jit_int32_t, jit_int32_t, jit_int32_t);
# define x87ri(cc,r0) _x87ri(_jit,cc,r0)
# define fchs_() x87ri(014, 0)
# define fabs_() x87ri(014, 1)
# define fld1() x87ri(015, 0)
# define fldl2t() x87ri(015, 1)
# define fldl2e() x87ri(015, 2)
# define fldpi() x87ri(015, 3)
# define fldlg2() x87ri(015, 4)
# define fldln2() x87ri(015, 5)
# define fldz() x87ri(015, 6)
# define fsqrt_() x87ri(017, 2)
# define fldr(r0) x87ri(010, r0)
# define fxchr(r0) x87ri(011, r0)
# define fstr(r0) x87ri(052, r0)
# define fstpr(r0) x87ri(053, r0)
# define fucomir(r0) x87ri(035, r0)
# define fucomipr(r0) x87ri(075, r0)
static void _x87ri(jit_state_t*, jit_int32_t, jit_int32_t);
# define faddr(r0, r1) x87rri(000, r0, r1)
# define fmulr(r0, r1) x87rri(001, r0, r1)
# define fsubr(r0, r1) x87rri(004, r0, r1)
# define fsubrr(r0, r1) x87rri(005, r0, r1)
# define fdivr(r0, r1) x87rri(006, r0, r1)
# define fdivrr(r0, r1) x87rri(007, r0, r1)
# define x87rri(cc, r0, r1) _x87rri(_jit, cc, r0, r1)
static void _x87rri(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_addr_f(r0, r1, r2) _x87_addr_d(_jit, r0, r1, r2)
# define x87_addi_f(r0, r1, i0) _x87_addi_f(_jit, r0, r1, i0)
static void _x87_addi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_addr_d(r0, r1, r2) _x87_addr_d(_jit, r0, r1, r2)
static void _x87_addr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_addi_d(r0, r1, i0) _x87_addi_d(_jit, r0, r1, i0)
static void _x87_addi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_subr_f(r0, r1, r2) _x87_subr_d(_jit, r0, r1, r2)
# define x87_subi_f(r0, r1, i0) _x87_subi_f(_jit, r0, r1, i0)
static void _x87_subi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_subr_d(r0, r1, r2) _x87_subr_d(_jit, r0, r1, r2)
static void _x87_subr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_subi_d(r0, r1, i0) _x87_subi_d(_jit, r0, r1, i0)
static void _x87_subi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_mulr_f(r0, r1, r2) _x87_mulr_d(_jit, r0, r1, r2)
# define x87_muli_f(r0, r1, i0) _x87_muli_f(_jit, r0, r1, i0)
static void _x87_muli_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_mulr_d(r0, r1, r2) _x87_mulr_d(_jit, r0, r1, r2)
static void _x87_mulr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_muli_d(r0, r1, i0) _x87_muli_d(_jit, r0, r1, i0)
static void _x87_muli_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_divr_f(r0, r1, r2) _x87_divr_d(_jit, r0, r1, r2)
# define x87_divi_f(r0, r1, i0) _x87_divi_f(_jit, r0, r1, i0)
static void _x87_divi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_divr_d(r0, r1, r2) _x87_divr_d(_jit, r0, r1, r2)
static void _x87_divr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_divi_d(r0, r1, i0) _x87_divi_d(_jit, r0, r1, i0)
static void _x87_divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_absr_f(r0, r1) _x87_absr_d(_jit, r0, r1)
# define x87_absr_d(r0, r1) _x87_absr_d(_jit, r0, r1)
static void _x87_absr_d(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87_negr_f(r0, r1) _x87_negr_d(_jit, r0, r1)
# define x87_negr_d(r0, r1) _x87_negr_d(_jit, r0, r1)
static void _x87_negr_d(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87_sqrtr_f(r0, r1) _x87_sqrtr_d(_jit, r0, r1)
# define x87_sqrtr_d(r0, r1) _x87_sqrtr_d(_jit, r0, r1)
static void _x87_sqrtr_d(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87_truncr_f_i(r0, r1) _x87_truncr_d_i(_jit, r0, r1)
# define x87_truncr_d_i(r0, r1) _x87_truncr_d_i(_jit, r0, r1)
static void _x87_truncr_d_i(jit_state_t*, jit_int32_t, jit_int32_t);
# if __WORDSIZE == 64
# define x87_truncr_f_l(r0, r1) _x87_truncr_d_l(_jit, r0, r1)
# define x87_truncr_d_l(r0, r1) _x87_truncr_d_l(_jit, r0, r1)
static void _x87_truncr_d_l(jit_state_t*, jit_int32_t, jit_int32_t);
# endif
# define x87_extr_f(r0, r1) _x87_extr_d(_jit, r0, r1)
# define x87_extr_d(r0, r1) _x87_extr_d(_jit, r0, r1)
# define x87_extr_f_d(r0, r1) x87_movr_d(r0, r1)
# define x87_extr_d_f(r0, r1) x87_movr_d(r0, r1)
static void _x87_extr_d(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87cmp(code, r0, r1, r2) _x87cmp(_jit, code, r0, r1, r2)
static void
_x87cmp(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87cmp2(code, r0, r1, r2) _x87cmp2(_jit, code, r0, r1, r2)
static void
_x87cmp2(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87jcc(code, i0, r0, r1) _x87jcc(_jit, code, i0, r0, r1)
static jit_word_t
_x87jcc(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
# define x87jcc2(code, i0, r0, r1) _x87jcc2(_jit, code, i0, r0, r1)
static jit_word_t
_x87jcc2(jit_state_t*, jit_int32_t, jit_word_t, jit_int32_t, jit_int32_t);
#define x87_movi_f(r0,i0) _x87_movi_f(_jit,r0,i0)
static void _x87_movi_f(jit_state_t*, jit_int32_t, jit_float32_t*);
# define x87_ldr_f(r0, r1) _x87_ldr_f(_jit, r0, r1)
static void _x87_ldr_f(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87_ldi_f(r0, i0) _x87_ldi_f(_jit, r0, i0)
static void _x87_ldi_f(jit_state_t*, jit_int32_t, jit_word_t);
# define x87_ldxr_f(r0, r1, r2) _x87_ldxr_f(_jit, r0, r1, r2)
static void _x87_ldxr_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_ldxi_f(r0, r1, i0) _x87_ldxi_f(_jit, r0, r1, i0)
static void _x87_ldxi_f(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
# define x87_str_f(r0, r1) _x87_str_f(_jit, r0, r1)
static void _x87_str_f(jit_state_t*,jit_int32_t,jit_int32_t);
# define x87_sti_f(i0, r0) _x87_sti_f(_jit, i0, r0)
static void _x87_sti_f(jit_state_t*,jit_word_t, jit_int32_t);
# define x87_stxr_f(r0, r1, r2) _x87_stxr_f(_jit, r0, r1, r2)
static void _x87_stxr_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define x87_stxi_f(i0, r0, r1) _x87_stxi_f(_jit, i0, r0, r1)
static void _x87_stxi_f(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define x87_ltr_f(r0, r1, r2) x87cmp(X86_CC_A, r0, r2, r1)
# define x87_lti_f(r0, r1, i0) _x87_lti_f(_jit, r0, r1, i0)
static void _x87_lti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ler_f(r0, r1, r2) x87cmp(X86_CC_AE, r0, r2, r1)
# define x87_lei_f(r0, r1, i0) _x87_lei_f(_jit, r0, r1, i0)
static void _x87_lei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_eqr_f(r0, r1, r2) x87_eqr_d(r0, r2, r1)
# define x87_eqi_f(r0, r1, i0) _x87_eqi_f(_jit, r0, r1, i0)
static void _x87_eqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ger_f(r0, r1, r2) x87cmp(X86_CC_AE, r0, r1, r2)
# define x87_gei_f(r0, r1, i0) _x87_gei_f(_jit, r0, r1, i0)
static void _x87_gei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_gtr_f(r0, r1, r2) x87cmp(X86_CC_A, r0, r1, r2)
# define x87_gti_f(r0, r1, i0) _x87_gti_f(_jit, r0, r1, i0)
static void _x87_gti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ner_f(r0, r1, r2) x87_ner_d(r0, r2, r1)
# define x87_nei_f(r0, r1, i0) _x87_nei_f(_jit, r0, r1, i0)
static void _x87_nei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_unltr_f(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r1, r2)
# define x87_unlti_f(r0, r1, i0) _x87_unlti_f(_jit, r0, r1, i0)
static void _x87_unlti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_unler_f(r0, r1, r2) x87cmp(X86_CC_NA, r0, r1, r2)
# define x87_unlei_f(r0, r1, i0) _x87_unlei_f(_jit, r0, r1, i0)
static void _x87_unlei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_uneqr_f(r0, r1, r2) x87cmp2(X86_CC_E, r0, r1, r2)
# define x87_uneqi_f(r0, r1, i0) _x87_uneqi_f(_jit, r0, r1, i0)
static void _x87_uneqi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_unger_f(r0, r1, r2) x87cmp(X86_CC_NA, r0, r2, r1)
# define x87_ungei_f(r0, r1, i0) _x87_ungei_f(_jit, r0, r1, i0)
static void _x87_ungei_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ungtr_f(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r2, r1)
# define x87_ungti_f(r0, r1, i0) _x87_ungti_f(_jit, r0, r1, i0)
static void _x87_ungti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ltgtr_f(r0, r1, r2) x87_ltgtr_d(r0, r1, r2)
# define x87_ltgti_f(r0, r1, i0) _x87_ltgti_f(_jit, r0, r1, i0)
static void _x87_ltgti_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ordr_f(r0, r1, r2) x87cmp2(X86_CC_NP, r0, r2, r1)
# define x87_ordi_f(r0, r1, i0) _x87_ordi_f(_jit, r0, r1, i0)
static void _x87_ordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_unordr_f(r0, r1, r2) x87cmp2(X86_CC_P, r0, r2, r1)
# define x87_unordi_f(r0, r1, i0) _x87_unordi_f(_jit, r0, r1, i0)
static void _x87_unordi_f(jit_state_t*,jit_int32_t,jit_int32_t,jit_float32_t*);
# define x87_ltr_d(r0, r1, r2) x87cmp(X86_CC_A, r0, r2, r1)
# define x87_lti_d(r0, r1, i0) _x87_lti_d(_jit, r0, r1, i0)
static void _x87_lti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ler_d(r0, r1, r2) x87cmp(X86_CC_AE, r0, r2, r1)
# define x87_lei_d(r0, r1, i0) _x87_lei_d(_jit, r0, r1, i0)
static void _x87_lei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_eqr_d(r0, r1, r2) _x87_eqr_d(_jit, r0, r2, r1)
static void _x87_eqr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_eqi_d(r0, r1, i0) _x87_eqi_d(_jit, r0, r1, i0)
static void _x87_eqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ger_d(r0, r1, r2) x87cmp(X86_CC_AE, r0, r1, r2)
# define x87_gei_d(r0, r1, i0) _x87_gei_d(_jit, r0, r1, i0)
static void _x87_gei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_gtr_d(r0, r1, r2) x87cmp(X86_CC_A, r0, r1, r2)
# define x87_gti_d(r0, r1, i0) _x87_gti_d(_jit, r0, r1, i0)
static void _x87_gti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ner_d(r0, r1, r2) _x87_ner_d(_jit, r0, r2, r1)
static void _x87_ner_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_nei_d(r0, r1, i0) _x87_nei_d(_jit, r0, r1, i0)
static void _x87_nei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_unltr_d(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r1, r2)
# define x87_unlti_d(r0, r1, i0) _x87_unlti_d(_jit, r0, r1, i0)
static void _x87_unlti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_unler_d(r0, r1, r2) x87cmp(X86_CC_NA, r0, r1, r2)
# define x87_unlei_d(r0, r1, i0) _x87_unlei_d(_jit, r0, r1, i0)
static void _x87_unlei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_uneqr_d(r0, r1, r2) x87cmp2(X86_CC_E, r0, r1, r2)
# define x87_uneqi_d(r0, r1, i0) _x87_uneqi_d(_jit, r0, r1, i0)
static void _x87_uneqi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_unger_d(r0, r1, r2) x87cmp(X86_CC_NA, r0, r2, r1)
# define x87_ungei_d(r0, r1, i0) _x87_ungei_d(_jit, r0, r1, i0)
static void _x87_ungei_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ungtr_d(r0, r1, r2) x87cmp(X86_CC_NAE, r0, r2, r1)
# define x87_ungti_d(r0, r1, i0) _x87_ungti_d(_jit, r0, r1, i0)
static void _x87_ungti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ltgtr_d(r0, r1, r2) _x87_ltgtr_d(_jit, r0, r1, r2)
static void _x87_ltgtr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_ltgti_d(r0, r1, i0) _x87_ltgti_d(_jit, r0, r1, i0)
static void _x87_ltgti_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_ordr_d(r0, r1, r2) x87cmp2(X86_CC_NP, r0, r2, r1)
# define x87_ordi_d(r0, r1, i0) _x87_ordi_d(_jit, r0, r1, i0)
static void _x87_ordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define x87_unordr_d(r0, r1, r2) x87cmp2(X86_CC_P, r0, r2, r1)
# define x87_unordi_d(r0, r1, i0) _x87_unordi_d(_jit, r0, r1, i0)
static void _x87_unordi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
#define x87_movr_f(r0,r1) _x87_movr_d(_jit,r0,r1)
#define x87_movr_d(r0,r1) _x87_movr_d(_jit,r0,r1)
static void _x87_movr_d(jit_state_t*, jit_int32_t, jit_int32_t);
#define x87_movi_d(r0,i0) _x87_movi_d(_jit,r0,i0)
static void _x87_movi_d(jit_state_t*, jit_int32_t, jit_float64_t*);
# define x87_ldr_d(r0, r1) _x87_ldr_d(_jit, r0, r1)
static void _x87_ldr_d(jit_state_t*, jit_int32_t, jit_int32_t);
# define x87_ldi_d(r0, i0) _x87_ldi_d(_jit, r0, i0)
static void _x87_ldi_d(jit_state_t*, jit_int32_t, jit_word_t);
# define x87_ldxr_d(r0, r1, r2) _x87_ldxr_d(_jit, r0, r1, r2)
static void _x87_ldxr_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_int32_t);
# define x87_ldxi_d(r0, r1, i0) _x87_ldxi_d(_jit, r0, r1, i0)
static void _x87_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
# define x87_str_d(r0, r1) _x87_str_d(_jit, r0, r1)
static void _x87_str_d(jit_state_t*,jit_int32_t,jit_int32_t);
# define x87_sti_d(i0, r0) _x87_sti_d(_jit, i0, r0)
static void _x87_sti_d(jit_state_t*,jit_word_t,jit_int32_t);
# define x87_stxr_d(r0, r1, r2) _x87_stxr_d(_jit, r0, r1, r2)
static void _x87_stxr_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define x87_stxi_d(i0, r0, r1) _x87_stxi_d(_jit, i0, r0, r1)
static void _x87_stxi_d(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define x87_bltr_f(i0, r0, r1) x87jcc(X86_CC_A, i0, r1, r0)
# define x87_blti_f(i0, r0, i1) _x87_blti_f(_jit, i0, r0, i1)
static jit_word_t
_x87_blti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bler_f(i0, r0, r1) x87jcc(X86_CC_AE, i0, r1, r0)
# define x87_blei_f(i0, r0, i1) _x87_blei_f(_jit, i0, r0, i1)
static jit_word_t
_x87_blei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_beqr_f(i0, r0, r1) _x87_beqr_d(_jit, i0, r0, r1)
# define x87_beqi_f(i0, r0, i1) _x87_beqi_f(_jit, i0, r0, i1)
static jit_word_t
_x87_beqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bger_f(i0, r0, r1) x87jcc(X86_CC_AE, i0, r0, r1)
# define x87_bgei_f(i0, r0, i1) _x87_bgei_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bgei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bgtr_f(i0, r0, r1) x87jcc(X86_CC_A, i0, r0, r1)
# define x87_bgti_f(i0, r0, i1) _x87_bgti_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bner_f(i0, r0, r1) _x87_bner_d(_jit, i0, r0, r1)
# define x87_bnei_f(i0, r0, i1) _x87_bnei_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bnei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bunltr_f(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r0, r1)
# define x87_bunlti_f(i0, r0, i1) _x87_bunlti_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bunlti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bunler_f(i0, r0, r1) x87jcc(X86_CC_NA, i0, r0, r1)
# define x87_bunlei_f(i0, r0, i1) _x87_bunlei_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bunlei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_buneqr_f(i0, r0, r1) x87jcc2(X86_CC_E, i0, r0, r1)
# define x87_buneqi_f(i0, r0, i1) _x87_buneqi_f(_jit, i0, r0, i1)
static jit_word_t
_x87_buneqi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bunger_f(i0, r0, r1) x87jcc(X86_CC_NA, i0, r1, r0)
# define x87_bungei_f(i0, r0, i1) _x87_bungei_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bungei_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bungtr_f(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r1, r0)
# define x87_bungti_f(i0, r0, i1) _x87_bungti_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bungti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bltgtr_f(i0, r0, r1) x87jcc2(X86_CC_NE, i0, r0, r1)
# define x87_bltgti_f(i0, r0, i1) _x87_bltgti_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bltgti_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bordr_f(i0, r0, r1) x87jcc2(X86_CC_NP, i0, r0, r1)
# define x87_bordi_f(i0, r0, i1) _x87_bordi_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bunordr_f(i0, r0, r1) x87jcc2(X86_CC_P, i0, r0, r1)
# define x87_bunordi_f(i0, r0, i1) _x87_bunordi_f(_jit, i0, r0, i1)
static jit_word_t
_x87_bunordi_f(jit_state_t*, jit_word_t, jit_int32_t, jit_float32_t*);
# define x87_bltr_d(i0, r0, r1) x87jcc(X86_CC_A, i0, r1, r0)
# define x87_blti_d(i0, r0, i1) _x87_blti_d(_jit, i0, r0, i1)
static jit_word_t
_x87_blti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bler_d(i0, r0, r1) x87jcc(X86_CC_AE, i0, r1, r0)
# define x87_blei_d(i0, r0, i1) _x87_blei_d(_jit, i0, r0, i1)
static jit_word_t
_x87_blei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_beqr_d(i0, r0, r1) _x87_beqr_d(_jit, i0, r0, r1)
static jit_word_t
_x87_beqr_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
# define x87_beqi_d(i0, r0, i1) _x87_beqi_d(_jit, i0, r0, i1)
static jit_word_t
_x87_beqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bger_d(i0, r0, r1) x87jcc(X86_CC_AE, i0, r0, r1)
# define x87_bgei_d(i0, r0, i1) _x87_bgei_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bgei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bgtr_d(i0, r0, r1) x87jcc(X86_CC_A, i0, r0, r1)
# define x87_bgti_d(i0, r0, i1) _x87_bgti_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bner_d(i0, r0, r1) _x87_bner_d(_jit, i0, r0, r1)
static jit_word_t
_x87_bner_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
# define x87_bnei_d(i0, r0, i1) _x87_bnei_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bnei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bunltr_d(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r0, r1)
# define x87_bunlti_d(i0, r0, i1) _x87_bunlti_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bunlti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bunler_d(i0, r0, r1) x87jcc(X86_CC_NA, i0, r0, r1)
# define x87_bunlei_d(i0, r0, i1) _x87_bunlei_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bunlei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_buneqr_d(i0, r0, r1) x87jcc2(X86_CC_E, i0, r0, r1)
# define x87_buneqi_d(i0, r0, i1) _x87_buneqi_d(_jit, i0, r0, i1)
static jit_word_t
_x87_buneqi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bunger_d(i0, r0, r1) x87jcc(X86_CC_NA, i0, r1, r0)
# define x87_bungei_d(i0, r0, i1) _x87_bungei_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bungei_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bungtr_d(i0, r0, r1) x87jcc(X86_CC_NAE, i0, r1, r0)
# define x87_bungti_d(i0, r0, i1) _x87_bungti_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bungti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bltgtr_d(i0, r0, r1) x87jcc2(X86_CC_NE, i0, r0, r1)
# define x87_bltgti_d(i0, r0, i1) _x87_bltgti_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bltgti_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bordr_d(i0, r0, r1) x87jcc2(X86_CC_NP, i0, r0, r1)
# define x87_bordi_d(i0, r0, i1) _x87_bordi_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
# define x87_bunordr_d(i0, r0, r1) x87jcc2(X86_CC_P, i0, r0, r1)
# define x87_bunordi_d(i0, r0, i1) _x87_bunordi_d(_jit, i0, r0, i1)
static jit_word_t
_x87_bunordi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_float64_t*);
#endif
#if CODE
# define fpr_opi(name, type, size) \
static void \
_x87_##name##i_##type(jit_state_t *_jit, \
jit_int32_t r0, jit_int32_t r1, \
jit_float##size##_t *i0) \
{ \
jit_int32_t reg = jit_get_reg(jit_class_fpr); \
assert(jit_x87_reg_p(reg)); \
x87_movi_##type(rn(reg), i0); \
x87_##name##r_##type(r0, r1, rn(reg)); \
jit_unget_reg(reg); \
}
# define fpr_bopi(name, type, size) \
static jit_word_t \
_x87_b##name##i_##type(jit_state_t *_jit, \
jit_word_t i0, jit_int32_t r0, \
jit_float##size##_t *i1) \
{ \
jit_word_t word; \
jit_int32_t reg = jit_get_reg(jit_class_fpr); \
assert(jit_x87_reg_p(reg)); \
x87_movi_##type(rn(reg), i1); \
word = x87_b##name##r_##type(i0, r0, rn(reg)); \
jit_unget_reg(reg); \
return (word); \
}
# define fopi(name) fpr_opi(name, f, 32)
# define fbopi(name) fpr_bopi(name, f, 32)
# define dopi(name) fpr_opi(name, d, 64)
# define dbopi(name) fpr_bopi(name, d, 64)
static void
_fstcwm(jit_state_t *_jit, jit_int32_t md,
jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
{
ic(0x9b);
rex(0, 1, rb, ri, _NOREG);
x87rx(017, md, rb, ri, ms);
}
static void
_x87rx(jit_state_t *_jit, jit_int32_t code, jit_int32_t md,
jit_int32_t rb, jit_int32_t ri, jit_int32_t ms)
{
rex(0, 1, rb, ri, _NOREG);
ic(0xd8 | (code >> 3));
rx((code & 7), md, rb, ri, ms);
}
static void
_x87ri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0)
{
ic(0xd8 | (code >> 3));
mrm(0x03, (code & 7), r0);
}
static void
_x87rri(jit_state_t *_jit, jit_int32_t code, jit_int32_t r0, jit_int32_t r1)
{
if (r1 == _ST0_REGNO)
x87ri(code | 040, r0);
else {
assert(r0 == _ST0_REGNO);
x87ri(code, r1);
}
}
fopi(add)
fopi(sub)
fopi(mul)
fopi(div)
static void
_x87_addr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r0 == r1) {
if (r2 == _ST0_REGNO)
faddr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
faddr(_ST0_REGNO, r2);
else {
fxchr(r0);
faddr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
fxchr(r0);
}
}
else if (r0 == r2) {
if (r1 == _ST0_REGNO)
faddr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
faddr(_ST0_REGNO, r1);
else {
fxchr(r0);
faddr(_ST0_REGNO, r1);
fxchr(r0);
}
}
else {
fldr(r1);
faddr(_ST0_REGNO, r2 + 1);
fstpr(r0 + 1);
}
}
dopi(add)
static void
_x87_subr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r0 == r1) {
if (r2 == _ST0_REGNO)
fsubrr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fsubr(_ST0_REGNO, r2);
else {
fxchr(r0);
fsubr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
fxchr(r0);
}
}
else if (r0 == r2) {
if (r1 == _ST0_REGNO)
fsubr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fsubrr(_ST0_REGNO, r1);
else {
fxchr(r0);
fsubrr(_ST0_REGNO, r1);
fxchr(r0);
}
}
else {
fldr(r1);
fsubr(_ST0_REGNO, r2 + 1);
fstpr(r0 + 1);
}
}
dopi(sub)
static void
_x87_mulr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r0 == r1) {
if (r2 == _ST0_REGNO)
fmulr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fmulr(_ST0_REGNO, r2);
else {
fxchr(r0);
fmulr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
fxchr(r0);
}
}
else if (r0 == r2) {
if (r1 == _ST0_REGNO)
fmulr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fmulr(_ST0_REGNO, r1);
else {
fxchr(r0);
fmulr(_ST0_REGNO, r1);
fxchr(r0);
}
}
else {
fldr(r1);
fmulr(_ST0_REGNO, r2 + 1);
fstpr(r0 + 1);
}
}
dopi(mul)
static void
_x87_divr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r0 == r1) {
if (r2 == _ST0_REGNO)
fdivrr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fdivr(_ST0_REGNO, r2);
else {
fxchr(r0);
fdivr(_ST0_REGNO, r0 == r2 ? _ST0_REGNO : r2);
fxchr(r0);
}
}
else if (r0 == r2) {
if (r1 == _ST0_REGNO)
fdivr(r0, _ST0_REGNO);
else if (r0 == _ST0_REGNO)
fsubrr(_ST0_REGNO, r1);
else {
fxchr(r0);
fdivrr(_ST0_REGNO, r1);
fxchr(r0);
}
}
else {
fldr(r1);
fdivr(_ST0_REGNO, r2 + 1);
fstpr(r0 + 1);
}
}
dopi(div)
static void
_x87_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r0 == r1) {
if (r1 == _ST0_REGNO)
fabs_();
else {
fxchr(r0);
fabs_();
fxchr(r0);
}
}
else {
fldr(r1);
fabs_();
fstpr(r0 + 1);
}
}
static void
_x87_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r0 == r1) {
if (r1 == _ST0_REGNO)
fchs_();
else {
fxchr(r0);
fchs_();
fxchr(r0);
}
}
else {
fldr(r1);
fchs_();
fstpr(r0 + 1);
}
}
static void
_x87_sqrtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r0 == r1) {
if (r1 == _ST0_REGNO)
fsqrt_();
else {
fxchr(r0);
fsqrt_();
fxchr(r0);
}
}
else {
fldr(r1);
fsqrt_();
fstpr(r0 + 1);
}
}
static void
_x87_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
#if defined(sun)
/* for the sake of passing test cases in x87 mode, otherwise only sse
* is supported */
fstcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
ldxi_s(r0, _RBP_REGNO, -4);
extr_uc(r0, r0);
# define FPCW_CHOP 0xc00
ori(r0, r0, FPCW_CHOP);
stxi_s(-8, _RBP_REGNO, r0);
fldcwm(-8, _RBP_REGNO, _NOREG, _SCL1);
if (r1 == _ST0_REGNO)
fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
else {
fxchr(r1);
fistlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
fxchr(r1);
}
fldcwm(-4, _RBP_REGNO, _NOREG, _SCL1);
ldxi(r0, _RBP_REGNO, CVT_OFFSET);
#else
fldr(r1);
fisttplm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
ldxi_i(r0, _RBP_REGNO, CVT_OFFSET);
#endif
}
# if __WORDSIZE == 64
static void
_x87_truncr_d_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
fldr(r1);
fisttpqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
ldxi(r0, _RBP_REGNO, CVT_OFFSET);
}
# endif
static void
_x87_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
stxi(CVT_OFFSET, _RBP_REGNO, r1);
# if __WORDSIZE == 32
fildlm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
# else
fildqm(CVT_OFFSET, _RBP_REGNO, _NOREG, _SCL1);
# endif
fstpr(r0 + 1);
}
static void
_x87cmp(jit_state_t *_jit, jit_int32_t code,
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_bool_t rc;
jit_int32_t reg;
if ((rc = reg8_p(r0)))
reg = r0;
else {
reg = _RAX_REGNO;
movr(r0, reg);
}
ixorr(reg, reg);
if (r1 == _ST0_REGNO)
fucomir(r2);
else {
fldr(r1);
fucomipr(r2 + 1);
}
cc(code, reg);
if (!rc)
xchgr(r0, reg);
}
static void
_x87cmp2(jit_state_t *_jit, jit_int32_t code,
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_bool_t rc;
jit_int32_t reg;
jit_int32_t f1, f2;
if (r2 == _ST0_REGNO) f1 = r2, f2 = r1;
else f1 = r1, f2 = r2;
if ((rc = reg8_p(r0)))
reg = r0;
else {
reg = _RAX_REGNO;
movr(r0, reg);
}
ixorr(reg, reg);
if (f1 == _ST0_REGNO)
fucomir(f2);
else {
fldr(f1);
fucomipr(f2 + 1);
}
cc(code, reg);
if (!rc)
xchgr(r0, reg);
}
static jit_word_t
_x87jcc(jit_state_t *_jit, jit_int32_t code,
jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
if (r0 == _ST0_REGNO)
fucomir(r1);
else {
fldr(r0);
fucomipr(r1 + 1);
}
jcc(code, i0);
return (_jit->pc.w);
}
static jit_word_t
_x87jcc2(jit_state_t *_jit, jit_int32_t code,
jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t f0, f1;
if (r1 == _ST0_REGNO) f0 = r1, f1 = r0;
else f0 = r0, f1 = r1;
if (f0 == _ST0_REGNO)
fucomir(f1);
else {
fldr(f0);
fucomipr(f1 + 1);
}
jcc(code, i0);
return (_jit->pc.w);
}
fopi(lt)
fopi(le)
fopi(eq)
fopi(ge)
fopi(gt)
fopi(ne)
fopi(unlt)
fopi(unle)
fopi(uneq)
fopi(unge)
fopi(ungt)
fopi(ltgt)
fopi(ord)
fopi(unord)
fbopi(lt)
fbopi(le)
fbopi(eq)
fbopi(ge)
fbopi(gt)
fbopi(ne)
fbopi(unlt)
fbopi(unle)
fbopi(uneq)
fbopi(unge)
fbopi(ungt)
fbopi(ltgt)
fbopi(ord)
fbopi(unord)
static void
_x87_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t *i0)
{
union {
jit_int32_t i;
jit_float32_t f;
} data;
jit_int32_t reg;
data.f = *i0;
if (data.f == 0.0 && !(data.i & 0x80000000))
fldz();
else if (data.f == 1.0)
fld1();
else if (data.f == 3.3219280948873623478703195458468f)
fldl2t();
else if (data.f == 1.4426950408889634073599246886656f)
fldl2e();
else if (data.f == 3.1415926535897932384626421096161f)
fldpi();
else if (data.f == 0.3010299956639811952137387498515f)
fldlg2();
else if (data.f == 0.6931471805599453094172323683399f)
fldln2();
else {
if (_jitc->no_data) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), data.i);
stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
jit_unget_reg(reg);
x87_ldxi_f(r0, _RBP_REGNO, CVT_OFFSET);
}
else
x87_ldi_f(r0, (jit_word_t)i0);
return;
}
fstpr(r0 + 1);
}
static void
_x87_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
fldsm(0, r1, _NOREG, _SCL1);
fstpr(r0 + 1);
}
static void
_x87_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
fldsm(i0, _NOREG, _NOREG, _SCL1);
fstpr(r0 + 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_ldr_f(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_x87_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
fldsm(0, r1, r2, _SCL1);
fstpr(r0 + 1);
}
static void
_x87_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
fldsm(i0, r1, _NOREG, _SCL1);
fstpr(r0 + 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_ldxr_f(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_x87_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r1 == _ST0_REGNO)
fstsm(0, r0, _NOREG, _SCL1);
else {
fxchr(r1);
fstsm(0, r0, _NOREG, _SCL1);
fxchr(r1);
}
}
static void
_x87_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (!can_sign_extend_int_p(i0)) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_str_f(rn(reg), r0);
jit_unget_reg(reg);
}
else if (r0 == _ST0_REGNO)
fstsm(i0, _NOREG, _NOREG, _SCL1);
else {
fxchr(r0);
fstsm(i0, _NOREG, _NOREG, _SCL1);
fxchr(r0);
}
}
static void
_x87_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r2 == _ST0_REGNO)
fstsm(0, r0, r1, _SCL1);
else {
fxchr(r2);
fstsm(0, r0, r1, _SCL1);
fxchr(r2);
}
}
static void
_x87_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (!can_sign_extend_int_p(i0)) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_stxr_f(rn(reg), r0, r1);
jit_unget_reg(reg);
}
else if (r1 == _ST0_REGNO)
fstsm(i0, r0, _NOREG, _SCL1);
else {
fxchr(r1);
fstsm(i0, r0, _NOREG, _SCL1);
fxchr(r1);
}
}
static void
_x87_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r0 != r1) {
if (r1 == _ST0)
fstr(r0);
else if (r0 == _ST0) {
fxchr(r1);
fstr(r1);
}
else {
fldr(r1);
fstpr(r0 + 1);
}
}
}
static void
_x87_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
{
union {
jit_int32_t ii[2];
jit_word_t w;
jit_float64_t d;
} data;
jit_int32_t reg;
data.d = *i0;
if (data.d == 0.0 && !(data.ii[1] & 0x80000000))
fldz();
else if (data.d == 1.0)
fld1();
else if (data.d == 3.3219280948873623478703195458468)
fldl2t();
else if (data.d == 1.4426950408889634073599246886656)
fldl2e();
else if (data.d == 3.1415926535897932384626421096161)
fldpi();
else if (data.d == 0.3010299956639811952137387498515)
fldlg2();
else if (data.d == 0.6931471805599453094172323683399)
fldln2();
else {
if (_jitc->no_data) {
reg = jit_get_reg(jit_class_gpr);
#if __WORDSIZE == 32
movi(rn(reg), data.ii[0]);
stxi_i(CVT_OFFSET, _RBP_REGNO, rn(reg));
movi(rn(reg), data.ii[1]);
stxi_i(CVT_OFFSET + 4, _RBP_REGNO, rn(reg));
#else
movi(rn(reg), data.w);
stxi_l(CVT_OFFSET, _RBP_REGNO, rn(reg));
#endif
jit_unget_reg(reg);
x87_ldxi_d(r0, _RBP_REGNO, CVT_OFFSET);
}
else
x87_ldi_d(r0, (jit_word_t)i0);
return;
}
fstpr(r0 + 1);
}
dopi(lt)
dopi(le)
static void
_x87_eqr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_bool_t rc;
jit_word_t jp_code;
jit_int32_t reg, f1, f2;
if (r2 == _ST0_REGNO) f1 = r2, f2 = r1;
else f1 = r1, f2 = r2;
if ((rc = reg8_p(r0)))
reg = r0;
else {
reg = _RAX_REGNO;
movr(r0, reg);
}
ixorr(reg, reg);
if (f1 == _ST0_REGNO)
fucomir(f2);
else {
fldr(f1);
fucomipr(f2 + 1);
}
jpes(0);
jp_code = _jit->pc.w;
cc(X86_CC_E, reg);
patch_rel_char(jp_code, _jit->pc.w);
if (!rc)
xchgr(r0, reg);
}
dopi(eq)
dopi(ge)
dopi(gt)
static void
_x87_ner_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_bool_t rc;
jit_word_t jp_code;
jit_int32_t reg, f1, f2;
if (r2 == _ST0_REGNO) f1 = r2, f2 = r1;
else f1 = r1, f2 = r2;
if ((rc = reg8_p(r0)))
reg = r0;
else {
reg = _RAX_REGNO;
movr(r0, reg);
}
imovi(reg, 1);
if (f1 == _ST0_REGNO)
fucomir(f2);
else {
fldr(f1);
fucomipr(f2 + 1);
}
jpes(0);
jp_code = _jit->pc.w;
cc(X86_CC_NE, reg);
patch_rel_char(jp_code, _jit->pc.w);
if (!rc)
xchgr(r0, reg);
}
dopi(ne)
dopi(unlt)
dopi(unle)
dopi(uneq)
dopi(unge)
dopi(ungt)
static void
_x87_ltgtr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r1 == r2)
movi(r0, 1);
else
x87cmp2(X86_CC_NE, r0, r1, r2);
}
dopi(ltgt)
dopi(ord)
dopi(unord)
static void
_x87_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
fldlm(0, r1, _NOREG, _SCL1);
fstpr(r0 + 1);
}
static void
_x87_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
fldlm(i0, _NOREG, _NOREG, _SCL1);
fstpr(r0 + 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_ldr_d(r0, rn(reg));
jit_unget_reg(reg);
}
}
static void
_x87_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
fldlm(0, r1, r2, _SCL1);
fstpr(r0 + 1);
}
static void
_x87_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
fldlm(i0, r1, _NOREG, _SCL1);
fstpr(r0 + 1);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_ldxr_d(r0, r1, rn(reg));
jit_unget_reg(reg);
}
}
static void
_x87_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (r1 == _ST0_REGNO)
fstlm(0, r0, _NOREG, _SCL1);
else {
fxchr(r1);
fstlm(0, r0, _NOREG, _SCL1);
fxchr(r1);
}
}
static void
_x87_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (!can_sign_extend_int_p(i0)) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_str_d(rn(reg), r0);
jit_unget_reg(reg);
}
else if (r0 == _ST0_REGNO)
fstlm(i0, _NOREG, _NOREG, _SCL1);
else {
fxchr(r0);
fstlm(i0, _NOREG, _NOREG, _SCL1);
fxchr(r0);
}
}
static void
_x87_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (r2 == _ST0_REGNO)
fstlm(0, r0, r1, _SCL1);
else {
fxchr(r2);
fstlm(0, r0, r1, _SCL1);
fxchr(r2);
}
}
static void
_x87_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (!can_sign_extend_int_p(i0)) {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
x87_stxr_d(rn(reg), r0, r1);
jit_unget_reg(reg);
}
else if (r1 == _ST0_REGNO)
fstlm(i0, r0, _NOREG, _SCL1);
else {
fxchr(r1);
fstlm(i0, r0, _NOREG, _SCL1);
fxchr(r1);
}
}
dbopi(lt)
dbopi(le)
static jit_word_t
_x87_beqr_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t f0, f1;
jit_word_t jp_code;
if (r1 == _ST0_REGNO) f0 = r1, f1 = r0;
else f0 = r0, f1 = r1;
if (f0 == _ST0_REGNO)
fucomir(f1);
else {
fldr(f0);
fucomipr(f1 + 1);
}
jpes(0);
jp_code = _jit->pc.w;
jcc(X86_CC_E, i0);
patch_rel_char(jp_code, _jit->pc.w);
return (_jit->pc.w);
}
dbopi(eq)
dbopi(ge)
dbopi(gt)
static jit_word_t
_x87_bner_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t f0, f1;
jit_word_t jp_code;
jit_word_t jz_code;
if (r1 == _ST0_REGNO) f0 = r1, f1 = r0;
else f0 = r0, f1 = r1;
if (f0 == _ST0_REGNO)
fucomir(f1);
else {
fldr(f0);
fucomipr(f1 + 1);
}
jpes(0);
jp_code = _jit->pc.w;
jzs(0);
jz_code = _jit->pc.w;
patch_rel_char(jp_code, _jit->pc.w);
jmpi(i0);
patch_rel_char(jz_code, _jit->pc.w);
return (_jit->pc.w);
}
dbopi(ne)
dbopi(unlt)
dbopi(unle)
dbopi(uneq)
dbopi(unge)
dbopi(ungt)
dbopi(ltgt)
dbopi(ord)
dbopi(unord)
# undef fopi
# undef fbopi
# undef dopi
# undef dbopi
# undef fpr_bopi
# undef fpr_opi
#endif