From 1daeddffa3521a15493dbbd57ea8847f09d931b1 Mon Sep 17 00:00:00 2001 From: Guenter Bartsch Date: Mon, 22 Oct 2001 00:52:09 +0000 Subject: introducing libxineutils and a this pointer for video_out_x11 callbacks CVS patchset: 852 CVS date: 2001/10/22 00:52:09 --- configure.in | 4 +- src/Makefile.am | 4 +- src/audio_out/Makefile.am | 12 +- src/demuxers/Makefile.am | 13 +- src/dxr3/Makefile.am | 2 + src/input/Makefile.am | 6 + src/liba52/Makefile.am | 1 + src/libdivx4/Makefile.am | 1 + src/libdts/Makefile.am | 1 + src/libffmpeg/Makefile.am | 2 + src/liblpcm/Makefile.am | 1 + src/libmad/Makefile.am | 1 + src/libmpeg2/Makefile.am | 1 + src/libspudec/Makefile.am | 1 + src/libvfill/Makefile.am | 1 + src/libvorbis/Makefile.am | 2 +- src/libw32dll/Makefile.am | 2 +- src/video_out/Makefile.am | 9 +- src/video_out/deinterlace.c | 37 +-- src/video_out/video_out_syncfb.c | 8 +- src/video_out/video_out_x11.h | 10 +- src/video_out/video_out_xshm.c | 20 +- src/video_out/video_out_xv.c | 14 +- src/xine-engine/Makefile.am | 28 +-- src/xine-engine/attributes.h | 27 -- src/xine-engine/cpu_accel.c | 124 --------- src/xine-engine/cpu_accel.h | 531 --------------------------------------- src/xine-engine/memcpy.c | 439 -------------------------------- src/xine-engine/memcpy.h | 33 --- src/xine-engine/monitor.c | 138 ---------- src/xine-engine/monitor.h | 114 --------- src/xine-engine/utils.c | 146 ----------- src/xine-engine/utils.h | 52 ---- src/xine-utils/Makefile.am | 82 ++++++ src/xine-utils/attributes.h | 27 ++ src/xine-utils/cpu_accel.c | 124 +++++++++ src/xine-utils/cpu_accel.h | 531 +++++++++++++++++++++++++++++++++++++++ src/xine-utils/memcpy.c | 439 ++++++++++++++++++++++++++++++++ src/xine-utils/memcpy.h | 33 +++ src/xine-utils/monitor.c | 138 ++++++++++ src/xine-utils/monitor.h | 114 +++++++++ src/xine-utils/utils.c | 146 +++++++++++ src/xine-utils/utils.h | 52 ++++ 43 files changed, 1794 insertions(+), 1677 deletions(-) delete mode 100644 src/xine-engine/attributes.h delete mode 100644 src/xine-engine/cpu_accel.c delete mode 100644 src/xine-engine/cpu_accel.h delete mode 100644 src/xine-engine/memcpy.c delete mode 100644 src/xine-engine/memcpy.h delete mode 100644 src/xine-engine/monitor.c delete mode 100644 src/xine-engine/monitor.h delete mode 100644 src/xine-engine/utils.c delete mode 100644 src/xine-engine/utils.h create mode 100644 src/xine-utils/Makefile.am create mode 100644 src/xine-utils/attributes.h create mode 100644 src/xine-utils/cpu_accel.c create mode 100644 src/xine-utils/cpu_accel.h create mode 100644 src/xine-utils/memcpy.c create mode 100644 src/xine-utils/memcpy.h create mode 100644 src/xine-utils/monitor.c create mode 100644 src/xine-utils/monitor.h create mode 100644 src/xine-utils/utils.c create mode 100644 src/xine-utils/utils.h diff --git a/configure.in b/configure.in index aca3e598e..befeeb519 100644 --- a/configure.in +++ b/configure.in @@ -690,7 +690,7 @@ fi dnl dnl Some include paths ( !!! DO NOT REMOVE !!! ) dnl -INCLUDES='-I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src -I$(top_builddir)/src -I$(top_srcdir)/src/xine-engine -I$(top_builddir)/src/xine-engine' +INCLUDES='-I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src -I$(top_builddir)/src -I$(top_srcdir)/src/xine-engine -I$(top_builddir)/src/xine-engine -I$(top_srcdir)/src/xine-utils -I$(top_builddir)/src/xine-utils' AC_SUBST(INCLUDES) @@ -746,6 +746,7 @@ src/libspudec/Makefile src/libvfill/Makefile src/libvorbis/Makefile src/libdivx4/Makefile +src/xine-utils/Makefile src/input/Makefile src/xine-engine/Makefile misc/Makefile @@ -785,3 +786,4 @@ else fi chmod +x libtool-nofpic + diff --git a/src/Makefile.am b/src/Makefile.am index 7b284b9e3..c1860a489 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ -SUBDIRS = audio_out video_out dxr3 input libmpeg2 libspudec demuxers \ +SUBDIRS = xine-utils xine-engine audio_out video_out dxr3 input libmpeg2 libspudec demuxers \ liba52 libffmpeg liblpcm libw32dll libmad libdts libvfill \ - libvorbis libdivx4 xine-engine + libvorbis libdivx4 debug: @list='$(SUBDIRS)'; for subdir in $$list; do \ diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 81401173f..07fe7e799 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -53,29 +53,31 @@ lib_LTLIBRARIES = $(oss_module) $(alsa_module) $(esd_module) $(sun_module) $(art $(alsa05_module) $(irixal_module) xineplug_ao_out_oss_la_SOURCES = audio_oss_out.c +xineplug_ao_out_oss_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa05_la_SOURCES = audio_alsa05_out.c -xineplug_ao_out_alsa05_la_LIBADD = $(ALSA_LIBS) +xineplug_ao_out_alsa05_la_LIBADD = $(ALSA_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_alsa05_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c -xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) +xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_alsa_la_LDFLAGS = -avoid-version -module xineplug_ao_out_esd_la_SOURCES = audio_esd_out.c -xineplug_ao_out_esd_la_LIBADD = $(ESD_LIBS) +xineplug_ao_out_esd_la_LIBADD = $(ESD_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_esd_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c +xineplug_ao_out_sun_la_LIBADD = $(IRIXAL_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module xineplug_ao_out_irixal_la_SOURCES = audio_irixal_out.c -xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) +xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module xineplug_ao_out_arts_la_SOURCES = audio_arts_out.c -xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) +xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module noinst_HEADERS = audio_oss_out.h audio_alsa_out.h audio_esd_out.h \ diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index 57cfac345..77b017c9a 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -21,36 +21,43 @@ lib_LTLIBRARIES = $(ogg_module) xineplug_dmx_avi.la \ xineplug_dmx_qt.la xineplug_dmx_asf.la xineplug_dmx_ogg_la_SOURCES = demux_ogg.c -xineplug_dmx_ogg_la_LIBADD = @OGG_LIBS@ +xineplug_dmx_ogg_la_LIBADD = @OGG_LIBS@ $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_ogg_la_LDFLAGS = -avoid-version -module xineplug_dmx_avi_la_SOURCES = demux_avi.c +xineplug_dmx_avi_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_avi_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_block_la_SOURCES = demux_mpeg_block.c +xineplug_dmx_mpeg_block_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la $(top_builddir)/src/xine-engine/libxine.la xineplug_dmx_mpeg_block_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_la_SOURCES = demux_mpeg.c +xineplug_dmx_mpeg_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_mpeg_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_audio_la_SOURCES = demux_mpgaudio.c -xineplug_dmx_mpeg_audio_la_LIBADD = -lm +xineplug_dmx_mpeg_audio_la_LIBADD = -lm $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_mpeg_audio_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_elem_la_SOURCES = demux_elem.c +xineplug_dmx_mpeg_elem_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_mpeg_elem_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_pes_la_SOURCES = demux_pes.c +xineplug_dmx_mpeg_pes_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_mpeg_pes_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_ts_la_SOURCES = demux_ts.c +xineplug_dmx_mpeg_ts_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_mpeg_ts_la_LDFLAGS = -avoid-version -module xineplug_dmx_qt_la_SOURCES = demux_qt.c xineplug_dmx_qt_la_LDFLAGS = -avoid-version -module -xineplug_dmx_qt_la_LIBADD = -lz +xineplug_dmx_qt_la_LIBADD = -lz $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_asf_la_SOURCES = demux_asf.c +xineplug_dmx_asf_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_dmx_asf_la_LDFLAGS = -avoid-version -module include_HEADERS = demux.h diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index 830d06cd6..a171d1fca 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -14,9 +14,11 @@ lib_LTLIBRARIES = $(dxr3_modules) xineplug_decode_dxr3_la_SOURCES = dxr3_decoder.c xineplug_decode_dxr3_la_LDFLAGS = -avoid-version -module +xineplug_decode_dxr3_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la $(top_builddir)/src/xine-engine/libxine.la xineplug_vo_out_dxr3_la_SOURCES = video_out_dxr3.c overlay.c xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module $(X_LIBS) +xineplug_vo_out_dxr3_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la include_HEADERS = dxr3_overlay.h diff --git a/src/input/Makefile.am b/src/input/Makefile.am index 470428383..c79c1d5ca 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -24,21 +24,27 @@ lib_LTLIBRARIES = xineplug_inp_file.la $(in_dvd) $(in_vcd) \ xineplug_inp_rtp.la xineplug_inp_file_la_SOURCES = input_file.c +xineplug_inp_file_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_file_la_LDFLAGS = -avoid-version -module xineplug_inp_dvd_la_SOURCES = input_dvd.c dvd_udf.c read_cache.c +xineplug_inp_dvd_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module xineplug_inp_net_la_SOURCES = input_net.c +xineplug_inp_net_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_net_la_LDFLAGS = -avoid-version -module xineplug_inp_vcd_la_SOURCES = input_vcd.c +xineplug_inp_vcd_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c +xineplug_inp_stdin_fifo_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module xineplug_inp_rtp_la_SOURCES = input_rtp.c +xineplug_inp_rtp_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module include_HEADERS = input_plugin.h diff --git a/src/liba52/Makefile.am b/src/liba52/Makefile.am index 81e457c54..ac03c97aa 100644 --- a/src/liba52/Makefile.am +++ b/src/liba52/Makefile.am @@ -12,6 +12,7 @@ xineplug_decode_a52_la_SOURCES = bitstream.c bit_allocate.c \ parse.c downmix.c imdct.c imdct_mlib.c \ xine_decoder.c xineplug_decode_a52_la_LDFLAGS = -avoid-version -module +xineplug_decode_a52_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = a52.h a52_internal.h \ bitstream.h tables.h diff --git a/src/libdivx4/Makefile.am b/src/libdivx4/Makefile.am index 7cd8b7b56..3ad16baef 100644 --- a/src/libdivx4/Makefile.am +++ b/src/libdivx4/Makefile.am @@ -12,6 +12,7 @@ lib_LTLIBRARIES = xineplug_decode_divx4.la xineplug_decode_divx4_la_SOURCES = xine_decoder.c xineplug_decode_divx4_la_LDFLAGS = -avoid-version -module +xineplug_decode_divx4_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = decore-if.h diff --git a/src/libdts/Makefile.am b/src/libdts/Makefile.am index 6e7a93629..719daac06 100644 --- a/src/libdts/Makefile.am +++ b/src/libdts/Makefile.am @@ -8,6 +8,7 @@ lib_LTLIBRARIES = xineplug_decode_dts.la xineplug_decode_dts_la_SOURCES = xine_decoder.c xineplug_decode_dts_la_LDFLAGS = -avoid-version -module +xineplug_decode_dts_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am index b180b3ba4..f4d21c7c7 100644 --- a/src/libffmpeg/Makefile.am +++ b/src/libffmpeg/Makefile.am @@ -14,6 +14,8 @@ lib_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_ff_la_SOURCES = xine_decoder.c +xineplug_decode_ff_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la + xineplug_decode_ff_la_LDFLAGS = \ $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la \ -avoid-version -module diff --git a/src/liblpcm/Makefile.am b/src/liblpcm/Makefile.am index a382669f2..2e576650f 100644 --- a/src/liblpcm/Makefile.am +++ b/src/liblpcm/Makefile.am @@ -8,6 +8,7 @@ lib_LTLIBRARIES = xineplug_decode_lpcm.la xineplug_decode_lpcm_la_SOURCES = xine_decoder.c xineplug_decode_lpcm_la_LDFLAGS = -avoid-version -module +xineplug_decode_lpcm_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = diff --git a/src/libmad/Makefile.am b/src/libmad/Makefile.am index 35843426b..d3f295a8f 100644 --- a/src/libmad/Makefile.am +++ b/src/libmad/Makefile.am @@ -11,6 +11,7 @@ xineplug_decode_mad_la_SOURCES = bit.c frame.c layer3.c timer.c \ xineplug_decode_mad_la_LDFLAGS = -avoid-version -module +xineplug_decode_mad_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = D.dat huffman.h mad.h stream.h fixed.h \ imdct_s.dat qc_table.dat synth.h bit.h frame.h layer12.h \ diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am index cf093d802..5a63a0e71 100644 --- a/src/libmpeg2/Makefile.am +++ b/src/libmpeg2/Makefile.am @@ -16,6 +16,7 @@ xineplug_decode_mpeg2_la_SOURCES = slice.c header.c stats.c idct.c \ motion_comp.c decode.c idct_mmx.c motion_comp_mmx.c \ idct_mlib.c motion_comp_mlib.c xine_decoder.c xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module +xineplug_decode_mpeg2_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = vlc.h mpeg2.h mpeg2_internal.h diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am index 9e5d8ca4b..a9246e112 100644 --- a/src/libspudec/Makefile.am +++ b/src/libspudec/Makefile.am @@ -8,6 +8,7 @@ lib_LTLIBRARIES = xineplug_decode_spu.la xineplug_decode_spu_la_SOURCES = spu.c xine_decoder.c xineplug_decode_spu_la_LDFLAGS = -avoid-version -module +xineplug_decode_spu_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la $(top_builddir)/src/xine-engine/libxine.la noinst_HEADERS = spu.h include_HEADERS = spu_decoder_api.h diff --git a/src/libvfill/Makefile.am b/src/libvfill/Makefile.am index 4548b4c72..dcfd8b886 100644 --- a/src/libvfill/Makefile.am +++ b/src/libvfill/Makefile.am @@ -10,6 +10,7 @@ libdir = $(XINE_PLUGINDIR) lib_LTLIBRARIES = xineplug_decode_vfill.la xineplug_decode_vfill_la_SOURCES = xine_decoder.c +xineplug_decode_vfill_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_decode_vfill_la_LDFLAGS = -avoid-version -module # noinst_HEADERS = diff --git a/src/libvorbis/Makefile.am b/src/libvorbis/Makefile.am index 5a581756f..70216225f 100644 --- a/src/libvorbis/Makefile.am +++ b/src/libvorbis/Makefile.am @@ -15,7 +15,7 @@ endif lib_LTLIBRARIES = $(vorbis_module) xineplug_decode_vorbis_la_SOURCES = xine_decoder.c -xineplug_decode_vorbis_la_LIBADD = @VORBIS_LIBS@ +xineplug_decode_vorbis_la_LIBADD = @VORBIS_LIBS@ $(top_builddir)/src/xine-utils/libxineutils.la xineplug_decode_vorbis_la_LDFLAGS = -avoid-version -module diff --git a/src/libw32dll/Makefile.am b/src/libw32dll/Makefile.am index 5012c03f4..83a8df279 100644 --- a/src/libw32dll/Makefile.am +++ b/src/libw32dll/Makefile.am @@ -19,7 +19,7 @@ lib_LTLIBRARIES = $(w32dll_codec) xineplug_decode_w32dll_la_SOURCES = w32codec.c xineplug_decode_w32dll_la_LDFLAGS = -avoid-version -module -xineplug_decode_w32dll_la_LIBADD = $(top_builddir)/src/libw32dll/wine/libwine.la @KSTAT_LIBS@ +xineplug_decode_w32dll_la_LIBADD = $(top_builddir)/src/libw32dll/wine/libwine.la @KSTAT_LIBS@ $(top_builddir)/src/xine-utils/libxineutils.la noinst_HEADERS = w32codec.h diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index 908d9d1e5..2d3eeab22 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -26,19 +26,20 @@ endif lib_LTLIBRARIES = $(xv_module) $(syncfb_module) $(xshm_module) $(aa_module) xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c -xineplug_vo_out_xv_la_LIBADD = $(XV_LIB) $(X_LIBS) -lXext +xineplug_vo_out_xv_la_LIBADD = $(XV_LIB) $(X_LIBS) -lXext $(top_builddir)/src/xine-utils/libxineutils.la xineplug_vo_out_xv_la_LDFLAGS = -avoid-version -module xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ alphablend.c video_out_xshm.c -xineplug_vo_out_xshm_la_LIBADD = $(X_LIBS) -lXext +xineplug_vo_out_xshm_la_LIBADD = $(X_LIBS) -lXext $(top_builddir)/src/xine-utils/libxineutils.la xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module -xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c +xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c +xineplug_vo_out_syncfb_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la xineplug_vo_out_syncfb_la_LDFLAGS = -avoid-version -module xineplug_vo_out_aa_la_SOURCES = video_out_aa.c -xineplug_vo_out_aa_la_LIBADD = $(AALIB_LIBS) +xineplug_vo_out_aa_la_LIBADD = $(AALIB_LIBS) $(top_builddir)/src/xine-utils/libxineutils.la xineplug_vo_out_aa_la_LDFLAGS = -avoid-version -module noinst_HEADERS = yuv2rgb.h video_out_syncfb.h alphablend.h deinterlace.h diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c index afdc320bb..540941c20 100644 --- a/src/video_out/deinterlace.c +++ b/src/video_out/deinterlace.c @@ -27,10 +27,11 @@ #include #include #include "xine_internal.h" -#include "cpu_accel.h" #include "deinterlace.h" #include "memcpy.h" +#include "cpu_accel.c" +#include "memcpy.c" /* DeinterlaceFieldBob algorithm @@ -329,15 +330,17 @@ static int deinterlace_weave_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], psubsw_r2r ( mm4, mm5 ); // mm5 = Oold - O psraw_i2r ( 1, mm5 ); // XXX pmullw_r2r ( mm5, mm5 ); // mm5 = (Oold - O) ^ 2 - psubusw_r2r ( mm5, mm3 ); // mm0 = TT - (Oold - O) ^ 2, or 0 if that's negative + psubusw_r2r ( mm5, mm3 ); /* mm0 = TT - (Oold - O) ^ 2, or 0 if that's negative */ paddusw_r2r ( mm3, mm7 ); // mm7 = our magic number - // Now compare the similarity totals against our threshold. The pcmpgtw - // instruction will populate the target register with a bunch of mask bits, - // filling words where the comparison is true with 1s and ones where it's - // false with 0s. A few ANDs and NOTs and an OR later, we have bobbed - // values for pixels under the similarity threshold and weaved ones for - // pixels over the threshold. + /* + * Now compare the similarity totals against our threshold. The pcmpgtw + * instruction will populate the target register with a bunch of mask bits, + * filling words where the comparison is true with 1s and ones where it's + * false with 0s. A few ANDs and NOTs and an OR later, we have bobbed + * values for pixels under the similarity threshold and weaved ones for + * pixels over the threshold. + */ pcmpgtw_m2r( *&qwThreshold, mm7 ); // mm7 = 0xffff where we're greater than the threshold, 0 elsewhere movq_r2r ( mm7, mm6 ); // mm6 = 0xffff where we're greater than the threshold, 0 elsewhere @@ -521,7 +524,7 @@ static int deinterlace_greedy_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], } } - // Copy last odd line if we're processing an Odd field. + /* Copy last odd line if we're processing an Odd field. */ if (IsOdd) { fast_memcpy(pdst + (height * 2 - 1) * LineLength, @@ -529,7 +532,7 @@ static int deinterlace_greedy_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], LineLength); } - // clear out the MMX registers ready for doing floating point again + /* clear out the MMX registers ready for doing floating point again */ emms(); #endif @@ -559,8 +562,11 @@ static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], static mmx_t Mask = {ub:{0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}}; - // copy first even line no matter what, and the first odd line if we're - // processing an odd field. + /* + * copy first even line no matter what, and the first odd line if we're + * processing an odd field. + */ + fast_memcpy(pdst, pEvenLines, LineLength); if (IsOdd) fast_memcpy(pdst + LineLength, pOddLines, LineLength); @@ -601,7 +607,7 @@ static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], } } - // Copy last odd line if we're processing an even field. + /* Copy last odd line if we're processing an even field. */ if (! IsOdd) { fast_memcpy(pdst + (height * 2 - 1) * LineLength, @@ -609,8 +615,9 @@ static void deinterlace_onefield_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], LineLength); } - // clear out the MMX registers ready for doing floating point - // again + /* clear out the MMX registers ready for doing floating point + * again + */ emms(); #endif } diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 645b9f50b..a2226db8c 100644 --- a/src/video_out/video_out_syncfb.c +++ b/src/video_out/video_out_syncfb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_syncfb.c,v 1.15 2001/10/14 23:19:59 f1rmb Exp $ + * $Id: video_out_syncfb.c,v 1.16 2001/10/22 00:52:10 guenter Exp $ * * video_out_syncfb.c, Matrox G400 video extension interface for xine * @@ -143,8 +143,11 @@ typedef struct _mga_globals { int overlay_state; + void *user_data; + /* gui callback */ - void (*request_dest_size) (int video_width, int video_height, + void (*request_dest_size) (void *user_data, + int video_width, int video_height, int *dest_x, int *dest_y, int *dest_height, int *dest_width); @@ -927,6 +930,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual) { _mga_priv.user_ratio_changed = 0 ; _mga_priv.fourcc_format = 0; _mga_priv.request_dest_size = ((x11_visual_t*) visual)->request_dest_size; + _mga_priv.user_data = ((x11_visual_t*) visual)->user_data; _window.clasped_window = 0; _display.default_screen = DefaultScreen(_mga_priv.lDisplay); diff --git a/src/video_out/video_out_x11.h b/src/video_out/video_out_x11.h index faedf511e..a98ca612b 100644 --- a/src/video_out/video_out_x11.h +++ b/src/video_out/video_out_x11.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_x11.h,v 1.7 2001/10/10 10:06:59 jkeil Exp $ + * $Id: video_out_x11.h,v 1.8 2001/10/22 00:52:10 guenter Exp $ * * structs and defines specific to all x11 related output plugins * (any x11 base xine ui should include this) @@ -52,6 +52,8 @@ typedef struct { /* drawable to display the video in/on */ Drawable d; + + void *user_data; /* * calc dest size @@ -62,7 +64,8 @@ typedef struct { * video out area, just do some calculations and return * the size */ - void (*calc_dest_size) (int video_width, int video_height, + void (*calc_dest_size) (void *user_data, + int video_width, int video_height, int *dest_width, int *dest_height); /* @@ -78,7 +81,8 @@ typedef struct { * preserving aspect ration and stuff). */ - void (*request_dest_size) (int video_width, int video_height, + void (*request_dest_size) (void *user_data, + int video_width, int video_height, int *dest_x, int *dest_y, int *dest_width, int *dest_height); diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index c46c8d75b..f6e02a773 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xshm.c,v 1.47 2001/10/20 13:40:20 miguelfreitas Exp $ + * $Id: video_out_xshm.c,v 1.48 2001/10/22 00:52:10 guenter Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -137,13 +137,17 @@ typedef struct xshm_driver_s { /* profiler */ int prof_yuv2rgb; + void *user_data; + /* gui callbacks */ - void (*request_dest_size) (int video_width, int video_height, + void (*request_dest_size) (void *user_data, + int video_width, int video_height, int *dest_x, int *dest_y, int *dest_height, int *dest_width); - void (*calc_dest_size) (int video_width, int video_height, + void (*calc_dest_size) (void *user_data, + int video_width, int video_height, int *dest_width, int *dest_height); } xshm_driver_t; @@ -445,7 +449,8 @@ static void xshm_calc_output_size (xshm_driver_t *this) { this->output_height = this->delivered_height; this->ratio_factor = 1.0; - this->calc_dest_size (this->output_width, this->output_height, + this->calc_dest_size (this->user_data, + this->output_width, this->output_height, &dest_width, &dest_height); } else { @@ -528,7 +533,8 @@ static void xshm_calc_output_size (xshm_driver_t *this) { ideal_height != this->delivered_height ) ideal_width &= ~7; - this->calc_dest_size (ideal_width, ideal_height, + this->calc_dest_size (this->user_data, + ideal_width, ideal_height, &dest_width, &dest_height); /* @@ -776,7 +782,8 @@ static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xprintf (VIDEO, "video_out_xshm: requesting dest size of %d x %d \n", frame->rgb_width, frame->rgb_height); - this->request_dest_size (frame->rgb_width, frame->rgb_height, + this->request_dest_size (this->user_data, + frame->rgb_width, frame->rgb_height, &this->dest_x, &this->dest_y, &this->gui_width, &this->gui_height); /* for fullscreen modes, clear unused areas of old video area */ @@ -1174,6 +1181,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->display_ratio = visual->display_ratio; this->request_dest_size = visual->request_dest_size; this->calc_dest_size = visual->calc_dest_size; + this->user_data = visual->user_data; this->output_width = 0; this->output_height = 0; this->output_scale_factor = 1.0; diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index cdbbcd030..30bc08e70 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xv.c,v 1.69 2001/10/15 12:20:01 jkeil Exp $ + * $Id: video_out_xv.c,v 1.70 2001/10/22 00:52:10 guenter Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -51,7 +51,6 @@ #include #include "monitor.h" -#include "utils.h" #include "video_out.h" #include "video_out_x11.h" #include "xine_internal.h" @@ -131,9 +130,12 @@ typedef struct { double display_ratio; /* given by visual parameter from init function */ + void *user_data; + /* gui callback */ - void (*request_dest_size) (int video_width, int video_height, + void (*request_dest_size) (void *user_data, + int video_width, int video_height, int *dest_x, int *dest_y, int *dest_height, int *dest_width); @@ -331,7 +333,7 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, char *data; - data = xmalloc (width * height * 3/2); + data = malloc (width * height * 3/2); image = XvCreateImage (this->display, this->xv_port, xv_format, data, width, height); @@ -605,7 +607,8 @@ static void xv_calc_format (xv_driver_t *this, * ask gui to adapt to this size */ - this->request_dest_size (ideal_width, ideal_height, + this->request_dest_size (this->user_data, + ideal_width, ideal_height, &dest_x, &dest_y, &dest_width, &dest_height); xv_adapt_to_output_area (this, dest_x, dest_y, dest_width, dest_height); @@ -1025,6 +1028,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->screen = visual->screen; this->display_ratio = visual->display_ratio; this->request_dest_size = visual->request_dest_size; + this->user_data = visual->user_data; this->output_xoffset = 0; this->output_yoffset = 0; this->output_width = 0; diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index a9dd27d7e..b04c5c736 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -5,14 +5,12 @@ CFLAGS = @GLOBAL_CFLAGS@ @THREAD_CFLAGS@ -EXTRA_DIST = cpu_accel.c - lib_LTLIBRARIES = libxine.la -libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c monitor.c \ - utils.c memcpy.c load_plugins.c video_decoder.c \ +libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ + load_plugins.c video_decoder.c \ audio_decoder.c video_out.c audio_out.c resample.c events.c lrb.c -libxine_la_LIBADD = cpu_accel.lo \ +libxine_la_LIBADD = $(top_builddir)/src/xine-utils/libxineutils.la\ $(THREAD_LIBS) \ $(DYNAMIC_LD_LIBS) \ -lm @@ -22,31 +20,11 @@ libxine_la_LDFLAGS = \ -release $(LT_RELEASE) include_HEADERS = buffer.h metronom.h configfile.h \ - monitor.h cpu_accel.h attributes.h utils.h memcpy.h \ audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ events.h lrb.h noinst_HEADERS = bswap.h -### -# Hardcoded rule: -# gcc failed to compile this with -fPIC flag -# hackish: [X] yes [ ] no -# -LIBTOOLNOFPIC = $(SHELL) $(top_builddir)/libtool-nofpic -LTCOMPILENOFPIC = $(LIBTOOLNOFPIC) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -cpu_accel.lo: cpu_accel.c - @mkdir -p .deps; touch .deps/cpu_accel.pp; \ - echo '$(LTCOMPILENOFPIC) -c $<'; \ - $(LTCOMPILENOFPIC) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp - - debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" diff --git a/src/xine-engine/attributes.h b/src/xine-engine/attributes.h deleted file mode 100644 index 8ed7aef9e..000000000 --- a/src/xine-engine/attributes.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * attributes.h - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//use gcc attribs to align critical data structures -#ifdef ATTRIBUTE_ALIGNED_MAX -#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) -#else -#define ATTR_ALIGN(align) -#endif diff --git a/src/xine-engine/cpu_accel.c b/src/xine-engine/cpu_accel.c deleted file mode 100644 index 8c28d950a..000000000 --- a/src/xine-engine/cpu_accel.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * cpu_accel.c - * Copyright (C) 1999-2001 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include - -#include "attributes.h" -#include "cpu_accel.h" - -#ifdef ARCH_X86 -static uint32_t x86_accel (void) -{ - uint32_t eax, ebx, ecx, edx; - int AMD; - uint32_t caps; - -#define cpuid(op,eax,ebx,ecx,edx) \ - asm ("cpuid" \ - : "=a" (eax), \ - "=b" (ebx), \ - "=c" (ecx), \ - "=d" (edx) \ - : "a" (op) \ - : "cc") - - - asm ("pushfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "movl %0,%1\n\t" - "xorl $0x200000,%0\n\t" - "pushl %0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - "popfl" - : "=a" (eax), - "=b" (ebx) - : - : "cc"); - - if (eax == ebx) /* no cpuid */ - return 0; - - cpuid (0x00000000, eax, ebx, ecx, edx); - if (!eax) /* vendor string only */ - return 0; - - AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); - - cpuid (0x00000001, eax, ebx, ecx, edx); - if (! (edx & 0x00800000)) /* no MMX */ - return 0; - caps = MM_ACCEL_X86_MMX; - - if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ - caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT; - - if (edx & 0x04000000) /* SSE2 */ - caps |= MM_ACCEL_X86_SSE2; - - cpuid (0x80000000, eax, ebx, ecx, edx); - if (eax < 0x80000001) /* no extended capabilities */ - return caps; - - cpuid (0x80000001, eax, ebx, ecx, edx); - - if (edx & 0x80000000) /* 3DNOW */ - caps |= MM_ACCEL_X86_3DNOW; - - if (edx & 0x40000000) /* 3DNOWEXT */ - /*caps |= MM_ACCEL_X86_???*/ ; - - if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ - caps |= MM_ACCEL_X86_MMXEXT; - - return caps; -} -#endif - -uint32_t mm_accel (void) -{ -#ifdef ARCH_X86 - static int got_accel = 0; - static uint32_t accel; - - if (!got_accel) { - got_accel = 1; - accel = x86_accel (); - } - - return accel; -#else -#ifdef HAVE_MLIB - return MM_ACCEL_MLIB; -#else - return 0; -#endif -#endif -} - -uint32_t mm_support (void) -{ - return mm_accel(); -} diff --git a/src/xine-engine/cpu_accel.h b/src/xine-engine/cpu_accel.h deleted file mode 100644 index 053c142f6..000000000 --- a/src/xine-engine/cpu_accel.h +++ /dev/null @@ -1,531 +0,0 @@ -/* - * cpu_accel.h - based on mmx.h, sse.h - * Copyright (C) 1997-1999 H. Dietz and R. Fisher - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * xine specific modifications 2001 by G. Bartsch - * - */ - -/* - * The type of an value that fits in an MMX register (note that long - * long constant values MUST be suffixed by LL and unsigned long long - * values by ULL, lest they be truncated by the compiler) - */ - -#ifndef _CPU_ACCEL_H -#define _CPU_ACCEL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "attributes.h" - -/* generic accelerations */ -#define MM_ACCEL_MLIB 0x00000001 - -/* x86 accelerations */ -#define MM_ACCEL_X86_MMX 0x80000000 -#define MM_ACCEL_X86_3DNOW 0x40000000 -#define MM_ACCEL_X86_MMXEXT 0x20000000 -#define MM_ACCEL_X86_SSE 0x10000000 -#define MM_ACCEL_X86_SSE2 0x08000000 -/* x86 compat defines */ -#define MM_MMX MM_ACCEL_X86_MMX -#define MM_3DNOW MM_ACCEL_X86_3DNOW -#define MM_MMXEXT MM_ACCEL_X86_MMXEXT -#define MM_SSE MM_ACCEL_X86_SSE -#define MM_SSE2 MM_ACCEL_X86_SSE2 - -uint32_t mm_accel (void) ; -/* uint32_t mm_support (void) ; */ - -#ifdef ARCH_X86 - -typedef union { - long long q; /* Quadword (64-bit) value */ - unsigned long long uq; /* Unsigned Quadword */ - int d[2]; /* 2 Doubleword (32-bit) values */ - unsigned int ud[2]; /* 2 Unsigned Doubleword */ - short w[4]; /* 4 Word (16-bit) values */ - unsigned short uw[4]; /* 4 Unsigned Word */ - char b[8]; /* 8 Byte (8-bit) values */ - unsigned char ub[8]; /* 8 Unsigned Byte */ - float s[2]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ - - - -#define mmx_i2r(op,imm,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (imm) ) - -#define mmx_m2r(op,mem,reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem)) - -#define mmx_r2m(op,reg,mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=X" (mem) \ - : /* nothing */ ) - -#define mmx_r2r(op,regs,regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - - -#define emms() __asm__ __volatile__ ("emms") - -#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) -#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) -#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) - -#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) -#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) -#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) - -#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) -#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) -#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) -#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) - -#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) -#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) - -#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) -#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) -#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) -#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) -#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) -#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) - -#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) -#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) -#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) -#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) - -#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) -#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) -#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) -#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) - -#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) -#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) - -#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) -#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) - -#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) -#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) -#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) -#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) -#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) -#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) - -#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) -#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) -#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) -#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) -#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) -#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) - -#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) -#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) - -#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) -#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) - -#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) -#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) - -#define por_m2r(var,reg) mmx_m2r (por, var, reg) -#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) - -#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) -#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) -#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) -#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) -#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) -#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) -#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) -#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) -#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) - -#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) -#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) -#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) -#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) -#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) -#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) - -#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) -#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) -#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) -#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) -#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) -#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) -#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) -#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) -#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) - -#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) -#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) -#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) -#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) -#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) -#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) - -#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) -#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) -#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) -#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) - -#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) -#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) -#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) -#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) - -#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) -#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) -#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) -#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) -#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) -#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) - -#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) -#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) -#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) -#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) -#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) -#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) - -#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) -#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) - - -/* 3DNOW extensions */ - -#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) -#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) - - -/* AMD MMX extensions - also available in intel SSE */ - - -#define mmx_m2ri(op,mem,reg,imm) \ - __asm__ __volatile__ (#op " %1, %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem), "X" (imm)) -#define mmx_r2ri(op,regs,regd,imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define mmx_fetch(mem,hint) \ - __asm__ __volatile__ ("prefetch" #hint " %0" \ - : /* nothing */ \ - : "X" (mem)) - - -#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) - -#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) - -#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) -#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) -#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) -#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) - -#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) - -#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) - -#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) -#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) - -#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) -#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) - -#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) -#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) - -#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) -#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) - -#define pmovmskb(mmreg,reg) \ - __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) - -#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) -#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) - -#define prefetcht0(mem) mmx_fetch (mem, t0) -#define prefetcht1(mem) mmx_fetch (mem, t1) -#define prefetcht2(mem) mmx_fetch (mem, t2) -#define prefetchnta(mem) mmx_fetch (mem, nta) - -#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) -#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) - -#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) -#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) - -#define sfence() __asm__ __volatile__ ("sfence\n\t") - -typedef union { - float sf[4]; /* Single-precision (32-bit) value */ -} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ - - -#define sse_i2r(op, imm, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2r(op, mem, reg) \ - __asm__ __volatile__ (#op " %0, %%" #reg \ - : /* nothing */ \ - : "X" (mem)) - -#define sse_r2m(op, reg, mem) \ - __asm__ __volatile__ (#op " %%" #reg ", %0" \ - : "=X" (mem) \ - : /* nothing */ ) - -#define sse_r2r(op, regs, regd) \ - __asm__ __volatile__ (#op " %" #regs ", %" #regd) - -#define sse_r2ri(op, regs, regd, imm) \ - __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ - : /* nothing */ \ - : "X" (imm) ) - -#define sse_m2ri(op, mem, reg, subop) \ - __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ - : /* nothing */ \ - : "X" (mem)) - - -#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) -#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) -#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) - -#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) - -#define movups_m2r(var, reg) sse_m2r(movups, var, reg) -#define movups_r2m(reg, var) sse_r2m(movups, reg, var) -#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) - -#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) - -#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) - -#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) -#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) - -#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) -#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) - -#define movss_m2r(var, reg) sse_m2r(movss, var, reg) -#define movss_r2m(reg, var) sse_r2m(movss, reg, var) -#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) - -#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) -#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) - -#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) -#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) - -#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) -#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) - -#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) -#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) - -#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) -#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) - -#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) -#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) - -#define movmskps(xmmreg, reg) \ - __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) - -#define addps_m2r(var, reg) sse_m2r(addps, var, reg) -#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) - -#define addss_m2r(var, reg) sse_m2r(addss, var, reg) -#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) - -#define subps_m2r(var, reg) sse_m2r(subps, var, reg) -#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) - -#define subss_m2r(var, reg) sse_m2r(subss, var, reg) -#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) - -#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) -#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) - -#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) -#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) - -#define divps_m2r(var, reg) sse_m2r(divps, var, reg) -#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) - -#define divss_m2r(var, reg) sse_m2r(divss, var, reg) -#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) - -#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) -#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) - -#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) -#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) - -#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) -#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) - -#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) -#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) - -#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) -#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) - -#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) -#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) - -#define andps_m2r(var, reg) sse_m2r(andps, var, reg) -#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) - -#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) -#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) - -#define orps_m2r(var, reg) sse_m2r(orps, var, reg) -#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) - -#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) -#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) - -#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) -#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) - -#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) -#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) - -#define minps_m2r(var, reg) sse_m2r(minps, var, reg) -#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) - -#define minss_m2r(var, reg) sse_m2r(minss, var, reg) -#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) - -#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) -#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) - -#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) -#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) - -#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) -#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) - -#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) -#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) - -#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) -#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) - -#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) -#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) - -#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) -#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) - -#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) -#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) - -#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) -#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) - -#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) -#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) - -#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) -#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) - -#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) -#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) - -#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) -#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) - -#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) -#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) - -#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) -#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) - -#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) -#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) - -#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) -#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) - -#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) -#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) - -#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) -#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) - -#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) -#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) - -#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) -#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) - -#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) -#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) - -#define fxrstor(mem) \ - __asm__ __volatile__ ("fxrstor %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define fxsave(mem) \ - __asm__ __volatile__ ("fxsave %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define stmxcsr(mem) \ - __asm__ __volatile__ ("stmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) - -#define ldmxcsr(mem) \ - __asm__ __volatile__ ("ldmxcsr %0" \ - : /* nothing */ \ - : "X" (mem)) -#endif /*ARCH_X86 */ - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/xine-engine/memcpy.c b/src/xine-engine/memcpy.c deleted file mode 100644 index 23a17059c..000000000 --- a/src/xine-engine/memcpy.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * These are the MMX/MMX2/SSE optimized versions of memcpy - * - * This code was adapted from Linux Kernel sources by Nick Kurshev to - * the mplayer program. (http://mplayer.sourceforge.net) - * - * Miguel Freitas split the #ifdefs into several specialized functions that - * are benchmarked at runtime by xine. Some original comments from Nick - * have been preserved documenting some MMX/SSE oddities. - * Also added kernel memcpy function that seems faster than glibc one. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "xine_internal.h" -#include "cpu_accel.h" - -void *(* fast_memcpy)(void *to, const void *from, size_t len); - -/* Original comments from mplayer (file: aclib.c) - This part of code was taken by me from Linux-2.4.3 and slightly modified -for MMX, MMX2, SSE instruction set. I have done it since linux uses page aligned -blocks but mplayer uses weakly ordered data and original sources can not -speedup them. Only using PREFETCHNTA and MOVNTQ together have effect! - ->From IA-32 Intel Architecture Software Developer's Manual Volume 1, - -Order Number 245470: -"10.4.6. Cacheability Control, Prefetch, and Memory Ordering Instructions" - -Data referenced by a program can be temporal (data will be used again) or -non-temporal (data will be referenced once and not reused in the immediate -future). To make efficient use of the processor's caches, it is generally -desirable to cache temporal data and not cache non-temporal data. Overloading -the processor's caches with non-temporal data is sometimes referred to as -"polluting the caches". -The non-temporal data is written to memory with Write-Combining semantics. - -The PREFETCHh instructions permits a program to load data into the processor -at a suggested cache level, so that it is closer to the processors load and -store unit when it is needed. If the data is already present in a level of -the cache hierarchy that is closer to the processor, the PREFETCHh instruction -will not result in any data movement. -But we should you PREFETCHNTA: Non-temporal data fetch data into location -close to the processor, minimizing cache pollution. - -The MOVNTQ (store quadword using non-temporal hint) instruction stores -packed integer data from an MMX register to memory, using a non-temporal hint. -The MOVNTPS (store packed single-precision floating-point values using -non-temporal hint) instruction stores packed floating-point data from an -XMM register to memory, using a non-temporal hint. - -The SFENCE (Store Fence) instruction controls write ordering by creating a -fence for memory store operations. This instruction guarantees that the results -of every store instruction that precedes the store fence in program order is -globally visible before any store instruction that follows the fence. The -SFENCE instruction provides an efficient way of ensuring ordering between -procedures that produce weakly-ordered data and procedures that consume that -data. - -If you have questions please contact with me: Nick Kurshev: nickols_k@mail.ru. -*/ - -/* mmx v.1 Note: Since we added alignment of destinition it speedups - of memory copying on PentMMX, Celeron-1 and P2 upto 12% versus - standard (non MMX-optimized) version. - Note: on K6-2+ it speedups memory copying upto 25% and - on K7 and P3 about 500% (5 times). -*/ - -#ifdef ARCH_X86 - -/* for small memory blocks (<256 bytes) this version is faster */ -#define small_memcpy(to,from,n)\ -{\ -register unsigned long int dummy;\ -__asm__ __volatile__(\ - "rep; movsb"\ - :"=&D"(to), "=&S"(from), "=&c"(dummy)\ - :"0" (to), "1" (from),"2" (n)\ - : "memory");\ -} - -/* linux kernel __memcpy (from: /include/asm/string.h) */ -static inline void * __memcpy(void * to, const void * from, size_t n) -{ -int d0, d1, d2; - - if( n < 4 ) { - small_memcpy(to,from,n); - } - else - __asm__ __volatile__( - "rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); - - return (to); -} - -#define SSE_MMREG_SIZE 16 -#define MMX_MMREG_SIZE 8 - -#define MMX1_MIN_LEN 0x800 /* 2K blocks */ -#define MIN_LEN 0x40 /* 64-byte blocks */ - -/* SSE note: i tried to move 128 bytes a time instead of 64 but it -didn't make any measureable difference. i'm using 64 for the sake of -simplicity. [MF] */ -static void * sse_memcpy(void * to, const void * from, size_t len) -{ - void *retval; - size_t i; - retval = to; - - if(len >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(SSE_MMREG_SIZE-1); - if(delta) - { - delta=SSE_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); - } - i = len >> 6; /* len/64 */ - len&=63; - if(((unsigned long)from) & 15) - /* if SRC is misaligned */ - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "movups (%0), %%xmm0\n" - "movups 16(%0), %%xmm1\n" - "movups 32(%0), %%xmm2\n" - "movups 48(%0), %%xmm3\n" - "movntps %%xmm0, (%1)\n" - "movntps %%xmm1, 16(%1)\n" - "movntps %%xmm2, 32(%1)\n" - "movntps %%xmm3, 48(%1)\n" - :: "r" (from), "r" (to) : "memory"); - ((const unsigned char *)from)+=64; - ((unsigned char *)to)+=64; - } - else - /* - Only if SRC is aligned on 16-byte boundary. - It allows to use movaps instead of movups, which required data - to be aligned or a general-protection exception (#GP) is generated. - */ - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "movaps (%0), %%xmm0\n" - "movaps 16(%0), %%xmm1\n" - "movaps 32(%0), %%xmm2\n" - "movaps 48(%0), %%xmm3\n" - "movntps %%xmm0, (%1)\n" - "movntps %%xmm1, 16(%1)\n" - "movntps %%xmm2, 32(%1)\n" - "movntps %%xmm3, 48(%1)\n" - :: "r" (from), "r" (to) : "memory"); - ((const unsigned char *)from)+=64; - ((unsigned char *)to)+=64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - /* enables to use FPU */ - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; -} - -static void * mmx_memcpy(void * to, const void * from, size_t len) -{ - void *retval; - size_t i; - retval = to; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - " prefetchnta (%0)\n" - " prefetchnta 64(%0)\n" - " prefetchnta 128(%0)\n" - " prefetchnta 192(%0)\n" - " prefetchnta 256(%0)\n" - : : "r" (from) ); - - if(len >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); - if(delta) - { - delta=MMX_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); - } - i = len >> 6; /* len/64 */ - len&=63; - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "movq (%0), %%mm0\n" - "movq 8(%0), %%mm1\n" - "movq 16(%0), %%mm2\n" - "movq 24(%0), %%mm3\n" - "movq 32(%0), %%mm4\n" - "movq 40(%0), %%mm5\n" - "movq 48(%0), %%mm6\n" - "movq 56(%0), %%mm7\n" - "movq %%mm0, (%1)\n" - "movq %%mm1, 8(%1)\n" - "movq %%mm2, 16(%1)\n" - "movq %%mm3, 24(%1)\n" - "movq %%mm4, 32(%1)\n" - "movq %%mm5, 40(%1)\n" - "movq %%mm6, 48(%1)\n" - "movq %%mm7, 56(%1)\n" - :: "r" (from), "r" (to) : "memory"); - ((const unsigned char *)from)+=64; - ((unsigned char *)to)+=64; - } - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; -} - -void * mmx2_memcpy(void * to, const void * from, size_t len) -{ - void *retval; - size_t i; - retval = to; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - " prefetchnta (%0)\n" - " prefetchnta 64(%0)\n" - " prefetchnta 128(%0)\n" - " prefetchnta 192(%0)\n" - " prefetchnta 256(%0)\n" - : : "r" (from) ); - - if(len >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); - if(delta) - { - delta=MMX_MMREG_SIZE-delta; - len -= delta; - small_memcpy(to, from, delta); - } - i = len >> 6; /* len/64 */ - len&=63; - for(; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0)\n" - "movq (%0), %%mm0\n" - "movq 8(%0), %%mm1\n" - "movq 16(%0), %%mm2\n" - "movq 24(%0), %%mm3\n" - "movq 32(%0), %%mm4\n" - "movq 40(%0), %%mm5\n" - "movq 48(%0), %%mm6\n" - "movq 56(%0), %%mm7\n" - "movntq %%mm0, (%1)\n" - "movntq %%mm1, 8(%1)\n" - "movntq %%mm2, 16(%1)\n" - "movntq %%mm3, 24(%1)\n" - "movntq %%mm4, 32(%1)\n" - "movntq %%mm5, 40(%1)\n" - "movntq %%mm6, 48(%1)\n" - "movntq %%mm7, 56(%1)\n" - :: "r" (from), "r" (to) : "memory"); - ((const unsigned char *)from)+=64; - ((unsigned char *)to)+=64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if(len) __memcpy(to, from, len); - return retval; -} - -static void *linux_kernel_memcpy(void *to, const void *from, size_t len) { - return __memcpy(to,from,len); -} - -#endif /* ARCH_X86 */ - -static struct { - char *name; - void *(* function)(void *to, const void *from, size_t len); - unsigned long long time; - uint32_t cpu_require; -} memcpy_method[] = -{ - { "glibc memcpy()", memcpy, 0, 0 }, -#ifdef ARCH_X86 - { "linux kernel memcpy()", linux_kernel_memcpy, 0, 0 }, - { "MMX optimized memcpy()", mmx_memcpy, 0, MM_MMX }, - { "MMXEXT optimized memcpy()", mmx2_memcpy, 0, MM_MMXEXT }, - { "SSE optimized memcpy()", sse_memcpy, 0, MM_MMXEXT|MM_SSE }, -#endif /* ARCH_X86 */ - { NULL, NULL, 0, 0 } -}; - -#ifdef ARCH_X86 -static unsigned long long int rdtsc() -{ - unsigned long long int x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; -} -#else -static unsigned long long int rdtsc() -{ - /* FIXME: implement an equivalent for using optimized memcpy on other - architectures */ - return 0; -} -#endif - - -#define BUFSIZE 1024*1024 -void probe_fast_memcpy(config_values_t *config) -{ -unsigned long long t; -char *buf1, *buf2; -int i, j, best; -static int config_flags = -1; - -#ifdef ARCH_X86 - config_flags = mm_accel(); -#else - config_flags = 0; -#endif - - best = config->lookup_int (config, "fast_memcpy", -1); - /* check if function is configured and valid for this machine */ - if( best != -1 && - (config_flags & memcpy_method[best].cpu_require) == - memcpy_method[best].cpu_require ) { - printf("xine: using %s\n", memcpy_method[best].name ); - fast_memcpy = memcpy_method[best].function; - return; - } - - fast_memcpy = memcpy; - - if( (buf1 = malloc(BUFSIZE)) == NULL ) - return; - - if( (buf2 = malloc(BUFSIZE)) == NULL ) { - free(buf1); - return; - } - - printf("Benchmarking memcpy methods (smaller is better):\n"); - /* make sure buffers are present on physical memory */ - memcpy(buf1,buf2,BUFSIZE); - - for(i=0; memcpy_method[i].name; i++) - { - if( (config_flags & memcpy_method[i].cpu_require) != - memcpy_method[i].cpu_require ) - continue; - - t = rdtsc(); - for(j=0;j<100;j++) - memcpy_method[i].function(buf1,buf2,BUFSIZE); - t = rdtsc() - t; - memcpy_method[i].time = t; - - printf("\t%s : %lld\n",memcpy_method[i].name, t); - - if( best == -1 || t < memcpy_method[best].time ) - best = i; - } - printf("xine: using %s\n", memcpy_method[best].name ); - fast_memcpy = memcpy_method[best].function; - config->set_int (config, "fast_memcpy", best ); - - free(buf1); - free(buf2); -} diff --git a/src/xine-engine/memcpy.h b/src/xine-engine/memcpy.h deleted file mode 100644 index a693f37fe..000000000 --- a/src/xine-engine/memcpy.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - */ - -#ifndef HAVE_MEMCPY_H -#define HAVE_MEMCPY_H - -/* optimized/fast memcpy */ -extern void *(* fast_memcpy)(void *to, const void *from, size_t len); - -#ifdef HAVE_XINE_INTERNAL_H -/* benchmark available memcpy methods */ -void probe_fast_memcpy(config_values_t *config); -#endif - -#endif diff --git a/src/xine-engine/monitor.c b/src/xine-engine/monitor.c deleted file mode 100644 index 05ac994a6..000000000 --- a/src/xine-engine/monitor.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: monitor.c,v 1.5 2001/09/10 13:36:56 jkeil Exp $ - * - * debug print and profiling functions - implementation - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "utils.h" -#include "monitor.h" - -#define MAX_ID 10 - -#ifdef DEBUG - -long long int profiler_times[MAX_ID] ; -long long int profiler_start[MAX_ID] ; -long profiler_calls[MAX_ID] ; -char * profiler_label[MAX_ID] ; - -void profiler_init () { - int i; - for (i=0; i= MAX_ID) - return -1; - - profiler_label[id] = label; - return id; -} - - -#ifdef ARCH_X86 -__inline__ unsigned long long int rdtsc() -{ - unsigned long long int x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; -} -#endif - -void profiler_start_count (int id) { - - if ((unsigned)id >= MAX_ID) return; - -#ifdef ARCH_X86 - profiler_start[id] = rdtsc(); -#endif -} - -void profiler_stop_count (int id) { - - if ((unsigned)id >= MAX_ID) return; - -#ifdef ARCH_X86 - profiler_times[id] += rdtsc() - profiler_start[id]; -#endif - profiler_calls[id]++; -} - -void profiler_print_results () { - int i; - -#ifdef ARCH_X86 - static long long int cpu_speed; /* cpu cyles/usec */ - if (!cpu_speed) { - long long int tsc_start, tsc_end; - struct timeval tv_start, tv_end; - - tsc_start = rdtsc(); - gettimeofday(&tv_start, NULL); - - xine_usec_sleep(100000); - - tsc_end = rdtsc(); - gettimeofday(&tv_end, NULL); - - cpu_speed = (tsc_end - tsc_start) / - ((tv_end.tv_sec - tv_start.tv_sec) * 1e6 + - tv_end.tv_usec - tv_start.tv_usec); - } -#endif - - printf ("\n\nPerformance analysis:\n\n" - "%-3s %-24.24s %12s %9s %12s %9s\n" - "----------------------------------------------------------------------------\n", - "ID", "name", "cpu cycles", "calls", "cycles/call", "usec/call"); - for (i=0; i - -extern uint32_t xine_debug; - -#define VERBOSE (xine_debug & 0x8000>>1) // 16384 -#define METRONOM (xine_debug & 0x8000>>2) // 8192 -#define AUDIO (xine_debug & 0x8000>>3) // 4096 -#define DEMUX (xine_debug & 0x8000>>4) // 2048 -#define INPUT (xine_debug & 0x8000>>5) // 1024 -#define VIDEO (xine_debug & 0x8000>>6) // 512 -#define VPTS (xine_debug & 0x8000>>7) // 256 -#define MPEG (xine_debug & 0x8000>>8) // 128 -#define VAVI (xine_debug & 0x8000>>9) // 64 -#define AC3 (xine_debug & 0x8000>>10) // 32 -#define LOOP (xine_debug & 0x8000>>11) // 16 -#define GUI (xine_debug & 0x8000>>12) // 8 - -#ifdef __GNUC__ -#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);} -#else /* C99 version: */ -#define perr(...) {fprintf(stderr, __VA_ARGS__);fflush(stderr);} -#endif - -#ifdef DEBUG - -/* - * Debug stuff - */ - -//#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);} - -#ifdef __GNUC__ -#define xprintf(LVL, FMT, ARGS...) { \ - if(LVL) { \ - printf(FMT, ##ARGS); \ - } \ - } -#else /* C99 version: */ -#define xprintf(LVL, ...) { \ - if(LVL) { \ - printf(__VA_ARGS__); \ - } \ - } -#endif - -/* - * profiling - */ - -void profiler_init (); - -int profiler_allocate_slot (char *label); - -void profiler_start_count (int id); - -void profiler_stop_count (int id); - -void profiler_print_results (); - -#else /* no DEBUG, release version */ - -//#define perr(FMT,ARGS...) - -#ifdef __GNUC__ -#define xprintf(LVL, FMT, ARGS...) -#else /* C99 version: */ -#define xprintf(LVL, ...) -#endif - -#define profiler_init() -#define profiler_allocate_slot(label) (-1) -#define profiler_start_count(id) -#define profiler_stop_count(id) -#define profiler_print_results() - -#endif /* DEBUG*/ - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_MONITOR_H */ diff --git a/src/xine-engine/utils.c b/src/xine-engine/utils.c deleted file mode 100644 index e90b1dee1..000000000 --- a/src/xine-engine/utils.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: utils.c,v 1.5 2001/10/03 15:16:50 jkeil Exp $ - * - */ -#define _POSIX_PTHREAD_SEMANTICS 1 /* for 5-arg getpwuid_r on solaris */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __GNUC__ -#define __FUNCTION__ __func__ -#endif - - -/* - * - */ -void *xmalloc(size_t size) { - void *ptr; - - if((ptr = malloc(size)) == NULL) { - fprintf(stderr, "%s: malloc() failed: %s.\n", - __FUNCTION__, strerror(errno)); - return NULL; - } - - memset(ptr, 0, size); - - return ptr; -} - -/* - * - */ -void *xmalloc_aligned (size_t alignment, size_t size) { - char *pMem; - - pMem = xmalloc (size+alignment); - - while ((int) pMem % alignment) - pMem++; - - return pMem; -} - -/* - * - */ -const char *get_homedir(void) { - struct passwd *pw = NULL; - char *homedir = NULL; -#ifdef HAVE_GETPWUID_R - int ret; - struct passwd pwd; - char *buffer = NULL; - int bufsize = 128; - - buffer = (char *) xmalloc(bufsize); - - if((ret = getpwuid_r(getuid(), &pwd, buffer, bufsize, &pw)) < 0) { -#else - if((pw = getpwuid(getuid())) == NULL) { -#endif - if((homedir = getenv("HOME")) == NULL) { - fprintf(stderr, "Unable to get home directory, set it to /tmp.\n"); - homedir = strdup("/tmp"); - } - } - else { - if(pw) - homedir = strdup(pw->pw_dir); - } - - -#ifdef HAVE_GETPWUID_R - if(buffer) - free(buffer); -#endif - - return homedir; -} - -/* - * - */ -char *chomp(char *str) { - char *pbuf; - - pbuf = str; - - while(*pbuf != '\0') pbuf++; - - while(pbuf > str) { - if(*pbuf == '\r' || *pbuf == '\n' || *pbuf == '"') pbuf = '\0'; - pbuf--; - } - - while(*pbuf == '=' || *pbuf == '"') pbuf++; - - return pbuf; -} - - -/* - * A thread-safe usecond sleep - */ -void xine_usec_sleep(unsigned usec) { -#if HAVE_NANOSLEEP - /* nanosleep is prefered on solaris, because it's mt-safe */ - struct timespec ts; - - ts.tv_sec = usec / 1000000; - ts.tv_nsec = (usec % 1000000) * 1000; - nanosleep(&ts, NULL); -#else - usleep(usec); -#endif -} diff --git a/src/xine-engine/utils.h b/src/xine-engine/utils.h deleted file mode 100644 index ddc130871..000000000 --- a/src/xine-engine/utils.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: utils.h,v 1.3 2001/09/06 13:29:18 jkeil Exp $ - * - */ -#ifndef HAVE_UTILS_H -#define HAVE_UTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -void *xmalloc(size_t size); - -void *xmalloc_aligned(size_t alignment, size_t size); - -const char *get_homedir(void); - -/* - * Clean a string (remove spaces and '=' at the begin, - * and '\n', '\r' and spaces at the end. - */ - -char *chomp (char *str); - -/* - * A thread-safe usecond sleep - */ -void xine_usec_sleep(unsigned usec); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/xine-utils/Makefile.am b/src/xine-utils/Makefile.am new file mode 100644 index 000000000..29ef6eef0 --- /dev/null +++ b/src/xine-utils/Makefile.am @@ -0,0 +1,82 @@ +## +## Process this file with automake to produce Makefile.in +## + +CFLAGS = @GLOBAL_CFLAGS@ @THREAD_CFLAGS@ + + +EXTRA_DIST = cpu_accel.c + +lib_LTLIBRARIES = libxineutils.la + +libxineutils_la_SOURCES = utils.c memcpy.c monitor.c +libxineutils_la_LIBADD = cpu_accel.lo \ + $(THREAD_LIBS) \ + $(DYNAMIC_LD_LIBS) \ + -lm + +libxineutils_la_LDFLAGS = \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -release $(LT_RELEASE) + +include_HEADERS = attributes.h cpu_accel.h memcpy.h utils.h monitor.h + +### +# Hardcoded rule: +# gcc failed to compile this with -fPIC flag +# hackish: [X] yes [ ] no +# +LIBTOOLNOFPIC = $(SHELL) $(top_builddir)/libtool-nofpic +LTCOMPILENOFPIC = $(LIBTOOLNOFPIC) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +cpu_accel.lo: cpu_accel.c + @mkdir -p .deps; touch .deps/cpu_accel.pp; \ + echo '$(LTCOMPILENOFPIC) -c $<'; \ + $(LTCOMPILENOFPIC) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp + + +debug: + @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" + +install-debug: debug + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + + + +### +# Install header files (default=$includedir/xine) +# +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir)/xine + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \ + done + + +### +# Remove them +# +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/xine/$$p; \ + done + + +mostlyclean-generic: + -rm -f *~ \#* .*~ .\#* + + +maintainer-clean-generic: + -@echo "This command is intended for maintainers to use;" + -@echo "it deletes files that may require special tools to rebuild." + -rm -f Makefile.in + diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h new file mode 100644 index 000000000..8ed7aef9e --- /dev/null +++ b/src/xine-utils/attributes.h @@ -0,0 +1,27 @@ +/* + * attributes.h + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpeg2dec 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//use gcc attribs to align critical data structures +#ifdef ATTRIBUTE_ALIGNED_MAX +#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) +#else +#define ATTR_ALIGN(align) +#endif diff --git a/src/xine-utils/cpu_accel.c b/src/xine-utils/cpu_accel.c new file mode 100644 index 000000000..8c28d950a --- /dev/null +++ b/src/xine-utils/cpu_accel.c @@ -0,0 +1,124 @@ +/* + * cpu_accel.c + * Copyright (C) 1999-2001 Aaron Holtzman + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpeg2dec 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include + +#include "attributes.h" +#include "cpu_accel.h" + +#ifdef ARCH_X86 +static uint32_t x86_accel (void) +{ + uint32_t eax, ebx, ecx, edx; + int AMD; + uint32_t caps; + +#define cpuid(op,eax,ebx,ecx,edx) \ + asm ("cpuid" \ + : "=a" (eax), \ + "=b" (ebx), \ + "=c" (ecx), \ + "=d" (edx) \ + : "a" (op) \ + : "cc") + + + asm ("pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl $0x200000,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl" + : "=a" (eax), + "=b" (ebx) + : + : "cc"); + + if (eax == ebx) /* no cpuid */ + return 0; + + cpuid (0x00000000, eax, ebx, ecx, edx); + if (!eax) /* vendor string only */ + return 0; + + AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); + + cpuid (0x00000001, eax, ebx, ecx, edx); + if (! (edx & 0x00800000)) /* no MMX */ + return 0; + caps = MM_ACCEL_X86_MMX; + + if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ + caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT; + + if (edx & 0x04000000) /* SSE2 */ + caps |= MM_ACCEL_X86_SSE2; + + cpuid (0x80000000, eax, ebx, ecx, edx); + if (eax < 0x80000001) /* no extended capabilities */ + return caps; + + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & 0x80000000) /* 3DNOW */ + caps |= MM_ACCEL_X86_3DNOW; + + if (edx & 0x40000000) /* 3DNOWEXT */ + /*caps |= MM_ACCEL_X86_???*/ ; + + if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ + caps |= MM_ACCEL_X86_MMXEXT; + + return caps; +} +#endif + +uint32_t mm_accel (void) +{ +#ifdef ARCH_X86 + static int got_accel = 0; + static uint32_t accel; + + if (!got_accel) { + got_accel = 1; + accel = x86_accel (); + } + + return accel; +#else +#ifdef HAVE_MLIB + return MM_ACCEL_MLIB; +#else + return 0; +#endif +#endif +} + +uint32_t mm_support (void) +{ + return mm_accel(); +} diff --git a/src/xine-utils/cpu_accel.h b/src/xine-utils/cpu_accel.h new file mode 100644 index 000000000..053c142f6 --- /dev/null +++ b/src/xine-utils/cpu_accel.h @@ -0,0 +1,531 @@ +/* + * cpu_accel.h - based on mmx.h, sse.h + * Copyright (C) 1997-1999 H. Dietz and R. Fisher + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpeg2dec 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * xine specific modifications 2001 by G. Bartsch + * + */ + +/* + * The type of an value that fits in an MMX register (note that long + * long constant values MUST be suffixed by LL and unsigned long long + * values by ULL, lest they be truncated by the compiler) + */ + +#ifndef _CPU_ACCEL_H +#define _CPU_ACCEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "attributes.h" + +/* generic accelerations */ +#define MM_ACCEL_MLIB 0x00000001 + +/* x86 accelerations */ +#define MM_ACCEL_X86_MMX 0x80000000 +#define MM_ACCEL_X86_3DNOW 0x40000000 +#define MM_ACCEL_X86_MMXEXT 0x20000000 +#define MM_ACCEL_X86_SSE 0x10000000 +#define MM_ACCEL_X86_SSE2 0x08000000 +/* x86 compat defines */ +#define MM_MMX MM_ACCEL_X86_MMX +#define MM_3DNOW MM_ACCEL_X86_3DNOW +#define MM_MMXEXT MM_ACCEL_X86_MMXEXT +#define MM_SSE MM_ACCEL_X86_SSE +#define MM_SSE2 MM_ACCEL_X86_SSE2 + +uint32_t mm_accel (void) ; +/* uint32_t mm_support (void) ; */ + +#ifdef ARCH_X86 + +typedef union { + long long q; /* Quadword (64-bit) value */ + unsigned long long uq; /* Unsigned Quadword */ + int d[2]; /* 2 Doubleword (32-bit) values */ + unsigned int ud[2]; /* 2 Unsigned Doubleword */ + short w[4]; /* 4 Word (16-bit) values */ + unsigned short uw[4]; /* 4 Unsigned Word */ + char b[8]; /* 8 Byte (8-bit) values */ + unsigned char ub[8]; /* 8 Unsigned Byte */ + float s[2]; /* Single-precision (32-bit) value */ +} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ + + + +#define mmx_i2r(op,imm,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (imm) ) + +#define mmx_m2r(op,mem,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)) + +#define mmx_r2m(op,reg,mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ) + +#define mmx_r2r(op,regs,regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + + +#define emms() __asm__ __volatile__ ("emms") + +#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) +#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) +#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) + +#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) +#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) +#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) + +#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) +#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) +#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) +#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) + +#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) +#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) + +#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) +#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) +#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) +#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) +#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) +#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) + +#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) +#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) +#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) +#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) + +#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) +#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) +#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) +#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) + +#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) +#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) + +#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) +#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) + +#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) +#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) +#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) +#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) +#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) +#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) + +#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) +#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) +#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) +#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) +#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) +#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) + +#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) +#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) + +#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) +#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) + +#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) +#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) + +#define por_m2r(var,reg) mmx_m2r (por, var, reg) +#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) + +#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) +#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) +#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) +#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) +#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) +#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) +#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) +#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) +#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) + +#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) +#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) +#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) +#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) +#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) +#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) + +#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) +#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) +#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) +#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) +#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) +#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) +#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) +#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) +#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) + +#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) +#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) +#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) +#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) +#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) +#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) + +#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) +#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) +#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) +#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) + +#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) +#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) +#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) +#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) + +#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) +#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) +#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) +#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) +#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) +#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) + +#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) +#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) +#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) +#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) +#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) +#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) + +#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) +#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) + + +/* 3DNOW extensions */ + +#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) +#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) + + +/* AMD MMX extensions - also available in intel SSE */ + + +#define mmx_m2ri(op,mem,reg,imm) \ + __asm__ __volatile__ (#op " %1, %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem), "X" (imm)) +#define mmx_r2ri(op,regs,regd,imm) \ + __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ + : /* nothing */ \ + : "X" (imm) ) + +#define mmx_fetch(mem,hint) \ + __asm__ __volatile__ ("prefetch" #hint " %0" \ + : /* nothing */ \ + : "X" (mem)) + + +#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) + +#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) + +#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) +#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) +#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) +#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) + +#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) + +#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) + +#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) +#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) + +#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) +#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) + +#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) +#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) + +#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) +#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) + +#define pmovmskb(mmreg,reg) \ + __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) + +#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) +#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) + +#define prefetcht0(mem) mmx_fetch (mem, t0) +#define prefetcht1(mem) mmx_fetch (mem, t1) +#define prefetcht2(mem) mmx_fetch (mem, t2) +#define prefetchnta(mem) mmx_fetch (mem, nta) + +#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) +#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) + +#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) +#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) + +#define sfence() __asm__ __volatile__ ("sfence\n\t") + +typedef union { + float sf[4]; /* Single-precision (32-bit) value */ +} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ + + +#define sse_i2r(op, imm, reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (imm) ) + +#define sse_m2r(op, mem, reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)) + +#define sse_r2m(op, reg, mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ) + +#define sse_r2r(op, regs, regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + +#define sse_r2ri(op, regs, regd, imm) \ + __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ + : /* nothing */ \ + : "X" (imm) ) + +#define sse_m2ri(op, mem, reg, subop) \ + __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ + : /* nothing */ \ + : "X" (mem)) + + +#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) +#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) +#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) + +#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) + +#define movups_m2r(var, reg) sse_m2r(movups, var, reg) +#define movups_r2m(reg, var) sse_r2m(movups, reg, var) +#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) + +#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) + +#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) + +#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) +#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) + +#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) +#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) + +#define movss_m2r(var, reg) sse_m2r(movss, var, reg) +#define movss_r2m(reg, var) sse_r2m(movss, reg, var) +#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) + +#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) +#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) + +#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) +#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) + +#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) +#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) + +#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) +#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) + +#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) +#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) + +#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) +#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) + +#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) +#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) + +#define movmskps(xmmreg, reg) \ + __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) + +#define addps_m2r(var, reg) sse_m2r(addps, var, reg) +#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) + +#define addss_m2r(var, reg) sse_m2r(addss, var, reg) +#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) + +#define subps_m2r(var, reg) sse_m2r(subps, var, reg) +#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) + +#define subss_m2r(var, reg) sse_m2r(subss, var, reg) +#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) + +#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) +#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) + +#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) +#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) + +#define divps_m2r(var, reg) sse_m2r(divps, var, reg) +#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) + +#define divss_m2r(var, reg) sse_m2r(divss, var, reg) +#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) + +#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) +#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) + +#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) +#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) + +#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) +#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) + +#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) +#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) + +#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) +#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) + +#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) +#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) + +#define andps_m2r(var, reg) sse_m2r(andps, var, reg) +#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) + +#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) +#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) + +#define orps_m2r(var, reg) sse_m2r(orps, var, reg) +#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) + +#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) +#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) + +#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) +#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) + +#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) +#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) + +#define minps_m2r(var, reg) sse_m2r(minps, var, reg) +#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) + +#define minss_m2r(var, reg) sse_m2r(minss, var, reg) +#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) + +#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) +#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) + +#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) +#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) + +#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) +#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) + +#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) +#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) + +#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) +#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) + +#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) +#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) + +#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) +#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) + +#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) +#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) + +#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) +#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) + +#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) +#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) + +#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) +#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) + +#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) +#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) + +#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) +#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) + +#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) +#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) + +#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) +#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) + +#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) +#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) + +#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) +#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) + +#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) +#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) + +#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) +#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) + +#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) +#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) + +#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) +#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) + +#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) +#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) + +#define fxrstor(mem) \ + __asm__ __volatile__ ("fxrstor %0" \ + : /* nothing */ \ + : "X" (mem)) + +#define fxsave(mem) \ + __asm__ __volatile__ ("fxsave %0" \ + : /* nothing */ \ + : "X" (mem)) + +#define stmxcsr(mem) \ + __asm__ __volatile__ ("stmxcsr %0" \ + : /* nothing */ \ + : "X" (mem)) + +#define ldmxcsr(mem) \ + __asm__ __volatile__ ("ldmxcsr %0" \ + : /* nothing */ \ + : "X" (mem)) +#endif /*ARCH_X86 */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c new file mode 100644 index 000000000..23a17059c --- /dev/null +++ b/src/xine-utils/memcpy.c @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * These are the MMX/MMX2/SSE optimized versions of memcpy + * + * This code was adapted from Linux Kernel sources by Nick Kurshev to + * the mplayer program. (http://mplayer.sourceforge.net) + * + * Miguel Freitas split the #ifdefs into several specialized functions that + * are benchmarked at runtime by xine. Some original comments from Nick + * have been preserved documenting some MMX/SSE oddities. + * Also added kernel memcpy function that seems faster than glibc one. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "xine_internal.h" +#include "cpu_accel.h" + +void *(* fast_memcpy)(void *to, const void *from, size_t len); + +/* Original comments from mplayer (file: aclib.c) + This part of code was taken by me from Linux-2.4.3 and slightly modified +for MMX, MMX2, SSE instruction set. I have done it since linux uses page aligned +blocks but mplayer uses weakly ordered data and original sources can not +speedup them. Only using PREFETCHNTA and MOVNTQ together have effect! + +>From IA-32 Intel Architecture Software Developer's Manual Volume 1, + +Order Number 245470: +"10.4.6. Cacheability Control, Prefetch, and Memory Ordering Instructions" + +Data referenced by a program can be temporal (data will be used again) or +non-temporal (data will be referenced once and not reused in the immediate +future). To make efficient use of the processor's caches, it is generally +desirable to cache temporal data and not cache non-temporal data. Overloading +the processor's caches with non-temporal data is sometimes referred to as +"polluting the caches". +The non-temporal data is written to memory with Write-Combining semantics. + +The PREFETCHh instructions permits a program to load data into the processor +at a suggested cache level, so that it is closer to the processors load and +store unit when it is needed. If the data is already present in a level of +the cache hierarchy that is closer to the processor, the PREFETCHh instruction +will not result in any data movement. +But we should you PREFETCHNTA: Non-temporal data fetch data into location +close to the processor, minimizing cache pollution. + +The MOVNTQ (store quadword using non-temporal hint) instruction stores +packed integer data from an MMX register to memory, using a non-temporal hint. +The MOVNTPS (store packed single-precision floating-point values using +non-temporal hint) instruction stores packed floating-point data from an +XMM register to memory, using a non-temporal hint. + +The SFENCE (Store Fence) instruction controls write ordering by creating a +fence for memory store operations. This instruction guarantees that the results +of every store instruction that precedes the store fence in program order is +globally visible before any store instruction that follows the fence. The +SFENCE instruction provides an efficient way of ensuring ordering between +procedures that produce weakly-ordered data and procedures that consume that +data. + +If you have questions please contact with me: Nick Kurshev: nickols_k@mail.ru. +*/ + +/* mmx v.1 Note: Since we added alignment of destinition it speedups + of memory copying on PentMMX, Celeron-1 and P2 upto 12% versus + standard (non MMX-optimized) version. + Note: on K6-2+ it speedups memory copying upto 25% and + on K7 and P3 about 500% (5 times). +*/ + +#ifdef ARCH_X86 + +/* for small memory blocks (<256 bytes) this version is faster */ +#define small_memcpy(to,from,n)\ +{\ +register unsigned long int dummy;\ +__asm__ __volatile__(\ + "rep; movsb"\ + :"=&D"(to), "=&S"(from), "=&c"(dummy)\ + :"0" (to), "1" (from),"2" (n)\ + : "memory");\ +} + +/* linux kernel __memcpy (from: /include/asm/string.h) */ +static inline void * __memcpy(void * to, const void * from, size_t n) +{ +int d0, d1, d2; + + if( n < 4 ) { + small_memcpy(to,from,n); + } + else + __asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); + + return (to); +} + +#define SSE_MMREG_SIZE 16 +#define MMX_MMREG_SIZE 8 + +#define MMX1_MIN_LEN 0x800 /* 2K blocks */ +#define MIN_LEN 0x40 /* 64-byte blocks */ + +/* SSE note: i tried to move 128 bytes a time instead of 64 but it +didn't make any measureable difference. i'm using 64 for the sake of +simplicity. [MF] */ +static void * sse_memcpy(void * to, const void * from, size_t len) +{ + void *retval; + size_t i; + retval = to; + + if(len >= MIN_LEN) + { + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to)&(SSE_MMREG_SIZE-1); + if(delta) + { + delta=SSE_MMREG_SIZE-delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + if(((unsigned long)from) & 15) + /* if SRC is misaligned */ + for(; i>0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "movups (%0), %%xmm0\n" + "movups 16(%0), %%xmm1\n" + "movups 32(%0), %%xmm2\n" + "movups 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + :: "r" (from), "r" (to) : "memory"); + ((const unsigned char *)from)+=64; + ((unsigned char *)to)+=64; + } + else + /* + Only if SRC is aligned on 16-byte boundary. + It allows to use movaps instead of movups, which required data + to be aligned or a general-protection exception (#GP) is generated. + */ + for(; i>0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "movaps (%0), %%xmm0\n" + "movaps 16(%0), %%xmm1\n" + "movaps 32(%0), %%xmm2\n" + "movaps 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + :: "r" (from), "r" (to) : "memory"); + ((const unsigned char *)from)+=64; + ((unsigned char *)to)+=64; + } + /* since movntq is weakly-ordered, a "sfence" + * is needed to become ordered again. */ + __asm__ __volatile__ ("sfence":::"memory"); + /* enables to use FPU */ + __asm__ __volatile__ ("emms":::"memory"); + } + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; +} + +static void * mmx_memcpy(void * to, const void * from, size_t len) +{ + void *retval; + size_t i; + retval = to; + + /* PREFETCH has effect even for MOVSB instruction ;) */ + __asm__ __volatile__ ( + " prefetchnta (%0)\n" + " prefetchnta 64(%0)\n" + " prefetchnta 128(%0)\n" + " prefetchnta 192(%0)\n" + " prefetchnta 256(%0)\n" + : : "r" (from) ); + + if(len >= MMX1_MIN_LEN) + { + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); + if(delta) + { + delta=MMX_MMREG_SIZE-delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + for(; i>0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movq %%mm0, (%1)\n" + "movq %%mm1, 8(%1)\n" + "movq %%mm2, 16(%1)\n" + "movq %%mm3, 24(%1)\n" + "movq %%mm4, 32(%1)\n" + "movq %%mm5, 40(%1)\n" + "movq %%mm6, 48(%1)\n" + "movq %%mm7, 56(%1)\n" + :: "r" (from), "r" (to) : "memory"); + ((const unsigned char *)from)+=64; + ((unsigned char *)to)+=64; + } + __asm__ __volatile__ ("emms":::"memory"); + } + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; +} + +void * mmx2_memcpy(void * to, const void * from, size_t len) +{ + void *retval; + size_t i; + retval = to; + + /* PREFETCH has effect even for MOVSB instruction ;) */ + __asm__ __volatile__ ( + " prefetchnta (%0)\n" + " prefetchnta 64(%0)\n" + " prefetchnta 128(%0)\n" + " prefetchnta 192(%0)\n" + " prefetchnta 256(%0)\n" + : : "r" (from) ); + + if(len >= MIN_LEN) + { + register unsigned long int delta; + /* Align destinition to MMREG_SIZE -boundary */ + delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); + if(delta) + { + delta=MMX_MMREG_SIZE-delta; + len -= delta; + small_memcpy(to, from, delta); + } + i = len >> 6; /* len/64 */ + len&=63; + for(; i>0; i--) + { + __asm__ __volatile__ ( + "prefetchnta 320(%0)\n" + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "movntq %%mm6, 48(%1)\n" + "movntq %%mm7, 56(%1)\n" + :: "r" (from), "r" (to) : "memory"); + ((const unsigned char *)from)+=64; + ((unsigned char *)to)+=64; + } + /* since movntq is weakly-ordered, a "sfence" + * is needed to become ordered again. */ + __asm__ __volatile__ ("sfence":::"memory"); + __asm__ __volatile__ ("emms":::"memory"); + } + /* + * Now do the tail of the block + */ + if(len) __memcpy(to, from, len); + return retval; +} + +static void *linux_kernel_memcpy(void *to, const void *from, size_t len) { + return __memcpy(to,from,len); +} + +#endif /* ARCH_X86 */ + +static struct { + char *name; + void *(* function)(void *to, const void *from, size_t len); + unsigned long long time; + uint32_t cpu_require; +} memcpy_method[] = +{ + { "glibc memcpy()", memcpy, 0, 0 }, +#ifdef ARCH_X86 + { "linux kernel memcpy()", linux_kernel_memcpy, 0, 0 }, + { "MMX optimized memcpy()", mmx_memcpy, 0, MM_MMX }, + { "MMXEXT optimized memcpy()", mmx2_memcpy, 0, MM_MMXEXT }, + { "SSE optimized memcpy()", sse_memcpy, 0, MM_MMXEXT|MM_SSE }, +#endif /* ARCH_X86 */ + { NULL, NULL, 0, 0 } +}; + +#ifdef ARCH_X86 +static unsigned long long int rdtsc() +{ + unsigned long long int x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; +} +#else +static unsigned long long int rdtsc() +{ + /* FIXME: implement an equivalent for using optimized memcpy on other + architectures */ + return 0; +} +#endif + + +#define BUFSIZE 1024*1024 +void probe_fast_memcpy(config_values_t *config) +{ +unsigned long long t; +char *buf1, *buf2; +int i, j, best; +static int config_flags = -1; + +#ifdef ARCH_X86 + config_flags = mm_accel(); +#else + config_flags = 0; +#endif + + best = config->lookup_int (config, "fast_memcpy", -1); + /* check if function is configured and valid for this machine */ + if( best != -1 && + (config_flags & memcpy_method[best].cpu_require) == + memcpy_method[best].cpu_require ) { + printf("xine: using %s\n", memcpy_method[best].name ); + fast_memcpy = memcpy_method[best].function; + return; + } + + fast_memcpy = memcpy; + + if( (buf1 = malloc(BUFSIZE)) == NULL ) + return; + + if( (buf2 = malloc(BUFSIZE)) == NULL ) { + free(buf1); + return; + } + + printf("Benchmarking memcpy methods (smaller is better):\n"); + /* make sure buffers are present on physical memory */ + memcpy(buf1,buf2,BUFSIZE); + + for(i=0; memcpy_method[i].name; i++) + { + if( (config_flags & memcpy_method[i].cpu_require) != + memcpy_method[i].cpu_require ) + continue; + + t = rdtsc(); + for(j=0;j<100;j++) + memcpy_method[i].function(buf1,buf2,BUFSIZE); + t = rdtsc() - t; + memcpy_method[i].time = t; + + printf("\t%s : %lld\n",memcpy_method[i].name, t); + + if( best == -1 || t < memcpy_method[best].time ) + best = i; + } + printf("xine: using %s\n", memcpy_method[best].name ); + fast_memcpy = memcpy_method[best].function; + config->set_int (config, "fast_memcpy", best ); + + free(buf1); + free(buf2); +} diff --git a/src/xine-utils/memcpy.h b/src/xine-utils/memcpy.h new file mode 100644 index 000000000..a693f37fe --- /dev/null +++ b/src/xine-utils/memcpy.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2000-2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +#ifndef HAVE_MEMCPY_H +#define HAVE_MEMCPY_H + +/* optimized/fast memcpy */ +extern void *(* fast_memcpy)(void *to, const void *from, size_t len); + +#ifdef HAVE_XINE_INTERNAL_H +/* benchmark available memcpy methods */ +void probe_fast_memcpy(config_values_t *config); +#endif + +#endif diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c new file mode 100644 index 000000000..9250ee2c4 --- /dev/null +++ b/src/xine-utils/monitor.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2000-2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: monitor.c,v 1.1 2001/10/22 00:52:10 guenter Exp $ + * + * debug print and profiling functions - implementation + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "utils.h" +#include "monitor.h" + +#define MAX_ID 10 + +#ifdef DEBUG + +long long int profiler_times[MAX_ID] ; +long long int profiler_start[MAX_ID] ; +long profiler_calls[MAX_ID] ; +char * profiler_label[MAX_ID] ; + +void profiler_init () { + int i; + for (i=0; i= MAX_ID) + return -1; + + profiler_label[id] = label; + return id; +} + + +#ifdef ARCH_X86 +__inline__ unsigned long long int rdtsc() +{ + unsigned long long int x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; +} +#endif + +void profiler_start_count (int id) { + + if ((unsigned)id >= MAX_ID) return; + +#ifdef ARCH_X86 + profiler_start[id] = rdtsc(); +#endif +} + +void profiler_stop_count (int id) { + + if ((unsigned)id >= MAX_ID) return; + +#ifdef ARCH_X86 + profiler_times[id] += rdtsc() - profiler_start[id]; +#endif + profiler_calls[id]++; +} + +void profiler_print_results () { + int i; + +#ifdef ARCH_X86 + static long long int cpu_speed; /* cpu cyles/usec */ + if (!cpu_speed) { + long long int tsc_start, tsc_end; + struct timeval tv_start, tv_end; + + tsc_start = rdtsc(); + gettimeofday(&tv_start, NULL); + + xine_usec_sleep(100000); + + tsc_end = rdtsc(); + gettimeofday(&tv_end, NULL); + + cpu_speed = (tsc_end - tsc_start) / + ((tv_end.tv_sec - tv_start.tv_sec) * 1e6 + + tv_end.tv_usec - tv_start.tv_usec); + } +#endif + + printf ("\n\nPerformance analysis:\n\n" + "%-3s %-24.24s %12s %9s %12s %9s\n" + "----------------------------------------------------------------------------\n", + "ID", "name", "cpu cycles", "calls", "cycles/call", "usec/call"); + for (i=0; i + +extern uint32_t xine_debug; + +#define VERBOSE (xine_debug & 0x8000>>1) // 16384 +#define METRONOM (xine_debug & 0x8000>>2) // 8192 +#define AUDIO (xine_debug & 0x8000>>3) // 4096 +#define DEMUX (xine_debug & 0x8000>>4) // 2048 +#define INPUT (xine_debug & 0x8000>>5) // 1024 +#define VIDEO (xine_debug & 0x8000>>6) // 512 +#define VPTS (xine_debug & 0x8000>>7) // 256 +#define MPEG (xine_debug & 0x8000>>8) // 128 +#define VAVI (xine_debug & 0x8000>>9) // 64 +#define AC3 (xine_debug & 0x8000>>10) // 32 +#define LOOP (xine_debug & 0x8000>>11) // 16 +#define GUI (xine_debug & 0x8000>>12) // 8 + +#ifdef __GNUC__ +#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);} +#else /* C99 version: */ +#define perr(...) {fprintf(stderr, __VA_ARGS__);fflush(stderr);} +#endif + +#ifdef DEBUG + +/* + * Debug stuff + */ + +//#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);} + +#ifdef __GNUC__ +#define xprintf(LVL, FMT, ARGS...) { \ + if(LVL) { \ + printf(FMT, ##ARGS); \ + } \ + } +#else /* C99 version: */ +#define xprintf(LVL, ...) { \ + if(LVL) { \ + printf(__VA_ARGS__); \ + } \ + } +#endif + +/* + * profiling + */ + +void profiler_init (); + +int profiler_allocate_slot (char *label); + +void profiler_start_count (int id); + +void profiler_stop_count (int id); + +void profiler_print_results (); + +#else /* no DEBUG, release version */ + +//#define perr(FMT,ARGS...) + +#ifdef __GNUC__ +#define xprintf(LVL, FMT, ARGS...) +#else /* C99 version: */ +#define xprintf(LVL, ...) +#endif + +#define profiler_init() +#define profiler_allocate_slot(label) (-1) +#define profiler_start_count(id) +#define profiler_stop_count(id) +#define profiler_print_results() + +#endif /* DEBUG*/ + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_MONITOR_H */ diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c new file mode 100644 index 000000000..d3435ea84 --- /dev/null +++ b/src/xine-utils/utils.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2000-2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: utils.c,v 1.1 2001/10/22 00:52:10 guenter Exp $ + * + */ +#define _POSIX_PTHREAD_SEMANTICS 1 /* for 5-arg getpwuid_r on solaris */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __GNUC__ +#define __FUNCTION__ __func__ +#endif + + +/* + * + */ +void *xmalloc(size_t size) { + void *ptr; + + if((ptr = malloc(size)) == NULL) { + fprintf(stderr, "%s: malloc() failed: %s.\n", + __FUNCTION__, strerror(errno)); + return NULL; + } + + memset(ptr, 0, size); + + return ptr; +} + +/* + * + */ +void *xmalloc_aligned (size_t alignment, size_t size) { + char *pMem; + + pMem = xmalloc (size+alignment); + + while ((int) pMem % alignment) + pMem++; + + return pMem; +} + +/* + * + */ +const char *get_homedir(void) { + struct passwd *pw = NULL; + char *homedir = NULL; +#ifdef HAVE_GETPWUID_R + int ret; + struct passwd pwd; + char *buffer = NULL; + int bufsize = 128; + + buffer = (char *) xmalloc(bufsize); + + if((ret = getpwuid_r(getuid(), &pwd, buffer, bufsize, &pw)) < 0) { +#else + if((pw = getpwuid(getuid())) == NULL) { +#endif + if((homedir = getenv("HOME")) == NULL) { + fprintf(stderr, "Unable to get home directory, set it to /tmp.\n"); + homedir = strdup("/tmp"); + } + } + else { + if(pw) + homedir = strdup(pw->pw_dir); + } + + +#ifdef HAVE_GETPWUID_R + if(buffer) + free(buffer); +#endif + + return homedir; +} + +/* + * + */ +char *chomp(char *str) { + char *pbuf; + + pbuf = str; + + while(*pbuf != '\0') pbuf++; + + while(pbuf > str) { + if(*pbuf == '\r' || *pbuf == '\n' || *pbuf == '"') pbuf = '\0'; + pbuf--; + } + + while(*pbuf == '=' || *pbuf == '"') pbuf++; + + return pbuf; +} + + +/* + * A thread-safe usecond sleep + */ +void xine_usec_sleep(unsigned usec) { +#if HAVE_NANOSLEEP + /* nanosleep is prefered on solaris, because it's mt-safe */ + struct timespec ts; + + ts.tv_sec = usec / 1000000; + ts.tv_nsec = (usec % 1000000) * 1000; + nanosleep(&ts, NULL); +#else + usleep(usec); +#endif +} diff --git a/src/xine-utils/utils.h b/src/xine-utils/utils.h new file mode 100644 index 000000000..2c35d52db --- /dev/null +++ b/src/xine-utils/utils.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2000-2001 the xine project + * + * This file is part of xine, a unix video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: utils.h,v 1.1 2001/10/22 00:52:10 guenter Exp $ + * + */ +#ifndef HAVE_UTILS_H +#define HAVE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +void *xmalloc(size_t size); + +void *xmalloc_aligned(size_t alignment, size_t size); + +const char *get_homedir(void); + +/* + * Clean a string (remove spaces and '=' at the begin, + * and '\n', '\r' and spaces at the end. + */ + +char *chomp (char *str); + +/* + * A thread-safe usecond sleep + */ +void xine_usec_sleep(unsigned usec); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3